ath6kl: support fw reporting phy capabilities
authorThomas Pedersen <c_tpeder@qca.qualcomm.com>
Thu, 19 Apr 2012 22:31:56 +0000 (15:31 -0700)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 23 Apr 2012 11:28:00 +0000 (14:28 +0300)
Currently the supported bands are just hard coded in the driver.
However, the ath6kl FW will include its 11n and band capabilites in a
WMI_READY event. Handle this and report capabilites to cfg80211
accordingly.

Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index a8a7570e22a0e58b1db385b6151316ccdc31ce5d..b8489772c373dc591f72659afc54ec00e9a6cc28 100644 (file)
@@ -3419,6 +3419,7 @@ err:
 int ath6kl_cfg80211_init(struct ath6kl *ar)
 {
        struct wiphy *wiphy = ar->wiphy;
+       bool band_2gig = false, band_5gig = false, ht = false;
        int ret;
 
        wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
@@ -3439,8 +3440,39 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
        /* max num of ssids that can be probed during scanning */
        wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
        wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
-       wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
-       wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+       switch (ar->hw.cap) {
+       case WMI_11AN_CAP:
+               ht = true;
+       case WMI_11A_CAP:
+               band_5gig = true;
+               break;
+       case WMI_11GN_CAP:
+               ht = true;
+       case WMI_11G_CAP:
+               band_2gig = true;
+               break;
+       case WMI_11AGN_CAP:
+               ht = true;
+       case WMI_11AG_CAP:
+               band_2gig = true;
+               band_5gig = true;
+               break;
+       default:
+               ath6kl_err("invalid phy capability!\n");
+               return -EINVAL;
+       }
+
+       if (!ht) {
+               ath6kl_band_2ghz.ht_cap.cap = 0;
+               ath6kl_band_2ghz.ht_cap.ht_supported = false;
+               ath6kl_band_5ghz.ht_cap.cap = 0;
+               ath6kl_band_5ghz.ht_cap.ht_supported = false;
+       }
+       if (band_2gig)
+               wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+       if (band_5gig)
+               wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+
        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 
        wiphy->cipher_suites = cipher_suites;
index a97cb836106a2721d80c0f633f3ab45fa8740cd0..c26f0a269168ed7aa5496f16f7245347f2e8c319 100644 (file)
@@ -683,6 +683,7 @@ struct ath6kl {
                u32 refclk_hz;
                u32 uarttx_pin;
                u32 testscript_addr;
+               enum wmi_phy_cap cap;
 
                struct ath6kl_hw_fw {
                        const char *dir;
@@ -816,7 +817,8 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn);
 struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr);
 struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
 
-void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver);
+void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
+                       enum wmi_phy_cap cap);
 int ath6kl_control_tx(void *devt, struct sk_buff *skb,
                      enum htc_endpoint_id eid);
 void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
index 4f3aab22008a32b6c6989185b99edb8344875ec8..ff0b999f6f668cc23ded2bf22b627126e3ff9743 100644 (file)
@@ -548,7 +548,8 @@ void ath6kl_disconnect(struct ath6kl_vif *vif)
 
 /* WMI Event handlers */
 
-void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
+void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
+                       enum wmi_phy_cap cap)
 {
        struct ath6kl *ar = devt;
 
@@ -558,6 +559,7 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
 
        ar->version.wlan_ver = sw_ver;
        ar->version.abi_ver = abi_ver;
+       ar->hw.cap = cap;
 
        snprintf(ar->wiphy->fw_version,
                 sizeof(ar->wiphy->fw_version),
index db688a2e1f6c461ea4c2e11f194b7fd0a2b5d654..2eb771aa88f31828bdf086cbb4ab3ebcc72df7df 100644 (file)
@@ -690,7 +690,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
 
        ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
                           le32_to_cpu(ev->sw_version),
-                          le32_to_cpu(ev->abi_version));
+                          le32_to_cpu(ev->abi_version), ev->phy_cap);
 
        return 0;
 }
index 190b2c4e382f4ef32d2d8a974fcdeaf81387d525..996614038fd4f0fcfbc61e8e0b004b82b70c2125 100644 (file)
@@ -1417,6 +1417,16 @@ struct wmi_ready_event_2 {
        u8 phy_cap;
 } __packed;
 
+/* WMI_PHY_CAPABILITY */
+enum wmi_phy_cap {
+       WMI_11A_CAP = 0x01,
+       WMI_11G_CAP = 0x02,
+       WMI_11AG_CAP = 0x03,
+       WMI_11AN_CAP = 0x04,
+       WMI_11GN_CAP = 0x05,
+       WMI_11AGN_CAP = 0x06,
+};
+
 /* Connect Event */
 struct wmi_connect_event {
        union {