mirror of
https://github.com/open-sdr/openwifi.git
synced 2025-04-12 13:17:59 +00:00
Driver changes for FPGA SPI Tx LO control
- Manually issue Tx Quadrature calibration if frequency change is more than 100MHz - Disable FPGA SPI module before calibration - Add xpu reg 13 to disable control manually
This commit is contained in:
parent
f6ba34deac
commit
bc98f5bb6c
@ -5178,7 +5178,7 @@ static int ad9361_setup(struct ad9361_rf_phy *phy)
|
||||
|
||||
}
|
||||
|
||||
static int ad9361_do_calib_run(struct ad9361_rf_phy *phy, u32 cal, int arg)
|
||||
int ad9361_do_calib_run(struct ad9361_rf_phy *phy, u32 cal, int arg)
|
||||
{
|
||||
struct ad9361_rf_phy_state *st = phy->state;
|
||||
int ret;
|
||||
@ -5211,6 +5211,7 @@ static int ad9361_do_calib_run(struct ad9361_rf_phy *phy, u32 cal, int arg)
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ad9361_do_calib_run);
|
||||
|
||||
static int ad9361_update_rf_bandwidth(struct ad9361_rf_phy *phy,
|
||||
u32 rf_rx_bw, u32 rf_tx_bw)
|
||||
|
@ -304,6 +304,7 @@ const char *xpu_compatible_str = "sdr,xpu";
|
||||
#define XPU_REG_BB_RF_DELAY_ADDR (10*4)
|
||||
#define XPU_REG_ACK_CTL_MAX_NUM_RETRANS_ADDR (11*4)
|
||||
#define XPU_REG_AMPDU_ACTION_ADDR (12*4)
|
||||
#define XPU_REG_SPI_DISABLE_ADDR (13*4)
|
||||
#define XPU_REG_RECV_ACK_COUNT_TOP0_ADDR (16*4)
|
||||
#define XPU_REG_RECV_ACK_COUNT_TOP1_ADDR (17*4)
|
||||
#define XPU_REG_SEND_ACK_WAIT_TOP_ADDR (18*4)
|
||||
@ -444,6 +445,9 @@ struct xpu_driver_api {
|
||||
void (*XPU_REG_ACK_CTL_MAX_NUM_RETRANS_write)(u32 value);
|
||||
u32 (*XPU_REG_ACK_CTL_MAX_NUM_RETRANS_read)(void);
|
||||
|
||||
void (*XPU_REG_SPI_DISABLE_write)(u32 value);
|
||||
u32 (*XPU_REG_SPI_DISABLE_read)(void);
|
||||
|
||||
void (*XPU_REG_AMPDU_ACTION_write)(u32 value);
|
||||
u32 (*XPU_REG_AMPDU_ACTION_read)(void);
|
||||
|
||||
|
28
driver/sdr.c
28
driver/sdr.c
@ -55,6 +55,7 @@ extern int ad9361_set_tx_atten(struct ad9361_rf_phy *phy, u32 atten_mdb,
|
||||
bool tx1, bool tx2, bool immed);
|
||||
extern int ad9361_ctrl_outs_setup(struct ad9361_rf_phy *phy,
|
||||
struct ctrl_outs_control *ctrl);
|
||||
extern int ad9361_do_calib_run(struct ad9361_rf_phy *phy, u32 cal, int arg);
|
||||
|
||||
#include "../user_space/sdrctl_src/nl80211_testmode_def.h"
|
||||
#include "hw_def.h"
|
||||
@ -175,11 +176,17 @@ static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct openwifi_priv *priv = dev->priv;
|
||||
u32 actual_rx_lo = conf->chandef.chan->center_freq - priv->rx_freq_offset_to_lo_MHz;
|
||||
u32 actual_tx_lo;
|
||||
u32 spi_disable;
|
||||
u32 diff_tx_lo;
|
||||
bool change_flag = (actual_rx_lo != priv->actual_rx_lo);
|
||||
int static_lbt_th, auto_lbt_th, fpga_lbt_th, receiver_rssi_dbm_th;
|
||||
struct timeval tv;
|
||||
unsigned long time_before = 0;
|
||||
unsigned long time_after = 0;
|
||||
|
||||
if (change_flag) {
|
||||
actual_tx_lo = conf->chandef.chan->center_freq - priv->tx_freq_offset_to_lo_MHz;
|
||||
diff_tx_lo = priv->last_tx_quad_cal_lo > actual_tx_lo ? priv->last_tx_quad_cal_lo - actual_tx_lo : actual_tx_lo - priv->last_tx_quad_cal_lo;
|
||||
|
||||
// -------------------Tx Lo tuning-------------------
|
||||
clk_set_rate(priv->ad9361_phy->clks[TX_RFPLL], ( ( ((u64)1000000ull)*((u64)actual_tx_lo ) + priv->rf_reg_val[RF_TX_REG_IDX_FO] )>>1) );
|
||||
@ -188,6 +195,20 @@ static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
|
||||
// -------------------Rx Lo tuning-------------------
|
||||
clk_set_rate(priv->ad9361_phy->clks[RX_RFPLL], ( ( ((u64)1000000ull)*((u64)actual_rx_lo ) + priv->rf_reg_val[RF_RX_REG_IDX_FO] )>>1) );
|
||||
priv->actual_rx_lo = actual_rx_lo;
|
||||
|
||||
// call Tx Quadrature calibration if frequency change is more than 100MHz
|
||||
if (diff_tx_lo > 100) {
|
||||
priv->last_tx_quad_cal_lo = actual_tx_lo;
|
||||
do_gettimeofday(&tv);
|
||||
time_before = tv.tv_usec + ((u64)1000000ull)*((u64)tv.tv_sec );
|
||||
spi_disable = xpu_api->XPU_REG_SPI_DISABLE_read(); // disable FPGA SPI module
|
||||
xpu_api->XPU_REG_SPI_DISABLE_write(1);
|
||||
ad9361_do_calib_run(priv->ad9361_phy, TX_QUAD_CAL, (int)priv->ad9361_phy->state->last_tx_quad_cal_phase);
|
||||
// restore original SPI disable state
|
||||
xpu_api->XPU_REG_SPI_DISABLE_write(spi_disable);
|
||||
do_gettimeofday(&tv);
|
||||
time_after = tv.tv_usec + ((u64)1000000ull)*((u64)tv.tv_sec );
|
||||
}
|
||||
|
||||
// get rssi correction value from lookup table
|
||||
priv->rssi_correction = rssi_correction_lookup_table(actual_rx_lo);
|
||||
@ -217,7 +238,7 @@ static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
|
||||
xpu_api->XPU_REG_BAND_CHANNEL_write( (priv->use_short_slot<<24)|(priv->band<<16) );
|
||||
}
|
||||
}
|
||||
printk("%s ad9361_rf_set_channel %dM rssi_correction %d (change flag %d) fpga_lbt_th %d(%ddBm) (auto %d static %d)\n", sdr_compatible_str,conf->chandef.chan->center_freq,priv->rssi_correction,change_flag,fpga_lbt_th,rssi_half_db_to_rssi_dbm(fpga_lbt_th, priv->rssi_correction),auto_lbt_th,static_lbt_th);
|
||||
printk("%s ad9361_rf_set_channel %dM rssi_correction %d (change flag %d) fpga_lbt_th %d(%ddBm) (auto %d static %d) tx_quad_cal duration %lu us\n", sdr_compatible_str,conf->chandef.chan->center_freq,priv->rssi_correction,change_flag,fpga_lbt_th,rssi_half_db_to_rssi_dbm(fpga_lbt_th, priv->rssi_correction),auto_lbt_th,static_lbt_th, time_after-time_before);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1297,6 +1318,10 @@ static void openwifi_stop(struct ieee80211_hw *dev)
|
||||
u32 reg, reg1;
|
||||
int i;
|
||||
|
||||
// enable ad9361 auto calibration and disable openwifi fpga spi control
|
||||
priv->ad9361_phy->state->auto_cal_en = true; // turn on auto Tx quadrature calib.
|
||||
priv->ad9361_phy->state->manual_tx_quad_cal_en = false; // turn off manual Tx quadrature calib.
|
||||
xpu_api->XPU_REG_SPI_DISABLE_write(1);
|
||||
|
||||
//turn off radio
|
||||
#if 1
|
||||
@ -1776,6 +1801,7 @@ static int openwifi_dev_probe(struct platform_device *pdev)
|
||||
// //-------------find ad9361-phy driver for lo/channel control---------------
|
||||
priv->actual_rx_lo = 1000; //Some value aligned with rf_init/rf_init_11n.sh that is not WiFi channel to force ad9361_rf_set_channel execution triggered by Linux
|
||||
priv->actual_tx_lo = 1000; //Some value aligned with rf_init/rf_init_11n.sh that is not WiFi channel to force ad9361_rf_set_channel execution triggered by Linux
|
||||
priv->last_tx_quad_cal_lo = 1000;
|
||||
tmp_dev = bus_find_device( &spi_bus_type, NULL, "ad9361-phy", custom_match_spi_dev );
|
||||
if (tmp_dev == NULL) {
|
||||
printk(KERN_ERR "%s find_dev ad9361-phy failed\n",sdr_compatible_str);
|
||||
|
@ -384,6 +384,7 @@ struct openwifi_priv {
|
||||
u32 rf_bw;
|
||||
u32 actual_rx_lo;
|
||||
u32 actual_tx_lo;
|
||||
u32 last_tx_quad_cal_lo;
|
||||
|
||||
struct ieee80211_rate rates_2GHz[12];
|
||||
struct ieee80211_rate rates_5GHz[12];
|
||||
|
@ -280,6 +280,14 @@ 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) ) );
|
||||
@ -359,8 +367,8 @@ static inline u32 hw_init(enum xpu_mode mode){
|
||||
|
||||
//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
|
||||
|
||||
// xpu_api->XPU_REG_BB_RF_DELAY_write((1<<8)|47);
|
||||
xpu_api->XPU_REG_BB_RF_DELAY_write((10<<8)|40); // extended rf is ongoing for perfect muting. (10<<8)|40 is verified good for zcu102/zed
|
||||
// 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
|
||||
@ -540,6 +548,9 @@ static int dev_probe(struct platform_device *pdev)
|
||||
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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user