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