xref: /openwifi/driver/xpu/xpu.c (revision 9d7c6e634f14808c446226d4d3d1c695fe201460)
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 all queues. all time open.
338 	for (i=0; i<4; i++) {
339 		xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((i<<20)|16);//total 16us
340 		xpu_api->XPU_REG_SLICE_COUNT_START_write((i<<20)|0); //start 0us
341 		xpu_api->XPU_REG_SLICE_COUNT_END_write((i<<20)|16);  //end   16us
342 	}
343 
344 	// all slice sync rest
345 	xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
346 	xpu_api->XPU_REG_MULTI_RST_write(0<<7);
347 
348 	switch(mode)
349 	{
350 		case XPU_TEST:
351 			printk("%s hw_init mode XPU_TEST\n", xpu_compatible_str);
352 			break;
353 
354 		case XPU_NORMAL:
355 			printk("%s hw_init mode XPU_NORMAL\n", xpu_compatible_str);
356 			break;
357 
358 		default:
359 			printk("%s hw_init mode %d is wrong!\n", xpu_compatible_str, mode);
360 			err=1;
361 	}
362 	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
363 
364 	agc_gain_delay = 39; //samples
365 	rssi_half_db_offset = 75<<1;
366 	xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
367 	xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
368 
369 	//rssi_half_db_th = 70<<1; // with splitter
370 	rssi_half_db_th = 87<<1; // -62dBm
371 	xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
372 
373   // control the duration to force ch_idle after decoding a packet due to imperfection of agc and signals
374   // (1<<26) to disable eifs_trigger_by_last_tx_fail by default (standard does not ask so)
375 	xpu_api->XPU_REG_FORCE_IDLE_MISC_write((1<<26)|75);
376 
377 	//xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5));
378 	xpu_api->XPU_REG_CSMA_DEBUG_write(0);
379 
380 	// xpu_api->XPU_REG_CSMA_CFG_write(268435459);  // Linux will do config for each queue via openwifi_conf_tx
381 	// xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); // Linux will do config for each queue via openwifi_conf_tx
382 
383 //	// ------- assume 2.4 and 5GHz have the same SIFS (6us signal extension) --------
384 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+25)<<16)|((16+25)<<0) );
385 	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)
386 	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)
387 //	// ------- assume 2.4 and 5GHz have different SIFS --------
388 	// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+23)<<16)|(0+23) );
389 	// 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)
390 	// 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)
391 
392 	xpu_api->XPU_REG_DIFS_ADVANCE_write((OPENWIFI_MAX_SIGNAL_LEN_TH<<16)|2); //us. bit31~16 max pkt length threshold
393 
394 	printk("%s hw_init err %d\n", xpu_compatible_str, err);
395 	return(err);
396 }
397 
398 static int dev_probe(struct platform_device *pdev)
399 {
400 	struct device_node *np = pdev->dev.of_node;
401 	struct resource *io;
402 	u32 test_us0, test_us1, test_us2;
403 	int err=1;
404 
405 	printk("\n");
406 
407 	if (np) {
408 		const struct of_device_id *match;
409 
410 		match = of_match_node(dev_of_ids, np);
411 		if (match) {
412 			printk("%s dev_probe match!\n", xpu_compatible_str);
413 			err = 0;
414 		}
415 	}
416 
417 	if (err)
418 		return err;
419 
420 	xpu_api->hw_init=hw_init;
421 
422 	xpu_api->reg_read=reg_read;
423 	xpu_api->reg_write=reg_write;
424 
425 	xpu_api->XPU_REG_MULTI_RST_write=XPU_REG_MULTI_RST_write;
426 	xpu_api->XPU_REG_MULTI_RST_read=XPU_REG_MULTI_RST_read;
427 	xpu_api->XPU_REG_SRC_SEL_write=XPU_REG_SRC_SEL_write;
428 	xpu_api->XPU_REG_SRC_SEL_read=XPU_REG_SRC_SEL_read;
429 
430 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write=XPU_REG_RECV_ACK_COUNT_TOP0_write;
431 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_read=XPU_REG_RECV_ACK_COUNT_TOP0_read;
432 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write=XPU_REG_RECV_ACK_COUNT_TOP1_write;
433 	xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_read=XPU_REG_RECV_ACK_COUNT_TOP1_read;
434 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write=XPU_REG_SEND_ACK_WAIT_TOP_write;
435 	xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_read=XPU_REG_SEND_ACK_WAIT_TOP_read;
436 	xpu_api->XPU_REG_MAC_ADDR_LOW_write=XPU_REG_MAC_ADDR_LOW_write;
437 	xpu_api->XPU_REG_MAC_ADDR_LOW_read=XPU_REG_MAC_ADDR_LOW_read;
438 	xpu_api->XPU_REG_MAC_ADDR_HIGH_write=XPU_REG_MAC_ADDR_HIGH_write;
439 	xpu_api->XPU_REG_MAC_ADDR_HIGH_read=XPU_REG_MAC_ADDR_HIGH_read;
440 
441 	xpu_api->XPU_REG_FILTER_FLAG_write=XPU_REG_FILTER_FLAG_write;
442 	xpu_api->XPU_REG_FILTER_FLAG_read=XPU_REG_FILTER_FLAG_read;
443 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write=XPU_REG_CTS_TO_RTS_CONFIG_write;
444 	xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_read=XPU_REG_CTS_TO_RTS_CONFIG_read;
445 	xpu_api->XPU_REG_BSSID_FILTER_LOW_write=XPU_REG_BSSID_FILTER_LOW_write;
446 	xpu_api->XPU_REG_BSSID_FILTER_LOW_read=XPU_REG_BSSID_FILTER_LOW_read;
447 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_write=XPU_REG_BSSID_FILTER_HIGH_write;
448 	xpu_api->XPU_REG_BSSID_FILTER_HIGH_read=XPU_REG_BSSID_FILTER_HIGH_read;
449 
450 	xpu_api->XPU_REG_BAND_CHANNEL_write=XPU_REG_BAND_CHANNEL_write;
451 	xpu_api->XPU_REG_BAND_CHANNEL_read=XPU_REG_BAND_CHANNEL_read;
452 
453 	xpu_api->XPU_REG_DIFS_ADVANCE_write=XPU_REG_DIFS_ADVANCE_write;
454 	xpu_api->XPU_REG_DIFS_ADVANCE_read=XPU_REG_DIFS_ADVANCE_read;
455 
456 	xpu_api->XPU_REG_FORCE_IDLE_MISC_write=XPU_REG_FORCE_IDLE_MISC_write;
457 	xpu_api->XPU_REG_FORCE_IDLE_MISC_read=XPU_REG_FORCE_IDLE_MISC_read;
458 
459 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read=XPU_REG_TSF_RUNTIME_VAL_LOW_read;
460 	xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read=XPU_REG_TSF_RUNTIME_VAL_HIGH_read;
461 	xpu_api->XPU_REG_TSF_LOAD_VAL_LOW_write=XPU_REG_TSF_LOAD_VAL_LOW_write;
462 	xpu_api->XPU_REG_TSF_LOAD_VAL_HIGH_write=XPU_REG_TSF_LOAD_VAL_HIGH_write;
463 	xpu_api->XPU_REG_TSF_LOAD_VAL_write=XPU_REG_TSF_LOAD_VAL_write;
464 
465 	xpu_api->XPU_REG_LBT_TH_write=XPU_REG_LBT_TH_write;
466 	xpu_api->XPU_REG_LBT_TH_read=XPU_REG_LBT_TH_read;
467 
468 	xpu_api->XPU_REG_RSSI_DB_CFG_read=XPU_REG_RSSI_DB_CFG_read;
469 	xpu_api->XPU_REG_RSSI_DB_CFG_write=XPU_REG_RSSI_DB_CFG_write;
470 
471 	xpu_api->XPU_REG_CSMA_DEBUG_write=XPU_REG_CSMA_DEBUG_write;
472 	xpu_api->XPU_REG_CSMA_DEBUG_read=XPU_REG_CSMA_DEBUG_read;
473 
474 	xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write;
475 	xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read;
476 
477 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write=XPU_REG_SLICE_COUNT_TOTAL_write;
478 	xpu_api->XPU_REG_SLICE_COUNT_START_write=XPU_REG_SLICE_COUNT_START_write;
479 	xpu_api->XPU_REG_SLICE_COUNT_END_write=XPU_REG_SLICE_COUNT_END_write;
480 
481 	xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read=XPU_REG_SLICE_COUNT_TOTAL_read;
482 	xpu_api->XPU_REG_SLICE_COUNT_START_read=XPU_REG_SLICE_COUNT_START_read;
483 	xpu_api->XPU_REG_SLICE_COUNT_END_read=XPU_REG_SLICE_COUNT_END_read;
484 
485 	xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write;
486 
487 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write;
488 	xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read;
489 
490 	xpu_api->XPU_REG_AMPDU_ACTION_write=XPU_REG_AMPDU_ACTION_write;
491 	xpu_api->XPU_REG_AMPDU_ACTION_read=XPU_REG_AMPDU_ACTION_read;
492 
493 	xpu_api->XPU_REG_SPI_DISABLE_write=XPU_REG_SPI_DISABLE_write;
494 	xpu_api->XPU_REG_SPI_DISABLE_read=XPU_REG_SPI_DISABLE_read;
495 
496 	xpu_api->XPU_REG_MAC_ADDR_write=XPU_REG_MAC_ADDR_write;
497 
498 	/* Request and map I/O memory */
499 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
500 	base_addr = devm_ioremap_resource(&pdev->dev, io);
501 	if (IS_ERR(base_addr))
502 		return PTR_ERR(base_addr);
503 
504 	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);
505 	printk("%s dev_probe base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
506 	printk("%s dev_probe xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
507 	printk("%s dev_probe             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
508 
509 	printk("%s dev_probe reset tsf timer\n", xpu_compatible_str);
510 	xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
511 	test_us0 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
512 	mdelay(33);
513 	test_us1 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
514 	mdelay(67);
515 	test_us2 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
516 	printk("%s dev_probe XPU_REG_TSF_RUNTIME_VAL_LOW_read %d %d %dus\n", xpu_compatible_str, test_us0, test_us1, test_us2);
517 
518 	printk("%s dev_probe succeed!\n", xpu_compatible_str);
519 
520 	err = hw_init(XPU_NORMAL);
521 
522 	return err;
523 }
524 
525 static int dev_remove(struct platform_device *pdev)
526 {
527 	printk("\n");
528 
529 	printk("%s dev_remove base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
530 	printk("%s dev_remove xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
531 	printk("%s dev_remove             xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
532 
533 	printk("%s dev_remove succeed!\n", xpu_compatible_str);
534 	return 0;
535 }
536 
537 static struct platform_driver dev_driver = {
538 	.driver = {
539 		.name = "sdr,xpu",
540 		.owner = THIS_MODULE,
541 		.of_match_table = dev_of_ids,
542 	},
543 	.probe = dev_probe,
544 	.remove = dev_remove,
545 };
546 
547 module_platform_driver(dev_driver);
548 
549 MODULE_AUTHOR("Xianjun Jiao");
550 MODULE_DESCRIPTION("sdr,xpu");
551 MODULE_LICENSE("GPL v2");
552