On 2011-09-07 10:03 PM, Daniel Golle wrote:
This is a temporary solution to add support for the external antenna switching
logic built-into the ALL0258N. Obviously this cannot go upstream, but works
for now...

Signed-off-by: Daniel Golle<dgo...@allnet.de>

Index: 950-ar9285_external_pa_and_high_power.patch
===================================================================
--- 950-ar9285_external_pa_and_high_power.patch (revision 0)
+++ 950-ar9285_external_pa_and_high_power.patch (revision 0)
@@ -0,0 +1,53 @@
+diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c 
b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+index 2d4c091..f9b05e6 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+@@ -561,10 +561,12 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, 
bool is_reset)
+
+       ath_dbg(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+
++#if 0
+       /* PA CAL is not needed for high power solution */
+       if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
+           AR5416_EEP_TXGAIN_HIGH_POWER)
+               return;
++#endif
+
+       for (i = 0; i<  ARRAY_SIZE(regList); i++)
+               regList[i][1] = REG_READ(ah, regList[i][0]);
+diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c 
b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+index 44d9d8d..4c0bfdf 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+@@ -262,7 +262,7 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw 
*ah)
+       } else if (AR_SREV_9280_20(ah)) {
+               ar9280_20_hw_init_txgain_ini(ah);
+       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
+-              u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
++              u32 txgain_type = 1;
+
+               /* txgain table */
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
You could work around the wrong EEPROM programming this by patching a copy of the eeprom file in the mach file in the kernel. The format is documented in the eeprom header file.

+diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c 
b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+index 1c6ce04..56ef4c4 100644
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -523,8 +523,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct 
ath_hw *ah,
+                       (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+       }
+
+-      scaledPower = min(powerLimit, maxRegAllowedPower);
+-      scaledPower = max((u16)0, scaledPower);
++      scaledPower = max((u16)0, powerLimit);
+
+       numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+       pCtlMode = ctlModesFor11g;
+@@ -597,7 +596,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct 
ath_hw *ah,
+                       }
+               }
+
+-              minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
++              minCtlPower = scaledPower;
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
What is this for? It does not make much sense to me.

+diff --git a/drivers/net/wireless/ath/ath9k/hw.c 
b/drivers/net/wireless/ath/ath9k/hw.c
+index bce8583..92b4421 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -26,6 +26,8 @@
+
+ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+
++static struct proc_dir_entry *switch_com_entry = NULL;
++
+ MODULE_AUTHOR("Atheros Communications");
+ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
+ MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
+@@ -651,6 +653,22 @@ static int __ath9k_hw_init(struct ath_hw *ah)
+       return 0;
+ }
+
++static int ath9k_set_switch_com(struct file *file, const char *buf, unsigned 
long count, void *data)
++{
++      struct ath_hw *ah = (struct ath_hw *)data;
++
++      ah->eep_ops->set_switch_com(ah, simple_strtoul(buf, NULL, 16));
++
++      return -EINVAL;
++}
++
++static int ath9k_get_switch_com(char *page, char **start, off_t off, int 
count, int *eof, void *data)
++{
++      struct ath_hw *ah = (struct ath_hw *)data;
++
++      return sprintf(page, "0x%08x\n", ah->eep_ops->get_switch_com(ah));
++}
++
+ int ath9k_hw_init(struct ath_hw *ah)
+ {
+       int ret;
+@@ -688,6 +706,11 @@ int ath9k_hw_init(struct ath_hw *ah)
+                       ret);
+               return ret;
+       }
++      else if (switch_com_entry = create_proc_entry("switch_com", 0644, 
NULL)) {
++              switch_com_entry->data = (void *)ah;
++              switch_com_entry->write_proc = ath9k_set_switch_com;
++              switch_com_entry->read_proc = ath9k_get_switch_com;
++      }
+
+       return 0;
+ }
+@@ -1051,6 +1074,11 @@ void ath9k_hw_deinit(struct ath_hw *ah)
+ {
+       struct ath_common *common = ath9k_hw_common(ah);
+
++      if (switch_com_entry != NULL) {
++              remove_proc_entry("switch_com", NULL);
++              switch_com_entry = NULL;
++      }
++
+       if (common->state<  ATH_HW_INITIALIZED)
+               goto free_hw;
+
What kind of values get written to that file, how does it control the antenna? By the way, you can switch between the two LNA paths through the nl80211 antenna selection API. Would this be enough to control the antenna selection on this device?

- Felix
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to