mirror of
https://github.com/open-sdr/openwifi.git
synced 2024-12-19 21:58:13 +00:00
640 lines
23 KiB
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");
|