xref: /openwifi/driver/xpu/xpu.c (revision 6fdc02fb326ac7beccc948dddf343004bd0a7105)
1 /*
2  * axi lite register access driver
3  * Author: Xianjun Jiao, Michael Mehari, Wei Liu
4  * SPDX-FileCopyrightText: 2019 UGent
5  * SPDX-License-Identifier: AGPL-3.0-or-later
6 */
7 
8 #include <linux/bitops.h>
9 #include <linux/dmapool.h>
10 #include <linux/dma/xilinx_dma.h>
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/io.h>
14 #include <linux/iopoll.h>
15 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/of_dma.h>
18 #include <linux/of_platform.h>
19 #include <linux/of_irq.h>
20 #include <linux/slab.h>
21 #include <linux/clk.h>
22 #include <linux/io-64-nonatomic-lo-hi.h>
23 #include <linux/delay.h>
24 #include <net/mac80211.h>
25 
26 #include "../hw_def.h"
27 
28 static void __iomem *base_addr; // to store driver specific base address needed for mmu to translate virtual address to physical address in our FPGA design
29 
30 /* IO accessors */
31 static inline u32 reg_read(u32 reg)
32 {
33 	return ioread32(base_addr + reg);
34 }
35 
36 static inline void reg_write(u32 reg, u32 value)
37 {
38 	iowrite32(value, base_addr + reg);
39 }
40 
41 static inline void XPU_REG_MULTI_RST_write(u32 Data) {
42 	reg_write(XPU_REG_MULTI_RST_ADDR, Data);
43 }
44 
45 static inline u32 XPU_REG_MULTI_RST_read(void){
46 	return reg_read(XPU_REG_MULTI_RST_ADDR);
47 }
48 
49 static inline void XPU_REG_SRC_SEL_write(u32 Data) {
50 	reg_write(XPU_REG_SRC_SEL_ADDR, Data);
51 }
52 
53 static inline u32 XPU_REG_SRC_SEL_read(void){
54 	return reg_read(XPU_REG_SRC_SEL_ADDR);
55 }
56 
57 static inline void XPU_REG_RECV_ACK_COUNT_TOP0_write(u32 Data) {
58 	reg_write(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR, Data);
59 }
60 
61 static inline u32 XPU_REG_RECV_ACK_COUNT_TOP0_read(void){
62 	return reg_read(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR);
63 }
64 
65 static inline void XPU_REG_RECV_ACK_COUNT_TOP1_write(u32 Data) {
66 	reg_write(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR, Data);
67 }
68 
69 static inline u32 XPU_REG_RECV_ACK_COUNT_TOP1_read(void){
70 	return reg_read(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR);
71 }
72 
73 static inline void XPU_REG_SEND_ACK_WAIT_TOP_write(u32 Data) {
74 	reg_write(XPU_REG_SEND_ACK_WAIT_TOP_ADDR, Data);
75 }
76 
77 static inline u32 XPU_REG_SEND_ACK_WAIT_TOP_read(void){
78 	return reg_read(XPU_REG_SEND_ACK_WAIT_TOP_ADDR);
79 }
80 
81 static inline void XPU_REG_FILTER_FLAG_write(u32 Data) {
82 	reg_write(XPU_REG_FILTER_FLAG_ADDR, Data);
83 }
84 
85 static inline u32 XPU_REG_FILTER_FLAG_read(void){
86 	return reg_read(XPU_REG_FILTER_FLAG_ADDR);
87 }
88 
89 static inline void XPU_REG_CTS_TO_RTS_CONFIG_write(u32 Data) {
90 	reg_write(XPU_REG_CTS_TO_RTS_CONFIG_ADDR, Data);
91 }
92 
93 static inline u32 XPU_REG_CTS_TO_RTS_CONFIG_read(void){
94 	return reg_read(XPU_REG_CTS_TO_RTS_CONFIG_ADDR);
95 }
96 
97 static inline void XPU_REG_MAC_ADDR_LOW_write(u32 Data) {
98 	reg_write(XPU_REG_MAC_ADDR_LOW_ADDR, Data);
99 }
100 
101 static inline u32 XPU_REG_MAC_ADDR_LOW_read(void){
102 	return reg_read(XPU_REG_MAC_ADDR_LOW_ADDR);
103 }
104 
105 static inline void XPU_REG_MAC_ADDR_HIGH_write(u32 Data) {
106 	reg_write(XPU_REG_MAC_ADDR_HIGH_ADDR, Data);
107 }
108 
109 static inline u32 XPU_REG_MAC_ADDR_HIGH_read(void){
110 	return reg_read(XPU_REG_MAC_ADDR_HIGH_ADDR);
111 }
112 
113 static inline void XPU_REG_BSSID_FILTER_LOW_write(u32 Data) {
114 	reg_write(XPU_REG_BSSID_FILTER_LOW_ADDR, Data);
115 }
116 
117 static inline u32 XPU_REG_BSSID_FILTER_LOW_read(void){
118 	return reg_read(XPU_REG_BSSID_FILTER_LOW_ADDR);
119 }
120 
121 static inline void XPU_REG_BSSID_FILTER_HIGH_write(u32 Data) {
122 	reg_write(XPU_REG_BSSID_FILTER_HIGH_ADDR, Data);
123 }
124 
125 static inline u32 XPU_REG_BSSID_FILTER_HIGH_read(void){
126 	return reg_read(XPU_REG_BSSID_FILTER_HIGH_ADDR);
127 }
128 
129 static inline void XPU_REG_BAND_CHANNEL_write(u32 Data) {
130 	reg_write(XPU_REG_BAND_CHANNEL_ADDR, Data);
131 }
132 
133 static inline u32 XPU_REG_BAND_CHANNEL_read(void){
134 	return reg_read(XPU_REG_BAND_CHANNEL_ADDR);
135 }
136 
137 static inline void XPU_REG_DIFS_ADVANCE_write(u32 Data) {
138 	reg_write(XPU_REG_DIFS_ADVANCE_ADDR, Data);
139 }
140 
141 static inline u32 XPU_REG_DIFS_ADVANCE_read(void){
142 	return reg_read(XPU_REG_DIFS_ADVANCE_ADDR);
143 }
144 
145 static inline void XPU_REG_FORCE_IDLE_MISC_write(u32 Data) {
146 	reg_write(XPU_REG_FORCE_IDLE_MISC_ADDR, Data);
147 }
148 
149 static inline u32 XPU_REG_FORCE_IDLE_MISC_read(void){
150 	return reg_read(XPU_REG_FORCE_IDLE_MISC_ADDR);
151 }
152 
153 static inline u32 XPU_REG_TRX_STATUS_read(void){
154 	return reg_read(XPU_REG_TRX_STATUS_ADDR);
155 }
156 
157 static inline u32 XPU_REG_TX_RESULT_read(void){
158 	return reg_read(XPU_REG_TX_RESULT_ADDR);
159 }
160 
161 static inline u32 XPU_REG_TSF_RUNTIME_VAL_LOW_read(void){
162 	return reg_read(XPU_REG_TSF_RUNTIME_VAL_LOW_ADDR);
163 }
164 
165 static inline u32 XPU_REG_TSF_RUNTIME_VAL_HIGH_read(void){
166 	return reg_read(XPU_REG_TSF_RUNTIME_VAL_HIGH_ADDR);
167 }
168 
169 static inline void XPU_REG_TSF_LOAD_VAL_LOW_write(u32 value){
170 	reg_write(XPU_REG_TSF_LOAD_VAL_LOW_ADDR, value);
171 }
172 
173 static inline void XPU_REG_TSF_LOAD_VAL_HIGH_write(u32 value){
174 	reg_write(XPU_REG_TSF_LOAD_VAL_HIGH_ADDR, value);
175 }
176 
177 static inline void XPU_REG_TSF_LOAD_VAL_write(u32 high_value, u32 low_value){
178 	XPU_REG_TSF_LOAD_VAL_LOW_write(low_value);
179 	XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value|0x80000000); // msb high
180 	XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value&(~0x80000000)); // msb low
181 }
182 
183 static inline u32 XPU_REG_FC_DI_read(void){
184 	return reg_read(XPU_REG_FC_DI_ADDR);
185 }
186 
187 static inline u32 XPU_REG_ADDR1_LOW_read(void){
188 	return reg_read(XPU_REG_ADDR1_LOW_ADDR);
189 }
190 
191 static inline u32 XPU_REG_ADDR1_HIGH_read(void){
192 	return reg_read(XPU_REG_ADDR1_HIGH_ADDR);
193 }
194 
195 static inline u32 XPU_REG_ADDR2_LOW_read(void){
196 	return reg_read(XPU_REG_ADDR2_LOW_ADDR);
197 }
198 
199 static inline u32 XPU_REG_ADDR2_HIGH_read(void){
200 	return reg_read(XPU_REG_ADDR2_HIGH_ADDR);
201 }
202 
203 // static inline void XPU_REG_LBT_TH_write(u32 value, u32 en_flag) {
204 // 	if (en_flag) {
205 // 		reg_write(XPU_REG_LBT_TH_ADDR, value&0x7FFFFFFF);
206 // 	} else {
207 // 		reg_write(XPU_REG_LBT_TH_ADDR, value|0x80000000);
208 // 	}
209 // }
210 
211 static inline void XPU_REG_LBT_TH_write(u32 value) {
212 	reg_write(XPU_REG_LBT_TH_ADDR, value);
213 }
214 
215 static inline u32 XPU_REG_RSSI_DB_CFG_read(void){
216 	return reg_read(XPU_REG_RSSI_DB_CFG_ADDR);
217 }
218 
219 static inline void XPU_REG_RSSI_DB_CFG_write(u32 Data) {
220 	reg_write(XPU_REG_RSSI_DB_CFG_ADDR, Data);
221 }
222 
223 static inline u32 XPU_REG_LBT_TH_read(void){
224 	return reg_read(XPU_REG_LBT_TH_ADDR);
225 }
226 
227 static inline void XPU_REG_CSMA_DEBUG_write(u32 value){
228 	reg_write(XPU_REG_CSMA_DEBUG_ADDR, value);
229 }
230 
231 static inline u32 XPU_REG_CSMA_DEBUG_read(void){
232 	return reg_read(XPU_REG_CSMA_DEBUG_ADDR);
233 }
234 
235 static inline void XPU_REG_CSMA_CFG_write(u32 value){
236 	reg_write(XPU_REG_CSMA_CFG_ADDR, value);
237 }
238 
239 static inline u32 XPU_REG_CSMA_CFG_read(void){
240 	return reg_read(XPU_REG_CSMA_CFG_ADDR);
241 }
242 
243 static inline void XPU_REG_SLICE_COUNT_TOTAL_write(u32 value){
244 	reg_write(XPU_REG_SLICE_COUNT_TOTAL_ADDR, value);
245 }
246 static inline void XPU_REG_SLICE_COUNT_START_write(u32 value){
247 	reg_write(XPU_REG_SLICE_COUNT_START_ADDR, value);
248 }
249 static inline void XPU_REG_SLICE_COUNT_END_write(u32 value){
250 	reg_write(XPU_REG_SLICE_COUNT_END_ADDR, value);
251 }
252 
253 
254 static inline u32 XPU_REG_SLICE_COUNT_TOTAL_read(void){
255 	return reg_read(XPU_REG_SLICE_COUNT_TOTAL_ADDR);
256 }
257 static inline u32 XPU_REG_SLICE_COUNT_START_read(void){
258 	return reg_read(XPU_REG_SLICE_COUNT_START_ADDR);
259 }
260 static inline u32 XPU_REG_SLICE_COUNT_END_read(void){
261 	return reg_read(XPU_REG_SLICE_COUNT_END_ADDR);
262 }
263 
264 static inline void XPU_REG_BB_RF_DELAY_write(u32 value){
265 	reg_write(XPU_REG_BB_RF_DELAY_ADDR, value);
266 }
267 
268 static inline void XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write(u32 value){
269 	reg_write(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR, value);
270 }
271 static inline u32 XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read(void){
272 	return reg_read(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR);
273 }
274 
275 static inline void XPU_REG_AMPDU_ACTION_write(u32 Data) {
276 	reg_write(XPU_REG_AMPDU_ACTION_ADDR, Data);
277 }
278 
279 static inline u32 XPU_REG_AMPDU_ACTION_read(void){
280 	return reg_read(XPU_REG_AMPDU_ACTION_ADDR);
281 }
282 
283 static inline void XPU_REG_SPI_DISABLE_write(u32 Data) {
284 	reg_write(XPU_REG_SPI_DISABLE_ADDR, Data);
285 }
286 
287 static inline u32 XPU_REG_SPI_DISABLE_read(void){
288 	return reg_read(XPU_REG_SPI_DISABLE_ADDR);
289 }
290 
291 static inline void XPU_REG_MAC_ADDR_write(u8 *mac_addr) {//, u32 en_flag){
292 	XPU_REG_MAC_ADDR_LOW_write( *( (u32*)(mac_addr) ) );
293 	XPU_REG_MAC_ADDR_HIGH_write( *( (u16*)(mac_addr + 4) ) );
294 	#if 0
295 	if (en_flag) {
296 		XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) | 0x80000000 ); // 0x80000000 by default we turn on mac addr filter
297 	} else {
298 		XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) & 0x7FFFFFFF );
299 	}
300 	#endif
301 }
302 
303 static const struct of_device_id dev_of_ids[] = {
304 	{ .compatible = "sdr,xpu", },
305 	{}
306 };
307 MODULE_DEVICE_TABLE(of, dev_of_ids);
308 
309 static struct xpu_driver_api xpu_driver_api_inst;
310 static struct xpu_driver_api *xpu_api = &xpu_driver_api_inst;
311 EXPORT_SYMBOL(xpu_api);
312 
313 static inline u32 hw_init(enum xpu_mode mode){
314 	int err=0, i, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay;
315 	u32 filter_flag = 0;
316 
317 	printk("%s hw_init mode %d\n", xpu_compatible_str, mode);
318 
319 	//rst
320 	for (i=0;i<8;i++)
321 		xpu_api->XPU_REG_MULTI_RST_write(0);
322 	for (i=0;i<32;i++)
323 		xpu_api->XPU_REG_MULTI_RST_write(0xFFFFFFFF);
324 	for (i=0;i<8;i++)
325 		xpu_api->XPU_REG_MULTI_RST_write(0);
326 
327 	// http://www.studioreti.it/slide/802-11-Frame_E_C.pdf
328 	// https://mrncciew.com/2014/10/14/cwap-802-11-phy-ppdu/
329 	// https://mrncciew.com/2014/09/27/cwap-mac-header-frame-control/
330 	// https://mrncciew.com/2014/10/25/cwap-mac-header-durationid/
331 	// https://mrncciew.com/2014/11/01/cwap-mac-header-sequence-control/
332 	// https://witestlab.poly.edu/blog/802-11-wireless-lan-2/
333 	// phy_rx byte idx:
334 	// 5(3 sig + 2 service), -- PHY
335 	// 2 frame control, 2 duration/conn ID, --MAC PDU
336 	// 6 receiver address, 6 destination address, 6 transmitter address
337 	// 2 sequence control
338 	// 6 source address
339 	// reg_val = 5 + 0;
340 	// xpu_api->XPU_REG_PHY_RX_PKT_READ_OFFSET_write(reg_val);
341 	// printk("%s hw_init XPU_REG_PHY_RX_PKT_READ_OFFSET_write %d\n", xpu_compatible_str, reg_val);
342 
343 	// by default turn off filter, because all register are zeros
344 	// let's filter out packet according to: enum ieee80211_filter_flags at: https://www.kernel.org/doc/html/v4.9/80211/mac80211.html
345 	#if 0 // define in FPGA
346     localparam [13:0]   FIF_ALLMULTI =           14b00000000000010, //get all mac addr like 01:00:5E:xx:xx:xx and 33:33:xx:xx:xx:xx through to ARM
347                         FIF_FCSFAIL =            14b00000000000100, //not support
348                         FIF_PLCPFAIL =           14b00000000001000, //not support
349                         FIF_BCN_PRBRESP_PROMISC= 14b00000000010000,
350                         FIF_CONTROL =            14b00000000100000,
351                         FIF_OTHER_BSS =          14b00000001000000,
352                         FIF_PSPOLL =             14b00000010000000,
353                         FIF_PROBE_REQ =          14b00000100000000,
354                         UNICAST_FOR_US =         14b00001000000000,
355                         BROADCAST_ALL_ONE =      14b00010000000000,
356                         BROADCAST_ALL_ZERO =     14b00100000000000,
357                         MY_BEACON          =     14b01000000000000,
358                         MONITOR_ALL =            14b10000000000000;
359 	#endif
360 	filter_flag = (FIF_ALLMULTI|FIF_FCSFAIL|FIF_PLCPFAIL|FIF_BCN_PRBRESP_PROMISC|FIF_CONTROL|FIF_OTHER_BSS|FIF_PSPOLL|FIF_PROBE_REQ|UNICAST_FOR_US|BROADCAST_ALL_ONE|BROADCAST_ALL_ZERO|MY_BEACON|MONITOR_ALL);
361 	xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag);
362 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write(0xB<<16);//6M 1011:0xB
363 
364 	// after send data frame wait for ACK, this will be set in real time in function ad9361_rf_set_channel
365 	// xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+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"!
366 	// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 6*10 ); // +6 = 16us for 5GHz
367 
368 	//xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write(3); // if this > 0, it will override mac80211 set value, and set static retransmission limit
369 
370 	// From CMW measurement: lo up 1us before the packet; lo down 0.4us after the packet/RF port switches 1.2us before and 0.2us after
371 	xpu_api->XPU_REG_BB_RF_DELAY_write((16<<24)|(0<<16)|(26<<8)|9); // calibrated by ila and spectrum analyzer (trigger mode)
372 
373 	// setup time schedule of 4 slices
374 	// slice 0
375 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
376 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
377 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
378 
379 	// slice 1
380 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
381 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
382 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
383 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
384 
385 	// slice 2
386 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
387 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
388 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
389 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
390 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
391 
392 	// slice 3
393 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
394 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
395 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
396 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
397 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
398 
399 	// all slice sync rest
400 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
401 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
402 
403 	switch(mode)
404 	{
405 		case XPU_TEST:
406 			printk("%s hw_init mode XPU_TEST\n", xpu_compatible_str);
407 			break;
408 
409 		case XPU_NORMAL:
410 			printk("%s hw_init mode XPU_NORMAL\n", xpu_compatible_str);
411 			break;
412 
413 		default:
414 			printk("%s hw_init mode %d is wrong!\n", xpu_compatible_str, mode);
415 			err=1;
416 	}
417 	xpu_api->XPU_REG_BAND_CHANNEL_write((false<<24)|(BAND_5_8GHZ<<16)|44);//use_short_slot==false; 5.8GHz; channel 44 -- default setting to sync with priv->band/channel/use_short_slot
418 
419 	agc_gain_delay = 39; //samples
420 	rssi_half_db_offset = 75<<1;
421 	xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
422 	xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
423 
424 	//rssi_half_db_th = 70<<1; // with splitter
425 	rssi_half_db_th = 87<<1; // -62dBm
426 	xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
427 
428 	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
429 
430 	//xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5));
431 	xpu_api->XPU_REG_CSMA_DEBUG_write(0);
432 
433 	// xpu_api->XPU_REG_CSMA_CFG_write(268435459);  // Linux will do config for each queue via openwifi_conf_tx
434 	// xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); // Linux will do config for each queue via openwifi_conf_tx
435 
436 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+23)<<16)|(0+23) );
437 
438 	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)
439 	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)
440 
441 	xpu_api->XPU_REG_DIFS_ADVANCE_write((OPENWIFI_MAX_SIGNAL_LEN_TH<<16)|2); //us. bit31~16 max pkt length threshold
442 
443 	// setup time schedule of 4 slices
444 	// slice 0
445 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
446 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
447 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
448 
449 	// slice 1
450 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
451 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
452 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
453 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
454 
455 	// slice 2
456 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
457 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
458 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
459 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
460 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
461 
462 	// slice 3
463 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
464 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
465 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
466 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
467 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
468 
469 	// all slice sync rest
470 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
471 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
472 
473 	printk("%s hw_init err %d\n", xpu_compatible_str, err);
474 	return(err);
475 }
476 
477 static int dev_probe(struct platform_device *pdev)
478 {
479 	struct device_node *np = pdev->dev.of_node;
480 	struct resource *io;
481 	u32 test_us0, test_us1, test_us2;
482 	int err=1;
483 
484 	printk("\n");
485 
486 	if (np) {
487 		const struct of_device_id *match;
488 
489 		match = of_match_node(dev_of_ids, np);
490 		if (match) {
491 			printk("%s dev_probe match!\n", xpu_compatible_str);
492 			err = 0;
493 		}
494 	}
495 
496 	if (err)
497 		return err;
498 
499 	xpu_api->hw_init=hw_init;
500 
501 	xpu_api->reg_read=reg_read;
502 	xpu_api->reg_write=reg_write;
503 
504 	xpu_api->XPU_REG_MULTI_RST_write=XPU_REG_MULTI_RST_write;
505 	xpu_api->XPU_REG_MULTI_RST_read=XPU_REG_MULTI_RST_read;
506 	xpu_api->XPU_REG_SRC_SEL_write=XPU_REG_SRC_SEL_write;
507 	xpu_api->XPU_REG_SRC_SEL_read=XPU_REG_SRC_SEL_read;
508 
509 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write=XPU_REG_RECV_ACK_COUNT_TOP0_write;
510 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_read=XPU_REG_RECV_ACK_COUNT_TOP0_read;
511 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write=XPU_REG_RECV_ACK_COUNT_TOP1_write;
512 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_read=XPU_REG_RECV_ACK_COUNT_TOP1_read;
513 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write=XPU_REG_SEND_ACK_WAIT_TOP_write;
514 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_read=XPU_REG_SEND_ACK_WAIT_TOP_read;
515 	xpu_api->XPU_REG_MAC_ADDR_LOW_write=XPU_REG_MAC_ADDR_LOW_write;
516 	xpu_api->XPU_REG_MAC_ADDR_LOW_read=XPU_REG_MAC_ADDR_LOW_read;
517 	xpu_api->XPU_REG_MAC_ADDR_HIGH_write=XPU_REG_MAC_ADDR_HIGH_write;
518 	xpu_api->XPU_REG_MAC_ADDR_HIGH_read=XPU_REG_MAC_ADDR_HIGH_read;
519 
520 	xpu_api->XPU_REG_FILTER_FLAG_write=XPU_REG_FILTER_FLAG_write;
521 	xpu_api->XPU_REG_FILTER_FLAG_read=XPU_REG_FILTER_FLAG_read;
522 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write=XPU_REG_CTS_TO_RTS_CONFIG_write;
523 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_read=XPU_REG_CTS_TO_RTS_CONFIG_read;
524 	xpu_api->XPU_REG_BSSID_FILTER_LOW_write=XPU_REG_BSSID_FILTER_LOW_write;
525 	xpu_api->XPU_REG_BSSID_FILTER_LOW_read=XPU_REG_BSSID_FILTER_LOW_read;
526 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_write=XPU_REG_BSSID_FILTER_HIGH_write;
527 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_read=XPU_REG_BSSID_FILTER_HIGH_read;
528 
529 	xpu_api->XPU_REG_BAND_CHANNEL_write=XPU_REG_BAND_CHANNEL_write;
530 	xpu_api->XPU_REG_BAND_CHANNEL_read=XPU_REG_BAND_CHANNEL_read;
531 
532 	xpu_api->XPU_REG_DIFS_ADVANCE_write=XPU_REG_DIFS_ADVANCE_write;
533 	xpu_api->XPU_REG_DIFS_ADVANCE_read=XPU_REG_DIFS_ADVANCE_read;
534 
535 	xpu_api->XPU_REG_FORCE_IDLE_MISC_write=XPU_REG_FORCE_IDLE_MISC_write;
536 	xpu_api->XPU_REG_FORCE_IDLE_MISC_read=XPU_REG_FORCE_IDLE_MISC_read;
537 
538 	xpu_api->XPU_REG_TRX_STATUS_read=XPU_REG_TRX_STATUS_read;
539 	xpu_api->XPU_REG_TX_RESULT_read=XPU_REG_TX_RESULT_read;
540 
541 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read=XPU_REG_TSF_RUNTIME_VAL_LOW_read;
542 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read=XPU_REG_TSF_RUNTIME_VAL_HIGH_read;
543 	xpu_api->XPU_REG_TSF_LOAD_VAL_LOW_write=XPU_REG_TSF_LOAD_VAL_LOW_write;
544 	xpu_api->XPU_REG_TSF_LOAD_VAL_HIGH_write=XPU_REG_TSF_LOAD_VAL_HIGH_write;
545 	xpu_api->XPU_REG_TSF_LOAD_VAL_write=XPU_REG_TSF_LOAD_VAL_write;
546 
547 	xpu_api->XPU_REG_FC_DI_read=XPU_REG_FC_DI_read;
548 	xpu_api->XPU_REG_ADDR1_LOW_read=XPU_REG_ADDR1_LOW_read;
549 	xpu_api->XPU_REG_ADDR1_HIGH_read=XPU_REG_ADDR1_HIGH_read;
550 	xpu_api->XPU_REG_ADDR2_LOW_read=XPU_REG_ADDR2_LOW_read;
551 	xpu_api->XPU_REG_ADDR2_HIGH_read=XPU_REG_ADDR2_HIGH_read;
552 
553 	xpu_api->XPU_REG_LBT_TH_write=XPU_REG_LBT_TH_write;
554 	xpu_api->XPU_REG_LBT_TH_read=XPU_REG_LBT_TH_read;
555 
556 	xpu_api->XPU_REG_RSSI_DB_CFG_read=XPU_REG_RSSI_DB_CFG_read;
557 	xpu_api->XPU_REG_RSSI_DB_CFG_write=XPU_REG_RSSI_DB_CFG_write;
558 
559 	xpu_api->XPU_REG_CSMA_DEBUG_write=XPU_REG_CSMA_DEBUG_write;
560 	xpu_api->XPU_REG_CSMA_DEBUG_read=XPU_REG_CSMA_DEBUG_read;
561 
562 	xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write;
563 	xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read;
564 
565 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write=XPU_REG_SLICE_COUNT_TOTAL_write;
566 	xpu_api->XPU_REG_SLICE_COUNT_START_write=XPU_REG_SLICE_COUNT_START_write;
567 	xpu_api->XPU_REG_SLICE_COUNT_END_write=XPU_REG_SLICE_COUNT_END_write;
568 
569 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read=XPU_REG_SLICE_COUNT_TOTAL_read;
570 	xpu_api->XPU_REG_SLICE_COUNT_START_read=XPU_REG_SLICE_COUNT_START_read;
571 	xpu_api->XPU_REG_SLICE_COUNT_END_read=XPU_REG_SLICE_COUNT_END_read;
572 
573 	xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write;
574 
575 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write;
576 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read;
577 
578 	xpu_api->XPU_REG_AMPDU_ACTION_write=XPU_REG_AMPDU_ACTION_write;
579 	xpu_api->XPU_REG_AMPDU_ACTION_read=XPU_REG_AMPDU_ACTION_read;
580 
581 	xpu_api->XPU_REG_SPI_DISABLE_write=XPU_REG_SPI_DISABLE_write;
582 	xpu_api->XPU_REG_SPI_DISABLE_read=XPU_REG_SPI_DISABLE_read;
583 
584 	xpu_api->XPU_REG_MAC_ADDR_write=XPU_REG_MAC_ADDR_write;
585 
586 	/* Request and map I/O memory */
587 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
588 	base_addr = devm_ioremap_resource(&pdev->dev, io);
589 	if (IS_ERR(base_addr))
590 		return PTR_ERR(base_addr);
591 
592 	printk("%s dev_probe io start 0x%08x end 0x%08x name %s flags 0x%08x desc 0x%08x\n", xpu_compatible_str,io->start,io->end,io->name,(u32)io->flags,(u32)io->desc);
593 	printk("%s dev_probe base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
594 	printk("%s dev_probe xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
595 	printk("%s dev_probe             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
596 
597 	printk("%s dev_probe reset tsf timer\n", xpu_compatible_str);
598 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
599 	test_us0 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
600 	mdelay(33);
601 	test_us1 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
602 	mdelay(67);
603 	test_us2 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
604 	printk("%s dev_probe XPU_REG_TSF_RUNTIME_VAL_LOW_read %d %d %dus\n", xpu_compatible_str, test_us0, test_us1, test_us2);
605 
606 	printk("%s dev_probe succeed!\n", xpu_compatible_str);
607 
608 	err = hw_init(XPU_NORMAL);
609 
610 	return err;
611 }
612 
613 static int dev_remove(struct platform_device *pdev)
614 {
615 	printk("\n");
616 
617 	printk("%s dev_remove base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
618 	printk("%s dev_remove xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
619 	printk("%s dev_remove             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
620 
621 	printk("%s dev_remove succeed!\n", xpu_compatible_str);
622 	return 0;
623 }
624 
625 static struct platform_driver dev_driver = {
626 	.driver = {
627 		.name = "sdr,xpu",
628 		.owner = THIS_MODULE,
629 		.of_match_table = dev_of_ids,
630 	},
631 	.probe = dev_probe,
632 	.remove = dev_remove,
633 };
634 
635 module_platform_driver(dev_driver);
636 
637 MODULE_AUTHOR("Xianjun Jiao");
638 MODULE_DESCRIPTION("sdr,xpu");
639 MODULE_LICENSE("GPL v2");
640