carl9170 firmware: 5/10 MHz Channel Support for carl9170
authorChristian Lamparter <chunkeey@googlemail.com>
Wed, 5 Jun 2013 20:30:11 +0000 (22:30 +0200)
committerChristian Lamparter <chunkeey@googlemail.com>
Wed, 5 Jun 2013 20:30:11 +0000 (22:30 +0200)
This patch enables experimental support for 5 and 10 MHz channel.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
carlfw/include/carl9170.h
carlfw/include/timer.h
carlfw/src/fw.c
carlfw/src/main.c
carlfw/src/rf.c
carlfw/src/timer.c
carlfw/usb/main.c
include/shared/fwcmd.h
include/shared/fwdesc.h
include/shared/hw.h
tools/src/fwinfo.c

index a807dd4be27447639545e7b5da2a5cca6b91c86c..26d247bb6d752f634345b1b7f2420a00b7499f6f 100644 (file)
@@ -183,7 +183,7 @@ struct firmware_context_struct {
 
                /* PHY/RF state */
                unsigned int frequency;
-               unsigned int ht_settings;
+               unsigned int settings;
 
                enum carl9170_phy_state state;
                struct carl9170_psm psm;
index 1b9d1c17f74f00f73eb92a57b5764555e43403f7..139bc390c99c1ee9d77be06e104ea5da3e4f04ec 100644 (file)
@@ -84,7 +84,7 @@ static inline __inline void udelay(const uint32_t usec)
        }
 }
 
-void clock_set(enum cpu_clock_t _clock, bool on);
+void clock_set(const enum cpu_clock_t _clock, const bool on, const unsigned int div);
 void handle_timer(void);
 void timer_init(const unsigned int timer, const unsigned int interval);
 
index f705a0d9dcb446c21b7d5de0da341ac613d36e71..493546be69097c00e692e509b0e33cdb9cdfc941 100644 (file)
@@ -40,6 +40,7 @@ const struct carl9170_firmware_descriptor __section(fwdsc) __visible carl9170fw_
                                        BIT(CARL9170FW_HW_COUNTERS) |
                                        BIT(CARL9170FW_RX_BA_FILTER) |
                                        BIT(CARL9170FW_USB_INIT_FIRMWARE) |
+                                       BIT(CARL9170FW_HALF_QUARTER_CHANNEL) |
 #ifdef CONFIG_CARL9170FW_USB_UP_STREAM
                                        BIT(CARL9170FW_USB_UP_STREAM) |
 #endif /* CONFIG_CARL9170FW_USB_UP_STREAM */
index b2d16390cff576eea2f4fd2608ba849b650f1849..47b4da449356004cc5e7dbb49c91ff05e235f55d 100644 (file)
@@ -140,7 +140,7 @@ static void __noreturn main_loop(void)
 
 void __section(boot) __noreturn __visible start(void)
 {
-       clock_set(AHB_40MHZ_OSC, true);
+       clock_set(AHB_40MHZ_OSC, true, 0);
 
        /* watchdog magic pattern check */
        if ((get(AR9170_PWR_REG_WATCH_DOG_MAGIC) & 0xffff0000) == 0x12340000) {
index e031dd8ee4d1f84e7fa3570dbd8c1e6f6c8b56fb..152aac59f5be225600e6b5cd081c1fb9cb9e31e6 100644 (file)
@@ -197,18 +197,19 @@ static uint32_t rf_init(const uint32_t delta_slope_coeff_exp,
 
 void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp)
 {
-       uint32_t ret;
+       uint32_t ret, div;
 
-       fw.phy.ht_settings = cmd->rf_init.ht_settings;
+       fw.phy.settings = cmd->rf_init.settings;
        fw.phy.frequency = cmd->rf_init.freq;
+       div = GET_VAL(CARL9170FW_PHY_RF_DIV, fw.phy.settings);
 
        /*
         * Is the clock controlled by the PHY?
         */
-       if ((fw.phy.ht_settings & EIGHTY_FLAG) == EIGHTY_FLAG)
-               clock_set(AHB_80_88MHZ, true);
+       if ((fw.phy.settings & EIGHTY_FLAG) == EIGHTY_FLAG)
+               clock_set(AHB_80_88MHZ, true, div);
        else
-               clock_set(AHB_40_44MHZ, true);
+               clock_set(AHB_40_44MHZ, true, div);
 
        ret = rf_init(le32_to_cpu(cmd->rf_init.delta_slope_coeff_exp),
                      le32_to_cpu(cmd->rf_init.delta_slope_coeff_man),
index 95058183cbd97245fa9b2ac793b81b578b861d62..79fcc31ab2f45c795094ca85dd5f1bb81040a257 100644 (file)
@@ -41,7 +41,7 @@ void timer_init(const unsigned int timer, const unsigned int interval)
        orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer));
 }
 
-void clock_set(enum cpu_clock_t clock_, bool on)
+void clock_set(const enum cpu_clock_t clock_, const bool on, const unsigned int div)
 {
        /*
         * Word of Warning!
@@ -60,7 +60,8 @@ void clock_set(enum cpu_clock_t clock_, bool on)
        fw.ticks_per_usec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV,
                get(AR9170_PWR_REG_PLL_ADDAC));
 
-       set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_));
+       set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_ |
+           SET_CONSTVAL(AR9170_PWR_CLK_ADDAC_CLK160, div))));
 
        switch (clock_) {
        case AHB_20_22MHZ:
index 1fb119e996f8933e70b16b4d24c77337203aa834..106eeb72137355f75e04175e86fb0deeda1f563f 100644 (file)
@@ -246,7 +246,7 @@ static void turn_power_off(void)
                                  AR9170_PWR_RESET_WLAN_MASK);
        set(AR9170_PWR_REG_RESET, 0x0);
 
-       clock_set(AHB_20_22MHZ, false);
+       clock_set(AHB_20_22MHZ, false, 0);
 
        set(AR9170_PWR_REG_PLL_ADDAC, 0x5163);  /* 0x502b; */
        set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO);
index 9111d4ffc1b3851309af860a7b2e3e8175a2fb3e..9f06a05b9fa11fc9f46641fb0e9d169b63a4258e 100644 (file)
@@ -127,10 +127,15 @@ struct carl9170_write_reg {
 #define        CARL9170FW_PHY_HT_DYN2040               0x8
 #define        CARL9170FW_PHY_HT_EXT_CHAN_OFF          0x3
 #define        CARL9170FW_PHY_HT_EXT_CHAN_OFF_S        2
+#define CARL9170FW_PHY_RF_DIV                  (BIT(4) | BIT(5))
+#define CARL9170FW_PHY_RF_BW_10MHZ             BIT(4)
+#define CARL9170FW_PHY_RF_BW_5MHZ              BIT(5)
+#define CARL9170FW_PHY_RF_DIV_S                        4
+
 
 struct carl9170_rf_init {
        __le32          freq;
-       u8              ht_settings;
+       u8              settings;
        u8              padding2[3];
        __le32          delta_slope_coeff_exp;
        __le32          delta_slope_coeff_man;
index 66848d47c88e993c2c04d328699e94249c5bad61..b1dba7001160e924a7bf1269578a972219ffab94 100644 (file)
@@ -81,6 +81,9 @@ enum carl9170fw_feature_list {
        /* Firmware will pass BA when BARs are queued */
        CARL9170FW_RX_BA_FILTER,
 
+       /* Supports 10MHz / 5 MHz channels */
+       CARL9170FW_HALF_QUARTER_CHANNEL,
+
        /* KEEP LAST */
        __CARL9170FW_FEATURE_NUM
 };
index 139ded8dc6a402d1efe179cb40108452d9ecd22b..ca464027afd8f8dd177780bc32c6e953dea16d4e 100644 (file)
 #define                AR9170_PWR_CLK_AHB_20_22MHZ             1
 #define                AR9170_PWR_CLK_AHB_40_44MHZ             2
 #define                AR9170_PWR_CLK_AHB_80_88MHZ             3
+#define                AR9170_PWR_CLK_ADDAC_CLK160             (BIT(2) | (BIT(3))
+#define                AR9170_PWR_CLK_ADDAC_CLK160_S           2
 #define                AR9170_PWR_CLK_DAC_160_INV_DLY          0x70
 
 #define        AR9170_PWR_REG_CHIP_REVISION            (AR9170_PWR_REG_BASE + 0x010)
index 0d5cd0947922d92243c61645a3b0ecb7f88827ed..bed9fe3df14387b32ed2d5955ab28b364a3612c1 100644 (file)
@@ -69,6 +69,7 @@ static const struct feature_list known_otus_features_v1[] = {
        CHECK_FOR_FEATURE(CARL9170FW_FIXED_5GHZ_PSM),
        CHECK_FOR_FEATURE(CARL9170FW_HW_COUNTERS),
        CHECK_FOR_FEATURE(CARL9170FW_RX_BA_FILTER),
+       CHECK_FOR_FEATURE(CARL9170FW_HALF_QUARTER_CHANNEL),
 };
 
 static void check_feature_list(const struct carl9170fw_desc_head *head,