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