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