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