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