reduce some of ath9k_htc performance problems
v2 cover reduce some of ath9k_htc performance problems
This patchset adds new WMI_RMW handler to reduce some of usb related performance problems.
Oleksij Rempel (18):
ath9k_htc: add new WMI_REG_RMW_CMDID command
ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
ath9k: ar9271_hw_pa_cal: use proper makroses.
ath9k: ar9271_hw_pa_cal: use RMW buffer
ath9k: add multi_read to be compatible with ath9k_htc
ath9k: add new function ath9k_hw_read_array
ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
ath9k: use one shot read in ath9k_hw_update_mibstats
ath9k: ath9k_hw_loadnf: use REG_RMW
ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
ath9k: use rmw buffer in ath9k_hw_set_operating_mode and
ath9k_hw_reset
ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
drivers/net/wireless/ath/ath.h | 3 + drivers/net/wireless/ath/ath9k/ani.c | 20 +++- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 +- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 77 +++++++------- drivers/net/wireless/ath/ath9k/calib.c | 19 ++-- drivers/net/wireless/ath/ath9k/eeprom.c | 7 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 36 ++++--- drivers/net/wireless/ath/ath9k/eeprom_def.c | 34 +++--- drivers/net/wireless/ath/ath9k/htc.h | 5 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/hw.c | 24 +++++ drivers/net/wireless/ath/ath9k/hw.h | 15 +++ drivers/net/wireless/ath/ath9k/init.c | 11 ++ drivers/net/wireless/ath/ath9k/wmi.c | 3 + drivers/net/wireless/ath/ath9k/wmi.h | 16 +++ 15 files changed, 314 insertions(+), 103 deletions(-)
Signature · 1 line
1.9.1
PATCH v2 1/18 ath9k_htc: add new WMI_REG_RMW_CMDID command
Since usb bus add extra delay on each request, a command with read + write requests is too expensive. We can dramtically reduce usb load by moving this command to firmware.
In my tests, this patch will reduce channel scan time for about 5-10 seconds.
--- drivers/net/wireless/ath/ath.h | 3 + drivers/net/wireless/ath/ath9k/htc.h | 5 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/hw.h | 12 +++ drivers/net/wireless/ath/ath9k/wmi.c | 3 + drivers/net/wireless/ath/ath9k/wmi.h | 16 +++ 6 files changed, 175 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath.h +3 -0
@@ -131,6 +131,9 @@ struct ath_ops {void (*enable_write_buffer)(void *);void (*write_flush) (void *);u32 (*rmw)(void *,u32 reg_offset,u32 set,u32 clr); +void (*enable_rmw_buffer)(void *); +void (*rmw_flush) (void *); + };struct ath_common ;
drivers/net/wireless/ath/ath9k/htc.h +5 -0
@@ -444,6 +444,10 @@ static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)#define OP_BT_SCAN BIT(4)#define OP_TSF_RESET BIT(6) +enum htc_op_flags { +HTC_FWFLAG_NO_RMW , +}; +struct ath9k_htc_priv {struct device *dev;struct ieee80211_hw *hw;
@@ -482,6 +486,7 @@ struct ath9k_htc_priv {bool reconfig_beacon;unsigned int rxfilter;unsigned long op_flags; +unsigned long fw_flags;struct ath9k_hw_cal_data caldata;struct ath_spec_scan_priv spec_priv;
drivers/net/wireless/ath/ath9k/htc_drv_init.c +136 -6
165 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/hw.h +12 -0
@@ -100,6 +100,18 @@ (_ah)->reg_ops.write_flush ((_ah)); \ } while (0) +#define ENABLE_REG_RMW_BUFFER (_ah) \ + do { \ + if ((_ah)->reg_ops.enable_rmw_buffer) \ + (_ah)->reg_ops.enable_rmw_buffer((_ah)); \ + } while (0) + +#define REG_RMW_BUFFER_FLUSH (_ah) \ + do { \ + if ((_ah)->reg_ops.rmw_flush) \ + (_ah)->reg_ops.rmw_flush((_ah)); \ + } while (0) +#define PR_EEP (_s, _val) \ do { \ len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
drivers/net/wireless/ath/ath9k/wmi.c +3 -0
@@ -61,6 +61,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)return "WMI_REG_READ_CMDID" ;case WMI_REG_WRITE_CMDID :return "WMI_REG_WRITE_CMDID" ; +case WMI_REG_RMW_CMDID : +return "WMI_REG_RMW_CMDID" ;case WMI_RC_STATE_CHANGE_CMDID :return "WMI_RC_STATE_CHANGE_CMDID" ;case WMI_RC_RATE_UPDATE_CMDID :
@@ -101,6 +103,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)spin_lock_init (&wmi->event_lock);mutex_init (&wmi->op_mutex);mutex_init (&wmi->multi_write_mutex); +mutex_init (&wmi->multi_rmw_mutex);init_completion (&wmi->cmd_wait);INIT_LIST_HEAD (&wmi->pending_tx_events); tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
drivers/net/wireless/ath/ath9k/wmi.h +16 -0
@@ -112,6 +112,7 @@ enum wmi_cmd_id {WMI_TX_STATS_CMDID ,WMI_RX_STATS_CMDID ,WMI_BITRATE_MASK_CMDID , + WMI_REG_RMW_CMDID, }; enum wmi_event_id {
@@ -125,12 +126,19 @@ enum wmi_event_id { };#define MAX_CMD_NUMBER 62 +#define MAX_RMW_CMD_NUMBER 15struct register_write {__be32 reg;__be32 val; }; +struct register_rmw { +__be32 reg; +__be32 set; +__be32 clr; +} __packed; +struct ath9k_htc_tx_event {int count;struct __wmi_event_txstatus txs;
@@ -156,10 +164,18 @@ struct wmi {spinlock_t wmi_lock; +/* multi write section */ atomic_t mwrite_cnt;struct register_write multi_write[MAX_CMD_NUMBER ];u32 multi_write_idx;struct mutex multi_write_mutex; + +/* multi rmw section */ +atomic_t m_rmw_cnt; +struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER ]; +u32 multi_rmw_idx; +struct mutex multi_rmw_mutex; + };struct wmi *ath9k_init_wmi (struct ath9k_htc_priv *priv);
Signature · 1 line
1.9.1
PATCH v2 2/18 ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
In reply to Oleksij RempelThis function uses mixed styles for register names/numbers which is make harder reading and optimisation.
--- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-)
drivers/net/wireless/ath/ath9k/ar9002_calib.c +18 -17
@@ -430,22 +430,22 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)u32 regVal;unsigned int i;u32 regList[][2 ] = { - {0x786c ,0 }, - {0x7854 ,0 }, - {0x7820 ,0 }, - {0x7824 ,0 }, - {0x7868 ,0 }, - {0x783c ,0 }, - {0x7838 ,0 } , - {0x7828 ,0 } , + {AR9285_AN_TOP3 ,0 }, + {AR9285_AN_RXTXBB1 ,0 }, + {AR9285_AN_RF2G1 ,0 }, + {AR9285_AN_RF2G2 ,0 }, + {AR9285_AN_TOP2 ,0 }, + {AR9285_AN_RF2G8 ,0 }, + {AR9285_AN_RF2G7 ,0 } , + {AR9285_AN_RF2G3 ,0 } , };for (i =0 ; i <ARRAY_SIZE (regList); i++) regList[i][1 ] =REG_READ (ah, regList[i][0 ]); - regVal =REG_READ (ah,0x7834 ); + regVal =REG_READ (ah,AR9285_AN_RF2G6 ); regVal &= (~(0x1 )); -REG_WRITE (ah,0x7834 , regVal); +REG_WRITE (ah,AR9285_AN_RF2G6 , regVal); regVal =REG_READ (ah,0x9808 ); regVal |= (0x1 <<27 );REG_WRITE (ah,0x9808 , regVal);
@@ -477,7 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)* does not matter since we turn it off */ REG_RMW_FIELD (ah,AR9285_AN_RF2G7 ,AR9285_AN_RF2G7_PADRVGN2TAB0 ,0 ); - +/* 7828, b0-11, ccom=fff */ REG_RMW_FIELD (ah,AR9285_AN_RF2G3 ,AR9271_AN_RF2G3_CCOMP ,0xfff );/* Set:
@@ -490,15 +490,16 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)/* find off_6_1; */ for (i =6 ; i >0 ; i--) { - regVal =REG_READ (ah,0x7834 ); + regVal =REG_READ (ah,AR9285_AN_RF2G6 ); regVal |= (1 << (20 + i)); -REG_WRITE (ah,0x7834 , regVal); +REG_WRITE (ah,AR9285_AN_RF2G6 , regVal);udelay (1 );/* regVal = REG_READ(ah, 0x7834); */ regVal &= (~(0x1 << (20 + i))); - regVal |= (MS (REG_READ (ah,0x7840 ),AR9285_AN_RXTXBB1_SPARE9 ) + regVal |= (MS (REG_READ (ah,AR9285_AN_RF2G9 ), +AR9285_AN_RXTXBB1_SPARE9 ) << (20 + i)); -REG_WRITE (ah,0x7834 , regVal); +REG_WRITE (ah,AR9285_AN_RF2G6 , regVal); } regVal = (regVal >>20 ) &0x7f ;
@@ -517,9 +518,9 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)ENABLE_REGWRITE_BUFFER (ah); - regVal =REG_READ (ah,0x7834 ); + regVal =REG_READ (ah,AR_AN_RF2G1_CH1 ); regVal |=0x1 ; -REG_WRITE (ah,0x7834 , regVal); +REG_WRITE (ah,AR_AN_RF2G1_CH1 , regVal); regVal =REG_READ (ah,0x9808 ); regVal &= (~(0x1 <<27 ));REG_WRITE (ah,0x9808 , regVal);
Signature · 1 line
1.9.1
PATCH v2 3/18 ath9k: ar9271_hw_pa_cal: use proper makroses.
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 43 ++++++++++++--------------- 1 file changed, 19 insertions(+), 24 deletions(-)
drivers/net/wireless/ath/ath9k/ar9002_calib.c +19 -24
@@ -443,33 +443,30 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)for (i =0 ; i <ARRAY_SIZE (regList); i++) regList[i][1 ] =REG_READ (ah, regList[i][0 ]); - regVal =REG_READ (ah,AR9285_AN_RF2G6 ); - regVal &= (~(0x1 )); -REG_WRITE (ah,AR9285_AN_RF2G6 , regVal); - regVal =REG_READ (ah,0x9808 ); - regVal |= (0x1 <<27 ); -REG_WRITE (ah,0x9808 , regVal); - +/* 7834, b1=0 */ +REG_CLR_BIT (ah,AR9285_AN_RF2G6 ,1 <<0 ); +/* 9808, b27=1 */ +REG_SET_BIT (ah,0x9808 ,1 <<27 );/* 786c,b23,1, pwddac=1 */ -REG_RMW_FIELD (ah,AR9285_AN_TOP3 ,AR9285_AN_TOP3_PWDDAC ,1 ); +REG_SET_BIT (ah,AR9285_AN_TOP3 ,AR9285_AN_TOP3_PWDDAC );/* 7854, b5,1, pdrxtxbb=1 */ -REG_RMW_FIELD (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDRXTXBB1 ,1 ); +REG_SET_BIT (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDRXTXBB1 );/* 7854, b7,1, pdv2i=1 */ -REG_RMW_FIELD (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDV2I ,1 ); +REG_SET_BIT (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDV2I );/* 7854, b8,1, pddacinterface=1 */ -REG_RMW_FIELD (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDDACIF ,1 ); +REG_SET_BIT (ah,AR9285_AN_RXTXBB1 ,AR9285_AN_RXTXBB1_PDDACIF );/* 7824,b12,0, offcal=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G2 ,AR9285_AN_RF2G2_OFFCAL ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G2 ,AR9285_AN_RF2G2_OFFCAL );/* 7838, b1,0, pwddb=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G7 ,AR9285_AN_RF2G7_PWDDB ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G7 ,AR9285_AN_RF2G7_PWDDB );/* 7820,b11,0, enpacal=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_ENPACAL ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_ENPACAL );/* 7820,b25,1, pdpadrv1=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPADRV1 ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPADRV1 );/* 7820,b24,0, pdpadrv2=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPADRV2 ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPADRV2 );/* 7820,b23,0, pdpaout=0 */ -REG_RMW_FIELD (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPAOUT ,0 ); +REG_CLR_BIT (ah,AR9285_AN_RF2G1 ,AR9285_AN_RF2G1_PDPAOUT );/* 783c,b14-16,7, padrvgn2tab_0=7 */ REG_RMW_FIELD (ah,AR9285_AN_RF2G8 ,AR9285_AN_RF2G8_PADRVGN2TAB0 ,7 );/*
@@ -516,15 +513,13 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) ah->pacal_info.prev_offset = regVal; } -ENABLE_REGWRITE_BUFFER (ah); - regVal =REG_READ (ah,AR_AN_RF2G1_CH1 ); - regVal |=0x1 ; -REG_WRITE (ah,AR_AN_RF2G1_CH1 , regVal); - regVal =REG_READ (ah,0x9808 ); - regVal &= (~(0x1 <<27 )); -REG_WRITE (ah,0x9808 , regVal); +/* 7834, b1=1 */ +REG_SET_BIT (ah,AR9285_AN_RF2G6 ,1 <<0 ); +/* 9808, b27=0 */ +REG_CLR_BIT (ah,0x9808 ,1 <<27 ); +ENABLE_REGWRITE_BUFFER (ah);for (i =0 ; i <ARRAY_SIZE (regList); i++)REG_WRITE (ah, regList[i][0 ], regList[i][1 ]);
Signature · 1 line
1.9.1
PATCH v2 4/18 ath9k: ar9271_hw_pa_cal: use RMW buffer
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9002_calib.c +6 -2
@@ -436,13 +436,14 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) { AR9285_AN_RF2G2, 0 }, { AR9285_AN_TOP2, 0 }, { AR9285_AN_RF2G8, 0 }, - { AR9285_AN_RF2G7, 0 } , - { AR9285_AN_RF2G3, 0 } , + { AR9285_AN_RF2G7, 0 }, + { AR9285_AN_RF2G3, 0 }, };for (i =0 ; i <ARRAY_SIZE (regList); i++) regList[i][1 ] =REG_READ (ah, regList[i][0 ]); +ENABLE_REG_RMW_BUFFER (ah);/* 7834, b1=0 */ REG_CLR_BIT (ah,AR9285_AN_RF2G6 ,1 <<0 );/* 9808, b27=1 */
@@ -476,6 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)REG_RMW_FIELD (ah,AR9285_AN_RF2G7 ,AR9285_AN_RF2G7_PADRVGN2TAB0 ,0 );/* 7828, b0-11, ccom=fff */ REG_RMW_FIELD (ah,AR9285_AN_RF2G3 ,AR9271_AN_RF2G3_CCOMP ,0xfff ); +REG_RMW_BUFFER_FLUSH (ah);/* Set: * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
@@ -514,10 +516,12 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) } +ENABLE_REG_RMW_BUFFER (ah);/* 7834, b1=1 */ REG_SET_BIT (ah,AR9285_AN_RF2G6 ,1 <<0 );/* 9808, b27=0 */ REG_CLR_BIT (ah,0x9808 ,1 <<27 ); +REG_RMW_BUFFER_FLUSH (ah);ENABLE_REGWRITE_BUFFER (ah);for (i =0 ; i <ARRAY_SIZE (regList); i++)
Signature · 1 line
1.9.1
PATCH v2 5/18 ath9k: add multi_read to be compatible with ath9k_htc
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/init.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/net/wireless/ath/ath9k/init.c +11 -0
@@ -141,6 +141,16 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)return val; } +static void ath9k_multi_ioread32 (void *hw_priv,u32 *addr, +u32 *val,u16 count) +{ +int i; + +for (i =0 ; i < count; i++) + val[i] =ath9k_ioread32 (hw_priv, addr[i]); +} + +static unsigned int __ath9k_reg_rmw (struct ath_softc *sc,u32 reg_offset,u32 set,u32 clr) {
@@ -530,6 +540,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ah->hw = sc->hw; ah->hw_version.devid = devid; ah->reg_ops.read = ath9k_ioread32; + ah->reg_ops.multi_read = ath9k_multi_ioread32; ah->reg_ops.write = ath9k_iowrite32; ah->reg_ops.rmw = ath9k_reg_rmw; pCap = &ah->caps;
Signature · 1 line
1.9.1
PATCH v2 6/18 ath9k: add new function ath9k_hw_read_array
In reply to Oleksij RempelREG_READ generate most overhead on usb bus. It send and read micro packages and reduce usb bandwidth. To reduce this overhead we should read in batches.
--- drivers/net/wireless/ath/ath9k/hw.c | 20 ++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 3 +++ 2 files changed, 23 insertions(+)
drivers/net/wireless/ath/ath9k/hw.c +20 -0
@@ -121,6 +121,26 @@ void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,REGWRITE_BUFFER_FLUSH (ah); } +void ath9k_hw_read_array (struct ath_hw *ah,u32 array[][2 ],int size) +{ +u32 *tmp_reg_list, *tmp_data; +int i; + + tmp_reg_list =kmalloc (size *sizeof (u32),GFP_KERNEL ); + tmp_data =kmalloc (size *sizeof (u32),GFP_KERNEL ); + +for (i =0 ; i < size; i++) + tmp_reg_list[i] = array[i][0 ]; + +REG_READ_MULTI (ah, tmp_reg_list, tmp_data, size); + +for (i =0 ; i < size; i++) + array[i][1 ] = tmp_data[i]; + +kfree (tmp_reg_list); +kfree (tmp_data); +} +u32 ath9k_hw_reverse_bits (u32 val,u32 n) {u32 retval;
drivers/net/wireless/ath/ath9k/hw.h +3 -0
@@ -138,6 +138,8 @@#define REG_WRITE_ARRAY (iniarray, column, regWr) \ ath9k_hw_write_array(ah, iniarray, column, &(regWr)) +#define REG_READ_ARRAY (ah, array, size) \ + ath9k_hw_read_array(ah, array, size)#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -1020,6 +1022,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,bool ath9k_hw_wait (struct ath_hw *ah,u32 reg,u32 mask,u32 val,u32 timeout);void ath9k_hw_write_array (struct ath_hw *ah,const struct ar5416IniArray *array,int column,unsigned int *writecnt); +void ath9k_hw_read_array (struct ath_hw *ah,u32 array[][2 ],int size);u32 ath9k_hw_reverse_bits (u32 val,u32 n); u16 ath9k_hw_computetxtime(struct ath_hw *ah, u8 phy, int kbps,
Signature · 1 line
1.9.1
PATCH v2 6/18 ath9k: add new function ath9k_hw_read_array
Quoted 14 lines · Oleksij Rempel
REG_READgenerate most overhead on usb bus. It send and read micro packages and reduce usb bandwidth. To reduce this overhead we should read in batches.Signed-off-by Oleksij Rempel <[email protected]>--- drivers/net/wireless/ath/ath9k/hw.c | 20 ++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 3 +++ 2 files changed, 23 insertions(+)drivers/net/wireless/ath/ath9k/hw.c +0
-0
drivers/net/wireless/ath/ath9k/hw.c void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, · line 130
Quoted 10 lines
drivers/net/wireless/ath/ath9k/hw.c +7
-0@@ -121,6 +121,26 @@ void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,REGWRITE_BUFFER_FLUSH (ah); } +void ath9k_hw_read_array (struct ath_hw *ah,u32 array[][2 ],int size) +{ +u32 *tmp_reg_list, *tmp_data; +int i; + + tmp_reg_list =kmalloc (size *sizeof (u32),GFP_KERNEL ); + tmp_data =kmalloc (size *sizeof (u32),GFP_KERNEL );
You probably want to check for kmalloc returning NULL here.
Quoted 31 lines
drivers/net/wireless/ath/ath9k/hw.c +13
-0+ +for (i =0 ; i < size; i++) + tmp_reg_list[i] = array[i][0 ]; + +REG_READ_MULTI (ah, tmp_reg_list, tmp_data, size); + +for (i =0 ; i < size; i++) + array[i][1 ] = tmp_data[i]; + +kfree (tmp_reg_list); +kfree (tmp_data); +} +u32 ath9k_hw_reverse_bits (u32 val,u32 n) {u32 retval;drivers/net/wireless/ath/ath9k/hw.h +2
-0@@ -138,6 +138,8 @@#define REG_WRITE_ARRAY (iniarray, column, regWr) \ ath9k_hw_write_array(ah, iniarray, column, &(regWr)) +#define REG_READ_ARRAY (ah, array, size) \ + ath9k_hw_read_array(ah, array, size)#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
drivers/net/wireless/ath/ath9k/hw.h void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, · line 1028
Quoted 7 lines
drivers/net/wireless/ath/ath9k/hw.h +1
-0@@ -1020,6 +1022,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,bool ath9k_hw_wait (struct ath_hw *ah,u32 reg,u32 mask,u32 val,u32 timeout);void ath9k_hw_write_array (struct ath_hw *ah,const struct ar5416IniArray *array,int column,unsigned int *writecnt); +void ath9k_hw_read_array (struct ath_hw *ah,u32 array[][2 ],int size);u32 ath9k_hw_reverse_bits (u32 val,u32 n); u16 ath9k_hw_computetxtime(struct ath_hw *ah, u8 phy, int kbps,
Marc
Signature · 12 lines
Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20150321/4e40bd16/attachment.pgp
PATCH v2 7/18 ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
In reply to Oleksij Rempelinsted of reading each register separatly
and waste 4ms on each operation, we can
use one shot read.
--- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9002_calib.c +1 -2
@@ -440,8 +440,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) { AR9285_AN_RF2G3, 0 }, }; -for (i =0 ; i <ARRAY_SIZE (regList); i++) - regList[i][1 ] =REG_READ (ah, regList[i][0 ]); +REG_READ_ARRAY (ah, regList,ARRAY_SIZE (regList));ENABLE_REG_RMW_BUFFER (ah);/* 7834, b1=0 */
Signature · 1 line
1.9.1
PATCH v2 8/18 ath9k: use one shot read in ath9k_hw_update_mibstats
In reply to Oleksij Rempelthis will reduce some overhead on usb bus.
--- drivers/net/wireless/ath/ath9k/ani.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath9k/ani.c +15 -5
@@ -107,11 +107,21 @@ static const struct ani_cck_level_entry cck_level_table[] = {static void ath9k_hw_update_mibstats (struct ath_hw *ah,struct ath9k_mib_stats *stats) { - stats->ackrcv_bad +=REG_READ (ah,AR_ACK_FAIL ); - stats->rts_bad +=REG_READ (ah,AR_RTS_FAIL ); - stats->fcs_bad +=REG_READ (ah,AR_FCS_FAIL ); - stats->rts_good +=REG_READ (ah,AR_RTS_OK ); - stats->beacons +=REG_READ (ah,AR_BEACON_CNT ); +u32 addr[5 ] = {AR_RTS_OK ,AR_RTS_FAIL ,AR_ACK_FAIL , +AR_FCS_FAIL ,AR_BEACON_CNT }; +u32 data[5 ]; + +REG_READ_MULTI (ah, &addr[0 ], &data[0 ],5 ); +/* AR_RTS_OK */ + stats->rts_good += data[0 ]; +/* AR_RTS_FAIL */ + stats->rts_bad += data[1 ]; +/* AR_ACK_FAIL */ + stats->ackrcv_bad += data[2 ]; +/* AR_FCS_FAIL */ + stats->fcs_bad += data[3 ]; +/* AR_BEACON_CNT */ + stats->beacons += data[4 ]; }static void ath9k_ani_restart (struct ath_hw *ah)
Signature · 1 line
1.9.1
PATCH v2 9/18 ath9k: ath9k_hw_loadnf: use REG_RMW
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/calib.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/net/wireless/ath/ath9k/calib.c +8 -11
@@ -238,7 +238,6 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) {struct ath9k_nfcal_hist *h =NULL ;unsigned i, j; -int32_t val;u8 chainmask = (ah->rxchainmask <<3 ) | ah->rxchainmask;struct ath_common *common =ath9k_hw_common (ah);s16 default_nf =ath9k_hw_get_default_nf (ah, chan);
@@ -246,6 +245,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)if (ah->caldata) h = ah->caldata->nfCalHist; +ENABLE_REG_RMW_BUFFER (ah);for (i =0 ; i <NUM_NF_READINGS ; i++) {if (chainmask & (1 << i)) {s16 nfval;
@@ -258,10 +258,8 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)else nfval = default_nf; - val =REG_READ (ah, ah->nf_regs[i]); - val &=0xFFFFFE00 ; - val |= (((u32 ) nfval <<1 ) &0x1ff ); -REG_WRITE (ah, ah->nf_regs[i], val); +REG_RMW (ah, ah->nf_regs[i], + (((u32 ) nfval <<1 ) &0x1ff ),0x1ff ); } }
@@ -274,6 +272,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)REG_CLR_BIT (ah,AR_PHY_AGC_CONTROL ,AR_PHY_AGC_CONTROL_NO_UPDATE_NF );REG_SET_BIT (ah,AR_PHY_AGC_CONTROL ,AR_PHY_AGC_CONTROL_NF ); +REG_RMW_BUFFER_FLUSH (ah);/* * Wait for load to complete, should be fast, a few 10s of us.
@@ -309,19 +308,17 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)* by the median we just loaded. This will be initial (and max) value * of next noise floor calibration the baseband does. */ -ENABLE_REGWRITE_BUFFER (ah); +ENABLE_REG_RMW_BUFFER (ah);for (i =0 ; i <NUM_NF_READINGS ; i++) {if (chainmask & (1 << i)) {if ((i >=AR5416_MAX_CHAINS ) && !IS_CHAN_HT40 (chan))continue ; - val =REG_READ (ah, ah->nf_regs[i]); - val &=0xFFFFFE00 ; - val |= (((u32) (-50 ) <<1 ) &0x1ff ); -REG_WRITE (ah, ah->nf_regs[i], val); +REG_RMW (ah, ah->nf_regs[i], + (((u32) (-50 ) <<1 ) &0x1ff ),0x1ff ); } } -REGWRITE_BUFFER_FLUSH (ah); +REG_RMW_BUFFER_FLUSH (ah);return 0 ; }
Signature · 1 line
1.9.1
PATCH v2 10/18 ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar5008_phy.c +3 -2
@@ -681,12 +681,13 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, phymode |=AR_PHY_FC_DYN2040_PRI_CH ; } +ENABLE_REGWRITE_BUFFER (ah);REG_WRITE (ah,AR_PHY_TURBO , phymode); +/* This function do only REG_WRITE, so +* we can include it to REGWRITE_BUFFER. */ ath9k_hw_set11nmac2040 (ah, chan); -ENABLE_REGWRITE_BUFFER (ah); -REG_WRITE (ah,AR_GTXTO ,25 <<AR_GTXTO_TIMEOUT_LIMIT_S );REG_WRITE (ah,AR_CST ,0xF <<AR_CST_TIMEOUT_LIMIT_S );
Signature · 1 line
1.9.1
PATCH v2 11/18 ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/eeprom_4k.c +2 -0
@@ -389,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, } } +ENABLE_REG_RMW_BUFFER (ah);REG_RMW_FIELD (ah,AR_PHY_TPCRG1 ,AR_PHY_TPCRG1_NUM_PD_GAIN , (numXpdGain -1 ) &0x3 ); REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
@@ -396,6 +397,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,REG_RMW_FIELD (ah,AR_PHY_TPCRG1 ,AR_PHY_TPCRG1_PD_GAIN_2 , xpdGainValues[1 ]);REG_RMW_FIELD (ah,AR_PHY_TPCRG1 ,AR_PHY_TPCRG1_PD_GAIN_3 ,0 ); +REG_RMW_BUFFER_FLUSH (ah);for (i =0 ; i <AR5416_EEP4K_MAX_CHAINS ; i++) { regChainOffset = i *0x1000 ;
Signature · 1 line
1.9.1
PATCH v2 12/18 ath9k: use rmw buffer in ath9k_hw_set_operating_mode and ath9k_hw_reset
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/hw.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/ath/ath9k/hw.c +4 -0
@@ -1217,6 +1217,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)u32 mask =AR_STA_ID1_STA_AP |AR_STA_ID1_ADHOC ;u32 set =AR_STA_ID1_KSRCH_MODE ; +ENABLE_REG_RMW_BUFFER (ah);switch (opmode) {case NL80211_IFTYPE_ADHOC :if (!AR_SREV_9340_13 (ah)) {
@@ -1238,6 +1239,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)break ; }REG_RMW (ah,AR_STA_ID1 , set, mask); +REG_RMW_BUFFER_FLUSH (ah); } void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1950,6 +1952,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,if (!ath9k_hw_mci_is_enabled (ah))REG_WRITE (ah,AR_OBS ,8 ); +ENABLE_REG_RMW_BUFFER (ah);if (ah->config.rx_intr_mitigation) {REG_RMW_FIELD (ah,AR_RIMT ,AR_RIMT_LAST , ah->config.rimt_last);REG_RMW_FIELD (ah,AR_RIMT ,AR_RIMT_FIRST , ah->config.rimt_first);
@@ -1959,6 +1962,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,REG_RMW_FIELD (ah,AR_TIMT ,AR_TIMT_LAST ,300 );REG_RMW_FIELD (ah,AR_TIMT ,AR_TIMT_FIRST ,750 ); } +REG_RMW_BUFFER_FLUSH (ah);ath9k_hw_init_bb (ah, chan);
Signature · 1 line
1.9.1
PATCH v2 13/18 ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/eeprom_4k.c +2 -0
@@ -1082,6 +1082,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, mask =BIT (0 )|BIT (5 )|BIT (10 )|BIT (15 )|BIT (20 )|BIT (25 ); pwrctrl = mask * bb_desired_scale; clr = mask *0x1f ; +ENABLE_REG_RMW_BUFFER (ah);REG_RMW (ah,AR_PHY_TX_PWRCTRL8 , pwrctrl, clr);REG_RMW (ah,AR_PHY_TX_PWRCTRL10 , pwrctrl, clr);REG_RMW (ah,AR_PHY_CH0_TX_PWRCTRL12 , pwrctrl, clr);
@@ -1096,6 +1097,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, clr = mask *0x1f ;REG_RMW (ah,AR_PHY_CH0_TX_PWRCTRL11 , pwrctrl, clr);REG_RMW (ah,AR_PHY_CH0_TX_PWRCTRL13 , pwrctrl, clr); +REG_RMW_BUFFER_FLUSH (ah); } }
Signature · 1 line
1.9.1
PATCH v2 14/18 ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
In reply to Oleksij Rempeluse REG_RMW in ath9k_hw_analog_shift_rmw.
It will double execution speed on usb bus.
--- drivers/net/wireless/ath/ath9k/eeprom.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/net/wireless/ath/ath9k/eeprom.c +1 -6
@@ -27,12 +27,7 @@ void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)void ath9k_hw_analog_shift_rmw (struct ath_hw *ah,u32 reg,u32 mask,u32 shift,u32 val) { -u32 regVal; - - regVal =REG_READ (ah, reg) & ~mask; - regVal |= (val << shift) & mask; - -REG_WRITE (ah, reg, regVal); +REG_RMW (ah, reg, ((val << shift) & mask), mask);if (ah->config.analog_shiftreg)udelay (100 );
Signature · 1 line
1.9.1
PATCH v2 15/18 ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
In reply to Oleksij Rempelit will reduce exution time from 14ms to 2ms on ar9271
--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/eeprom_4k.c +2 -0
@@ -930,6 +930,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, } } +ENABLE_REG_RMW_BUFFER (ah);if (AR_SREV_9271 (ah)) { ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
@@ -1034,6 +1035,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,AR9285_AN_RF2G4_DB2_4_S , db2[4]); } +REG_RMW_BUFFER_FLUSH (ah); REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
Signature · 1 line
1.9.1
PATCH v2 16/18 ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
In reply to Oleksij Rempelit is possible to reduce time needed for this function
by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands in same buffer.
--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath9k/eeprom_4k.c +8 -8
@@ -772,15 +772,14 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,struct ar5416_eeprom_4k *eep, u8 txRxAttenLocal) { -REG_WRITE (ah ,AR_PHY_SWITCH_CHAIN_0 , - pModal->antCtrlChain[0]); +ENABLE_REG_RMW_BUFFER (ah ); +REG_RMW (ah,AR_PHY_SWITCH_CHAIN_0 , + pModal->antCtrlChain[0 ],0 ); -REG_WRITE (ah,AR_PHY_TIMING_CTRL4 (0 ), - (REG_READ (ah,AR_PHY_TIMING_CTRL4 (0 )) & - ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | -AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF )) | -SM (pModal->iqCalICh[0 ],AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) | -SM (pModal->iqCalQCh[0 ],AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF )); +REG_RMW (ah,AR_PHY_TIMING_CTRL4 (0 ), +SM (pModal->iqCalICh[0 ],AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) | +SM (pModal->iqCalQCh[0 ],AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF ), +AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF );if ((eep->baseEepHeader.version &AR5416_EEP_VER_MINOR_MASK ) >=AR5416_EEP_MINOR_VER_3 ) {
@@ -819,6 +818,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);REG_RMW_FIELD (ah,AR_PHY_RXGAIN +0x1000 ,AR9280_PHY_RXGAIN_TXRX_MARGIN , pModal->rxTxMarginCh[0 ]); +REG_RMW_BUFFER_FLUSH (ah); }/*
Signature · 1 line
1.9.1
PATCH v2 17/18 ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
In reply to Oleksij Rempelreplace REG_WRITE to REG_RMW and place every thing in one RMW buffer.
--- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath9k/eeprom_4k.c +8 -6
@@ -1037,17 +1037,17 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, }REG_RMW_BUFFER_FLUSH (ah); - +ENABLE_REG_RMW_BUFFER (ah);REG_RMW_FIELD (ah,AR_PHY_SETTLING ,AR_PHY_SETTLING_SWITCH , pModal->switchSettling);REG_RMW_FIELD (ah,AR_PHY_DESIRED_SZ ,AR_PHY_DESIRED_SZ_ADC , pModal->adcDesiredSize); -REG_WRITE (ah,AR_PHY_RF_CTL4 , -SM (pModal->txEndToXpaOff,AR_PHY_RF_CTL4_TX_END_XPAA_OFF ) | -SM (pModal->txEndToXpaOff,AR_PHY_RF_CTL4_TX_END_XPAB_OFF ) | -SM (pModal->txFrameToXpaOn,AR_PHY_RF_CTL4_FRAME_XPAA_ON ) | -SM (pModal->txFrameToXpaOn,AR_PHY_RF_CTL4_FRAME_XPAB_ON )); +REG_RMW (ah,AR_PHY_RF_CTL4 , +SM (pModal->txEndToXpaOff,AR_PHY_RF_CTL4_TX_END_XPAA_OFF ) | +SM (pModal->txEndToXpaOff,AR_PHY_RF_CTL4_TX_END_XPAB_OFF ) | +SM (pModal->txFrameToXpaOn,AR_PHY_RF_CTL4_FRAME_XPAA_ON ) | +SM (pModal->txFrameToXpaOn,AR_PHY_RF_CTL4_FRAME_XPAB_ON ),0 );REG_RMW_FIELD (ah,AR_PHY_RF_CTL3 ,AR_PHY_TX_END_TO_A2_RX_ON , pModal->txEndToRxOn);
@@ -1076,6 +1076,8 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, pModal->swSettleHt40); } +REG_RMW_BUFFER_FLUSH (ah); + bb_desired_scale = (pModal->bb_scale_smrt_antenna &EEP_4K_BB_DESIRED_SCALE_MASK );if ((pBase->txGainType ==0 ) && (bb_desired_scale !=0 )) {
Signature · 1 line
1.9.1
PATCH v2 18/18 ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
In reply to Oleksij Rempel--- drivers/net/wireless/ath/ath9k/eeprom_def.c | 34 ++++++++++++----------------- 1 file changed, 14 insertions(+), 20 deletions(-)
drivers/net/wireless/ath/ath9k/eeprom_def.c +14 -20
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,struct ar5416_eeprom_def *eep, u8 txRxAttenLocal, int regChainOffset, int i) { +ENABLE_REG_RMW_BUFFER (ah );if (AR5416_VER_MASK >=AR5416_EEP_MINOR_VER_3 ) { txRxAttenLocal = pModal->txRxAttenCh[i];
@@ -483,16 +484,12 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,AR_PHY_GAIN_2GHZ_XATTEN2_DB , pModal->xatten2Db[i]); }else { -REG_WRITE (ah,AR_PHY_GAIN_2GHZ + regChainOffset, - (REG_READ (ah,AR_PHY_GAIN_2GHZ + regChainOffset) & - ~AR_PHY_GAIN_2GHZ_BSW_MARGIN ) - |SM (pModal-> bswMargin[i], -AR_PHY_GAIN_2GHZ_BSW_MARGIN )); -REG_WRITE (ah,AR_PHY_GAIN_2GHZ + regChainOffset, - (REG_READ (ah,AR_PHY_GAIN_2GHZ + regChainOffset) & - ~AR_PHY_GAIN_2GHZ_BSW_ATTEN ) - |SM (pModal->bswAtten[i], -AR_PHY_GAIN_2GHZ_BSW_ATTEN )); +REG_RMW (ah,AR_PHY_GAIN_2GHZ + regChainOffset, +SM (pModal-> bswMargin[i],AR_PHY_GAIN_2GHZ_BSW_MARGIN ), +AR_PHY_GAIN_2GHZ_BSW_MARGIN ); +REG_RMW (ah,AR_PHY_GAIN_2GHZ + regChainOffset, +SM (pModal->bswAtten[i],AR_PHY_GAIN_2GHZ_BSW_ATTEN ), +AR_PHY_GAIN_2GHZ_BSW_ATTEN ); } }
@@ -504,17 +501,14 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,AR_PHY_RXGAIN + regChainOffset, AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); }else { -REG_WRITE (ah, -AR_PHY_RXGAIN + regChainOffset, - (REG_READ (ah,AR_PHY_RXGAIN + regChainOffset) & - ~AR_PHY_RXGAIN_TXRX_ATTEN ) - |SM (txRxAttenLocal,AR_PHY_RXGAIN_TXRX_ATTEN )); -REG_WRITE (ah, -AR_PHY_GAIN_2GHZ + regChainOffset, - (REG_READ (ah,AR_PHY_GAIN_2GHZ + regChainOffset) & - ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN ) | -SM (pModal->rxTxMarginCh[i],AR_PHY_GAIN_2GHZ_RXTX_MARGIN )); +REG_RMW (ah,AR_PHY_RXGAIN + regChainOffset, +SM (txRxAttenLocal,AR_PHY_RXGAIN_TXRX_ATTEN ), +AR_PHY_RXGAIN_TXRX_ATTEN ); +REG_RMW (ah,AR_PHY_GAIN_2GHZ + regChainOffset, +SM (pModal->rxTxMarginCh[i],AR_PHY_GAIN_2GHZ_RXTX_MARGIN ), +AR_PHY_GAIN_2GHZ_RXTX_MARGIN ); } +REG_RMW_BUFFER_FLUSH (ah); } static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
Signature · 1 line
1.9.1