xref: /openwifi/driver/xpu/xpu.c (revision ec5a505373d7ca009d6c4282ba8b128b357e0fd8)
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_TSF_RUNTIME_VAL_LOW_read(void){
154 	return reg_read(XPU_REG_TSF_RUNTIME_VAL_LOW_ADDR);
155 }
156 
157 static inline u32 XPU_REG_TSF_RUNTIME_VAL_HIGH_read(void){
158 	return reg_read(XPU_REG_TSF_RUNTIME_VAL_HIGH_ADDR);
159 }
160 
161 static inline void XPU_REG_TSF_LOAD_VAL_LOW_write(u32 value){
162 	reg_write(XPU_REG_TSF_LOAD_VAL_LOW_ADDR, value);
163 }
164 
165 static inline void XPU_REG_TSF_LOAD_VAL_HIGH_write(u32 value){
166 	reg_write(XPU_REG_TSF_LOAD_VAL_HIGH_ADDR, value);
167 }
168 
169 static inline void XPU_REG_TSF_LOAD_VAL_write(u32 high_value, u32 low_value){
170 	XPU_REG_TSF_LOAD_VAL_LOW_write(low_value);
171 	XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value|0x80000000); // msb high
172 	XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value&(~0x80000000)); // msb low
173 }
174 
175 static inline void XPU_REG_LBT_TH_write(u32 value) {
176 	reg_write(XPU_REG_LBT_TH_ADDR, value);
177 }
178 
179 static inline u32 XPU_REG_RSSI_DB_CFG_read(void){
180 	return reg_read(XPU_REG_RSSI_DB_CFG_ADDR);
181 }
182 
183 static inline void XPU_REG_RSSI_DB_CFG_write(u32 Data) {
184 	reg_write(XPU_REG_RSSI_DB_CFG_ADDR, Data);
185 }
186 
187 static inline u32 XPU_REG_LBT_TH_read(void){
188 	return reg_read(XPU_REG_LBT_TH_ADDR);
189 }
190 
191 static inline void XPU_REG_CSMA_DEBUG_write(u32 value){
192 	reg_write(XPU_REG_CSMA_DEBUG_ADDR, value);
193 }
194 
195 static inline u32 XPU_REG_CSMA_DEBUG_read(void){
196 	return reg_read(XPU_REG_CSMA_DEBUG_ADDR);
197 }
198 
199 static inline void XPU_REG_CSMA_CFG_write(u32 value){
200 	reg_write(XPU_REG_CSMA_CFG_ADDR, value);
201 }
202 
203 static inline u32 XPU_REG_CSMA_CFG_read(void){
204 	return reg_read(XPU_REG_CSMA_CFG_ADDR);
205 }
206 
207 static inline void XPU_REG_SLICE_COUNT_TOTAL_write(u32 value){
208 	reg_write(XPU_REG_SLICE_COUNT_TOTAL_ADDR, value);
209 }
210 static inline void XPU_REG_SLICE_COUNT_START_write(u32 value){
211 	reg_write(XPU_REG_SLICE_COUNT_START_ADDR, value);
212 }
213 static inline void XPU_REG_SLICE_COUNT_END_write(u32 value){
214 	reg_write(XPU_REG_SLICE_COUNT_END_ADDR, value);
215 }
216 
217 
218 static inline u32 XPU_REG_SLICE_COUNT_TOTAL_read(void){
219 	return reg_read(XPU_REG_SLICE_COUNT_TOTAL_ADDR);
220 }
221 static inline u32 XPU_REG_SLICE_COUNT_START_read(void){
222 	return reg_read(XPU_REG_SLICE_COUNT_START_ADDR);
223 }
224 static inline u32 XPU_REG_SLICE_COUNT_END_read(void){
225 	return reg_read(XPU_REG_SLICE_COUNT_END_ADDR);
226 }
227 
228 static inline void XPU_REG_BB_RF_DELAY_write(u32 value){
229 	reg_write(XPU_REG_BB_RF_DELAY_ADDR, value);
230 }
231 
232 static inline void XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write(u32 value){
233 	reg_write(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR, value);
234 }
235 static inline u32 XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read(void){
236 	return reg_read(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR);
237 }
238 
239 static inline void XPU_REG_AMPDU_ACTION_write(u32 Data) {
240 	reg_write(XPU_REG_AMPDU_ACTION_ADDR, Data);
241 }
242 
243 static inline u32 XPU_REG_AMPDU_ACTION_read(void){
244 	return reg_read(XPU_REG_AMPDU_ACTION_ADDR);
245 }
246 
247 static inline void XPU_REG_SPI_DISABLE_write(u32 Data) {
248 	reg_write(XPU_REG_SPI_DISABLE_ADDR, Data);
249 }
250 
251 static inline u32 XPU_REG_SPI_DISABLE_read(void){
252 	return reg_read(XPU_REG_SPI_DISABLE_ADDR);
253 }
254 
255 static inline void XPU_REG_MAC_ADDR_write(u8 *mac_addr) {//, u32 en_flag){
256 	XPU_REG_MAC_ADDR_LOW_write( *( (u32*)(mac_addr) ) );
257 	XPU_REG_MAC_ADDR_HIGH_write( *( (u16*)(mac_addr + 4) ) );
258 	#if 0
259 	if (en_flag) {
260 		XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) | 0x80000000 ); // 0x80000000 by default we turn on mac addr filter
261 	} else {
262 		XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) & 0x7FFFFFFF );
263 	}
264 	#endif
265 }
266 
267 static const struct of_device_id dev_of_ids[] = {
268 	{ .compatible = "sdr,xpu", },
269 	{}
270 };
271 MODULE_DEVICE_TABLE(of, dev_of_ids);
272 
273 static struct xpu_driver_api xpu_driver_api_inst;
274 static struct xpu_driver_api *xpu_api = &xpu_driver_api_inst;
275 EXPORT_SYMBOL(xpu_api);
276 
277 static inline u32 hw_init(enum xpu_mode mode){
278 	int err=0, i, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay;
279 	u32 filter_flag = 0;
280 
281 	printk("%s hw_init mode %d\n", xpu_compatible_str, mode);
282 
283 	//rst
284 	for (i=0;i<8;i++)
285 		xpu_api->XPU_REG_MULTI_RST_write(0);
286 	for (i=0;i<32;i++)
287 		xpu_api->XPU_REG_MULTI_RST_write(0xFFFFFFFF);
288 	for (i=0;i<8;i++)
289 		xpu_api->XPU_REG_MULTI_RST_write(0);
290 
291 	// http://www.studioreti.it/slide/802-11-Frame_E_C.pdf
292 	// https://mrncciew.com/2014/10/14/cwap-802-11-phy-ppdu/
293 	// https://mrncciew.com/2014/09/27/cwap-mac-header-frame-control/
294 	// https://mrncciew.com/2014/10/25/cwap-mac-header-durationid/
295 	// https://mrncciew.com/2014/11/01/cwap-mac-header-sequence-control/
296 	// https://witestlab.poly.edu/blog/802-11-wireless-lan-2/
297 	// phy_rx byte idx:
298 	// 5(3 sig + 2 service), -- PHY
299 	// 2 frame control, 2 duration/conn ID, --MAC PDU
300 	// 6 receiver address, 6 destination address, 6 transmitter address
301 	// 2 sequence control
302 	// 6 source address
303 	// reg_val = 5 + 0;
304 	// xpu_api->XPU_REG_PHY_RX_PKT_READ_OFFSET_write(reg_val);
305 	// printk("%s hw_init XPU_REG_PHY_RX_PKT_READ_OFFSET_write %d\n", xpu_compatible_str, reg_val);
306 
307 	// by default turn off filter, because all register are zeros
308 	// let's filter out packet according to: enum ieee80211_filter_flags at: https://www.kernel.org/doc/html/v4.9/80211/mac80211.html
309 	#if 0 // define in FPGA
310     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
311                         FIF_FCSFAIL =            14b00000000000100, //not support
312                         FIF_PLCPFAIL =           14b00000000001000, //not support
313                         FIF_BCN_PRBRESP_PROMISC= 14b00000000010000,
314                         FIF_CONTROL =            14b00000000100000,
315                         FIF_OTHER_BSS =          14b00000001000000,
316                         FIF_PSPOLL =             14b00000010000000,
317                         FIF_PROBE_REQ =          14b00000100000000,
318                         UNICAST_FOR_US =         14b00001000000000,
319                         BROADCAST_ALL_ONE =      14b00010000000000,
320                         BROADCAST_ALL_ZERO =     14b00100000000000,
321                         MY_BEACON          =     14b01000000000000,
322                         MONITOR_ALL =            14b10000000000000;
323 	#endif
324 	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);
325 	xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag);
326 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write(0xB<<16);//6M 1011:0xB
327 
328 	// after send data frame wait for ACK, this will be set in real time in function ad9361_rf_set_channel
329 	// 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"!
330 	// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 6*10 ); // +6 = 16us for 5GHz
331 
332 	//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
333 
334 	// 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
335 	xpu_api->XPU_REG_BB_RF_DELAY_write((16<<24)|(0<<16)|(26<<8)|9); // calibrated by ila and spectrum analyzer (trigger mode)
336 
337 	// setup time schedule of 4 slices
338 	// slice 0
339 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
340 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
341 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
342 
343 	// slice 1
344 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
345 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
346 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
347 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
348 
349 	// slice 2
350 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
351 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
352 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
353 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
354 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
355 
356 	// slice 3
357 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
358 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
359 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
360 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
361 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
362 
363 	// all slice sync rest
364 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
365 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
366 
367 	switch(mode)
368 	{
369 		case XPU_TEST:
370 			printk("%s hw_init mode XPU_TEST\n", xpu_compatible_str);
371 			break;
372 
373 		case XPU_NORMAL:
374 			printk("%s hw_init mode XPU_NORMAL\n", xpu_compatible_str);
375 			break;
376 
377 		default:
378 			printk("%s hw_init mode %d is wrong!\n", xpu_compatible_str, mode);
379 			err=1;
380 	}
381 	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
382 
383 	agc_gain_delay = 39; //samples
384 	rssi_half_db_offset = 75<<1;
385 	xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
386 	xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
387 
388 	//rssi_half_db_th = 70<<1; // with splitter
389 	rssi_half_db_th = 87<<1; // -62dBm
390 	xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
391 
392 	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
393 
394 	//xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5));
395 	xpu_api->XPU_REG_CSMA_DEBUG_write(0);
396 
397 	// xpu_api->XPU_REG_CSMA_CFG_write(268435459);  // Linux will do config for each queue via openwifi_conf_tx
398 	// xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); // Linux will do config for each queue via openwifi_conf_tx
399 
400 //	// ------- assume 2.4 and 5GHz have the same SIFS (6us signal extension) --------
401 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+25)<<16)|((16+25)<<0) );
402 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (1<<31) | (((51+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)
403 	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)
404 //	// ------- assume 2.4 and 5GHz have different SIFS --------
405 	// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+23)<<16)|(0+23) );
406 	// 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)
407 	// 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)
408 
409 	xpu_api->XPU_REG_DIFS_ADVANCE_write((OPENWIFI_MAX_SIGNAL_LEN_TH<<16)|2); //us. bit31~16 max pkt length threshold
410 
411 	// setup time schedule of 4 slices
412 	// slice 0
413 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
414 	xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
415 	xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
416 
417 	// slice 1
418 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
419 	xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
420 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
421 	xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
422 
423 	// slice 2
424 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
425 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
426 	xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
427 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
428 	xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
429 
430 	// slice 3
431 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
432 	//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
433 	xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
434 	//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
435 	xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
436 
437 	// all slice sync rest
438 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
439 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
440 
441 	printk("%s hw_init err %d\n", xpu_compatible_str, err);
442 	return(err);
443 }
444 
445 static int dev_probe(struct platform_device *pdev)
446 {
447 	struct device_node *np = pdev->dev.of_node;
448 	struct resource *io;
449 	u32 test_us0, test_us1, test_us2;
450 	int err=1;
451 
452 	printk("\n");
453 
454 	if (np) {
455 		const struct of_device_id *match;
456 
457 		match = of_match_node(dev_of_ids, np);
458 		if (match) {
459 			printk("%s dev_probe match!\n", xpu_compatible_str);
460 			err = 0;
461 		}
462 	}
463 
464 	if (err)
465 		return err;
466 
467 	xpu_api->hw_init=hw_init;
468 
469 	xpu_api->reg_read=reg_read;
470 	xpu_api->reg_write=reg_write;
471 
472 	xpu_api->XPU_REG_MULTI_RST_write=XPU_REG_MULTI_RST_write;
473 	xpu_api->XPU_REG_MULTI_RST_read=XPU_REG_MULTI_RST_read;
474 	xpu_api->XPU_REG_SRC_SEL_write=XPU_REG_SRC_SEL_write;
475 	xpu_api->XPU_REG_SRC_SEL_read=XPU_REG_SRC_SEL_read;
476 
477 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write=XPU_REG_RECV_ACK_COUNT_TOP0_write;
478 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_read=XPU_REG_RECV_ACK_COUNT_TOP0_read;
479 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write=XPU_REG_RECV_ACK_COUNT_TOP1_write;
480 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_read=XPU_REG_RECV_ACK_COUNT_TOP1_read;
481 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write=XPU_REG_SEND_ACK_WAIT_TOP_write;
482 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_read=XPU_REG_SEND_ACK_WAIT_TOP_read;
483 	xpu_api->XPU_REG_MAC_ADDR_LOW_write=XPU_REG_MAC_ADDR_LOW_write;
484 	xpu_api->XPU_REG_MAC_ADDR_LOW_read=XPU_REG_MAC_ADDR_LOW_read;
485 	xpu_api->XPU_REG_MAC_ADDR_HIGH_write=XPU_REG_MAC_ADDR_HIGH_write;
486 	xpu_api->XPU_REG_MAC_ADDR_HIGH_read=XPU_REG_MAC_ADDR_HIGH_read;
487 
488 	xpu_api->XPU_REG_FILTER_FLAG_write=XPU_REG_FILTER_FLAG_write;
489 	xpu_api->XPU_REG_FILTER_FLAG_read=XPU_REG_FILTER_FLAG_read;
490 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write=XPU_REG_CTS_TO_RTS_CONFIG_write;
491 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_read=XPU_REG_CTS_TO_RTS_CONFIG_read;
492 	xpu_api->XPU_REG_BSSID_FILTER_LOW_write=XPU_REG_BSSID_FILTER_LOW_write;
493 	xpu_api->XPU_REG_BSSID_FILTER_LOW_read=XPU_REG_BSSID_FILTER_LOW_read;
494 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_write=XPU_REG_BSSID_FILTER_HIGH_write;
495 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_read=XPU_REG_BSSID_FILTER_HIGH_read;
496 
497 	xpu_api->XPU_REG_BAND_CHANNEL_write=XPU_REG_BAND_CHANNEL_write;
498 	xpu_api->XPU_REG_BAND_CHANNEL_read=XPU_REG_BAND_CHANNEL_read;
499 
500 	xpu_api->XPU_REG_DIFS_ADVANCE_write=XPU_REG_DIFS_ADVANCE_write;
501 	xpu_api->XPU_REG_DIFS_ADVANCE_read=XPU_REG_DIFS_ADVANCE_read;
502 
503 	xpu_api->XPU_REG_FORCE_IDLE_MISC_write=XPU_REG_FORCE_IDLE_MISC_write;
504 	xpu_api->XPU_REG_FORCE_IDLE_MISC_read=XPU_REG_FORCE_IDLE_MISC_read;
505 
506 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read=XPU_REG_TSF_RUNTIME_VAL_LOW_read;
507 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read=XPU_REG_TSF_RUNTIME_VAL_HIGH_read;
508 	xpu_api->XPU_REG_TSF_LOAD_VAL_LOW_write=XPU_REG_TSF_LOAD_VAL_LOW_write;
509 	xpu_api->XPU_REG_TSF_LOAD_VAL_HIGH_write=XPU_REG_TSF_LOAD_VAL_HIGH_write;
510 	xpu_api->XPU_REG_TSF_LOAD_VAL_write=XPU_REG_TSF_LOAD_VAL_write;
511 
512 	xpu_api->XPU_REG_LBT_TH_write=XPU_REG_LBT_TH_write;
513 	xpu_api->XPU_REG_LBT_TH_read=XPU_REG_LBT_TH_read;
514 
515 	xpu_api->XPU_REG_RSSI_DB_CFG_read=XPU_REG_RSSI_DB_CFG_read;
516 	xpu_api->XPU_REG_RSSI_DB_CFG_write=XPU_REG_RSSI_DB_CFG_write;
517 
518 	xpu_api->XPU_REG_CSMA_DEBUG_write=XPU_REG_CSMA_DEBUG_write;
519 	xpu_api->XPU_REG_CSMA_DEBUG_read=XPU_REG_CSMA_DEBUG_read;
520 
521 	xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write;
522 	xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read;
523 
524 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write=XPU_REG_SLICE_COUNT_TOTAL_write;
525 	xpu_api->XPU_REG_SLICE_COUNT_START_write=XPU_REG_SLICE_COUNT_START_write;
526 	xpu_api->XPU_REG_SLICE_COUNT_END_write=XPU_REG_SLICE_COUNT_END_write;
527 
528 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read=XPU_REG_SLICE_COUNT_TOTAL_read;
529 	xpu_api->XPU_REG_SLICE_COUNT_START_read=XPU_REG_SLICE_COUNT_START_read;
530 	xpu_api->XPU_REG_SLICE_COUNT_END_read=XPU_REG_SLICE_COUNT_END_read;
531 
532 	xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write;
533 
534 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write;
535 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read;
536 
537 	xpu_api->XPU_REG_AMPDU_ACTION_write=XPU_REG_AMPDU_ACTION_write;
538 	xpu_api->XPU_REG_AMPDU_ACTION_read=XPU_REG_AMPDU_ACTION_read;
539 
540 	xpu_api->XPU_REG_SPI_DISABLE_write=XPU_REG_SPI_DISABLE_write;
541 	xpu_api->XPU_REG_SPI_DISABLE_read=XPU_REG_SPI_DISABLE_read;
542 
543 	xpu_api->XPU_REG_MAC_ADDR_write=XPU_REG_MAC_ADDR_write;
544 
545 	/* Request and map I/O memory */
546 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
547 	base_addr = devm_ioremap_resource(&pdev->dev, io);
548 	if (IS_ERR(base_addr))
549 		return PTR_ERR(base_addr);
550 
551 	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);
552 	printk("%s dev_probe base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
553 	printk("%s dev_probe xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
554 	printk("%s dev_probe             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
555 
556 	printk("%s dev_probe reset tsf timer\n", xpu_compatible_str);
557 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
558 	test_us0 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
559 	mdelay(33);
560 	test_us1 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
561 	mdelay(67);
562 	test_us2 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
563 	printk("%s dev_probe XPU_REG_TSF_RUNTIME_VAL_LOW_read %d %d %dus\n", xpu_compatible_str, test_us0, test_us1, test_us2);
564 
565 	printk("%s dev_probe succeed!\n", xpu_compatible_str);
566 
567 	err = hw_init(XPU_NORMAL);
568 
569 	return err;
570 }
571 
572 static int dev_remove(struct platform_device *pdev)
573 {
574 	printk("\n");
575 
576 	printk("%s dev_remove base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
577 	printk("%s dev_remove xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
578 	printk("%s dev_remove             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
579 
580 	printk("%s dev_remove succeed!\n", xpu_compatible_str);
581 	return 0;
582 }
583 
584 static struct platform_driver dev_driver = {
585 	.driver = {
586 		.name = "sdr,xpu",
587 		.owner = THIS_MODULE,
588 		.of_match_table = dev_of_ids,
589 	},
590 	.probe = dev_probe,
591 	.remove = dev_remove,
592 };
593 
594 module_platform_driver(dev_driver);
595 
596 MODULE_AUTHOR("Xianjun Jiao");
597 MODULE_DESCRIPTION("sdr,xpu");
598 MODULE_LICENSE("GPL v2");
599