1*2ee67178SXianjun Jiao /* 2*2ee67178SXianjun Jiao * axi lite register access driver 3*2ee67178SXianjun Jiao * Xianjun jiao. [email protected]; [email protected] 4*2ee67178SXianjun Jiao */ 5*2ee67178SXianjun Jiao 6*2ee67178SXianjun Jiao #include <linux/bitops.h> 7*2ee67178SXianjun Jiao #include <linux/dmapool.h> 8*2ee67178SXianjun Jiao #include <linux/dma/xilinx_dma.h> 9*2ee67178SXianjun Jiao #include <linux/init.h> 10*2ee67178SXianjun Jiao #include <linux/interrupt.h> 11*2ee67178SXianjun Jiao #include <linux/io.h> 12*2ee67178SXianjun Jiao #include <linux/iopoll.h> 13*2ee67178SXianjun Jiao #include <linux/module.h> 14*2ee67178SXianjun Jiao #include <linux/of_address.h> 15*2ee67178SXianjun Jiao #include <linux/of_dma.h> 16*2ee67178SXianjun Jiao #include <linux/of_platform.h> 17*2ee67178SXianjun Jiao #include <linux/of_irq.h> 18*2ee67178SXianjun Jiao #include <linux/slab.h> 19*2ee67178SXianjun Jiao #include <linux/clk.h> 20*2ee67178SXianjun Jiao #include <linux/io-64-nonatomic-lo-hi.h> 21*2ee67178SXianjun Jiao #include <linux/delay.h> 22*2ee67178SXianjun Jiao #include <net/mac80211.h> 23*2ee67178SXianjun Jiao 24*2ee67178SXianjun Jiao #include "../hw_def.h" 25*2ee67178SXianjun Jiao 26*2ee67178SXianjun Jiao 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 27*2ee67178SXianjun Jiao 28*2ee67178SXianjun Jiao /* IO accessors */ 29*2ee67178SXianjun Jiao static inline u32 reg_read(u32 reg) 30*2ee67178SXianjun Jiao { 31*2ee67178SXianjun Jiao return ioread32(base_addr + reg); 32*2ee67178SXianjun Jiao } 33*2ee67178SXianjun Jiao 34*2ee67178SXianjun Jiao static inline void reg_write(u32 reg, u32 value) 35*2ee67178SXianjun Jiao { 36*2ee67178SXianjun Jiao iowrite32(value, base_addr + reg); 37*2ee67178SXianjun Jiao } 38*2ee67178SXianjun Jiao 39*2ee67178SXianjun Jiao static inline void XPU_REG_MULTI_RST_write(u32 Data) { 40*2ee67178SXianjun Jiao reg_write(XPU_REG_MULTI_RST_ADDR, Data); 41*2ee67178SXianjun Jiao } 42*2ee67178SXianjun Jiao 43*2ee67178SXianjun Jiao static inline u32 XPU_REG_MULTI_RST_read(void){ 44*2ee67178SXianjun Jiao return reg_read(XPU_REG_MULTI_RST_ADDR); 45*2ee67178SXianjun Jiao } 46*2ee67178SXianjun Jiao 47*2ee67178SXianjun Jiao static inline void XPU_REG_SRC_SEL_write(u32 Data) { 48*2ee67178SXianjun Jiao reg_write(XPU_REG_SRC_SEL_ADDR, Data); 49*2ee67178SXianjun Jiao } 50*2ee67178SXianjun Jiao 51*2ee67178SXianjun Jiao static inline u32 XPU_REG_SRC_SEL_read(void){ 52*2ee67178SXianjun Jiao return reg_read(XPU_REG_SRC_SEL_ADDR); 53*2ee67178SXianjun Jiao } 54*2ee67178SXianjun Jiao 55*2ee67178SXianjun Jiao static inline void XPU_REG_RECV_ACK_COUNT_TOP0_write(u32 Data) { 56*2ee67178SXianjun Jiao reg_write(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR, Data); 57*2ee67178SXianjun Jiao } 58*2ee67178SXianjun Jiao 59*2ee67178SXianjun Jiao static inline u32 XPU_REG_RECV_ACK_COUNT_TOP0_read(void){ 60*2ee67178SXianjun Jiao return reg_read(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR); 61*2ee67178SXianjun Jiao } 62*2ee67178SXianjun Jiao 63*2ee67178SXianjun Jiao static inline void XPU_REG_RECV_ACK_COUNT_TOP1_write(u32 Data) { 64*2ee67178SXianjun Jiao reg_write(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR, Data); 65*2ee67178SXianjun Jiao } 66*2ee67178SXianjun Jiao 67*2ee67178SXianjun Jiao static inline u32 XPU_REG_RECV_ACK_COUNT_TOP1_read(void){ 68*2ee67178SXianjun Jiao return reg_read(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR); 69*2ee67178SXianjun Jiao } 70*2ee67178SXianjun Jiao 71*2ee67178SXianjun Jiao static inline void XPU_REG_SEND_ACK_WAIT_TOP_write(u32 Data) { 72*2ee67178SXianjun Jiao reg_write(XPU_REG_SEND_ACK_WAIT_TOP_ADDR, Data); 73*2ee67178SXianjun Jiao } 74*2ee67178SXianjun Jiao 75*2ee67178SXianjun Jiao static inline u32 XPU_REG_SEND_ACK_WAIT_TOP_read(void){ 76*2ee67178SXianjun Jiao return reg_read(XPU_REG_SEND_ACK_WAIT_TOP_ADDR); 77*2ee67178SXianjun Jiao } 78*2ee67178SXianjun Jiao 79*2ee67178SXianjun Jiao static inline void XPU_REG_FILTER_FLAG_write(u32 Data) { 80*2ee67178SXianjun Jiao reg_write(XPU_REG_FILTER_FLAG_ADDR, Data); 81*2ee67178SXianjun Jiao } 82*2ee67178SXianjun Jiao 83*2ee67178SXianjun Jiao static inline u32 XPU_REG_FILTER_FLAG_read(void){ 84*2ee67178SXianjun Jiao return reg_read(XPU_REG_FILTER_FLAG_ADDR); 85*2ee67178SXianjun Jiao } 86*2ee67178SXianjun Jiao 87*2ee67178SXianjun Jiao static inline void XPU_REG_CTS_TO_RTS_CONFIG_write(u32 Data) { 88*2ee67178SXianjun Jiao reg_write(XPU_REG_CTS_TO_RTS_CONFIG_ADDR, Data); 89*2ee67178SXianjun Jiao } 90*2ee67178SXianjun Jiao 91*2ee67178SXianjun Jiao static inline u32 XPU_REG_CTS_TO_RTS_CONFIG_read(void){ 92*2ee67178SXianjun Jiao return reg_read(XPU_REG_CTS_TO_RTS_CONFIG_ADDR); 93*2ee67178SXianjun Jiao } 94*2ee67178SXianjun Jiao 95*2ee67178SXianjun Jiao static inline void XPU_REG_MAC_ADDR_LOW_write(u32 Data) { 96*2ee67178SXianjun Jiao reg_write(XPU_REG_MAC_ADDR_LOW_ADDR, Data); 97*2ee67178SXianjun Jiao } 98*2ee67178SXianjun Jiao 99*2ee67178SXianjun Jiao static inline u32 XPU_REG_MAC_ADDR_LOW_read(void){ 100*2ee67178SXianjun Jiao return reg_read(XPU_REG_MAC_ADDR_LOW_ADDR); 101*2ee67178SXianjun Jiao } 102*2ee67178SXianjun Jiao 103*2ee67178SXianjun Jiao static inline void XPU_REG_MAC_ADDR_HIGH_write(u32 Data) { 104*2ee67178SXianjun Jiao reg_write(XPU_REG_MAC_ADDR_HIGH_ADDR, Data); 105*2ee67178SXianjun Jiao } 106*2ee67178SXianjun Jiao 107*2ee67178SXianjun Jiao static inline u32 XPU_REG_MAC_ADDR_HIGH_read(void){ 108*2ee67178SXianjun Jiao return reg_read(XPU_REG_MAC_ADDR_HIGH_ADDR); 109*2ee67178SXianjun Jiao } 110*2ee67178SXianjun Jiao 111*2ee67178SXianjun Jiao static inline void XPU_REG_BSSID_FILTER_LOW_write(u32 Data) { 112*2ee67178SXianjun Jiao reg_write(XPU_REG_BSSID_FILTER_LOW_ADDR, Data); 113*2ee67178SXianjun Jiao } 114*2ee67178SXianjun Jiao 115*2ee67178SXianjun Jiao static inline u32 XPU_REG_BSSID_FILTER_LOW_read(void){ 116*2ee67178SXianjun Jiao return reg_read(XPU_REG_BSSID_FILTER_LOW_ADDR); 117*2ee67178SXianjun Jiao } 118*2ee67178SXianjun Jiao 119*2ee67178SXianjun Jiao static inline void XPU_REG_BSSID_FILTER_HIGH_write(u32 Data) { 120*2ee67178SXianjun Jiao reg_write(XPU_REG_BSSID_FILTER_HIGH_ADDR, Data); 121*2ee67178SXianjun Jiao } 122*2ee67178SXianjun Jiao 123*2ee67178SXianjun Jiao static inline u32 XPU_REG_BSSID_FILTER_HIGH_read(void){ 124*2ee67178SXianjun Jiao return reg_read(XPU_REG_BSSID_FILTER_HIGH_ADDR); 125*2ee67178SXianjun Jiao } 126*2ee67178SXianjun Jiao 127*2ee67178SXianjun Jiao static inline void XPU_REG_BAND_CHANNEL_write(u32 Data) { 128*2ee67178SXianjun Jiao reg_write(XPU_REG_BAND_CHANNEL_ADDR, Data); 129*2ee67178SXianjun Jiao } 130*2ee67178SXianjun Jiao 131*2ee67178SXianjun Jiao static inline u32 XPU_REG_BAND_CHANNEL_read(void){ 132*2ee67178SXianjun Jiao return reg_read(XPU_REG_BAND_CHANNEL_ADDR); 133*2ee67178SXianjun Jiao } 134*2ee67178SXianjun Jiao 135*2ee67178SXianjun Jiao static inline u32 XPU_REG_TRX_STATUS_read(void){ 136*2ee67178SXianjun Jiao return reg_read(XPU_REG_TRX_STATUS_ADDR); 137*2ee67178SXianjun Jiao } 138*2ee67178SXianjun Jiao 139*2ee67178SXianjun Jiao static inline u32 XPU_REG_TX_RESULT_read(void){ 140*2ee67178SXianjun Jiao return reg_read(XPU_REG_TX_RESULT_ADDR); 141*2ee67178SXianjun Jiao } 142*2ee67178SXianjun Jiao 143*2ee67178SXianjun Jiao static inline u32 XPU_REG_TSF_RUNTIME_VAL_LOW_read(void){ 144*2ee67178SXianjun Jiao return reg_read(XPU_REG_TSF_RUNTIME_VAL_LOW_ADDR); 145*2ee67178SXianjun Jiao } 146*2ee67178SXianjun Jiao 147*2ee67178SXianjun Jiao static inline u32 XPU_REG_TSF_RUNTIME_VAL_HIGH_read(void){ 148*2ee67178SXianjun Jiao return reg_read(XPU_REG_TSF_RUNTIME_VAL_HIGH_ADDR); 149*2ee67178SXianjun Jiao } 150*2ee67178SXianjun Jiao 151*2ee67178SXianjun Jiao static inline void XPU_REG_TSF_LOAD_VAL_LOW_write(u32 value){ 152*2ee67178SXianjun Jiao reg_write(XPU_REG_TSF_LOAD_VAL_LOW_ADDR, value); 153*2ee67178SXianjun Jiao } 154*2ee67178SXianjun Jiao 155*2ee67178SXianjun Jiao static inline void XPU_REG_TSF_LOAD_VAL_HIGH_write(u32 value){ 156*2ee67178SXianjun Jiao reg_write(XPU_REG_TSF_LOAD_VAL_HIGH_ADDR, value); 157*2ee67178SXianjun Jiao } 158*2ee67178SXianjun Jiao 159*2ee67178SXianjun Jiao static inline void XPU_REG_TSF_LOAD_VAL_write(u32 high_value, u32 low_value){ 160*2ee67178SXianjun Jiao XPU_REG_TSF_LOAD_VAL_LOW_write(low_value); 161*2ee67178SXianjun Jiao XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value|0x80000000); // msb high 162*2ee67178SXianjun Jiao XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value&(~0x80000000)); // msb low 163*2ee67178SXianjun Jiao } 164*2ee67178SXianjun Jiao 165*2ee67178SXianjun Jiao static inline u32 XPU_REG_FC_DI_read(void){ 166*2ee67178SXianjun Jiao return reg_read(XPU_REG_FC_DI_ADDR); 167*2ee67178SXianjun Jiao } 168*2ee67178SXianjun Jiao 169*2ee67178SXianjun Jiao static inline u32 XPU_REG_ADDR1_LOW_read(void){ 170*2ee67178SXianjun Jiao return reg_read(XPU_REG_ADDR1_LOW_ADDR); 171*2ee67178SXianjun Jiao } 172*2ee67178SXianjun Jiao 173*2ee67178SXianjun Jiao static inline u32 XPU_REG_ADDR1_HIGH_read(void){ 174*2ee67178SXianjun Jiao return reg_read(XPU_REG_ADDR1_HIGH_ADDR); 175*2ee67178SXianjun Jiao } 176*2ee67178SXianjun Jiao 177*2ee67178SXianjun Jiao static inline u32 XPU_REG_ADDR2_LOW_read(void){ 178*2ee67178SXianjun Jiao return reg_read(XPU_REG_ADDR2_LOW_ADDR); 179*2ee67178SXianjun Jiao } 180*2ee67178SXianjun Jiao 181*2ee67178SXianjun Jiao static inline u32 XPU_REG_ADDR2_HIGH_read(void){ 182*2ee67178SXianjun Jiao return reg_read(XPU_REG_ADDR2_HIGH_ADDR); 183*2ee67178SXianjun Jiao } 184*2ee67178SXianjun Jiao 185*2ee67178SXianjun Jiao // static inline void XPU_REG_LBT_TH_write(u32 value, u32 en_flag) { 186*2ee67178SXianjun Jiao // if (en_flag) { 187*2ee67178SXianjun Jiao // reg_write(XPU_REG_LBT_TH_ADDR, value&0x7FFFFFFF); 188*2ee67178SXianjun Jiao // } else { 189*2ee67178SXianjun Jiao // reg_write(XPU_REG_LBT_TH_ADDR, value|0x80000000); 190*2ee67178SXianjun Jiao // } 191*2ee67178SXianjun Jiao // } 192*2ee67178SXianjun Jiao 193*2ee67178SXianjun Jiao static inline void XPU_REG_LBT_TH_write(u32 value) { 194*2ee67178SXianjun Jiao reg_write(XPU_REG_LBT_TH_ADDR, value); 195*2ee67178SXianjun Jiao } 196*2ee67178SXianjun Jiao 197*2ee67178SXianjun Jiao static inline u32 XPU_REG_RSSI_DB_CFG_read(void){ 198*2ee67178SXianjun Jiao return reg_read(XPU_REG_RSSI_DB_CFG_ADDR); 199*2ee67178SXianjun Jiao } 200*2ee67178SXianjun Jiao 201*2ee67178SXianjun Jiao static inline void XPU_REG_RSSI_DB_CFG_write(u32 Data) { 202*2ee67178SXianjun Jiao reg_write(XPU_REG_RSSI_DB_CFG_ADDR, Data); 203*2ee67178SXianjun Jiao } 204*2ee67178SXianjun Jiao 205*2ee67178SXianjun Jiao static inline u32 XPU_REG_LBT_TH_read(void){ 206*2ee67178SXianjun Jiao return reg_read(XPU_REG_LBT_TH_ADDR); 207*2ee67178SXianjun Jiao } 208*2ee67178SXianjun Jiao 209*2ee67178SXianjun Jiao static inline void XPU_REG_CSMA_DEBUG_write(u32 value){ 210*2ee67178SXianjun Jiao reg_write(XPU_REG_CSMA_DEBUG_ADDR, value); 211*2ee67178SXianjun Jiao } 212*2ee67178SXianjun Jiao 213*2ee67178SXianjun Jiao static inline u32 XPU_REG_CSMA_DEBUG_read(void){ 214*2ee67178SXianjun Jiao return reg_read(XPU_REG_CSMA_DEBUG_ADDR); 215*2ee67178SXianjun Jiao } 216*2ee67178SXianjun Jiao 217*2ee67178SXianjun Jiao static inline void XPU_REG_CSMA_CFG_write(u32 value){ 218*2ee67178SXianjun Jiao reg_write(XPU_REG_CSMA_CFG_ADDR, value); 219*2ee67178SXianjun Jiao } 220*2ee67178SXianjun Jiao 221*2ee67178SXianjun Jiao static inline u32 XPU_REG_CSMA_CFG_read(void){ 222*2ee67178SXianjun Jiao return reg_read(XPU_REG_CSMA_CFG_ADDR); 223*2ee67178SXianjun Jiao } 224*2ee67178SXianjun Jiao 225*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_TOTAL0_write(u32 value){ 226*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_TOTAL0_ADDR, value); 227*2ee67178SXianjun Jiao } 228*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_START0_write(u32 value){ 229*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_START0_ADDR, value); 230*2ee67178SXianjun Jiao } 231*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_END0_write(u32 value){ 232*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_END0_ADDR, value); 233*2ee67178SXianjun Jiao } 234*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_TOTAL1_write(u32 value){ 235*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_TOTAL1_ADDR, value); 236*2ee67178SXianjun Jiao } 237*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_START1_write(u32 value){ 238*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_START1_ADDR, value); 239*2ee67178SXianjun Jiao } 240*2ee67178SXianjun Jiao static inline void XPU_REG_SLICE_COUNT_END1_write(u32 value){ 241*2ee67178SXianjun Jiao reg_write(XPU_REG_SLICE_COUNT_END1_ADDR, value); 242*2ee67178SXianjun Jiao } 243*2ee67178SXianjun Jiao 244*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_TOTAL0_read(void){ 245*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_TOTAL0_ADDR); 246*2ee67178SXianjun Jiao } 247*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_START0_read(void){ 248*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_START0_ADDR); 249*2ee67178SXianjun Jiao } 250*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_END0_read(void){ 251*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_END0_ADDR); 252*2ee67178SXianjun Jiao } 253*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_TOTAL1_read(void){ 254*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_TOTAL1_ADDR); 255*2ee67178SXianjun Jiao } 256*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_START1_read(void){ 257*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_START1_ADDR); 258*2ee67178SXianjun Jiao } 259*2ee67178SXianjun Jiao static inline u32 XPU_REG_SLICE_COUNT_END1_read(void){ 260*2ee67178SXianjun Jiao return reg_read(XPU_REG_SLICE_COUNT_END1_ADDR); 261*2ee67178SXianjun Jiao } 262*2ee67178SXianjun Jiao 263*2ee67178SXianjun Jiao static inline void XPU_REG_BB_RF_DELAY_write(u32 value){ 264*2ee67178SXianjun Jiao reg_write(XPU_REG_BB_RF_DELAY_ADDR, value); 265*2ee67178SXianjun Jiao } 266*2ee67178SXianjun Jiao 267*2ee67178SXianjun Jiao static inline void XPU_REG_MAX_NUM_RETRANS_write(u32 value){ 268*2ee67178SXianjun Jiao reg_write(XPU_REG_MAX_NUM_RETRANS_ADDR, value); 269*2ee67178SXianjun Jiao } 270*2ee67178SXianjun Jiao 271*2ee67178SXianjun Jiao static inline void XPU_REG_MAC_ADDR_write(u8 *mac_addr) {//, u32 en_flag){ 272*2ee67178SXianjun Jiao XPU_REG_MAC_ADDR_LOW_write( *( (u32*)(mac_addr) ) ); 273*2ee67178SXianjun Jiao XPU_REG_MAC_ADDR_HIGH_write( *( (u16*)(mac_addr + 4) ) ); 274*2ee67178SXianjun Jiao #if 0 275*2ee67178SXianjun Jiao if (en_flag) { 276*2ee67178SXianjun Jiao XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) | 0x80000000 ); // 0x80000000 by default we turn on mac addr filter 277*2ee67178SXianjun Jiao } else { 278*2ee67178SXianjun Jiao XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) & 0x7FFFFFFF ); 279*2ee67178SXianjun Jiao } 280*2ee67178SXianjun Jiao #endif 281*2ee67178SXianjun Jiao } 282*2ee67178SXianjun Jiao 283*2ee67178SXianjun Jiao static const struct of_device_id dev_of_ids[] = { 284*2ee67178SXianjun Jiao { .compatible = "sdr,xpu", }, 285*2ee67178SXianjun Jiao {} 286*2ee67178SXianjun Jiao }; 287*2ee67178SXianjun Jiao MODULE_DEVICE_TABLE(of, dev_of_ids); 288*2ee67178SXianjun Jiao 289*2ee67178SXianjun Jiao static struct xpu_driver_api xpu_driver_api_inst; 290*2ee67178SXianjun Jiao static struct xpu_driver_api *xpu_api = &xpu_driver_api_inst; 291*2ee67178SXianjun Jiao EXPORT_SYMBOL(xpu_api); 292*2ee67178SXianjun Jiao 293*2ee67178SXianjun Jiao static inline u32 hw_init(enum xpu_mode mode){ 294*2ee67178SXianjun Jiao int err=0, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay; 295*2ee67178SXianjun Jiao u32 reg_val; 296*2ee67178SXianjun Jiao u32 filter_flag = 0; 297*2ee67178SXianjun Jiao 298*2ee67178SXianjun Jiao printk("%s hw_init mode %d\n", xpu_compatible_str, mode); 299*2ee67178SXianjun Jiao 300*2ee67178SXianjun Jiao //rst internal module 301*2ee67178SXianjun Jiao for (reg_val=0;reg_val<32;reg_val++) 302*2ee67178SXianjun Jiao xpu_api->XPU_REG_MULTI_RST_write(0xFFFFFFFF); 303*2ee67178SXianjun Jiao xpu_api->XPU_REG_MULTI_RST_write(0); 304*2ee67178SXianjun Jiao 305*2ee67178SXianjun Jiao // http://www.studioreti.it/slide/802-11-Frame_E_C.pdf 306*2ee67178SXianjun Jiao // https://mrncciew.com/2014/10/14/cwap-802-11-phy-ppdu/ 307*2ee67178SXianjun Jiao // https://mrncciew.com/2014/09/27/cwap-mac-header-frame-control/ 308*2ee67178SXianjun Jiao // https://mrncciew.com/2014/10/25/cwap-mac-header-durationid/ 309*2ee67178SXianjun Jiao // https://mrncciew.com/2014/11/01/cwap-mac-header-sequence-control/ 310*2ee67178SXianjun Jiao // https://witestlab.poly.edu/blog/802-11-wireless-lan-2/ 311*2ee67178SXianjun Jiao // phy_rx byte idx: 312*2ee67178SXianjun Jiao // 5(3 sig + 2 service), -- PHY 313*2ee67178SXianjun Jiao // 2 frame control, 2 duration/conn ID, --MAC PDU 314*2ee67178SXianjun Jiao // 6 receiver address, 6 destination address, 6 transmitter address 315*2ee67178SXianjun Jiao // 2 sequence control 316*2ee67178SXianjun Jiao // 6 source address 317*2ee67178SXianjun Jiao // reg_val = 5 + 0; 318*2ee67178SXianjun Jiao // xpu_api->XPU_REG_PHY_RX_PKT_READ_OFFSET_write(reg_val); 319*2ee67178SXianjun Jiao // printk("%s hw_init XPU_REG_PHY_RX_PKT_READ_OFFSET_write %d\n", xpu_compatible_str, reg_val); 320*2ee67178SXianjun Jiao 321*2ee67178SXianjun Jiao // by default turn off filter, because all register are zeros 322*2ee67178SXianjun Jiao // let's filter out packet according to: enum ieee80211_filter_flags at: https://www.kernel.org/doc/html/v4.9/80211/mac80211.html 323*2ee67178SXianjun Jiao #if 0 // define in FPGA 324*2ee67178SXianjun Jiao 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 325*2ee67178SXianjun Jiao FIF_FCSFAIL = 14b00000000000100, //not support 326*2ee67178SXianjun Jiao FIF_PLCPFAIL = 14b00000000001000, //not support 327*2ee67178SXianjun Jiao FIF_BCN_PRBRESP_PROMISC= 14b00000000010000, 328*2ee67178SXianjun Jiao FIF_CONTROL = 14b00000000100000, 329*2ee67178SXianjun Jiao FIF_OTHER_BSS = 14b00000001000000, 330*2ee67178SXianjun Jiao FIF_PSPOLL = 14b00000010000000, 331*2ee67178SXianjun Jiao FIF_PROBE_REQ = 14b00000100000000, 332*2ee67178SXianjun Jiao UNICAST_FOR_US = 14b00001000000000, 333*2ee67178SXianjun Jiao BROADCAST_ALL_ONE = 14b00010000000000, 334*2ee67178SXianjun Jiao BROADCAST_ALL_ZERO = 14b00100000000000, 335*2ee67178SXianjun Jiao MY_BEACON = 14b01000000000000, 336*2ee67178SXianjun Jiao MONITOR_ALL = 14b10000000000000; 337*2ee67178SXianjun Jiao #endif 338*2ee67178SXianjun Jiao 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); 339*2ee67178SXianjun Jiao xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag); 340*2ee67178SXianjun Jiao xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write(0xB<<16);//6M 1011:0xB 341*2ee67178SXianjun Jiao 342*2ee67178SXianjun Jiao ////set up FC type filter for packet needs ACK -- no use, FPGA handle by itself 343*2ee67178SXianjun Jiao //xpu_api->XPU_REG_ACK_FC_FILTER_write((3<<(2+16))|(2<<2)); // low 16 bits target FC 16 bits; high 16 bits -- mask 344*2ee67178SXianjun Jiao 345*2ee67178SXianjun Jiao // after send data frame wait for ACK, this will be set in real time in function ad9361_rf_set_channel 346*2ee67178SXianjun Jiao // xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+2)*200)<<16) | 200 ); // 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"! 347*2ee67178SXianjun Jiao // xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 1200 ); // +6 = 16us for 5GHz 348*2ee67178SXianjun Jiao 349*2ee67178SXianjun Jiao //xpu_api->XPU_REG_MAX_NUM_RETRANS_write(3); // if this > 0, it will override mac80211 set value, and set static retransmission limit 350*2ee67178SXianjun Jiao 351*2ee67178SXianjun Jiao xpu_api->XPU_REG_BB_RF_DELAY_write(975); 352*2ee67178SXianjun Jiao 353*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write(50000-1); // total 50ms 354*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START0_write(0); //start 0ms 355*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END0_write(50000-1); //end 10ms 356*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write(50000-1); // total 50ms 357*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START1_write(0000); //start 0ms 358*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END1_write(1000-1); //end 1ms 359*2ee67178SXianjun Jiao 360*2ee67178SXianjun Jiao switch(mode) 361*2ee67178SXianjun Jiao { 362*2ee67178SXianjun Jiao case XPU_TEST: 363*2ee67178SXianjun Jiao printk("%s hw_init mode XPU_TEST\n", xpu_compatible_str); 364*2ee67178SXianjun Jiao break; 365*2ee67178SXianjun Jiao 366*2ee67178SXianjun Jiao case XPU_NORMAL: 367*2ee67178SXianjun Jiao printk("%s hw_init mode XPU_NORMAL\n", xpu_compatible_str); 368*2ee67178SXianjun Jiao break; 369*2ee67178SXianjun Jiao 370*2ee67178SXianjun Jiao default: 371*2ee67178SXianjun Jiao printk("%s hw_init mode %d is wrong!\n", xpu_compatible_str, mode); 372*2ee67178SXianjun Jiao err=1; 373*2ee67178SXianjun Jiao } 374*2ee67178SXianjun Jiao 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 375*2ee67178SXianjun Jiao 376*2ee67178SXianjun Jiao agc_gain_delay = 50; //samples 377*2ee67178SXianjun Jiao rssi_half_db_offset = 75<<1; 378*2ee67178SXianjun Jiao xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) ); 379*2ee67178SXianjun Jiao xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) ); 380*2ee67178SXianjun Jiao 381*2ee67178SXianjun Jiao //rssi_half_db_th = 70<<1; // with splitter 382*2ee67178SXianjun Jiao rssi_half_db_th = 87<<1; // -62dBm 383*2ee67178SXianjun Jiao xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it 384*2ee67178SXianjun Jiao 385*2ee67178SXianjun Jiao //xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5)); 386*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_DEBUG_write(0); 387*2ee67178SXianjun Jiao 388*2ee67178SXianjun Jiao //xpu_api->XPU_REG_CSMA_CFG_write(3); //normal CSMA 389*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); //high priority 390*2ee67178SXianjun Jiao 391*2ee67178SXianjun Jiao xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((1030-238)<<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!) 392*2ee67178SXianjun Jiao //xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (((45+2+2)*200)<<16) | 400 );//2.4GHz 393*2ee67178SXianjun Jiao //xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+2+2)*200)<<16) | 400 );//5GHz 394*2ee67178SXianjun Jiao 395*2ee67178SXianjun Jiao // // value from openwifi-preo csma_test 396*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (((45+2+6)*200)<<16) | 200 );//2.4GHz, still need to find out why sometimes the PI in ad-hoc 2.4GHz mode give ack so slow: 18us 397*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+2)*200)<<16) | 200 );//5GHz 398*2ee67178SXianjun Jiao 399*2ee67178SXianjun Jiao printk("%s hw_init err %d\n", xpu_compatible_str, err); 400*2ee67178SXianjun Jiao return(err); 401*2ee67178SXianjun Jiao } 402*2ee67178SXianjun Jiao 403*2ee67178SXianjun Jiao static int dev_probe(struct platform_device *pdev) 404*2ee67178SXianjun Jiao { 405*2ee67178SXianjun Jiao struct device_node *np = pdev->dev.of_node; 406*2ee67178SXianjun Jiao struct resource *io; 407*2ee67178SXianjun Jiao u32 test_us0, test_us1, test_us2; 408*2ee67178SXianjun Jiao int err=1; 409*2ee67178SXianjun Jiao 410*2ee67178SXianjun Jiao printk("\n"); 411*2ee67178SXianjun Jiao 412*2ee67178SXianjun Jiao if (np) { 413*2ee67178SXianjun Jiao const struct of_device_id *match; 414*2ee67178SXianjun Jiao 415*2ee67178SXianjun Jiao match = of_match_node(dev_of_ids, np); 416*2ee67178SXianjun Jiao if (match) { 417*2ee67178SXianjun Jiao printk("%s dev_probe match!\n", xpu_compatible_str); 418*2ee67178SXianjun Jiao err = 0; 419*2ee67178SXianjun Jiao } 420*2ee67178SXianjun Jiao } 421*2ee67178SXianjun Jiao 422*2ee67178SXianjun Jiao if (err) 423*2ee67178SXianjun Jiao return err; 424*2ee67178SXianjun Jiao 425*2ee67178SXianjun Jiao xpu_api->hw_init=hw_init; 426*2ee67178SXianjun Jiao 427*2ee67178SXianjun Jiao xpu_api->reg_read=reg_read; 428*2ee67178SXianjun Jiao xpu_api->reg_write=reg_write; 429*2ee67178SXianjun Jiao 430*2ee67178SXianjun Jiao xpu_api->XPU_REG_MULTI_RST_write=XPU_REG_MULTI_RST_write; 431*2ee67178SXianjun Jiao xpu_api->XPU_REG_MULTI_RST_read=XPU_REG_MULTI_RST_read; 432*2ee67178SXianjun Jiao xpu_api->XPU_REG_SRC_SEL_write=XPU_REG_SRC_SEL_write; 433*2ee67178SXianjun Jiao xpu_api->XPU_REG_SRC_SEL_read=XPU_REG_SRC_SEL_read; 434*2ee67178SXianjun Jiao 435*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write=XPU_REG_RECV_ACK_COUNT_TOP0_write; 436*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_read=XPU_REG_RECV_ACK_COUNT_TOP0_read; 437*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write=XPU_REG_RECV_ACK_COUNT_TOP1_write; 438*2ee67178SXianjun Jiao xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_read=XPU_REG_RECV_ACK_COUNT_TOP1_read; 439*2ee67178SXianjun Jiao xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write=XPU_REG_SEND_ACK_WAIT_TOP_write; 440*2ee67178SXianjun Jiao xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_read=XPU_REG_SEND_ACK_WAIT_TOP_read; 441*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAC_ADDR_LOW_write=XPU_REG_MAC_ADDR_LOW_write; 442*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAC_ADDR_LOW_read=XPU_REG_MAC_ADDR_LOW_read; 443*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAC_ADDR_HIGH_write=XPU_REG_MAC_ADDR_HIGH_write; 444*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAC_ADDR_HIGH_read=XPU_REG_MAC_ADDR_HIGH_read; 445*2ee67178SXianjun Jiao 446*2ee67178SXianjun Jiao xpu_api->XPU_REG_FILTER_FLAG_write=XPU_REG_FILTER_FLAG_write; 447*2ee67178SXianjun Jiao xpu_api->XPU_REG_FILTER_FLAG_read=XPU_REG_FILTER_FLAG_read; 448*2ee67178SXianjun Jiao xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write=XPU_REG_CTS_TO_RTS_CONFIG_write; 449*2ee67178SXianjun Jiao xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_read=XPU_REG_CTS_TO_RTS_CONFIG_read; 450*2ee67178SXianjun Jiao xpu_api->XPU_REG_BSSID_FILTER_LOW_write=XPU_REG_BSSID_FILTER_LOW_write; 451*2ee67178SXianjun Jiao xpu_api->XPU_REG_BSSID_FILTER_LOW_read=XPU_REG_BSSID_FILTER_LOW_read; 452*2ee67178SXianjun Jiao xpu_api->XPU_REG_BSSID_FILTER_HIGH_write=XPU_REG_BSSID_FILTER_HIGH_write; 453*2ee67178SXianjun Jiao xpu_api->XPU_REG_BSSID_FILTER_HIGH_read=XPU_REG_BSSID_FILTER_HIGH_read; 454*2ee67178SXianjun Jiao 455*2ee67178SXianjun Jiao xpu_api->XPU_REG_BAND_CHANNEL_write=XPU_REG_BAND_CHANNEL_write; 456*2ee67178SXianjun Jiao xpu_api->XPU_REG_BAND_CHANNEL_read=XPU_REG_BAND_CHANNEL_read; 457*2ee67178SXianjun Jiao 458*2ee67178SXianjun Jiao xpu_api->XPU_REG_TRX_STATUS_read=XPU_REG_TRX_STATUS_read; 459*2ee67178SXianjun Jiao xpu_api->XPU_REG_TX_RESULT_read=XPU_REG_TX_RESULT_read; 460*2ee67178SXianjun Jiao 461*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read=XPU_REG_TSF_RUNTIME_VAL_LOW_read; 462*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read=XPU_REG_TSF_RUNTIME_VAL_HIGH_read; 463*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_LOAD_VAL_LOW_write=XPU_REG_TSF_LOAD_VAL_LOW_write; 464*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_LOAD_VAL_HIGH_write=XPU_REG_TSF_LOAD_VAL_HIGH_write; 465*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_LOAD_VAL_write=XPU_REG_TSF_LOAD_VAL_write; 466*2ee67178SXianjun Jiao 467*2ee67178SXianjun Jiao xpu_api->XPU_REG_FC_DI_read=XPU_REG_FC_DI_read; 468*2ee67178SXianjun Jiao xpu_api->XPU_REG_ADDR1_LOW_read=XPU_REG_ADDR1_LOW_read; 469*2ee67178SXianjun Jiao xpu_api->XPU_REG_ADDR1_HIGH_read=XPU_REG_ADDR1_HIGH_read; 470*2ee67178SXianjun Jiao xpu_api->XPU_REG_ADDR2_LOW_read=XPU_REG_ADDR2_LOW_read; 471*2ee67178SXianjun Jiao xpu_api->XPU_REG_ADDR2_HIGH_read=XPU_REG_ADDR2_HIGH_read; 472*2ee67178SXianjun Jiao 473*2ee67178SXianjun Jiao xpu_api->XPU_REG_LBT_TH_write=XPU_REG_LBT_TH_write; 474*2ee67178SXianjun Jiao xpu_api->XPU_REG_LBT_TH_read=XPU_REG_LBT_TH_read; 475*2ee67178SXianjun Jiao 476*2ee67178SXianjun Jiao xpu_api->XPU_REG_RSSI_DB_CFG_read=XPU_REG_RSSI_DB_CFG_read; 477*2ee67178SXianjun Jiao xpu_api->XPU_REG_RSSI_DB_CFG_write=XPU_REG_RSSI_DB_CFG_write; 478*2ee67178SXianjun Jiao 479*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_DEBUG_write=XPU_REG_CSMA_DEBUG_write; 480*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_DEBUG_read=XPU_REG_CSMA_DEBUG_read; 481*2ee67178SXianjun Jiao 482*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write; 483*2ee67178SXianjun Jiao xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read; 484*2ee67178SXianjun Jiao 485*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_write=XPU_REG_SLICE_COUNT_TOTAL0_write; 486*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START0_write=XPU_REG_SLICE_COUNT_START0_write; 487*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END0_write=XPU_REG_SLICE_COUNT_END0_write; 488*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_write=XPU_REG_SLICE_COUNT_TOTAL1_write; 489*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START1_write=XPU_REG_SLICE_COUNT_START1_write; 490*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END1_write=XPU_REG_SLICE_COUNT_END1_write; 491*2ee67178SXianjun Jiao 492*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL0_read=XPU_REG_SLICE_COUNT_TOTAL0_read; 493*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START0_read=XPU_REG_SLICE_COUNT_START0_read; 494*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END0_read=XPU_REG_SLICE_COUNT_END0_read; 495*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_TOTAL1_read=XPU_REG_SLICE_COUNT_TOTAL1_read; 496*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_START1_read=XPU_REG_SLICE_COUNT_START1_read; 497*2ee67178SXianjun Jiao xpu_api->XPU_REG_SLICE_COUNT_END1_read=XPU_REG_SLICE_COUNT_END1_read; 498*2ee67178SXianjun Jiao 499*2ee67178SXianjun Jiao xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write; 500*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAX_NUM_RETRANS_write=XPU_REG_MAX_NUM_RETRANS_write; 501*2ee67178SXianjun Jiao 502*2ee67178SXianjun Jiao xpu_api->XPU_REG_MAC_ADDR_write=XPU_REG_MAC_ADDR_write; 503*2ee67178SXianjun Jiao 504*2ee67178SXianjun Jiao /* Request and map I/O memory */ 505*2ee67178SXianjun Jiao io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 506*2ee67178SXianjun Jiao base_addr = devm_ioremap_resource(&pdev->dev, io); 507*2ee67178SXianjun Jiao if (IS_ERR(base_addr)) 508*2ee67178SXianjun Jiao return PTR_ERR(base_addr); 509*2ee67178SXianjun Jiao 510*2ee67178SXianjun Jiao 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); 511*2ee67178SXianjun Jiao printk("%s dev_probe base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr); 512*2ee67178SXianjun Jiao printk("%s dev_probe xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst); 513*2ee67178SXianjun Jiao printk("%s dev_probe xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api); 514*2ee67178SXianjun Jiao 515*2ee67178SXianjun Jiao printk("%s dev_probe reset tsf timer\n", xpu_compatible_str); 516*2ee67178SXianjun Jiao xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0); 517*2ee67178SXianjun Jiao test_us0 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read(); 518*2ee67178SXianjun Jiao mdelay(33); 519*2ee67178SXianjun Jiao test_us1 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read(); 520*2ee67178SXianjun Jiao mdelay(67); 521*2ee67178SXianjun Jiao test_us2 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read(); 522*2ee67178SXianjun Jiao printk("%s dev_probe XPU_REG_TSF_RUNTIME_VAL_LOW_read %d %d %dus\n", xpu_compatible_str, test_us0, test_us1, test_us2); 523*2ee67178SXianjun Jiao 524*2ee67178SXianjun Jiao printk("%s dev_probe succeed!\n", xpu_compatible_str); 525*2ee67178SXianjun Jiao 526*2ee67178SXianjun Jiao err = hw_init(XPU_NORMAL); 527*2ee67178SXianjun Jiao 528*2ee67178SXianjun Jiao return err; 529*2ee67178SXianjun Jiao } 530*2ee67178SXianjun Jiao 531*2ee67178SXianjun Jiao static int dev_remove(struct platform_device *pdev) 532*2ee67178SXianjun Jiao { 533*2ee67178SXianjun Jiao printk("\n"); 534*2ee67178SXianjun Jiao 535*2ee67178SXianjun Jiao printk("%s dev_remove base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr); 536*2ee67178SXianjun Jiao printk("%s dev_remove xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst); 537*2ee67178SXianjun Jiao printk("%s dev_remove xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api); 538*2ee67178SXianjun Jiao 539*2ee67178SXianjun Jiao printk("%s dev_remove succeed!\n", xpu_compatible_str); 540*2ee67178SXianjun Jiao return 0; 541*2ee67178SXianjun Jiao } 542*2ee67178SXianjun Jiao 543*2ee67178SXianjun Jiao static struct platform_driver dev_driver = { 544*2ee67178SXianjun Jiao .driver = { 545*2ee67178SXianjun Jiao .name = "sdr,xpu", 546*2ee67178SXianjun Jiao .owner = THIS_MODULE, 547*2ee67178SXianjun Jiao .of_match_table = dev_of_ids, 548*2ee67178SXianjun Jiao }, 549*2ee67178SXianjun Jiao .probe = dev_probe, 550*2ee67178SXianjun Jiao .remove = dev_remove, 551*2ee67178SXianjun Jiao }; 552*2ee67178SXianjun Jiao 553*2ee67178SXianjun Jiao module_platform_driver(dev_driver); 554*2ee67178SXianjun Jiao 555*2ee67178SXianjun Jiao MODULE_AUTHOR("Xianjun Jiao"); 556*2ee67178SXianjun Jiao MODULE_DESCRIPTION("sdr,xpu"); 557*2ee67178SXianjun Jiao MODULE_LICENSE("GPL v2"); 558