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