support for antenna configuration profiles
PATCH 3/3 support for antenna configuration profiles
This adds support for controlling AR_PHY_SWITCH_COM of the AR9285 by using antenna configuration profiles to ath9k.
Signed-off-by Daniel Golle <[email protected]>
--- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 13 ++++ drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++- drivers/net/wireless/ath/ath9k/eeprom.h | 1 + drivers/net/wireless/ath/ath9k/eeprom_4k.c | 29 +++++++- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 8 ++- drivers/net/wireless/ath/ath9k/eeprom_def.c | 8 ++- drivers/net/wireless/ath/ath9k/hw.h | 28 +++++++ drivers/net/wireless/ath/ath9k/init.c | 93 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/main.c | 36 +++++++++ include/linux/ath9k_platform.h | 6 ++ 10 files changed, 225 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath9k/ar9002_phy.c +13 -0
@@ -556,6 +556,16 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,REG_WRITE (ah,AR_PHY_MULTICHAIN_GAIN_CTL , regval); } +static void ar9002_hw_extant_switchcom_set (struct ath_hw *ah,u32 switch_com_value) +{ +REG_WRITE (ah,AR_PHY_SWITCH_COM , switch_com_value); +} + +static u32 ar9002_hw_extant_switchcom_get (struct ath_hw *ah) +{ +return REG_READ (ah,AR_PHY_SWITCH_COM ); +} +void ar9002_hw_attach_phy_ops (struct ath_hw *ah) {struct ath_hw_private_ops *priv_ops =ath9k_hw_private_ops (ah);
@@ -573,5 +583,8 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; + ops->extant_switchcom_set = ar9002_hw_extant_switchcom_set; + ops->extant_switchcom_get = ar9002_hw_extant_switchcom_get; +ar9002_hw_set_nf_limits (ah); }
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +7 -1
@@ -5140,6 +5140,11 @@ unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, } } +static u32 ath9k_hw_ar9300_get_switch_com (struct ath_hw *ah) +{ +return 0 ; +} +const struct eeprom_ops eep_ar9300_ops = { .check_eeprom = ath9k_hw_ar9300_check_eeprom, .get_eeprom = ath9k_hw_ar9300_get_eeprom,
@@ -5150,5 +5155,6 @@ const struct eeprom_ops eep_ar9300_ops = { .set_board_values = ath9k_hw_ar9300_set_board_values, .set_addac = ath9k_hw_ar9300_set_addac, .set_txpower = ath9k_hw_ar9300_set_txpower, - .get_spur_channel = ath9k_hw_ar9300_get_spur_channel + .get_spur_channel = ath9k_hw_ar9300_get_spur_channel, + .get_switch_com = ath9k_hw_ar9300_get_switch_com };
drivers/net/wireless/ath/ath9k/eeprom.h +1 -0
@@ -656,6 +656,7 @@ struct eeprom_ops { u16 cfgCtl, u8 twiceAntennaReduction, u8 powerLimit, bool test);u16 (*get_spur_channel)(struct ath_hw *ah,u16 i,bool is2GHz); +u32 (*get_switch_com)(struct ath_hw *ah); };void ath9k_hw_analog_shift_regwrite (struct ath_hw *ah,u32 reg,u32 val);
drivers/net/wireless/ath/ath9k/eeprom_4k.c +27 -2
@@ -815,6 +815,30 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah, }/* +* Get common antenna configuration bits +*/ +static u32 ath9k_hw_4k_get_switch_com (struct ath_hw *ah) +{ +struct ath_hw_switch_com_profile *easp; +struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; +struct modal_eep_4k_header *pModal = &eep->modalHeader; + +/* return value from eeprom if there are no profiles */ +if (!ah->switch_com_profiles) +return pModal->antCtrlCommon; + +/* find matching value for profile id */ +for (easp = ah->switch_com_profiles;easp->id >=0 ; easp++) { +if ( easp->id == ah->selected_extant_profile ) +return easp->switch_com_value; + } + +/* invalid profile selected, return an error */ +return 1 ; +} + + +/* * Read EEPROM header info and program the device for correct operation * given the channel value. */
@@ -833,7 +857,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, pModal = &eep->modalHeader; txRxAttenLocal =23 ; -REG_WRITE (ah,AR_PHY_SWITCH_COM , pModal->antCtrlCommon); +REG_WRITE (ah,AR_PHY_SWITCH_COM ,ath9k_hw_4k_get_switch_com (ah));/* Single chain for 4K EEPROM*/ ath9k_hw_4k_set_gain (ah, pModal, eep, txRxAttenLocal);
@@ -1112,5 +1136,6 @@ const struct eeprom_ops eep_4k_ops = { .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, .set_board_values = ath9k_hw_4k_set_board_values, .set_txpower = ath9k_hw_4k_set_txpower, - .get_spur_channel = ath9k_hw_4k_get_spur_channel + .get_spur_channel = ath9k_hw_4k_get_spur_channel, + .get_switch_com = ath9k_hw_4k_get_switch_com };
drivers/net/wireless/ath/ath9k/eeprom_9287.c +7 -1
@@ -1062,6 +1062,11 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,#undef EEP_MAP9287_SPURCHAN } +static u32 ath9k_hw_ar9287_get_switch_com (struct ath_hw *ah) +{ +return 0 ; +} +const struct eeprom_ops eep_ar9287_ops = { .check_eeprom = ath9k_hw_ar9287_check_eeprom, .get_eeprom = ath9k_hw_ar9287_get_eeprom,
@@ -1071,5 +1076,6 @@ const struct eeprom_ops eep_ar9287_ops = { .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, .set_board_values = ath9k_hw_ar9287_set_board_values, .set_txpower = ath9k_hw_ar9287_set_txpower, - .get_spur_channel = ath9k_hw_ar9287_get_spur_channel + .get_spur_channel = ath9k_hw_ar9287_get_spur_channel, + .get_switch_com = ath9k_hw_ar9287_get_switch_com };
drivers/net/wireless/ath/ath9k/eeprom_def.c +7 -1
@@ -1420,6 +1420,11 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)#undef EEP_DEF_SPURCHAN } +static u32 ath9k_hw_def_get_switch_com (struct ath_hw *ah) +{ +return 0 ; +} +const struct eeprom_ops eep_def_ops = { .check_eeprom = ath9k_hw_def_check_eeprom, .get_eeprom = ath9k_hw_def_get_eeprom,
@@ -1430,5 +1435,6 @@ const struct eeprom_ops eep_def_ops = { .set_board_values = ath9k_hw_def_set_board_values, .set_addac = ath9k_hw_def_set_addac, .set_txpower = ath9k_hw_def_set_txpower, - .get_spur_channel = ath9k_hw_def_get_spur_channel + .get_spur_channel = ath9k_hw_def_get_spur_channel, + .get_switch_com = ath9k_hw_def_get_switch_com };
drivers/net/wireless/ath/ath9k/hw.h +28 -0
@@ -545,6 +545,25 @@ struct ath_hw_radar_conf {bool ext_channel; }; + +/** +* struct ath_hw_switch_com_profile - external antenna switch settings +* +* This structure holds a platform_data-supplied alternative value +* of AR_PHY_SWITCH_COM. +* +* @id: unique identifier +* @switch_com_value: bit-field to be set in register AR_PHY_SWITCH_COM +* @name: profile name +* @desc: profile description +*/ +struct ath_hw_switch_com_profile { +int id; +u32 switch_com_value; +char *name; +char *desc; +}; +/** * struct ath_hw_private_ops - callbacks used internally by hardware code *
@@ -643,6 +662,9 @@ struct ath_hw_ops {void (*antdiv_comb_conf_set)(struct ath_hw *ah,struct ath_hw_antcomb_conf *antconf); +u32 (*extant_switchcom_get)(struct ath_hw *ah); +void (*extant_switchcom_set)(struct ath_hw *ah, +u32 switch_com_value); };struct ath_nf_limits {
@@ -882,6 +904,12 @@ struct ath_hw {bool is_clk_25mhz;int (*get_mac_revision)(void );int (*external_reset)(void ); + +/* +* External antenna switch configuration profiles +*/ +struct ath_hw_switch_com_profile *switch_com_profiles; +u32 selected_extant_profile; };struct ath_bus_ops {
drivers/net/wireless/ath/ath9k/init.c +93 -0
140 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/main.c +36 -0
@@ -2484,6 +2484,40 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)return 0 ; } +static int ath9k_set_extant (struct ieee80211_hw *hw,u32 extant) +{ +struct ath_softc *sc = hw->priv; +struct ath_hw *ah = sc->sc_ah; +struct ath_common *common =ath9k_hw_common (ah); +u32 backup_extant = ah->selected_extant_profile; +u32 switch_com_value =0 ; + +ath_dbg (common,ATH_DBG_CONFIG ,"entering set_extant(%d)\n" , extant); + + ah->selected_extant_profile = extant; + switch_com_value = ah->eep_ops->get_switch_com (ah); +if (switch_com_value &0xf ) + goto invalid_profile; + +ath_dbg (common,ATH_DBG_CONFIG ,"switch_com: %08x\n" , switch_com_value); +return 0 ; + +invalid_profile: +ath_dbg (common,ATH_DBG_CONFIG ,"invalid profile (%08x)\n" , switch_com_value); + ah->selected_extant_profile = backup_extant; +return -EINVAL ; +} + +static int ath9k_get_extant (struct ieee80211_hw *hw,u32 *extant) +{ +struct ath_softc *sc = hw->priv; +struct ath_hw *ah = sc->sc_ah; +if (!ah->switch_com_profiles) +return -EINVAL ; + *extant = ah->selected_extant_profile; +return 0 ; +} +struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start,
@@ -2512,4 +2546,6 @@ struct ieee80211_ops ath9k_ops = { .get_stats = ath9k_get_stats, .set_antenna = ath9k_set_antenna, .get_antenna = ath9k_get_antenna, + .set_extant = ath9k_set_extant, + .get_extant = ath9k_get_extant, };
include/linux/ath9k_platform.h +6 -0
@@ -20,6 +20,7 @@#define _LINUX_ATH9K_PLATFORM_H#define ATH9K_PLAT_EEP_MAX_WORDS 2048 +#define ATH9K_PLAT_MAX_SWITCH_COM_PROFILES 4struct ath9k_platform_data {u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS ];
@@ -32,6 +33,11 @@ struct ath9k_platform_data {bool is_clk_25mhz;int (*get_mac_revision)(void );int (*external_reset)(void ); +struct { +u32 val; +char *name; +char *desc; + } switch_com_profiles[ATH9K_PLAT_MAX_SWITCH_COM_PROFILES]; };#endif /* _LINUX_ATH9K_PLATFORM_H */
Signature · 1 line
1.7.4.1