xref: /openwifi/driver/sdr.c (revision b196f496dfdf395d7da3a4bb1d2872c7dd3c7b10)
1 // Author: Xianjun Jiao, Michael Mehari, Wei Liu, Jetmir Haxhibeqiri, Pablo Avila Campos
2 // SPDX-FileCopyrightText: 2022 UGent
3 // SPDX-License-Identifier: AGPL-3.0-or-later
4 
5 #include <linux/bitops.h>
6 #include <linux/dmapool.h>
7 #include <linux/io.h>
8 #include <linux/iopoll.h>
9 #include <linux/of_address.h>
10 #include <linux/of_platform.h>
11 #include <linux/of_irq.h>
12 #include <linux/slab.h>
13 #include <linux/clk.h>
14 #include <linux/io-64-nonatomic-lo-hi.h>
15 
16 #include <linux/delay.h>
17 #include <linux/interrupt.h>
18 
19 #include <linux/dmaengine.h>
20 #include <linux/slab.h>
21 #include <linux/delay.h>
22 #include <linux/etherdevice.h>
23 
24 #include <linux/init.h>
25 #include <linux/kthread.h>
26 #include <linux/module.h>
27 #include <linux/of_dma.h>
28 #include <linux/platform_device.h>
29 #include <linux/random.h>
30 #include <linux/slab.h>
31 #include <linux/wait.h>
32 #include <linux/sched/task.h>
33 #include <linux/dma/xilinx_dma.h>
34 #include <linux/spi/spi.h>
35 #include <net/mac80211.h>
36 
37 #include <linux/clk.h>
38 #include <linux/clkdev.h>
39 #include <linux/clk-provider.h>
40 
41 #include <linux/iio/iio.h>
42 #include <linux/iio/sysfs.h>
43 
44 #include <linux/gpio.h>
45 #include <linux/leds.h>
46 
47 #define IIO_AD9361_USE_PRIVATE_H_
48 #include <../../drivers/iio/adc/ad9361_regs.h>
49 #include <../../drivers/iio/adc/ad9361.h>
50 #include <../../drivers/iio/adc/ad9361_private.h>
51 
52 #include <../../drivers/iio/frequency/cf_axi_dds.h>
53 extern int ad9361_get_tx_atten(struct ad9361_rf_phy *phy, u32 tx_num);
54 extern int ad9361_set_tx_atten(struct ad9361_rf_phy *phy, u32 atten_mdb,
55 			       bool tx1, bool tx2, bool immed);
56 extern int ad9361_ctrl_outs_setup(struct ad9361_rf_phy *phy,
57 				  struct ctrl_outs_control *ctrl);
58 
59 #include "../user_space/sdrctl_src/nl80211_testmode_def.h"
60 #include "hw_def.h"
61 #include "sdr.h"
62 #include "git_rev.h"
63 
64 // driver API of component driver
65 extern struct tx_intf_driver_api *tx_intf_api;
66 extern struct rx_intf_driver_api *rx_intf_api;
67 extern struct openofdm_tx_driver_api *openofdm_tx_api;
68 extern struct openofdm_rx_driver_api *openofdm_rx_api;
69 extern struct xpu_driver_api *xpu_api;
70 
71 u32 gen_mpdu_crc(u8 *data_in, u32 num_bytes);
72 u8 gen_mpdu_delim_crc(u16 m);
73 
74 #include "sdrctl_intf.c"
75 #include "sysfs_intf.c"
76 
77 static int test_mode = 0; // 0 normal; 1 rx test
78 
79 MODULE_AUTHOR("Xianjun Jiao");
80 MODULE_DESCRIPTION("SDR driver");
81 MODULE_LICENSE("GPL v2");
82 
83 module_param(test_mode, int, 0);
84 MODULE_PARM_DESC(myint, "test_mode. 0 normal; 1 rx test");
85 
86 // ---------------rfkill---------------------------------------
87 static bool openwifi_is_radio_enabled(struct openwifi_priv *priv)
88 {
89 	int reg;
90 
91 	if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1)
92 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
93 	else
94 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 1);
95 
96 	if (reg == AD9361_RADIO_ON_TX_ATT)
97 		return true;// 0 off, 1 on
98 	return false;
99 }
100 
101 void openwifi_rfkill_init(struct ieee80211_hw *hw)
102 {
103 	struct openwifi_priv *priv = hw->priv;
104 
105 	priv->rfkill_off = openwifi_is_radio_enabled(priv);
106 	printk("%s openwifi_rfkill_init: wireless switch is %s\n", sdr_compatible_str, priv->rfkill_off ? "on" : "off");
107 	wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off);
108 	wiphy_rfkill_start_polling(hw->wiphy);
109 }
110 
111 void openwifi_rfkill_poll(struct ieee80211_hw *hw)
112 {
113 	bool enabled;
114 	struct openwifi_priv *priv = hw->priv;
115 
116 	enabled = openwifi_is_radio_enabled(priv);
117 	// printk("%s openwifi_rfkill_poll: wireless radio switch turned %s\n", sdr_compatible_str, enabled ? "on" : "off");
118 	if (unlikely(enabled != priv->rfkill_off)) {
119 		priv->rfkill_off = enabled;
120 		printk("%s openwifi_rfkill_poll: WARNING wireless radio switch turned %s\n", sdr_compatible_str, enabled ? "on" : "off");
121 		wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
122 	}
123 }
124 
125 void openwifi_rfkill_exit(struct ieee80211_hw *hw)
126 {
127 	printk("%s openwifi_rfkill_exit\n", sdr_compatible_str);
128 	wiphy_rfkill_stop_polling(hw->wiphy);
129 }
130 //----------------rfkill end-----------------------------------
131 
132 //static void ad9361_rf_init(void);
133 //static void ad9361_rf_stop(void);
134 //static void ad9361_rf_calc_rssi(void);
135 static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
136 				  struct ieee80211_conf *conf)
137 {
138 	struct openwifi_priv *priv = dev->priv;
139 	u32 actual_rx_lo = conf->chandef.chan->center_freq - priv->rx_freq_offset_to_lo_MHz + priv->drv_rx_reg_val[DRV_RX_REG_IDX_EXTRA_FO];
140 	u32 actual_tx_lo;
141 	bool change_flag = (actual_rx_lo != priv->actual_rx_lo);
142 	int static_lbt_th, auto_lbt_th, fpga_lbt_th;
143 
144 	if (change_flag) {
145 		priv->actual_rx_lo = actual_rx_lo;
146 		priv->actual_tx_lo = actual_tx_lo;
147 
148 		actual_tx_lo = conf->chandef.chan->center_freq - priv->tx_freq_offset_to_lo_MHz;
149 
150 		clk_set_rate(priv->ad9361_phy->clks[RX_RFPLL], ( ((u64)1000000ull)*((u64)actual_rx_lo )>>1) );
151 		clk_set_rate(priv->ad9361_phy->clks[TX_RFPLL], ( ((u64)1000000ull)*((u64)actual_tx_lo )>>1) );
152 
153 		if (actual_rx_lo<2412) {
154 			priv->rssi_correction = 153;
155 		} else if (actual_rx_lo<=2484) {
156 			priv->rssi_correction = 153;
157 		} else if (actual_rx_lo<5160) {
158 			priv->rssi_correction = 153;
159 		} else if (actual_rx_lo<=5240) {
160 			priv->rssi_correction = 145;
161 		} else if (actual_rx_lo<=5320) {
162 			priv->rssi_correction = 148;
163 		} else {
164 			priv->rssi_correction = 148;
165 		}
166 
167 		// xpu_api->XPU_REG_LBT_TH_write((priv->rssi_correction-62)<<1); // -62dBm
168 		// xpu_api->XPU_REG_LBT_TH_write((priv->rssi_correction-62-16)<<1); // wei's magic value is 135, here is 134 @ ch 44
169 		auto_lbt_th = ((priv->rssi_correction-62-16)<<1);
170 		static_lbt_th = priv->drv_xpu_reg_val[DRV_XPU_REG_IDX_LBT_TH];
171 		fpga_lbt_th = (static_lbt_th==0?auto_lbt_th:static_lbt_th);
172 		xpu_api->XPU_REG_LBT_TH_write(fpga_lbt_th);
173 
174 		priv->last_auto_fpga_lbt_th = auto_lbt_th;
175 
176 		if (actual_rx_lo < 2500) {
177 			//priv->slot_time = 20; //20 is default slot time in ERP(OFDM)/11g 2.4G; short one is 9.
178 			//xpu_api->XPU_REG_BAND_CHANNEL_write(BAND_2_4GHZ<<16);
179 			if (priv->band != BAND_2_4GHZ) {
180 				priv->band = BAND_2_4GHZ;
181 				xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
182 			}
183 			// //xpu_api->XPU_REG_RECV_ACK_COUNT_TOP_write( (((45+2)*10)<<16) | 10 ); // high 16 bits to cover sig valid of ACK packet, low 16 bits is adjustment of fcs valid waiting time.  let's add 2us for those device that is really "slow"!
184 			// xpu_api->XPU_REG_RECV_ACK_COUNT_TOP_write( (((45+2+2)*10)<<16) | 10 );//add 2us for longer fir. BUT corrding to FPGA probing test, we do not need this
185 			// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 0 );
186 			// tx_intf_api->TX_INTF_REG_CTS_TOSELF_WAIT_SIFS_TOP_write(((10)*10)<<16);
187 		}
188 		else {
189 			//priv->slot_time = 9; //default slot time of OFDM PHY (OFDM by default means 5GHz)
190 			// xpu_api->XPU_REG_BAND_CHANNEL_write(BAND_5_8GHZ<<16);
191 			if (priv->band != BAND_5_8GHZ) {
192 				priv->band = BAND_5_8GHZ;
193 				xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
194 			}
195 			// //xpu_api->XPU_REG_RECV_ACK_COUNT_TOP_write( (((51+2)*10)<<16) | 10 ); // because 5GHz needs longer SIFS (16 instead of 10), we need 58 instead of 48 for XPU low mac setting.  let's add 2us for those device that is really "slow"!
196 			// xpu_api->XPU_REG_RECV_ACK_COUNT_TOP_write( (((51+2+2)*10)<<16) | 10 );//add 2us for longer fir.  BUT corrding to FPGA probing test, we do not need this
197 			// //xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 60*10 );
198 			// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 50*10 );// for longer fir we need this delay 1us shorter
199 			// tx_intf_api->TX_INTF_REG_CTS_TOSELF_WAIT_SIFS_TOP_write(((16)*10)<<16);
200 		}
201 		//printk("%s ad9361_rf_set_channel %dM rssi_correction %d\n", sdr_compatible_str,conf->chandef.chan->center_freq,priv->rssi_correction);
202 		// //-- use less
203 		//clk_prepare_enable(priv->ad9361_phy->clks[RX_RFPLL]);
204 		//printk("%s ad9361_rf_set_channel tune to %d read back %llu\n", sdr_compatible_str,conf->chandef.chan->center_freq,2*priv->ad9361_phy->state->current_rx_lo_freq);
205 		//ad9361_set_trx_clock_chain_default(priv->ad9361_phy);
206 		//printk("%s ad9361_rf_set_channel tune to %d read back %llu\n", sdr_compatible_str,conf->chandef.chan->center_freq,2*priv->ad9361_phy->state->current_rx_lo_freq);
207 		printk("%s ad9361_rf_set_channel %dM rssi_correction %d (change flag %d) fpga_lbt_th %d (auto %d static %d)\n", sdr_compatible_str,conf->chandef.chan->center_freq,priv->rssi_correction,change_flag,fpga_lbt_th,auto_lbt_th,static_lbt_th);
208 	}
209 }
210 
211 const struct openwifi_rf_ops ad9361_rf_ops = {
212 	.name		= "ad9361",
213 //	.init		= ad9361_rf_init,
214 //	.stop		= ad9361_rf_stop,
215 	.set_chan	= ad9361_rf_set_channel,
216 //	.calc_rssi	= ad9361_rf_calc_rssi,
217 };
218 
219 u16 reverse16(u16 d) {
220 	union u16_byte2 tmp0, tmp1;
221 	tmp0.a = d;
222 	tmp1.c[0] = tmp0.c[1];
223 	tmp1.c[1] = tmp0.c[0];
224 	return(tmp1.a);
225 }
226 
227 u32 reverse32(u32 d) {
228 	union u32_byte4 tmp0, tmp1;
229 	tmp0.a = d;
230 	tmp1.c[0] = tmp0.c[3];
231 	tmp1.c[1] = tmp0.c[2];
232 	tmp1.c[2] = tmp0.c[1];
233 	tmp1.c[3] = tmp0.c[0];
234 	return(tmp1.a);
235 }
236 
237 static int openwifi_init_tx_ring(struct openwifi_priv *priv, int ring_idx)
238 {
239 	struct openwifi_ring *ring = &(priv->tx_ring[ring_idx]);
240 	int i;
241 
242 	ring->stop_flag = 0;
243 	ring->bd_wr_idx = 0;
244 	ring->bd_rd_idx = 0;
245 	ring->bds = kmalloc(sizeof(struct openwifi_buffer_descriptor)*NUM_TX_BD,GFP_KERNEL);
246 	if (ring->bds==NULL) {
247 		printk("%s openwifi_init_tx_ring: WARNING Cannot allocate TX ring\n",sdr_compatible_str);
248 		return -ENOMEM;
249 	}
250 
251 	for (i = 0; i < NUM_TX_BD; i++) {
252 		ring->bds[i].skb_linked=0; // for tx, skb is from upper layer
253 		//at first right after skb allocated, head, data, tail are the same.
254 		ring->bds[i].dma_mapping_addr = 0; // for tx, mapping is done after skb is received from upper layer in tx routine
255 		ring->bds[i].seq_no = 0;
256 	}
257 
258 	return 0;
259 }
260 
261 static void openwifi_free_tx_ring(struct openwifi_priv *priv, int ring_idx)
262 {
263 	struct openwifi_ring *ring = &(priv->tx_ring[ring_idx]);
264 	int i;
265 
266 	ring->stop_flag = 0;
267 	ring->bd_wr_idx = 0;
268 	ring->bd_rd_idx = 0;
269 	for (i = 0; i < NUM_TX_BD; i++) {
270 		if (ring->bds[i].skb_linked == 0 && ring->bds[i].dma_mapping_addr == 0)
271 			continue;
272 		if (ring->bds[i].dma_mapping_addr != 0)
273 			dma_unmap_single(priv->tx_chan->device->dev, ring->bds[i].dma_mapping_addr,ring->bds[i].skb_linked->len, DMA_MEM_TO_DEV);
274 //		if (ring->bds[i].skb_linked!=NULL)
275 //			dev_kfree_skb(ring->bds[i].skb_linked); // only use dev_kfree_skb when there is exception
276 		if ( (ring->bds[i].dma_mapping_addr != 0 && ring->bds[i].skb_linked == 0) ||
277 		     (ring->bds[i].dma_mapping_addr == 0 && ring->bds[i].skb_linked != 0))
278 			printk("%s openwifi_free_tx_ring: WARNING ring %d i %d skb_linked %p dma_mapping_addr %08x\n", sdr_compatible_str,
279 			ring_idx, i, (void*)(ring->bds[i].skb_linked), (unsigned int)(ring->bds[i].dma_mapping_addr));
280 
281 		ring->bds[i].skb_linked=0;
282 		ring->bds[i].dma_mapping_addr = 0;
283 		ring->bds[i].seq_no = 0;
284 	}
285 	if (ring->bds)
286 		kfree(ring->bds);
287 	ring->bds = NULL;
288 }
289 
290 static int openwifi_init_rx_ring(struct openwifi_priv *priv)
291 {
292 	int i;
293 	u8 *pdata_tmp;
294 
295 	priv->rx_cyclic_buf = dma_alloc_coherent(priv->rx_chan->device->dev,RX_BD_BUF_SIZE*NUM_RX_BD,&priv->rx_cyclic_buf_dma_mapping_addr,GFP_KERNEL);
296 	if (!priv->rx_cyclic_buf) {
297 		printk("%s openwifi_init_rx_ring: WARNING dma_alloc_coherent failed!\n", sdr_compatible_str);
298 		dma_free_coherent(priv->rx_chan->device->dev,RX_BD_BUF_SIZE*NUM_RX_BD,priv->rx_cyclic_buf,priv->rx_cyclic_buf_dma_mapping_addr);
299 		return(-1);
300 	}
301 
302 	// Set tsft_low and tsft_high to 0. If they are not zero, it means there is a packet in the buffer by DMA
303 	for (i=0; i<NUM_RX_BD; i++) {
304 		pdata_tmp = priv->rx_cyclic_buf + i*RX_BD_BUF_SIZE; // our header insertion is at the beginning
305 		(*((u32*)(pdata_tmp+0 ))) = 0;
306 		(*((u32*)(pdata_tmp+4 ))) = 0;
307 	}
308 	printk("%s openwifi_init_rx_ring: tsft_low and tsft_high are cleared!\n", sdr_compatible_str);
309 
310 	return 0;
311 }
312 
313 static void openwifi_free_rx_ring(struct openwifi_priv *priv)
314 {
315 	if (priv->rx_cyclic_buf)
316 		dma_free_coherent(priv->rx_chan->device->dev,RX_BD_BUF_SIZE*NUM_RX_BD,priv->rx_cyclic_buf,priv->rx_cyclic_buf_dma_mapping_addr);
317 
318 	priv->rx_cyclic_buf_dma_mapping_addr = 0;
319 	priv->rx_cyclic_buf = 0;
320 }
321 
322 static int rx_dma_setup(struct ieee80211_hw *dev){
323 	struct openwifi_priv *priv = dev->priv;
324 	struct dma_device *rx_dev = priv->rx_chan->device;
325 
326 	priv->rxd = rx_dev->device_prep_dma_cyclic(priv->rx_chan,priv->rx_cyclic_buf_dma_mapping_addr,RX_BD_BUF_SIZE*NUM_RX_BD,RX_BD_BUF_SIZE,DMA_DEV_TO_MEM,DMA_CTRL_ACK|DMA_PREP_INTERRUPT);
327 	if (!(priv->rxd)) {
328 		openwifi_free_rx_ring(priv);
329 		printk("%s rx_dma_setup: WARNING rx_dev->device_prep_dma_cyclic %p\n", sdr_compatible_str, (void*)(priv->rxd));
330 		return(-1);
331 	}
332 	priv->rxd->callback = 0;
333 	priv->rxd->callback_param = 0;
334 
335 	priv->rx_cookie = priv->rxd->tx_submit(priv->rxd);
336 
337 	if (dma_submit_error(priv->rx_cookie)) {
338 		printk("%s rx_dma_setup: WARNING dma_submit_error(rx_cookie) %d\n", sdr_compatible_str, (u32)(priv->rx_cookie));
339 		return(-1);
340 	}
341 
342 	dma_async_issue_pending(priv->rx_chan);
343 	return(0);
344 }
345 
346 static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id)
347 {
348 	struct ieee80211_hw *dev = dev_id;
349 	struct openwifi_priv *priv = dev->priv;
350 	struct ieee80211_rx_status rx_status = {0};
351 	struct sk_buff *skb;
352 	struct ieee80211_hdr *hdr;
353 	u32 addr1_low32=0, addr2_low32=0, addr3_low32=0, len, rate_idx, tsft_low, tsft_high, loop_count=0;//, fc_di;
354 	bool ht_flag, short_gi, ht_aggr, ht_aggr_last;
355 	// u32 dma_driver_buf_idx_mod;
356 	u8 *pdata_tmp, fcs_ok;//, target_buf_idx;//, phy_rx_sn_hw;
357 	s8 signal;
358 	u16 agc_status_and_pkt_exist_flag, rssi_val, addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0;
359 	bool content_ok = false, len_overflow = false;
360 
361 #ifdef USE_NEW_RX_INTERRUPT
362 	int i;
363 	spin_lock(&priv->lock);
364 	for (i=0; i<NUM_RX_BD; i++) {
365 		pdata_tmp = priv->rx_cyclic_buf + i*RX_BD_BUF_SIZE;
366 		agc_status_and_pkt_exist_flag = (*((u16*)(pdata_tmp+10))); //check rx_intf_pl_to_m_axis.v. FPGA TODO: add pkt exist 1bit flag next to gpio_status_lock_by_sig_valid
367 		if ( agc_status_and_pkt_exist_flag==0 ) // no packet in the buffer
368 			continue;
369 #else
370 	static u8 target_buf_idx_old = 0;
371 	spin_lock(&priv->lock);
372 	while(1) { // loop all rx buffers that have new rx packets
373 		pdata_tmp = priv->rx_cyclic_buf + target_buf_idx_old*RX_BD_BUF_SIZE; // our header insertion is at the beginning
374 		agc_status_and_pkt_exist_flag = (*((u16*)(pdata_tmp+10)));
375 		if ( agc_status_and_pkt_exist_flag==0 ) // no packet in the buffer
376 			break;
377 #endif
378 
379 		tsft_low =     (*((u32*)(pdata_tmp+0 )));
380 		tsft_high =    (*((u32*)(pdata_tmp+4 )));
381 		rssi_val =     (*((u16*)(pdata_tmp+8 )));
382 		len =          (*((u16*)(pdata_tmp+12)));
383 
384 		len_overflow = (len>(RX_BD_BUF_SIZE-16)?true:false);
385 
386 		rate_idx =     (*((u16*)(pdata_tmp+14)));
387 		ht_flag  =     ((rate_idx&0x10)!=0);
388 		short_gi =     ((rate_idx&0x20)!=0);
389 		ht_aggr  =     (ht_flag & ((rate_idx&0x40)!=0));
390 		ht_aggr_last = (ht_flag & ((rate_idx&0x80)!=0));
391 		rate_idx =     (rate_idx&0x1F);
392 
393 		fcs_ok = ( len_overflow?0:(*(( u8*)(pdata_tmp+16+len-1))) );
394 
395 		//phy_rx_sn_hw = (fcs_ok&(NUM_RX_BD-1));
396 		// phy_rx_sn_hw = (fcs_ok&0x7f);//0x7f is FPGA limitation
397 		// dma_driver_buf_idx_mod = (state.residue&0x7f);
398 		fcs_ok = ((fcs_ok&0x80)!=0);
399 
400 		if ( (len>=14 && (!len_overflow)) && (rate_idx>=8 && rate_idx<=23)) {
401 			// if ( phy_rx_sn_hw!=dma_driver_buf_idx_mod) {
402 			// 	printk("%s openwifi_rx_interrupt: WARNING sn %d next buf_idx %d!\n", sdr_compatible_str,phy_rx_sn_hw,dma_driver_buf_idx_mod);
403 			// }
404 			content_ok = true;
405 		} else {
406 			printk("%s openwifi_rx_interrupt: WARNING content!\n", sdr_compatible_str);
407 			content_ok = false;
408 		}
409 
410 		rssi_val = (rssi_val>>1);
411 		if ( (rssi_val+128)<priv->rssi_correction )
412 			signal = -128;
413 		else
414 			signal = rssi_val - priv->rssi_correction;
415 
416 		// fc_di =        (*((u32*)(pdata_tmp+16)));
417 		// addr1_high16 = (*((u16*)(pdata_tmp+16+4)));
418 		// addr1_low32  = (*((u32*)(pdata_tmp+16+4+2)));
419 		// addr2_high16 = (*((u16*)(pdata_tmp+16+6+4)));
420 		// addr2_low32  = (*((u32*)(pdata_tmp+16+6+4+2)));
421 		// addr3_high16 = (*((u16*)(pdata_tmp+16+12+4)));
422 		// addr3_low32  = (*((u32*)(pdata_tmp+16+12+4+2)));
423 		if ( (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&2) || ( (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&1) && fcs_ok==0 ) ) {
424 			hdr = (struct ieee80211_hdr *)(pdata_tmp+16);
425 			addr1_low32  = *((u32*)(hdr->addr1+2));
426 			addr1_high16 = *((u16*)(hdr->addr1));
427 			if (len>=20) {
428 				addr2_low32  = *((u32*)(hdr->addr2+2));
429 				addr2_high16 = *((u16*)(hdr->addr2));
430 			}
431 			if (len>=26) {
432 				addr3_low32  = *((u32*)(hdr->addr3+2));
433 				addr3_high16 = *((u16*)(hdr->addr3));
434 			}
435 			if (len>=28)
436 				sc = hdr->seq_ctrl;
437 
438 			if ( (addr1_low32!=0xffffffff || addr1_high16!=0xffff) || (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&4) )
439 				printk("%s openwifi_rx_interrupt:%4dbytes ht%d aggr%d/%d sgi%d %3dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x fcs%d buf_idx%d %ddBm\n", sdr_compatible_str,
440 					len, ht_flag, ht_aggr, ht_aggr_last, short_gi, wifi_rate_table[rate_idx], hdr->frame_control, hdr->duration_id,
441 					reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32),
442 #ifdef USE_NEW_RX_INTERRUPT
443 					sc, fcs_ok, i, signal);
444 #else
445 					sc, fcs_ok, target_buf_idx_old, signal);
446 #endif
447 		}
448 
449 		// priv->phy_rx_sn_hw_old = phy_rx_sn_hw;
450 		if (content_ok) {
451 			skb = dev_alloc_skb(len);
452 			if (skb) {
453 				skb_put_data(skb,pdata_tmp+16,len);
454 
455 				rx_status.antenna = 0;
456 				// def in ieee80211_rate openwifi_rates 0~11. 0~3 11b(1M~11M), 4~11 11a/g(6M~54M)
457 				rx_status.rate_idx = wifi_rate_table_mapping[rate_idx];
458 				rx_status.signal = signal;
459 				rx_status.freq = dev->conf.chandef.chan->center_freq;
460 				rx_status.band = dev->conf.chandef.chan->band;
461 				rx_status.mactime = ( ( (u64)tsft_low ) | ( ((u64)tsft_high)<<32 ) );
462 				rx_status.flag |= RX_FLAG_MACTIME_START;
463 				if (!fcs_ok)
464 					rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
465 				if (rate_idx <= 15)
466 					rx_status.encoding = RX_ENC_LEGACY;
467 				else
468 					rx_status.encoding = RX_ENC_HT;
469 				rx_status.bw = RATE_INFO_BW_20;
470 				if (short_gi)
471 					rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
472 				if(ht_aggr)
473 				{
474 					rx_status.ampdu_reference = priv->ampdu_reference;
475 					rx_status.flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
476 					if (ht_aggr_last)
477 						rx_status.flag |= RX_FLAG_AMPDU_IS_LAST;
478 				}
479 
480 				memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); // put rx_status into skb->cb, from now on skb->cb is not dma_dsts any more.
481 				ieee80211_rx_irqsafe(dev, skb); // call mac80211 function
482 			} else
483 				printk("%s openwifi_rx_interrupt: WARNING dev_alloc_skb failed!\n", sdr_compatible_str);
484 
485 			if(ht_aggr_last)
486 				priv->ampdu_reference++;
487 		}
488 		(*((u16*)(pdata_tmp+10))) = 0; // clear the field (set by rx_intf_pl_to_m_axis.v) to indicate the packet has been processed
489 		loop_count++;
490 #ifndef USE_NEW_RX_INTERRUPT
491 		target_buf_idx_old=((target_buf_idx_old+1)&(NUM_RX_BD-1));
492 #endif
493 	}
494 
495 	if ( loop_count!=1 && (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&1) )
496 		printk("%s openwifi_rx_interrupt: WARNING loop_count %d\n", sdr_compatible_str,loop_count);
497 
498 // openwifi_rx_interrupt_out:
499 	spin_unlock(&priv->lock);
500 	return IRQ_HANDLED;
501 }
502 
503 static irqreturn_t openwifi_tx_interrupt(int irq, void *dev_id)
504 {
505 	struct ieee80211_hw *dev = dev_id;
506 	struct openwifi_priv *priv = dev->priv;
507 	struct openwifi_ring *ring;
508 	struct sk_buff *skb;
509 	struct ieee80211_tx_info *info;
510 	u32 reg_val1, hw_queue_len, reg_val2, prio, queue_idx, dma_fifo_no_room_flag, num_slot_random, cw, loop_count=0;
511 	u16 seq_no, pkt_cnt, blk_ack_ssn, start_idx;
512 	u8 nof_retx=-1, last_bd_rd_idx, i;
513 	u64 blk_ack_bitmap;
514 	// u16 prio_rd_idx_store[64]={0};
515 	bool tx_fail=false;
516 
517 	spin_lock(&priv->lock);
518 
519 	while(1) { // loop all packets that have been sent by FPGA
520 		reg_val1 = tx_intf_api->TX_INTF_REG_PKT_INFO1_read();
521         reg_val2 = tx_intf_api->TX_INTF_REG_PKT_INFO2_read();
522 		blk_ack_bitmap = (tx_intf_api->TX_INTF_REG_PKT_INFO3_read() | ((u64)tx_intf_api->TX_INTF_REG_PKT_INFO4_read())<<32);
523 
524 		if (reg_val1!=0xFFFFFFFF) {
525 			nof_retx = (reg_val1&0xF);
526 			last_bd_rd_idx = ((reg_val1>>5)&(NUM_TX_BD-1));
527 			prio = ((reg_val1>>17)&0x3);
528 			num_slot_random = ((reg_val1>>19)&0x1FF);
529 			//num_slot_random = ((0xFF80000 &reg_val1)>>(2+5+NUM_BIT_MAX_PHY_TX_SN+NUM_BIT_MAX_NUM_HW_QUEUE));
530 			cw = ((reg_val1>>28)&0xF);
531 			//cw = ((0xF0000000 & reg_val1) >> 28);
532 			if(cw > 10) {
533 				cw = 10 ;
534 				num_slot_random += 512 ;
535 			}
536 			pkt_cnt = (reg_val2&0x3F);
537 			blk_ack_ssn = ((reg_val2>>6)&0xFFF);
538 
539 			ring = &(priv->tx_ring[prio]);
540 
541 			if ( ring->stop_flag == 1) {
542 				// Wake up Linux queue if FPGA and driver ring have room
543 				queue_idx = ((reg_val1>>15)&(MAX_NUM_HW_QUEUE-1));
544 				dma_fifo_no_room_flag = tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read();
545 				hw_queue_len = tx_intf_api->TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read();
546 
547 				if ( ((dma_fifo_no_room_flag>>queue_idx)&1)==0 && (NUM_TX_BD-((hw_queue_len>>(queue_idx*8))&0xFF))>=RING_ROOM_THRESHOLD ) {
548 					// printk("%s openwifi_tx_interrupt: WARNING ieee80211_wake_queue loop %d call %d\n", sdr_compatible_str, loop_count, priv->call_counter);
549 					printk("%s openwifi_tx_interrupt: WARNING ieee80211_wake_queue prio %d queue %d no room flag %x hw queue len %08x wr %d rd %d\n", sdr_compatible_str,
550 					prio, queue_idx, dma_fifo_no_room_flag, hw_queue_len, ring->bd_wr_idx, last_bd_rd_idx);
551 					ieee80211_wake_queue(dev, prio);
552 					ring->stop_flag = 0;
553 				}
554 			}
555 
556 			for(i = 1; i <= pkt_cnt; i++)
557 			{
558 				ring->bd_rd_idx = (last_bd_rd_idx + i - pkt_cnt + 64)%64;
559 				seq_no = ring->bds[ring->bd_rd_idx].seq_no;
560 				skb = ring->bds[ring->bd_rd_idx].skb_linked;
561 
562 				dma_unmap_single(priv->tx_chan->device->dev,ring->bds[ring->bd_rd_idx].dma_mapping_addr,
563 						skb->len, DMA_MEM_TO_DEV);
564 
565 				info = IEEE80211_SKB_CB(skb);
566 				ieee80211_tx_info_clear_status(info);
567 
568 				// Aggregation packet
569 				if(pkt_cnt > 1)
570 				{
571 					start_idx = (seq_no>=blk_ack_ssn) ? (seq_no-blk_ack_ssn) : (seq_no+((~blk_ack_ssn+1)&0x0FFF));
572 					tx_fail = (((blk_ack_bitmap>>start_idx)&0x1)==0);
573 					info->flags |= IEEE80211_TX_STAT_AMPDU;
574 					info->status.ampdu_len = 1;
575 					info->status.ampdu_ack_len = (tx_fail == true) ? 0 : 1;
576 
577 					skb_pull(skb, LEN_MPDU_DELIM);
578 					//skb_trim(skb, num_byte_pad_skb);
579 				}
580 				// Normal packet
581 				else
582 				{
583 					tx_fail = ((blk_ack_bitmap&0x1)==0);
584 					info->flags &= (~IEEE80211_TX_CTL_AMPDU);
585 				}
586 
587 				if (tx_fail == false)
588 					info->flags |= IEEE80211_TX_STAT_ACK;
589 
590 				info->status.rates[0].count = nof_retx + 1; //according to our test, the 1st rate is the most important. we only do retry on the 1st rate
591 				info->status.rates[1].idx = -1;
592 				info->status.rates[2].idx = -1;
593 				info->status.rates[3].idx = -1;//in mac80211.h: #define IEEE80211_TX_MAX_RATES	4
594 
595 				if ( tx_fail && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&1) )
596 					printk("%s openwifi_tx_interrupt: WARNING pkt_no %d/%d tx_result [nof_retx %d pass %d] prio%d wr%d rd%d\n", sdr_compatible_str, i, pkt_cnt, nof_retx+1, !tx_fail, prio, ring->bd_wr_idx, ring->bd_rd_idx);
597 				if ( ( (!(info->flags & IEEE80211_TX_CTL_NO_ACK))||(priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG]&4) ) && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&2) )
598 					printk("%s openwifi_tx_interrupt: tx_result [nof_retx %d pass %d] prio%d wr%d rd%d num_rand_slot %d cw %d \n", sdr_compatible_str, nof_retx+1, !tx_fail, prio, ring->bd_wr_idx, ring->bd_rd_idx, num_slot_random, cw);
599 
600 				ieee80211_tx_status_irqsafe(dev, skb);
601 			}
602 
603 			loop_count++;
604 
605 			// printk("%s openwifi_tx_interrupt: loop %d prio %d rd %d\n", sdr_compatible_str, loop_count, prio, ring->bd_rd_idx);
606 
607 		} else
608 			break;
609 	}
610 	if ( loop_count!=1 && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&1) )
611 		printk("%s openwifi_tx_interrupt: WARNING loop_count %d\n", sdr_compatible_str, loop_count);
612 
613 	spin_unlock(&priv->lock);
614 	return IRQ_HANDLED;
615 }
616 
617 u32 crc_table[16] = {0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0, 0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320, 0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190, 0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000};
618 u32 gen_mpdu_crc(u8 *data_in, u32 num_bytes)
619 {
620 	u32 i, crc = 0;
621 	u8 idx;
622 	for( i = 0; i < num_bytes; i++)
623 	{
624 		idx = (crc & 0x0F) ^ (data_in[i] & 0x0F);
625 		crc = (crc >> 4) ^ crc_table[idx];
626 
627 		idx = (crc & 0x0F) ^ ((data_in[i] >> 4) & 0x0F);
628 		crc = (crc >> 4) ^ crc_table[idx];
629 	}
630 
631 	return crc;
632 }
633 
634 u8 gen_mpdu_delim_crc(u16 m)
635 {
636 	u8 i, temp, c[8] = {1, 1, 1, 1, 1, 1, 1, 1}, mpdu_delim_crc;
637 
638 	for (i = 0; i < 16; i++)
639 	{
640 		temp = c[7] ^ ((m >> i) & 0x01);
641 
642 		c[7] = c[6];
643 		c[6] = c[5];
644 		c[5] = c[4];
645 		c[4] = c[3];
646 		c[3] = c[2];
647 		c[2] = c[1] ^ temp;
648 		c[1] = c[0] ^ temp;
649 		c[0] = temp;
650 	}
651 	mpdu_delim_crc = ((~c[7] & 0x01) << 0) | ((~c[6] & 0x01) << 1) | ((~c[5] & 0x01) << 2) | ((~c[4] & 0x01) << 3) | ((~c[3] & 0x01) << 4) | ((~c[2] & 0x01) << 5) | ((~c[1] & 0x01) << 6) | ((~c[0] & 0x01) << 7);
652 
653 	return mpdu_delim_crc;
654 }
655 
656 static inline struct gpio_led_data * //please align with the implementation in leds-gpio.c
657 			cdev_to_gpio_led_data(struct led_classdev *led_cdev)
658 {
659 	return container_of(led_cdev, struct gpio_led_data, cdev);
660 }
661 
662 static void openwifi_tx(struct ieee80211_hw *dev,
663 		       struct ieee80211_tx_control *control,
664 		       struct sk_buff *skb)
665 {
666 	struct openwifi_priv *priv = dev->priv;
667 	unsigned long flags;
668 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
669 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
670 	struct openwifi_ring *ring = NULL;
671 	dma_addr_t dma_mapping_addr;
672 	unsigned int prio=0, i;
673 	u32 num_dma_symbol, len_mpdu = 0, len_mpdu_delim_pad = 0, num_dma_byte, len_psdu, num_byte_pad;
674 	u32 rate_signal_value,rate_hw_value=0,ack_flag;
675 	u32 pkt_need_ack=0, addr1_low32=0, addr2_low32=0, addr3_low32=0, queue_idx=2, tx_config, cts_reg, phy_hdr_config;//, openofdm_state_history;
676 	u16 addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0, cts_duration=0, cts_rate_hw_value=0, cts_rate_signal_value=0, sifs, ack_duration=0, traffic_pkt_duration;
677 	u8 fc_flag,fc_type,fc_subtype,retry_limit_raw=0,use_short_gi=0,*dma_buf,retry_limit_hw_value,rc_flags,*qos_hdr;
678 	bool use_rts_cts, use_cts_protect=false, ht_aggr_start=false, use_ht_rate=false, use_ht_aggr=false, addr_flag, cts_use_traffic_rate=false, force_use_cts_protect=false;
679 	__le16 frame_control,duration_id;
680 	u32 dma_fifo_no_room_flag, hw_queue_len;
681 	enum dma_status status;
682 
683 	static u32 addr1_low32_prev = -1, rate_hw_value_prev = -1, pkt_need_ack_prev = -1;
684 	static u16 addr1_high16_prev = -1;
685 	static __le16 duration_id_prev = -1;
686 	static unsigned int prio_prev = -1;
687 	static u8 retry_limit_raw_prev = -1;
688 	static u8 use_short_gi_prev = -1;
689 
690 	// static bool led_status=0;
691 	// struct gpio_led_data *led_dat = cdev_to_gpio_led_data(priv->led[3]);
692 
693 	// if ( (priv->phy_tx_sn&7) ==0 ) {
694 	// 	openofdm_state_history = openofdm_rx_api->OPENOFDM_RX_REG_STATE_HISTORY_read();
695 	// 	if (openofdm_state_history!=openofdm_state_history_old){
696 	// 		led_status = (~led_status);
697 	// 		openofdm_state_history_old = openofdm_state_history;
698 	// 		gpiod_set_value(led_dat->gpiod, led_status);
699 	// 	}
700 	// }
701 
702 	if (test_mode==1){
703 		printk("%s openwifi_tx: WARNING test_mode==1\n", sdr_compatible_str);
704 		goto openwifi_tx_early_out;
705 	}
706 
707 	if (skb->data_len>0) {// more data are not in linear data area skb->data
708 		printk("%s openwifi_tx: WARNING skb->data_len>0\n", sdr_compatible_str);
709 		goto openwifi_tx_early_out;
710 	}
711 
712 	len_mpdu = skb->len;
713 
714 	// get Linux priority/queue setting info and target mac address
715 	prio = skb_get_queue_mapping(skb);
716 	addr1_low32  = *((u32*)(hdr->addr1+2));
717 	ring = &(priv->tx_ring[prio]);
718 
719 	// -------------- DO your idea here! Map Linux/SW "prio" to hardware "queue_idx" -----------
720 	if (priv->slice_idx == 0xFFFFFFFF) {// use Linux default prio setting, if there isn't any slice config
721 		queue_idx = prio;
722 	} else {// customized prio to queue_idx mapping
723 		//if (fc_type==2 && fc_subtype==0 && (!addr_flag)) { // for unicast data packet only
724 		// check current packet belonging to which slice/hw-queue
725 			for (i=0; i<MAX_NUM_HW_QUEUE; i++) {
726 				if ( priv->dest_mac_addr_queue_map[i] == addr1_low32 ) {
727 					break;
728 				}
729 			}
730 		//}
731 		queue_idx = (i>=MAX_NUM_HW_QUEUE?2:i); // if no address is hit, use FPGA queue 2. because the queue 2 is the longest.
732 	}
733 	// -------------------- end of Map Linux/SW "prio" to hardware "queue_idx" ------------------
734 	// get other info from packet header
735 	addr1_high16 = *((u16*)(hdr->addr1));
736 	if (len_mpdu>=20) {
737 		addr2_low32  = *((u32*)(hdr->addr2+2));
738 		addr2_high16 = *((u16*)(hdr->addr2));
739 	}
740 	if (len_mpdu>=26) {
741 		addr3_low32  = *((u32*)(hdr->addr3+2));
742 		addr3_high16 = *((u16*)(hdr->addr3));
743 	}
744 
745 	duration_id = hdr->duration_id;
746 	frame_control=hdr->frame_control;
747 	ack_flag = (info->flags&IEEE80211_TX_CTL_NO_ACK);
748 	fc_type = ((frame_control)>>2)&3;
749 	fc_subtype = ((frame_control)>>4)&0xf;
750 	fc_flag = ( fc_type==2 || fc_type==0 || (fc_type==1 && (fc_subtype==8 || fc_subtype==9 || fc_subtype==10) ) );
751 	//if it is broadcasting or multicasting addr
752 	addr_flag = ( (addr1_low32==0 && addr1_high16==0) ||
753 	              (addr1_low32==0xFFFFFFFF && addr1_high16==0xFFFF) ||
754 				  (addr1_high16==0x3333) ||
755 				  (addr1_high16==0x0001 && hdr->addr1[2]==0x5E)  );
756 	if ( fc_flag && ( !addr_flag ) && (!ack_flag) ) { // unicast data frame
757 		pkt_need_ack = 1; //FPGA need to wait ACK after this pkt sent
758 	} else {
759 		pkt_need_ack = 0;
760 	}
761 
762 	// get Linux rate (MCS) setting
763 	rate_hw_value = ieee80211_get_tx_rate(dev, info)->hw_value;
764 	//rate_hw_value = 10; //4:6M, 5:9M, 6:12M, 7:18M, 8:24M, 9:36M, 10:48M, 11:54M
765 	if (priv->drv_tx_reg_val[DRV_TX_REG_IDX_RATE]>0 && fc_type==2 && (!addr_flag)) //rate override command
766 		rate_hw_value = priv->drv_tx_reg_val[DRV_TX_REG_IDX_RATE];
767 
768 	retry_limit_raw = info->control.rates[0].count;
769 
770 	rc_flags = info->control.rates[0].flags;
771 	use_rts_cts = ((rc_flags&IEEE80211_TX_RC_USE_RTS_CTS)!=0);
772 	use_cts_protect = ((rc_flags&IEEE80211_TX_RC_USE_CTS_PROTECT)!=0);
773 	use_ht_rate = ((rc_flags&IEEE80211_TX_RC_MCS)!=0);
774 	use_short_gi = ((rc_flags&IEEE80211_TX_RC_SHORT_GI)!=0);
775 	use_ht_aggr = ((info->flags&IEEE80211_TX_CTL_AMPDU)!=0);
776 
777 	if (use_rts_cts)
778 		printk("%s openwifi_tx: WARNING sn %d use_rts_cts is not supported!\n", sdr_compatible_str, ring->bd_wr_idx);
779 
780 	if (use_cts_protect) {
781 		cts_rate_hw_value = ieee80211_get_rts_cts_rate(dev, info)->hw_value;
782 		cts_duration = le16_to_cpu(ieee80211_ctstoself_duration(dev,info->control.vif,len_mpdu,info));
783 	} else if (force_use_cts_protect) { // could override mac80211 setting here.
784 		cts_rate_hw_value = 4; //wifi_mcs_table_11b_force_up[] translate it to 1011(6M)
785 		sifs = (priv->actual_rx_lo<2500?10:16);
786 		if (pkt_need_ack)
787 			ack_duration = 44;//assume the ack we wait use 6Mbps: 4*ceil((22+14*8)/24) + 20(preamble+SIGNAL)
788 		traffic_pkt_duration = 20 + 4*(((22+len_mpdu*8)/wifi_n_dbps_table[rate_hw_value])+1);
789 		cts_duration = traffic_pkt_duration + sifs + pkt_need_ack*(sifs+ack_duration);
790 	}
791 
792 // this is 11b stuff
793 //	if (info->flags&IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
794 //		printk("%s openwifi_tx: WARNING IEEE80211_TX_RC_USE_SHORT_PREAMBLE\n", sdr_compatible_str);
795 
796 	if (len_mpdu>=28) {
797 		if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
798 			if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
799 				priv->seqno += 0x10;
800 			hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
801 			hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
802 		}
803 		sc = hdr->seq_ctrl;
804 	}
805 
806 	if ( ( (!addr_flag)||(priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG]&4) ) && (priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG]&2) )
807 		printk("%s openwifi_tx: %4dbytes ht%d aggr%d %3dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x flag%08x retr%d ack%d prio%d q%d wr%d rd%d\n", sdr_compatible_str,
808 			len_mpdu, (use_ht_rate == false ? 0 : 1), (use_ht_aggr == false ? 0 : 1), (use_ht_rate == false ? wifi_rate_all[rate_hw_value] : wifi_rate_all[rate_hw_value + 12]),frame_control,duration_id,
809 			reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32),
810 			sc, info->flags, retry_limit_raw, pkt_need_ack, prio, queue_idx,
811 			// use_rts_cts,use_cts_protect|force_use_cts_protect,wifi_rate_all[cts_rate_hw_value],cts_duration,
812 			ring->bd_wr_idx,ring->bd_rd_idx);
813 
814 		// printk("%s openwifi_tx: rate&try: %d %d %03x; %d %d %03x; %d %d %03x; %d %d %03x\n", sdr_compatible_str,
815 		// 	info->status.rates[0].idx,info->status.rates[0].count,info->status.rates[0].flags,
816 		// 	info->status.rates[1].idx,info->status.rates[1].count,info->status.rates[1].flags,
817 		// 	info->status.rates[2].idx,info->status.rates[2].count,info->status.rates[2].flags,
818 		// 	info->status.rates[3].idx,info->status.rates[3].count,info->status.rates[3].flags);
819 
820 	// -----------end of preprocess some info from header and skb----------------
821 
822 	// /* HW will perform RTS-CTS when only RTS flags is set.
823 	//  * HW will perform CTS-to-self when both RTS and CTS flags are set.
824 	//  * RTS rate and RTS duration will be used also for CTS-to-self.
825 	//  */
826 	// if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
827 	// 	tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
828 	// 	rts_duration = ieee80211_rts_duration(dev, priv->vif[0], // assume all vif have the same config
829 	// 					len_mpdu, info);
830 	// 	printk("%s openwifi_tx: rc_flags & IEEE80211_TX_RC_USE_RTS_CTS\n", sdr_compatible_str);
831 	// } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
832 	// 	tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
833 	// 	rts_duration = ieee80211_ctstoself_duration(dev, priv->vif[0], // assume all vif have the same config
834 	// 					len_mpdu, info);
835 	// 	printk("%s openwifi_tx: rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT\n", sdr_compatible_str);
836 	// }
837 
838 	if(use_ht_aggr)
839 	{
840 		qos_hdr = ieee80211_get_qos_ctl(hdr);
841 		if(ieee80211_is_data_qos(frame_control) == false || qos_hdr[0] != priv->tid)
842 		{
843 			printk("%s openwifi_tx: WARNING packet is either not qos or tid %u does not match registered tid %u\n", sdr_compatible_str, qos_hdr[0], priv->tid);
844 			goto openwifi_tx_early_out;
845 		}
846 
847 		// psdu = [ MPDU DEL | MPDU | CRC | MPDU padding ]
848 		len_mpdu_delim_pad = ((len_mpdu + LEN_PHY_CRC)%4 == 0) ? 0 :(4 - (len_mpdu + LEN_PHY_CRC)%4);
849 		len_psdu = LEN_MPDU_DELIM + len_mpdu + LEN_PHY_CRC + len_mpdu_delim_pad;
850 
851 		if( (addr1_low32 != addr1_low32_prev) || (addr1_high16 != addr1_high16_prev) || (duration_id != duration_id_prev) ||
852 			(rate_hw_value != rate_hw_value_prev) || (use_short_gi != use_short_gi_prev) ||
853 			(prio != prio_prev) || (retry_limit_raw != retry_limit_raw_prev) || (pkt_need_ack != pkt_need_ack_prev) )
854 		{
855 			addr1_low32_prev = addr1_low32;
856 			addr1_high16_prev = addr1_high16;
857 			duration_id_prev = duration_id;
858 			rate_hw_value_prev = rate_hw_value;
859 			use_short_gi_prev = use_short_gi;
860 			prio_prev = prio;
861 			retry_limit_raw_prev = retry_limit_raw;
862 			pkt_need_ack_prev = pkt_need_ack;
863 
864 			ht_aggr_start = true;
865 		}
866 	}
867 	else
868 	{
869 		// psdu = [ MPDU ]
870 		len_psdu = len_mpdu;
871 
872 		addr1_low32_prev = -1;
873 		addr1_high16_prev = -1;
874 		duration_id_prev = -1;
875 		use_short_gi_prev = -1;
876 		rate_hw_value_prev = -1;
877 		prio_prev = -1;
878 		retry_limit_raw_prev = -1;
879 		pkt_need_ack_prev = -1;
880 	}
881 	num_dma_symbol = (len_psdu>>TX_INTF_NUM_BYTE_PER_DMA_SYMBOL_IN_BITS) + ((len_psdu&(TX_INTF_NUM_BYTE_PER_DMA_SYMBOL-1))!=0);
882 
883 	// check whether the packet is bigger than DMA buffer size
884 	num_dma_byte = (num_dma_symbol<<TX_INTF_NUM_BYTE_PER_DMA_SYMBOL_IN_BITS);
885 	if (num_dma_byte > TX_BD_BUF_SIZE) {
886 		printk("%s openwifi_tx: WARNING sn %d num_dma_byte > TX_BD_BUF_SIZE\n", sdr_compatible_str, ring->bd_wr_idx);
887 		goto openwifi_tx_early_out;
888 	}
889 
890 	// Copy MPDU delimiter and padding into sk_buff
891 	if(use_ht_aggr)
892 	{
893 		// when skb does not have enough headroom, skb_push will cause kernel panic. headroom needs to be extended if necessary
894 		if (skb_headroom(skb)<LEN_MPDU_DELIM) {
895 			struct sk_buff *skb_new; // in case original skb headroom is not enough to host MPDU delimiter
896 			printk("%s openwifi_tx: WARNING sn %d skb_headroom(skb)<LEN_MPDU_DELIM\n", sdr_compatible_str, ring->bd_wr_idx);
897 			if ((skb_new = skb_realloc_headroom(skb, LEN_MPDU_DELIM)) == NULL) {
898 				printk("%s openwifi_tx: WARNING sn %d skb_realloc_headroom failed!\n", sdr_compatible_str, ring->bd_wr_idx);
899 				goto openwifi_tx_early_out;
900 			}
901 			if (skb->sk != NULL)
902 				skb_set_owner_w(skb_new, skb->sk);
903 			dev_kfree_skb(skb);
904 			skb = skb_new;
905 		}
906 		skb_push( skb, LEN_MPDU_DELIM );
907 		dma_buf = skb->data;
908 
909 		// fill in MPDU delimiter
910 		*((u16*)(dma_buf+0)) = ((u16)(len_mpdu+LEN_PHY_CRC) << 4) & 0xFFF0;
911 		*((u8 *)(dma_buf+2)) = gen_mpdu_delim_crc(*((u16 *)dma_buf));
912 		*((u8 *)(dma_buf+3)) = 0x4e;
913 
914 		// Extend sk_buff to hold CRC + MPDU padding + empty MPDU delimiter
915 		num_byte_pad = num_dma_byte - (LEN_MPDU_DELIM + len_mpdu);
916 		if (skb_tailroom(skb)<num_byte_pad) {
917 			printk("%s openwifi_tx: WARNING sn %d skb_tailroom(skb)<num_byte_pad!\n", sdr_compatible_str, ring->bd_wr_idx);
918 			goto openwifi_tx_early_out;
919 		}
920 		skb_put( skb, num_byte_pad );
921 
922 		// fill in MPDU CRC
923 		*((u32*)(dma_buf+LEN_MPDU_DELIM+len_mpdu)) = gen_mpdu_crc(dma_buf+LEN_MPDU_DELIM, len_mpdu);
924 
925 		// fill in MPDU delimiter padding
926 		memset(dma_buf+LEN_MPDU_DELIM+len_mpdu+LEN_PHY_CRC, 0, len_mpdu_delim_pad);
927 
928 		// num_dma_byte is on 8-byte boundary and len_psdu is on 4 byte boundary.
929 		// If they have different lengths, add "empty MPDU delimiter" for alignment
930 		if(num_dma_byte == len_psdu + 4)
931 		{
932 			*((u32*)(dma_buf+len_psdu)) = 0x4e140000;
933 			len_psdu = num_dma_byte;
934 		}
935 	}
936 	else
937 	{
938 		// Extend sk_buff to hold padding
939 		num_byte_pad = num_dma_byte - len_mpdu;
940 		if (skb_tailroom(skb)<num_byte_pad) {
941 			printk("%s openwifi_tx: WARNING sn %d skb_tailroom(skb)<num_byte_pad!\n", sdr_compatible_str, ring->bd_wr_idx);
942 			goto openwifi_tx_early_out;
943 		}
944 		skb_put( skb, num_byte_pad );
945 
946 		dma_buf = skb->data;
947 	}
948 //	for(i = 0; i <= num_dma_symbol; i++)
949 //		printk("%16llx\n", (*(u64*)(&(dma_buf[i*8]))));
950 
951 	rate_signal_value = (use_ht_rate ? rate_hw_value : wifi_mcs_table_11b_force_up[rate_hw_value]);
952 
953 	retry_limit_hw_value = ( retry_limit_raw==0?0:((retry_limit_raw - 1)&0xF) );
954 
955 	cts_rate_signal_value = wifi_mcs_table_11b_force_up[cts_rate_hw_value];
956 	cts_reg = ((use_cts_protect|force_use_cts_protect)<<31 | cts_use_traffic_rate<<30 | cts_duration<<8 | cts_rate_signal_value<<4 | rate_signal_value);
957 	tx_config = ( prio<<26 | ring->bd_wr_idx<<20 | queue_idx<<18 | retry_limit_hw_value<<14 | pkt_need_ack<<13 | (len_mpdu+LEN_PHY_CRC) );
958 	phy_hdr_config = ( ht_aggr_start<<20 | rate_hw_value<<16 | use_ht_rate<<15 | use_short_gi<<14 | use_ht_aggr<<13 | len_psdu );
959 
960 	/* We must be sure that tx_flags is written last because the HW
961 	 * looks at it to check if the rest of data is valid or not
962 	 */
963 	//wmb();
964 	// entry->flags = cpu_to_le32(tx_flags);
965 	/* We must be sure this has been written before following HW
966 	 * register write, because this write will make the HW attempts
967 	 * to DMA the just-written data
968 	 */
969 	//wmb();
970 
971 	spin_lock_irqsave(&priv->lock, flags); // from now on, we'd better avoid interrupt because ring->stop_flag is shared with interrupt
972 
973 	// -------------check whether FPGA dma fifo and queue (queue_idx) has enough room-------------
974 	dma_fifo_no_room_flag = tx_intf_api->TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read();
975 	hw_queue_len = tx_intf_api->TX_INTF_REG_QUEUE_FIFO_DATA_COUNT_read();
976 	if ( ((dma_fifo_no_room_flag>>queue_idx)&1) || ((NUM_TX_BD-((hw_queue_len>>(queue_idx*8))&0xFF))<RING_ROOM_THRESHOLD)  || ring->stop_flag==1 ) {
977 		ieee80211_stop_queue(dev, prio); // here we should stop those prio related to the queue idx flag set in TX_INTF_REG_S_AXIS_FIFO_NO_ROOM_read
978 		printk("%s openwifi_tx: WARNING ieee80211_stop_queue prio %d queue %d no room flag %x hw queue len %08x request %d wr %d rd %d\n", sdr_compatible_str,
979 		prio, queue_idx, dma_fifo_no_room_flag, hw_queue_len, num_dma_symbol, ring->bd_wr_idx, ring->bd_rd_idx);
980 		ring->stop_flag = 1;
981 		goto openwifi_tx_early_out_after_lock;
982 	}
983 	// --------end of check whether FPGA fifo (queue_idx) has enough room------------
984 
985 	status = dma_async_is_tx_complete(priv->tx_chan, priv->tx_cookie, NULL, NULL);
986 	if (status!=DMA_COMPLETE) {
987 		printk("%s openwifi_tx: WARNING status!=DMA_COMPLETE\n", sdr_compatible_str);
988 		goto openwifi_tx_early_out_after_lock;
989 	}
990 
991 //-------------------------fire skb DMA to hardware----------------------------------
992 	dma_mapping_addr = dma_map_single(priv->tx_chan->device->dev, dma_buf,
993 				 num_dma_byte, DMA_MEM_TO_DEV);
994 
995 	if (dma_mapping_error(priv->tx_chan->device->dev,dma_mapping_addr)) {
996 		// dev_err(priv->tx_chan->device->dev, "sdr,sdr openwifi_tx: WARNING TX DMA mapping error\n");
997 		printk("%s openwifi_tx: WARNING sn %d TX DMA mapping error\n", sdr_compatible_str, ring->bd_wr_idx);
998 		goto openwifi_tx_early_out_after_lock;
999 	}
1000 
1001 	sg_init_table(&(priv->tx_sg), 1); // only need to be initialized once in openwifi_start
1002 	sg_dma_address( &(priv->tx_sg) ) = dma_mapping_addr;
1003 	sg_dma_len( &(priv->tx_sg) ) = num_dma_byte;
1004 
1005 	tx_intf_api->TX_INTF_REG_CTS_TOSELF_CONFIG_write(cts_reg);
1006 	tx_intf_api->TX_INTF_REG_TX_CONFIG_write(tx_config);
1007 	tx_intf_api->TX_INTF_REG_PHY_HDR_CONFIG_write(phy_hdr_config);
1008 	priv->txd = priv->tx_chan->device->device_prep_slave_sg(priv->tx_chan, &(priv->tx_sg),1,DMA_MEM_TO_DEV, DMA_CTRL_ACK | DMA_PREP_INTERRUPT, NULL);
1009 	if (!(priv->txd)) {
1010 		printk("%s openwifi_tx: WARNING sn %d device_prep_slave_sg %p\n", sdr_compatible_str, ring->bd_wr_idx, (void*)(priv->txd));
1011 		goto openwifi_tx_after_dma_mapping;
1012 	}
1013 
1014 	priv->tx_cookie = priv->txd->tx_submit(priv->txd);
1015 
1016 	if (dma_submit_error(priv->tx_cookie)) {
1017 		printk("%s openwifi_tx: WARNING sn %d dma_submit_error(tx_cookie) %d\n", sdr_compatible_str, ring->bd_wr_idx, (u32)(priv->tx_cookie));
1018 		goto openwifi_tx_after_dma_mapping;
1019 	}
1020 
1021 	// seems everything is ok. let's mark this pkt in bd descriptor ring
1022 	ring->bds[ring->bd_wr_idx].seq_no = (sc&IEEE80211_SCTL_SEQ)>>4;
1023 	ring->bds[ring->bd_wr_idx].skb_linked = skb;
1024 	ring->bds[ring->bd_wr_idx].dma_mapping_addr = dma_mapping_addr;
1025 
1026 	ring->bd_wr_idx = ((ring->bd_wr_idx+1)&(NUM_TX_BD-1));
1027 
1028 	dma_async_issue_pending(priv->tx_chan);
1029 
1030 	spin_unlock_irqrestore(&priv->lock, flags);
1031 
1032 	return;
1033 
1034 openwifi_tx_after_dma_mapping:
1035 	dma_unmap_single(priv->tx_chan->device->dev, dma_mapping_addr, num_dma_byte, DMA_MEM_TO_DEV);
1036 
1037 openwifi_tx_early_out_after_lock:
1038 	dev_kfree_skb(skb);
1039 	spin_unlock_irqrestore(&priv->lock, flags);
1040 	// printk("%s openwifi_tx: WARNING openwifi_tx_after_dma_mapping phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx);
1041 	return;
1042 
1043 openwifi_tx_early_out:
1044 	dev_kfree_skb(skb);
1045 	// printk("%s openwifi_tx: WARNING openwifi_tx_early_out phy_tx_sn %d queue %d\n", sdr_compatible_str,priv->phy_tx_sn,queue_idx);
1046 }
1047 
1048 static int openwifi_start(struct ieee80211_hw *dev)
1049 {
1050 	struct openwifi_priv *priv = dev->priv;
1051 	int ret, i, rssi_half_db_offset, agc_gain_delay;//rssi_half_db_th,
1052 	u32 reg;
1053 
1054 	for (i=0; i<MAX_NUM_VIF; i++) {
1055 		priv->vif[i] = NULL;
1056 	}
1057 
1058 	memset(priv->drv_tx_reg_val, 0, sizeof(priv->drv_tx_reg_val));
1059 	memset(priv->drv_rx_reg_val, 0, sizeof(priv->drv_rx_reg_val));
1060 	memset(priv->drv_xpu_reg_val, 0, sizeof(priv->drv_xpu_reg_val));
1061 	priv->drv_xpu_reg_val[DRV_XPU_REG_IDX_GIT_REV] = GIT_REV;
1062 
1063 	//turn on radio
1064 	if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1) {
1065 		ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, false, true, true); // AD9361_RADIO_ON_TX_ATT 3000 means 3dB, 0 means 0dB
1066 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1067 	} else {
1068 		ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, true, false, true); // AD9361_RADIO_ON_TX_ATT 3000 means 3dB, 0 means 0dB
1069 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1070 	}
1071 	if (reg == AD9361_RADIO_ON_TX_ATT) {
1072 		priv->rfkill_off = 1;// 0 off, 1 on
1073 		printk("%s openwifi_start: rfkill radio on\n",sdr_compatible_str);
1074 	}
1075 	else
1076 		printk("%s openwifi_start: WARNING rfkill radio on failed. tx att read %d require %d\n",sdr_compatible_str, reg, AD9361_RADIO_ON_TX_ATT);
1077 
1078 	if (priv->rx_intf_cfg == RX_INTF_BW_20MHZ_AT_0MHZ_ANT0)
1079 		priv->ctrl_out.index=0x16;
1080 	else
1081 		priv->ctrl_out.index=0x17;
1082 
1083 	ret = ad9361_ctrl_outs_setup(priv->ad9361_phy, &(priv->ctrl_out));
1084 	if (ret < 0) {
1085 		printk("%s openwifi_start: WARNING ad9361_ctrl_outs_setup %d\n",sdr_compatible_str, ret);
1086 	} else {
1087 		printk("%s openwifi_start: ad9361_ctrl_outs_setup en_mask 0x%02x index 0x%02x\n",sdr_compatible_str, priv->ctrl_out.en_mask, priv->ctrl_out.index);
1088 	}
1089 
1090 	priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg];
1091 	priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg];
1092 
1093 	rx_intf_api->hw_init(priv->rx_intf_cfg,8,8);
1094 	tx_intf_api->hw_init(priv->tx_intf_cfg,8,8,priv->fpga_type);
1095 	openofdm_tx_api->hw_init(priv->openofdm_tx_cfg);
1096 	openofdm_rx_api->hw_init(priv->openofdm_rx_cfg);
1097 	xpu_api->hw_init(priv->xpu_cfg);
1098 
1099 	agc_gain_delay = 50; //samples
1100 	rssi_half_db_offset = 150; // to be consistent
1101 	xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
1102 	xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
1103 
1104 	openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write(0);
1105 	// rssi_half_db_th = 87<<1; // -62dBm // will setup in runtime in _rf_set_channel
1106 	// xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
1107 	xpu_api->XPU_REG_FORCE_IDLE_MISC_write(75); //control the duration to force ch_idle after decoding a packet due to imperfection of agc and signals
1108 
1109 	//xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((40)<<16)|0 );//high 16bit 5GHz; low 16 bit 2.4GHz (Attention, current tx core has around 1.19us starting delay that makes the ack fall behind 10us SIFS in 2.4GHz! Need to improve TX in 2.4GHz!)
1110 	//xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51)<<16)|0 );//now our tx send out I/Q immediately
1111 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51+23)<<16)|(0+23) );//we have more time when we use FIR in AD9361
1112 
1113 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (1<<31) | (((45+2+2)*10 + 15)<<16) | 10 );//2.4GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
1114 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (1<<31) | (((51+2+2)*10 + 15)<<16) | 10 );//5GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
1115 
1116 	tx_intf_api->TX_INTF_REG_CTS_TOSELF_WAIT_SIFS_TOP_write( ((16*10)<<16)|(10*10) );//high 16bit 5GHz; low 16 bit 2.4GHz. counter speed 10MHz is assumed
1117 
1118 	// //xpu_api->XPU_REG_BB_RF_DELAY_write(51); // fine tuned value at 0.005us. old: dac-->ant port: 0.6us, 57 taps fir at 40MHz: 1.425us; round trip: 2*(0.6+1.425)=4.05us; 4.05*10=41
1119 	// xpu_api->XPU_REG_BB_RF_DELAY_write(47);//add .5us for slightly longer fir -- already in xpu.c
1120 	xpu_api->XPU_REG_MAC_ADDR_write(priv->mac_addr);
1121 
1122 	// setup time schedule of 4 slices
1123 	// slice 0
1124 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
1125 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
1126 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
1127 
1128 	// slice 1
1129 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
1130 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
1131 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
1132 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
1133 
1134 	// slice 2
1135 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
1136 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
1137 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
1138 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
1139 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
1140 
1141 	// slice 3
1142 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
1143 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
1144 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
1145 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
1146 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
1147 
1148 	// all slice sync rest
1149 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
1150 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
1151 
1152 	//xpu_api->XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(priv->mac_addr + 4) )) );
1153 	printk("%s openwifi_start: rx_intf_cfg %d openofdm_rx_cfg %d tx_intf_cfg %d openofdm_tx_cfg %d\n",sdr_compatible_str, priv->rx_intf_cfg, priv->openofdm_rx_cfg, priv->tx_intf_cfg, priv->openofdm_tx_cfg);
1154 	printk("%s openwifi_start: rx_freq_offset_to_lo_MHz %d tx_freq_offset_to_lo_MHz %d\n",sdr_compatible_str, priv->rx_freq_offset_to_lo_MHz, priv->tx_freq_offset_to_lo_MHz);
1155 
1156 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30004); //disable tx interrupt
1157 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable rx interrupt by interrupt test mode
1158 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status
1159 
1160 	if (test_mode==1) {
1161 		printk("%s openwifi_start: test_mode==1\n",sdr_compatible_str);
1162 		goto normal_out;
1163 	}
1164 
1165 	priv->rx_chan = dma_request_slave_channel(&(priv->pdev->dev), "rx_dma_s2mm");
1166 	if (IS_ERR(priv->rx_chan) || priv->rx_chan==NULL) {
1167 		ret = PTR_ERR(priv->rx_chan);
1168 		pr_err("%s openwifi_start: No Rx channel ret %d priv->rx_chan 0x%p\n",sdr_compatible_str, ret, priv->rx_chan);
1169 		goto err_dma;
1170 	}
1171 
1172 	priv->tx_chan = dma_request_slave_channel(&(priv->pdev->dev), "tx_dma_mm2s");
1173 	if (IS_ERR(priv->tx_chan) || priv->tx_chan==NULL) {
1174 		ret = PTR_ERR(priv->tx_chan);
1175 		pr_err("%s openwifi_start: No Tx channel ret %d priv->tx_chan 0x%p\n",sdr_compatible_str, ret, priv->tx_chan);
1176 		goto err_dma;
1177 	}
1178 	printk("%s openwifi_start: DMA channel setup successfully. priv->rx_chan 0x%p priv->tx_chan 0x%p\n",sdr_compatible_str, priv->rx_chan, priv->tx_chan);
1179 
1180 	ret = openwifi_init_rx_ring(priv);
1181 	if (ret) {
1182 		printk("%s openwifi_start: openwifi_init_rx_ring ret %d\n", sdr_compatible_str,ret);
1183 		goto err_free_rings;
1184 	}
1185 
1186 	priv->seqno=0;
1187 	for (i=0; i<MAX_NUM_SW_QUEUE; i++) {
1188 		if ((ret = openwifi_init_tx_ring(priv, i))) {
1189 			printk("%s openwifi_start: openwifi_init_tx_ring %d ret %d\n", sdr_compatible_str, i, ret);
1190 			goto err_free_rings;
1191 		}
1192 	}
1193 
1194 	if ( (ret = rx_dma_setup(dev)) ) {
1195 		printk("%s openwifi_start: rx_dma_setup ret %d\n", sdr_compatible_str,ret);
1196 		goto err_free_rings;
1197 	}
1198 
1199 	priv->irq_rx = irq_of_parse_and_map(priv->pdev->dev.of_node, 1);
1200 	ret = request_irq(priv->irq_rx, openwifi_rx_interrupt,
1201 			IRQF_SHARED, "sdr,rx_pkt_intr", dev);
1202 	if (ret) {
1203 		wiphy_err(dev->wiphy, "openwifi_start:failed to register IRQ handler openwifi_rx_interrupt\n");
1204 		goto err_free_rings;
1205 	} else {
1206 		printk("%s openwifi_start: irq_rx %d\n", sdr_compatible_str, priv->irq_rx);
1207 	}
1208 
1209 	priv->irq_tx = irq_of_parse_and_map(priv->pdev->dev.of_node, 3);
1210 	ret = request_irq(priv->irq_tx, openwifi_tx_interrupt,
1211 			IRQF_SHARED, "sdr,tx_itrpt", dev);
1212 	if (ret) {
1213 		wiphy_err(dev->wiphy, "openwifi_start: failed to register IRQ handler openwifi_tx_interrupt\n");
1214 		goto err_free_rings;
1215 	} else {
1216 		printk("%s openwifi_start: irq_tx %d\n", sdr_compatible_str, priv->irq_tx);
1217 	}
1218 
1219 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x000); // enable rx interrupt get normal fcs valid pass through ddc to ARM
1220 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x4); //enable tx interrupt
1221 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(0); // release M AXIS
1222 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0); // reset tsf timer
1223 
1224 	//ieee80211_wake_queue(dev, 0);
1225 
1226 normal_out:
1227 	printk("%s openwifi_start: normal end\n", sdr_compatible_str);
1228 	return 0;
1229 
1230 err_free_rings:
1231 	openwifi_free_rx_ring(priv);
1232 	for (i=0; i<MAX_NUM_SW_QUEUE; i++)
1233 		openwifi_free_tx_ring(priv, i);
1234 
1235 err_dma:
1236 	ret = -1;
1237 	printk("%s openwifi_start: abnormal end ret %d\n", sdr_compatible_str, ret);
1238 	return ret;
1239 }
1240 
1241 static void openwifi_stop(struct ieee80211_hw *dev)
1242 {
1243 	struct openwifi_priv *priv = dev->priv;
1244 	u32 reg, reg1;
1245 	int i;
1246 
1247 	if (test_mode==1){
1248 		pr_info("%s openwifi_stop: test_mode==1\n", sdr_compatible_str);
1249 		goto normal_out;
1250 	}
1251 
1252 	//turn off radio
1253 	#if 1
1254 	ad9361_tx_mute(priv->ad9361_phy, 1);
1255 	reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1256 	reg1 = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1257 	if (reg == AD9361_RADIO_OFF_TX_ATT && reg1 == AD9361_RADIO_OFF_TX_ATT ) {
1258 		priv->rfkill_off = 0;// 0 off, 1 on
1259 		printk("%s openwifi_stop: rfkill radio off\n",sdr_compatible_str);
1260 	}
1261 	else
1262 		printk("%s openwifi_stop: WARNING rfkill radio off failed. tx att read %d %d require %d\n",sdr_compatible_str, reg, reg1, AD9361_RADIO_OFF_TX_ATT);
1263 	#endif
1264 
1265 	//ieee80211_stop_queue(dev, 0);
1266 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30004); //disable tx interrupt
1267 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable fcs_valid by interrupt test mode
1268 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status
1269 
1270 	for (i=0; i<MAX_NUM_VIF; i++) {
1271 		priv->vif[i] = NULL;
1272 	}
1273 
1274 	openwifi_free_rx_ring(priv);
1275 	for (i=0; i<MAX_NUM_SW_QUEUE; i++)
1276 		openwifi_free_tx_ring(priv, i);
1277 
1278 	pr_info("%s openwifi_stop: dropped channel %s\n", sdr_compatible_str, dma_chan_name(priv->rx_chan));
1279 	dmaengine_terminate_all(priv->rx_chan);
1280 	dma_release_channel(priv->rx_chan);
1281 	pr_info("%s openwifi_stop: dropped channel %s\n", sdr_compatible_str, dma_chan_name(priv->tx_chan));
1282 	dmaengine_terminate_all(priv->tx_chan);
1283 	dma_release_channel(priv->tx_chan);
1284 
1285 	//priv->rf->stop(dev);
1286 
1287 	free_irq(priv->irq_rx, dev);
1288 	free_irq(priv->irq_tx, dev);
1289 
1290 normal_out:
1291 	printk("%s openwifi_stop\n", sdr_compatible_str);
1292 }
1293 
1294 static u64 openwifi_get_tsf(struct ieee80211_hw *dev,
1295 			   struct ieee80211_vif *vif)
1296 {
1297 	u32 tsft_low, tsft_high;
1298 
1299 	tsft_low = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
1300 	tsft_high = xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read();
1301 	//printk("%s openwifi_get_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low);
1302 	return( ( (u64)tsft_low ) | ( ((u64)tsft_high)<<32 ) );
1303 }
1304 
1305 static void openwifi_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf)
1306 {
1307 	u32 tsft_high = ((tsf >> 32)&0xffffffff);
1308 	u32 tsft_low  = (tsf&0xffffffff);
1309 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(tsft_high,tsft_low);
1310 	printk("%s openwifi_set_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low);
1311 }
1312 
1313 static void openwifi_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1314 {
1315 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
1316 	printk("%s openwifi_reset_tsf\n", sdr_compatible_str);
1317 }
1318 
1319 static int openwifi_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1320 {
1321 	printk("%s openwifi_set_rts_threshold WARNING value %d\n", sdr_compatible_str,value);
1322 	return(0);
1323 }
1324 
1325 static void openwifi_beacon_work(struct work_struct *work)
1326 {
1327 	struct openwifi_vif *vif_priv =
1328 		container_of(work, struct openwifi_vif, beacon_work.work);
1329 	struct ieee80211_vif *vif =
1330 		container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
1331 	struct ieee80211_hw *dev = vif_priv->dev;
1332 	struct ieee80211_mgmt *mgmt;
1333 	struct sk_buff *skb;
1334 
1335 	/* don't overflow the tx ring */
1336 	if (ieee80211_queue_stopped(dev, 0))
1337 		goto resched;
1338 
1339 	/* grab a fresh beacon */
1340 	skb = ieee80211_beacon_get(dev, vif);
1341 	if (!skb)
1342 		goto resched;
1343 
1344 	/*
1345 	 * update beacon timestamp w/ TSF value
1346 	 * TODO: make hardware update beacon timestamp
1347 	 */
1348 	mgmt = (struct ieee80211_mgmt *)skb->data;
1349 	mgmt->u.beacon.timestamp = cpu_to_le64(openwifi_get_tsf(dev, vif));
1350 
1351 	/* TODO: use actual beacon queue */
1352 	skb_set_queue_mapping(skb, 0);
1353 	openwifi_tx(dev, NULL, skb);
1354 
1355 resched:
1356 	/*
1357 	 * schedule next beacon
1358 	 * TODO: use hardware support for beacon timing
1359 	 */
1360 	schedule_delayed_work(&vif_priv->beacon_work,
1361 			usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
1362 }
1363 
1364 static int openwifi_add_interface(struct ieee80211_hw *dev,
1365 				 struct ieee80211_vif *vif)
1366 {
1367 	int i;
1368 	struct openwifi_priv *priv = dev->priv;
1369 	struct openwifi_vif *vif_priv;
1370 
1371 	switch (vif->type) {
1372 	case NL80211_IFTYPE_AP:
1373 	case NL80211_IFTYPE_STATION:
1374 	case NL80211_IFTYPE_ADHOC:
1375 	case NL80211_IFTYPE_MONITOR:
1376 	case NL80211_IFTYPE_MESH_POINT:
1377 		break;
1378 	default:
1379 		return -EOPNOTSUPP;
1380 	}
1381 	// let's support more than 1 interface
1382 	for (i=0; i<MAX_NUM_VIF; i++) {
1383 		if (priv->vif[i] == NULL)
1384 			break;
1385 	}
1386 
1387 	printk("%s openwifi_add_interface start. vif for loop result %d\n", sdr_compatible_str, i);
1388 
1389 	if (i==MAX_NUM_VIF)
1390 		return -EBUSY;
1391 
1392 	priv->vif[i] = vif;
1393 
1394 	/* Initialize driver private area */
1395 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1396 	vif_priv->idx = i;
1397 
1398 	vif_priv->dev = dev;
1399 	INIT_DELAYED_WORK(&vif_priv->beacon_work, openwifi_beacon_work);
1400 	vif_priv->enable_beacon = false;
1401 
1402 	printk("%s openwifi_add_interface end with vif idx %d\n", sdr_compatible_str,vif_priv->idx);
1403 
1404 	return 0;
1405 }
1406 
1407 static void openwifi_remove_interface(struct ieee80211_hw *dev,
1408 				     struct ieee80211_vif *vif)
1409 {
1410 	struct openwifi_vif *vif_priv;
1411 	struct openwifi_priv *priv = dev->priv;
1412 
1413 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1414 	priv->vif[vif_priv->idx] = NULL;
1415 	printk("%s openwifi_remove_interface vif idx %d\n", sdr_compatible_str, vif_priv->idx);
1416 }
1417 
1418 static int openwifi_config(struct ieee80211_hw *dev, u32 changed)
1419 {
1420 	struct openwifi_priv *priv = dev->priv;
1421 	struct ieee80211_conf *conf = &dev->conf;
1422 
1423 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
1424 		priv->rf->set_chan(dev, conf);
1425 	else
1426 		printk("%s openwifi_config changed flag %08x\n", sdr_compatible_str, changed);
1427 
1428 	return 0;
1429 }
1430 
1431 static void openwifi_bss_info_changed(struct ieee80211_hw *dev,
1432 				     struct ieee80211_vif *vif,
1433 				     struct ieee80211_bss_conf *info,
1434 				     u32 changed)
1435 {
1436 	struct openwifi_priv *priv = dev->priv;
1437 	struct openwifi_vif *vif_priv;
1438 	u32 bssid_low, bssid_high;
1439 
1440 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1441 
1442 	//be careful: we don have valid chip, so registers addresses in priv->map->BSSID[0] are not valid! should not print it!
1443 	//printk("%s openwifi_bss_info_changed map bssid %02x%02x%02x%02x%02x%02x\n",sdr_compatible_str,priv->map->BSSID[0],priv->map->BSSID[1],priv->map->BSSID[2],priv->map->BSSID[3],priv->map->BSSID[4],priv->map->BSSID[5]);
1444 	if (changed & BSS_CHANGED_BSSID) {
1445 		printk("%s openwifi_bss_info_changed BSS_CHANGED_BSSID %02x%02x%02x%02x%02x%02x\n",sdr_compatible_str,info->bssid[0],info->bssid[1],info->bssid[2],info->bssid[3],info->bssid[4],info->bssid[5]);
1446 		// write new bssid to our HW, and do not change bssid filter
1447 		//u32 bssid_filter_high = xpu_api->XPU_REG_BSSID_FILTER_HIGH_read();
1448 		bssid_low = ( *( (u32*)(info->bssid) ) );
1449 		bssid_high = ( *( (u16*)(info->bssid+4) ) );
1450 
1451 		//bssid_filter_high = (bssid_filter_high&0x80000000);
1452 		//bssid_high = (bssid_high|bssid_filter_high);
1453 		xpu_api->XPU_REG_BSSID_FILTER_LOW_write(bssid_low);
1454 		xpu_api->XPU_REG_BSSID_FILTER_HIGH_write(bssid_high);
1455 	}
1456 
1457 	if (changed & BSS_CHANGED_BEACON_INT) {
1458 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_INT %x\n",sdr_compatible_str,info->beacon_int);
1459 	}
1460 
1461 	if (changed & BSS_CHANGED_TXPOWER)
1462 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_TXPOWER %x\n",sdr_compatible_str,info->txpower);
1463 
1464 	if (changed & BSS_CHANGED_ERP_CTS_PROT)
1465 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_ERP_CTS_PROT %x\n",sdr_compatible_str,info->use_cts_prot);
1466 
1467 	if (changed & BSS_CHANGED_BASIC_RATES)
1468 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BASIC_RATES %x\n",sdr_compatible_str,info->basic_rates);
1469 
1470 	if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) {
1471 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_ERP_SLOT %d BSS_CHANGED_ERP_PREAMBLE %d short slot %d\n",sdr_compatible_str,
1472 		changed&BSS_CHANGED_ERP_SLOT,changed&BSS_CHANGED_ERP_PREAMBLE,info->use_short_slot);
1473 		if (info->use_short_slot && priv->use_short_slot==false) {
1474 			priv->use_short_slot=true;
1475 			xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
1476 		} else if ((!info->use_short_slot) && priv->use_short_slot==true) {
1477 			priv->use_short_slot=false;
1478 			xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
1479 		}
1480 	}
1481 
1482 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
1483 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_ENABLED\n",sdr_compatible_str);
1484 		vif_priv->enable_beacon = info->enable_beacon;
1485 	}
1486 
1487 	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
1488 		cancel_delayed_work_sync(&vif_priv->beacon_work);
1489 		if (vif_priv->enable_beacon)
1490 			schedule_work(&vif_priv->beacon_work.work);
1491 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_ENABLED %d BSS_CHANGED_BEACON %d\n",sdr_compatible_str,
1492 		changed&BSS_CHANGED_BEACON_ENABLED,changed&BSS_CHANGED_BEACON);
1493 	}
1494 }
1495 // helper function
1496 u32 log2val(u32 val){
1497 	u32 ret_val = 0 ;
1498 	while(val>1){
1499 		val = val >> 1 ;
1500 		ret_val ++ ;
1501 	}
1502 	return ret_val ;
1503 }
1504 
1505 static int openwifi_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
1506 	      const struct ieee80211_tx_queue_params *params)
1507 {
1508 	u32 reg_val, cw_min_exp, cw_max_exp;
1509 
1510 	printk("%s openwifi_conf_tx: [queue %d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d, aifs and txop ignored\n",
1511 		  sdr_compatible_str,queue,params->aifs,params->cw_min,params->cw_max,params->txop);
1512 
1513 	reg_val=xpu_api->XPU_REG_CSMA_CFG_read();
1514 	cw_min_exp = (log2val(params->cw_min + 1) & 0x0F);
1515 	cw_max_exp = (log2val(params->cw_max + 1) & 0x0F);
1516 	switch(queue){
1517 		case 0: reg_val = ( (reg_val & 0xFFFFFF00) | ((cw_min_exp | (cw_max_exp << 4)) << 0) );  break;
1518 		case 1: reg_val = ( (reg_val & 0xFFFF00FF) | ((cw_min_exp | (cw_max_exp << 4)) << 8) );  break;
1519 		case 2: reg_val = ( (reg_val & 0xFF00FFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 16) ); break;
1520 		case 3: reg_val = ( (reg_val & 0x00FFFFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 24) ); break;
1521 		default: printk("%s openwifi_conf_tx: WARNING queue %d does not exist",sdr_compatible_str, queue); return(0);
1522 	}
1523 	xpu_api->XPU_REG_CSMA_CFG_write(reg_val);
1524 	return(0);
1525 }
1526 
1527 static u64 openwifi_prepare_multicast(struct ieee80211_hw *dev,
1528 				     struct netdev_hw_addr_list *mc_list)
1529 {
1530 	printk("%s openwifi_prepare_multicast\n", sdr_compatible_str);
1531 	return netdev_hw_addr_list_count(mc_list);
1532 }
1533 
1534 static void openwifi_configure_filter(struct ieee80211_hw *dev,
1535 				     unsigned int changed_flags,
1536 				     unsigned int *total_flags,
1537 				     u64 multicast)
1538 {
1539 	u32 filter_flag;
1540 
1541 	(*total_flags) &= SDR_SUPPORTED_FILTERS;
1542 	(*total_flags) |= FIF_ALLMULTI; //because we need to pass all multicast (no matter it is for us or not) to upper layer
1543 
1544 	filter_flag = (*total_flags);
1545 
1546 	filter_flag = (filter_flag|UNICAST_FOR_US|BROADCAST_ALL_ONE|BROADCAST_ALL_ZERO);
1547 	//filter_flag = (filter_flag|UNICAST_FOR_US|BROADCAST_ALL_ONE|BROADCAST_ALL_ZERO|MONITOR_ALL); // all pkt will be delivered to arm
1548 
1549 	//if (priv->vif[0]->type == NL80211_IFTYPE_MONITOR)
1550 	if ((filter_flag&0xf0) == 0xf0) //FIF_BCN_PRBRESP_PROMISC/FIF_CONTROL/FIF_OTHER_BSS/FIF_PSPOLL are set means monitor mode
1551 		filter_flag = (filter_flag|MONITOR_ALL);
1552 	else
1553 		filter_flag = (filter_flag&(~MONITOR_ALL));
1554 
1555 	if ( !(filter_flag&FIF_BCN_PRBRESP_PROMISC) )
1556 		filter_flag = (filter_flag|MY_BEACON);
1557 
1558 	filter_flag = (filter_flag|FIF_PSPOLL);
1559 
1560 	xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag|HIGH_PRIORITY_DISCARD_FLAG);
1561 	//xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag); //do not discard any pkt
1562 
1563 	printk("%s openwifi_configure_filter MON %d M_BCN %d BST0 %d BST1 %d UST %d PB_RQ %d PS_PL %d O_BSS %d CTL %d BCN_PRP %d PCP_FL %d FCS_FL %d ALL_MUT %d\n", sdr_compatible_str,
1564 	(filter_flag>>13)&1,(filter_flag>>12)&1,(filter_flag>>11)&1,(filter_flag>>10)&1,(filter_flag>>9)&1,(filter_flag>>8)&1,(filter_flag>>7)&1,(filter_flag>>6)&1,(filter_flag>>5)&1,(filter_flag>>4)&1,(filter_flag>>3)&1,(filter_flag>>2)&1,(filter_flag>>1)&1);
1565 }
1566 
1567 static int openwifi_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params)
1568 {
1569 	struct ieee80211_sta *sta = params->sta;
1570 	enum ieee80211_ampdu_mlme_action action = params->action;
1571 	// struct openwifi_priv *priv = hw->priv;
1572 	u16 max_tx_bytes, buf_size;
1573 	u32 ampdu_action_config;
1574 
1575 	switch (action)
1576 	{
1577 		case IEEE80211_AMPDU_TX_START:
1578 			ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, params->tid);
1579 			break;
1580 		case IEEE80211_AMPDU_TX_STOP_CONT:
1581 		case IEEE80211_AMPDU_TX_STOP_FLUSH:
1582 		case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1583 			ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, params->tid);
1584 			break;
1585 		case IEEE80211_AMPDU_TX_OPERATIONAL:
1586 			buf_size = 4;
1587 //			buf_size = (params->buf_size) - 1;
1588 			max_tx_bytes = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor)) - 1;
1589 			ampdu_action_config = ( sta->ht_cap.ampdu_density<<24 | buf_size<<16 | max_tx_bytes );
1590 			tx_intf_api->TX_INTF_REG_AMPDU_ACTION_CONFIG_write(ampdu_action_config);
1591 			break;
1592 		case IEEE80211_AMPDU_RX_START:
1593 			printk("%s openwifi_ampdu_action: start RX aggregation. tid %d\n", sdr_compatible_str, params->tid);
1594 			break;
1595 		case IEEE80211_AMPDU_RX_STOP:
1596 			printk("%s openwifi_ampdu_action: stop RX aggregation. tid %d\n", sdr_compatible_str, params->tid);
1597 			break;
1598 		default:
1599 			return -EOPNOTSUPP;
1600 	}
1601 
1602 	return 0;
1603 }
1604 
1605 static const struct ieee80211_ops openwifi_ops = {
1606 	.tx			       = openwifi_tx,
1607 	.start			   = openwifi_start,
1608 	.stop			   = openwifi_stop,
1609 	.add_interface	   = openwifi_add_interface,
1610 	.remove_interface  = openwifi_remove_interface,
1611 	.config			   = openwifi_config,
1612 	.bss_info_changed  = openwifi_bss_info_changed,
1613 	.conf_tx		   = openwifi_conf_tx,
1614 	.prepare_multicast = openwifi_prepare_multicast,
1615 	.configure_filter  = openwifi_configure_filter,
1616 	.rfkill_poll	   = openwifi_rfkill_poll,
1617 	.get_tsf		   = openwifi_get_tsf,
1618 	.set_tsf		   = openwifi_set_tsf,
1619 	.reset_tsf		   = openwifi_reset_tsf,
1620 	.set_rts_threshold = openwifi_set_rts_threshold,
1621 	.ampdu_action      = openwifi_ampdu_action,
1622 	.testmode_cmd	   = openwifi_testmode_cmd,
1623 };
1624 
1625 static const struct of_device_id openwifi_dev_of_ids[] = {
1626 	{ .compatible = "sdr,sdr", },
1627 	{}
1628 };
1629 MODULE_DEVICE_TABLE(of, openwifi_dev_of_ids);
1630 
1631 static int custom_match_spi_dev(struct device *dev, void *data)
1632 {
1633     const char *name = data;
1634 
1635 	bool ret = sysfs_streq(name, dev->of_node->name);
1636 	printk("%s custom_match_spi_dev %s %s %d\n", sdr_compatible_str,name, dev->of_node->name, ret);
1637 	return ret;
1638 }
1639 
1640 static int custom_match_platform_dev(struct device *dev, void *data)
1641 {
1642 	struct platform_device *plat_dev = to_platform_device(dev);
1643 	const char *name = data;
1644 	char *name_in_sys_bus_platform_devices = strstr(plat_dev->name, name);
1645 	bool match_flag = (name_in_sys_bus_platform_devices != NULL);
1646 
1647 	if (match_flag) {
1648 		printk("%s custom_match_platform_dev %s\n", sdr_compatible_str,plat_dev->name);
1649 	}
1650 	return(match_flag);
1651 }
1652 
1653 static int openwifi_dev_probe(struct platform_device *pdev)
1654 {
1655 	struct ieee80211_hw *dev;
1656 	struct openwifi_priv *priv;
1657 	int err=1, rand_val;
1658 	const char *chip_name, *fpga_model;
1659 	u32 reg;//, reg1;
1660 
1661 	struct device_node *np = pdev->dev.of_node;
1662 
1663 	struct device *tmp_dev;
1664 	struct platform_device *tmp_pdev;
1665 	struct iio_dev *tmp_indio_dev;
1666 	// struct gpio_leds_priv *tmp_led_priv;
1667 
1668 	printk("\n");
1669 
1670 	if (np) {
1671 		const struct of_device_id *match;
1672 
1673 		match = of_match_node(openwifi_dev_of_ids, np);
1674 		if (match) {
1675 			printk("%s openwifi_dev_probe: match!\n", sdr_compatible_str);
1676 			err = 0;
1677 		}
1678 	}
1679 
1680 	if (err)
1681 		return err;
1682 
1683 	dev = ieee80211_alloc_hw(sizeof(*priv), &openwifi_ops);
1684 	if (!dev) {
1685 		printk(KERN_ERR "%s openwifi_dev_probe: ieee80211 alloc failed\n",sdr_compatible_str);
1686 		err = -ENOMEM;
1687 		goto err_free_dev;
1688 	}
1689 
1690 	priv = dev->priv;
1691 	priv->pdev = pdev;
1692 
1693 	err = of_property_read_string(of_find_node_by_path("/"), "model", &fpga_model);
1694 	if(err < 0) {
1695 		printk("%s openwifi_dev_probe: WARNING unknown openwifi FPGA model %d\n",sdr_compatible_str, err);
1696 		priv->fpga_type = SMALL_FPGA;
1697 	} else {
1698 		// LARGE FPGAs (i.e. ZCU102, Z7035, ZC706)
1699 		if(strstr(fpga_model, "ZCU102") != NULL || strstr(fpga_model, "Z7035") != NULL || strstr(fpga_model, "ZC706") != NULL)
1700 			priv->fpga_type = LARGE_FPGA;
1701 		// SMALL FPGA: (i.e. ZED, ZC702, Z7020)
1702 		else if(strstr(fpga_model, "ZED") != NULL || strstr(fpga_model, "ZC702") != NULL || strstr(fpga_model, "Z7020") != NULL)
1703 			priv->fpga_type = SMALL_FPGA;
1704 	}
1705 
1706 	// //-------------find ad9361-phy driver for lo/channel control---------------
1707 	priv->actual_rx_lo = 0;
1708 	priv->actual_tx_lo = 0;
1709 	tmp_dev = bus_find_device( &spi_bus_type, NULL, "ad9361-phy", custom_match_spi_dev );
1710 	if (tmp_dev == NULL) {
1711 		printk(KERN_ERR "%s find_dev ad9361-phy failed\n",sdr_compatible_str);
1712 		err = -ENOMEM;
1713 		goto err_free_dev;
1714 	}
1715 	printk("%s bus_find_device ad9361-phy: %s. driver_data pointer %p\n", sdr_compatible_str, ((struct spi_device*)tmp_dev)->modalias, (void*)(((struct spi_device*)tmp_dev)->dev.driver_data));
1716 	if (((struct spi_device*)tmp_dev)->dev.driver_data == NULL) {
1717 		printk(KERN_ERR "%s find_dev ad9361-phy failed. dev.driver_data == NULL\n",sdr_compatible_str);
1718 		err = -ENOMEM;
1719 		goto err_free_dev;
1720 	}
1721 
1722 	priv->ad9361_phy = ad9361_spi_to_phy((struct spi_device*)tmp_dev);
1723 	if (!(priv->ad9361_phy)) {
1724 		printk(KERN_ERR "%s ad9361_spi_to_phy failed\n",sdr_compatible_str);
1725 		err = -ENOMEM;
1726 		goto err_free_dev;
1727 	}
1728 	printk("%s ad9361_spi_to_phy ad9361-phy: %s\n", sdr_compatible_str, priv->ad9361_phy->spi->modalias);
1729 
1730 	priv->ctrl_out.en_mask=0xFF;
1731 	priv->ctrl_out.index=0x16;
1732 	err = ad9361_ctrl_outs_setup(priv->ad9361_phy, &(priv->ctrl_out));
1733 	if (err < 0) {
1734 		printk("%s openwifi_dev_probe: WARNING ad9361_ctrl_outs_setup %d\n",sdr_compatible_str, err);
1735 	} else {
1736 		printk("%s openwifi_dev_probe: ad9361_ctrl_outs_setup en_mask 0x%02x index 0x%02x\n",sdr_compatible_str, priv->ctrl_out.en_mask, priv->ctrl_out.index);
1737 	}
1738 
1739 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_POINTER);
1740 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_POINTER 0x%02x\n",sdr_compatible_str, reg);
1741 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_ENABLE);
1742 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_ENABLE 0x%02x\n",sdr_compatible_str, reg);
1743 
1744 	// //-------------find driver: axi_ad9361 hdl ref design module, dac channel---------------
1745 	tmp_dev = bus_find_device( &platform_bus_type, NULL, "cf-ad9361-dds-core-lpc", custom_match_platform_dev );
1746 	if (!tmp_dev) {
1747 		printk(KERN_ERR "%s bus_find_device platform_bus_type cf-ad9361-dds-core-lpc failed\n",sdr_compatible_str);
1748 		err = -ENOMEM;
1749 		goto err_free_dev;
1750 	}
1751 
1752 	tmp_pdev = to_platform_device(tmp_dev);
1753 	if (!tmp_pdev) {
1754 		printk(KERN_ERR "%s to_platform_device failed\n",sdr_compatible_str);
1755 		err = -ENOMEM;
1756 		goto err_free_dev;
1757 	}
1758 
1759 	tmp_indio_dev = platform_get_drvdata(tmp_pdev);
1760 	if (!tmp_indio_dev) {
1761 		printk(KERN_ERR "%s platform_get_drvdata failed\n",sdr_compatible_str);
1762 		err = -ENOMEM;
1763 		goto err_free_dev;
1764 	}
1765 
1766 	priv->dds_st = iio_priv(tmp_indio_dev);
1767 	if (!(priv->dds_st)) {
1768 		printk(KERN_ERR "%s iio_priv failed\n",sdr_compatible_str);
1769 		err = -ENOMEM;
1770 		goto err_free_dev;
1771 	}
1772 	printk("%s openwifi_dev_probe: cf-ad9361-dds-core-lpc dds_st->version %08x chip_info->name %s\n",sdr_compatible_str,priv->dds_st->version,priv->dds_st->chip_info->name);
1773 	cf_axi_dds_datasel(priv->dds_st, -1, DATA_SEL_DMA);
1774 	printk("%s openwifi_dev_probe: cf_axi_dds_datasel DATA_SEL_DMA\n",sdr_compatible_str);
1775 
1776 	// //-------------find driver: axi_ad9361 hdl ref design module, adc channel---------------
1777 	// turn off radio by muting tx
1778 	// ad9361_tx_mute(priv->ad9361_phy, 1);
1779 	// reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1780 	// reg1 = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1781 	// if (reg == AD9361_RADIO_OFF_TX_ATT && reg1 == AD9361_RADIO_OFF_TX_ATT ) {
1782 	// 	priv->rfkill_off = 0;// 0 off, 1 on
1783 	// 	printk("%s openwifi_dev_probe: rfkill radio off\n",sdr_compatible_str);
1784 	// }
1785 	// else
1786 	// 	printk("%s openwifi_dev_probe: WARNING rfkill radio off failed. tx att read %d %d require %d\n",sdr_compatible_str, reg, reg1, AD9361_RADIO_OFF_TX_ATT);
1787 
1788 	priv->last_auto_fpga_lbt_th = 134;//just to avoid uninitialized
1789 	priv->rssi_correction = 43;//this will be set in real-time by _rf_set_channel()
1790 
1791 	//priv->rf_bw = 20000000; // Signal quality issue! NOT use for now. 20MHz or 40MHz. 40MHz need ddc/duc. 20MHz works in bypass mode
1792 	priv->rf_bw = 40000000; // 20MHz or 40MHz. 40MHz need ddc/duc. 20MHz works in bypass mode
1793 
1794 	priv->xpu_cfg = XPU_NORMAL;
1795 
1796 	priv->openofdm_tx_cfg = OPENOFDM_TX_NORMAL;
1797 	priv->openofdm_rx_cfg = OPENOFDM_RX_NORMAL;
1798 
1799 	printk("%s openwifi_dev_probe: priv->rf_bw == %dHz. bool for 20000000 %d, 40000000 %d\n",sdr_compatible_str, priv->rf_bw, (priv->rf_bw==20000000) , (priv->rf_bw==40000000) );
1800 	if (priv->rf_bw == 20000000) {
1801 		priv->rx_intf_cfg = RX_INTF_BYPASS;
1802 		priv->tx_intf_cfg = TX_INTF_BYPASS;
1803 		//priv->rx_freq_offset_to_lo_MHz = 0;
1804 		//priv->tx_freq_offset_to_lo_MHz = 0;
1805 	} else if (priv->rf_bw == 40000000) {
1806 		//priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_P_10MHZ; //work
1807 		//priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1; //work
1808 
1809 		// // test ddc at central, duc at central+10M. It works. And also change rx BW from 40MHz to 20MHz in rf_init.sh. Rx sampling rate is still 40Msps
1810 		priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT0;
1811 		priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0; // Let's use rx0 tx0 as default mode, because it works for both 9361 and 9364
1812 		// // try another antenna option
1813 		//priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT1;
1814 		//priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0;
1815 
1816 		#if 0
1817 		if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_N_10MHZ) {
1818 			priv->rx_freq_offset_to_lo_MHz = -10;
1819 		} else if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_P_10MHZ) {
1820 			priv->rx_freq_offset_to_lo_MHz = 10;
1821 		} else if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_0MHZ) {
1822 			priv->rx_freq_offset_to_lo_MHz = 0;
1823 		} else {
1824 			printk("%s openwifi_dev_probe: Warning! priv->rx_intf_cfg == %d\n",sdr_compatible_str,priv->rx_intf_cfg);
1825 		}
1826 		#endif
1827 	} else {
1828 		printk("%s openwifi_dev_probe: Warning! priv->rf_bw == %dHz (should be 20000000 or 40000000)\n",sdr_compatible_str, priv->rf_bw);
1829 	}
1830 	priv->rx_freq_offset_to_lo_MHz = rx_intf_fo_mapping[priv->rx_intf_cfg];
1831 	priv->tx_freq_offset_to_lo_MHz = tx_intf_fo_mapping[priv->tx_intf_cfg];
1832 	printk("%s openwifi_dev_probe: test_mode %d\n", sdr_compatible_str, test_mode);
1833 
1834 	//let's by default turn radio on when probing
1835 	if (priv->tx_intf_cfg == TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1) {
1836 		ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, false, true, true); // AD9361_RADIO_ON_TX_ATT 3000 means 3dB, 0 means 0dB
1837 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1838 	} else {
1839 		ad9361_set_tx_atten(priv->ad9361_phy, AD9361_RADIO_ON_TX_ATT, true, false, true); // AD9361_RADIO_ON_TX_ATT 3000 means 3dB, 0 means 0dB
1840 		reg = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1841 	}
1842 	if (reg == AD9361_RADIO_ON_TX_ATT) {
1843 		priv->rfkill_off = 1;// 0 off, 1 on
1844 		printk("%s openwifi_dev_probe: rfkill radio on\n",sdr_compatible_str);
1845 	} else
1846 		printk("%s openwifi_dev_probe: WARNING rfkill radio on failed. tx att read %d require %d\n",sdr_compatible_str, reg, AD9361_RADIO_ON_TX_ATT);
1847 
1848 	memset(priv->drv_rx_reg_val,0,sizeof(priv->drv_rx_reg_val));
1849 	memset(priv->drv_tx_reg_val,0,sizeof(priv->drv_tx_reg_val));
1850 	memset(priv->drv_xpu_reg_val,0,sizeof(priv->drv_xpu_reg_val));
1851 
1852 	// //set ad9361 in certain mode
1853 	#if 0
1854 	err = ad9361_set_trx_clock_chain_freq(priv->ad9361_phy,priv->rf_bw);
1855 	printk("%s openwifi_dev_probe: ad9361_set_trx_clock_chain_freq %dHz err %d\n",sdr_compatible_str, priv->rf_bw,err);
1856 	err = ad9361_update_rf_bandwidth(priv->ad9361_phy,priv->rf_bw,priv->rf_bw);
1857 	printk("%s openwifi_dev_probe: ad9361_update_rf_bandwidth %dHz err %d\n",sdr_compatible_str, priv->rf_bw,err);
1858 
1859 	rx_intf_api->hw_init(priv->rx_intf_cfg,8,8);
1860 	tx_intf_api->hw_init(priv->tx_intf_cfg,8,8,priv->fpga_type);
1861 	openofdm_tx_api->hw_init(priv->openofdm_tx_cfg);
1862 	openofdm_rx_api->hw_init(priv->openofdm_rx_cfg);
1863 	printk("%s openwifi_dev_probe: rx_intf_cfg %d openofdm_rx_cfg %d tx_intf_cfg %d openofdm_tx_cfg %d\n",sdr_compatible_str, priv->rx_intf_cfg, priv->openofdm_rx_cfg, priv->tx_intf_cfg, priv->openofdm_tx_cfg);
1864 	printk("%s openwifi_dev_probe: rx_freq_offset_to_lo_MHz %d tx_freq_offset_to_lo_MHz %d\n",sdr_compatible_str, priv->rx_freq_offset_to_lo_MHz, priv->tx_freq_offset_to_lo_MHz);
1865 	#endif
1866 
1867 	dev->max_rates = 1; //maximum number of alternate rate retry stages the hw can handle.
1868 
1869 	SET_IEEE80211_DEV(dev, &pdev->dev);
1870 	platform_set_drvdata(pdev, dev);
1871 
1872 	BUILD_BUG_ON(sizeof(priv->rates_2GHz) != sizeof(openwifi_2GHz_rates));
1873 	BUILD_BUG_ON(sizeof(priv->rates_5GHz) != sizeof(openwifi_5GHz_rates));
1874 	BUILD_BUG_ON(sizeof(priv->channels_2GHz) != sizeof(openwifi_2GHz_channels));
1875 	BUILD_BUG_ON(sizeof(priv->channels_5GHz) != sizeof(openwifi_5GHz_channels));
1876 
1877 	memcpy(priv->rates_2GHz, openwifi_2GHz_rates, sizeof(openwifi_2GHz_rates));
1878 	memcpy(priv->rates_5GHz, openwifi_5GHz_rates, sizeof(openwifi_5GHz_rates));
1879 	memcpy(priv->channels_2GHz, openwifi_2GHz_channels, sizeof(openwifi_2GHz_channels));
1880 	memcpy(priv->channels_5GHz, openwifi_5GHz_channels, sizeof(openwifi_5GHz_channels));
1881 
1882 	priv->band = BAND_5_8GHZ; //this can be changed by band _rf_set_channel() (2.4GHz ERP(OFDM)) (5GHz OFDM)
1883 	priv->channel = 44;  //currently useless. this can be changed by band _rf_set_channel()
1884 	priv->use_short_slot = false; //this can be changed by openwifi_bss_info_changed: BSS_CHANGED_ERP_SLOT
1885 	priv->ampdu_reference = 0;
1886 
1887 	priv->band_2GHz.band = NL80211_BAND_2GHZ;
1888 	priv->band_2GHz.channels = priv->channels_2GHz;
1889 	priv->band_2GHz.n_channels = ARRAY_SIZE(priv->channels_2GHz);
1890 	priv->band_2GHz.bitrates = priv->rates_2GHz;
1891 	priv->band_2GHz.n_bitrates = ARRAY_SIZE(priv->rates_2GHz);
1892 	priv->band_2GHz.ht_cap.ht_supported = true;
1893 	priv->band_2GHz.ht_cap.cap = IEEE80211_HT_CAP_SGI_20;
1894 	priv->band_2GHz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1895 	priv->band_2GHz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2;
1896 	memset(&priv->band_2GHz.ht_cap.mcs, 0, sizeof(priv->band_2GHz.ht_cap.mcs));
1897 	priv->band_2GHz.ht_cap.mcs.rx_mask[0] = 0xff;
1898 	priv->band_2GHz.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1899 	dev->wiphy->bands[NL80211_BAND_2GHZ] = &(priv->band_2GHz);
1900 
1901 	priv->band_5GHz.band = NL80211_BAND_5GHZ;
1902 	priv->band_5GHz.channels = priv->channels_5GHz;
1903 	priv->band_5GHz.n_channels = ARRAY_SIZE(priv->channels_5GHz);
1904 	priv->band_5GHz.bitrates = priv->rates_5GHz;
1905 	priv->band_5GHz.n_bitrates = ARRAY_SIZE(priv->rates_5GHz);
1906 	priv->band_5GHz.ht_cap.ht_supported = true;
1907 	priv->band_5GHz.ht_cap.cap = IEEE80211_HT_CAP_SGI_20;
1908 	priv->band_5GHz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1909 	priv->band_5GHz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2;
1910 	memset(&priv->band_5GHz.ht_cap.mcs, 0, sizeof(priv->band_5GHz.ht_cap.mcs));
1911 	priv->band_5GHz.ht_cap.mcs.rx_mask[0] = 0xff;
1912 	priv->band_5GHz.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1913 	dev->wiphy->bands[NL80211_BAND_5GHZ] = &(priv->band_5GHz);
1914 
1915 	printk("%s openwifi_dev_probe: band_2GHz.n_channels %d n_bitrates %d band_5GHz.n_channels %d n_bitrates %d\n",sdr_compatible_str,
1916 	priv->band_2GHz.n_channels,priv->band_2GHz.n_bitrates,priv->band_5GHz.n_channels,priv->band_5GHz.n_bitrates);
1917 
1918 	ieee80211_hw_set(dev, HOST_BROADCAST_PS_BUFFERING);
1919 	ieee80211_hw_set(dev, RX_INCLUDES_FCS);
1920 	ieee80211_hw_set(dev, BEACON_TX_STATUS);
1921 	ieee80211_hw_set(dev, AMPDU_AGGREGATION);
1922 
1923 	dev->vif_data_size = sizeof(struct openwifi_vif);
1924 	dev->wiphy->interface_modes =
1925 			BIT(NL80211_IFTYPE_MONITOR)|
1926 			BIT(NL80211_IFTYPE_P2P_GO) |
1927 			BIT(NL80211_IFTYPE_P2P_CLIENT) |
1928 			BIT(NL80211_IFTYPE_AP) |
1929 			BIT(NL80211_IFTYPE_STATION) |
1930 			BIT(NL80211_IFTYPE_ADHOC) |
1931 			BIT(NL80211_IFTYPE_MESH_POINT) |
1932 			BIT(NL80211_IFTYPE_OCB);
1933 	dev->wiphy->iface_combinations = &openwifi_if_comb;
1934 	dev->wiphy->n_iface_combinations = 1;
1935 
1936 	dev->wiphy->regulatory_flags = (REGULATORY_STRICT_REG|REGULATORY_CUSTOM_REG); // use our own config within strict regulation
1937 	//dev->wiphy->regulatory_flags = REGULATORY_CUSTOM_REG; // use our own config
1938 	wiphy_apply_custom_regulatory(dev->wiphy, &sdr_regd);
1939 
1940 	chip_name = "ZYNQ";
1941 
1942 	/* we declare to MAC80211 all the queues except for beacon queue
1943 	 * that will be eventually handled by DRV.
1944 	 * TX rings are arranged in such a way that lower is the IDX,
1945 	 * higher is the priority, in order to achieve direct mapping
1946 	 * with mac80211, however the beacon queue is an exception and it
1947 	 * is mapped on the highst tx ring IDX.
1948 	 */
1949 	dev->queues = MAX_NUM_HW_QUEUE;
1950 	//dev->queues = 1;
1951 
1952 	ieee80211_hw_set(dev, SIGNAL_DBM);
1953 
1954 	wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1955 
1956 	priv->rf = &ad9361_rf_ops;
1957 
1958 	memset(priv->dest_mac_addr_queue_map,0,sizeof(priv->dest_mac_addr_queue_map));
1959 	priv->slice_idx = 0xFFFFFFFF;
1960 
1961 	sg_init_table(&(priv->tx_sg), 1);
1962 
1963 	get_random_bytes(&rand_val, sizeof(rand_val));
1964     rand_val%=250;
1965 	priv->mac_addr[0]=0x66;	priv->mac_addr[1]=0x55;	priv->mac_addr[2]=0x44;	priv->mac_addr[3]=0x33;	priv->mac_addr[4]=0x22;
1966 	priv->mac_addr[5]=rand_val+1;
1967 	//priv->mac_addr[5]=0x11;
1968 	if (!is_valid_ether_addr(priv->mac_addr)) {
1969 		printk(KERN_WARNING "%s openwifi_dev_probe: WARNING Invalid hwaddr! Using randomly generated MAC addr\n",sdr_compatible_str);
1970 		eth_random_addr(priv->mac_addr);
1971 	} else {
1972 		printk("%s openwifi_dev_probe: mac_addr %02x:%02x:%02x:%02x:%02x:%02x\n",sdr_compatible_str,priv->mac_addr[0],priv->mac_addr[1],priv->mac_addr[2],priv->mac_addr[3],priv->mac_addr[4],priv->mac_addr[5]);
1973 	}
1974 	SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);
1975 
1976 	spin_lock_init(&priv->lock);
1977 
1978 	err = ieee80211_register_hw(dev);
1979 	if (err) {
1980 		pr_err(KERN_ERR "%s openwifi_dev_probe: WARNING Cannot register device\n",sdr_compatible_str);
1981 		goto err_free_dev;
1982 	} else {
1983 		printk("%s openwifi_dev_probe: ieee80211_register_hw %d\n",sdr_compatible_str, err);
1984 	}
1985 
1986 	// // //--------------------hook leds (not complete yet)--------------------------------
1987 	// tmp_dev = bus_find_device( &platform_bus_type, NULL, "leds", custom_match_platform_dev ); //leds is the name in devicetree, not "compatible" field
1988 	// if (!tmp_dev) {
1989 	// 	printk(KERN_ERR "%s bus_find_device platform_bus_type leds-gpio failed\n",sdr_compatible_str);
1990 	// 	err = -ENOMEM;
1991 	// 	goto err_free_dev;
1992 	// }
1993 
1994 	// tmp_pdev = to_platform_device(tmp_dev);
1995 	// if (!tmp_pdev) {
1996 	// 	printk(KERN_ERR "%s to_platform_device failed for leds-gpio\n",sdr_compatible_str);
1997 	// 	err = -ENOMEM;
1998 	// 	goto err_free_dev;
1999 	// }
2000 
2001 	// tmp_led_priv = platform_get_drvdata(tmp_pdev);
2002 	// if (!tmp_led_priv) {
2003 	// 	printk(KERN_ERR "%s platform_get_drvdata failed for leds-gpio\n",sdr_compatible_str);
2004 	// 	err = -ENOMEM;
2005 	// 	goto err_free_dev;
2006 	// }
2007 	// printk("%s openwifi_dev_probe: leds-gpio detect %d leds!\n",sdr_compatible_str, tmp_led_priv->num_leds);
2008 	// if (tmp_led_priv->num_leds!=4){
2009 	// 	printk(KERN_ERR "%s WARNING we expect 4 leds, but actual %d leds\n",sdr_compatible_str,tmp_led_priv->num_leds);
2010 	// 	err = -ENOMEM;
2011 	// 	goto err_free_dev;
2012 	// }
2013 	// gpiod_set_value(tmp_led_priv->leds[0].gpiod, 1);//light it
2014 	// gpiod_set_value(tmp_led_priv->leds[3].gpiod, 0);//black it
2015 	// priv->num_led = tmp_led_priv->num_leds;
2016 	// priv->led[0] = &(tmp_led_priv->leds[0].cdev);
2017 	// priv->led[1] = &(tmp_led_priv->leds[1].cdev);
2018 	// priv->led[2] = &(tmp_led_priv->leds[2].cdev);
2019 	// priv->led[3] = &(tmp_led_priv->leds[3].cdev);
2020 
2021 	// snprintf(priv->led_name[0], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::radio", wiphy_name(dev->wiphy));
2022 	// snprintf(priv->led_name[1], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::assoc", wiphy_name(dev->wiphy));
2023 	// snprintf(priv->led_name[2], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::tx", wiphy_name(dev->wiphy));
2024 	// snprintf(priv->led_name[3], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::rx", wiphy_name(dev->wiphy));
2025 
2026 	wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
2027 		   priv->mac_addr, chip_name, priv->rf->name);
2028 
2029 	openwifi_rfkill_init(dev);
2030 	return 0;
2031 
2032  err_free_dev:
2033 	ieee80211_free_hw(dev);
2034 
2035 	return err;
2036 }
2037 
2038 static int openwifi_dev_remove(struct platform_device *pdev)
2039 {
2040 	struct ieee80211_hw *dev = platform_get_drvdata(pdev);
2041 
2042 	if (!dev) {
2043 		pr_info("%s openwifi_dev_remove: dev %p\n", sdr_compatible_str, (void*)dev);
2044 		return(-1);
2045 	}
2046 
2047 	openwifi_rfkill_exit(dev);
2048 	ieee80211_unregister_hw(dev);
2049 	ieee80211_free_hw(dev);
2050 	return(0);
2051 }
2052 
2053 static struct platform_driver openwifi_dev_driver = {
2054 	.driver = {
2055 		.name = "sdr,sdr",
2056 		.owner = THIS_MODULE,
2057 		.of_match_table = openwifi_dev_of_ids,
2058 	},
2059 	.probe = openwifi_dev_probe,
2060 	.remove = openwifi_dev_remove,
2061 };
2062 
2063 module_platform_driver(openwifi_dev_driver);
2064