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