ath9k_htc: Fix AMPDU subframe handling
authorSujith Manoharan <Sujith.Manoharan@atheros.com>
Wed, 20 Apr 2011 09:03:28 +0000 (14:33 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 25 Apr 2011 18:50:14 +0000 (14:50 -0400)
* Register the driver's maximum ampdu subframe limit to mac80211.
* Cleanup the target capabilities structure and fix an endian issue.
* Fix BTCOEX by sending a command to the target when the BT priority
  changes.
* Bump the required firmware version to 1.1

Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/hif_usb.h
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c

index f59df48a86e22de3b160df5187ef7f989e9b0ef2..9a52ccc94d12d410ab9a6695bd1d7c1e5b7cff70 100644 (file)
@@ -17,6 +17,9 @@
 #ifndef HTC_USB_H
 #define HTC_USB_H
 
+#define MAJOR_VERSION_REQ 1
+#define MINOR_VERSION_REQ 1
+
 #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
 
 #define AR9271_FIRMWARE       0x501000
index 48a885575085286bd0aae8539071152ff3e72638..af908297084523bbec0f6ada17e383751fbb4d50 100644 (file)
@@ -106,15 +106,14 @@ struct tx_beacon_header {
        u16 rev;
 } __packed;
 
+#define MAX_TX_AMPDU_SUBFRAMES_9271 17
+#define MAX_TX_AMPDU_SUBFRAMES_7010 22
+
 struct ath9k_htc_cap_target {
-       u32 flags;
-       u32 flags_ext;
-       u32 ampdu_limit;
+       __be32 ampdu_limit;
        u8 ampdu_subframes;
+       u8 enable_coex;
        u8 tx_chainmask;
-       u8 tx_chainmask_legacy;
-       u8 rtscts_ratecode;
-       u8 protmode;
        u8 pad;
 } __packed;
 
@@ -551,7 +550,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
                        enum htc_endpoint_id ep_id, bool txok);
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+                               u8 enable_coex);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_htc_ani_work(struct work_struct *work);
index 138f8e1350d4968325310490471f459e70e3953b..d051a4263e0c7c24493503d2cc2111c6e6319574 100644 (file)
@@ -65,15 +65,13 @@ static void ath_btcoex_period_work(struct work_struct *work)
        u32 timer_period;
        bool is_btscan;
        int ret;
-       u8 cmd_rsp, aggr;
 
        ath_detect_bt_priority(priv);
 
        is_btscan = !!(priv->op_flags & OP_BT_SCAN);
 
-       aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
-
-       WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
+       ret = ath9k_htc_update_cap_target(priv,
+                                 !!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
        if (ret) {
                ath_err(common, "Unable to set BTCOEX parameters\n");
                return;
index 06e043bffaf45c72376e965257aa13002bf1d887..dbf5f959cf9b1fde1f55c2a1aa597ffad2586910 100644 (file)
@@ -753,6 +753,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
        hw->queues = 4;
        hw->channel_change_time = 5000;
        hw->max_listen_interval = 10;
+
+       if (AR_SREV_9271(priv->ah))
+               hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
+       else
+               hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
+
        hw->vif_data_size = sizeof(struct ath9k_htc_vif);
        hw->sta_data_size = sizeof(struct ath9k_htc_sta);
 
@@ -802,6 +808,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
                 priv->fw_version_major,
                 priv->fw_version_minor);
 
+       /*
+        * Check if the available FW matches the driver's
+        * required version.
+        */
+       if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+           priv->fw_version_minor != MINOR_VERSION_REQ) {
+               dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+                       MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
index 7cff5547b8c0fc84fbddb5572f59fec7a0199dc7..a6402681d58d09771a0fe9c4fa9fed37287e5cf1 100644 (file)
@@ -563,7 +563,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
        return 0;
 }
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+                               u8 enable_coex)
 {
        struct ath9k_htc_cap_target tcap;
        int ret;
@@ -571,13 +572,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
 
        memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
 
-       /* FIXME: Values are hardcoded */
-       tcap.flags = 0x240c40;
-       tcap.flags_ext = 0x80601000;
-       tcap.ampdu_limit = 0xffff0000;
-       tcap.ampdu_subframes = 20;
-       tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
-       tcap.protmode = 1;
+       tcap.ampdu_limit = cpu_to_be32(0xffff);
+       tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
+       tcap.enable_coex = enable_coex;
        tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
 
        WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
@@ -936,7 +933,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
 
        ath9k_host_rx_init(priv);
 
-       ret = ath9k_htc_update_cap_target(priv);
+       ret = ath9k_htc_update_cap_target(priv, 0);
        if (ret)
                ath_dbg(common, ATH_DBG_CONFIG,
                        "Failed to update capability in target\n");