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