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