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