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