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