xref: /openwifi/driver/sdr.c (revision e21492d7679da1db9902db958d07a536e873a875)
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 	// //keep software registers persistent between NIC down and up for multiple times
1167 	/*memset(priv->drv_tx_reg_val, 0, sizeof(priv->drv_tx_reg_val));
1168 	memset(priv->drv_rx_reg_val, 0, sizeof(priv->drv_rx_reg_val));
1169 	memset(priv->drv_xpu_reg_val, 0, sizeof(priv->drv_xpu_reg_val));
1170 	memset(priv->rf_reg_val,0,sizeof(priv->rf_reg_val));
1171 	priv->drv_xpu_reg_val[DRV_XPU_REG_IDX_GIT_REV] = GIT_REV;*/
1172 
1173 	//turn on radio
1174 	openwifi_set_antenna(dev, priv->runtime_tx_ant_cfg, priv->runtime_rx_ant_cfg);
1175 	reg = ad9361_get_tx_atten(priv->ad9361_phy, ((priv->runtime_tx_ant_cfg==1 || priv->runtime_tx_ant_cfg==3)?1:2));
1176 	if (reg == (AD9361_RADIO_ON_TX_ATT+priv->rf_reg_val[RF_TX_REG_IDX_ATT])) {
1177 		priv->rfkill_off = 1;// 0 off, 1 on
1178 		printk("%s openwifi_start: rfkill radio on\n",sdr_compatible_str);
1179 	}
1180 	else
1181 		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]);
1182 
1183 	rx_intf_api->hw_init(priv->rx_intf_cfg,8,8);
1184 	tx_intf_api->hw_init(priv->tx_intf_cfg,8,8,priv->fpga_type);
1185 	openofdm_tx_api->hw_init(priv->openofdm_tx_cfg);
1186 	openofdm_rx_api->hw_init(priv->openofdm_rx_cfg);
1187 	xpu_api->hw_init(priv->xpu_cfg);
1188 
1189 	agc_gain_delay = 50; //samples
1190 	rssi_half_db_offset = 150; // to be consistent
1191 	xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
1192 	xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
1193 
1194 	openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write(0);
1195 	// rssi_half_db_th = 87<<1; // -62dBm // will setup in runtime in _rf_set_channel
1196 	// xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
1197 	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
1198 
1199 	//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!)
1200 	//xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51)<<16)|0 );//now our tx send out I/Q immediately
1201 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51+23)<<16)|(0+23) );//we have more time when we use FIR in AD9361
1202 
1203 	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)
1204 	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)
1205 
1206 	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
1207 
1208 	// //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
1209 	// xpu_api->XPU_REG_BB_RF_DELAY_write(47);//add .5us for slightly longer fir -- already in xpu.c
1210 	xpu_api->XPU_REG_MAC_ADDR_write(priv->mac_addr);
1211 
1212 	// setup time schedule of 4 slices
1213 	// slice 0
1214 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
1215 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
1216 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
1217 
1218 	// slice 1
1219 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
1220 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
1221 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
1222 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
1223 
1224 	// slice 2
1225 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
1226 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
1227 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
1228 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
1229 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
1230 
1231 	// slice 3
1232 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
1233 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
1234 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
1235 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
1236 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
1237 
1238 	// all slice sync rest
1239 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
1240 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
1241 
1242 	//xpu_api->XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(priv->mac_addr + 4) )) );
1243 	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);
1244 	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);
1245 
1246 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30004); //disable tx interrupt
1247 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable rx interrupt by interrupt test mode
1248 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status
1249 
1250 	if (test_mode==1) {
1251 		printk("%s openwifi_start: test_mode==1\n",sdr_compatible_str);
1252 		goto normal_out;
1253 	}
1254 
1255 	priv->rx_chan = dma_request_slave_channel(&(priv->pdev->dev), "rx_dma_s2mm");
1256 	if (IS_ERR(priv->rx_chan) || priv->rx_chan==NULL) {
1257 		ret = PTR_ERR(priv->rx_chan);
1258 		pr_err("%s openwifi_start: No Rx channel ret %d priv->rx_chan 0x%p\n",sdr_compatible_str, ret, priv->rx_chan);
1259 		goto err_dma;
1260 	}
1261 
1262 	priv->tx_chan = dma_request_slave_channel(&(priv->pdev->dev), "tx_dma_mm2s");
1263 	if (IS_ERR(priv->tx_chan) || priv->tx_chan==NULL) {
1264 		ret = PTR_ERR(priv->tx_chan);
1265 		pr_err("%s openwifi_start: No Tx channel ret %d priv->tx_chan 0x%p\n",sdr_compatible_str, ret, priv->tx_chan);
1266 		goto err_dma;
1267 	}
1268 	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);
1269 
1270 	ret = openwifi_init_rx_ring(priv);
1271 	if (ret) {
1272 		printk("%s openwifi_start: openwifi_init_rx_ring ret %d\n", sdr_compatible_str,ret);
1273 		goto err_free_rings;
1274 	}
1275 
1276 	priv->seqno=0;
1277 	for (i=0; i<MAX_NUM_SW_QUEUE; i++) {
1278 		if ((ret = openwifi_init_tx_ring(priv, i))) {
1279 			printk("%s openwifi_start: openwifi_init_tx_ring %d ret %d\n", sdr_compatible_str, i, ret);
1280 			goto err_free_rings;
1281 		}
1282 	}
1283 
1284 	if ( (ret = rx_dma_setup(dev)) ) {
1285 		printk("%s openwifi_start: rx_dma_setup ret %d\n", sdr_compatible_str,ret);
1286 		goto err_free_rings;
1287 	}
1288 
1289 	priv->irq_rx = irq_of_parse_and_map(priv->pdev->dev.of_node, 1);
1290 	ret = request_irq(priv->irq_rx, openwifi_rx_interrupt,
1291 			IRQF_SHARED, "sdr,rx_pkt_intr", dev);
1292 	if (ret) {
1293 		wiphy_err(dev->wiphy, "openwifi_start:failed to register IRQ handler openwifi_rx_interrupt\n");
1294 		goto err_free_rings;
1295 	} else {
1296 		printk("%s openwifi_start: irq_rx %d\n", sdr_compatible_str, priv->irq_rx);
1297 	}
1298 
1299 	priv->irq_tx = irq_of_parse_and_map(priv->pdev->dev.of_node, 3);
1300 	ret = request_irq(priv->irq_tx, openwifi_tx_interrupt,
1301 			IRQF_SHARED, "sdr,tx_itrpt", dev);
1302 	if (ret) {
1303 		wiphy_err(dev->wiphy, "openwifi_start: failed to register IRQ handler openwifi_tx_interrupt\n");
1304 		goto err_free_rings;
1305 	} else {
1306 		printk("%s openwifi_start: irq_tx %d\n", sdr_compatible_str, priv->irq_tx);
1307 	}
1308 
1309 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x000); // enable rx interrupt get normal fcs valid pass through ddc to ARM
1310 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x4); //enable tx interrupt
1311 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(0); // release M AXIS
1312 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0); // reset tsf timer
1313 
1314 	//ieee80211_wake_queue(dev, 0);
1315 
1316 normal_out:
1317 	printk("%s openwifi_start: normal end\n", sdr_compatible_str);
1318 	return 0;
1319 
1320 err_free_rings:
1321 	openwifi_free_rx_ring(priv);
1322 	for (i=0; i<MAX_NUM_SW_QUEUE; i++)
1323 		openwifi_free_tx_ring(priv, i);
1324 
1325 err_dma:
1326 	ret = -1;
1327 	printk("%s openwifi_start: abnormal end ret %d\n", sdr_compatible_str, ret);
1328 	return ret;
1329 }
1330 
1331 static void openwifi_stop(struct ieee80211_hw *dev)
1332 {
1333 	struct openwifi_priv *priv = dev->priv;
1334 	u32 reg, reg1;
1335 	int i;
1336 
1337 	if (test_mode==1){
1338 		pr_info("%s openwifi_stop: test_mode==1\n", sdr_compatible_str);
1339 		goto normal_out;
1340 	}
1341 
1342 	//turn off radio
1343 	#if 1
1344 	ad9361_tx_mute(priv->ad9361_phy, 1);
1345 	reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1346 	reg1 = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1347 	if (reg == AD9361_RADIO_OFF_TX_ATT && reg1 == AD9361_RADIO_OFF_TX_ATT ) {
1348 		priv->rfkill_off = 0;// 0 off, 1 on
1349 		printk("%s openwifi_stop: rfkill radio off\n",sdr_compatible_str);
1350 	}
1351 	else
1352 		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);
1353 	#endif
1354 
1355 	//ieee80211_stop_queue(dev, 0);
1356 	tx_intf_api->TX_INTF_REG_INTERRUPT_SEL_write(0x30004); //disable tx interrupt
1357 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); // disable fcs_valid by interrupt test mode
1358 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status
1359 
1360 	for (i=0; i<MAX_NUM_VIF; i++) {
1361 		priv->vif[i] = NULL;
1362 	}
1363 
1364 	openwifi_free_rx_ring(priv);
1365 	for (i=0; i<MAX_NUM_SW_QUEUE; i++)
1366 		openwifi_free_tx_ring(priv, i);
1367 
1368 	pr_info("%s openwifi_stop: dropped channel %s\n", sdr_compatible_str, dma_chan_name(priv->rx_chan));
1369 	dmaengine_terminate_all(priv->rx_chan);
1370 	dma_release_channel(priv->rx_chan);
1371 	pr_info("%s openwifi_stop: dropped channel %s\n", sdr_compatible_str, dma_chan_name(priv->tx_chan));
1372 	dmaengine_terminate_all(priv->tx_chan);
1373 	dma_release_channel(priv->tx_chan);
1374 
1375 	//priv->rf->stop(dev);
1376 
1377 	free_irq(priv->irq_rx, dev);
1378 	free_irq(priv->irq_tx, dev);
1379 
1380 normal_out:
1381 	printk("%s openwifi_stop\n", sdr_compatible_str);
1382 }
1383 
1384 static u64 openwifi_get_tsf(struct ieee80211_hw *dev,
1385 			   struct ieee80211_vif *vif)
1386 {
1387 	u32 tsft_low, tsft_high;
1388 
1389 	tsft_low = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
1390 	tsft_high = xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read();
1391 	//printk("%s openwifi_get_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low);
1392 	return( ( (u64)tsft_low ) | ( ((u64)tsft_high)<<32 ) );
1393 }
1394 
1395 static void openwifi_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf)
1396 {
1397 	u32 tsft_high = ((tsf >> 32)&0xffffffff);
1398 	u32 tsft_low  = (tsf&0xffffffff);
1399 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(tsft_high,tsft_low);
1400 	printk("%s openwifi_set_tsf: %08x%08x\n", sdr_compatible_str,tsft_high,tsft_low);
1401 }
1402 
1403 static void openwifi_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1404 {
1405 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
1406 	printk("%s openwifi_reset_tsf\n", sdr_compatible_str);
1407 }
1408 
1409 static int openwifi_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1410 {
1411 	printk("%s openwifi_set_rts_threshold WARNING value %d\n", sdr_compatible_str,value);
1412 	return(0);
1413 }
1414 
1415 static void openwifi_beacon_work(struct work_struct *work)
1416 {
1417 	struct openwifi_vif *vif_priv =
1418 		container_of(work, struct openwifi_vif, beacon_work.work);
1419 	struct ieee80211_vif *vif =
1420 		container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
1421 	struct ieee80211_hw *dev = vif_priv->dev;
1422 	struct ieee80211_mgmt *mgmt;
1423 	struct sk_buff *skb;
1424 
1425 	/* don't overflow the tx ring */
1426 	if (ieee80211_queue_stopped(dev, 0))
1427 		goto resched;
1428 
1429 	/* grab a fresh beacon */
1430 	skb = ieee80211_beacon_get(dev, vif);
1431 	if (!skb)
1432 		goto resched;
1433 
1434 	/*
1435 	 * update beacon timestamp w/ TSF value
1436 	 * TODO: make hardware update beacon timestamp
1437 	 */
1438 	mgmt = (struct ieee80211_mgmt *)skb->data;
1439 	mgmt->u.beacon.timestamp = cpu_to_le64(openwifi_get_tsf(dev, vif));
1440 
1441 	/* TODO: use actual beacon queue */
1442 	skb_set_queue_mapping(skb, 0);
1443 	openwifi_tx(dev, NULL, skb);
1444 
1445 resched:
1446 	/*
1447 	 * schedule next beacon
1448 	 * TODO: use hardware support for beacon timing
1449 	 */
1450 	schedule_delayed_work(&vif_priv->beacon_work,
1451 			usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
1452 }
1453 
1454 static int openwifi_add_interface(struct ieee80211_hw *dev,
1455 				 struct ieee80211_vif *vif)
1456 {
1457 	int i;
1458 	struct openwifi_priv *priv = dev->priv;
1459 	struct openwifi_vif *vif_priv;
1460 
1461 	switch (vif->type) {
1462 	case NL80211_IFTYPE_AP:
1463 	case NL80211_IFTYPE_STATION:
1464 	case NL80211_IFTYPE_ADHOC:
1465 	case NL80211_IFTYPE_MONITOR:
1466 	case NL80211_IFTYPE_MESH_POINT:
1467 		break;
1468 	default:
1469 		return -EOPNOTSUPP;
1470 	}
1471 	// let's support more than 1 interface
1472 	for (i=0; i<MAX_NUM_VIF; i++) {
1473 		if (priv->vif[i] == NULL)
1474 			break;
1475 	}
1476 
1477 	printk("%s openwifi_add_interface start. vif for loop result %d\n", sdr_compatible_str, i);
1478 
1479 	if (i==MAX_NUM_VIF)
1480 		return -EBUSY;
1481 
1482 	priv->vif[i] = vif;
1483 
1484 	/* Initialize driver private area */
1485 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1486 	vif_priv->idx = i;
1487 
1488 	vif_priv->dev = dev;
1489 	INIT_DELAYED_WORK(&vif_priv->beacon_work, openwifi_beacon_work);
1490 	vif_priv->enable_beacon = false;
1491 
1492 	printk("%s openwifi_add_interface end with vif idx %d\n", sdr_compatible_str,vif_priv->idx);
1493 
1494 	return 0;
1495 }
1496 
1497 static void openwifi_remove_interface(struct ieee80211_hw *dev,
1498 				     struct ieee80211_vif *vif)
1499 {
1500 	struct openwifi_vif *vif_priv;
1501 	struct openwifi_priv *priv = dev->priv;
1502 
1503 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1504 	priv->vif[vif_priv->idx] = NULL;
1505 	printk("%s openwifi_remove_interface vif idx %d\n", sdr_compatible_str, vif_priv->idx);
1506 }
1507 
1508 static int openwifi_config(struct ieee80211_hw *dev, u32 changed)
1509 {
1510 	struct openwifi_priv *priv = dev->priv;
1511 	struct ieee80211_conf *conf = &dev->conf;
1512 
1513 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
1514 		priv->rf->set_chan(dev, conf);
1515 	else
1516 		printk("%s openwifi_config changed flag %08x\n", sdr_compatible_str, changed);
1517 
1518 	return 0;
1519 }
1520 
1521 static void openwifi_bss_info_changed(struct ieee80211_hw *dev,
1522 				     struct ieee80211_vif *vif,
1523 				     struct ieee80211_bss_conf *info,
1524 				     u32 changed)
1525 {
1526 	struct openwifi_priv *priv = dev->priv;
1527 	struct openwifi_vif *vif_priv;
1528 	u32 bssid_low, bssid_high;
1529 
1530 	vif_priv = (struct openwifi_vif *)&vif->drv_priv;
1531 
1532 	//be careful: we don have valid chip, so registers addresses in priv->map->BSSID[0] are not valid! should not print it!
1533 	//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]);
1534 	if (changed & BSS_CHANGED_BSSID) {
1535 		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]);
1536 		// write new bssid to our HW, and do not change bssid filter
1537 		//u32 bssid_filter_high = xpu_api->XPU_REG_BSSID_FILTER_HIGH_read();
1538 		bssid_low = ( *( (u32*)(info->bssid) ) );
1539 		bssid_high = ( *( (u16*)(info->bssid+4) ) );
1540 
1541 		//bssid_filter_high = (bssid_filter_high&0x80000000);
1542 		//bssid_high = (bssid_high|bssid_filter_high);
1543 		xpu_api->XPU_REG_BSSID_FILTER_LOW_write(bssid_low);
1544 		xpu_api->XPU_REG_BSSID_FILTER_HIGH_write(bssid_high);
1545 	}
1546 
1547 	if (changed & BSS_CHANGED_BEACON_INT) {
1548 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_INT %x\n",sdr_compatible_str,info->beacon_int);
1549 	}
1550 
1551 	if (changed & BSS_CHANGED_TXPOWER)
1552 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_TXPOWER %x\n",sdr_compatible_str,info->txpower);
1553 
1554 	if (changed & BSS_CHANGED_ERP_CTS_PROT)
1555 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_ERP_CTS_PROT %x\n",sdr_compatible_str,info->use_cts_prot);
1556 
1557 	if (changed & BSS_CHANGED_BASIC_RATES)
1558 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BASIC_RATES %x\n",sdr_compatible_str,info->basic_rates);
1559 
1560 	if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) {
1561 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_ERP_SLOT %d BSS_CHANGED_ERP_PREAMBLE %d short slot %d\n",sdr_compatible_str,
1562 		changed&BSS_CHANGED_ERP_SLOT,changed&BSS_CHANGED_ERP_PREAMBLE,info->use_short_slot);
1563 		if (info->use_short_slot && priv->use_short_slot==false) {
1564 			priv->use_short_slot=true;
1565 			xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
1566 		} else if ((!info->use_short_slot) && priv->use_short_slot==true) {
1567 			priv->use_short_slot=false;
1568 			xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
1569 		}
1570 	}
1571 
1572 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
1573 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_ENABLED\n",sdr_compatible_str);
1574 		vif_priv->enable_beacon = info->enable_beacon;
1575 	}
1576 
1577 	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
1578 		cancel_delayed_work_sync(&vif_priv->beacon_work);
1579 		if (vif_priv->enable_beacon)
1580 			schedule_work(&vif_priv->beacon_work.work);
1581 		printk("%s openwifi_bss_info_changed WARNING BSS_CHANGED_BEACON_ENABLED %d BSS_CHANGED_BEACON %d\n",sdr_compatible_str,
1582 		changed&BSS_CHANGED_BEACON_ENABLED,changed&BSS_CHANGED_BEACON);
1583 	}
1584 }
1585 // helper function
1586 u32 log2val(u32 val){
1587 	u32 ret_val = 0 ;
1588 	while(val>1){
1589 		val = val >> 1 ;
1590 		ret_val ++ ;
1591 	}
1592 	return ret_val ;
1593 }
1594 
1595 static int openwifi_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
1596 	      const struct ieee80211_tx_queue_params *params)
1597 {
1598 	u32 reg_val, cw_min_exp, cw_max_exp;
1599 
1600 	printk("%s openwifi_conf_tx: [queue %d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d, aifs and txop ignored\n",
1601 		  sdr_compatible_str,queue,params->aifs,params->cw_min,params->cw_max,params->txop);
1602 
1603 	reg_val=xpu_api->XPU_REG_CSMA_CFG_read();
1604 	cw_min_exp = (log2val(params->cw_min + 1) & 0x0F);
1605 	cw_max_exp = (log2val(params->cw_max + 1) & 0x0F);
1606 	switch(queue){
1607 		case 0: reg_val = ( (reg_val & 0xFFFFFF00) | ((cw_min_exp | (cw_max_exp << 4)) << 0) );  break;
1608 		case 1: reg_val = ( (reg_val & 0xFFFF00FF) | ((cw_min_exp | (cw_max_exp << 4)) << 8) );  break;
1609 		case 2: reg_val = ( (reg_val & 0xFF00FFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 16) ); break;
1610 		case 3: reg_val = ( (reg_val & 0x00FFFFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 24) ); break;
1611 		default: printk("%s openwifi_conf_tx: WARNING queue %d does not exist",sdr_compatible_str, queue); return(0);
1612 	}
1613 	xpu_api->XPU_REG_CSMA_CFG_write(reg_val);
1614 	return(0);
1615 }
1616 
1617 static u64 openwifi_prepare_multicast(struct ieee80211_hw *dev,
1618 				     struct netdev_hw_addr_list *mc_list)
1619 {
1620 	printk("%s openwifi_prepare_multicast\n", sdr_compatible_str);
1621 	return netdev_hw_addr_list_count(mc_list);
1622 }
1623 
1624 static void openwifi_configure_filter(struct ieee80211_hw *dev,
1625 				     unsigned int changed_flags,
1626 				     unsigned int *total_flags,
1627 				     u64 multicast)
1628 {
1629 	u32 filter_flag;
1630 
1631 	(*total_flags) &= SDR_SUPPORTED_FILTERS;
1632 	(*total_flags) |= FIF_ALLMULTI; //because we need to pass all multicast (no matter it is for us or not) to upper layer
1633 
1634 	filter_flag = (*total_flags);
1635 
1636 	filter_flag = (filter_flag|UNICAST_FOR_US|BROADCAST_ALL_ONE|BROADCAST_ALL_ZERO);
1637 	//filter_flag = (filter_flag|UNICAST_FOR_US|BROADCAST_ALL_ONE|BROADCAST_ALL_ZERO|MONITOR_ALL); // all pkt will be delivered to arm
1638 
1639 	//if (priv->vif[0]->type == NL80211_IFTYPE_MONITOR)
1640 	if ((filter_flag&0xf0) == 0xf0) //FIF_BCN_PRBRESP_PROMISC/FIF_CONTROL/FIF_OTHER_BSS/FIF_PSPOLL are set means monitor mode
1641 		filter_flag = (filter_flag|MONITOR_ALL);
1642 	else
1643 		filter_flag = (filter_flag&(~MONITOR_ALL));
1644 
1645 	if ( !(filter_flag&FIF_BCN_PRBRESP_PROMISC) )
1646 		filter_flag = (filter_flag|MY_BEACON);
1647 
1648 	filter_flag = (filter_flag|FIF_PSPOLL);
1649 
1650 	xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag|HIGH_PRIORITY_DISCARD_FLAG);
1651 	//xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag); //do not discard any pkt
1652 
1653 	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,
1654 	(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);
1655 }
1656 
1657 static int openwifi_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params)
1658 {
1659 	struct ieee80211_sta *sta = params->sta;
1660 	enum ieee80211_ampdu_mlme_action action = params->action;
1661 	// struct openwifi_priv *priv = hw->priv;
1662 	u16 max_tx_bytes, buf_size;
1663 	u32 ampdu_action_config;
1664 
1665 	switch (action)
1666 	{
1667 		case IEEE80211_AMPDU_TX_START:
1668 			ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, params->tid);
1669 			break;
1670 		case IEEE80211_AMPDU_TX_STOP_CONT:
1671 		case IEEE80211_AMPDU_TX_STOP_FLUSH:
1672 		case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1673 			ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, params->tid);
1674 			break;
1675 		case IEEE80211_AMPDU_TX_OPERATIONAL:
1676 			buf_size = 4;
1677 //			buf_size = (params->buf_size) - 1;
1678 			max_tx_bytes = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor)) - 1;
1679 			ampdu_action_config = ( sta->ht_cap.ampdu_density<<24 | buf_size<<16 | max_tx_bytes );
1680 			tx_intf_api->TX_INTF_REG_AMPDU_ACTION_CONFIG_write(ampdu_action_config);
1681 			break;
1682 		case IEEE80211_AMPDU_RX_START:
1683 			printk("%s openwifi_ampdu_action: start RX aggregation. tid %d\n", sdr_compatible_str, params->tid);
1684 			break;
1685 		case IEEE80211_AMPDU_RX_STOP:
1686 			printk("%s openwifi_ampdu_action: stop RX aggregation. tid %d\n", sdr_compatible_str, params->tid);
1687 			break;
1688 		default:
1689 			return -EOPNOTSUPP;
1690 	}
1691 
1692 	return 0;
1693 }
1694 
1695 static const struct ieee80211_ops openwifi_ops = {
1696 	.tx			       = openwifi_tx,
1697 	.start			   = openwifi_start,
1698 	.stop			   = openwifi_stop,
1699 	.add_interface	   = openwifi_add_interface,
1700 	.remove_interface  = openwifi_remove_interface,
1701 	.config			   = openwifi_config,
1702 	.bss_info_changed  = openwifi_bss_info_changed,
1703 	.conf_tx		   = openwifi_conf_tx,
1704 	.prepare_multicast = openwifi_prepare_multicast,
1705 	.configure_filter  = openwifi_configure_filter,
1706 	.rfkill_poll	   = openwifi_rfkill_poll,
1707 	.get_tsf		   = openwifi_get_tsf,
1708 	.set_tsf		   = openwifi_set_tsf,
1709 	.reset_tsf		   = openwifi_reset_tsf,
1710 	.set_rts_threshold = openwifi_set_rts_threshold,
1711 	.ampdu_action      = openwifi_ampdu_action,
1712 	.testmode_cmd	   = openwifi_testmode_cmd,
1713 };
1714 
1715 static const struct of_device_id openwifi_dev_of_ids[] = {
1716 	{ .compatible = "sdr,sdr", },
1717 	{}
1718 };
1719 MODULE_DEVICE_TABLE(of, openwifi_dev_of_ids);
1720 
1721 static int custom_match_spi_dev(struct device *dev, void *data)
1722 {
1723     const char *name = data;
1724 
1725 	bool ret = sysfs_streq(name, dev->of_node->name);
1726 	printk("%s custom_match_spi_dev %s %s %d\n", sdr_compatible_str,name, dev->of_node->name, ret);
1727 	return ret;
1728 }
1729 
1730 static int custom_match_platform_dev(struct device *dev, void *data)
1731 {
1732 	struct platform_device *plat_dev = to_platform_device(dev);
1733 	const char *name = data;
1734 	char *name_in_sys_bus_platform_devices = strstr(plat_dev->name, name);
1735 	bool match_flag = (name_in_sys_bus_platform_devices != NULL);
1736 
1737 	if (match_flag) {
1738 		printk("%s custom_match_platform_dev %s\n", sdr_compatible_str,plat_dev->name);
1739 	}
1740 	return(match_flag);
1741 }
1742 
1743 static int openwifi_dev_probe(struct platform_device *pdev)
1744 {
1745 	struct ieee80211_hw *dev;
1746 	struct openwifi_priv *priv;
1747 	int err=1, rand_val;
1748 	const char *chip_name, *fpga_model;
1749 	u32 reg;//, reg1;
1750 
1751 	struct device_node *np = pdev->dev.of_node;
1752 
1753 	struct device *tmp_dev;
1754 	struct platform_device *tmp_pdev;
1755 	struct iio_dev *tmp_indio_dev;
1756 	// struct gpio_leds_priv *tmp_led_priv;
1757 
1758 	printk("\n");
1759 
1760 	if (np) {
1761 		const struct of_device_id *match;
1762 
1763 		match = of_match_node(openwifi_dev_of_ids, np);
1764 		if (match) {
1765 			printk("%s openwifi_dev_probe: match!\n", sdr_compatible_str);
1766 			err = 0;
1767 		}
1768 	}
1769 
1770 	if (err)
1771 		return err;
1772 
1773 	dev = ieee80211_alloc_hw(sizeof(*priv), &openwifi_ops);
1774 	if (!dev) {
1775 		printk(KERN_ERR "%s openwifi_dev_probe: ieee80211 alloc failed\n",sdr_compatible_str);
1776 		err = -ENOMEM;
1777 		goto err_free_dev;
1778 	}
1779 
1780 	priv = dev->priv;
1781 	priv->pdev = pdev;
1782 
1783 	err = of_property_read_string(of_find_node_by_path("/"), "model", &fpga_model);
1784 	if(err < 0) {
1785 		printk("%s openwifi_dev_probe: WARNING unknown openwifi FPGA model %d\n",sdr_compatible_str, err);
1786 		priv->fpga_type = SMALL_FPGA;
1787 	} else {
1788 		// LARGE FPGAs (i.e. ZCU102, Z7035, ZC706)
1789 		if(strstr(fpga_model, "ZCU102") != NULL || strstr(fpga_model, "Z7035") != NULL || strstr(fpga_model, "ZC706") != NULL)
1790 			priv->fpga_type = LARGE_FPGA;
1791 		// SMALL FPGA: (i.e. ZED, ZC702, Z7020)
1792 		else if(strstr(fpga_model, "ZED") != NULL || strstr(fpga_model, "ZC702") != NULL || strstr(fpga_model, "Z7020") != NULL)
1793 			priv->fpga_type = SMALL_FPGA;
1794 	}
1795 
1796 	// //-------------find ad9361-phy driver for lo/channel control---------------
1797 	priv->actual_rx_lo = 0;
1798 	priv->actual_tx_lo = 0;
1799 	tmp_dev = bus_find_device( &spi_bus_type, NULL, "ad9361-phy", custom_match_spi_dev );
1800 	if (tmp_dev == NULL) {
1801 		printk(KERN_ERR "%s find_dev ad9361-phy failed\n",sdr_compatible_str);
1802 		err = -ENOMEM;
1803 		goto err_free_dev;
1804 	}
1805 	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));
1806 	if (((struct spi_device*)tmp_dev)->dev.driver_data == NULL) {
1807 		printk(KERN_ERR "%s find_dev ad9361-phy failed. dev.driver_data == NULL\n",sdr_compatible_str);
1808 		err = -ENOMEM;
1809 		goto err_free_dev;
1810 	}
1811 
1812 	priv->ad9361_phy = ad9361_spi_to_phy((struct spi_device*)tmp_dev);
1813 	if (!(priv->ad9361_phy)) {
1814 		printk(KERN_ERR "%s ad9361_spi_to_phy failed\n",sdr_compatible_str);
1815 		err = -ENOMEM;
1816 		goto err_free_dev;
1817 	}
1818 	printk("%s ad9361_spi_to_phy ad9361-phy: %s\n", sdr_compatible_str, priv->ad9361_phy->spi->modalias);
1819 
1820 	priv->ctrl_out.en_mask=0xFF;
1821 	priv->ctrl_out.index=0x16;
1822 	err = ad9361_ctrl_outs_setup(priv->ad9361_phy, &(priv->ctrl_out));
1823 	if (err < 0) {
1824 		printk("%s openwifi_dev_probe: WARNING ad9361_ctrl_outs_setup %d\n",sdr_compatible_str, err);
1825 	} else {
1826 		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);
1827 	}
1828 
1829 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_POINTER);
1830 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_POINTER 0x%02x\n",sdr_compatible_str, reg);
1831 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_ENABLE);
1832 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_ENABLE 0x%02x\n",sdr_compatible_str, reg);
1833 
1834 	// //-------------find driver: axi_ad9361 hdl ref design module, dac channel---------------
1835 	tmp_dev = bus_find_device( &platform_bus_type, NULL, "cf-ad9361-dds-core-lpc", custom_match_platform_dev );
1836 	if (!tmp_dev) {
1837 		printk(KERN_ERR "%s bus_find_device platform_bus_type cf-ad9361-dds-core-lpc failed\n",sdr_compatible_str);
1838 		err = -ENOMEM;
1839 		goto err_free_dev;
1840 	}
1841 
1842 	tmp_pdev = to_platform_device(tmp_dev);
1843 	if (!tmp_pdev) {
1844 		printk(KERN_ERR "%s to_platform_device failed\n",sdr_compatible_str);
1845 		err = -ENOMEM;
1846 		goto err_free_dev;
1847 	}
1848 
1849 	tmp_indio_dev = platform_get_drvdata(tmp_pdev);
1850 	if (!tmp_indio_dev) {
1851 		printk(KERN_ERR "%s platform_get_drvdata failed\n",sdr_compatible_str);
1852 		err = -ENOMEM;
1853 		goto err_free_dev;
1854 	}
1855 
1856 	priv->dds_st = iio_priv(tmp_indio_dev);
1857 	if (!(priv->dds_st)) {
1858 		printk(KERN_ERR "%s iio_priv failed\n",sdr_compatible_str);
1859 		err = -ENOMEM;
1860 		goto err_free_dev;
1861 	}
1862 	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);
1863 	cf_axi_dds_datasel(priv->dds_st, -1, DATA_SEL_DMA);
1864 	printk("%s openwifi_dev_probe: cf_axi_dds_datasel DATA_SEL_DMA\n",sdr_compatible_str);
1865 
1866 	// //-------------find driver: axi_ad9361 hdl ref design module, adc channel---------------
1867 	// turn off radio by muting tx
1868 	// ad9361_tx_mute(priv->ad9361_phy, 1);
1869 	// reg = ad9361_get_tx_atten(priv->ad9361_phy, 2);
1870 	// reg1 = ad9361_get_tx_atten(priv->ad9361_phy, 1);
1871 	// if (reg == AD9361_RADIO_OFF_TX_ATT && reg1 == AD9361_RADIO_OFF_TX_ATT ) {
1872 	// 	priv->rfkill_off = 0;// 0 off, 1 on
1873 	// 	printk("%s openwifi_dev_probe: rfkill radio off\n",sdr_compatible_str);
1874 	// }
1875 	// else
1876 	// 	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);
1877 
1878 	priv->last_auto_fpga_lbt_th = 134;//just to avoid uninitialized
1879 	priv->rssi_correction = 43;//this will be set in real-time by _rf_set_channel()
1880 
1881 	//priv->rf_bw = 20000000; // Signal quality issue! NOT use for now. 20MHz or 40MHz. 40MHz need ddc/duc. 20MHz works in bypass mode
1882 	priv->rf_bw = 40000000; // 20MHz or 40MHz. 40MHz need ddc/duc. 20MHz works in bypass mode
1883 
1884 	priv->xpu_cfg = XPU_NORMAL;
1885 
1886 	priv->openofdm_tx_cfg = OPENOFDM_TX_NORMAL;
1887 	priv->openofdm_rx_cfg = OPENOFDM_RX_NORMAL;
1888 
1889 	printk("%s openwifi_dev_probe: priv->rf_bw == %dHz. bool for 20000000 %d, 40000000 %d\n",sdr_compatible_str, priv->rf_bw, (priv->rf_bw==20000000) , (priv->rf_bw==40000000) );
1890 	if (priv->rf_bw == 20000000) {
1891 		priv->rx_intf_cfg = RX_INTF_BYPASS;
1892 		priv->tx_intf_cfg = TX_INTF_BYPASS;
1893 		//priv->rx_freq_offset_to_lo_MHz = 0;
1894 		//priv->tx_freq_offset_to_lo_MHz = 0;
1895 	} else if (priv->rf_bw == 40000000) {
1896 		//priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_P_10MHZ; //work
1897 		//priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1; //work
1898 
1899 		// // test ddc at central, duc at central+10M. It works. And also change rx BW from 40MHz to 20MHz in rf_init.sh. Rx sampling rate is still 40Msps
1900 		priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT0;
1901 		priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0; // Let's use rx0 tx0 as default mode, because it works for both 9361 and 9364
1902 		// // try another antenna option
1903 		//priv->rx_intf_cfg = RX_INTF_BW_20MHZ_AT_0MHZ_ANT1;
1904 		//priv->tx_intf_cfg = TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0;
1905 
1906 		#if 0
1907 		if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_N_10MHZ) {
1908 			priv->rx_freq_offset_to_lo_MHz = -10;
1909 		} else if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_P_10MHZ) {
1910 			priv->rx_freq_offset_to_lo_MHz = 10;
1911 		} else if (priv->rx_intf_cfg == DDC_BW_20MHZ_AT_0MHZ) {
1912 			priv->rx_freq_offset_to_lo_MHz = 0;
1913 		} else {
1914 			printk("%s openwifi_dev_probe: Warning! priv->rx_intf_cfg == %d\n",sdr_compatible_str,priv->rx_intf_cfg);
1915 		}
1916 		#endif
1917 	} else {
1918 		printk("%s openwifi_dev_probe: Warning! priv->rf_bw == %dHz (should be 20000000 or 40000000)\n",sdr_compatible_str, priv->rf_bw);
1919 	}
1920 
1921 	printk("%s openwifi_dev_probe: test_mode %d\n", sdr_compatible_str, test_mode);
1922 
1923 	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));
1924 	priv->runtime_rx_ant_cfg = (priv->rx_intf_cfg==RX_INTF_BW_20MHZ_AT_0MHZ_ANT0?1:2);
1925 
1926 	priv->ctrl_out.en_mask=AD9361_CTRL_OUT_EN_MASK;
1927 	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);
1928 
1929 	memset(priv->drv_rx_reg_val,0,sizeof(priv->drv_rx_reg_val));
1930 	memset(priv->drv_tx_reg_val,0,sizeof(priv->drv_tx_reg_val));
1931 	memset(priv->drv_xpu_reg_val,0,sizeof(priv->drv_xpu_reg_val));
1932 	memset(priv->rf_reg_val,0,sizeof(priv->rf_reg_val));
1933 
1934 	//let's by default turn radio on when probing
1935 	err = openwifi_set_antenna(dev, priv->runtime_tx_ant_cfg, priv->runtime_rx_ant_cfg);
1936 	if (err) {
1937 		printk("%s openwifi_dev_probe: WARNING openwifi_set_antenna FAIL %d\n",sdr_compatible_str, err);
1938 		err = -EIO;
1939 		goto err_free_dev;
1940 	}
1941 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_POINTER);
1942 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_POINTER 0x%02x\n",sdr_compatible_str, reg);
1943 	reg = ad9361_spi_read(priv->ad9361_phy->spi, REG_CTRL_OUTPUT_ENABLE);
1944 	printk("%s openwifi_dev_probe: ad9361_spi_read REG_CTRL_OUTPUT_ENABLE 0x%02x\n",sdr_compatible_str, reg);
1945 
1946 	reg = ad9361_get_tx_atten(priv->ad9361_phy, ((priv->runtime_tx_ant_cfg==1 || priv->runtime_tx_ant_cfg==3)?1:2));
1947 	if (reg == (AD9361_RADIO_ON_TX_ATT+priv->rf_reg_val[RF_TX_REG_IDX_ATT])) {
1948 		priv->rfkill_off = 1;// 0 off, 1 on
1949 		printk("%s openwifi_dev_probe: rfkill radio on\n",sdr_compatible_str);
1950 	} else
1951 		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]);
1952 
1953 	priv->drv_xpu_reg_val[DRV_XPU_REG_IDX_GIT_REV] = GIT_REV;
1954 
1955 	// //set ad9361 in certain mode
1956 	#if 0
1957 	err = ad9361_set_trx_clock_chain_freq(priv->ad9361_phy,priv->rf_bw);
1958 	printk("%s openwifi_dev_probe: ad9361_set_trx_clock_chain_freq %dHz err %d\n",sdr_compatible_str, priv->rf_bw,err);
1959 	err = ad9361_update_rf_bandwidth(priv->ad9361_phy,priv->rf_bw,priv->rf_bw);
1960 	printk("%s openwifi_dev_probe: ad9361_update_rf_bandwidth %dHz err %d\n",sdr_compatible_str, priv->rf_bw,err);
1961 
1962 	rx_intf_api->hw_init(priv->rx_intf_cfg,8,8);
1963 	tx_intf_api->hw_init(priv->tx_intf_cfg,8,8,priv->fpga_type);
1964 	openofdm_tx_api->hw_init(priv->openofdm_tx_cfg);
1965 	openofdm_rx_api->hw_init(priv->openofdm_rx_cfg);
1966 	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);
1967 	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);
1968 	#endif
1969 
1970 	dev->max_rates = 1; //maximum number of alternate rate retry stages the hw can handle.
1971 
1972 	SET_IEEE80211_DEV(dev, &pdev->dev);
1973 	platform_set_drvdata(pdev, dev);
1974 
1975 	BUILD_BUG_ON(sizeof(priv->rates_2GHz) != sizeof(openwifi_2GHz_rates));
1976 	BUILD_BUG_ON(sizeof(priv->rates_5GHz) != sizeof(openwifi_5GHz_rates));
1977 	BUILD_BUG_ON(sizeof(priv->channels_2GHz) != sizeof(openwifi_2GHz_channels));
1978 	BUILD_BUG_ON(sizeof(priv->channels_5GHz) != sizeof(openwifi_5GHz_channels));
1979 
1980 	memcpy(priv->rates_2GHz, openwifi_2GHz_rates, sizeof(openwifi_2GHz_rates));
1981 	memcpy(priv->rates_5GHz, openwifi_5GHz_rates, sizeof(openwifi_5GHz_rates));
1982 	memcpy(priv->channels_2GHz, openwifi_2GHz_channels, sizeof(openwifi_2GHz_channels));
1983 	memcpy(priv->channels_5GHz, openwifi_5GHz_channels, sizeof(openwifi_5GHz_channels));
1984 
1985 	priv->band = BAND_5_8GHZ; //this can be changed by band _rf_set_channel() (2.4GHz ERP(OFDM)) (5GHz OFDM)
1986 	priv->channel = 44;  //currently useless. this can be changed by band _rf_set_channel()
1987 	priv->use_short_slot = false; //this can be changed by openwifi_bss_info_changed: BSS_CHANGED_ERP_SLOT
1988 	priv->ampdu_reference = 0;
1989 
1990 	priv->band_2GHz.band = NL80211_BAND_2GHZ;
1991 	priv->band_2GHz.channels = priv->channels_2GHz;
1992 	priv->band_2GHz.n_channels = ARRAY_SIZE(priv->channels_2GHz);
1993 	priv->band_2GHz.bitrates = priv->rates_2GHz;
1994 	priv->band_2GHz.n_bitrates = ARRAY_SIZE(priv->rates_2GHz);
1995 	priv->band_2GHz.ht_cap.ht_supported = true;
1996 	priv->band_2GHz.ht_cap.cap = IEEE80211_HT_CAP_SGI_20;
1997 	priv->band_2GHz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1998 	priv->band_2GHz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2;
1999 	memset(&priv->band_2GHz.ht_cap.mcs, 0, sizeof(priv->band_2GHz.ht_cap.mcs));
2000 	priv->band_2GHz.ht_cap.mcs.rx_mask[0] = 0xff;
2001 	priv->band_2GHz.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2002 	dev->wiphy->bands[NL80211_BAND_2GHZ] = &(priv->band_2GHz);
2003 
2004 	priv->band_5GHz.band = NL80211_BAND_5GHZ;
2005 	priv->band_5GHz.channels = priv->channels_5GHz;
2006 	priv->band_5GHz.n_channels = ARRAY_SIZE(priv->channels_5GHz);
2007 	priv->band_5GHz.bitrates = priv->rates_5GHz;
2008 	priv->band_5GHz.n_bitrates = ARRAY_SIZE(priv->rates_5GHz);
2009 	priv->band_5GHz.ht_cap.ht_supported = true;
2010 	priv->band_5GHz.ht_cap.cap = IEEE80211_HT_CAP_SGI_20;
2011 	priv->band_5GHz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2012 	priv->band_5GHz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2;
2013 	memset(&priv->band_5GHz.ht_cap.mcs, 0, sizeof(priv->band_5GHz.ht_cap.mcs));
2014 	priv->band_5GHz.ht_cap.mcs.rx_mask[0] = 0xff;
2015 	priv->band_5GHz.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2016 	dev->wiphy->bands[NL80211_BAND_5GHZ] = &(priv->band_5GHz);
2017 
2018 	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,
2019 	priv->band_2GHz.n_channels,priv->band_2GHz.n_bitrates,priv->band_5GHz.n_channels,priv->band_5GHz.n_bitrates);
2020 
2021 	ieee80211_hw_set(dev, HOST_BROADCAST_PS_BUFFERING);
2022 	ieee80211_hw_set(dev, RX_INCLUDES_FCS);
2023 	ieee80211_hw_set(dev, BEACON_TX_STATUS);
2024 	ieee80211_hw_set(dev, AMPDU_AGGREGATION);
2025 
2026 	dev->vif_data_size = sizeof(struct openwifi_vif);
2027 	dev->wiphy->interface_modes =
2028 			BIT(NL80211_IFTYPE_MONITOR)|
2029 			BIT(NL80211_IFTYPE_P2P_GO) |
2030 			BIT(NL80211_IFTYPE_P2P_CLIENT) |
2031 			BIT(NL80211_IFTYPE_AP) |
2032 			BIT(NL80211_IFTYPE_STATION) |
2033 			BIT(NL80211_IFTYPE_ADHOC) |
2034 			BIT(NL80211_IFTYPE_MESH_POINT) |
2035 			BIT(NL80211_IFTYPE_OCB);
2036 	dev->wiphy->iface_combinations = &openwifi_if_comb;
2037 	dev->wiphy->n_iface_combinations = 1;
2038 
2039 	dev->wiphy->available_antennas_tx = NUM_TX_ANT_MASK;
2040 	dev->wiphy->available_antennas_rx = NUM_RX_ANT_MASK;
2041 
2042 	dev->wiphy->regulatory_flags = (REGULATORY_STRICT_REG|REGULATORY_CUSTOM_REG); // use our own config within strict regulation
2043 	//dev->wiphy->regulatory_flags = REGULATORY_CUSTOM_REG; // use our own config
2044 	wiphy_apply_custom_regulatory(dev->wiphy, &sdr_regd);
2045 
2046 	chip_name = "ZYNQ";
2047 
2048 	/* we declare to MAC80211 all the queues except for beacon queue
2049 	 * that will be eventually handled by DRV.
2050 	 * TX rings are arranged in such a way that lower is the IDX,
2051 	 * higher is the priority, in order to achieve direct mapping
2052 	 * with mac80211, however the beacon queue is an exception and it
2053 	 * is mapped on the highst tx ring IDX.
2054 	 */
2055 	dev->queues = MAX_NUM_HW_QUEUE;
2056 	//dev->queues = 1;
2057 
2058 	ieee80211_hw_set(dev, SIGNAL_DBM);
2059 
2060 	wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
2061 
2062 	priv->rf = &ad9361_rf_ops;
2063 
2064 	memset(priv->dest_mac_addr_queue_map,0,sizeof(priv->dest_mac_addr_queue_map));
2065 	priv->slice_idx = 0xFFFFFFFF;
2066 
2067 	sg_init_table(&(priv->tx_sg), 1);
2068 
2069 	get_random_bytes(&rand_val, sizeof(rand_val));
2070     rand_val%=250;
2071 	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;
2072 	priv->mac_addr[5]=rand_val+1;
2073 	//priv->mac_addr[5]=0x11;
2074 	if (!is_valid_ether_addr(priv->mac_addr)) {
2075 		printk(KERN_WARNING "%s openwifi_dev_probe: WARNING Invalid hwaddr! Using randomly generated MAC addr\n",sdr_compatible_str);
2076 		eth_random_addr(priv->mac_addr);
2077 	} else {
2078 		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]);
2079 	}
2080 	SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);
2081 
2082 	spin_lock_init(&priv->lock);
2083 
2084 	err = ieee80211_register_hw(dev);
2085 	if (err) {
2086 		pr_err(KERN_ERR "%s openwifi_dev_probe: WARNING Cannot register device\n",sdr_compatible_str);
2087 		goto err_free_dev;
2088 	} else {
2089 		printk("%s openwifi_dev_probe: ieee80211_register_hw %d\n",sdr_compatible_str, err);
2090 	}
2091 
2092 	// // //--------------------hook leds (not complete yet)--------------------------------
2093 	// tmp_dev = bus_find_device( &platform_bus_type, NULL, "leds", custom_match_platform_dev ); //leds is the name in devicetree, not "compatible" field
2094 	// if (!tmp_dev) {
2095 	// 	printk(KERN_ERR "%s bus_find_device platform_bus_type leds-gpio failed\n",sdr_compatible_str);
2096 	// 	err = -ENOMEM;
2097 	// 	goto err_free_dev;
2098 	// }
2099 
2100 	// tmp_pdev = to_platform_device(tmp_dev);
2101 	// if (!tmp_pdev) {
2102 	// 	printk(KERN_ERR "%s to_platform_device failed for leds-gpio\n",sdr_compatible_str);
2103 	// 	err = -ENOMEM;
2104 	// 	goto err_free_dev;
2105 	// }
2106 
2107 	// tmp_led_priv = platform_get_drvdata(tmp_pdev);
2108 	// if (!tmp_led_priv) {
2109 	// 	printk(KERN_ERR "%s platform_get_drvdata failed for leds-gpio\n",sdr_compatible_str);
2110 	// 	err = -ENOMEM;
2111 	// 	goto err_free_dev;
2112 	// }
2113 	// printk("%s openwifi_dev_probe: leds-gpio detect %d leds!\n",sdr_compatible_str, tmp_led_priv->num_leds);
2114 	// if (tmp_led_priv->num_leds!=4){
2115 	// 	printk(KERN_ERR "%s WARNING we expect 4 leds, but actual %d leds\n",sdr_compatible_str,tmp_led_priv->num_leds);
2116 	// 	err = -ENOMEM;
2117 	// 	goto err_free_dev;
2118 	// }
2119 	// gpiod_set_value(tmp_led_priv->leds[0].gpiod, 1);//light it
2120 	// gpiod_set_value(tmp_led_priv->leds[3].gpiod, 0);//black it
2121 	// priv->num_led = tmp_led_priv->num_leds;
2122 	// priv->led[0] = &(tmp_led_priv->leds[0].cdev);
2123 	// priv->led[1] = &(tmp_led_priv->leds[1].cdev);
2124 	// priv->led[2] = &(tmp_led_priv->leds[2].cdev);
2125 	// priv->led[3] = &(tmp_led_priv->leds[3].cdev);
2126 
2127 	// snprintf(priv->led_name[0], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::radio", wiphy_name(dev->wiphy));
2128 	// snprintf(priv->led_name[1], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::assoc", wiphy_name(dev->wiphy));
2129 	// snprintf(priv->led_name[2], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::tx", wiphy_name(dev->wiphy));
2130 	// snprintf(priv->led_name[3], OPENWIFI_LED_MAX_NAME_LEN, "openwifi-%s::rx", wiphy_name(dev->wiphy));
2131 
2132 	wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
2133 		   priv->mac_addr, chip_name, priv->rf->name);
2134 
2135 	openwifi_rfkill_init(dev);
2136 	return 0;
2137 
2138  err_free_dev:
2139 	ieee80211_free_hw(dev);
2140 
2141 	return err;
2142 }
2143 
2144 static int openwifi_dev_remove(struct platform_device *pdev)
2145 {
2146 	struct ieee80211_hw *dev = platform_get_drvdata(pdev);
2147 
2148 	if (!dev) {
2149 		pr_info("%s openwifi_dev_remove: dev %p\n", sdr_compatible_str, (void*)dev);
2150 		return(-1);
2151 	}
2152 
2153 	openwifi_rfkill_exit(dev);
2154 	ieee80211_unregister_hw(dev);
2155 	ieee80211_free_hw(dev);
2156 	return(0);
2157 }
2158 
2159 static struct platform_driver openwifi_dev_driver = {
2160 	.driver = {
2161 		.name = "sdr,sdr",
2162 		.owner = THIS_MODULE,
2163 		.of_match_table = openwifi_dev_of_ids,
2164 	},
2165 	.probe = openwifi_dev_probe,
2166 	.remove = openwifi_dev_remove,
2167 };
2168 
2169 module_platform_driver(openwifi_dev_driver);
2170