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