openwifi/driver/xpu/xpu.c

640 lines
23 KiB
C

/*
* axi lite register access driver
* Author: Xianjun Jiao, Michael Mehari, Wei Liu
* SPDX-FileCopyrightText: 2019 UGent
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <linux/bitops.h>
#include <linux/dmapool.h>
#include <linux/dma/xilinx_dma.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_dma.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/delay.h>
#include <net/mac80211.h>
#include "../hw_def.h"
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
/* IO accessors */
static inline u32 reg_read(u32 reg)
{
return ioread32(base_addr + reg);
}
static inline void reg_write(u32 reg, u32 value)
{
iowrite32(value, base_addr + reg);
}
static inline void XPU_REG_MULTI_RST_write(u32 Data) {
reg_write(XPU_REG_MULTI_RST_ADDR, Data);
}
static inline u32 XPU_REG_MULTI_RST_read(void){
return reg_read(XPU_REG_MULTI_RST_ADDR);
}
static inline void XPU_REG_SRC_SEL_write(u32 Data) {
reg_write(XPU_REG_SRC_SEL_ADDR, Data);
}
static inline u32 XPU_REG_SRC_SEL_read(void){
return reg_read(XPU_REG_SRC_SEL_ADDR);
}
static inline void XPU_REG_RECV_ACK_COUNT_TOP0_write(u32 Data) {
reg_write(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR, Data);
}
static inline u32 XPU_REG_RECV_ACK_COUNT_TOP0_read(void){
return reg_read(XPU_REG_RECV_ACK_COUNT_TOP0_ADDR);
}
static inline void XPU_REG_RECV_ACK_COUNT_TOP1_write(u32 Data) {
reg_write(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR, Data);
}
static inline u32 XPU_REG_RECV_ACK_COUNT_TOP1_read(void){
return reg_read(XPU_REG_RECV_ACK_COUNT_TOP1_ADDR);
}
static inline void XPU_REG_SEND_ACK_WAIT_TOP_write(u32 Data) {
reg_write(XPU_REG_SEND_ACK_WAIT_TOP_ADDR, Data);
}
static inline u32 XPU_REG_SEND_ACK_WAIT_TOP_read(void){
return reg_read(XPU_REG_SEND_ACK_WAIT_TOP_ADDR);
}
static inline void XPU_REG_FILTER_FLAG_write(u32 Data) {
reg_write(XPU_REG_FILTER_FLAG_ADDR, Data);
}
static inline u32 XPU_REG_FILTER_FLAG_read(void){
return reg_read(XPU_REG_FILTER_FLAG_ADDR);
}
static inline void XPU_REG_CTS_TO_RTS_CONFIG_write(u32 Data) {
reg_write(XPU_REG_CTS_TO_RTS_CONFIG_ADDR, Data);
}
static inline u32 XPU_REG_CTS_TO_RTS_CONFIG_read(void){
return reg_read(XPU_REG_CTS_TO_RTS_CONFIG_ADDR);
}
static inline void XPU_REG_MAC_ADDR_LOW_write(u32 Data) {
reg_write(XPU_REG_MAC_ADDR_LOW_ADDR, Data);
}
static inline u32 XPU_REG_MAC_ADDR_LOW_read(void){
return reg_read(XPU_REG_MAC_ADDR_LOW_ADDR);
}
static inline void XPU_REG_MAC_ADDR_HIGH_write(u32 Data) {
reg_write(XPU_REG_MAC_ADDR_HIGH_ADDR, Data);
}
static inline u32 XPU_REG_MAC_ADDR_HIGH_read(void){
return reg_read(XPU_REG_MAC_ADDR_HIGH_ADDR);
}
static inline void XPU_REG_BSSID_FILTER_LOW_write(u32 Data) {
reg_write(XPU_REG_BSSID_FILTER_LOW_ADDR, Data);
}
static inline u32 XPU_REG_BSSID_FILTER_LOW_read(void){
return reg_read(XPU_REG_BSSID_FILTER_LOW_ADDR);
}
static inline void XPU_REG_BSSID_FILTER_HIGH_write(u32 Data) {
reg_write(XPU_REG_BSSID_FILTER_HIGH_ADDR, Data);
}
static inline u32 XPU_REG_BSSID_FILTER_HIGH_read(void){
return reg_read(XPU_REG_BSSID_FILTER_HIGH_ADDR);
}
static inline void XPU_REG_BAND_CHANNEL_write(u32 Data) {
reg_write(XPU_REG_BAND_CHANNEL_ADDR, Data);
}
static inline u32 XPU_REG_BAND_CHANNEL_read(void){
return reg_read(XPU_REG_BAND_CHANNEL_ADDR);
}
static inline void XPU_REG_DIFS_ADVANCE_write(u32 Data) {
reg_write(XPU_REG_DIFS_ADVANCE_ADDR, Data);
}
static inline u32 XPU_REG_DIFS_ADVANCE_read(void){
return reg_read(XPU_REG_DIFS_ADVANCE_ADDR);
}
static inline void XPU_REG_FORCE_IDLE_MISC_write(u32 Data) {
reg_write(XPU_REG_FORCE_IDLE_MISC_ADDR, Data);
}
static inline u32 XPU_REG_FORCE_IDLE_MISC_read(void){
return reg_read(XPU_REG_FORCE_IDLE_MISC_ADDR);
}
static inline u32 XPU_REG_TRX_STATUS_read(void){
return reg_read(XPU_REG_TRX_STATUS_ADDR);
}
static inline u32 XPU_REG_TX_RESULT_read(void){
return reg_read(XPU_REG_TX_RESULT_ADDR);
}
static inline u32 XPU_REG_TSF_RUNTIME_VAL_LOW_read(void){
return reg_read(XPU_REG_TSF_RUNTIME_VAL_LOW_ADDR);
}
static inline u32 XPU_REG_TSF_RUNTIME_VAL_HIGH_read(void){
return reg_read(XPU_REG_TSF_RUNTIME_VAL_HIGH_ADDR);
}
static inline void XPU_REG_TSF_LOAD_VAL_LOW_write(u32 value){
reg_write(XPU_REG_TSF_LOAD_VAL_LOW_ADDR, value);
}
static inline void XPU_REG_TSF_LOAD_VAL_HIGH_write(u32 value){
reg_write(XPU_REG_TSF_LOAD_VAL_HIGH_ADDR, value);
}
static inline void XPU_REG_TSF_LOAD_VAL_write(u32 high_value, u32 low_value){
XPU_REG_TSF_LOAD_VAL_LOW_write(low_value);
XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value|0x80000000); // msb high
XPU_REG_TSF_LOAD_VAL_HIGH_write(high_value&(~0x80000000)); // msb low
}
static inline u32 XPU_REG_FC_DI_read(void){
return reg_read(XPU_REG_FC_DI_ADDR);
}
static inline u32 XPU_REG_ADDR1_LOW_read(void){
return reg_read(XPU_REG_ADDR1_LOW_ADDR);
}
static inline u32 XPU_REG_ADDR1_HIGH_read(void){
return reg_read(XPU_REG_ADDR1_HIGH_ADDR);
}
static inline u32 XPU_REG_ADDR2_LOW_read(void){
return reg_read(XPU_REG_ADDR2_LOW_ADDR);
}
static inline u32 XPU_REG_ADDR2_HIGH_read(void){
return reg_read(XPU_REG_ADDR2_HIGH_ADDR);
}
// static inline void XPU_REG_LBT_TH_write(u32 value, u32 en_flag) {
// if (en_flag) {
// reg_write(XPU_REG_LBT_TH_ADDR, value&0x7FFFFFFF);
// } else {
// reg_write(XPU_REG_LBT_TH_ADDR, value|0x80000000);
// }
// }
static inline void XPU_REG_LBT_TH_write(u32 value) {
reg_write(XPU_REG_LBT_TH_ADDR, value);
}
static inline u32 XPU_REG_RSSI_DB_CFG_read(void){
return reg_read(XPU_REG_RSSI_DB_CFG_ADDR);
}
static inline void XPU_REG_RSSI_DB_CFG_write(u32 Data) {
reg_write(XPU_REG_RSSI_DB_CFG_ADDR, Data);
}
static inline u32 XPU_REG_LBT_TH_read(void){
return reg_read(XPU_REG_LBT_TH_ADDR);
}
static inline void XPU_REG_CSMA_DEBUG_write(u32 value){
reg_write(XPU_REG_CSMA_DEBUG_ADDR, value);
}
static inline u32 XPU_REG_CSMA_DEBUG_read(void){
return reg_read(XPU_REG_CSMA_DEBUG_ADDR);
}
static inline void XPU_REG_CSMA_CFG_write(u32 value){
reg_write(XPU_REG_CSMA_CFG_ADDR, value);
}
static inline u32 XPU_REG_CSMA_CFG_read(void){
return reg_read(XPU_REG_CSMA_CFG_ADDR);
}
static inline void XPU_REG_SLICE_COUNT_TOTAL_write(u32 value){
reg_write(XPU_REG_SLICE_COUNT_TOTAL_ADDR, value);
}
static inline void XPU_REG_SLICE_COUNT_START_write(u32 value){
reg_write(XPU_REG_SLICE_COUNT_START_ADDR, value);
}
static inline void XPU_REG_SLICE_COUNT_END_write(u32 value){
reg_write(XPU_REG_SLICE_COUNT_END_ADDR, value);
}
static inline u32 XPU_REG_SLICE_COUNT_TOTAL_read(void){
return reg_read(XPU_REG_SLICE_COUNT_TOTAL_ADDR);
}
static inline u32 XPU_REG_SLICE_COUNT_START_read(void){
return reg_read(XPU_REG_SLICE_COUNT_START_ADDR);
}
static inline u32 XPU_REG_SLICE_COUNT_END_read(void){
return reg_read(XPU_REG_SLICE_COUNT_END_ADDR);
}
static inline void XPU_REG_BB_RF_DELAY_write(u32 value){
reg_write(XPU_REG_BB_RF_DELAY_ADDR, value);
}
static inline void XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write(u32 value){
reg_write(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR, value);
}
static inline u32 XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read(void){
return reg_read(XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR);
}
static inline void XPU_REG_AMPDU_ACTION_write(u32 Data) {
reg_write(XPU_REG_AMPDU_ACTION_ADDR, Data);
}
static inline u32 XPU_REG_AMPDU_ACTION_read(void){
return reg_read(XPU_REG_AMPDU_ACTION_ADDR);
}
static inline void XPU_REG_SPI_DISABLE_write(u32 Data) {
reg_write(XPU_REG_SPI_DISABLE_ADDR, Data);
}
static inline u32 XPU_REG_SPI_DISABLE_read(void){
return reg_read(XPU_REG_SPI_DISABLE_ADDR);
}
static inline void XPU_REG_MAC_ADDR_write(u8 *mac_addr) {//, u32 en_flag){
XPU_REG_MAC_ADDR_LOW_write( *( (u32*)(mac_addr) ) );
XPU_REG_MAC_ADDR_HIGH_write( *( (u16*)(mac_addr + 4) ) );
#if 0
if (en_flag) {
XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) | 0x80000000 ); // 0x80000000 by default we turn on mac addr filter
} else {
XPU_REG_MAC_ADDR_HIGH_write( (*( (u16*)(mac_addr + 4) )) & 0x7FFFFFFF );
}
#endif
}
static const struct of_device_id dev_of_ids[] = {
{ .compatible = "sdr,xpu", },
{}
};
MODULE_DEVICE_TABLE(of, dev_of_ids);
static struct xpu_driver_api xpu_driver_api_inst;
static struct xpu_driver_api *xpu_api = &xpu_driver_api_inst;
EXPORT_SYMBOL(xpu_api);
static inline u32 hw_init(enum xpu_mode mode){
int err=0, i, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay;
u32 filter_flag = 0;
printk("%s hw_init mode %d\n", xpu_compatible_str, mode);
//rst
for (i=0;i<8;i++)
xpu_api->XPU_REG_MULTI_RST_write(0);
for (i=0;i<32;i++)
xpu_api->XPU_REG_MULTI_RST_write(0xFFFFFFFF);
for (i=0;i<8;i++)
xpu_api->XPU_REG_MULTI_RST_write(0);
// http://www.studioreti.it/slide/802-11-Frame_E_C.pdf
// https://mrncciew.com/2014/10/14/cwap-802-11-phy-ppdu/
// https://mrncciew.com/2014/09/27/cwap-mac-header-frame-control/
// https://mrncciew.com/2014/10/25/cwap-mac-header-durationid/
// https://mrncciew.com/2014/11/01/cwap-mac-header-sequence-control/
// https://witestlab.poly.edu/blog/802-11-wireless-lan-2/
// phy_rx byte idx:
// 5(3 sig + 2 service), -- PHY
// 2 frame control, 2 duration/conn ID, --MAC PDU
// 6 receiver address, 6 destination address, 6 transmitter address
// 2 sequence control
// 6 source address
// reg_val = 5 + 0;
// xpu_api->XPU_REG_PHY_RX_PKT_READ_OFFSET_write(reg_val);
// printk("%s hw_init XPU_REG_PHY_RX_PKT_READ_OFFSET_write %d\n", xpu_compatible_str, reg_val);
// by default turn off filter, because all register are zeros
// let's filter out packet according to: enum ieee80211_filter_flags at: https://www.kernel.org/doc/html/v4.9/80211/mac80211.html
#if 0 // define in FPGA
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
FIF_FCSFAIL = 14b00000000000100, //not support
FIF_PLCPFAIL = 14b00000000001000, //not support
FIF_BCN_PRBRESP_PROMISC= 14b00000000010000,
FIF_CONTROL = 14b00000000100000,
FIF_OTHER_BSS = 14b00000001000000,
FIF_PSPOLL = 14b00000010000000,
FIF_PROBE_REQ = 14b00000100000000,
UNICAST_FOR_US = 14b00001000000000,
BROADCAST_ALL_ONE = 14b00010000000000,
BROADCAST_ALL_ZERO = 14b00100000000000,
MY_BEACON = 14b01000000000000,
MONITOR_ALL = 14b10000000000000;
#endif
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);
xpu_api->XPU_REG_FILTER_FLAG_write(filter_flag);
xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write(0xB<<16);//6M 1011:0xB
// after send data frame wait for ACK, this will be set in real time in function ad9361_rf_set_channel
// 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"!
// xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( 6*10 ); // +6 = 16us for 5GHz
//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
// 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
xpu_api->XPU_REG_BB_RF_DELAY_write((16<<24)|(0<<16)|(26<<8)|9); // calibrated by ila and spectrum analyzer (trigger mode)
// setup time schedule of 4 slices
// slice 0
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
// slice 1
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
// slice 2
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
// slice 3
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
// all slice sync rest
xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
xpu_api->XPU_REG_MULTI_RST_write(0<<7);
switch(mode)
{
case XPU_TEST:
printk("%s hw_init mode XPU_TEST\n", xpu_compatible_str);
break;
case XPU_NORMAL:
printk("%s hw_init mode XPU_NORMAL\n", xpu_compatible_str);
break;
default:
printk("%s hw_init mode %d is wrong!\n", xpu_compatible_str, mode);
err=1;
}
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
agc_gain_delay = 39; //samples
rssi_half_db_offset = 75<<1;
xpu_api->XPU_REG_RSSI_DB_CFG_write(0x80000000|((rssi_half_db_offset<<16)|agc_gain_delay) );
xpu_api->XPU_REG_RSSI_DB_CFG_write((~0x80000000)&((rssi_half_db_offset<<16)|agc_gain_delay) );
//rssi_half_db_th = 70<<1; // with splitter
rssi_half_db_th = 87<<1; // -62dBm
xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
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
//xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5));
xpu_api->XPU_REG_CSMA_DEBUG_write(0);
// xpu_api->XPU_REG_CSMA_CFG_write(268435459); // Linux will do config for each queue via openwifi_conf_tx
// xpu_api->XPU_REG_CSMA_CFG_write(0xe0000000); // Linux will do config for each queue via openwifi_conf_tx
xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((16+23)<<16)|(0+23) );
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)
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)
xpu_api->XPU_REG_DIFS_ADVANCE_write((OPENWIFI_MAX_SIGNAL_LEN_TH<<16)|2); //us. bit31~16 max pkt length threshold
// setup time schedule of 4 slices
// slice 0
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write(50000-1); // total 50ms
xpu_api->XPU_REG_SLICE_COUNT_START_write(0); //start 0ms
xpu_api->XPU_REG_SLICE_COUNT_END_write(50000-1); //end 50ms
// slice 1
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((1<<20)|(50000-1)); // total 50ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((1<<20)|(0)); //start 0ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(20000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((1<<20)|(50000-1)); //end 20ms
// slice 2
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((2<<20)|(50000-1)); // total 50ms
//xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(20000)); //start 20ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((2<<20)|(0)); //start 20ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(40000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((2<<20)|(50000-1)); //end 20ms
// slice 3
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write((3<<20)|(50000-1)); // total 50ms
//xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(40000)); //start 40ms
xpu_api->XPU_REG_SLICE_COUNT_START_write((3<<20)|(0)); //start 40ms
//xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
xpu_api->XPU_REG_SLICE_COUNT_END_write((3<<20)|(50000-1)); //end 20ms
// all slice sync rest
xpu_api->XPU_REG_MULTI_RST_write(1<<7); //bit7 reset the counter for all queues at the same time
xpu_api->XPU_REG_MULTI_RST_write(0<<7);
printk("%s hw_init err %d\n", xpu_compatible_str, err);
return(err);
}
static int dev_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct resource *io;
u32 test_us0, test_us1, test_us2;
int err=1;
printk("\n");
if (np) {
const struct of_device_id *match;
match = of_match_node(dev_of_ids, np);
if (match) {
printk("%s dev_probe match!\n", xpu_compatible_str);
err = 0;
}
}
if (err)
return err;
xpu_api->hw_init=hw_init;
xpu_api->reg_read=reg_read;
xpu_api->reg_write=reg_write;
xpu_api->XPU_REG_MULTI_RST_write=XPU_REG_MULTI_RST_write;
xpu_api->XPU_REG_MULTI_RST_read=XPU_REG_MULTI_RST_read;
xpu_api->XPU_REG_SRC_SEL_write=XPU_REG_SRC_SEL_write;
xpu_api->XPU_REG_SRC_SEL_read=XPU_REG_SRC_SEL_read;
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write=XPU_REG_RECV_ACK_COUNT_TOP0_write;
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_read=XPU_REG_RECV_ACK_COUNT_TOP0_read;
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write=XPU_REG_RECV_ACK_COUNT_TOP1_write;
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_read=XPU_REG_RECV_ACK_COUNT_TOP1_read;
xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write=XPU_REG_SEND_ACK_WAIT_TOP_write;
xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_read=XPU_REG_SEND_ACK_WAIT_TOP_read;
xpu_api->XPU_REG_MAC_ADDR_LOW_write=XPU_REG_MAC_ADDR_LOW_write;
xpu_api->XPU_REG_MAC_ADDR_LOW_read=XPU_REG_MAC_ADDR_LOW_read;
xpu_api->XPU_REG_MAC_ADDR_HIGH_write=XPU_REG_MAC_ADDR_HIGH_write;
xpu_api->XPU_REG_MAC_ADDR_HIGH_read=XPU_REG_MAC_ADDR_HIGH_read;
xpu_api->XPU_REG_FILTER_FLAG_write=XPU_REG_FILTER_FLAG_write;
xpu_api->XPU_REG_FILTER_FLAG_read=XPU_REG_FILTER_FLAG_read;
xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_write=XPU_REG_CTS_TO_RTS_CONFIG_write;
xpu_api->XPU_REG_CTS_TO_RTS_CONFIG_read=XPU_REG_CTS_TO_RTS_CONFIG_read;
xpu_api->XPU_REG_BSSID_FILTER_LOW_write=XPU_REG_BSSID_FILTER_LOW_write;
xpu_api->XPU_REG_BSSID_FILTER_LOW_read=XPU_REG_BSSID_FILTER_LOW_read;
xpu_api->XPU_REG_BSSID_FILTER_HIGH_write=XPU_REG_BSSID_FILTER_HIGH_write;
xpu_api->XPU_REG_BSSID_FILTER_HIGH_read=XPU_REG_BSSID_FILTER_HIGH_read;
xpu_api->XPU_REG_BAND_CHANNEL_write=XPU_REG_BAND_CHANNEL_write;
xpu_api->XPU_REG_BAND_CHANNEL_read=XPU_REG_BAND_CHANNEL_read;
xpu_api->XPU_REG_DIFS_ADVANCE_write=XPU_REG_DIFS_ADVANCE_write;
xpu_api->XPU_REG_DIFS_ADVANCE_read=XPU_REG_DIFS_ADVANCE_read;
xpu_api->XPU_REG_FORCE_IDLE_MISC_write=XPU_REG_FORCE_IDLE_MISC_write;
xpu_api->XPU_REG_FORCE_IDLE_MISC_read=XPU_REG_FORCE_IDLE_MISC_read;
xpu_api->XPU_REG_TRX_STATUS_read=XPU_REG_TRX_STATUS_read;
xpu_api->XPU_REG_TX_RESULT_read=XPU_REG_TX_RESULT_read;
xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read=XPU_REG_TSF_RUNTIME_VAL_LOW_read;
xpu_api->XPU_REG_TSF_RUNTIME_VAL_HIGH_read=XPU_REG_TSF_RUNTIME_VAL_HIGH_read;
xpu_api->XPU_REG_TSF_LOAD_VAL_LOW_write=XPU_REG_TSF_LOAD_VAL_LOW_write;
xpu_api->XPU_REG_TSF_LOAD_VAL_HIGH_write=XPU_REG_TSF_LOAD_VAL_HIGH_write;
xpu_api->XPU_REG_TSF_LOAD_VAL_write=XPU_REG_TSF_LOAD_VAL_write;
xpu_api->XPU_REG_FC_DI_read=XPU_REG_FC_DI_read;
xpu_api->XPU_REG_ADDR1_LOW_read=XPU_REG_ADDR1_LOW_read;
xpu_api->XPU_REG_ADDR1_HIGH_read=XPU_REG_ADDR1_HIGH_read;
xpu_api->XPU_REG_ADDR2_LOW_read=XPU_REG_ADDR2_LOW_read;
xpu_api->XPU_REG_ADDR2_HIGH_read=XPU_REG_ADDR2_HIGH_read;
xpu_api->XPU_REG_LBT_TH_write=XPU_REG_LBT_TH_write;
xpu_api->XPU_REG_LBT_TH_read=XPU_REG_LBT_TH_read;
xpu_api->XPU_REG_RSSI_DB_CFG_read=XPU_REG_RSSI_DB_CFG_read;
xpu_api->XPU_REG_RSSI_DB_CFG_write=XPU_REG_RSSI_DB_CFG_write;
xpu_api->XPU_REG_CSMA_DEBUG_write=XPU_REG_CSMA_DEBUG_write;
xpu_api->XPU_REG_CSMA_DEBUG_read=XPU_REG_CSMA_DEBUG_read;
xpu_api->XPU_REG_CSMA_CFG_write=XPU_REG_CSMA_CFG_write;
xpu_api->XPU_REG_CSMA_CFG_read=XPU_REG_CSMA_CFG_read;
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_write=XPU_REG_SLICE_COUNT_TOTAL_write;
xpu_api->XPU_REG_SLICE_COUNT_START_write=XPU_REG_SLICE_COUNT_START_write;
xpu_api->XPU_REG_SLICE_COUNT_END_write=XPU_REG_SLICE_COUNT_END_write;
xpu_api->XPU_REG_SLICE_COUNT_TOTAL_read=XPU_REG_SLICE_COUNT_TOTAL_read;
xpu_api->XPU_REG_SLICE_COUNT_START_read=XPU_REG_SLICE_COUNT_START_read;
xpu_api->XPU_REG_SLICE_COUNT_END_read=XPU_REG_SLICE_COUNT_END_read;
xpu_api->XPU_REG_BB_RF_DELAY_write=XPU_REG_BB_RF_DELAY_write;
xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write;
xpu_api->XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read=XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read;
xpu_api->XPU_REG_AMPDU_ACTION_write=XPU_REG_AMPDU_ACTION_write;
xpu_api->XPU_REG_AMPDU_ACTION_read=XPU_REG_AMPDU_ACTION_read;
xpu_api->XPU_REG_SPI_DISABLE_write=XPU_REG_SPI_DISABLE_write;
xpu_api->XPU_REG_SPI_DISABLE_read=XPU_REG_SPI_DISABLE_read;
xpu_api->XPU_REG_MAC_ADDR_write=XPU_REG_MAC_ADDR_write;
/* Request and map I/O memory */
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base_addr = devm_ioremap_resource(&pdev->dev, io);
if (IS_ERR(base_addr))
return PTR_ERR(base_addr);
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);
printk("%s dev_probe base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
printk("%s dev_probe xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
printk("%s dev_probe xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
printk("%s dev_probe reset tsf timer\n", xpu_compatible_str);
xpu_api->XPU_REG_TSF_LOAD_VAL_write(0,0);
test_us0 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
mdelay(33);
test_us1 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
mdelay(67);
test_us2 = xpu_api->XPU_REG_TSF_RUNTIME_VAL_LOW_read();
printk("%s dev_probe XPU_REG_TSF_RUNTIME_VAL_LOW_read %d %d %dus\n", xpu_compatible_str, test_us0, test_us1, test_us2);
printk("%s dev_probe succeed!\n", xpu_compatible_str);
err = hw_init(XPU_NORMAL);
return err;
}
static int dev_remove(struct platform_device *pdev)
{
printk("\n");
printk("%s dev_remove base_addr 0x%08x\n", xpu_compatible_str,(u32)base_addr);
printk("%s dev_remove xpu_driver_api_inst 0x%08x\n", xpu_compatible_str, (u32)&xpu_driver_api_inst);
printk("%s dev_remove xpu_api 0x%08x\n", xpu_compatible_str, (u32)xpu_api);
printk("%s dev_remove succeed!\n", xpu_compatible_str);
return 0;
}
static struct platform_driver dev_driver = {
.driver = {
.name = "sdr,xpu",
.owner = THIS_MODULE,
.of_match_table = dev_of_ids,
},
.probe = dev_probe,
.remove = dev_remove,
};
module_platform_driver(dev_driver);
MODULE_AUTHOR("Xianjun Jiao");
MODULE_DESCRIPTION("sdr,xpu");
MODULE_LICENSE("GPL v2");