Skip to content

Commit

Permalink
ath9k_htc: Fix AMPDU subframe handling
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Apr 25, 2011
1 parent 0ff2b5c commit 3a0593e
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 20 deletions.
3 changes: 3 additions & 0 deletions drivers/net/wireless/ath/ath9k/hif_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/wireless/ath/ath9k/htc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions drivers/net/wireless/ath/ath9k/htc_drv_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}

Expand Down
15 changes: 6 additions & 9 deletions drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,21 +563,18 @@ 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;
u8 cmd_rsp;

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);
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 3a0593e

Please sign in to comment.