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