From 1d5cc5559aaf5273cc1f9aac9b428e3a99d41de6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Mar 2011 16:12:43 -0700 Subject: iwlwifi: remove extranious macro from firmware define define of firmware filenames use extra macro to build the files name. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-2000.c | 9 +++------ drivers/net/wireless/iwlwifi/iwl-5000.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++-------- 4 files changed, 11 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1b279929183..4323d27cc9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -57,12 +57,10 @@ #define IWL100_UCODE_API_MIN 5 #define IWL1000_FW_PRE "iwlwifi-1000-" -#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" -#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) +#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" #define IWL100_FW_PRE "iwlwifi-100-" -#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" -#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) +#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" /* diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index f602af4b940..564477d0915 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -60,16 +60,13 @@ #define IWL200_UCODE_API_MIN 5 #define IWL2030_FW_PRE "iwlwifi-2030-" -#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" -#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api) +#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" #define IWL2000_FW_PRE "iwlwifi-2000-" -#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" -#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api) +#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" #define IWL200_FW_PRE "iwlwifi-200-" -#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" -#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api) +#define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" static void iwl2000_set_ct_threshold(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 66f5fe8fe1a..4dafc58800d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -59,12 +59,10 @@ #define IWL5150_UCODE_API_MIN 1 #define IWL5000_FW_PRE "iwlwifi-5000-" -#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" -#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api) +#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" #define IWL5150_FW_PRE "iwlwifi-5150-" -#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" -#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) +#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" /* NIC configuration for 5000 series */ static void iwl5000_nic_config(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 24d105b29ae..9fb2a42e5ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -60,20 +60,16 @@ #define IWL6000G2_UCODE_API_MIN 4 #define IWL6000_FW_PRE "iwlwifi-6000-" -#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" -#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api) +#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" #define IWL6050_FW_PRE "iwlwifi-6050-" -#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" -#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) +#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" #define IWL6005_FW_PRE "iwlwifi-6000g2a-" -#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" -#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api) +#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" #define IWL6030_FW_PRE "iwlwifi-6000g2b-" -#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" -#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api) +#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { -- cgit v1.2.3-70-g09d2 From 3ecccbcd3c67374aeee447c08fcb9e39a99f7ee5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 29 Mar 2011 17:53:15 -0700 Subject: iwlagn: remove un-necessary function pointer After driver split, no need to use function pointer for those event and register dump function. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 -------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++------ drivers/net/wireless/iwlwifi/iwl-core.h | 8 ++------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 21 ++++++++------------- 8 files changed, 14 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 4323d27cc9f..cb2f87101f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -182,10 +182,6 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 564477d0915..e73ac80a721 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -262,10 +262,6 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl2030_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4dafc58800d..4c8f72a77a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -350,10 +350,6 @@ static struct iwl_lib_ops iwl5000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, @@ -406,9 +402,6 @@ static struct iwl_lib_ops iwl5150_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9fb2a42e5ea..80a335fc78c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -289,10 +289,6 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, @@ -347,10 +343,6 @@ static struct iwl_lib_ops iwl6030_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 016b79e4421..290a2081469 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -173,8 +173,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); -void iwl_dump_csr(struct iwl_priv *priv); -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c46be36b9e2..5e7281c22c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -965,12 +965,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv) IWL_ERR(priv, "Loaded firmware version: %s\n", priv->hw->wiphy->fw_version); - priv->cfg->ops->lib->dump_nic_error_log(priv); - if (priv->cfg->ops->lib->dump_csr) - priv->cfg->ops->lib->dump_csr(priv); - if (priv->cfg->ops->lib->dump_fh) - priv->cfg->ops->lib->dump_fh(priv, NULL, false); - priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); + iwl_dump_nic_error_log(priv); + iwl_dump_csr(priv); + iwl_dump_fh(priv, NULL, false); + iwl_dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) iwl_print_rx_config_cmd(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 82939f851eb..43d4c92268e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -171,12 +171,6 @@ struct iwl_lib_ops { void (*cancel_deferred_work)(struct iwl_priv *priv); /* check validity of rtc data address */ int (*is_valid_rtc_data_addr)(u32 addr); - - int (*dump_nic_event_log)(struct iwl_priv *priv, - bool full_log, char **buf, bool display); - void (*dump_nic_error_log)(struct iwl_priv *priv); - void (*dump_csr)(struct iwl_priv *priv); - int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); /* power management */ @@ -598,6 +592,8 @@ extern const struct dev_pm_ops iwl_pm_ops; void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); +void iwl_dump_csr(struct iwl_priv *priv); +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 92f6efd2c73..93a86998a3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -437,8 +437,7 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file, int pos = 0; ssize_t ret = -ENOMEM; - ret = pos = priv->cfg->ops->lib->dump_nic_event_log( - priv, true, &buf, true); + ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -462,8 +461,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, if (sscanf(buf, "%d", &event_log_flag) != 1) return -EFAULT; if (event_log_flag == 1) - priv->cfg->ops->lib->dump_nic_event_log(priv, true, - NULL, false); + iwl_dump_nic_event_log(priv, true, NULL, false); return count; } @@ -1268,8 +1266,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, if (sscanf(buf, "%d", &csr) != 1) return -EFAULT; - if (priv->cfg->ops->lib->dump_csr) - priv->cfg->ops->lib->dump_csr(priv); + iwl_dump_csr(priv); return count; } @@ -1359,13 +1356,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, int pos = 0; ssize_t ret = -EFAULT; - if (priv->cfg->ops->lib->dump_fh) { - ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); - if (buf) { - ret = simple_read_from_buffer(user_buf, - count, ppos, buf, pos); - kfree(buf); - } + ret = pos = iwl_dump_fh(priv, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, + count, ppos, buf, pos); + kfree(buf); } return ret; -- cgit v1.2.3-70-g09d2 From 68b993118f715cc631b62b6a50574e4701fe9ace Mon Sep 17 00:00:00 2001 From: Garen Tamrazian Date: Wed, 30 Mar 2011 02:29:32 -0700 Subject: iwlagn: fix radar frame rejection The microcode may sometimes reject TX frames when on a radar channel even after we associated as it clears information during association and needs to receive a new beacon before allowing that channel again. This manifests itself as a TX status value of TX_STATUS_FAIL_PASSIVE_NO_RX. So in this case, stop the corresponding queue and give the frame back to mac80211 for retransmission. We start the queue again when a beacon from the AP is received which will make the regulatory enforcement in the device allow transmitting again. Signed-off-by: Garen Tamrazian Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 29 ++++++++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 13 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-helpers.h | 13 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-rx.c | 21 ++++++++++++++++++++ 7 files changed, 74 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9e47be6a739..cccf7471c00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -172,6 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, + struct iwl_rxon_context *ctx, struct iwlagn_tx_resp *tx_resp, int txq_id, bool is_agg) { @@ -186,6 +187,13 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, if (!iwl_is_tx_success(status)) iwlagn_count_tx_err_status(priv, status); + if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && + iwl_is_associated_ctx(ctx) && ctx->vif && + ctx->vif->type == NL80211_IFTYPE_STATION) { + ctx->last_tx_rejected = true; + iwl_stop_queue(priv, &priv->txq[txq_id]); + } + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " "0x%x retries %d\n", txq_id, @@ -242,15 +250,16 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, /* # frames attempted by Tx command */ if (agg->frame_count == 1) { + struct iwl_tx_info *txb; + /* Only one frame was attempted; no block-ack will arrive */ idx = start_idx; IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - iwlagn_set_tx_status(priv, - IEEE80211_SKB_CB( - priv->txq[txq_id].txb[idx].skb), - tx_resp, txq_id, true); + txb = &priv->txq[txq_id].txb[idx]; + iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb), + txb->ctx, tx_resp, txq_id, true); agg->wait_for_ba = 0; } else { /* Two or more frames were attempted; expect block-ack */ @@ -391,7 +400,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_info *info; struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le16_to_cpu(tx_resp->status.status); + struct iwl_tx_info *txb; + u32 status = le16_to_cpu(tx_resp->status.status); int tid; int sta_id; int freed; @@ -406,7 +416,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, } txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + txb = &txq->txb[txq->q.read_ptr]; + info = IEEE80211_SKB_CB(txb->skb); memset(&info->status, 0, sizeof(info->status)); tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> @@ -450,12 +461,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, iwl_wake_queue(priv, txq); } } else { - iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); + iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp, + txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark)) + iwl_queue_space(&txq->q) > txq->q.low_mark && + status != TX_STATUS_FAIL_PASSIVE_NO_RX) iwl_wake_queue(priv, txq); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c335ee6883e..56f46ee3bac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -29,6 +29,7 @@ #include "iwl-sta.h" #include "iwl-core.h" #include "iwl-agn-calib.h" +#include "iwl-helpers.h" static int iwlagn_disable_bss(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -600,6 +601,18 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, priv->timestamp = bss_conf->timestamp; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { + /* + * If we disassociate while there are pending + * frames, just wake up the queues and let the + * frames "escape" ... This shouldn't really + * be happening to start with, but we should + * not get stuck in this case either since it + * can happen if userspace gets confused. + */ + if (ctx->last_tx_rejected) { + ctx->last_tx_rejected = false; + iwl_wake_any_queue(priv, ctx); + } ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 01a6d2fc795..5c30f6b19a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -428,6 +428,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { const struct queue_to_fifo_ac *queue_to_fifo; + struct iwl_rxon_context *ctx; u32 a; unsigned long flags; int i, chan; @@ -501,6 +502,8 @@ int iwlagn_alive_notify(struct iwl_priv *priv) memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); for (i = 0; i < 4; i++) atomic_set(&priv->queue_stop_count[i], 0); + for_each_context(priv, ctx) + ctx->last_tx_rejected = false; /* reset to 0 to enable all the queue first */ priv->txq_ctx_active_msk = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 290a2081469..078a23e5d99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -220,6 +220,7 @@ static inline u32 iwl_tx_status_to_mac80211(u32 status) case TX_STATUS_DIRECT_DONE: return IEEE80211_TX_STAT_ACK; case TX_STATUS_FAIL_DEST_PS: + case TX_STATUS_FAIL_PASSIVE_NO_RX: return IEEE80211_TX_STAT_TX_FILTERED; default: return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 72133368c1f..14f7d8fb688 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1170,6 +1170,8 @@ struct iwl_rxon_context { bool enabled, is_40mhz; u8 extension_chan_offset; } ht; + + bool last_tx_rejected; }; enum iwl_scan_type { diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 5da5761c74b..9309ff2df4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -131,6 +131,19 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, ieee80211_stop_queue(priv->hw, ac); } +static inline void iwl_wake_any_queue(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + u8 ac; + + for (ac = 0; ac < AC_NUM; ac++) { + IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n", + ac, (atomic_read(&priv->queue_stop_count[ac]) > 0) + ? "stopped" : "awake"); + iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]); + } +} + #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c421f566982..4472761fc59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -873,6 +873,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, { struct sk_buff *skb; __le16 fc = hdr->frame_control; + struct iwl_rxon_context *ctx; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -895,6 +896,26 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); iwl_update_stats(priv, false, fc, len); + + /* + * Wake any queues that were stopped due to a passive channel tx + * failure. This can happen because the regulatory enforcement in + * the device waits for a beacon before allowing transmission, + * sometimes even after already having transmitted frames for the + * association because the new RXON may reset the information. + */ + if (unlikely(ieee80211_is_beacon(fc))) { + for_each_context(priv, ctx) { + if (!ctx->last_tx_rejected) + continue; + if (compare_ether_addr(hdr->addr3, + ctx->active.bssid_addr)) + continue; + ctx->last_tx_rejected = false; + iwl_wake_any_queue(priv, ctx); + } + } + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); -- cgit v1.2.3-70-g09d2 From a2b76b3b31568da9d281a393845f17689594ccdf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 29 Mar 2011 06:29:37 -0700 Subject: iwlwifi: fix bugs in change_interface If change_interface gets invoked during a firmware restart, it may crash; prevent that from happening by checking if ctx->vif is assigned. Additionally, in my initial commit I forgot to set the vif->p2p variable correctly, so fix that too. Cc: stable@kernel.org [2.6.38+] Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5e7281c22c0..b5a06549b2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1775,6 +1775,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&priv->mutex); + if (!ctx->vif || !iwl_is_ready_rf(priv)) { + /* + * Huh? But wait ... this can maybe happen when + * we're in the middle of a firmware restart! + */ + err = -EBUSY; + goto out; + } + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; if (!(interface_modes & BIT(newtype))) { @@ -1802,6 +1811,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* success */ iwl_teardown_interface(priv, vif, true); vif->type = newtype; + vif->p2p = newp2p; err = iwl_setup_interface(priv, ctx); WARN_ON(err); /* -- cgit v1.2.3-70-g09d2 From dcf6640f0f58affa93f158d8573b6868136e3d62 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 13:20:44 -0700 Subject: iwlagn: PAPD read for 2000 series devices For 2000 series NICs, disable OTP refresh in order to read correct PAPD table from high OTP block Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e73ac80a721..86d7ffd6e38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -98,6 +98,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) iwl_set_bit(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); + if (priv->cfg->disable_otp_refresh) + iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010); } static struct iwl_sensitivity_ranges iwl2000_sensitivity = { @@ -409,7 +411,8 @@ static struct iwl_bt_params iwl2030_bt_params = { .need_dc_calib = true, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ - .iq_invert = true \ + .iq_invert = true, \ + .disable_otp_refresh = true \ struct iwl_cfg iwl2000_2bgn_cfg = { .name = "2000 Series 2x2 BGN", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 43d4c92268e..10a6f856356 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -331,6 +331,7 @@ struct iwl_ht_params { * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device * @iq_invert: I/Q inversion + * @disable_otp_refresh: disable OTP refresh current limit * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -381,6 +382,7 @@ struct iwl_cfg { const bool rx_with_siso_diversity; const bool internal_wimax_coex; const bool iq_invert; + const bool disable_otp_refresh; }; /*************************** -- cgit v1.2.3-70-g09d2 From ece3cd2e8fb119a4394dcdc6ef921e85cdd4cc69 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:47 -0700 Subject: iwlagn: no 3945 define needed Remove 3945 define Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 69a29932bab..bdae82e7fa9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -83,7 +83,6 @@ enum { enum { IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, - IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, -- cgit v1.2.3-70-g09d2 From ab4bf5ef5afce9d31cf5cf05ac80b3b01cbb24a3 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:35:09 -0700 Subject: iwlagn: remove unused 3945 define 3945 no longer apply Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-fh.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index da06d136a35..0f1052f80a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -424,7 +424,6 @@ #define RX_LOW_WATERMARK 8 /* Size of one Rx buffer in host DRAM */ -#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */ #define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024) @@ -443,7 +442,7 @@ struct iwl_rb_status { __le16 closed_fr_num; __le16 finished_rb_num; __le16 finished_fr_nam; - __le32 __unused; /* 3945 only */ + __le32 __unused; } __packed; -- cgit v1.2.3-70-g09d2 From ee3cd7e04ca08ff0ec1ebb96be7e64aef928f511 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:35:10 -0700 Subject: iwlagn: cleanup to remove the reference for 3945 More clean up after driver split Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b5a06549b2a..4c764996098 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1049,7 +1049,6 @@ int iwl_apm_init(struct iwl_priv *priv) /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s - * NOTE: This is no-op for 3945 (non-existant bit) */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); -- cgit v1.2.3-70-g09d2 From 6bb64697ed58909985487e885c269dafd09583f1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:50 -0700 Subject: iwlagn: remove more reference to legacy devices Remove the reference to both 3945 and 4965 in LED code Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-led.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index c2862d4e00e..0d90004e8b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -63,8 +63,8 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* * Adjust led blink rate to compensate on a MAC Clock difference on every HW - * Led blink rate analysis showed an average deviation of 0% on 3945, - * 5% on 4965 HW and 20% on 5000 series and up. + * Led blink rate analysis showed an average deviation of 20% on 5000 series + * and up. * Need to compensate on the led on/off time per HW according to the deviation * to achieve the desired led frequency * The calculation is: (100-averageDeviation)/100 * blinkTime -- cgit v1.2.3-70-g09d2 From 15ade3ca647d95611814333cfe0885fd0184481e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:51 -0700 Subject: iwlagn: remove un-needed configuration After driver split, set_l0s config is no longer needed, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.c | 26 ++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 12 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cb2f87101f9..5a7281047a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -235,7 +235,6 @@ static struct iwl_base_params iwl1000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .eeprom_size = OTP_LOW_IMAGE_SIZE, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, .led_compensation = 51, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 86d7ffd6e38..9daf888b733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -343,7 +343,6 @@ static struct iwl_base_params iwl2000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 51, @@ -366,7 +365,6 @@ static struct iwl_base_params iwl2030_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4c8f72a77a7..8106423a2c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -464,7 +464,6 @@ static struct iwl_base_params iwl5000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 80a335fc78c..7f0715eb059 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -432,7 +432,6 @@ static struct iwl_base_params iwl6000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 51, @@ -454,7 +453,6 @@ static struct iwl_base_params iwl6050_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, @@ -475,7 +473,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4c764996098..0e98a8703e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1061,20 +1061,18 @@ int iwl_apm_init(struct iwl_priv *priv) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (priv->cfg->base_params->set_l0s) { - lctl = iwl_pcie_link_ctl(priv); - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); - } + lctl = iwl_pcie_link_ctl(priv); + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); } /* Configure analog phase-lock-loop before activating to D0A */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 10a6f856356..7d303acc837 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -265,7 +265,6 @@ struct iwl_base_params { int num_of_ampdu_queues;/* def: HW dependent */ /* for iwl_apm_init() */ u32 pll_cfg_val; - bool set_l0s; const u16 max_ll_items; const bool shadow_ram_support; -- cgit v1.2.3-70-g09d2 From 8ff84a2c99bc7f5f22d9d2b5365d821ce4f7a8f9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:52 -0700 Subject: iwlagn: more cleanup to remove unused reference More cleanup code, no functional changes Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-fh.h | 35 ++++++++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-prph.h | 16 +++------------ drivers/net/wireless/iwlwifi/iwl-tx.c | 1 - 3 files changed, 20 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 0f1052f80a5..b90924e890a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -77,14 +77,14 @@ /** * Keep-Warm (KW) buffer base address. * - * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the + * Driver must allocate a 4KByte buffer that is for keeping the * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency - * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host + * DRAM access when doing Txing or Rxing. The dummy accesses prevent host * from going into a power-savings mode that would cause higher DRAM latency, * and possible data over/under-runs, before all Tx/Rx is complete. * * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) - * of the buffer, which must be 4K aligned. Once this is set up, the 4965 + * of the buffer, which must be 4K aligned. Once this is set up, the device * automatically invokes keep-warm accesses when normal accesses might not * be sufficient to maintain fast DRAM response. * @@ -97,7 +97,7 @@ /** * TFD Circular Buffers Base (CBBC) addresses * - * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident + * Device has 16 base pointer registers, one for each of 16 host-DRAM-resident * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte @@ -116,16 +116,16 @@ /** * Rx SRAM Control and Status Registers (RSCSR) * - * These registers provide handshake between driver and 4965 for the Rx queue + * These registers provide handshake between driver and device for the Rx queue * (this queue handles *all* command responses, notifications, Rx data, etc. - * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx + * sent from uCode to host driver). Unlike Tx, there is only one Rx * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 * mapping between RBDs and RBs. * * Driver must allocate host DRAM memory for the following, and set the - * physical address of each into 4965 registers: + * physical address of each into device registers: * * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 * entries (although any power of 2, up to 4096, is selectable by driver). @@ -140,20 +140,20 @@ * Driver sets physical address [35:8] of base of RBD circular buffer * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. * - * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers + * 2) Rx status buffer, 8 bytes, in which uCode indicates which Rx Buffers * (RBs) have been filled, via a "write pointer", actually the index of * the RB's corresponding RBD within the circular buffer. Driver sets * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. * * Bit fields in lower dword of Rx status buffer (upper dword not used - * by driver; see struct iwl4965_shared, val0): + * by driver: * 31-12: Not used by driver * 11- 0: Index of last filled Rx buffer descriptor - * (4965 writes, driver reads this value) + * (device writes, driver reads this value) * - * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must + * As the driver prepares Receive Buffers (RBs) for device to fill, driver must * enter pointers to these RBs into contiguous RBD circular buffer entries, - * and update the 4965's "write" index register, + * and update the device's "write" index register, * FH_RSCSR_CHNL0_RBDCB_WPTR_REG. * * This "write" index corresponds to the *next* RBD that the driver will make @@ -162,12 +162,12 @@ * RBs), should be 8 after preparing the first 8 RBs (for example), and must * wrap back to 0 at the end of the circular buffer (but don't wrap before * "read" index has advanced past 1! See below). - * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. + * NOTE: DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. * - * As the 4965 fills RBs (referenced from contiguous RBDs within the circular + * As the device fills RBs (referenced from contiguous RBDs within the circular * buffer), it updates the Rx status buffer in host DRAM, 2) described above, * to tell the driver the index of the latest filled RBD. The driver must - * read this "read" index from DRAM after receiving an Rx interrupt from 4965. + * read this "read" index from DRAM after receiving an Rx interrupt from device * * The driver must also internally keep track of a third index, which is the * next RBD to process. When receiving an Rx interrupt, driver should process @@ -176,7 +176,7 @@ * driver may process the RB pointed to by RBD 0. Depending on volume of * traffic, there may be many RBs to process. * - * If read index == write index, 4965 thinks there is no room to put new data. + * If read index == write index, device thinks there is no room to put new data. * Due to this, the maximum number of filled RBs is 255, instead of 256. To * be safe, make sure that there is a gap of at least 2 RBDs between "write" * and "read" indexes; that is, make sure that there are no more than 254 @@ -303,7 +303,7 @@ /** * Transmit DMA Channel Control/Status Registers (TCSR) * - * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels + * Device has one configuration register for each of 8 Tx DMA/FIFO channels * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. * @@ -326,7 +326,6 @@ #define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) /* Find Control/Status reg for given Tx DMA/FIFO channel */ -#define FH49_TCSR_CHNL_NUM (7) #define FH50_TCSR_CHNL_NUM (8) /* TCSR: tx_config register values */ diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index c960195df98..f00d188b2cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -107,17 +107,7 @@ * device. A queue maps to only one (selectable by driver) Tx DMA channel, * but one DMA channel may take input from several queues. * - * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows - * (cf. default_queue_to_tx_fifo in iwl-4965.c): - * - * 0 -- EDCA BK (background) frames, lowest priority - * 1 -- EDCA BE (best effort) frames, normal priority - * 2 -- EDCA VI (video) frames, higher priority - * 3 -- EDCA VO (voice) and management frames, highest priority - * 4 -- Commands (e.g. RXON, etc.) - * 5 -- unused (HCCA) - * 6 -- unused (HCCA) - * 7 -- not used by driver (device-internal only) + * Tx DMA FIFOs have dedicated purposes. * * For 5000 series and up, they are used differently * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): @@ -151,7 +141,7 @@ * Tx completion may end up being out-of-order). * * The driver must maintain the queue's Byte Count table in host DRAM - * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. + * for this mode. * This mode does not support fragmentation. * * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. @@ -164,7 +154,7 @@ * * Driver controls scheduler operation via 3 means: * 1) Scheduler registers - * 2) Shared scheduler data base in internal 4956 SRAM + * 2) Shared scheduler data base in internal SRAM * 3) Shared data in host DRAM * * Initialization: diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 565980fbb59..3732380c4ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -232,7 +232,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * - * See more detailed info in iwl-4965-hw.h. ***************************************************/ int iwl_queue_space(const struct iwl_queue *q) -- cgit v1.2.3-70-g09d2 From 23c0fcc66b4345ea97ae588c2e01f10c994652ba Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:53 -0700 Subject: iwlagn: all _agn devices support power save mode Remove broken_power_save checking Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++----- drivers/net/wireless/iwlwifi/iwl-power.c | 4 +--- 4 files changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 60bfde75ce8..23b89c2e71d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2828,9 +2828,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; - if (!priv->cfg->base_params->broken_powersave) - hw->flags |= IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; if (priv->cfg->sku & IWL_SKU_N) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7d303acc837..a0530d03b30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -269,7 +269,6 @@ struct iwl_base_params { const u16 max_ll_items; const bool shadow_ram_support; u16 led_compensation; - const bool broken_powersave; int chain_noise_num_beacons; bool adv_thermal_throttle; bool support_ct_kill_exit; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 93a86998a3b..2c58980f2d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1723,11 +1723,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); - if (!priv->cfg->base_params->broken_powersave) { - DEBUGFS_ADD_FILE(sleep_level_override, dir_data, - S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); - } + DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c43c8e66de7..ae176d8da9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -354,9 +354,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->cfg->base_params->broken_powersave) - iwl_power_sleep_cam_cmd(priv, cmd); - else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) + if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && priv->cfg->ops->lib->tt_ops.tt_power_mode && -- cgit v1.2.3-70-g09d2 From ae89726a02049e8f61bb3c8bf5dbf1fc06527a07 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:54 -0700 Subject: iwlagn: tx power calib always done in firmware Remove the config flag for tx power calib Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-core.h | 3 --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index cccf7471c00..bc5dfe2978f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -495,8 +495,10 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) void iwlagn_setup_deferred_work(struct iwl_priv *priv) { - /* in agn, the tx power calibration is done in uCode */ - priv->disable_tx_power_cal = 1; + /* + * nothing need to be done here anymore + * still keep for future use if needed + */ } int iwlagn_hw_valid_rtc_data_addr(u32 addr) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a0530d03b30..98dc544f112 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -250,8 +250,6 @@ struct iwl_mod_params { * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging - * @tx_power_by_driver: tx power calibration performed by driver - * instead of uCode * @ucode_tracing: support ucode continuous tracing * @sensitivity_calib_by_driver: driver has the capability to perform * sensitivity calibration operation @@ -278,7 +276,6 @@ struct iwl_base_params { unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; - const bool tx_power_by_driver; const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 2c58980f2d0..9b1f9621b63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1767,9 +1767,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &priv->disable_chain_noise_cal); - if (priv->cfg->base_params->tx_power_by_driver) - DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, - &priv->disable_tx_power_cal); return 0; err: diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 14f7d8fb688..7fe68f8dd21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1489,7 +1489,6 @@ struct iwl_priv { struct work_struct txpower_work; u32 disable_sens_cal; u32 disable_chain_noise_cal; - u32 disable_tx_power_cal; struct work_struct run_time_calib_work; struct timer_list statistics_periodic; struct timer_list ucode_trace; -- cgit v1.2.3-70-g09d2 From 703bc583cb98a24eeedd297ee59dfa12852897d1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 3 Apr 2011 08:14:41 -0700 Subject: iwlagn: sensitivity and chain noise done by driver _agn driver should perform both sensitivity and chain noise calib. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-core.h | 6 ------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 16 ++++++---------- 6 files changed, 6 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5a7281047a1..d1d7852f0ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -245,8 +245,6 @@ static struct iwl_base_params iwl1000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 9daf888b733..805b0394850 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -354,8 +354,6 @@ static struct iwl_base_params iwl2000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; @@ -376,8 +374,6 @@ static struct iwl_base_params iwl2030_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8106423a2c8..357137f0863 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -471,8 +471,6 @@ static struct iwl_base_params iwl5000_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 7f0715eb059..8847b211397 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -443,8 +443,6 @@ static struct iwl_base_params iwl6000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; @@ -464,8 +462,6 @@ static struct iwl_base_params iwl6050_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; static struct iwl_base_params iwl6000_g2_base_params = { @@ -484,8 +480,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 98dc544f112..57763c013ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -251,10 +251,6 @@ struct iwl_mod_params { * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging * @ucode_tracing: support ucode continuous tracing - * @sensitivity_calib_by_driver: driver has the capability to perform - * sensitivity calibration operation - * @chain_noise_calib_by_driver: driver has the capability to perform - * chain noise calibration operation * @shadow_reg_enable: HW shadhow register bit */ struct iwl_base_params { @@ -277,8 +273,6 @@ struct iwl_base_params { bool temperature_kelvin; u32 max_event_log_size; const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; const bool shadow_reg_enable; }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9b1f9621b63..c02f06901f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1747,10 +1747,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->base_params->sensitivity_calib_by_driver) - DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (priv->cfg->base_params->chain_noise_calib_by_driver) - DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); if (iwl_bt_statistics(priv)) @@ -1761,12 +1759,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); - if (priv->cfg->base_params->sensitivity_calib_by_driver) - DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, - &priv->disable_sens_cal); - if (priv->cfg->base_params->chain_noise_calib_by_driver) - DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, - &priv->disable_chain_noise_cal); + DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, + &priv->disable_sens_cal); + DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, + &priv->disable_chain_noise_cal); return 0; err: -- cgit v1.2.3-70-g09d2 From 0da0e5bf1522d75d446f5124e17016628d0a149e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 Apr 2011 08:14:56 -0700 Subject: iwlagn: clean up & autodetect statistics There's no need to keep both normal and BT statistics versions around all the time in memory when we only use a subset of both. So keep only the subsets that we need in memory, depending on the debug config). Also, in doing so, we can remove all the calls to iwl_bt_statistics() in the driver as we'll just access the copied statistics now. Finally, also remove this call from the one place where it might still be needed and automatically detect what kind of statistics the device is sending based on their size. This way, we don't need to keep track of which devices do what any more, which is good since this is subject to change based on the ucode version (as some ucode even for non-BT devices will in fact use BT statistics). Warn upon encountering a statistics command from the ucode that isn't known, so we will find such issues earlier in the future. Signed-off-by: Johannes Berg Tested-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 43 +--- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 134 ++++------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 17 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 64 ------ drivers/net/wireless/iwlwifi/iwl-core.h | 7 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 41 ++-- drivers/net/wireless/iwlwifi/iwl-rx.c | 298 +++++++++++++------------ 13 files changed, 243 insertions(+), 376 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 805b0394850..a31314fdb05 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -383,7 +383,6 @@ static struct iwl_ht_params iwl2000_ht_params = { }; static struct iwl_bt_params iwl2030_bt_params = { - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 357137f0863..7c286662d26 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -259,7 +259,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) u32 vt = 0; s32 offset = iwl_temp_calib_to_offset(priv); - vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); + vt = le32_to_cpu(priv->statistics.common.temperature); vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; /* now vt hold the temperature in Kelvin */ priv->temperature = KELVIN_TO_CELSIUS(vt); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8847b211397..064981345c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -489,7 +489,6 @@ static struct iwl_ht_params iwl6000_ht_params = { }; static struct iwl_bt_params iwl6000_bt_params = { - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 7b761de77b0..0f6bb9b2e64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "<lock, flags); - if (iwl_bt_statistics(priv)) { - rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> - rx.general.common); - ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); - } else { - rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); - ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); - } + rx_info = &priv->statistics.rx_non_phy; + ofdm = &priv->statistics.rx_ofdm; + cck = &priv->statistics.rx_cck; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. */ -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) +void iwl_chain_noise_calibration(struct iwl_priv *priv) { struct iwl_chain_noise_data *data = NULL; @@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (iwl_bt_statistics(priv)) { - rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> - rx.general.common); - } else { - rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> - rx.general); - } + + rx_info = &priv->statistics.rx_non_phy; + if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(ctx->staging.channel); - if (iwl_bt_statistics(priv)) { - stat_band24 = !!(((struct iwl_bt_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) - stat_resp)->flag) >> 16; - } else { - stat_band24 = !!(((struct iwl_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) - stat_resp)->flag) >> 16; - } + stat_band24 = + !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16; /* Make sure we accumulate data for just the associated channel * (even if scanning). */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index ef4d5079a7e..4ef4dd93425 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -66,8 +66,8 @@ #include "iwl-core.h" #include "iwl-commands.h" -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); -void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); +void iwl_chain_noise_calibration(struct iwl_priv *priv); +void iwl_sensitivity_calibration(struct iwl_priv *priv); void iwl_init_sensitivity(struct iwl_priv *priv); void iwl_reset_run_time_calib(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index d1834aa7edf..71a5f31cd7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -39,10 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; - if (iwl_bt_statistics(priv)) - flag = le32_to_cpu(priv->_agn.statistics_bt.flag); - else - flag = le32_to_cpu(priv->_agn.statistics.flag); + flag = le32_to_cpu(priv->statistics.flag); p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); if (flag & UCODE_STATISTICS_CLEAR_MSK) @@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (iwl_bt_statistics(priv)) { - ofdm = &priv->_agn.statistics_bt.rx.ofdm; - cck = &priv->_agn.statistics_bt.rx.cck; - general = &priv->_agn.statistics_bt.rx.general.common; - ht = &priv->_agn.statistics_bt.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; - accum_general = - &priv->_agn.accum_statistics_bt.rx.general.common; - accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; - delta_general = - &priv->_agn.delta_statistics_bt.rx.general.common; - delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; - max_cck = &priv->_agn.max_delta_bt.rx.cck; - max_general = &priv->_agn.max_delta_bt.rx.general.common; - max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; - } else { - ofdm = &priv->_agn.statistics.rx.ofdm; - cck = &priv->_agn.statistics.rx.cck; - general = &priv->_agn.statistics.rx.general; - ht = &priv->_agn.statistics.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics.rx.cck; - accum_general = &priv->_agn.accum_statistics.rx.general; - accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics.rx.cck; - delta_general = &priv->_agn.delta_statistics.rx.general; - delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta.rx.ofdm; - max_cck = &priv->_agn.max_delta.rx.cck; - max_general = &priv->_agn.max_delta.rx.general; - max_ht = &priv->_agn.max_delta.rx.ofdm_ht; - } + ofdm = &priv->statistics.rx_ofdm; + cck = &priv->statistics.rx_cck; + general = &priv->statistics.rx_non_phy; + ht = &priv->statistics.rx_ofdm_ht; + accum_ofdm = &priv->accum_stats.rx_ofdm; + accum_cck = &priv->accum_stats.rx_cck; + accum_general = &priv->accum_stats.rx_non_phy; + accum_ht = &priv->accum_stats.rx_ofdm_ht; + delta_ofdm = &priv->delta_stats.rx_ofdm; + delta_cck = &priv->delta_stats.rx_cck; + delta_general = &priv->delta_stats.rx_non_phy; + delta_ht = &priv->delta_stats.rx_ofdm_ht; + max_ofdm = &priv->max_delta_stats.rx_ofdm; + max_cck = &priv->max_delta_stats.rx_cck; + max_general = &priv->max_delta_stats.rx_non_phy; + max_ht = &priv->max_delta_stats.rx_ofdm_ht; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, } /* the statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - if (iwl_bt_statistics(priv)) { - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta_tx = &priv->_agn.delta_statistics_bt.tx; - max_tx = &priv->_agn.max_delta_bt.tx; - } else { - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta_tx = &priv->_agn.delta_statistics.tx; - max_tx = &priv->_agn.max_delta.tx; - } + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + tx = &priv->statistics.tx; + accum_tx = &priv->accum_stats.tx; + delta_tx = &priv->delta_stats.tx; + max_tx = &priv->max_delta_stats.tx; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, } /* the statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - if (iwl_bt_statistics(priv)) { - general = &priv->_agn.statistics_bt.general.common; - dbg = &priv->_agn.statistics_bt.general.common.dbg; - div = &priv->_agn.statistics_bt.general.common.div; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; - accum_div = &priv->_agn.accum_statistics_bt.general.common.div; - delta_general = &priv->_agn.delta_statistics_bt.general.common; - max_general = &priv->_agn.max_delta_bt.general.common; - delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; - max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; - delta_div = &priv->_agn.delta_statistics_bt.general.common.div; - max_div = &priv->_agn.max_delta_bt.general.common.div; - } else { - general = &priv->_agn.statistics.general.common; - dbg = &priv->_agn.statistics.general.common.dbg; - div = &priv->_agn.statistics.general.common.div; - accum_general = &priv->_agn.accum_statistics.general.common; - accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; - accum_div = &priv->_agn.accum_statistics.general.common.div; - delta_general = &priv->_agn.delta_statistics.general.common; - max_general = &priv->_agn.max_delta.general.common; - delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; - max_dbg = &priv->_agn.max_delta.general.common.dbg; - delta_div = &priv->_agn.delta_statistics.general.common.div; - max_div = &priv->_agn.max_delta.general.common.div; - } + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + general = &priv->statistics.common; + dbg = &priv->statistics.common.dbg; + div = &priv->statistics.common.div; + accum_general = &priv->accum_stats.common; + accum_dbg = &priv->accum_stats.common.dbg; + accum_div = &priv->accum_stats.common.div; + delta_general = &priv->delta_stats.common; + max_general = &priv->max_delta_stats.common; + delta_dbg = &priv->delta_stats.common.dbg; + max_dbg = &priv->max_delta_stats.common.dbg; + delta_div = &priv->delta_stats.common.div; + max_div = &priv->max_delta_stats.common.div; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - bt = &priv->_agn.statistics_bt.general.activity; - accum_bt = &priv->_agn.accum_statistics_bt.general.activity; + bt = &priv->statistics.bt_activity; + accum_bt = &priv->accum_stats.bt_activity; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); @@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", - le32_to_cpu(priv->_agn.statistics_bt.rx. - general.num_bt_kills), - priv->_agn.accum_statistics_bt.rx. - general.num_bt_kills); + le32_to_cpu(priv->statistics.num_bt_kills), + priv->statistics.accum_num_bt_kills); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index bc5dfe2978f..e741128842b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -549,9 +549,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv) { /* store temperature from correct statistics (in Celsius) */ - priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? - priv->_agn.statistics_bt.general.common.temperature : - priv->_agn.statistics.general.common.temperature); + priv->temperature = le32_to_cpu(priv->statistics.common.temperature); iwl_tt_handler(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 23b89c2e71d..20499b76443 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1705,10 +1705,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) else priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS || - (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)) - priv->bt_statistics = true; - /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -2626,17 +2622,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (iwl_bt_statistics(priv)) { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics_bt); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics_bt); - } else { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics); - } + iwl_chain_noise_calibration(priv); + iwl_sensitivity_calibration(priv); } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index a1a5c1b2309..0edba8a6419 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2535,53 +2535,6 @@ struct rate_histogram { /* statistics command response */ -struct iwl39_statistics_rx_phy { - __le32 ina_cnt; - __le32 fina_cnt; - __le32 plcp_err; - __le32 crc32_err; - __le32 overrun_err; - __le32 early_overrun_err; - __le32 crc32_good; - __le32 false_alarm_cnt; - __le32 fina_sync_err_cnt; - __le32 sfd_timeout; - __le32 fina_timeout; - __le32 unresponded_rts; - __le32 rxe_frame_limit_overrun; - __le32 sent_ack_cnt; - __le32 sent_cts_cnt; -} __packed; - -struct iwl39_statistics_rx_non_phy { - __le32 bogus_cts; /* CTS received when not expecting CTS */ - __le32 bogus_ack; /* ACK received when not expecting ACK */ - __le32 non_bssid_frames; /* number of frames with BSSID that - * doesn't belong to the STA BSSID */ - __le32 filtered_frames; /* count frames that were dumped in the - * filtering process */ - __le32 non_channel_beacons; /* beacons with our bss id but not on - * our serving channel */ -} __packed; - -struct iwl39_statistics_rx { - struct iwl39_statistics_rx_phy ofdm; - struct iwl39_statistics_rx_phy cck; - struct iwl39_statistics_rx_non_phy general; -} __packed; - -struct iwl39_statistics_tx { - __le32 preamble_cnt; - __le32 rx_detected_cnt; - __le32 bt_prio_defer_cnt; - __le32 bt_prio_kill_cnt; - __le32 few_bytes_cnt; - __le32 cts_timeout; - __le32 ack_timeout; - __le32 expected_ack_cnt; - __le32 actual_ack_cnt; -} __packed; - struct statistics_dbg { __le32 burst_check; __le32 burst_count; @@ -2589,23 +2542,6 @@ struct statistics_dbg { __le32 reserved[3]; } __packed; -struct iwl39_statistics_div { - __le32 tx_on_a; - __le32 tx_on_b; - __le32 exec_time; - __le32 probe_time; -} __packed; - -struct iwl39_statistics_general { - __le32 temperature; - struct statistics_dbg dbg; - __le32 sleep_time; - __le32 slots_out; - __le32 slots_idle; - __le32 ttl_timestamp; - struct iwl39_statistics_div div; -} __packed; - struct statistics_rx_phy { __le32 ina_cnt; __le32 fina_cnt; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 57763c013ca..6988335328e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -279,7 +279,6 @@ struct iwl_base_params { * @advanced_bt_coexist: support advanced bt coexist * @bt_init_traffic_load: specify initial bt traffic load * @bt_prio_boost: default bt priority boost value - * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation * @ampdu_factor: Maximum A-MPDU length factor * @ampdu_density: Minimum A-MPDU spacing @@ -289,7 +288,6 @@ struct iwl_bt_params { bool advanced_bt_coexist; u8 bt_init_traffic_load; u8 bt_prio_boost; - const bool bt_statistics; u16 agg_time_limit; u8 ampdu_factor; u8 ampdu_density; @@ -696,11 +694,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist; } -static inline bool iwl_bt_statistics(struct iwl_priv *priv) -{ - return priv->bt_statistics; -} - extern bool bt_coex_active; extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index c02f06901f8..897efacb96e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1751,8 +1751,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (iwl_bt_statistics(priv)) - DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7fe68f8dd21..e84534c4d95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -543,13 +543,12 @@ enum iwl_ucode_tlv_type { * enum iwl_ucode_tlv_flag - ucode API flags * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which - * may be true even if the device doesn't have BT. + * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). */ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1), + IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1), IWL_UCODE_TLV_FLAGS_MFP = BIT(2), }; @@ -1356,6 +1355,31 @@ struct iwl_priv { /* Last Rx'd beacon timestamp */ u64 timestamp; + struct { + __le32 flag; + struct statistics_general_common common; + struct statistics_rx_non_phy rx_non_phy; + struct statistics_rx_phy rx_ofdm; + struct statistics_rx_ht_phy rx_ofdm_ht; + struct statistics_rx_phy rx_cck; + struct statistics_tx tx; +#ifdef CONFIG_IWLWIFI_DEBUGFS + struct statistics_bt_activity bt_activity; + __le32 num_bt_kills, accum_num_bt_kills; +#endif + } statistics; +#ifdef CONFIG_IWLWIFI_DEBUGFS + struct { + struct statistics_general_common common; + struct statistics_rx_non_phy rx_non_phy; + struct statistics_rx_phy rx_ofdm; + struct statistics_rx_ht_phy rx_ofdm_ht; + struct statistics_rx_phy rx_cck; + struct statistics_tx tx; + struct statistics_bt_activity bt_activity; + } accum_stats, delta_stats, max_delta_stats; +#endif + struct { /* INT ICT Table */ __le32 *ict_tbl; @@ -1387,19 +1411,9 @@ struct iwl_priv { u8 phy_calib_chain_noise_reset_cmd; u8 phy_calib_chain_noise_gain_cmd; - struct iwl_notif_statistics statistics; - struct iwl_bt_notif_statistics statistics_bt; /* counts reply_tx error */ struct reply_tx_error_statistics reply_tx_stats; struct reply_agg_tx_error_statistics reply_agg_tx_stats; -#ifdef CONFIG_IWLWIFI_DEBUGFS - struct iwl_notif_statistics accum_statistics; - struct iwl_notif_statistics delta_statistics; - struct iwl_notif_statistics max_delta; - struct iwl_bt_notif_statistics accum_statistics_bt; - struct iwl_bt_notif_statistics delta_statistics_bt; - struct iwl_bt_notif_statistics max_delta_bt; -#endif /* notification wait support */ struct list_head notif_waits; spinlock_t notif_wait_lock; @@ -1424,7 +1438,6 @@ struct iwl_priv { bool bt_ch_announce; bool bt_full_concurrent; bool bt_ant_couple_ok; - bool bt_statistics; __le32 kill_ack_mask; __le32 kill_cts_mask; __le16 bt_valid; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 4472761fc59..b49819ca2cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -390,21 +390,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal * operation state. */ -static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +static bool iwl_good_ack_health(struct iwl_priv *priv, + struct statistics_tx *cur) { int actual_delta, expected_delta, ba_timeout_delta; - struct statistics_tx *cur, *old; + struct statistics_tx *old; if (priv->_agn.agg_tids_count) return true; - if (iwl_bt_statistics(priv)) { - cur = &pkt->u.stats_bt.tx; - old = &priv->_agn.statistics_bt.tx; - } else { - cur = &pkt->u.stats.tx; - old = &priv->_agn.statistics.tx; - } + old = &priv->statistics.tx; actual_delta = le32_to_cpu(cur->actual_ack_cnt) - le32_to_cpu(old->actual_ack_cnt); @@ -430,10 +425,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * DEBUG is not, these will just compile out. */ IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", - priv->_agn.delta_statistics.tx.rx_detected_cnt); + priv->delta_stats.tx.rx_detected_cnt); IWL_DEBUG_RADIO(priv, "ack_or_ba_timeout_collision delta %d\n", - priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); + priv->delta_stats.tx.ack_or_ba_timeout_collision); #endif if (ba_timeout_delta >= BA_TIMEOUT_MAX) @@ -450,7 +445,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * to improve the throughput. */ static bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, unsigned int msecs) + struct statistics_rx_phy *cur_ofdm, + struct statistics_rx_ht_phy *cur_ofdm_ht, + unsigned int msecs) { int delta; int threshold = priv->cfg->base_params->plcp_delta_threshold; @@ -460,29 +457,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, return true; } - if (iwl_bt_statistics(priv)) { - struct statistics_rx_bt *cur, *old; - - cur = &pkt->u.stats_bt.rx; - old = &priv->_agn.statistics_bt.rx; - - delta = le32_to_cpu(cur->ofdm.plcp_err) - - le32_to_cpu(old->ofdm.plcp_err) + - le32_to_cpu(cur->ofdm_ht.plcp_err) - - le32_to_cpu(old->ofdm_ht.plcp_err); - } else { - struct statistics_rx *cur, *old; - - cur = &pkt->u.stats.rx; - old = &priv->_agn.statistics.rx; - - delta = le32_to_cpu(cur->ofdm.plcp_err) - - le32_to_cpu(old->ofdm.plcp_err) + - le32_to_cpu(cur->ofdm_ht.plcp_err) - - le32_to_cpu(old->ofdm_ht.plcp_err); - } + delta = le32_to_cpu(cur_ofdm->plcp_err) - + le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) + + le32_to_cpu(cur_ofdm_ht->plcp_err) - + le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err); - /* Can be negative if firmware reseted statistics */ + /* Can be negative if firmware reset statistics */ if (delta <= 0) return true; @@ -497,44 +477,36 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, } static void iwl_recover_from_statistics(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) + struct statistics_rx_phy *cur_ofdm, + struct statistics_rx_ht_phy *cur_ofdm_ht, + struct statistics_tx *tx, + unsigned long stamp) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; unsigned int msecs; - unsigned long stamp; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - stamp = jiffies; msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); /* Only gather statistics and update time stamp when not associated */ if (!iwl_is_any_associated(priv)) - goto out; + return; /* Do not check/recover when do not have enough statistics data */ if (msecs < 99) return; - if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { + if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) { IWL_ERR(priv, "low ack count detected, restart firmware\n"); if (!iwl_force_reset(priv, IWL_FW_RESET, false)) return; } - if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) + if (mod_params->plcp_check && + !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) iwl_force_reset(priv, IWL_RF_RESET, false); - -out: - if (iwl_bt_statistics(priv)) - memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, - sizeof(priv->_agn.statistics_bt)); - else - memcpy(&priv->_agn.statistics, &pkt->u.stats, - sizeof(priv->_agn.statistics)); - - priv->rx_statistics_jiffies = stamp; } /* Calculate noise level, based on measurements during network silence just @@ -548,10 +520,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) int bcn_silence_a, bcn_silence_b, bcn_silence_c; int last_rx_noise; - if (iwl_bt_statistics(priv)) - rx_info = &(priv->_agn.statistics_bt.rx.general.common); - else - rx_info = &(priv->_agn.statistics.rx.general); + rx_info = &priv->statistics.rx_non_phy; + bcn_silence_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; bcn_silence_b = @@ -583,105 +553,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) last_rx_noise); } +#ifdef CONFIG_IWLWIFI_DEBUGFS /* * based on the assumption of all statistics counter are in DWORD * FIXME: This function is for debugging, do not deal with * the case of counters roll-over. */ -static void iwl_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) +static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta, + __le32 *max_delta, __le32 *accum, int size) { -#ifdef CONFIG_IWLWIFI_DEBUGFS - int i, size; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - struct statistics_general_common *general, *accum_general; - struct statistics_tx *tx, *accum_tx; - - if (iwl_bt_statistics(priv)) { - prev_stats = (__le32 *)&priv->_agn.statistics_bt; - accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; - size = sizeof(struct iwl_bt_notif_statistics); - general = &priv->_agn.statistics_bt.general.common; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta = (u32 *)&priv->_agn.delta_statistics_bt; - max_delta = (u32 *)&priv->_agn.max_delta_bt; - } else { - prev_stats = (__le32 *)&priv->_agn.statistics; - accum_stats = (u32 *)&priv->_agn.accum_statistics; - size = sizeof(struct iwl_notif_statistics); - general = &priv->_agn.statistics.general.common; - accum_general = &priv->_agn.accum_statistics.general.common; - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta = (u32 *)&priv->_agn.delta_statistics; - max_delta = (u32 *)&priv->_agn.max_delta; - } - for (i = sizeof(__le32); i < size; - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) + int i; + + for (i = 0; + i < size / sizeof(__le32); + i++, prev++, cur++, delta++, max_delta++, accum++) { + if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) { + *delta = cpu_to_le32( + le32_to_cpu(*cur) - le32_to_cpu(*prev)); + le32_add_cpu(accum, le32_to_cpu(*delta)); + if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta)) *max_delta = *delta; } } +} - /* reset accumulative statistics for "no-counter" type statistics */ - accum_general->temperature = general->temperature; - accum_general->temperature_m = general->temperature_m; - accum_general->ttl_timestamp = general->ttl_timestamp; - accum_tx->tx_power.ant_a = tx->tx_power.ant_a; - accum_tx->tx_power.ant_b = tx->tx_power.ant_b; - accum_tx->tx_power.ant_c = tx->tx_power.ant_c; -#endif +static void +iwl_accumulative_statistics(struct iwl_priv *priv, + struct statistics_general_common *common, + struct statistics_rx_non_phy *rx_non_phy, + struct statistics_rx_phy *rx_ofdm, + struct statistics_rx_ht_phy *rx_ofdm_ht, + struct statistics_rx_phy *rx_cck, + struct statistics_tx *tx, + struct statistics_bt_activity *bt_activity) +{ +#define ACCUM(_name) \ + accum_stats((__le32 *)&priv->statistics._name, \ + (__le32 *)_name, \ + (__le32 *)&priv->delta_stats._name, \ + (__le32 *)&priv->max_delta_stats._name, \ + (__le32 *)&priv->accum_stats._name, \ + sizeof(*_name)); + + ACCUM(common); + ACCUM(rx_non_phy); + ACCUM(rx_ofdm); + ACCUM(rx_ofdm_ht); + ACCUM(rx_cck); + ACCUM(tx); + if (bt_activity) + ACCUM(bt_activity); +#undef ACCUM } +#else +static inline void +iwl_accumulative_statistics(struct iwl_priv *priv, + struct statistics_general_common *common, + struct statistics_rx_non_phy *rx_non_phy, + struct statistics_rx_phy *rx_ofdm, + struct statistics_rx_ht_phy *rx_ofdm_ht, + struct statistics_rx_phy *rx_cck, + struct statistics_tx *tx, + struct statistics_bt_activity *bt_activity) +{ +} +#endif static void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { + unsigned long stamp = jiffies; const int reg_recalib_period = 60; int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + __le32 *flag; + struct statistics_general_common *common; + struct statistics_rx_non_phy *rx_non_phy; + struct statistics_rx_phy *rx_ofdm; + struct statistics_rx_ht_phy *rx_ofdm_ht; + struct statistics_rx_phy *rx_cck; + struct statistics_tx *tx; + struct statistics_bt_activity *bt_activity; + + len -= sizeof(struct iwl_cmd_header); /* skip header */ + + IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", + len); + + if (len == sizeof(struct iwl_bt_notif_statistics)) { + struct iwl_bt_notif_statistics *stats; + stats = &pkt->u.stats_bt; + flag = &stats->flag; + common = &stats->general.common; + rx_non_phy = &stats->rx.general.common; + rx_ofdm = &stats->rx.ofdm; + rx_ofdm_ht = &stats->rx.ofdm_ht; + rx_cck = &stats->rx.cck; + tx = &stats->tx; + bt_activity = &stats->general.activity; - if (iwl_bt_statistics(priv)) { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_bt_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics_bt.general.common.temperature != - pkt->u.stats_bt.general.common.temperature) || - ((priv->_agn.statistics_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); +#ifdef CONFIG_IWLWIFI_DEBUGFS + /* handle this exception directly */ + priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills; + le32_add_cpu(&priv->statistics.accum_num_bt_kills, + le32_to_cpu(stats->rx.general.num_bt_kills)); +#endif + } else if (len == sizeof(struct iwl_notif_statistics)) { + struct iwl_notif_statistics *stats; + stats = &pkt->u.stats; + flag = &stats->flag; + common = &stats->general.common; + rx_non_phy = &stats->rx.general; + rx_ofdm = &stats->rx.ofdm; + rx_ofdm_ht = &stats->rx.ofdm_ht; + rx_cck = &stats->rx.cck; + tx = &stats->tx; + bt_activity = NULL; } else { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics.general.common.temperature != - pkt->u.stats.general.common.temperature) || - ((priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); + WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", + len, sizeof(struct iwl_bt_notif_statistics), + sizeof(struct iwl_notif_statistics)); + return; } - iwl_recover_from_statistics(priv, pkt); + change = common->temperature != priv->statistics.common.temperature || + (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); + + iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, + rx_ofdm_ht, rx_cck, tx, bt_activity); + + iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); + + priv->statistics.flag = *flag; + memcpy(&priv->statistics.common, common, sizeof(*common)); + memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy)); + memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm)); + memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht)); + memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck)); + memcpy(&priv->statistics.tx, tx, sizeof(*tx)); +#ifdef CONFIG_IWLWIFI_DEBUGFS + if (bt_activity) + memcpy(&priv->statistics.bt_activity, bt_activity, + sizeof(*bt_activity)); +#endif + + priv->rx_statistics_jiffies = stamp; set_bit(STATUS_STATISTICS, &priv->status); @@ -708,18 +726,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv, if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { #ifdef CONFIG_IWLWIFI_DEBUGFS - memset(&priv->_agn.accum_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.delta_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.max_delta, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.accum_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.delta_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.max_delta_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->accum_stats, 0, + sizeof(priv->accum_stats)); + memset(&priv->delta_stats, 0, + sizeof(priv->delta_stats)); + memset(&priv->max_delta_stats, 0, + sizeof(priv->max_delta_stats)); #endif IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); } -- cgit v1.2.3-70-g09d2 From 6fc3ba999994b675c4e6af77ac4e1a6bfd8e6128 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Apr 2011 06:16:29 -0700 Subject: iwlagn: downgrade warning on unknown TLV If we maintain API properly, then there isn't really a reason to warn about this since we'll just be adding things that are safe to ignore, so downgrade the warning to debug info level. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 20499b76443..47a4cda9eb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1481,7 +1481,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, le32_to_cpup((__le32 *)tlv_data); break; default: - IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); + IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); break; } } -- cgit v1.2.3-70-g09d2 From 15b91e830dbf300d653b3fe70f6ef71b568164a3 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 6 Apr 2011 11:41:11 +0530 Subject: ath9k: Implement dev_tx_frames_pending callback. This function returns true if there is atleast one frame in any one of the tx queues. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ba1c9a684ef..93b9fa2cbaf 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2201,6 +2201,21 @@ out: ath9k_ps_restore(sc); } +static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) +{ + struct ath_softc *sc = hw->priv; + int i; + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + + if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) + return true; + } + return false; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2223,4 +2238,5 @@ struct ieee80211_ops ath9k_ops = { .rfkill_poll = ath9k_rfkill_poll_state, .set_coverage_class = ath9k_set_coverage_class, .flush = ath9k_flush, + .tx_frames_pending = ath9k_tx_frames_pending, }; -- cgit v1.2.3-70-g09d2 From d88525e8fdc00c0078d38353caffc29e5a9c70cc Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 6 Apr 2011 21:42:52 +0530 Subject: ath9k_hw: Fix instable target power control b/w CCK/OFDM The problem is that when the attenuation is increased, the rate will start to drop from MCS7 -> MCS6, and finally will see MCS1 -> CCK_11Mbps. When the rate is changed b/w CCK and OFDM, it will use register desired_scale to calculate how much tx gain need to change. The output power with the same tx gain for CCK and OFDM modulated signals are different. This difference is constant for AR9280 but not AR9285/AR9271. It has different PA architecture a constant. So it should be calibrated against this PA characteristic. The driver has to read the calibrated values from EEPROM and set the tx power registers accordingly. Signed-off-by: Rajkumar Manoharan Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.h | 6 ++++++ drivers/net/wireless/ath/ath9k/eeprom.h | 6 +++++- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 37663dbbcf5..47780ef1c89 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -483,7 +483,11 @@ #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 +#define AR_PHY_TX_PWRCTRL8 0xa278 + #define AR_PHY_TX_PWRCTRL9 0xa27C + +#define AR_PHY_TX_PWRCTRL10 0xa394 #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 @@ -495,6 +499,8 @@ #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 +#define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc +#define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index bd82447f5b7..3e316133f11 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -436,7 +436,11 @@ struct modal_eep_4k_header { u8 db2_2:4, db2_3:4; u8 db2_4:4, reserved:4; #endif - u8 futureModal[4]; + u8 tx_diversity; + u8 flc_pwr_thresh; + u8 bb_scale_smrt_antenna; +#define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f + u8 futureModal[1]; struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; } __packed; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index bc77a308c90..6f714dd7236 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, { struct modal_eep_4k_header *pModal; struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; + struct base_eep_header_4k *pBase = &eep->baseEepHeader; u8 txRxAttenLocal; u8 ob[5], db1[5], db2[5]; u8 ant_div_control1, ant_div_control2; @@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); } + if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { + u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & + EEP_4K_BB_DESIRED_SCALE_MASK); + if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { + u32 pwrctrl, mask, clr; + + mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); + REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); + + mask = BIT(0)|BIT(5)|BIT(15); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); + + mask = BIT(0)|BIT(5); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); + } + } } static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) -- cgit v1.2.3-70-g09d2 From 18bf965702058f5f8039e6a46bb5ebaa18d38ebd Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 6 Apr 2011 16:46:55 -0700 Subject: mwifiex: fix cmd_skb headroom decreasing issue Before calling host_to_card() to send the cmd to firmware, we use skb_push() to add 4 bytes SDIO interface header at the start of the data buffer. Since cmd_skb data structure will be re-used at a later time, we need to restore its headroom by removing the 4 bytes header. Signed-off-by: Bing Zhao Signed-off-by: Marc Yang Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a9aeb31af45..8676480ead9 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -206,6 +206,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, cmd_node->cmd_skb->data, cmd_node->cmd_skb->len, NULL); + skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); + if (ret == -1) { dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); if (wait_queue) -- cgit v1.2.3-70-g09d2 From 6a35a0ac5771fa962c45926678d1f194cbc98c4e Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 6 Apr 2011 16:46:56 -0700 Subject: mwifiex: use common keyinfo bitmap for different key types Instead of having separate key information definitions for each type of key, a common key information bitmap is used. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 27 +++------------------------ drivers/net/wireless/mwifiex/sta_cmd.c | 27 +++++++++++++-------------- drivers/net/wireless/mwifiex/sta_cmdresp.c | 3 +-- drivers/net/wireless/mwifiex/sta_ioctl.c | 3 +-- 4 files changed, 18 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 2b938115b26..f8c008f8f47 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -72,33 +72,12 @@ enum KEY_TYPE_ID { KEY_TYPE_ID_AES, KEY_TYPE_ID_WAPI, }; - -enum KEY_INFO_WEP { - KEY_INFO_WEP_MCAST = 0x01, - KEY_INFO_WEP_UNICAST = 0x02, - KEY_INFO_WEP_ENABLED = 0x04 -}; - -enum KEY_INFO_TKIP { - KEY_INFO_TKIP_MCAST = 0x01, - KEY_INFO_TKIP_UNICAST = 0x02, - KEY_INFO_TKIP_ENABLED = 0x04 -}; - -enum KEY_INFO_AES { - KEY_INFO_AES_MCAST = 0x01, - KEY_INFO_AES_UNICAST = 0x02, - KEY_INFO_AES_ENABLED = 0x04 -}; +#define KEY_MCAST BIT(0) +#define KEY_UNICAST BIT(1) +#define KEY_ENABLED BIT(2) #define WAPI_KEY_LEN 50 -enum KEY_INFO_WAPI { - KEY_INFO_WAPI_MCAST = 0x01, - KEY_INFO_WAPI_UNICAST = 0x02, - KEY_INFO_WAPI_ENABLED = 0x04 -}; - #define MAX_POLL_TRIES 100 #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6fff26153e2..19de6524d42 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -500,9 +500,8 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, key_param_set->key_type_id = cpu_to_le16(KEY_TYPE_ID_WEP); key_param_set->key_info = - cpu_to_le16(KEY_INFO_WEP_ENABLED | - KEY_INFO_WEP_UNICAST | - KEY_INFO_WEP_MCAST); + cpu_to_le16(KEY_ENABLED | KEY_UNICAST | + KEY_MCAST); key_param_set->key_len = cpu_to_le16(priv->wep_key[i].key_length); /* Set WEP key index */ @@ -589,10 +588,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, cpu_to_le16(KEY_TYPE_ID_WAPI); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_WAPI_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_INFO_WAPI_ENABLED); + cpu_to_le16(!KEY_ENABLED); key_material->key_param_set.key[0] = enc_key->key_index; if (!priv->sec_info.wapi_key_on) @@ -604,10 +603,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { /* WAPI pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_WAPI_UNICAST); + cpu_to_le16(KEY_UNICAST); } else { /* WAPI group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_WAPI_MCAST); + cpu_to_le16(KEY_MCAST); priv->sec_info.wapi_key_on = true; } @@ -634,32 +633,32 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, cpu_to_le16(KEY_TYPE_ID_AES); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_AES_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_INFO_AES_ENABLED); + cpu_to_le16(!KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* AES pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_AES_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* AES group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_AES_MCAST); + cpu_to_le16(KEY_MCAST); } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); key_material->key_param_set.key_type_id = cpu_to_le16(KEY_TYPE_ID_TKIP); key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_TKIP_ENABLED); + cpu_to_le16(KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* TKIP pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_TKIP_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* TKIP group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_TKIP_MCAST); + cpu_to_le16(KEY_MCAST); } if (key_material->key_param_set.key_type_id) { diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 74add45b99b..648df690f5d 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -574,8 +574,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, &resp->params.key_material; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { - if ((le16_to_cpu(key->key_param_set.key_info) & - KEY_INFO_TKIP_MCAST)) { + if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); priv->wpa_is_gtk_set = true; priv->scan_block = false; diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b163507b1fe..2fcdbc224e0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -1729,8 +1729,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, sizeof(ibss_key->key_param_set.key_len)); ibss_key->key_param_set.key_type_id = cpu_to_le16(KEY_TYPE_ID_TKIP); - ibss_key->key_param_set.key_info - = cpu_to_le16(KEY_INFO_TKIP_ENABLED); + ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED); /* Send the key as GTK to firmware */ encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; -- cgit v1.2.3-70-g09d2 From 264bbec811024e39fe8f9e7a45743f81f373529e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Apr 2011 19:24:23 +0200 Subject: ath9k: fix PS-Poll reception on AR9160 and earlier I can't find any valid reason for not setting the ATH9K_RX_FILTER_PSPOLL flag on older hardware and neither the documentation nor the reference code mention any reason for excluding older hardware here. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3842b751866..ef198ae71eb 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -426,9 +426,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) else rfilt |= ATH9K_RX_FILTER_BEACON; - if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || - AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && - (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && + if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->rx.rxfilter & FIF_PSPOLL)) rfilt |= ATH9K_RX_FILTER_PSPOLL; -- cgit v1.2.3-70-g09d2 From 952949738aba19f84dae9def18e0baa58f0ce0b8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Apr 2011 19:30:32 +0200 Subject: ath9k: fix too early enabling of rx during ath_startrecv() rx should only be enabled after enough rx buffers have been given to the hardware, however ath_rx_buf_link was calling ath9k_hw_rxena after every single added buffer. Fix this by calling ath9k_hw_rxena directly from the rx tasklet after completion instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ef198ae71eb..b81bfc4d66e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) *sc->rx.rxlink = bf->bf_daddr; sc->rx.rxlink = &ds->ds_link; - ath9k_hw_rxena(ah); } static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) @@ -1765,6 +1764,7 @@ requeue: } else { list_move_tail(&bf->list, &sc->rx.rxbuf); ath_rx_buf_link(sc, bf); + ath9k_hw_rxena(ah); } } while (1); -- cgit v1.2.3-70-g09d2 From a22e93f5d819f11d2a2d6332e20ff5b462e5c208 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 7 Apr 2011 20:40:32 +0200 Subject: iwl4965: drop a lone pr_err() iwl4965_rate_control_register() prints a message at KERN_ERR level. It looks like it's just a debugging message, so pr_err() seems to be overdone. But none of the similar functions in drivers/net/wireless print a message, so let's just drop it. Signed-off-by: Paul Bolle Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965-rs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 31ac672b64e..89509392ef5 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c @@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = { int iwl4965_rate_control_register(void) { - pr_err("Registering 4965 rate control operations\n"); return ieee80211_rate_control_register(&rs_4965_ops); } -- cgit v1.2.3-70-g09d2 From 7d75541499319dff375af252345ae1999540b4a9 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 8 Apr 2011 15:30:34 +0530 Subject: ath9k: Add RSSI information from control and extension chains Export RSSI information from all the control and extension channel chains to debugfs. Also add rx antenna information to debugfs. This will be useful for debugging purpose. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 40 +++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/debug.h | 7 ++++++ 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a762cadb3ab..34f191ec8e8 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -845,7 +845,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 1152; + unsigned int len = 0, size = 1400; ssize_t retval = 0; buf = kzalloc(size, GFP_KERNEL); @@ -874,6 +874,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, "%18s : %10u\n", "DECRYPT BUSY ERR", sc->debug.stats.rxstats.decrypt_busy_err); + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL0", + sc->debug.stats.rxstats.rs_rssi_ctl0); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL1", + sc->debug.stats.rxstats.rs_rssi_ctl1); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL2", + sc->debug.stats.rxstats.rs_rssi_ctl2); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT0", + sc->debug.stats.rxstats.rs_rssi_ext0); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT1", + sc->debug.stats.rxstats.rs_rssi_ext1); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT2", + sc->debug.stats.rxstats.rs_rssi_ext2); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "Rx Antenna", + sc->debug.stats.rxstats.rs_antenna); + PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); @@ -948,6 +976,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) RX_PHY_ERR_INC(phyerr); } + sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; + sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; + sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; + + sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; + sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; + sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; + + sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; + #undef RX_STAT_INC #undef RX_PHY_ERR_INC } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 59338de0ce1..1f9f8eada46 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -157,6 +157,13 @@ struct ath_rx_stats { u32 post_delim_crc_err; u32 decrypt_busy_err; u32 phy_err_stats[ATH9K_PHYERR_MAX]; + int8_t rs_rssi_ctl0; + int8_t rs_rssi_ctl1; + int8_t rs_rssi_ctl2; + int8_t rs_rssi_ext0; + int8_t rs_rssi_ext1; + int8_t rs_rssi_ext2; + u8 rs_antenna; }; struct ath_stats { -- cgit v1.2.3-70-g09d2 From d0ef824b9a712b866e38212089ade3a7114225a4 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 8 Apr 2011 15:30:35 +0530 Subject: ath9k: Update gain table for AR9485 Update Tx gain 23 for all tx gain table. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index f91f73e50d0..fbdde29f0ab 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -396,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -469,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -635,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -728,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -827,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, -- cgit v1.2.3-70-g09d2 From f60c49b67dd6db2ccb740a6a671414f9dab00c4f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Apr 2011 17:06:25 +0530 Subject: ath9k: Fix kernel panic on module unload The commit "ath9k: configure beacons based on hw opmode" introduced a regression which leads to kernel panic. Failed to stop ani timer during the driver unload while any of the beaconing vif is running. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eccb0ec87ad..b56f69e7677 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) if (avp->av_bcbuf != NULL) { struct ath_buf *bf; + avp->is_bslot_active = false; if (avp->av_bslot != -1) { sc->beacon.bslot[avp->av_bslot] = NULL; sc->nbcnvifs--; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93b9fa2cbaf..a55a8929810 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1375,6 +1375,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, if ((iter_data.naps + iter_data.nadhocs) > 0) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); + } else { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); } } -- cgit v1.2.3-70-g09d2 From 1296433bf39a8dea852aafad1f29b775f993bca1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Apr 2011 20:49:16 +0200 Subject: ath9k_hw: remove unnecessary parts of the AR9380 SREV check Older versions have not been sold and the driver does not explicitly check for them anyway, so we can simply ignore the macRev here. Reduces ath9k_hw size on mips by more than 2 KB. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/reg.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 693d543937b..2fbbe8842bb 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -858,9 +858,7 @@ #define AR_SREV_9300(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) #define AR_SREV_9300_20_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) + ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) #define AR_SREV_9485(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) -- cgit v1.2.3-70-g09d2 From ba30c4a58ceb10e81dbf6bd80aeb6a4db42db8fe Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Sat, 9 Apr 2011 00:25:37 +0530 Subject: mwl8k: Fix checkpatch.pl and sparse warnings and errors Fix checkpatch errors and warnings comprising of indent errors, spaces and __packed warnings. Also fix 'make C = 2' warnings. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 8913180a7bd..fb472f4924d 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -701,7 +701,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) "helper image\n", pci_name(priv->pdev)); return rc; } - msleep(5); + msleep(20); rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); } else { @@ -823,8 +823,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) /* * Make sure the packet header is in the DMA header format (4-address * without QoS), the necessary crypto padding between the header and the - * payload has already been provided by mac80211, but it doesn't add tail - * padding when HW crypto is enabled. + * payload has already been provided by mac80211, but it doesn't add + * tail padding when HW crypto is enabled. * * We have the following trailer padding requirements: * - WEP: 4 trailer bytes (ICV) @@ -1487,9 +1487,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) if (timeout) { WARN_ON(priv->pending_tx_pkts); - if (retry) { + if (retry) wiphy_notice(hw->wiphy, "tx rings drained\n"); - } break; } @@ -1649,8 +1648,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) /* Rate control is happening in the firmware. * Ensure no tx rate is being reported. */ - info->status.rates[0].idx = -1; - info->status.rates[0].count = 1; + info->status.rates[0].idx = -1; + info->status.rates[0].count = 1; if (MWL8K_TXD_SUCCESS(status)) info->flags |= IEEE80211_TX_STAT_ACK; @@ -1688,7 +1687,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) } /* caller must hold priv->stream_lock when calling the stream functions */ -struct mwl8k_ampdu_stream * +static struct mwl8k_ampdu_stream * mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) { struct mwl8k_ampdu_stream *stream; @@ -2657,7 +2656,7 @@ struct mwl8k_cmd_tx_power { __le16 bw; __le16 sub_ch; __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, struct ieee80211_conf *conf, @@ -3520,13 +3519,13 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 -enum { +enum ba_stream_action_type { MWL8K_BA_CREATE, MWL8K_BA_UPDATE, MWL8K_BA_DESTROY, MWL8K_BA_FLUSH, MWL8K_BA_CHECK, -} ba_stream_action_type; +}; struct mwl8k_create_ba_stream { @@ -3780,7 +3779,7 @@ struct mwl8k_cmd_update_encryption { __u8 mac_addr[6]; __u8 encr_type; -} __attribute__((packed)); +} __packed; struct mwl8k_cmd_set_key { struct mwl8k_cmd_pkt header; @@ -3800,7 +3799,7 @@ struct mwl8k_cmd_set_key { __le16 tkip_tsc_low; __le32 tkip_tsc_high; __u8 mac_addr[6]; -} __attribute__((packed)); +} __packed; enum { MWL8K_ENCR_ENABLE, @@ -4502,7 +4501,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { struct mwl8k_priv *priv = hw->priv; - u32 ap_legacy_rates; + u32 ap_legacy_rates = 0; u8 ap_mcs_rates[16]; int rc; -- cgit v1.2.3-70-g09d2 From a065784620a2b78a2bbd00e066c004644d227ea8 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 8 Apr 2011 15:33:12 -0400 Subject: ath5k: improve pcal error handling for ENOMEM case The ath5k driver does kmalloc allocations for pcal info in a loop. But, if one fails it was simply returning -ENOMEM without freeing already allocated memory. This patch corrects that oversight. Reported-by: Eugene A. Shatokhin Signed-off-by: John W. Linville Reviewed-by: Bob Copeland --- drivers/net/wireless/ath/ath5k/eeprom.c | 129 +++++++++++++++++--------------- 1 file changed, 70 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index b6561f785c6..fb12027e034 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; } +static int +ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) +{ + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + struct ath5k_chan_pcal_info *chinfo; + u8 pier, pdg; + + switch (mode) { + case AR5K_EEPROM_MODE_11A: + if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_a; + break; + case AR5K_EEPROM_MODE_11B: + if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_b; + break; + case AR5K_EEPROM_MODE_11G: + if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_g; + break; + default: + return -EINVAL; + } + + for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { + if (!chinfo[pier].pd_curves) + continue; + + for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { + struct ath5k_pdgain_info *pd = + &chinfo[pier].pd_curves[pdg]; + + if (pd != NULL) { + kfree(pd->pd_step); + kfree(pd->pd_pwr); + } + } + + kfree(chinfo[pier].pd_curves); + } + + return 0; +} + /* Convert RF5111 specific data to generic raw data * used by interpolation code */ static int @@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Only one curve for RF5111 * find out which one and place @@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * (convert power to 0.25dB units @@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; - + goto err_out; /* Fill raw dataset * (all power levels are in 0.25dB units) */ @@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * (all power levels are in 0.25dB units) */ @@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * convert all pwr levels to @@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) return 0; } -static int -ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *chinfo; - u8 pier, pdg; - - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - if (!chinfo[pier].pd_curves) - continue; - - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { - struct ath5k_pdgain_info *pd = - &chinfo[pier].pd_curves[pdg]; - - if (pd != NULL) { - kfree(pd->pd_step); - kfree(pd->pd_pwr); - } - } - - kfree(chinfo[pier].pd_curves); - } - - return 0; -} - /* Read conformance test limits used for regulatory control */ static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) -- cgit v1.2.3-70-g09d2 From 6d7b97b23e114c8fbb825e6721164d228c1af3fc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 21:37:14 +0200 Subject: ath5k: fix tx status reporting issues During normal operation, minstrel was showing suspicious EWMA probabilities exceeding 100%. It looks like the tx status reporting in ath5k was not properly clearing the rate index for rates which were never attempted. This is caused by uninitialized stale data in the on-stack tx status information, which is reused when more frames are received. To fix this, rely on ts->ts_final_idx to select the last attempted rate, instead of checking whether ts->ts_rate is set. Additionally, the conversion from the driver rate index back to the mac80211 rate index can be dropped, as the mac80211 tx status will still have the original rate index which was used to set up the descriptor. Additionally, one more inaccuracy was fixed - the final rate attempt count only needs to be increased by one if the transmission attempt was successful. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4d7f21ee111..753662f98f7 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1580,21 +1580,14 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); - for (i = 0; i < 4; i++) { + for (i = 0; i <= ts->ts_final_idx; i++) { struct ieee80211_tx_rate *r = &info->status.rates[i]; - if (ts->ts_rate[i]) { - r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); - r->count = ts->ts_retry[i]; - } else { - r->idx = -1; - r->count = 0; - } + r->count = ts->ts_retry[i]; } - /* count the successful attempt as well */ - info->status.rates[ts->ts_final_idx].count++; + info->status.rates[ts->ts_final_idx + 1].idx = -1; if (unlikely(ts->ts_status)) { sc->stats.ack_fail++; @@ -1609,6 +1602,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, } else { info->flags |= IEEE80211_TX_STAT_ACK; info->status.ack_signal = ts->ts_rssi; + + /* count the successful attempt as well */ + info->status.rates[ts->ts_final_idx].count++; } /* -- cgit v1.2.3-70-g09d2 From a27049e2c926bcf68360532a5ae66e408296ae85 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:19 +0200 Subject: ath5k: fix short preamble rate duration value Subtract the difference in preamble duration (in usec) from the value returned by ieee80211_generic_frame_duration. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 31 ++++++++++++------------------- drivers/net/wireless/ath/ath5k/qcu.c | 2 +- 3 files changed, 14 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8a06dbd3962..996d8afafdb 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1233,7 +1233,7 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); /* Protocol Control Unit Functions */ /* Helpers */ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, - int len, struct ieee80211_rate *rate); + int len, struct ieee80211_rate *rate, bool shortpre); unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index a702817daf7..e342e470fb0 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] = * bwmodes. */ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, - int len, struct ieee80211_rate *rate) + int len, struct ieee80211_rate *rate, bool shortpre) { struct ath5k_softc *sc = ah->ah_sc; int sifs, preamble, plcp_bits, sym_time; @@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, /* Fallback */ if (!ah->ah_bwmode) { - dur = ieee80211_generic_frame_duration(sc->hw, - NULL, len, rate); - return le16_to_cpu(dur); + __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, + NULL, len, rate); + + /* subtract difference between long and short preamble */ + dur = le16_to_cpu(raw_dur); + if (shortpre) + dur -= 96; + + return dur; } bitrate = rate->bitrate; @@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) * actual rate for this rate. See mac80211 tx.c * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ - tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); + tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); ath5k_hw_reg_write(ah, tx_time, reg); if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) continue; - /* - * We're not distinguishing short preamble here, - * This is true, all we'll get is a longer value here - * which is not necessarilly bad. We could use - * export ieee80211_frame_duration() but that needs to be - * fixed first to be properly used by mac802111 drivers: - * - * - remove erp stuff and let the routine figure ofdm - * erp rates - * - remove passing argument ieee80211_local as - * drivers don't have access to it - * - move drivers using ieee80211_generic_frame_duration() - * to this - */ + tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); ath5k_hw_reg_write(ah, tx_time, reg + (AR5K_SET_SHORT_PREAMBLE << 2)); } diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 3343fb9e494..93abcfacd99 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) else rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; - ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); + ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); /* ack_tx_time includes an SIFS already */ eifs = ack_tx_time + sifs + 2 * slot_time; -- cgit v1.2.3-70-g09d2 From 488a50176c169eb36544b4f970c8bba68ede30a1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:20 +0200 Subject: ath5k: fix SIFS time handling ath5k uses 8 usec as a sifs time, extracted from the initvals, whereas the standard requires a sifs time of 10. The difference originates from the fact that the SIFS register has an offset of 2 usec. Fix the SIFS time definition to use the standard value of 10 usec and subtract 2 usecs when writing the SIFS register. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/qcu.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 996d8afafdb..a49aeac378c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -224,8 +224,7 @@ /* SIFS */ #define AR5K_INIT_SIFS_TURBO 6 -/* XXX: 8 from initvals 10 from standard */ -#define AR5K_INIT_SIFS_DEFAULT_BG 8 +#define AR5K_INIT_SIFS_DEFAULT_BG 10 #define AR5K_INIT_SIFS_DEFAULT_A 16 #define AR5K_INIT_SIFS_HALF_RATE 32 #define AR5K_INIT_SIFS_QUARTER_RATE 64 diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 93abcfacd99..b18c5021aac 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) return -EINVAL; sifs = ath5k_hw_get_default_sifs(ah); - sifs_clock = ath5k_hw_htoclock(ah, sifs); + sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); /* EIFS * Txtime of ack at lowest rate + SIFS + DIFS -- cgit v1.2.3-70-g09d2 From b1ad1b6febb7772583c98d9a879fbbdb82a726a7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:21 +0200 Subject: ath5k: fix slot time handling Set the slot time based on the mac80211 short slot vs long slot setting instead of just forcing long slot for all CCK-enabled channels. This slightly improves 802.11g mode performance in in my tests. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/mac80211-ops.c | 9 +++++++++ drivers/net/wireless/ath/ath5k/pcu.c | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index a49aeac378c..4bb381cae08 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1057,6 +1057,7 @@ struct ath5k_hw { u8 ah_coverage_class; bool ah_ack_bitrate_high; u8 ah_bwmode; + bool ah_short_slot; /* Antenna Control */ u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 9be29b728b1..807bd644016 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_BEACON_INT) sc->bintval = bss_conf->beacon_int; + if (changes & BSS_CHANGED_ERP_SLOT) { + int slot_time; + + ah->ah_short_slot = bss_conf->use_short_slot; + slot_time = ath5k_hw_get_default_slottime(ah) + + 3 * ah->ah_coverage_class; + ath5k_hw_set_ifs_intervals(ah, slot_time); + } + if (changes & BSS_CHANGED_ASSOC) { avf->assoc = bss_conf->assoc; if (bss_conf->assoc) diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e342e470fb0..71b60b7c617 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -151,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; break; case AR5K_BWMODE_DEFAULT: - slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; default: - if (channel->hw_value & CHANNEL_CCK) + slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; + if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) slot_time = AR5K_INIT_SLOT_TIME_B; break; } -- cgit v1.2.3-70-g09d2 From c5e0a88aa2e0f42cdb4c79c977c52f6bc38ec160 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:13 +0200 Subject: ath5k: optimize tx descriptor setup Use local variables to reduce the number of load/store operations on uncached memory. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 16b44ff7dd3..0a8a9efaf8b 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -184,6 +184,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; + u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; @@ -209,7 +210,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, tx_power = AR5K_TUNE_MAX_TXPOWER; /* Clear descriptor */ - memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); + memset(&desc->ud.ds_tx5212.tx_stat, 0, + sizeof(desc->ud.ds_tx5212.tx_stat)); /* Setup control descriptor */ @@ -221,7 +223,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ @@ -232,21 +234,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; - tx_ctl->tx_control_0 |= - AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | - AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_ctl->tx_control_1 |= AR5K_REG_SM(type, - AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); - tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); - tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; + txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | + AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); + txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); + txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); + txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ - tx_ctl->tx_control_##_c |= \ - AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ + txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ } _TX_FLAGS(0, CLRDMASK); @@ -262,8 +260,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, * WEP crap */ if (key_index != AR5K_TXKEYIX_INVALID) { - tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, + txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; + txctl1 |= AR5K_REG_SM(key_index, AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); } @@ -274,12 +272,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if ((flags & AR5K_TXDESC_RTSENA) && (flags & AR5K_TXDESC_CTSENA)) return -EINVAL; - tx_ctl->tx_control_2 |= rtscts_duration & - AR5K_4W_TX_DESC_CTL2_RTS_DURATION; - tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, + txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; + txctl3 |= AR5K_REG_SM(rtscts_rate, AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); } + tx_ctl->tx_control_0 = txctl0; + tx_ctl->tx_control_1 = txctl1; + tx_ctl->tx_control_2 = txctl2; + tx_ctl->tx_control_3 = txctl3; + return 0; } -- cgit v1.2.3-70-g09d2 From fe12081cb664cd5d412dc56de0585a80484b1331 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:14 +0200 Subject: ath5k: remove ts_rate from ath5k_tx_status It is no longer necessary for preparing mac80211 tx status Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 - drivers/net/wireless/ath/ath5k/desc.c | 13 ------------- 2 files changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 4bb381cae08..aa588a0521c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -452,7 +452,6 @@ struct ath5k_tx_status { u16 ts_seqnum; u16 ts_tstamp; u8 ts_status; - u8 ts_rate[4]; u8 ts_retry[4]; u8 ts_final_idx; s8 ts_rssi; diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 0a8a9efaf8b..990a3b42144 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -375,8 +375,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = 1; ts->ts_status = 0; - ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, - AR5K_2W_TX_DESC_CTL0_XMIT_RATE); ts->ts_retry[0] = ts->ts_longretry; ts->ts_final_idx = 0; @@ -439,32 +437,21 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; switch (ts->ts_final_idx) { case 3: - ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); - ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); ts->ts_longretry += ts->ts_retry[2]; /* fall through */ case 2: - ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); - ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[1]; /* fall through */ case 1: - ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); - ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[0]; /* fall through */ case 0: - ts->ts_rate[0] = tx_ctl->tx_control_3 & - AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; break; } -- cgit v1.2.3-70-g09d2 From b161b89fb97b30233526d31c5f94397ed94ffea6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:15 +0200 Subject: ath5k: optimize tx status processing Use ACCESS_ONCE to reduce the number of variable reloads on uncached memory Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 990a3b42144..3758b967029 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -401,32 +401,38 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; + u32 txstat0, txstat1, txctl2; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; + txstat1 = ACCESS_ONCE(tx_status->tx_status_1); + /* No frame has been send or error */ - if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) + if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) return -EINPROGRESS; + txstat0 = ACCESS_ONCE(tx_status->tx_status_0); + txctl2 = ACCESS_ONCE(tx_ctl->tx_control_2); + /* * Get descriptor status */ - ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_tstamp = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_shortretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_longretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_seqnum = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_SEQ_NUM); - ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_rssi = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - ts->ts_antenna = (tx_status->tx_status_1 & + ts->ts_antenna = (txstat1 & AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; ts->ts_status = 0; - ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_final_idx = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); /* The longretry counter has the number of un-acked retries @@ -437,17 +443,17 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; switch (ts->ts_final_idx) { case 3: - ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[2] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); ts->ts_longretry += ts->ts_retry[2]; /* fall through */ case 2: - ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[1] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[1]; /* fall through */ case 1: - ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[0] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[0]; /* fall through */ @@ -456,15 +462,14 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, } /* TX error */ - if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) + if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { + if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) ts->ts_status |= AR5K_TXERR_XRETRY; - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) + if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) ts->ts_status |= AR5K_TXERR_FIFO; - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) + if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) ts->ts_status |= AR5K_TXERR_FILT; } -- cgit v1.2.3-70-g09d2 From b2fd97d0190a400b49a2f910109a4a492bfea319 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:16 +0200 Subject: ath5k: optimize rx status processing Use ACCESS_ONCE to reduce the number of redundant loads on uncached memory Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 41 +++++++++++++++-------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 3758b967029..e366d30ef03 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -603,37 +603,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, struct ath5k_rx_status *rs) { struct ath5k_hw_rx_status *rx_status; + u32 rxstat0, rxstat1; rx_status = &desc->ud.ds_rx.rx_stat; + rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); /* No frame received / not ready */ - if (unlikely(!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_DONE))) + if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) return -EINPROGRESS; memset(rs, 0, sizeof(struct ath5k_rx_status)); + rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); /* * Frame receive status */ - rs->rs_datalen = rx_status->rx_status_0 & - AR5K_5212_RX_DESC_STATUS0_DATA_LEN; - rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; + rs->rs_rssi = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); - rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_rate = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); - rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_antenna = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); - rs->rs_more = !!(rx_status->rx_status_0 & - AR5K_5212_RX_DESC_STATUS0_MORE); - rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); + rs->rs_tstamp = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); /* * Key table status */ - if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) - rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) + rs->rs_keyix = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); else rs->rs_keyix = AR5K_RXKEYIX_INVALID; @@ -641,27 +641,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, /* * Receive/descriptor errors */ - if (!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) + if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_phyerr = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); if (!ah->ah_capabilities.cap_has_phyerr_counters) ath5k_ani_phy_error_report(ah, rs->rs_phyerr); } - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) rs->rs_status |= AR5K_RXERR_DECRYPT; - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) rs->rs_status |= AR5K_RXERR_MIC; } return 0; -- cgit v1.2.3-70-g09d2 From ed8950857f728303a1463ac9267e72c278738bf6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:17 +0200 Subject: ath5k: remove ts_retry from ath5k_tx_status Reusing the configured retry counts from the skb cb is more efficient than reloading the data from uncached memory. Replace ts_longretry (unused) with ts_final_retry which contains the retry count for the final rate only Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/base.c | 11 +++++++++-- drivers/net/wireless/ath/ath5k/desc.c | 34 +++------------------------------- 3 files changed, 13 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index aa588a0521c..fcaf4ed84ca 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -452,11 +452,10 @@ struct ath5k_tx_status { u16 ts_seqnum; u16 ts_tstamp; u8 ts_status; - u8 ts_retry[4]; u8 ts_final_idx; + u8 ts_final_retry; s8 ts_rssi; u8 ts_shortretry; - u8 ts_longretry; u8 ts_virtcol; u8 ts_antenna; }; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 753662f98f7..1a561b89221 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1573,20 +1573,27 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, struct ath5k_txq *txq, struct ath5k_tx_status *ts) { struct ieee80211_tx_info *info; + u8 tries[3]; int i; sc->stats.tx_all_count++; sc->stats.tx_bytes_count += skb->len; info = IEEE80211_SKB_CB(skb); + tries[0] = info->status.rates[0].count; + tries[1] = info->status.rates[1].count; + tries[2] = info->status.rates[2].count; + ieee80211_tx_info_clear_status(info); - for (i = 0; i <= ts->ts_final_idx; i++) { + + for (i = 0; i < ts->ts_final_idx; i++) { struct ieee80211_tx_rate *r = &info->status.rates[i]; - r->count = ts->ts_retry[i]; + r->count = tries[i]; } + info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; info->status.rates[ts->ts_final_idx + 1].idx = -1; if (unlikely(ts->ts_status)) { diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index e366d30ef03..0391813befd 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -366,7 +366,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); /*TODO: ts->ts_virtcol + test*/ ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, @@ -375,7 +375,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = 1; ts->ts_status = 0; - ts->ts_retry[0] = ts->ts_longretry; ts->ts_final_idx = 0; if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { @@ -401,7 +400,7 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - u32 txstat0, txstat1, txctl2; + u32 txstat0, txstat1; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; @@ -413,7 +412,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, return -EINPROGRESS; txstat0 = ACCESS_ONCE(tx_status->tx_status_0); - txctl2 = ACCESS_ONCE(tx_ctl->tx_control_2); /* * Get descriptor status @@ -422,7 +420,7 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(txstat0, + ts->ts_final_retry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); ts->ts_seqnum = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_SEQ_NUM); @@ -435,32 +433,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_final_idx = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); - /* The longretry counter has the number of un-acked retries - * for the final rate. To get the total number of retries - * we have to add the retry counters for the other rates - * as well - */ - ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; - switch (ts->ts_final_idx) { - case 3: - ts->ts_retry[2] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); - ts->ts_longretry += ts->ts_retry[2]; - /* fall through */ - case 2: - ts->ts_retry[1] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); - ts->ts_longretry += ts->ts_retry[1]; - /* fall through */ - case 1: - ts->ts_retry[0] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); - ts->ts_longretry += ts->ts_retry[0]; - /* fall through */ - case 0: - break; - } - /* TX error */ if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) -- cgit v1.2.3-70-g09d2 From 5b7916ad8c29da9f30fbf03a8b61862acdba00ce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:18 +0200 Subject: ath5k: clean up debugfs code The pointers to the debugfs entries do not need to be saved, because they will be recursively removed when the wiphy is unregistered. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 1 - drivers/net/wireless/ath/ath5k/debug.c | 65 ++++++++++------------------------ drivers/net/wireless/ath/ath5k/debug.h | 17 --------- 3 files changed, 19 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1a561b89221..a799d04e0c8 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2901,7 +2901,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc) * XXX: ??? detach ath5k_hw ??? * Other than that, it's straightforward... */ - ath5k_debug_finish_device(sc); ieee80211_unregister_hw(hw); ath5k_desc_free(sc); ath5k_txq_release(sc); diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0230f30e9e9..0bf7313b8a1 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -888,65 +888,38 @@ static const struct file_operations fops_queue = { void ath5k_debug_init_device(struct ath5k_softc *sc) { - sc->debug.level = ath5k_debug; + struct dentry *phydir; - sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", - sc->hw->wiphy->debugfsdir); + sc->debug.level = ath5k_debug; - sc->debug.debugfs_debug = debugfs_create_file("debug", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_debug); + phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); + if (!phydir) + return; - sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_registers); + debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, + &fops_debug); - sc->debug.debugfs_beacon = debugfs_create_file("beacon", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_beacon); + debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers); - sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, - sc->debug.debugfs_phydir, sc, &fops_reset); + debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc, + &fops_beacon); - sc->debug.debugfs_antenna = debugfs_create_file("antenna", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_antenna); + debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset); - sc->debug.debugfs_misc = debugfs_create_file("misc", - S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_misc); + debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc, + &fops_antenna); - sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_frameerrors); + debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc); - sc->debug.debugfs_ani = debugfs_create_file("ani", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_ani); + debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc, + &fops_frameerrors); - sc->debug.debugfs_queue = debugfs_create_file("queue", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_queue); -} + debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani); -void -ath5k_debug_finish_device(struct ath5k_softc *sc) -{ - debugfs_remove(sc->debug.debugfs_debug); - debugfs_remove(sc->debug.debugfs_registers); - debugfs_remove(sc->debug.debugfs_beacon); - debugfs_remove(sc->debug.debugfs_reset); - debugfs_remove(sc->debug.debugfs_antenna); - debugfs_remove(sc->debug.debugfs_misc); - debugfs_remove(sc->debug.debugfs_frameerrors); - debugfs_remove(sc->debug.debugfs_ani); - debugfs_remove(sc->debug.debugfs_queue); - debugfs_remove(sc->debug.debugfs_phydir); + debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, + &fops_queue); } - /* functions used in other places */ void diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index b0355aef68d..193dd2d4ea3 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -68,17 +68,6 @@ struct ath5k_buf; struct ath5k_dbg_info { unsigned int level; /* debug level */ - /* debugfs entries */ - struct dentry *debugfs_phydir; - struct dentry *debugfs_debug; - struct dentry *debugfs_registers; - struct dentry *debugfs_beacon; - struct dentry *debugfs_reset; - struct dentry *debugfs_antenna; - struct dentry *debugfs_misc; - struct dentry *debugfs_frameerrors; - struct dentry *debugfs_ani; - struct dentry *debugfs_queue; }; /** @@ -140,9 +129,6 @@ enum ath5k_debug_level { void ath5k_debug_init_device(struct ath5k_softc *sc); -void -ath5k_debug_finish_device(struct ath5k_softc *sc); - void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); @@ -166,9 +152,6 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) static inline void ath5k_debug_init_device(struct ath5k_softc *sc) {} -static inline void -ath5k_debug_finish_device(struct ath5k_softc *sc) {} - static inline void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} -- cgit v1.2.3-70-g09d2 From c266c71a9cbdccb40fb6f4c05d4ddaa6226e5eba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:19 +0200 Subject: ath5k: reduce interrupt load caused by rx/tx interrupts While the rx/tx tasklet is pending, new unnecessary interrupts may arrive. Decrease the load by temporarily disabling the interrupts until the tasklet has completed. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 13 ++++++++++ drivers/net/wireless/ath/ath5k/base.c | 45 +++++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath5k/base.h | 4 +++ 3 files changed, 59 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index fcaf4ed84ca..e303db7ee6f 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -872,6 +872,19 @@ enum ath5k_int { AR5K_INT_QTRIG = 0x40000000, /* Non common */ AR5K_INT_GLOBAL = 0x80000000, + AR5K_INT_TX_ALL = AR5K_INT_TXOK + | AR5K_INT_TXDESC + | AR5K_INT_TXERR + | AR5K_INT_TXEOL + | AR5K_INT_TXURN, + + AR5K_INT_RX_ALL = AR5K_INT_RXOK + | AR5K_INT_RXDESC + | AR5K_INT_RXERR + | AR5K_INT_RXNOFRM + | AR5K_INT_RXEOL + | AR5K_INT_RXORN, + AR5K_INT_COMMON = AR5K_INT_RXOK | AR5K_INT_RXDESC | AR5K_INT_RXERR diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a799d04e0c8..c7da0045439 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1443,6 +1443,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) return true; } +static void +ath5k_set_current_imask(struct ath5k_softc *sc) +{ + enum ath5k_int imask = sc->imask; + unsigned long flags; + + spin_lock_irqsave(&sc->irqlock, flags); + if (sc->rx_pending) + imask &= ~AR5K_INT_RX_ALL; + if (sc->tx_pending) + imask &= ~AR5K_INT_TX_ALL; + ath5k_hw_set_imr(sc->ah, imask); + spin_unlock_irqrestore(&sc->irqlock, flags); +} + static void ath5k_tasklet_rx(unsigned long data) { @@ -1506,6 +1521,8 @@ next: } while (ath5k_rxbuf_setup(sc, bf) == 0); unlock: spin_unlock(&sc->rxbuflock); + sc->rx_pending = false; + ath5k_set_current_imask(sc); } @@ -1693,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data) for (i=0; i < AR5K_NUM_TX_QUEUES; i++) if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) ath5k_tx_processq(sc, &sc->txqs[i]); + + sc->tx_pending = false; + ath5k_set_current_imask(sc); } @@ -2122,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ } +static void +ath5k_schedule_rx(struct ath5k_softc *sc) +{ + sc->rx_pending = true; + tasklet_schedule(&sc->rxtq); +} + +static void +ath5k_schedule_tx(struct ath5k_softc *sc) +{ + sc->tx_pending = true; + tasklet_schedule(&sc->txtq); +} + irqreturn_t ath5k_intr(int irq, void *dev_id) { @@ -2164,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id) ieee80211_queue_work(sc->hw, &sc->reset_work); } else - tasklet_schedule(&sc->rxtq); + ath5k_schedule_rx(sc); } else { if (status & AR5K_INT_SWBA) { tasklet_hi_schedule(&sc->beacontq); @@ -2182,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id) ath5k_hw_update_tx_triglevel(ah, true); } if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) - tasklet_schedule(&sc->rxtq); + ath5k_schedule_rx(sc); if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | AR5K_INT_TXERR | AR5K_INT_TXEOL)) - tasklet_schedule(&sc->txtq); + ath5k_schedule_tx(sc); if (status & AR5K_INT_BMISS) { /* TODO */ } @@ -2204,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id) } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); + if (sc->rx_pending || sc->tx_pending) + ath5k_set_current_imask(sc); + if (unlikely(!counter)) ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); @@ -2575,6 +2612,8 @@ done: static void stop_tasklets(struct ath5k_softc *sc) { + sc->rx_pending = false; + sc->tx_pending = false; tasklet_kill(&sc->rxtq); tasklet_kill(&sc->txtq); tasklet_kill(&sc->calib); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 978f1f4ac2f..4c4e36064a3 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -207,6 +207,10 @@ struct ath5k_softc { enum ath5k_int imask; /* interrupt mask copy */ + spinlock_t irqlock; + bool rx_pending; /* rx tasklet pending */ + bool tx_pending; /* tx tasklet pending */ + u8 lladdr[ETH_ALEN]; u8 bssidmask[ETH_ALEN]; -- cgit v1.2.3-70-g09d2 From 0f8e94d2ae4f7966d09c8105ccabb3b3d8238a4d Mon Sep 17 00:00:00 2001 From: roel Date: Sun, 10 Apr 2011 21:09:50 +0200 Subject: ath9k_hw: index out of bounds Check whether index is within bounds before testing the element Both spurChans arrays in modalHeader5G and modalHeader2G have 5 elements, AR_EEPROM_MODAL_SPURS is defined 5. So unless a break occurs, in the last iteration (i=5) we tried to access spurChansPtr[5] before testing whether i was within bounds. Fix this. Signed-off-by: Roel Kluin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eb250d6b803..93398de0bf6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -401,7 +401,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, ar9003_hw_spur_ofdm_clear(ah); - for (i = 0; spurChansPtr[i] && i < 5; i++) { + for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; if (abs(freq_offset) < range) { ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); -- cgit v1.2.3-70-g09d2 From f0bce44f5f2eb37dba58aa992d0c58da92ded201 Mon Sep 17 00:00:00 2001 From: roel Date: Sun, 10 Apr 2011 21:09:55 +0200 Subject: ath9k: index out of bounds Check whether index is within bounds before testing the element Signed-off-by: Roel Kluin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a3241cd089b..2a40532126f 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1092,8 +1092,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, if (!(rate->flags & IEEE80211_TX_RC_MCS)) return rate->idx; - while (rate->idx > mcs_rix_off[i] && - i < ARRAY_SIZE(mcs_rix_off)) { + while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { rix++; i++; } -- cgit v1.2.3-70-g09d2 From 228bdfca9a09c1263c24509b4bc23a67be168e1a Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Sun, 10 Apr 2011 18:30:23 -0500 Subject: rtlwifi: rtl8192ce: Fix LED initialization Driver rtl8192ce does not initialize the LED correctly. Signed-off-by: Chaoming Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 12 +++++++----- drivers/net/wireless/rtlwifi/pci.c | 3 ++- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 14 +++++++++++--- drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 1 - drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 - 5 files changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index dd5318ed787..9477785f116 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -251,14 +251,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) bool blocked; u8 valid = 0; - radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + /*set init state to on */ + rtlpriv->rfkill.rfkill_state = 1; + wiphy_rfkill_set_hw_state(hw->wiphy, 0); - /*set init state to that of switch */ - rtlpriv->rfkill.rfkill_state = radio_state; - printk(KERN_INFO "rtlwifi: wireless switch is %s\n", - rtlpriv->rfkill.rfkill_state ? "on" : "off"); + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); if (valid) { + printk(KERN_INFO "rtlwifi: wireless switch is %s\n", + rtlpriv->rfkill.rfkill_state ? "on" : "off"); + rtlpriv->rfkill.rfkill_state = radio_state; blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index efded435d59..59a150ce306 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1785,7 +1785,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_pci_deinit(hw); rtl_deinit_core(hw); - rtlpriv->cfg->ops->deinit_sw_leds(hw); + if (rtlpriv->cfg->ops->deinit_sw_leds) + rtlpriv->cfg->ops->deinit_sw_leds(hw); _rtl_pci_io_handler_release(hw); rtlpriv->cfg->ops->deinit_sw_vars(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 7b1da8d7508..d21b934b5c3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -32,6 +32,14 @@ #include "reg.h" #include "led.h" +static void _rtl92ce_init_led(struct ieee80211_hw *hw, + struct rtl_led *pled, enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) { u8 ledcfg; @@ -97,10 +105,10 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) { -} + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); -void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) -{ + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); } void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 10da3018f4b..94332b3af5b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -31,7 +31,6 @@ #define __RTL92CE_LED_H__ void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); -void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b1cc4d44f53..f4e2f3dccca 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -131,7 +131,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .enable_hw_sec = rtl92ce_enable_hw_security_config, .set_key = rtl92ce_set_key, .init_sw_leds = rtl92ce_init_sw_leds, - .deinit_sw_leds = rtl92ce_deinit_sw_leds, .get_bbreg = rtl92c_phy_query_bb_reg, .set_bbreg = rtl92c_phy_set_bb_reg, .get_rfreg = rtl92ce_phy_query_rf_reg, -- cgit v1.2.3-70-g09d2 From 3dfd7f606645279c788f48cfdfdf9565ec72c4f0 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 11 Apr 2011 16:39:40 +0530 Subject: ath9k: Implement integer mode for AR9485 This fixes random disconnect. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 15 ++++++++-- drivers/net/wireless/ath/ath9k/hw.c | 45 +++++++++++++++++++---------- drivers/net/wireless/ath/ath9k/phy.h | 1 - drivers/net/wireless/ath/ath9k/reg.h | 31 ++++++++++++++++---- 4 files changed, 67 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 93398de0bf6..1bc33f51e46 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -75,9 +75,18 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) freq = centers.synth_center; if (freq < 4800) { /* 2 GHz, fractional mode */ - if (AR_SREV_9485(ah)) - channelSel = CHANSEL_2G_9485(freq); - else + if (AR_SREV_9485(ah)) { + u32 chan_frac; + + /* + * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 + * ndiv = ((chan_mhz * 4) / 3) / freq_ref; + * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 + */ + channelSel = (freq * 4) / 120; + chan_frac = (((freq * 4) % 120) * 0x20000) / 120; + channelSel = (channelSel << 17) | chan_frac; + } else channelSel = CHANSEL_2G(freq); /* Set to 2G mode */ bMode = 1; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1b5bd13b0a6..3a8c41c782e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -676,42 +676,55 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); -#define DPLL2_KD_VAL 0x3D -#define DPLL2_KI_VAL 0x06 -#define DPLL3_PHASE_SHIFT_VAL 0x1 - +#define DPLL3_PHASE_SHIFT_VAL 0x1 static void ath9k_hw_init_pll(struct ath_hw *ah, struct ath9k_channel *chan) { u32 pll; if (AR_SREV_9485(ah)) { - REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); - REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); - - REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, - AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); - REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); - udelay(1000); + /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_PLL_PWD, 0x1); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KD, 0x40); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KI, 0x4); - REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_REFDIV, 0x5); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_NINI, 0x58); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_NFRAC, 0x0); REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, - AR_CH0_DPLL2_KD, DPLL2_KD_VAL); + AR_CH0_BB_DPLL2_OUTDIV, 0x1); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, - AR_CH0_DPLL2_KI, DPLL2_KI_VAL); + AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); + /* program BB PLL phase_shift to 0x6 */ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, - AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); - REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); + AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_PLL_PWD, 0x0); udelay(1000); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, + AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); } pll = ath9k_hw_compute_pll_control(ah, chan); REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); + if (AR_SREV_9485(ah)) + udelay(1000); + /* Switch the core clock for ar9271 to 117Mhz */ if (AR_SREV_9271(ah)) { udelay(500); diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index f50e2c29f71..8e5fe9d7f17 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -19,7 +19,6 @@ #define CHANSEL_DIV 15 #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) -#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV) #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) #define AR_PHY_BASE 0x9800 diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 2fbbe8842bb..6acbf0e2240 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1086,14 +1086,35 @@ enum { #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 #define AR_ENT_OTP_MPSD 0x00800000 -#define AR_CH0_BB_DPLL2 0x16184 + +#define AR_CH0_BB_DPLL1 0x16180 +#define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 +#define AR_CH0_BB_DPLL1_REFDIV_S 27 +#define AR_CH0_BB_DPLL1_NINI 0x07FC0000 +#define AR_CH0_BB_DPLL1_NINI_S 18 +#define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF +#define AR_CH0_BB_DPLL1_NFRAC_S 0 + +#define AR_CH0_BB_DPLL2 0x16184 +#define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000 +#define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30 +#define AR_CH0_DPLL2_KI 0x3C000000 +#define AR_CH0_DPLL2_KI_S 26 +#define AR_CH0_DPLL2_KD 0x03F80000 +#define AR_CH0_DPLL2_KD_S 19 +#define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000 +#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18 +#define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000 +#define AR_CH0_BB_DPLL2_PLL_PWD_S 16 +#define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000 +#define AR_CH0_BB_DPLL2_OUTDIV_S 13 + #define AR_CH0_BB_DPLL3 0x16188 +#define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000 +#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23 + #define AR_CH0_DDR_DPLL2 0x16244 #define AR_CH0_DDR_DPLL3 0x16248 -#define AR_CH0_DPLL2_KD 0x03F80000 -#define AR_CH0_DPLL2_KD_S 19 -#define AR_CH0_DPLL2_KI 0x3C000000 -#define AR_CH0_DPLL2_KI_S 26 #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 #define AR_PHY_CCA_NOM_VAL_2GHZ -118 -- cgit v1.2.3-70-g09d2 From 2d05a0c2b4ac614cb5e0eba75d39a37205d129e8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:28 +0530 Subject: ath9k_hw: Remove unused code in AR9287 eeprom Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 2f0712ea49a..13579752a30 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -858,35 +858,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct modal_eep_ar9287_header *pModal = &eep->modalHeader; - u16 antWrites[AR9287_ANT_16S]; u32 regChainOffset, regval; u8 txRxAttenLocal; - int i, j, offset_num; + int i; pModal = &eep->modalHeader; - antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); - antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); - antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); - antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); - antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); - antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); - antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); - antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); - - offset_num = 8; - - for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); - antWrites[j++] = 0; - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); - antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); - } - REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); for (i = 0; i < AR9287_MAX_CHAINS; i++) { -- cgit v1.2.3-70-g09d2 From 5fb32faf821586312dc0b51a64bfa17ad0633daf Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:29 +0530 Subject: ath9k_hw: update Ar9003 intervals to fix carrier leak Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 96 +++++++++++----------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 9ecca93392e..7f30bc68643 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = { static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, @@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -1392,14 +1392,14 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -- cgit v1.2.3-70-g09d2 From 901c1113da1efc98881233a8a67f98286a0b766a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:30 +0530 Subject: ath9k_hw: update AR9003 low_ob_db_tx_gain to improve spur performance Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 100 ++++++++++----------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 7f30bc68643..f915a3dbfca 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1307,9 +1307,9 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -1361,44 +1361,44 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, + {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, -- cgit v1.2.3-70-g09d2 From b3ba44c6d1633692b45910ee77064e635e2c3143 Mon Sep 17 00:00:00 2001 From: Mark Davis Date: Tue, 12 Apr 2011 00:19:10 -0400 Subject: rt2800usb: Add seven new USB IDs Adds USB IDs for seven previously missing devices. Additionally, all instances of 'Conceptronic' have been replaced by the OEM name. Devices added are.. 0411:01a2 - Buffalo WLI-UC-GNM, RT3070V 0586:341e - ZyXEL NWD2105, RT3070 13b1:002f - Linksys AE1000, RT3572 13b1:0031 - Cisco / Linksys AM10, RT3072 14b2:3c2c - Keebox W150NU / Alpha Networks WUS-N12, RT3070 157e:3013 - TRENDnet TEW-645UB, RT2770+RT2720 15a9:0012 - Airlink AWLL7025 / Gemtek WUBR-208N, RT2870+RT2850 Signed-off-by: Mark Davis Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 35 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6ba31a0e8f7..d2f5c87305a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -710,6 +710,16 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Alpha Networks */ + { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c2c), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amit */ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Askey */ @@ -736,15 +746,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Buffalo */ { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0411, 0x01a2), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -776,6 +778,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Gemtek */ + { USB_DEVICE(0x15a9, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Gigabyte */ { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -792,6 +796,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Linksys */ + { USB_DEVICE(0x13b1, 0x0031), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Logitec */ @@ -870,8 +875,9 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sweex */ { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* U-Media*/ + /* U-Media */ { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x157e, 0x3013), USB_DEVICE_DATA(&rt2800usb_ops) }, /* ZCOM */ { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -883,6 +889,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Zyxel */ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0586, 0x341e), USB_DEVICE_DATA(&rt2800usb_ops) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -901,6 +908,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, /* I-O DATA */ { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Linksys */ + { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ @@ -915,6 +924,9 @@ static struct usb_device_id rt2800usb_device_table[] = { * Unclear what kind of devices these are (they aren't supported by the * vendor linux driver). */ + /* Alpha Networks */ + { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amigo */ { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -933,9 +945,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Corega */ { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, -- cgit v1.2.3-70-g09d2 From 6f11c819d5fb24b637f2db605e5d3c270c979627 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 12 Apr 2011 12:42:22 +0530 Subject: ath9k: Register id table for platform device Currently the device id in the platform driver is hardcoded to an id which is specific to AR9130/AR9132 SOCs as it supports only wmac (wireless mac) of these SOCs. But this needs to be dynamic when we want to support different wmac of SOCs. So add id_table to driver to make it extendable to more SOCs. Signed-off-by: Vasanthakumar Thiagarajan Acked-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cb0efa9b4c..5193ed58a17 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -21,6 +21,14 @@ #include #include "ath9k.h" +const struct platform_device_id ath9k_platform_id_table[] = { + { + .name = "ath9k", + .driver_data = AR5416_AR9100_DEVID, + }, + {}, +}; + /* return bus cachesize in 4B word units */ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) { @@ -57,6 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev) struct ath_softc *sc; struct ieee80211_hw *hw; struct resource *res; + const struct platform_device_id *id = platform_get_device_id(pdev); int irq; int ret = 0; struct ath_hw *ah; @@ -116,7 +125,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_free_hw; } - ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); + ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); if (ret) { dev_err(&pdev->dev, "failed to initialize device\n"); goto err_irq; @@ -165,8 +174,11 @@ static struct platform_driver ath_ahb_driver = { .name = "ath9k", .owner = THIS_MODULE, }, + .id_table = ath9k_platform_id_table, }; +MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table); + int ath_ahb_init(void) { return platform_driver_register(&ath_ahb_driver); -- cgit v1.2.3-70-g09d2 From 8962d87129ec0a820d17ac44cbf3f51010ad8db8 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 13 Apr 2011 08:47:32 -0400 Subject: ath5k: improve comments for optimized tx descriptor setup Comment the use of local variables to reduce the number of load/store operations on uncached memory, in hopes of not losing this optimization accidentally in the future. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 0391813befd..dd7cd95c364 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -184,6 +184,11 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; + + /* + * Use local variables for these to reduce load/store access on + * uncached memory + */ u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; @@ -209,7 +214,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (tx_power > AR5K_TUNE_MAX_TXPOWER) tx_power = AR5K_TUNE_MAX_TXPOWER; - /* Clear descriptor */ + /* Clear descriptor status area */ memset(&desc->ud.ds_tx5212.tx_stat, 0, sizeof(desc->ud.ds_tx5212.tx_stat)); -- cgit v1.2.3-70-g09d2 From 0733119c0bed37eda4bb832d049939a0dc53a233 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 5 Apr 2011 22:29:31 -0300 Subject: Bluetooth: Clean up ath3k_load_firmware() Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 5577ed656e2..695d4414bd4 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -138,9 +138,6 @@ static int ath3k_load_firmware(struct usb_device *udev, count -= size; } - kfree(send_buf); - return 0; - error: kfree(send_buf); return err; -- cgit v1.2.3-70-g09d2 From 78b4a56c28c096a1eb02f1d864eb450eb910e43d Mon Sep 17 00:00:00 2001 From: Jiejing Zhang Date: Thu, 7 Apr 2011 20:37:06 +0800 Subject: Bluetooth: hci_uart: check the return value of recv() Check the return value of hu->proto->recv() in hci_uart_tty_receive() the recv() may return error, check it, not add this to statistics. Signed-off-by: Jiejing Zhang Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_ath.c | 7 ++++++- drivers/bluetooth/hci_ldisc.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index bd34406faaa..4093935ddf4 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) /* Recv data */ static int ath_recv(struct hci_uart *hu, void *data, int count) { - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + int ret; + + ret = hci_recv_stream_fragment(hu->hdev, data, count); + if (ret < 0) { BT_ERR("Frame Reassembly Failed"); + return ret; + } return count; } diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 48ad2a7ab08..320f71803a2 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -359,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) */ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) { + int ret; struct hci_uart *hu = (void *)tty->disc_data; if (!hu || tty != hu->tty) @@ -368,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f return; spin_lock(&hu->rx_lock); - hu->proto->recv(hu, (void *) data, count); - hu->hdev->stat.byte_rx += count; + ret = hu->proto->recv(hu, (void *) data, count); + if (ret > 0) + hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); tty_unthrottle(tty); -- cgit v1.2.3-70-g09d2 From b86ed368f1f0b19de1918c57e4b056e73d5613a0 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 7 Apr 2011 18:53:45 -0300 Subject: Bluetooth: Check return value of hci_recv_stream_fragment() It may return error and in this case we do add to the stats. Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_h4.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 7b8ad93e2c3..2fcd8b387d6 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) /* Recv data */ static int h4_recv(struct hci_uart *hu, void *data, int count) { - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + int ret; + + ret = hci_recv_stream_fragment(hu->hdev, data, count); + if (ret < 0) { BT_ERR("Frame Reassembly Failed"); + return ret; + } return count; } -- cgit v1.2.3-70-g09d2 From 9f72c1d977e47a7d182d49ea131067cba0a96ab8 Mon Sep 17 00:00:00 2001 From: Kevin Gan Date: Fri, 8 Apr 2011 18:19:33 -0700 Subject: Bluetooth: btmrvl: support Marvell Bluetooth device SD8787 The SD8787 firmware image is shared with mwifiex driver. Whoever gets loaded first will be responsible for firmware downloading. Signed-off-by: Kevin Gan Signed-off-by: Tristan Xu Signed-off-by: Bing Zhao Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/Kconfig | 4 +- drivers/bluetooth/btmrvl_sdio.c | 124 ++++++++++++++++++++++++++++++---------- drivers/bluetooth/btmrvl_sdio.h | 68 +++++++++++----------- 3 files changed, 132 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 8e0de9a0586..11b41fd40c2 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -188,7 +188,7 @@ config BT_MRVL The core driver to support Marvell Bluetooth devices. This driver is required if you want to support - Marvell Bluetooth devices, such as 8688. + Marvell Bluetooth devices, such as 8688/8787. Say Y here to compile Marvell Bluetooth driver into the kernel or say M to compile it as module. @@ -201,7 +201,7 @@ config BT_MRVL_SDIO The driver for Marvell Bluetooth chipsets with SDIO interface. This driver is required if you want to use Marvell Bluetooth - devices with SDIO interface. Currently only SD8688 chipset is + devices with SDIO interface. Currently SD8688/SD8787 chipsets are supported. Say Y here to compile support for Marvell BT-over-SDIO driver diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index dcc2a6ec23f..7f521d4ac65 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -49,15 +49,59 @@ static u8 user_rmmod; static u8 sdio_ireg; +static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { + .cfg = 0x03, + .host_int_mask = 0x04, + .host_intstatus = 0x05, + .card_status = 0x20, + .sq_read_base_addr_a0 = 0x10, + .sq_read_base_addr_a1 = 0x11, + .card_fw_status0 = 0x40, + .card_fw_status1 = 0x41, + .card_rx_len = 0x42, + .card_rx_unit = 0x43, + .io_port_0 = 0x00, + .io_port_1 = 0x01, + .io_port_2 = 0x02, +}; +static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { + .cfg = 0x00, + .host_int_mask = 0x02, + .host_intstatus = 0x03, + .card_status = 0x30, + .sq_read_base_addr_a0 = 0x40, + .sq_read_base_addr_a1 = 0x41, + .card_revision = 0x5c, + .card_fw_status0 = 0x60, + .card_fw_status1 = 0x61, + .card_rx_len = 0x62, + .card_rx_unit = 0x63, + .io_port_0 = 0x78, + .io_port_1 = 0x79, + .io_port_2 = 0x7a, +}; + static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { .helper = "sd8688_helper.bin", .firmware = "sd8688.bin", + .reg = &btmrvl_reg_8688, + .sd_blksz_fw_dl = 64, +}; + +static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { + .helper = NULL, + .firmware = "mrvl/sd8787_uapsta.bin", + .reg = &btmrvl_reg_8787, + .sd_blksz_fw_dl = 256, }; static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8688 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, + /* Marvell SD8787 Bluetooth device */ + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), + .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, { } /* Terminating entry */ }; @@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) u8 reg; int ret; - reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret); + reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret); if (!ret) card->rx_unit = reg; @@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) *dat = 0; - fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); + fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); if (ret) return -EIO; - fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); + fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret); if (ret) return -EIO; @@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) u8 reg; int ret; - reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret); + reg = sdio_readb(card->func, card->reg->card_rx_len, &ret); if (!ret) *dat = (u16) reg << card->rx_unit; @@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, { int ret; - sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret); + sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret); if (ret) { BT_ERR("Unable to enable the host interrupt!"); ret = -EIO; @@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, u8 host_int_mask; int ret; - host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); + host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret); if (ret) return -EIO; host_int_mask &= ~mask; - sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); + sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret); if (ret < 0) { BT_ERR("Unable to disable the host interrupt!"); return -EIO; @@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits) int ret; for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { - status = sdio_readb(card->func, CARD_STATUS_REG, &ret); + status = sdio_readb(card->func, card->reg->card_status, &ret); if (ret) goto failed; if ((status & bits) == bits) @@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) u8 base0, base1; void *tmpfwbuf = NULL; u8 *fwbuf; - u16 len; + u16 len, blksz_dl = card->sd_blksz_fw_dl; int txlen = 0, tx_blocks = 0, count = 0; ret = request_firmware(&fw_firmware, card->firmware, @@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) for (tries = 0; tries < MAX_POLL_TRIES; tries++) { base0 = sdio_readb(card->func, - SQ_READ_BASE_ADDRESS_A0_REG, &ret); + card->reg->sq_read_base_addr_a0, &ret); if (ret) { BT_ERR("BASE0 register read failed:" " base0 = 0x%04X(%d)." @@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) goto done; } base1 = sdio_readb(card->func, - SQ_READ_BASE_ADDRESS_A1_REG, &ret); + card->reg->sq_read_base_addr_a1, &ret); if (ret) { BT_ERR("BASE1 register read failed:" " base1 = 0x%04X(%d)." @@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) if (firmwarelen - offset < txlen) txlen = firmwarelen - offset; - tx_blocks = - (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE; + tx_blocks = (txlen + blksz_dl - 1) / blksz_dl; memcpy(fwbuf, &firmware[offset], txlen); } ret = sdio_writesb(card->func, card->ioport, fwbuf, - tx_blocks * SDIO_BLOCK_SIZE); + tx_blocks * blksz_dl); if (ret < 0) { BT_ERR("FW download, writesb(%d) failed @%d", count, offset); - sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, - &ret); + sdio_writeb(card->func, HOST_CMD53_FIN, + card->reg->cfg, &ret); if (ret) BT_ERR("writeb failed (CFG)"); } @@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) priv = card->priv; - ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); + ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); if (ret) { BT_ERR("sdio_readb: read int status register failed"); return; @@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), - HOST_INTSTATUS_REG, &ret); + card->reg->host_intstatus, &ret); if (ret) { BT_ERR("sdio_writeb: clear int status register failed"); return; @@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) goto release_irq; } - reg = sdio_readb(func, IO_PORT_0_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_0, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) card->ioport = reg; - reg = sdio_readb(func, IO_PORT_1_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_1, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) card->ioport |= (reg << 8); - reg = sdio_readb(func, IO_PORT_2_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_2, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -815,6 +858,8 @@ exit: static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) { int ret = 0; + u8 fws0; + int pollnum = MAX_POLL_TRIES; if (!card || !card->func) { BT_ERR("card or function is NULL!"); @@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) goto done; } - ret = btmrvl_sdio_download_helper(card); + /* Check if other function driver is downloading the firmware */ + fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); if (ret) { - BT_ERR("Failed to download helper!"); + BT_ERR("Failed to read FW downloading status!"); ret = -EIO; goto done; } + if (fws0) { + BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0); + + /* Give other function more time to download the firmware */ + pollnum *= 10; + } else { + if (card->helper) { + ret = btmrvl_sdio_download_helper(card); + if (ret) { + BT_ERR("Failed to download helper!"); + ret = -EIO; + goto done; + } + } - if (btmrvl_sdio_download_fw_w_helper(card)) { - BT_ERR("Failed to download firmware!"); - ret = -EIO; - goto done; + if (btmrvl_sdio_download_fw_w_helper(card)) { + BT_ERR("Failed to download firmware!"); + ret = -EIO; + goto done; + } } - if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) { + if (btmrvl_sdio_verify_fw_download(card, pollnum)) { BT_ERR("FW failed to be active in time!"); ret = -ETIMEDOUT; goto done; @@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) sdio_claim_host(card->func); - sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret); + sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret); sdio_release_host(card->func); @@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func, if (id->driver_data) { struct btmrvl_sdio_device *data = (void *) id->driver_data; - card->helper = data->helper; + card->helper = data->helper; card->firmware = data->firmware; + card->reg = data->reg; + card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; } if (btmrvl_sdio_register_dev(card) < 0) { @@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION); MODULE_LICENSE("GPL v2"); MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688.bin"); +MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h index 27329f107e5..43d35a609ca 100644 --- a/drivers/bluetooth/btmrvl_sdio.h +++ b/drivers/bluetooth/btmrvl_sdio.h @@ -47,44 +47,46 @@ /* Max retry number of CMD53 write */ #define MAX_WRITE_IOMEM_RETRY 2 -/* Host Control Registers */ -#define IO_PORT_0_REG 0x00 -#define IO_PORT_1_REG 0x01 -#define IO_PORT_2_REG 0x02 - -#define CONFIG_REG 0x03 -#define HOST_POWER_UP BIT(1) -#define HOST_CMD53_FIN BIT(2) - -#define HOST_INT_MASK_REG 0x04 -#define HIM_DISABLE 0xff -#define HIM_ENABLE (BIT(0) | BIT(1)) - -#define HOST_INTSTATUS_REG 0x05 -#define UP_LD_HOST_INT_STATUS BIT(0) -#define DN_LD_HOST_INT_STATUS BIT(1) - -/* Card Control Registers */ -#define SQ_READ_BASE_ADDRESS_A0_REG 0x10 -#define SQ_READ_BASE_ADDRESS_A1_REG 0x11 - -#define CARD_STATUS_REG 0x20 -#define DN_LD_CARD_RDY BIT(0) -#define CARD_IO_READY BIT(3) - -#define CARD_FW_STATUS0_REG 0x40 -#define CARD_FW_STATUS1_REG 0x41 -#define FIRMWARE_READY 0xfedc - -#define CARD_RX_LEN_REG 0x42 -#define CARD_RX_UNIT_REG 0x43 - +/* register bitmasks */ +#define HOST_POWER_UP BIT(1) +#define HOST_CMD53_FIN BIT(2) + +#define HIM_DISABLE 0xff +#define HIM_ENABLE (BIT(0) | BIT(1)) + +#define UP_LD_HOST_INT_STATUS BIT(0) +#define DN_LD_HOST_INT_STATUS BIT(1) + +#define DN_LD_CARD_RDY BIT(0) +#define CARD_IO_READY BIT(3) + +#define FIRMWARE_READY 0xfedc + + +struct btmrvl_sdio_card_reg { + u8 cfg; + u8 host_int_mask; + u8 host_intstatus; + u8 card_status; + u8 sq_read_base_addr_a0; + u8 sq_read_base_addr_a1; + u8 card_revision; + u8 card_fw_status0; + u8 card_fw_status1; + u8 card_rx_len; + u8 card_rx_unit; + u8 io_port_0; + u8 io_port_1; + u8 io_port_2; +}; struct btmrvl_sdio_card { struct sdio_func *func; u32 ioport; const char *helper; const char *firmware; + const struct btmrvl_sdio_card_reg *reg; + u16 sd_blksz_fw_dl; u8 rx_unit; struct btmrvl_private *priv; }; @@ -92,6 +94,8 @@ struct btmrvl_sdio_card { struct btmrvl_sdio_device { const char *helper; const char *firmware; + const struct btmrvl_sdio_card_reg *reg; + u16 sd_blksz_fw_dl; }; -- cgit v1.2.3-70-g09d2 From 12488e01fb2b06bb3f6ee137efc88e29d827817e Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Fri, 8 Apr 2011 14:38:27 +0530 Subject: mwl8k: interrupt handling changes We do not need to enable all the interrupts in mwl8k_probe_hw. We need to enable only MWL8K_A2H_INT_OPC_DONE interrupt for sending commands to the firmware. Keep the other interrupts masked in mwl8k_probe_hw. Also, in mwl8k_start, where we expect other interrupts, enable only those interrupts we are interested in. Signed-off-by: Nishant Sarmukadam Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index fb472f4924d..d2416709ba5 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4284,6 +4284,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) /* Enable interrupts */ iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); + iowrite32(MWL8K_A2H_EVENTS, + priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); rc = mwl8k_fw_lock(hw); if (!rc) { @@ -5282,7 +5284,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| MWL8K_A2H_INT_BA_WATCHDOG, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); - iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); + iowrite32(MWL8K_A2H_INT_OPC_DONE, + priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); -- cgit v1.2.3-70-g09d2 From 8e26a0303614e766f993b1ac4a5bfbf80436d9dd Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 12 Apr 2011 18:23:16 +0200 Subject: ath9k: introduce ATH9K_{PCI,AHB} config options Currently ath9k only available in menuconfig if PCI bus support is enabled. However the driver is required for the built-in wireless MACs of the Atheros AR9130/AR9132 SoCs. These SoCs have no PCI controller, the wireless MAC is connected to the AHB bus on them. Introduce separated config options for the supported buses, in order to allow building of ath9h without PCI bus support. As a bonus, this patch removes the cross-reference of the ATHEROS_AR71XX option which is not present in the kernel. Cc: Luis R. Rodriguez Cc: Vasanthakumar Thiagarajan Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 21 ++++++++++++++++++++- drivers/net/wireless/ath/ath9k/Makefile | 4 ++-- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ad57a6d2311..d9ff8413ab9 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -5,7 +5,7 @@ config ATH9K_COMMON config ATH9K tristate "Atheros 802.11n wireless cards support" - depends on PCI && MAC80211 + depends on MAC80211 select ATH9K_HW select MAC80211_LEDS select LEDS_CLASS @@ -23,6 +23,25 @@ config ATH9K If you choose to build a module, it'll be called ath9k. +config ATH9K_PCI + bool "Atheros ath9k PCI/PCIe bus support" + depends on ATH9K && PCI + default PCI + ---help--- + This option enables the PCI bus support in ath9k. + + Say Y, if you have a compatible PCI/PCIe wireless card. + +config ATH9K_AHB + bool "Atheros ath9k AHB bus support" + depends on ATH9K + default n + ---help--- + This option enables the AHB bus support in ath9k. + + Say Y, if you have a SoC with a compatible built-in + wireless MAC. Say N if unsure. + config ATH9K_DEBUGFS bool "Atheros ath9k debugging" depends on ATH9K && DEBUG_FS diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d66ca8042e..ca4c436e0f6 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -6,8 +6,8 @@ ath9k-y += beacon.o \ xmit.o \ ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o -ath9k-$(CONFIG_PCI) += pci.o -ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o +ath9k-$(CONFIG_ATH9K_PCI) += pci.o +ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o obj-$(CONFIG_ATH9K) += ath9k.o diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 38835bc324b..77ad407e9fa 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -665,7 +665,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); bool ath9k_uses_beacons(int type); -#ifdef CONFIG_PCI +#ifdef CONFIG_ATH9K_PCI int ath_pci_init(void); void ath_pci_exit(void); #else @@ -673,7 +673,7 @@ static inline int ath_pci_init(void) { return 0; }; static inline void ath_pci_exit(void) {}; #endif -#ifdef CONFIG_ATHEROS_AR71XX +#ifdef CONFIG_ATH9K_AHB int ath_ahb_init(void); void ath_ahb_exit(void); #else -- cgit v1.2.3-70-g09d2 From d0805c1c5758f8fd16c88bf1efa8fb4be4408ce1 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Tue, 12 Apr 2011 11:06:28 -0700 Subject: mwl8k: use traffic threshold to decide when to start ampdu Currently, ampdu stream is created on the first qos packet to an HT sta. The overhead of setting up the BA session may not be justified if the outgoing packet rate is minimal (e.g., ping). So we only allow ampdu streams after seeing a critical number of packets in an arbitrary one-second interval. Based on work by Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 45 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index d2416709ba5..28ebaec80be 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -289,10 +289,17 @@ struct mwl8k_vif { #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) +struct tx_traffic_info { + u32 start_time; + u32 pkts; +}; + +#define MWL8K_MAX_TID 8 struct mwl8k_sta { /* Index into station database. Returned by UPDATE_STADB. */ u8 peer_id; u8 is_ampdu_allowed; + struct tx_traffic_info tx_stats[MWL8K_MAX_TID]; }; #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) @@ -1754,6 +1761,41 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) return NULL; } +#define MWL8K_AMPDU_PACKET_THRESHOLD 64 +static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid) +{ + struct mwl8k_sta *sta_info = MWL8K_STA(sta); + struct tx_traffic_info *tx_stats; + + BUG_ON(tid >= MWL8K_MAX_TID); + tx_stats = &sta_info->tx_stats[tid]; + + return sta_info->is_ampdu_allowed && + tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; +} + +static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) +{ + struct mwl8k_sta *sta_info = MWL8K_STA(sta); + struct tx_traffic_info *tx_stats; + + BUG_ON(tid >= MWL8K_MAX_TID); + tx_stats = &sta_info->tx_stats[tid]; + + if (tx_stats->start_time == 0) + tx_stats->start_time = jiffies; + + /* reset the packet count after each second elapses. If the number of + * packets ever exceeds the ampdu_min_traffic threshold, we will allow + * an ampdu stream to be started. + */ + if (jiffies - tx_stats->start_time > HZ) { + tx_stats->pkts = 0; + tx_stats->start_time = 0; + } else + tx_stats->pkts++; +} + static void mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) { @@ -1840,6 +1882,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) skb->protocol != cpu_to_be16(ETH_P_PAE) && sta->ht_cap.ht_supported && priv->ap_fw) { tid = qos & 0xf; + mwl8k_tx_count_packet(sta, tid); spin_lock(&priv->stream_lock); stream = mwl8k_lookup_stream(hw, sta->addr, tid); if (stream != NULL) { @@ -1880,7 +1923,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) * prevents sequence number mismatch at the recepient * as described above. */ - if (MWL8K_STA(sta)->is_ampdu_allowed) { + if (mwl8k_ampdu_allowed(sta, tid)) { stream = mwl8k_add_stream(hw, sta, tid); if (stream != NULL) start_ba_session = true; -- cgit v1.2.3-70-g09d2 From 9efabad2b228ef820f5ce969baa62860cf65b9ea Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:33 +0530 Subject: ath9k_htc: Remove AR7010 v1.0 support All the AR7010 devices supoprted by ath9k_htc are based on version v1.1, so remove support for v1.0. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f1b8af64569..3d53d989962 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -17,11 +17,9 @@ #include "htc.h" /* identify firmware images */ -#define FIRMWARE_AR7010 "ar7010.fw" #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" #define FIRMWARE_AR9271 "ar9271.fw" -MODULE_FIRMWARE(FIRMWARE_AR7010); MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); MODULE_FIRMWARE(FIRMWARE_AR9271); @@ -1026,10 +1024,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, /* Find out which firmware to load */ if (IS_AR7010_DEVICE(id->driver_info)) - if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) - hif_dev->fw_name = FIRMWARE_AR7010_1_1; - else - hif_dev->fw_name = FIRMWARE_AR7010; + hif_dev->fw_name = FIRMWARE_AR7010_1_1; else hif_dev->fw_name = FIRMWARE_AR9271; -- cgit v1.2.3-70-g09d2 From ce18f391aa872a910e7798c340b6cf22d02c77a2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:42 +0530 Subject: ath9k_htc: Rename firmware Since the new FW requires backward incompatible host driver changes, rename the FW to allow older driver versions to work with the older FW. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 3d53d989962..23094b70d6e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -17,8 +17,8 @@ #include "htc.h" /* identify firmware images */ -#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" -#define FIRMWARE_AR9271 "ar9271.fw" +#define FIRMWARE_AR7010_1_1 "htc_7010.fw" +#define FIRMWARE_AR9271 "htc_9271.fw" MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); MODULE_FIRMWARE(FIRMWARE_AR9271); -- cgit v1.2.3-70-g09d2 From 29bbfb2491316f9a3888e74b0de7fccdbde67aaa Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:51 +0530 Subject: ath9k_htc: Add a WMI command to get the firmware version Also, update the wiphy information and use the correct device pointer when registering. This would fix ethtool. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 +++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 32 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/wmi.c | 2 ++ drivers/net/wireless/ath/ath9k/wmi.h | 6 +++++ 4 files changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ec47be94b74..9544cd7fd44 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -388,6 +388,9 @@ struct ath9k_htc_priv { struct htc_target *htc; struct wmi *wmi; + u16 fw_version_major; + u16 fw_version_minor; + enum htc_endpoint_id wmi_cmd_ep; enum htc_endpoint_id beacon_ep; enum htc_endpoint_id cab_ep; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8303b34bdc9..6bbfca58ded 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -782,6 +782,32 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } +static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) +{ + struct ieee80211_hw *hw = priv->hw; + struct wmi_fw_version cmd_rsp; + int ret; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_GET_FW_VERSION); + if (ret) + return -EINVAL; + + priv->fw_version_major = be16_to_cpu(cmd_rsp.major); + priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor); + + snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d", + priv->fw_version_major, + priv->fw_version_minor); + + dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n", + priv->fw_version_major, + priv->fw_version_minor); + + return 0; +} + static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid, char *product, u32 drv_info) { @@ -801,6 +827,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, common = ath9k_hw_common(ah); ath9k_set_hw_capab(priv, hw); + error = ath9k_init_firmware_version(priv); + if (error != 0) + goto err_fw; + /* Initialize regulatory */ error = ath_regd_init(&common->regulatory, priv->hw->wiphy, ath9k_reg_notifier); @@ -861,6 +891,8 @@ err_rx: err_tx: /* Nothing */ err_regd: + /* Nothing */ +err_fw: ath9k_deinit_priv(priv); err_init: return error; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index d3d24904f62..267a98fcf5f 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -23,6 +23,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_ECHO_CMDID"; case WMI_ACCESS_MEMORY_CMDID: return "WMI_ACCESS_MEMORY_CMDID"; + case WMI_GET_FW_VERSION: + return "WMI_GET_FW_VERSION"; case WMI_DISABLE_INTR_CMDID: return "WMI_DISABLE_INTR_CMDID"; case WMI_ENABLE_INTR_CMDID: diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 42084277522..6a36572b6fb 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -31,11 +31,17 @@ struct wmi_cmd_hdr { __be16 seq_no; } __packed; +struct wmi_fw_version { + __be16 major; + __be16 minor; + +} __packed; enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, /* Commands to Target */ + WMI_GET_FW_VERSION, WMI_DISABLE_INTR_CMDID, WMI_ENABLE_INTR_CMDID, WMI_RX_LINK_CMDID, -- cgit v1.2.3-70-g09d2 From 1c165c972b040f9ce199b8d8d3cc4f619872cba5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:59 +0530 Subject: ath9k_htc: Fix WMI and beacon header Match the beacon header with that of the firmware. Also, the firmware reports the TSF for an SWBA, so store it. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/wmi.c | 7 ++++++- drivers/net/wireless/ath/ath9k/wmi.h | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 9544cd7fd44..cf7909ec076 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -96,8 +96,8 @@ struct tx_mgmt_hdr { } __packed; struct tx_beacon_header { - u8 len_changed; u8 vif_index; + u8 len_changed; u16 rev; } __packed; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 267a98fcf5f..96171a2c687 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -156,6 +156,7 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi_cmd_hdr *hdr; u16 cmd_id; void *wmi_event; + struct wmi_event_swba *swba; #ifdef CONFIG_ATH9K_HTC_DEBUGFS __be32 txrate; #endif @@ -170,7 +171,11 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); switch (cmd_id) { case WMI_SWBA_EVENTID: - wmi->beacon_pending = *(u8 *)wmi_event; + swba = (struct wmi_event_swba *) wmi_event; + + wmi->tsf = be64_to_cpu(swba->tsf); + wmi->beacon_pending = swba->beacon_pending; + tasklet_schedule(&wmi->drv_priv->swba_tasklet); break; case WMI_FATAL_EVENTID: diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 6a36572b6fb..2fa91a941a7 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -36,6 +36,11 @@ struct wmi_fw_version { __be16 minor; } __packed; + +struct wmi_event_swba { + __be64 tsf; + u8 beacon_pending; +}; enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -106,6 +111,7 @@ struct wmi { u32 cmd_rsp_len; bool stopped; + u64 tsf; u8 beacon_pending; spinlock_t wmi_lock; -- cgit v1.2.3-70-g09d2 From 832f6a18fc2aead14954c081ece03b7a5b425f81 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:08 +0530 Subject: ath9k_htc: Add beacon slots Beacon transmission is now handled through a slot mechanism. This allows multiple beaconing interfaces to be be present. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 13 ++- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 123 +++++++++++++++++++++--- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 5 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 ++- drivers/net/wireless/ath/ath9k/wmi.c | 4 +- 5 files changed, 138 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index cf7909ec076..31c649605d7 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -244,6 +244,7 @@ struct ath9k_htc_vif { u8 index; u16 seq_no; bool beacon_configured; + int bslot; }; struct ath9k_vif_iter_data { @@ -351,10 +352,14 @@ struct ath_led { int brightness; }; +#define BSTUCK_THRESHOLD 10 + struct htc_beacon_config { + struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; u16 beacon_interval; u16 dtim_period; u16 bmiss_timeout; + u32 bmiss_cnt; }; struct ath_btcoex { @@ -414,7 +419,6 @@ struct ath9k_htc_priv { u16 txpowlimit; u16 nvifs; u16 nstations; - u32 bmiss_cnt; bool rearm_ani; bool reconfig_beacon; @@ -425,7 +429,6 @@ struct ath9k_htc_priv { bool tx_queues_stop; spinlock_t tx_lock; - struct ieee80211_vif *vif; struct htc_beacon_config cur_beacon_conf; unsigned int rxfilter; struct tasklet_struct swba_tasklet; @@ -473,11 +476,15 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) void ath9k_htc_reset(struct ath9k_htc_priv *priv); +void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); +void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); -void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); +void ath9k_htc_swba(struct ath9k_htc_priv *priv); void ath9k_htc_rxep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8f56158e588..b561f703e46 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -172,12 +172,13 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", + "AP Beacon config, intval: %d, nexttbtt: %u " + "imask: 0x%x\n", bss_conf->beacon_interval, nexttbtt, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); - priv->bmiss_cnt = 0; + priv->cur_beacon_conf.bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); } @@ -214,7 +215,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); - priv->bmiss_cnt = 0; + priv->cur_beacon_conf.bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); } @@ -225,9 +226,11 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, dev_kfree_skb_any(skb); } -void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) +static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, + int slot) { - struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; + struct ieee80211_vif *vif; + struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; struct ath9k_htc_tx_ctl tx_ctl; struct ieee80211_tx_info *info; @@ -237,21 +240,18 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); - /* FIXME: Handle BMISS */ - if (beacon_pending != 0) { - priv->bmiss_cnt++; - return; - } - spin_lock_bh(&priv->beacon_lock); + vif = priv->cur_beacon_conf.bslot[slot]; + avp = (struct ath9k_htc_vif *)vif->drv_priv; + if (unlikely(priv->op_flags & OP_SCANNING)) { spin_unlock_bh(&priv->beacon_lock); return; } /* Get a new beacon */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); + beacon = ieee80211_beacon_get(priv->hw, vif); if (!beacon) { spin_unlock_bh(&priv->beacon_lock); return; @@ -276,6 +276,69 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) spin_unlock_bh(&priv->beacon_lock); } +static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + unsigned long flags; + u64 tsf; + u32 tsftu; + u16 intval; + int slot; + + intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; + + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + tsf = priv->wmi->tsf; + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + + tsftu = TSF_TO_TU(tsf >> 32, tsf); + slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; + slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; + + ath_dbg(common, ATH_DBG_BEACON, + "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", + slot, tsf, tsftu, intval); + + return slot; +} + +void ath9k_htc_swba(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + unsigned long flags; + int slot; + + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + if (priv->wmi->beacon_pending != 0) { + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + priv->cur_beacon_conf.bmiss_cnt++; + if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { + ath_dbg(common, ATH_DBG_BEACON, + "Beacon stuck, HW reset\n"); + ath9k_htc_reset(priv); + } + return; + } + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + + if (priv->cur_beacon_conf.bmiss_cnt) { + ath_dbg(common, ATH_DBG_BEACON, + "Resuming beacon xmit after %u misses\n", + priv->cur_beacon_conf.bmiss_cnt); + priv->cur_beacon_conf.bmiss_cnt = 0; + } + + slot = ath9k_htc_choose_bslot(priv); + spin_lock_bh(&priv->beacon_lock); + if (priv->cur_beacon_conf.bslot[slot] == NULL) { + spin_unlock_bh(&priv->beacon_lock); + return; + } + spin_unlock_bh(&priv->beacon_lock); + + ath9k_htc_send_beacon(priv, slot); +} + /* Currently, only for IBSS */ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) { @@ -307,6 +370,42 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) } } +void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + int i = 0; + + spin_lock_bh(&priv->beacon_lock); + for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { + if (priv->cur_beacon_conf.bslot[i] == NULL) { + avp->bslot = i; + break; + } + } + + priv->cur_beacon_conf.bslot[avp->bslot] = vif; + spin_unlock_bh(&priv->beacon_lock); + + ath_dbg(common, ATH_DBG_CONFIG, + "Added interface at beacon slot: %d\n", avp->bslot); +} + +void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + + spin_lock_bh(&priv->beacon_lock); + priv->cur_beacon_conf.bslot[avp->bslot] = NULL; + spin_unlock_bh(&priv->beacon_lock); + + ath_dbg(common, ATH_DBG_CONFIG, + "Removed interface at beacon slot: %d\n", avp->bslot); +} + static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *beacon_configured = (bool *)data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 6bbfca58ded..9405e0ad703 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -643,7 +643,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, { struct ath_hw *ah = NULL; struct ath_common *common; - int ret = 0, csz = 0; + int i, ret = 0, csz = 0; priv->op_flags |= OP_INVALID; @@ -711,6 +711,9 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, if (ret) goto err_queues; + for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) + priv->cur_beacon_conf.bslot[i] = NULL; + ath9k_init_crypto(priv); ath9k_init_channels_rates(priv); ath9k_init_misc(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index db8c0c044e9..293a9b38e22 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1281,9 +1281,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, priv->vif_slot |= (1 << avp->index); priv->nvifs++; - priv->vif = vif; INC_VIF(priv, vif->type); + + if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) + ath9k_htc_assign_bslot(priv, vif); + ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && @@ -1321,9 +1325,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, priv->vif_slot &= ~(1 << avp->index); ath9k_htc_remove_station(priv, vif, NULL); - priv->vif = NULL; DEC_VIF(priv, vif->type); + + if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) + ath9k_htc_remove_bslot(priv, vif); + ath9k_htc_set_opmode(priv); /* diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 96171a2c687..a39552b3077 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -126,7 +126,7 @@ void ath9k_swba_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - ath9k_htc_swba(priv, priv->wmi->beacon_pending); + ath9k_htc_swba(priv); } void ath9k_fatal_work(struct work_struct *work) @@ -173,8 +173,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, case WMI_SWBA_EVENTID: swba = (struct wmi_event_swba *) wmi_event; + spin_lock(&wmi->wmi_lock); wmi->tsf = be64_to_cpu(swba->tsf); wmi->beacon_pending = swba->beacon_pending; + spin_unlock(&wmi->wmi_lock); tasklet_schedule(&wmi->drv_priv->swba_tasklet); break; -- cgit v1.2.3-70-g09d2 From 9b674a0207c9b75ddcdcdb07e46843fac8267507 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:17 +0530 Subject: ath9k_htc: Add TSF adjust capability In multi-interface mode, beacons/probe responses that are sent out must have their timestamp field updated. Calculate the TSF adjustment value for each beaconing interface and set it in the frame properly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 +++ drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 36 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 +++- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 12 ++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 31c649605d7..87e4ca911a5 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -245,6 +245,7 @@ struct ath9k_htc_vif { u16 seq_no; bool beacon_configured; int bslot; + __le64 tsfadjust; }; struct ath9k_vif_iter_data { @@ -480,6 +481,8 @@ void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index b561f703e46..2fad613add5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -234,6 +234,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct tx_beacon_header beacon_hdr; struct ath9k_htc_tx_ctl tx_ctl; struct ieee80211_tx_info *info; + struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; u8 *tx_fhdr; @@ -257,6 +258,13 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, return; } + /* + * Update the TSF adjust value here, the HW will + * add this value for every beacon. + */ + mgmt = (struct ieee80211_mgmt *)beacon->data; + mgmt->u.beacon.timestamp = avp->tsfadjust; + info = IEEE80211_SKB_CB(beacon); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = @@ -406,6 +414,34 @@ void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, "Removed interface at beacon slot: %d\n", avp->bslot); } +/* + * Calculate the TSF adjustment value for all slots + * other than zero. + */ +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; + u64 tsfadjust; + + if (avp->bslot == 0) + return; + + /* + * The beacon interval cannot be different for multi-AP mode, + * and we reach here only for VIF slots greater than zero, + * so beacon_interval is guaranteed to be set in cur_conf. + */ + tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; + avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); + + ath_dbg(common, ATH_DBG_CONFIG, + "tsfadjust is: %llu for bslot: %d\n", + (unsigned long long)tsfadjust, avp->bslot); +} + static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *beacon_configured = (bool *)data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 293a9b38e22..6926ac0d5e5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1291,8 +1291,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && - !(priv->op_flags & OP_ANI_RUNNING)) + !(priv->op_flags & OP_ANI_RUNNING)) { + ath9k_hw_set_tsfadjust(priv->ah, 1); ath9k_htc_start_ani(priv); + } ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1652,6 +1654,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { ath_dbg(common, ATH_DBG_CONFIG, "Beacon enabled for BSS: %pM\n", bss_conf->bssid); + ath9k_htc_set_tsfadjust(priv, vif); priv->op_flags |= OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27ba96a..b3f94850821 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -82,11 +82,12 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr; + struct ieee80211_mgmt *mgmt; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; - struct ath9k_htc_vif *avp; + struct ath9k_htc_vif *avp = NULL; struct ath9k_htc_tx_ctl tx_ctl; enum htc_endpoint_id epid; u16 qnum; @@ -195,6 +196,15 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); + /* + * Set the TSF adjust value for probe response + * frame also. + */ + if (avp && unlikely(ieee80211_is_probe_resp(fc))) { + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.probe_resp.timestamp = avp->tsfadjust; + } + tx_ctl.type = ATH9K_HTC_NORMAL; mgmt_hdr.node_idx = sta_idx; -- cgit v1.2.3-70-g09d2 From 2493a547ee81e6daca812d5dd7cf9357aebc379b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:26 +0530 Subject: ath9k_htc: Configure the beacon queue Set operating parameters (cwmin, cwmax) for the beacon queue in AP mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 77 +++++++++++++++---------- 1 file changed, 46 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 2fad613add5..7aafd217939 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -18,6 +18,50 @@ #define FUDGE 2 +void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + struct ath9k_tx_queue_info qi, qi_be; + + memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); + memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); + + ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); + + if (priv->ah->opmode == NL80211_IFTYPE_AP) { + qi.tqi_aifs = 1; + qi.tqi_cwmin = 0; + qi.tqi_cwmax = 0; + } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { + int qnum = priv->hwq_map[WME_AC_BE]; + + ath9k_hw_get_txq_props(ah, qnum, &qi_be); + + qi.tqi_aifs = qi_be.tqi_aifs; + + /* + * For WIFI Beacon Distribution + * Long slot time : 2x cwmin + * Short slot time : 4x cwmin + */ + if (ah->slottime == ATH9K_SLOT_TIME_20) + qi.tqi_cwmin = 2*qi_be.tqi_cwmin; + else + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + + qi.tqi_cwmax = qi_be.tqi_cwmax; + + } + + if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { + ath_err(ath9k_hw_common(ah), + "Unable to update beacon queue %u!\n", priv->beaconq); + } else { + ath9k_hw_resettxqueue(ah, priv->beaconq); + } +} + + static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, struct htc_beacon_config *bss_conf) { @@ -176,6 +220,8 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, "imask: 0x%x\n", bss_conf->beacon_interval, nexttbtt, imask); + ath9k_htc_beaconq_config(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); priv->cur_beacon_conf.bmiss_cnt = 0; @@ -347,37 +393,6 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv) ath9k_htc_send_beacon(priv, slot); } -/* Currently, only for IBSS */ -void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) -{ - struct ath_hw *ah = priv->ah; - struct ath9k_tx_queue_info qi, qi_be; - int qnum = priv->hwq_map[WME_AC_BE]; - - memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); - memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); - - ath9k_hw_get_txq_props(ah, qnum, &qi_be); - - qi.tqi_aifs = qi_be.tqi_aifs; - /* For WIFI Beacon Distribution - * Long slot time : 2x cwmin - * Short slot time : 4x cwmin - */ - if (ah->slottime == ATH9K_SLOT_TIME_20) - qi.tqi_cwmin = 2*qi_be.tqi_cwmin; - else - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; - qi.tqi_cwmax = qi_be.tqi_cwmax; - - if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { - ath_err(ath9k_hw_common(ah), - "Unable to update beacon queue %u!\n", qnum); - } else { - ath9k_hw_resettxqueue(ah, priv->beaconq); - } -} - void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif) { -- cgit v1.2.3-70-g09d2 From 7d547eb4bb664c5a6b7c8790c2ecb0aec5d15385 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:34 +0530 Subject: ath9k_htc: Handle buffered frames in AP mode Use the CAB endpoint to send buffered multicast or broadcast frames after each SWBA event. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 6 +++- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 43 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 14 ++++++-- 5 files changed, 65 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 87e4ca911a5..a072a9eb3f3 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -292,6 +292,7 @@ struct ath9k_htc_tx_ctl { #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) +#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) @@ -301,6 +302,7 @@ struct ath_tx_stats { u32 skb_queued; u32 skb_completed; u32 skb_dropped; + u32 cab_queued; u32 queue_stats[WME_NUM_AC]; }; @@ -324,6 +326,7 @@ struct ath9k_debug { #define TX_STAT_INC(c) do { } while (0) #define RX_STAT_INC(c) do { } while (0) +#define CAB_STAT_INC do { } while (0) #define TX_QSTAT_INC(c) do { } while (0) @@ -505,7 +508,8 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); -int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); +int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, + struct sk_buff *skb, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 7aafd217939..c96779c2429 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -272,6 +272,48 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, dev_kfree_skb_any(skb); } +static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, + int slot) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ieee80211_vif *vif; + struct sk_buff *skb; + struct ieee80211_hdr *hdr; + int padpos, padsize, ret; + + spin_lock_bh(&priv->beacon_lock); + + vif = priv->cur_beacon_conf.bslot[slot]; + + skb = ieee80211_get_buffered_bc(priv->hw, vif); + + while(skb) { + hdr = (struct ieee80211_hdr *) skb->data; + + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) { + dev_kfree_skb_any(skb); + goto next; + } + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, padpos); + } + + ret = ath9k_htc_tx_start(priv, skb, true); + if (ret != 0) { + ath_dbg(common, ATH_DBG_FATAL, + "Failed to send CAB frame\n"); + dev_kfree_skb_any(skb); + } + next: + skb = ieee80211_get_buffered_bc(priv->hw, vif); + } + + spin_unlock_bh(&priv->beacon_lock); +} + static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int slot) { @@ -390,6 +432,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv) } spin_unlock_bh(&priv->beacon_lock); + ath9k_htc_send_buffered(priv, slot); ath9k_htc_send_beacon(priv, slot); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9405e0ad703..b1c68bff72a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -748,7 +748,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK; + IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 6926ac0d5e5..8f38075d124 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -797,6 +797,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "SKBs dropped", priv->debug.tx_stats.skb_dropped); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CAB queued", + priv->debug.tx_stats.cab_queued); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BE queued", @@ -1054,7 +1057,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb); + ret = ath9k_htc_tx_start(priv, skb, false); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index b3f94850821..0e285589366 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -79,7 +79,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, return error; } -int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) +int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, + struct sk_buff *skb, bool is_cab) { struct ieee80211_hdr *hdr; struct ieee80211_mgmt *mgmt; @@ -170,6 +171,12 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) tx_fhdr = skb_push(skb, sizeof(tx_hdr)); memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); + if (is_cab) { + CAB_STAT_INC; + epid = priv->cab_ep; + goto send; + } + qnum = skb_get_queue_mapping(skb); switch (qnum) { @@ -222,7 +229,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); epid = priv->mgmt_ep; } - +send: return htc_send(priv->htc, skb, epid, &tx_ctl); } @@ -326,7 +333,8 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, } else if ((ep_id == priv->data_bk_ep) || (ep_id == priv->data_be_ep) || (ep_id == priv->data_vi_ep) || - (ep_id == priv->data_vo_ep)) { + (ep_id == priv->data_vo_ep) || + (ep_id == priv->cab_ep)) { skb_pull(skb, sizeof(struct tx_frame_hdr)); } else { ath_err(common, "Unsupported TX EPID: %d\n", ep_id); -- cgit v1.2.3-70-g09d2 From b0a6ba983e3663bf256ca2e79d17bb846878cd9e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:44 +0530 Subject: ath9k_htc: Fix beacon miss under heavy load Transmission of beacons becomes erratic when TX load is high, since the latency involved in the generation of a SWBA interrupt on the target to the actual sending of a beacon is quite high for USB devices. Fix this by adjusting the beacon response time. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 7 +++++ drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 39 +++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index a072a9eb3f3..133fc6dc392 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -358,6 +358,13 @@ struct ath_led { #define BSTUCK_THRESHOLD 10 +/* + * Adjust these when the max. no of beaconing interfaces is + * increased. + */ +#define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ +#define MIN_SWBA_RESPONSE 10 /* in TUs */ + struct htc_beacon_config { struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; u16 beacon_interval; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index c96779c2429..48bc28823f6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -198,6 +198,15 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, intval /= ATH9K_HTC_MAX_BCN_VIF; nexttbtt = intval; + /* + * To reduce beacon misses under heavy TX load, + * set the beacon response time to a larger value. + */ + if (intval > DEFAULT_SWBA_RESPONSE) + priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; + else + priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; + if (priv->op_flags & OP_TSF_RESET) { ath9k_hw_reset_tsf(priv->ah); priv->op_flags &= ~OP_TSF_RESET; @@ -216,9 +225,10 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "AP Beacon config, intval: %d, nexttbtt: %u " + "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " "imask: 0x%x\n", - bss_conf->beacon_interval, nexttbtt, imask); + bss_conf->beacon_interval, nexttbtt, + priv->ah->config.sw_beacon_response_time, imask); ath9k_htc_beaconq_config(priv); @@ -252,12 +262,22 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, nexttbtt += intval; } while (nexttbtt < tsftu); + /* + * Only one IBSS interfce is allowed. + */ + if (intval > DEFAULT_SWBA_RESPONSE) + priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; + else + priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; + if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", - bss_conf->beacon_interval, nexttbtt, imask); + "IBSS Beacon config, intval: %d, nexttbtt: %u, " + "resp_time: %d, imask: 0x%x\n", + bss_conf->beacon_interval, nexttbtt, + priv->ah->config.sw_beacon_response_time, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); @@ -317,6 +337,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int slot) { + struct ath_common *common = ath9k_hw_common(priv->ah); struct ieee80211_vif *vif; struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; @@ -325,6 +346,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; u8 *tx_fhdr; + int ret; memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); @@ -367,7 +389,14 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + ret = htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + if (ret != 0) { + if (ret == -ENOMEM) { + ath_dbg(common, ATH_DBG_BSTUCK, + "Failed to send beacon, no free TX buffer\n"); + } + dev_kfree_skb_any(beacon); + } spin_unlock_bh(&priv->beacon_lock); } -- cgit v1.2.3-70-g09d2 From f4c88991f51e097b6541f998fd23d477999e5886 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:52 +0530 Subject: ath9k_htc: Queue WMI events Use a queue to handle WMI events and schedule a tasklet to process the events. This fixes the race between the WMI event ISR and the SWBA tasklet when the arrival of WMI events in quick succession could overwrite the SWBA data before the tasklet from a previous iteration could have been scheduled. Also, drain the WMI queue properly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 27 +++---- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 3 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 - drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 +- drivers/net/wireless/ath/ath9k/wmi.c | 97 ++++++++++++++++--------- drivers/net/wireless/ath/ath9k/wmi.h | 7 +- 7 files changed, 89 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 133fc6dc392..20511af33f5 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -497,7 +497,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); -void ath9k_htc_swba(struct ath9k_htc_priv *priv); +void ath9k_htc_swba(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba); void ath9k_htc_rxep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 48bc28823f6..2180a9da380 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -401,10 +401,10 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, spin_unlock_bh(&priv->beacon_lock); } -static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) +static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba) { struct ath_common *common = ath9k_hw_common(priv->ah); - unsigned long flags; u64 tsf; u32 tsftu; u16 intval; @@ -412,10 +412,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - tsf = priv->wmi->tsf; - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); - + tsf = be64_to_cpu(swba->tsf); tsftu = TSF_TO_TU(tsf >> 32, tsf); slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; @@ -427,33 +424,31 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) return slot; } -void ath9k_htc_swba(struct ath9k_htc_priv *priv) +void ath9k_htc_swba(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba) { struct ath_common *common = ath9k_hw_common(priv->ah); - unsigned long flags; int slot; - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - if (priv->wmi->beacon_pending != 0) { - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + if (swba->beacon_pending != 0) { priv->cur_beacon_conf.bmiss_cnt++; if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { - ath_dbg(common, ATH_DBG_BEACON, + ath_dbg(common, ATH_DBG_BSTUCK, "Beacon stuck, HW reset\n"); - ath9k_htc_reset(priv); + ieee80211_queue_work(priv->hw, + &priv->fatal_work); } return; } - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); if (priv->cur_beacon_conf.bmiss_cnt) { - ath_dbg(common, ATH_DBG_BEACON, + ath_dbg(common, ATH_DBG_BSTUCK, "Resuming beacon xmit after %u misses\n", priv->cur_beacon_conf.bmiss_cnt); priv->cur_beacon_conf.bmiss_cnt = 0; } - slot = ath9k_htc_choose_bslot(priv); + slot = ath9k_htc_choose_bslot(priv, swba); spin_lock_bh(&priv->beacon_lock); if (priv->cur_beacon_conf.bslot[slot] == NULL) { spin_unlock_bh(&priv->beacon_lock); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 7e630a81b45..459ba0d36f4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -436,6 +436,9 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); + /* Clear the WMI event queue */ + ath9k_wmi_event_drain(priv); + /* * The MIB counters have to be disabled here, * since the target doesn't do it. diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b1c68bff72a..921d76f3201 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -676,8 +676,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, spin_lock_init(&priv->tx_lock); mutex_init(&priv->mutex); mutex_init(&priv->htc_pm_lock); - tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet, - (unsigned long)priv); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, (unsigned long)priv); tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8f38075d124..81dfe0782f7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -202,6 +202,8 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); + ath9k_wmi_event_drain(priv); + caldata = &priv->caldata; ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); if (ret) { @@ -255,6 +257,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); + ath9k_wmi_event_drain(priv); + ath_dbg(common, ATH_DBG_CONFIG, "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", priv->ah->curchan->channel, @@ -1172,12 +1176,13 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); - tasklet_kill(&priv->swba_tasklet); tasklet_kill(&priv->rx_tasklet); tasklet_kill(&priv->tx_tasklet); skb_queue_purge(&priv->tx_queue); + ath9k_wmi_event_drain(priv); + mutex_unlock(&priv->mutex); /* Cancel all the running timers/work .. */ diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index a39552b3077..45784754dbc 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -104,9 +104,12 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) wmi->drv_priv = priv; wmi->stopped = false; + skb_queue_head_init(&wmi->wmi_event_queue); mutex_init(&wmi->op_mutex); mutex_init(&wmi->multi_write_mutex); init_completion(&wmi->cmd_wait); + tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, + (unsigned long)wmi); return wmi; } @@ -122,11 +125,64 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) kfree(priv->wmi); } -void ath9k_swba_tasklet(unsigned long data) +void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) { - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + unsigned long flags; - ath9k_htc_swba(priv); + tasklet_kill(&priv->wmi->wmi_event_tasklet); + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + __skb_queue_purge(&priv->wmi->wmi_event_queue); + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); +} + +void ath9k_wmi_event_tasklet(unsigned long data) +{ + struct wmi *wmi = (struct wmi *)data; + struct ath9k_htc_priv *priv = wmi->drv_priv; + struct wmi_cmd_hdr *hdr; + void *wmi_event; + struct wmi_event_swba *swba; + struct sk_buff *skb = NULL; + unsigned long flags; + u16 cmd_id; +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + __be32 txrate; +#endif + + do { + spin_lock_irqsave(&wmi->wmi_lock, flags); + skb = __skb_dequeue(&wmi->wmi_event_queue); + if (!skb) { + spin_unlock_irqrestore(&wmi->wmi_lock, flags); + return; + } + spin_unlock_irqrestore(&wmi->wmi_lock, flags); + + hdr = (struct wmi_cmd_hdr *) skb->data; + cmd_id = be16_to_cpu(hdr->command_id); + wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + + switch (cmd_id) { + case WMI_SWBA_EVENTID: + swba = (struct wmi_event_swba *) wmi_event; + ath9k_htc_swba(priv, swba); + break; + case WMI_FATAL_EVENTID: + ieee80211_queue_work(wmi->drv_priv->hw, + &wmi->drv_priv->fatal_work); + break; + case WMI_TXRATE_EVENTID: +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; + wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); +#endif + break; + default: + break; + } + + kfree_skb(skb); + } while (1); } void ath9k_fatal_work(struct work_struct *work) @@ -155,11 +211,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi *wmi = (struct wmi *) priv; struct wmi_cmd_hdr *hdr; u16 cmd_id; - void *wmi_event; - struct wmi_event_swba *swba; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif if (unlikely(wmi->stopped)) goto free_skb; @@ -168,32 +219,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, cmd_id = be16_to_cpu(hdr->command_id); if (cmd_id & 0x1000) { - wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - switch (cmd_id) { - case WMI_SWBA_EVENTID: - swba = (struct wmi_event_swba *) wmi_event; - - spin_lock(&wmi->wmi_lock); - wmi->tsf = be64_to_cpu(swba->tsf); - wmi->beacon_pending = swba->beacon_pending; - spin_unlock(&wmi->wmi_lock); - - tasklet_schedule(&wmi->drv_priv->swba_tasklet); - break; - case WMI_FATAL_EVENTID: - ieee80211_queue_work(wmi->drv_priv->hw, - &wmi->drv_priv->fatal_work); - break; - case WMI_TXRATE_EVENTID: -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; - default: - break; - } - kfree_skb(skb); + spin_lock(&wmi->wmi_lock); + __skb_queue_tail(&wmi->wmi_event_queue, skb); + spin_unlock(&wmi->wmi_lock); + tasklet_schedule(&wmi->wmi_event_tasklet); return; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 2fa91a941a7..ff5ba2b30ec 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -106,13 +106,13 @@ struct wmi { struct mutex op_mutex; struct completion cmd_wait; enum wmi_cmd_id last_cmd_id; + struct sk_buff_head wmi_event_queue; + struct tasklet_struct wmi_event_tasklet; u16 tx_seq_id; u8 *cmd_rsp_buf; u32 cmd_rsp_len; bool stopped; - u64 tsf; - u8 beacon_pending; spinlock_t wmi_lock; atomic_t mwrite_cnt; @@ -129,8 +129,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, u8 *cmd_buf, u32 cmd_len, u8 *rsp_buf, u32 rsp_len, u32 timeout); -void ath9k_swba_tasklet(unsigned long data); +void ath9k_wmi_event_tasklet(unsigned long data); void ath9k_fatal_work(struct work_struct *work); +void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); #define WMI_CMD(_wmi_cmd) \ do { \ -- cgit v1.2.3-70-g09d2 From 8e42e4ba98f986be64016df79eacbb671dbd3d18 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:00 +0530 Subject: ath9k_htc: Move debug code to a separate file Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 2 + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 219 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 212 ------------------------ 3 files changed, 221 insertions(+), 212 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/htc_drv_debug.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index ca4c436e0f6..05a6fade7b1 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \ htc_drv_init.o \ htc_drv_gpio.o +ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o + obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c new file mode 100644 index 00000000000..8b679aab338 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2010-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "htc.h" + +static struct dentry *ath9k_debugfs_root; + +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_TGT_STATS_CMDID); + if (ret) + return -EINVAL; + + + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Short Retries", + be32_to_cpu(cmd_rsp.tx_shortretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Long Retries", + be32_to_cpu(cmd_rsp.tx_longretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Xretries", + be32_to_cpu(cmd_rsp.tx_xretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Unaggr. Xretries", + be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Xretries (HT)", + be32_to_cpu(cmd_rsp.ht_tx_xretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Rate", priv->debug.txrate); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_stats = { + .read = read_file_tgt_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_xmit(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers queued", + priv->debug.tx_stats.buf_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers completed", + priv->debug.tx_stats.buf_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs queued", + priv->debug.tx_stats.skb_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs completed", + priv->debug.tx_stats.skb_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs dropped", + priv->debug.tx_stats.skb_dropped); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CAB queued", + priv->debug.tx_stats.cab_queued); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BE queued", + priv->debug.tx_stats.queue_stats[WME_AC_BE]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BK queued", + priv->debug.tx_stats.queue_stats[WME_AC_BK]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VI queued", + priv->debug.tx_stats.queue_stats[WME_AC_VI]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VO queued", + priv->debug.tx_stats.queue_stats[WME_AC_VO]); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_xmit = { + .read = read_file_xmit, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_recv(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs allocated", + priv->debug.rx_stats.skb_allocated); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs completed", + priv->debug.rx_stats.skb_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs Dropped", + priv->debug.rx_stats.skb_dropped); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_recv = { + .read = read_file_recv, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +int ath9k_htc_init_debug(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + + if (!ath9k_debugfs_root) + return -ENOENT; + + priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), + ath9k_debugfs_root); + if (!priv->debug.debugfs_phy) + goto err; + + priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_stats); + if (!priv->debug.debugfs_tgt_stats) + goto err; + + + priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_xmit); + if (!priv->debug.debugfs_xmit) + goto err; + + priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_recv); + if (!priv->debug.debugfs_recv) + goto err; + + return 0; + +err: + ath9k_htc_exit_debug(ah); + return -ENOMEM; +} + +void ath9k_htc_exit_debug(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + + debugfs_remove(priv->debug.debugfs_recv); + debugfs_remove(priv->debug.debugfs_xmit); + debugfs_remove(priv->debug.debugfs_tgt_stats); + debugfs_remove(priv->debug.debugfs_phy); +} + +int ath9k_htc_debug_create_root(void) +{ + ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); + if (!ath9k_debugfs_root) + return -ENOENT; + + return 0; +} + +void ath9k_htc_debug_remove_root(void) +{ + debugfs_remove(ath9k_debugfs_root); + ath9k_debugfs_root = NULL; +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 81dfe0782f7..59710e75f05 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -16,10 +16,6 @@ #include "htc.h" -#ifdef CONFIG_ATH9K_HTC_DEBUGFS -static struct dentry *ath9k_debugfs_root; -#endif - /*************/ /* Utilities */ /*************/ @@ -720,214 +716,6 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, return ret; } -/*********/ -/* DEBUG */ -/*********/ - -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - -static int ath9k_debugfs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - struct ath9k_htc_target_stats cmd_rsp; - char buf[512]; - unsigned int len = 0; - int ret = 0; - - memset(&cmd_rsp, 0, sizeof(cmd_rsp)); - - WMI_CMD(WMI_TGT_STATS_CMDID); - if (ret) - return -EINVAL; - - - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Short Retries", - be32_to_cpu(cmd_rsp.tx_shortretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Long Retries", - be32_to_cpu(cmd_rsp.tx_longretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries", - be32_to_cpu(cmd_rsp.tx_xretries)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Unaggr. Xretries", - be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries (HT)", - be32_to_cpu(cmd_rsp.ht_tx_xretries)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Rate", priv->debug.txrate); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_tgt_stats = { - .read = read_file_tgt_stats, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t read_file_xmit(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers queued", - priv->debug.tx_stats.buf_queued); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers completed", - priv->debug.tx_stats.buf_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs queued", - priv->debug.tx_stats.skb_queued); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.tx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs dropped", - priv->debug.tx_stats.skb_dropped); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "CAB queued", - priv->debug.tx_stats.cab_queued); - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BE queued", - priv->debug.tx_stats.queue_stats[WME_AC_BE]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BK queued", - priv->debug.tx_stats.queue_stats[WME_AC_BK]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VI queued", - priv->debug.tx_stats.queue_stats[WME_AC_VI]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VO queued", - priv->debug.tx_stats.queue_stats[WME_AC_VO]); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_xmit = { - .read = read_file_xmit, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t read_file_recv(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs allocated", - priv->debug.rx_stats.skb_allocated); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.rx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs Dropped", - priv->debug.rx_stats.skb_dropped); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_recv = { - .read = read_file_recv, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -int ath9k_htc_init_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - if (!ath9k_debugfs_root) - return -ENOENT; - - priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), - ath9k_debugfs_root); - if (!priv->debug.debugfs_phy) - goto err; - - priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_stats); - if (!priv->debug.debugfs_tgt_stats) - goto err; - - - priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_xmit); - if (!priv->debug.debugfs_xmit) - goto err; - - priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_recv); - if (!priv->debug.debugfs_recv) - goto err; - - return 0; - -err: - ath9k_htc_exit_debug(ah); - return -ENOMEM; -} - -void ath9k_htc_exit_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - debugfs_remove(priv->debug.debugfs_recv); - debugfs_remove(priv->debug.debugfs_xmit); - debugfs_remove(priv->debug.debugfs_tgt_stats); - debugfs_remove(priv->debug.debugfs_phy); -} - -int ath9k_htc_debug_create_root(void) -{ - ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!ath9k_debugfs_root) - return -ENOENT; - - return 0; -} - -void ath9k_htc_debug_remove_root(void) -{ - debugfs_remove(ath9k_debugfs_root); - ath9k_debugfs_root = NULL; -} - -#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ - /*******/ /* ANI */ /*******/ -- cgit v1.2.3-70-g09d2 From 719c4cf6b1b113e9caf377c6607ae45758a85871 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:10 +0530 Subject: ath9k_htc: Add RX error statistics Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 16 ++++ drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 109 +++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 + 3 files changed, 118 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 20511af33f5..0e48fa0efa7 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -296,6 +296,9 @@ struct ath9k_htc_tx_ctl { #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) +void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs); + struct ath_tx_stats { u32 buf_queued; u32 buf_completed; @@ -310,6 +313,14 @@ struct ath_rx_stats { u32 skb_allocated; u32 skb_completed; u32 skb_dropped; + u32 err_crc; + u32 err_decrypt_crc; + u32 err_mic; + u32 err_pre_delim; + u32 err_post_delim; + u32 err_decrypt_busy; + u32 err_phy; + u32 err_phy_stats[ATH9K_PHYERR_MAX]; }; struct ath9k_debug { @@ -330,6 +341,11 @@ struct ath9k_debug { #define TX_QSTAT_INC(c) do { } while (0) +static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs) +{ +} + #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #define ATH_LED_PIN_DEF 1 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 8b679aab338..6fc6cb74936 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -123,27 +123,118 @@ static const struct file_operations fops_xmit = { .llseek = default_llseek, }; +void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs) +{ +#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ + + if (rxs->rs_status & ATH9K_RXERR_CRC) + priv->debug.rx_stats.err_crc++; + if (rxs->rs_status & ATH9K_RXERR_DECRYPT) + priv->debug.rx_stats.err_decrypt_crc++; + if (rxs->rs_status & ATH9K_RXERR_MIC) + priv->debug.rx_stats.err_mic++; + if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE) + priv->debug.rx_stats.err_pre_delim++; + if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST) + priv->debug.rx_stats.err_post_delim++; + if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY) + priv->debug.rx_stats.err_decrypt_busy++; + + if (rxs->rs_status & ATH9K_RXERR_PHY) { + priv->debug.rx_stats.err_phy++; + if (rxs->rs_phyerr < ATH9K_PHYERR_MAX) + RX_PHY_ERR_INC(rxs->rs_phyerr); + } + +#undef RX_PHY_ERR_INC +} + static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { +#define PHY_ERR(s, p) \ + len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ + priv->debug.rx_stats.err_phy_stats[p]); + struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; + char *buf; + unsigned int len = 0, size = 1500; + ssize_t retval = 0; - len += snprintf(buf + len, sizeof(buf) - len, + buf = kzalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs allocated", priv->debug.rx_stats.skb_allocated); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs completed", priv->debug.rx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs Dropped", priv->debug.rx_stats.skb_dropped); - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "CRC ERR", + priv->debug.rx_stats.err_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT CRC ERR", + priv->debug.rx_stats.err_decrypt_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "MIC ERR", + priv->debug.rx_stats.err_mic); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "PRE-DELIM CRC ERR", + priv->debug.rx_stats.err_pre_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "POST-DELIM CRC ERR", + priv->debug.rx_stats.err_post_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT BUSY ERR", + priv->debug.rx_stats.err_decrypt_busy); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "TOTAL PHY ERR", + priv->debug.rx_stats.err_phy); + + + PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); + PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); + PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); + PHY_ERR("RATE", ATH9K_PHYERR_RATE); + PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); + PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); + PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); + PHY_ERR("TOR", ATH9K_PHYERR_TOR); + PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); + PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); + PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); + PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); + PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); + PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); + PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); + PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); + PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); + PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); + PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); + PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); + PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); + PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); + PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); + PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); + PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); + PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); + + if (len > size) + len = size; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return retval; + +#undef PHY_ERR } static const struct file_operations fops_recv = { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 0e285589366..a62495d1330 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -540,6 +540,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, goto rx_next; } + ath9k_htc_err_stat_rx(priv, rxstatus); + /* Get the RX status information */ memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); -- cgit v1.2.3-70-g09d2 From b1563a4c3d721cb0496b8e1fb874f08a8f2b62cc Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:19 +0530 Subject: ath9k_htc: Fix RX length check The length of the received SKB could be equal to HTC_RX_FRAME_HEADER_SIZE in case of packets with phy/crc errors, in which case they are dropped without being processed. Fix this check so that the error counters are updated correctly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a62495d1330..7cd3e4e66aa 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -525,8 +525,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, int last_rssi = ATH_RSSI_DUMMY_MARKER; __le16 fc; - if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { - ath_err(common, "Corrupted RX frame, dropping\n"); + if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { + ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", + skb->len); goto rx_next; } -- cgit v1.2.3-70-g09d2 From e723f3900c3b23feb427672c6ccfe5d4243d2c2d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:25 +0530 Subject: ath9k_htc: Remove unused WMI commands WMI_TGT_TXQ_ENABLE_CMDID WMI_HOST_ATTACH WMI_DEBUG_INFO_CMDID WMI_BEACON_UPDATE_CMDID WMI_RESET_CMDID WMI_RX_LINK_CMDID WMI_STOP_DMA_RECV_CMDID Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.c | 14 -------------- drivers/net/wireless/ath/ath9k/wmi.h | 7 ------- 2 files changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 45784754dbc..3b8f25fbecf 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -29,16 +29,12 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_DISABLE_INTR_CMDID"; case WMI_ENABLE_INTR_CMDID: return "WMI_ENABLE_INTR_CMDID"; - case WMI_RX_LINK_CMDID: - return "WMI_RX_LINK_CMDID"; case WMI_ATH_INIT_CMDID: return "WMI_ATH_INIT_CMDID"; case WMI_ABORT_TXQ_CMDID: return "WMI_ABORT_TXQ_CMDID"; case WMI_STOP_TX_DMA_CMDID: return "WMI_STOP_TX_DMA_CMDID"; - case WMI_STOP_DMA_RECV_CMDID: - return "WMI_STOP_DMA_RECV_CMDID"; case WMI_ABORT_TX_DMA_CMDID: return "WMI_ABORT_TX_DMA_CMDID"; case WMI_DRAIN_TXQ_CMDID: @@ -53,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_FLUSH_RECV_CMDID"; case WMI_SET_MODE_CMDID: return "WMI_SET_MODE_CMDID"; - case WMI_RESET_CMDID: - return "WMI_RESET_CMDID"; case WMI_NODE_CREATE_CMDID: return "WMI_NODE_CREATE_CMDID"; case WMI_NODE_REMOVE_CMDID: @@ -63,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_VAP_REMOVE_CMDID"; case WMI_VAP_CREATE_CMDID: return "WMI_VAP_CREATE_CMDID"; - case WMI_BEACON_UPDATE_CMDID: - return "WMI_BEACON_UPDATE_CMDID"; case WMI_REG_READ_CMDID: return "WMI_REG_READ_CMDID"; case WMI_REG_WRITE_CMDID: @@ -73,10 +65,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_RC_STATE_CHANGE_CMDID"; case WMI_RC_RATE_UPDATE_CMDID: return "WMI_RC_RATE_UPDATE_CMDID"; - case WMI_DEBUG_INFO_CMDID: - return "WMI_DEBUG_INFO_CMDID"; - case WMI_HOST_ATTACH: - return "WMI_HOST_ATTACH"; case WMI_TARGET_IC_UPDATE_CMDID: return "WMI_TARGET_IC_UPDATE_CMDID"; case WMI_TGT_STATS_CMDID: @@ -85,8 +73,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_TX_AGGR_ENABLE_CMDID"; case WMI_TGT_DETACH_CMDID: return "WMI_TGT_DETACH_CMDID"; - case WMI_TGT_TXQ_ENABLE_CMDID: - return "WMI_TGT_TXQ_ENABLE_CMDID"; case WMI_AGGR_LIMIT_CMD: return "WMI_AGGR_LIMIT_CMD"; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index ff5ba2b30ec..3ab9604fd6b 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -49,11 +49,9 @@ enum wmi_cmd_id { WMI_GET_FW_VERSION, WMI_DISABLE_INTR_CMDID, WMI_ENABLE_INTR_CMDID, - WMI_RX_LINK_CMDID, WMI_ATH_INIT_CMDID, WMI_ABORT_TXQ_CMDID, WMI_STOP_TX_DMA_CMDID, - WMI_STOP_DMA_RECV_CMDID, WMI_ABORT_TX_DMA_CMDID, WMI_DRAIN_TXQ_CMDID, WMI_DRAIN_TXQ_ALL_CMDID, @@ -61,23 +59,18 @@ enum wmi_cmd_id { WMI_STOP_RECV_CMDID, WMI_FLUSH_RECV_CMDID, WMI_SET_MODE_CMDID, - WMI_RESET_CMDID, WMI_NODE_CREATE_CMDID, WMI_NODE_REMOVE_CMDID, WMI_VAP_REMOVE_CMDID, WMI_VAP_CREATE_CMDID, - WMI_BEACON_UPDATE_CMDID, WMI_REG_READ_CMDID, WMI_REG_WRITE_CMDID, WMI_RC_STATE_CHANGE_CMDID, WMI_RC_RATE_UPDATE_CMDID, - WMI_DEBUG_INFO_CMDID, - WMI_HOST_ATTACH, WMI_TARGET_IC_UPDATE_CMDID, WMI_TGT_STATS_CMDID, WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, - WMI_TGT_TXQ_ENABLE_CMDID, WMI_AGGR_LIMIT_CMD = 0x0026, }; -- cgit v1.2.3-70-g09d2 From 40dc9e4b86963b77918f1b8fa02b98c1e420a7e1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:31 +0530 Subject: ath9k_htc: Use SKB's private area for TX parameters For all packets sent through the USB_WLAN_TX_PIPE endpoint, the private area of the SKB's tx_info can be used to store driver-specific information. For packets sent through USB_REG_OUT_PIPE, this will not make a difference since they are routed through a separate routine that doesn't access the private region. This would help in situations where TX information is required in the URB callback. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 17 +++++++++-------- drivers/net/wireless/ath/ath9k/htc.h | 14 +++++++++++++- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 11 +++++++---- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 15 ++++++++------- drivers/net/wireless/ath/ath9k/htc_hst.c | 18 +++++++++--------- drivers/net/wireless/ath/ath9k/htc_hst.h | 5 ++--- drivers/net/wireless/ath/ath9k/wmi.c | 2 +- 7 files changed, 49 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 23094b70d6e..e252576760d 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -284,9 +284,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) return ret; } -static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, - struct ath9k_htc_tx_ctl *tx_ctl) +static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) { + struct ath9k_htc_tx_ctl *tx_ctl; unsigned long flags; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); @@ -305,12 +305,14 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); hif_dev->tx.tx_skb_cnt++; - /* Send normal frames immediately */ - if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) + tx_ctl = HTC_SKB_CB(skb); + + /* Send normal/mgmt/beacon frames immediately */ + if (tx_ctl->type != ATH9K_HTC_AMPDU) __hif_usb_tx(hif_dev); /* Check if AMPDUs have to be sent immediately */ - if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && + if ((tx_ctl->type == ATH9K_HTC_AMPDU) && (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && (hif_dev->tx.tx_skb_cnt < 2)) { __hif_usb_tx(hif_dev); @@ -352,15 +354,14 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) } } -static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, - struct ath9k_htc_tx_ctl *tx_ctl) +static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; int ret = 0; switch (pipe_id) { case USB_WLAN_TX_PIPE: - ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); + ret = hif_usb_send_tx(hif_dev, skb); break; case USB_REG_OUT_PIPE: ret = hif_usb_send_regout(hif_dev, skb); diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0e48fa0efa7..2eabfe4ad26 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -67,8 +67,11 @@ enum htc_opmode { }; #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) -#define ATH9K_HTC_AMPDU 1 + +#define ATH9K_HTC_AMPDU 1 #define ATH9K_HTC_NORMAL 2 +#define ATH9K_HTC_BEACON 3 +#define ATH9K_HTC_MGMT 4 #define ATH9K_HTC_TX_CTSONLY 0x1 #define ATH9K_HTC_TX_RTSCTS 0x2 @@ -288,6 +291,15 @@ struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ }; +static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) > + IEEE80211_TX_INFO_DRIVER_DATA_SIZE); + return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data; +} + #ifdef CONFIG_ATH9K_HTC_DEBUGFS #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 2180a9da380..713def18451 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -341,7 +341,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif; struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; - struct ath9k_htc_tx_ctl tx_ctl; + struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_tx_info *info; struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; @@ -349,7 +349,6 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int ret; memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); - memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); spin_lock_bh(&priv->beacon_lock); @@ -384,12 +383,16 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); } - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl = HTC_SKB_CB(beacon); + memset(tx_ctl, 0, sizeof(*tx_ctl)); + + tx_ctl->type = ATH9K_HTC_BEACON; + beacon_hdr.vif_index = avp->index; tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - ret = htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + ret = htc_send(priv->htc, beacon, priv->beacon_ep); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(common, ATH_DBG_BSTUCK, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7cd3e4e66aa..ab55dff4721 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -89,13 +89,16 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; - struct ath9k_htc_tx_ctl tx_ctl; + struct ath9k_htc_tx_ctl *tx_ctl; enum htc_endpoint_id epid; u16 qnum; __le16 fc; u8 *tx_fhdr; u8 sta_idx, vif_idx; + tx_ctl = HTC_SKB_CB(skb); + memset(tx_ctl, 0, sizeof(*tx_ctl)); + hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; @@ -126,8 +129,6 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, sta_idx = priv->vif_sta_pos[vif_idx]; } - memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); - if (ieee80211_is_data(fc)) { struct tx_frame_hdr tx_hdr; u32 flags = 0; @@ -139,10 +140,10 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.vif_idx = vif_idx; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - tx_ctl.type = ATH9K_HTC_AMPDU; + tx_ctl->type = ATH9K_HTC_AMPDU; tx_hdr.data_type = ATH9K_HTC_AMPDU; } else { - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl->type = ATH9K_HTC_NORMAL; tx_hdr.data_type = ATH9K_HTC_NORMAL; } @@ -212,7 +213,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, mgmt->u.probe_resp.timestamp = avp->tsfadjust; } - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl->type = ATH9K_HTC_MGMT; mgmt_hdr.node_idx = sta_idx; mgmt_hdr.vif_idx = vif_idx; @@ -230,7 +231,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, epid = priv->mgmt_ep; } send: - return htc_send(priv->htc, skb, epid, &tx_ctl); + return htc_send(priv->htc, skb, epid); } static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index c41ab8c3016..6ee53de45c6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -17,8 +17,8 @@ #include "htc.h" static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, - u16 len, u8 flags, u8 epid, - struct ath9k_htc_tx_ctl *tx_ctl) + u16 len, u8 flags, u8 epid) + { struct htc_frame_hdr *hdr; struct htc_endpoint *endpoint = &target->endpoint[epid]; @@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, hdr->flags = flags; hdr->payload_len = cpu_to_be16(len); - status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, - tx_ctl); + status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); + return status; } @@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target) target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target) target->htc_flags |= HTC_OP_START_WAIT; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target, conn_msg->dl_pipeid = endpoint->dl_pipeid; conn_msg->ul_pipeid = endpoint->ul_pipeid; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -287,9 +287,9 @@ err: } int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) + enum htc_endpoint_id epid) { - return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); + return htc_issue_send(target, skb, skb->len, 0, epid); } void htc_stop(struct htc_target *target) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index ecd018798c4..3531552672e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -35,8 +35,7 @@ struct ath9k_htc_hif { void (*start) (void *hif_handle, u8 pipe); void (*stop) (void *hif_handle, u8 pipe); - int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, - struct ath9k_htc_tx_ctl *tx_ctl); + int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; enum htc_endpoint_id { @@ -206,7 +205,7 @@ int htc_connect_service(struct htc_target *target, struct htc_service_connreq *service_connreq, enum htc_endpoint_id *conn_rsp_eid); int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); + enum htc_endpoint_id eid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 3b8f25fbecf..83d1e0e5dd8 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -267,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, hdr->command_id = cpu_to_be16(cmd); hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); - return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); + return htc_send(wmi->htc, skb, wmi->ctrl_epid); } int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, -- cgit v1.2.3-70-g09d2 From b97c57ff3f568b33ed91915f48431feae2dab288 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:37 +0530 Subject: ath9k_htc: Sync struct ath9k_htc_target_sta with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 30 ++++----------------------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 ++---- 2 files changed, 6 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 2eabfe4ad26..e096624d907 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -104,17 +104,6 @@ struct tx_beacon_header { u16 rev; } __packed; -struct ath9k_htc_target_hw { - u32 flags; - u32 flags_ext; - u32 ampdu_limit; - u8 ampdu_subframes; - u8 tx_chainmask; - u8 tx_chainmask_legacy; - u8 rtscts_ratecode; - u8 protmode; -} __packed; - struct ath9k_htc_cap_target { u32 flags; u32 flags_ext; @@ -146,27 +135,16 @@ struct ath9k_htc_target_vif { #define ATH_HTC_STA_ERP 0x0004 #define ATH_HTC_STA_HT 0x0008 -/* FIXME: UAPSD variables */ struct ath9k_htc_target_sta { - u16 associd; - u16 txpower; - u32 ucastkey; u8 macaddr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 sta_index; u8 vif_index; - u8 vif_sta; - __be16 flags; /* ATH_HTC_STA_* */ - u16 htcap; - u8 valid; - u16 capinfo; - struct ath9k_htc_target_hw *hw; - struct ath9k_htc_target_vif *vif; - u16 txseqmgmt; u8 is_vif_sta; - u16 maxampdu; - u16 iv16; - u32 iv32; + __be16 flags; /* ATH_HTC_STA_* */ + __be16 htcap; + __be16 maxampdu; + u8 pad; } __packed; struct ath9k_htc_target_aggr { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 59710e75f05..9bb20f33638 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -382,7 +382,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) tsta.is_vif_sta = 1; tsta.sta_index = sta_idx; tsta.vif_index = hvif.index; - tsta.maxampdu = 0xffff; + tsta.maxampdu = cpu_to_be16(0xffff); WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { @@ -463,9 +463,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ista = (struct ath9k_htc_sta *) sta->drv_priv; memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); - tsta.associd = common->curaid; tsta.is_vif_sta = 0; - tsta.valid = true; ista->index = sta_idx; } else { memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); @@ -474,7 +472,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, tsta.sta_index = sta_idx; tsta.vif_index = avp->index; - tsta.maxampdu = 0xffff; + tsta.maxampdu = cpu_to_be16(0xffff); if (sta && sta->ht_cap.ht_supported) tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); -- cgit v1.2.3-70-g09d2 From e4c62506fcfa7c1fa7c586ab518a172c3a65db0f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:43 +0530 Subject: ath9k_htc: Sync struct ath9k_htc_target_vif with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 12 +++--------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 8 ++++---- 2 files changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e096624d907..f74f45f238a 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -117,17 +117,11 @@ struct ath9k_htc_cap_target { struct ath9k_htc_target_vif { u8 index; - u8 des_bssid[ETH_ALEN]; - __be32 opmode; + u8 opmode; u8 myaddr[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u32 flags; - u32 flags_ext; - u16 ps_sta; - __be16 rtsthreshold; u8 ath_cap; - u8 node; - s8 mcast_rate; + __be16 rtsthreshold; + u8 pad; } __packed; #define ATH_HTC_STA_AUTH 0x0001 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9bb20f33638..400226702e0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -349,7 +349,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - hvif.opmode = cpu_to_be32(HTC_M_MONITOR); + hvif.opmode = HTC_M_MONITOR; hvif.index = ffz(priv->vif_slot); WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); @@ -1039,13 +1039,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, switch (vif->type) { case NL80211_IFTYPE_STATION: - hvif.opmode = cpu_to_be32(HTC_M_STA); + hvif.opmode = HTC_M_STA; break; case NL80211_IFTYPE_ADHOC: - hvif.opmode = cpu_to_be32(HTC_M_IBSS); + hvif.opmode = HTC_M_IBSS; break; case NL80211_IFTYPE_AP: - hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); + hvif.opmode = HTC_M_HOSTAP; break; default: ath_err(common, -- cgit v1.2.3-70-g09d2 From 0a8579f6b7c3f4332ad9eb6615c7631ef9cd4ed6 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:49 +0530 Subject: ath9k_htc: Sync struct ath9k_htc_cap_target with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index f74f45f238a..1568c3692da 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -113,6 +113,7 @@ struct ath9k_htc_cap_target { u8 tx_chainmask_legacy; u8 rtscts_ratecode; u8 protmode; + u8 pad; } __packed; struct ath9k_htc_target_vif { -- cgit v1.2.3-70-g09d2 From ee3fa1bdadd998652083a7814af745f765a06a25 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:55 +0530 Subject: ath9k_htc: Remove unused WMI_WLAN_TXCOMP_EVENTID Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 3ab9604fd6b..a81d554edb8 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -80,7 +80,6 @@ enum wmi_event_id { WMI_FATAL_EVENTID, WMI_TXTO_EVENTID, WMI_BMISS_EVENTID, - WMI_WLAN_TXCOMP_EVENTID, WMI_DELBA_EVENTID, WMI_TXRATE_EVENTID, }; -- cgit v1.2.3-70-g09d2 From 658ef04fd42a587b17a379ad9208023473442ddd Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:00 +0530 Subject: ath9k_htc: Move TX specific stuff to a separate structure Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 19 ++++++++++++------- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 8 ++++---- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 22 +++++++++++----------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 24 ++++++++++++------------ 5 files changed, 40 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1568c3692da..3af8a58d400 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -260,6 +260,13 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; +struct ath9k_htc_tx { + bool tx_queues_stop; + spinlock_t tx_lock; + + struct sk_buff_head tx_queue; +}; + struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ }; @@ -433,22 +440,20 @@ struct ath9k_htc_priv { u16 nstations; bool rearm_ani; bool reconfig_beacon; + unsigned int rxfilter; struct ath9k_hw_cal_data caldata; + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; spinlock_t beacon_lock; + struct htc_beacon_config cur_beacon_conf; - bool tx_queues_stop; - spinlock_t tx_lock; + struct ath9k_htc_rx rx; + struct ath9k_htc_tx tx; - struct htc_beacon_config cur_beacon_conf; - unsigned int rxfilter; struct tasklet_struct swba_tasklet; struct tasklet_struct rx_tasklet; - struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; - struct ath9k_htc_rx rx; struct tasklet_struct tx_tasklet; - struct sk_buff_head tx_queue; struct delayed_work ani_work; struct work_struct ps_work; struct work_struct fatal_work; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 459ba0d36f4..1f6df4a1d22 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -398,9 +398,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) /* Start TX */ htc_start(priv->htc); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); WMI_CMD(WMI_ENABLE_INTR_CMDID); @@ -431,7 +431,7 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) ieee80211_stop_queues(hw); htc_stop(priv->htc); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - skb_queue_purge(&priv->tx_queue); + skb_queue_purge(&priv->tx.tx_queue); /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 921d76f3201..c270da7be10 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -673,7 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); - spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->tx.tx_lock); mutex_init(&priv->mutex); mutex_init(&priv->htc_pm_lock); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 400226702e0..ff3a49577a0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -707,9 +707,9 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, (aggr.aggr_enable) ? "Starting" : "Stopping", sta->addr, tid); - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); return ret; } @@ -853,9 +853,9 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Stopping TX queues\n"); ieee80211_stop_queues(hw); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = true; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = true; + spin_unlock_bh(&priv->tx.tx_lock); } else { ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed\n"); @@ -923,9 +923,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) priv->op_flags &= ~OP_INVALID; htc_start(priv->htc); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); @@ -965,7 +965,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) tasklet_kill(&priv->rx_tasklet); tasklet_kill(&priv->tx_tasklet); - skb_queue_purge(&priv->tx_queue); + skb_queue_purge(&priv->tx.tx_queue); ath9k_wmi_event_drain(priv); @@ -1563,9 +1563,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_OPERATIONAL: ista = (struct ath9k_htc_sta *) sta->drv_priv; - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = AGGR_OPERATIONAL; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); break; default: ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index ab55dff4721..6f7987d7b6b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -239,10 +239,10 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, { bool ret = false; - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) ret = true; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); return ret; } @@ -257,7 +257,7 @@ void ath9k_tx_tasklet(unsigned long data) struct sk_buff *skb = NULL; __le16 fc; - while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; @@ -292,9 +292,9 @@ void ath9k_tx_tasklet(unsigned long data) if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { ieee80211_start_tx_ba_session(sta, tid, 0); - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = AGGR_PROGRESS; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); } } } @@ -307,16 +307,16 @@ void ath9k_tx_tasklet(unsigned long data) } /* Wake TX queues if needed */ - spin_lock_bh(&priv->tx_lock); - if (priv->tx_queues_stop) { - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.tx_queues_stop) { + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Waking up TX queues\n"); ieee80211_wake_queues(priv->hw); return; } - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); } void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, @@ -348,13 +348,13 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, if (txok) tx_info->flags |= IEEE80211_TX_STAT_ACK; - skb_queue_tail(&priv->tx_queue, skb); + skb_queue_tail(&priv->tx.tx_queue, skb); tasklet_schedule(&priv->tx_tasklet); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { - skb_queue_head_init(&priv->tx_queue); + skb_queue_head_init(&priv->tx.tx_queue); return 0; } -- cgit v1.2.3-70-g09d2 From 15f6d6d52fe0d9fcf8c09788caff5d1684e5f12c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:06 +0530 Subject: ath9k_htc: Reduce TX queue size The current max queue length of 1024 is quite large and unnecessary. 256 suffices well enough even for high throughput situations. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7b9d863d403..f82b32bbf4e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -31,7 +31,7 @@ /* FIXME: Verify these numbers (with Windows) */ #define MAX_TX_URB_NUM 8 -#define MAX_TX_BUF_NUM 1024 +#define MAX_TX_BUF_NUM 256 #define MAX_TX_BUF_SIZE 32768 #define MAX_TX_AGGR_NUM 20 -- cgit v1.2.3-70-g09d2 From e8e3860765641d5e9d1607ec50191cb33c28371d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:12 +0530 Subject: ath9k_htc: Sync MGMT/DATA packet headers with firmware Add a new cookie field that would be filled by the host. This can be used to match the TX status WMI event with the appropriate packet. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 3af8a58d400..3185fe7568c 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -85,7 +85,8 @@ struct tx_frame_hdr { __be32 flags; /* ATH9K_HTC_TX_* */ u8 key_type; u8 keyix; - u8 reserved[26]; + u8 cookie; + u8 pad; } __packed; struct tx_mgmt_hdr { @@ -95,7 +96,8 @@ struct tx_mgmt_hdr { u8 flags; u8 key_type; u8 keyix; - u16 reserved; + u8 cookie; + u8 pad; } __packed; struct tx_beacon_header { -- cgit v1.2.3-70-g09d2 From 16c56ae87509d9bbcd8c711dc4f99b38c234d6c5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:18 +0530 Subject: ath9k_htc: Add a new WMI event WMI_TXSTATUS_EVENTID This event will be generated by the target for packet completions. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.h | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index a81d554edb8..8c877dc2e2e 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -41,6 +41,44 @@ struct wmi_event_swba { __be64 tsf; u8 beacon_pending; }; + +/* + * 64 - HTC header - WMI header - 1 / txstatus + * And some other hdr. space is also accounted for. + * 13 seems to be the magic number. + */ +#define HTC_MAX_TX_STATUS 13 + +#define ATH9K_HTC_TXSTAT_ACK BIT(0) +#define ATH9K_HTC_TXSTAT_FILT BIT(1) +#define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2) +#define ATH9K_HTC_TXSTAT_MCS BIT(3) +#define ATH9K_HTC_TXSTAT_CW40 BIT(4) +#define ATH9K_HTC_TXSTAT_SGI BIT(5) + +/* + * Legacy rates are indicated as indices. + * HT rates are indicated as dot11 numbers. + * This allows us to resrict the rate field + * to 4 bits. + */ +#define ATH9K_HTC_TXSTAT_RATE 0x0f +#define ATH9K_HTC_TXSTAT_RATE_S 0 + +#define ATH9K_HTC_TXSTAT_EPID 0xf0 +#define ATH9K_HTC_TXSTAT_EPID_S 4 + +struct __wmi_event_txstatus { + u8 cookie; + u8 ts_rate; /* Also holds EP ID */ + u8 ts_flags; +}; + +struct wmi_event_txstatus { + u8 cnt; + struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS]; +} __packed; + enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -82,6 +120,7 @@ enum wmi_event_id { WMI_BMISS_EVENTID, WMI_DELBA_EVENTID, WMI_TXRATE_EVENTID, + WMI_TXSTATUS_EVENTID, }; #define MAX_CMD_NUMBER 62 -- cgit v1.2.3-70-g09d2 From 3deff76095c4ac4252e27c537db3041f619c23a2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:23 +0530 Subject: ath9k_htc: Increase URB count for REG_IN pipe Using a single URB for receiving WMI events is insufficient, increase it to 64 to not lose WMI events in high throughput situations. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 99 +++++++++++++++++++------------- drivers/net/wireless/ath/ath9k/hif_usb.h | 4 +- 2 files changed, 61 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index e252576760d..0b63a48462c 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -566,6 +566,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) case -ESHUTDOWN: goto free; default: + skb_reset_tail_pointer(skb); + skb_trim(skb, 0); + goto resubmit; } @@ -590,23 +593,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, nskb); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) { - kfree_skb(nskb); - urb->context = NULL; - } - - return; } resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); - + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) + if (ret) { + usb_unanchor_urb(urb); goto free; + } return; free: @@ -747,43 +742,67 @@ err_urb: return ret; } -static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) +static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - if (hif_dev->reg_in_urb) { - usb_kill_urb(hif_dev->reg_in_urb); - if (hif_dev->reg_in_urb->context) - kfree_skb((void *)hif_dev->reg_in_urb->context); - usb_free_urb(hif_dev->reg_in_urb); - hif_dev->reg_in_urb = NULL; - } + usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); } -static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) +static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - struct sk_buff *skb; + struct urb *urb = NULL; + struct sk_buff *skb = NULL; + int i, ret; - hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (hif_dev->reg_in_urb == NULL) - return -ENOMEM; + init_usb_anchor(&hif_dev->reg_in_submitted); - skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); - if (!skb) - goto err; + for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { - usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, - usb_rcvbulkpipe(hif_dev->udev, - USB_REG_IN_PIPE), - skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + /* Allocate URB */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (urb == NULL) { + ret = -ENOMEM; + goto err_urb; + } - if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) - goto err; + /* Allocate buffer */ + skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_skb; + } + + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), + skb->data, MAX_REG_IN_BUF_SIZE, + ath9k_hif_usb_reg_in_cb, skb); + + /* Anchor URB */ + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); + + /* Submit URB */ + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) { + usb_unanchor_urb(urb); + goto err_submit; + } + + /* + * Drop reference count. + * This ensures that the URB is freed when killing them. + */ + usb_free_urb(urb); + } return 0; -err: - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); - return -ENOMEM; +err_submit: + kfree_skb(skb); +err_skb: + usb_free_urb(urb); +err_urb: + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); + return ret; } static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) @@ -800,7 +819,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) goto err_rx; /* Register Read */ - if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) + if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) goto err_reg; return 0; @@ -815,7 +834,7 @@ err: static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->regout_submitted); - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); ath9k_hif_usb_dealloc_tx_urbs(hif_dev); ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index f82b32bbf4e..8b98d646e91 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -40,7 +40,7 @@ #define MAX_PKT_NUM_IN_TRANSFER 10 #define MAX_REG_OUT_URB_NUM 1 -#define MAX_REG_OUT_BUF_NUM 8 +#define MAX_REG_IN_URB_NUM 64 #define MAX_REG_IN_BUF_SIZE 64 @@ -90,9 +90,9 @@ struct hif_device_usb { const struct firmware *firmware; struct htc_target *htc_handle; struct hif_usb_tx tx; - struct urb *reg_in_urb; struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; + struct usb_anchor reg_in_submitted; struct sk_buff *remain_skb; const char *fw_name; int rx_remain_len; -- cgit v1.2.3-70-g09d2 From 8e86a54715c4102a8ed697939de9ebd9715dc59c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:29 +0530 Subject: ath9k_htc: Fix TX queue management Handle queue start/stop properly by maintaining a counter to check if the pending frame count has exceeded the threshold. Otherwise, packets would be dropped needlessly. While at it, use a simple flag to track queue status and use helper functions too. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 13 +++++++-- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 4 +++ drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 21 +++++-------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 39 ++++++++++++++++++------- 5 files changed, 52 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 3185fe7568c..fc4c466e756 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -262,11 +262,16 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; -struct ath9k_htc_tx { - bool tx_queues_stop; - spinlock_t tx_lock; +#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) + +#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) +struct ath9k_htc_tx { + u8 flags; + int queued_cnt; struct sk_buff_head tx_queue; + spinlock_t tx_lock; }; struct ath9k_htc_tx_ctl { @@ -532,6 +537,8 @@ int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); int get_hw_qnum(u16 queue, int *hwq_map); int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo); +void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); +void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 713def18451..de37d46bb0d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -326,6 +326,10 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, ath_dbg(common, ATH_DBG_FATAL, "Failed to send CAB frame\n"); dev_kfree_skb_any(skb); + } else { + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.queued_cnt++; + spin_unlock_bh(&priv->tx.tx_lock); } next: skb = ieee80211_get_buffered_bc(priv->hw, vif); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 1f6df4a1d22..92e4b312a98 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -399,7 +399,7 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) /* Start TX */ htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = false; + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ff3a49577a0..690113673d2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -833,6 +833,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; + struct ath_common *common = ath9k_hw_common(priv->ah); int padpos, padsize, ret; hdr = (struct ieee80211_hdr *) skb->data; @@ -841,28 +842,22 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) padpos = ath9k_cmn_padpos(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) + if (skb_headroom(skb) < padsize) { + ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); goto fail_tx; + } skb_push(skb, padsize); memmove(skb->data, skb->data + padsize, padpos); } ret = ath9k_htc_tx_start(priv, skb, false); if (ret != 0) { - if (ret == -ENOMEM) { - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Stopping TX queues\n"); - ieee80211_stop_queues(hw); - spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = true; - spin_unlock_bh(&priv->tx.tx_lock); - } else { - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Tx failed\n"); - } + ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); goto fail_tx; } + ath9k_htc_check_stop_queues(priv); + return; fail_tx: @@ -924,7 +919,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = false; + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 6f7987d7b6b..1cbe194179a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -53,6 +53,29 @@ int get_hw_qnum(u16 queue, int *hwq_map) } } +void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv) +{ + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.queued_cnt++; + if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) && + !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { + priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP; + ieee80211_stop_queues(priv->hw); + } + spin_unlock_bh(&priv->tx.tx_lock); +} + +void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) +{ + spin_lock_bh(&priv->tx.tx_lock); + if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) && + (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; + ieee80211_wake_queues(priv->hw); + } + spin_unlock_bh(&priv->tx.tx_lock); +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -302,21 +325,17 @@ void ath9k_tx_tasklet(unsigned long data) rcu_read_unlock(); send_mac80211: + spin_lock_bh(&priv->tx.tx_lock); + if (WARN_ON(--priv->tx.queued_cnt < 0)) + priv->tx.queued_cnt = 0; + spin_unlock_bh(&priv->tx.tx_lock); + /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } /* Wake TX queues if needed */ - spin_lock_bh(&priv->tx.tx_lock); - if (priv->tx.tx_queues_stop) { - priv->tx.tx_queues_stop = false; - spin_unlock_bh(&priv->tx.tx_lock); - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Waking up TX queues\n"); - ieee80211_wake_queues(priv->hw); - return; - } - spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_check_wake_queues(priv); } void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, -- cgit v1.2.3-70-g09d2 From d67ee5339363608adce786ec8fd62a0fb2b66116 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:35 +0530 Subject: ath9k_htc: Introduce new HTC API A new routine that takes an endpoint explicitly is introduced. The normal htc_send() now retrieves the endpoint from the packet's private data. This would be useful in TX completion when the endpoint ID would be required. While at it, use a helper function to map the queue to endpoint. Data/mgmt/beacon packets use htc_send(), while WMI comamnds pass the endpoint to HTC. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 56 ++++++++++++++----------- drivers/net/wireless/ath/ath9k/htc_hst.c | 12 +++++- drivers/net/wireless/ath/ath9k/htc_hst.h | 5 ++- drivers/net/wireless/ath/ath9k/wmi.c | 2 +- 6 files changed, 49 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index fc4c466e756..356f49c180b 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -276,6 +276,7 @@ struct ath9k_htc_tx { struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ + u8 epid; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index de37d46bb0d..97b116fb4e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -391,12 +391,13 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, memset(tx_ctl, 0, sizeof(*tx_ctl)); tx_ctl->type = ATH9K_HTC_BEACON; + tx_ctl->epid = priv->beacon_ep; beacon_hdr.vif_index = avp->index; tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - ret = htc_send(priv->htc, beacon, priv->beacon_ep); + ret = htc_send(priv->htc, beacon); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(common, ATH_DBG_BSTUCK, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 1cbe194179a..d17662fa604 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -76,6 +76,34 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) spin_unlock_bh(&priv->tx.tx_lock); } +static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, + u16 qnum) +{ + enum htc_endpoint_id epid; + + switch (qnum) { + case 0: + TX_QSTAT_INC(WME_AC_VO); + epid = priv->data_vo_ep; + break; + case 1: + TX_QSTAT_INC(WME_AC_VI); + epid = priv->data_vi_ep; + break; + case 2: + TX_QSTAT_INC(WME_AC_BE); + epid = priv->data_be_ep; + break; + case 3: + default: + TX_QSTAT_INC(WME_AC_BK); + epid = priv->data_bk_ep; + break; + } + + return epid; +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -113,7 +141,6 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; struct ath9k_htc_tx_ctl *tx_ctl; - enum htc_endpoint_id epid; u16 qnum; __le16 fc; u8 *tx_fhdr; @@ -197,31 +224,12 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, if (is_cab) { CAB_STAT_INC; - epid = priv->cab_ep; + tx_ctl->epid = priv->cab_ep; goto send; } qnum = skb_get_queue_mapping(skb); - - switch (qnum) { - case 0: - TX_QSTAT_INC(WME_AC_VO); - epid = priv->data_vo_ep; - break; - case 1: - TX_QSTAT_INC(WME_AC_VI); - epid = priv->data_vi_ep; - break; - case 2: - TX_QSTAT_INC(WME_AC_BE); - epid = priv->data_be_ep; - break; - case 3: - default: - TX_QSTAT_INC(WME_AC_BK); - epid = priv->data_bk_ep; - break; - } + tx_ctl->epid = get_htc_epid(priv, qnum); } else { struct tx_mgmt_hdr mgmt_hdr; @@ -251,10 +259,10 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); - epid = priv->mgmt_ep; + tx_ctl->epid = priv->mgmt_ep; } send: - return htc_send(priv->htc, skb, epid); + return htc_send(priv->htc, skb); } static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 6ee53de45c6..be87f4757bf 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -286,8 +286,16 @@ err: return ret; } -int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id epid) +int htc_send(struct htc_target *target, struct sk_buff *skb) +{ + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid); +} + +int htc_send_epid(struct htc_target *target, struct sk_buff *skb, + enum htc_endpoint_id epid) { return htc_issue_send(target, skb, skb->len, 0, epid); } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 3531552672e..064a324b522 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -204,8 +204,9 @@ int htc_init(struct htc_target *target); int htc_connect_service(struct htc_target *target, struct htc_service_connreq *service_connreq, enum htc_endpoint_id *conn_rsp_eid); -int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id eid); +int htc_send(struct htc_target *target, struct sk_buff *skb); +int htc_send_epid(struct htc_target *target, struct sk_buff *skb, + enum htc_endpoint_id epid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 83d1e0e5dd8..e66f6c33302 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -267,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, hdr->command_id = cpu_to_be16(cmd); hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); - return htc_send(wmi->htc, skb, wmi->ctrl_epid); + return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); } int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, -- cgit v1.2.3-70-g09d2 From 729bd3ab460d3bb8236cc8f6fd0289201124112d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:41 +0530 Subject: ath9k_htc: Move endpoint header parsing to TX tasklet There is no need to do endpoint header removal in the ISR. Also, this is needed when TX slot management is added later on. Use a helper function to strip the driver header. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 68 ++++++++++++++++++--------- 2 files changed, 46 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 356f49c180b..0831ca3de95 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -277,6 +277,7 @@ struct ath9k_htc_tx { struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ u8 epid; + u8 txok; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index d17662fa604..7b218dad55d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -104,6 +104,30 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +static inline int strip_drv_header(struct ath9k_htc_priv *priv, + struct sk_buff *skb) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if (tx_ctl->epid == priv->mgmt_ep) { + skb_pull(skb, sizeof(struct tx_mgmt_hdr)); + } else if ((tx_ctl->epid == priv->data_bk_ep) || + (tx_ctl->epid == priv->data_be_ep) || + (tx_ctl->epid == priv->data_vi_ep) || + (tx_ctl->epid == priv->data_vo_ep) || + (tx_ctl->epid == priv->cab_ep)) { + skb_pull(skb, sizeof(struct tx_frame_hdr)); + } else { + ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); + return -EINVAL; + } + + return 0; +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -281,22 +305,40 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_vif *vif; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info; struct sk_buff *skb = NULL; __le16 fc; + bool txok; while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + if (strip_drv_header(priv, skb) < 0) { + dev_kfree_skb_any(skb); + continue; + } + + tx_ctl = HTC_SKB_CB(skb); hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; tx_info = IEEE80211_SKB_CB(skb); vif = tx_info->control.vif; + txok = tx_ctl->txok; memset(&tx_info->status, 0, sizeof(tx_info->status)); + /* + * URB submission failed for this frame, it never reached + * the target. + */ + if (!txok) + goto send_mac80211; + + tx_info->flags |= IEEE80211_TX_STAT_ACK; + if (!vif) goto send_mac80211; @@ -350,30 +392,10 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, bool txok) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; - struct ath_common *common = ath9k_hw_common(priv->ah); - struct ieee80211_tx_info *tx_info; - - if (!skb) - return; - - if (ep_id == priv->mgmt_ep) { - skb_pull(skb, sizeof(struct tx_mgmt_hdr)); - } else if ((ep_id == priv->data_bk_ep) || - (ep_id == priv->data_be_ep) || - (ep_id == priv->data_vi_ep) || - (ep_id == priv->data_vo_ep) || - (ep_id == priv->cab_ep)) { - skb_pull(skb, sizeof(struct tx_frame_hdr)); - } else { - ath_err(common, "Unsupported TX EPID: %d\n", ep_id); - dev_kfree_skb_any(skb); - return; - } - - tx_info = IEEE80211_SKB_CB(skb); + struct ath9k_htc_tx_ctl *tx_ctl; - if (txok) - tx_info->flags |= IEEE80211_TX_STAT_ACK; + tx_ctl = HTC_SKB_CB(skb); + tx_ctl->txok = txok; skb_queue_tail(&priv->tx.tx_queue, skb); tasklet_schedule(&priv->tx_tasklet); -- cgit v1.2.3-70-g09d2 From 2c5d57f004673a9c8658e20b1fa3f992b5a10f70 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:47 +0530 Subject: ath9k_htc: Add TX slots Maintain a bitmap of slots for transmission and update the cookie field for every packet with the slot value. This value would be used for matching packets when TX completion processing is added. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 5 ++- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 17 +++++++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 14 +++++-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 51 ++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0831ca3de95..45cf7557943 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -271,6 +271,7 @@ struct ath9k_htc_tx { u8 flags; int queued_cnt; struct sk_buff_head tx_queue; + DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; }; @@ -532,7 +533,7 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct sk_buff *skb, bool is_cab); + struct sk_buff *skb, u8 slot, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); @@ -541,6 +542,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo); void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); +int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); +void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 97b116fb4e1..bf7ef1b7eb3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -299,7 +299,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif; struct sk_buff *skb; struct ieee80211_hdr *hdr; - int padpos, padsize, ret; + int padpos, padsize, ret, tx_slot; spin_lock_bh(&priv->beacon_lock); @@ -321,11 +321,20 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb, true); + tx_slot = ath9k_htc_tx_get_slot(priv); + if (tx_slot != 0) { + ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); + dev_kfree_skb_any(skb); + goto next; + } + + ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); if (ret != 0) { - ath_dbg(common, ATH_DBG_FATAL, - "Failed to send CAB frame\n"); + ath9k_htc_tx_clear_slot(priv, tx_slot); dev_kfree_skb_any(skb); + + ath_dbg(common, ATH_DBG_XMIT, + "Failed to send CAB frame\n"); } else { spin_lock_bh(&priv->tx.tx_lock); priv->tx.queued_cnt++; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 690113673d2..c7e056b40e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -834,7 +834,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); - int padpos, padsize, ret; + int padpos, padsize, ret, slot; hdr = (struct ieee80211_hdr *) skb->data; @@ -850,16 +850,24 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb, false); + slot = ath9k_htc_tx_get_slot(priv); + if (slot < 0) { + ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); + goto fail_tx; + } + + ret = ath9k_htc_tx_start(priv, skb, slot, false); if (ret != 0) { ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); - goto fail_tx; + goto clear_slot; } ath9k_htc_check_stop_queues(priv); return; +clear_slot: + ath9k_htc_tx_clear_slot(priv, slot); fail_tx: dev_kfree_skb_any(skb); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7b218dad55d..ee5b3e281cd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -76,6 +76,29 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) spin_unlock_bh(&priv->tx.tx_lock); } +int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv) +{ + int slot; + + spin_lock_bh(&priv->tx.tx_lock); + slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM); + if (slot >= MAX_TX_BUF_NUM) { + spin_unlock_bh(&priv->tx.tx_lock); + return -ENOBUFS; + } + __set_bit(slot, priv->tx.tx_slot); + spin_unlock_bh(&priv->tx.tx_lock); + + return slot; +} + +void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) +{ + spin_lock_bh(&priv->tx.tx_lock); + __clear_bit(slot, priv->tx.tx_slot); + spin_unlock_bh(&priv->tx.tx_lock); +} + static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, u16 qnum) { @@ -104,28 +127,38 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +/* + * Removes the driver header and returns the TX slot number + */ static inline int strip_drv_header(struct ath9k_htc_priv *priv, struct sk_buff *skb) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_tx_ctl *tx_ctl; + int slot; tx_ctl = HTC_SKB_CB(skb); if (tx_ctl->epid == priv->mgmt_ep) { + struct tx_mgmt_hdr *tx_mhdr = + (struct tx_mgmt_hdr *)skb->data; + slot = tx_mhdr->cookie; skb_pull(skb, sizeof(struct tx_mgmt_hdr)); } else if ((tx_ctl->epid == priv->data_bk_ep) || (tx_ctl->epid == priv->data_be_ep) || (tx_ctl->epid == priv->data_vi_ep) || (tx_ctl->epid == priv->data_vo_ep) || (tx_ctl->epid == priv->cab_ep)) { + struct tx_frame_hdr *tx_fhdr = + (struct tx_frame_hdr *)skb->data; + slot = tx_fhdr->cookie; skb_pull(skb, sizeof(struct tx_frame_hdr)); } else { ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); - return -EINVAL; + slot = -EINVAL; } - return 0; + return slot; } int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, @@ -155,7 +188,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, } int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct sk_buff *skb, bool is_cab) + struct sk_buff *skb, + u8 slot, bool is_cab) { struct ieee80211_hdr *hdr; struct ieee80211_mgmt *mgmt; @@ -212,6 +246,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.node_idx = sta_idx; tx_hdr.vif_idx = vif_idx; + tx_hdr.cookie = slot; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_ctl->type = ATH9K_HTC_AMPDU; @@ -274,6 +309,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, mgmt_hdr.vif_idx = vif_idx; mgmt_hdr.tidno = 0; mgmt_hdr.flags = 0; + mgmt_hdr.cookie = slot; mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) @@ -313,10 +349,12 @@ void ath9k_tx_tasklet(unsigned long data) struct sk_buff *skb = NULL; __le16 fc; bool txok; + int slot; while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - if (strip_drv_header(priv, skb) < 0) { + slot = strip_drv_header(priv, skb); + if (slot < 0) { dev_kfree_skb_any(skb); continue; } @@ -347,8 +385,7 @@ void ath9k_tx_tasklet(unsigned long data) sta = ieee80211_find_sta(vif, hdr->addr1); if (!sta) { rcu_read_unlock(); - ieee80211_tx_status(priv->hw, skb); - continue; + goto send_mac80211; } /* Check if we need to start aggregation */ @@ -380,6 +417,8 @@ void ath9k_tx_tasklet(unsigned long data) priv->tx.queued_cnt = 0; spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_tx_clear_slot(priv, slot); + /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } -- cgit v1.2.3-70-g09d2 From f2820f4583b233827f10d91adea70225e196d852 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:54 +0530 Subject: ath9k_htc: Use helper functions for TX processing Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 137 ++++++++++++++------------ 1 file changed, 73 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index ee5b3e281cd..944440c84c4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -325,8 +325,8 @@ send: return htc_send(priv->htc, skb); } -static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, - struct ath9k_htc_sta *ista, u8 tid) +static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, + struct ath9k_htc_sta *ista, u8 tid) { bool ret = false; @@ -338,89 +338,98 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, return ret; } -void ath9k_tx_tasklet(unsigned long data) +static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct sk_buff *skb) { - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - struct ath9k_htc_tx_ctl *tx_ctl; - struct ieee80211_vif *vif; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *tx_info; - struct sk_buff *skb = NULL; __le16 fc; - bool txok; - int slot; - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + hdr = (struct ieee80211_hdr *) skb->data; + fc = hdr->frame_control; - slot = strip_drv_header(priv, skb); - if (slot < 0) { - dev_kfree_skb_any(skb); - continue; - } + rcu_read_lock(); - tx_ctl = HTC_SKB_CB(skb); - hdr = (struct ieee80211_hdr *) skb->data; - fc = hdr->frame_control; - tx_info = IEEE80211_SKB_CB(skb); - vif = tx_info->control.vif; - txok = tx_ctl->txok; + sta = ieee80211_find_sta(vif, hdr->addr1); + if (!sta) { + rcu_read_unlock(); + return; + } - memset(&tx_info->status, 0, sizeof(tx_info->status)); + if (sta && conf_is_ht(&priv->hw->conf) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 *qc, tid; + struct ath9k_htc_sta *ista; - /* - * URB submission failed for this frame, it never reached - * the target. - */ - if (!txok) - goto send_mac80211; + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + ista = (struct ath9k_htc_sta *)sta->drv_priv; + if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) { + ieee80211_start_tx_ba_session(sta, tid, 0); + spin_lock_bh(&priv->tx.tx_lock); + ista->tid_state[tid] = AGGR_PROGRESS; + spin_unlock_bh(&priv->tx.tx_lock); + } + } + } - tx_info->flags |= IEEE80211_TX_STAT_ACK; + rcu_read_unlock(); +} - if (!vif) - goto send_mac80211; +static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, + struct sk_buff *skb) +{ + struct ieee80211_vif *vif; + struct ath9k_htc_tx_ctl *tx_ctl; + struct ieee80211_tx_info *tx_info; + bool txok; + int slot; - rcu_read_lock(); + slot = strip_drv_header(priv, skb); + if (slot < 0) { + dev_kfree_skb_any(skb); + return; + } - sta = ieee80211_find_sta(vif, hdr->addr1); - if (!sta) { - rcu_read_unlock(); - goto send_mac80211; - } + tx_ctl = HTC_SKB_CB(skb); + txok = tx_ctl->txok; + tx_info = IEEE80211_SKB_CB(skb); + vif = tx_info->control.vif; - /* Check if we need to start aggregation */ + memset(&tx_info->status, 0, sizeof(tx_info->status)); - if (sta && conf_is_ht(&priv->hw->conf) && - !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { - if (ieee80211_is_data_qos(fc)) { - u8 *qc, tid; - struct ath9k_htc_sta *ista; + /* + * URB submission failed for this frame, it never reached + * the target. + */ + if (!txok || !vif) + goto send_mac80211; - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - ista = (struct ath9k_htc_sta *)sta->drv_priv; + tx_info->flags |= IEEE80211_TX_STAT_ACK; - if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { - ieee80211_start_tx_ba_session(sta, tid, 0); - spin_lock_bh(&priv->tx.tx_lock); - ista->tid_state[tid] = AGGR_PROGRESS; - spin_unlock_bh(&priv->tx.tx_lock); - } - } - } + ath9k_htc_check_tx_aggr(priv, vif, skb); - rcu_read_unlock(); +send_mac80211: + spin_lock_bh(&priv->tx.tx_lock); + if (WARN_ON(--priv->tx.queued_cnt < 0)) + priv->tx.queued_cnt = 0; + spin_unlock_bh(&priv->tx.tx_lock); - send_mac80211: - spin_lock_bh(&priv->tx.tx_lock); - if (WARN_ON(--priv->tx.queued_cnt < 0)) - priv->tx.queued_cnt = 0; - spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_tx_clear_slot(priv, slot); + + /* Send status to mac80211 */ + ieee80211_tx_status(priv->hw, skb); +} - ath9k_htc_tx_clear_slot(priv, slot); +void ath9k_tx_tasklet(unsigned long data) +{ + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct sk_buff *skb = NULL; - /* Send status to mac80211 */ - ieee80211_tx_status(priv->hw, skb); + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + ath9k_htc_tx_process(priv, skb); } /* Wake TX queues if needed */ -- cgit v1.2.3-70-g09d2 From b587fc81a80b9656f64e89fe0a106ffa4b35abca Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:59 +0530 Subject: ath9k_htc: Drain pending TX frames properly When doing a channel set or a reset operation the pending frames queued up for transmission have to be flushed and sent to mac80211. Fixing this has to be done in two separate steps: * Flush queued frames and kill the URB TX completion handler. * Complete all the frames that in the TX pending queue. This patch adds proper support for draining and all the callsites namely, channel change/reset/idle/stop are fixed. A separate queue is used for handling failed frames. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 55 ++++++++++---------------- drivers/net/wireless/ath/ath9k/htc.h | 6 ++- drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 8 ++-- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 15 ++++--- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 31 ++++++++++++++- 6 files changed, 69 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 0b63a48462c..db07e7b9320 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -131,7 +131,19 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, while ((skb = __skb_dequeue(list)) != NULL) { dev_kfree_skb_any(skb); - TX_STAT_INC(skb_dropped); + } +} + +static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, + struct sk_buff_head *queue, + bool txok) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(queue)) != NULL) { + ath9k_htc_txcompletion_cb(hif_dev->htc_handle, + skb, txok); + (txok) ? TX_STAT_INC(skb_success) : TX_STAT_INC(skb_failed); } } @@ -139,7 +151,7 @@ static void hif_usb_tx_cb(struct urb *urb) { struct tx_buf *tx_buf = (struct tx_buf *) urb->context; struct hif_device_usb *hif_dev; - struct sk_buff *skb; + bool txok = true; if (!tx_buf || !tx_buf->hif_dev) return; @@ -153,10 +165,7 @@ static void hif_usb_tx_cb(struct urb *urb) case -ECONNRESET: case -ENODEV: case -ESHUTDOWN: - /* - * The URB has been killed, free the SKBs. - */ - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); + txok = false; /* * If the URBs are being flushed, no need to add this @@ -165,41 +174,19 @@ static void hif_usb_tx_cb(struct urb *urb) spin_lock(&hif_dev->tx.tx_lock); if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { spin_unlock(&hif_dev->tx.tx_lock); + ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); return; } spin_unlock(&hif_dev->tx.tx_lock); - /* - * In the stop() case, this URB has to be added to - * the free list. - */ - goto add_free; + break; default: + txok = false; break; } - /* - * Check if TX has been stopped, this is needed because - * this CB could have been invoked just after the TX lock - * was released in hif_stop() and kill_urb() hasn't been - * called yet. - */ - spin_lock(&hif_dev->tx.tx_lock); - if (hif_dev->tx.flags & HIF_USB_TX_STOP) { - spin_unlock(&hif_dev->tx.tx_lock); - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); - goto add_free; - } - spin_unlock(&hif_dev->tx.tx_lock); - - /* Complete the queued SKBs. */ - while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { - ath9k_htc_txcompletion_cb(hif_dev->htc_handle, - skb, 1); - TX_STAT_INC(skb_completed); - } + ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); -add_free: /* Re-initialize the SKB queue */ tx_buf->len = tx_buf->offset = 0; __skb_queue_head_init(&tx_buf->skb_queue); @@ -272,7 +259,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); if (ret) { tx_buf->len = tx_buf->offset = 0; - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); + ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); __skb_queue_head_init(&tx_buf->skb_queue); list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; @@ -342,7 +329,7 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) unsigned long flags; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); - ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); + ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); hif_dev->tx.tx_skb_cnt = 0; hif_dev->tx.flags |= HIF_USB_TX_STOP; spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 45cf7557943..0d2e2b10358 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -271,6 +271,7 @@ struct ath9k_htc_tx { u8 flags; int queued_cnt; struct sk_buff_head tx_queue; + struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; }; @@ -305,8 +306,8 @@ struct ath_tx_stats { u32 buf_queued; u32 buf_completed; u32 skb_queued; - u32 skb_completed; - u32 skb_dropped; + u32 skb_success; + u32 skb_failed; u32 cab_queued; u32 queue_stats[WME_NUM_AC]; }; @@ -544,6 +545,7 @@ void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); +void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 6fc6cb74936..91a486cca32 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -88,11 +88,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, "%20s : %10u\n", "SKBs queued", priv->debug.tx_stats.skb_queued); len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.tx_stats.skb_completed); + "%20s : %10u\n", "SKBs success", + priv->debug.tx_stats.skb_success); len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs dropped", - priv->debug.tx_stats.skb_dropped); + "%20s : %10u\n", "SKBs failed", + priv->debug.tx_stats.skb_failed); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "CAB queued", priv->debug.tx_stats.cab_queued); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 92e4b312a98..dc0b33d0121 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -429,9 +429,8 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) /* Stop TX */ ieee80211_stop_queues(hw); - htc_stop(priv->htc); + ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - skb_queue_purge(&priv->tx.tx_queue); /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index c7e056b40e1..fb9ff1188a0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -193,7 +193,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_stop_ani(priv); ieee80211_stop_queues(priv->hw); - htc_stop(priv->htc); + + ath9k_htc_tx_drain(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); @@ -248,7 +250,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); ath9k_htc_ps_wakeup(priv); - htc_stop(priv->htc); + + ath9k_htc_tx_drain(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); @@ -263,6 +267,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, if (!fastcc) caldata = &priv->caldata; + ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (ret) { ath_err(common, @@ -960,16 +965,14 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) } ath9k_htc_ps_wakeup(priv); - htc_stop(priv->htc); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); tasklet_kill(&priv->rx_tasklet); - tasklet_kill(&priv->tx_tasklet); - - skb_queue_purge(&priv->tx.tx_queue); + ath9k_htc_tx_drain(priv); ath9k_wmi_event_drain(priv); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 944440c84c4..9e0c34b0a79 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -423,6 +423,26 @@ send_mac80211: ieee80211_tx_status(priv->hw, skb); } +void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) +{ + struct sk_buff *skb = NULL; + + /* + * Ensure that all pending TX frames are flushed, + * and that the TX completion tasklet is killed. + */ + htc_stop(priv->htc); + tasklet_kill(&priv->tx_tasklet); + + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } + + while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } +} + void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; @@ -432,6 +452,10 @@ void ath9k_tx_tasklet(unsigned long data) ath9k_htc_tx_process(priv, skb); } + while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } + /* Wake TX queues if needed */ ath9k_htc_check_wake_queues(priv); } @@ -445,13 +469,18 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; - skb_queue_tail(&priv->tx.tx_queue, skb); + if (txok) + skb_queue_tail(&priv->tx.tx_queue, skb); + else + skb_queue_tail(&priv->tx.tx_failed, skb); + tasklet_schedule(&priv->tx_tasklet); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { skb_queue_head_init(&priv->tx.tx_queue); + skb_queue_head_init(&priv->tx.tx_failed); return 0; } -- cgit v1.2.3-70-g09d2 From e1fe7c38d39f8f6ebdffc3a55e2ec6e2ec0d1872 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:06 +0530 Subject: ath9k_htc: Optimize HTC start/stop API There is no point in looping over all the endpoints, since the HIF layer uses the start/stop APIs only for the TX pipe. Simplify the API accordingly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++-- drivers/net/wireless/ath/ath9k/htc_hst.c | 19 ++----------------- drivers/net/wireless/ath/ath9k/htc_hst.h | 4 ++-- 3 files changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index db07e7b9320..b3f23c2be73 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -310,7 +310,7 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) return 0; } -static void hif_usb_start(void *hif_handle, u8 pipe_id) +static void hif_usb_start(void *hif_handle) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; unsigned long flags; @@ -322,7 +322,7 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); } -static void hif_usb_stop(void *hif_handle, u8 pipe_id) +static void hif_usb_stop(void *hif_handle) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index be87f4757bf..7ced8ab1ae4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -302,27 +302,12 @@ int htc_send_epid(struct htc_target *target, struct sk_buff *skb, void htc_stop(struct htc_target *target) { - enum htc_endpoint_id epid; - struct htc_endpoint *endpoint; - - for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { - endpoint = &target->endpoint[epid]; - if (endpoint->service_id != 0) - target->hif->stop(target->hif_dev, endpoint->ul_pipeid); - } + target->hif->stop(target->hif_dev); } void htc_start(struct htc_target *target) { - enum htc_endpoint_id epid; - struct htc_endpoint *endpoint; - - for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { - endpoint = &target->endpoint[epid]; - if (endpoint->service_id != 0) - target->hif->start(target->hif_dev, - endpoint->ul_pipeid); - } + target->hif->start(target->hif_dev); } void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 064a324b522..191e3c0837a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -33,8 +33,8 @@ struct ath9k_htc_hif { u8 control_dl_pipe; u8 control_ul_pipe; - void (*start) (void *hif_handle, u8 pipe); - void (*stop) (void *hif_handle, u8 pipe); + void (*start) (void *hif_handle); + void (*stop) (void *hif_handle); int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; -- cgit v1.2.3-70-g09d2 From 84c9e164468bd707e52b440e1c34bc3c85299332 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:11 +0530 Subject: ath9k_htc: Drain packets on station removal When a station entry is removed, there could still be pending packets destined for that station in the HIF layer. Sending these to the target is not necessary, so drain them in the driver itself. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 35 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_main.c | 3 +++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 ++++++ drivers/net/wireless/ath/ath9k/htc_hst.c | 5 ++++ drivers/net/wireless/ath/ath9k/htc_hst.h | 2 ++ 6 files changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index b3f23c2be73..7fae79d1666 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -363,6 +363,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) return ret; } +static inline bool check_index(struct sk_buff *skb, u8 idx) +{ + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if ((tx_ctl->type == ATH9K_HTC_AMPDU) && + (tx_ctl->sta_idx == idx)) + return true; + + return false; +} + +static void hif_usb_sta_drain(void *hif_handle, u8 idx) +{ + struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; + struct sk_buff *skb, *tmp; + unsigned long flags; + + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + + skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { + if (check_index(skb, idx)) { + __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); + ath9k_htc_txcompletion_cb(hif_dev->htc_handle, + skb, false); + hif_dev->tx.tx_skb_cnt--; + TX_STAT_INC(skb_failed); + } + } + + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); +} + static struct ath9k_htc_hif hif_usb = { .transport = ATH9K_HIF_USB, .name = "ath9k_hif_usb", @@ -372,6 +406,7 @@ static struct ath9k_htc_hif hif_usb = { .start = hif_usb_start, .stop = hif_usb_stop, + .sta_drain = hif_usb_sta_drain, .send = hif_usb_send, }; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0d2e2b10358..41823fd6d9a 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -280,6 +280,7 @@ struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ u8 epid; u8 txok; + u8 sta_idx; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index fb9ff1188a0..ae85cc4373f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1303,10 +1303,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct ath9k_htc_priv *priv = hw->priv; + struct ath9k_htc_sta *ista; int ret; mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); + ista = (struct ath9k_htc_sta *) sta->drv_priv; + htc_sta_drain(priv->htc, ista->index); ret = ath9k_htc_remove_station(priv, vif, sta); ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 9e0c34b0a79..0790070a7f6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -248,6 +248,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.vif_idx = vif_idx; tx_hdr.cookie = slot; + /* + * This is a bit redundant but it helps to get + * the per-packet index quickly when draining the + * TX queue in the HIF layer. Otherwise we would + * have to parse the packet contents ... + */ + tx_ctl->sta_idx = sta_idx; + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_ctl->type = ATH9K_HTC_AMPDU; tx_hdr.data_type = ATH9K_HTC_AMPDU; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 7ced8ab1ae4..5c76352b131 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -310,6 +310,11 @@ void htc_start(struct htc_target *target) target->hif->start(target->hif_dev); } +void htc_sta_drain(struct htc_target *target, u8 idx) +{ + target->hif->sta_drain(target->hif_dev, idx); +} + void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, struct sk_buff *skb, bool txok) { diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 191e3c0837a..cb9174ade53 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -35,6 +35,7 @@ struct ath9k_htc_hif { void (*start) (void *hif_handle); void (*stop) (void *hif_handle); + void (*sta_drain) (void *hif_handle, u8 idx); int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; @@ -209,6 +210,7 @@ int htc_send_epid(struct htc_target *target, struct sk_buff *skb, enum htc_endpoint_id epid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); +void htc_sta_drain(struct htc_target *target, u8 idx); void ath9k_htc_rx_msg(struct htc_target *htc_handle, struct sk_buff *skb, u32 len, u8 pipe_id); -- cgit v1.2.3-70-g09d2 From 27876a29de221186c9d5883e5fe5f6da18ef9a45 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:18 +0530 Subject: ath9k_htc: Add support for TX completion Now that the infrastructure is in place, process WMI TX status events and complete packets. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 14 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 208 ++++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/wmi.c | 10 ++ drivers/net/wireless/ath/ath9k/wmi.h | 4 +- 5 files changed, 207 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 41823fd6d9a..6c103edf890 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -266,11 +266,17 @@ struct ath9k_htc_rx { #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) +#define ATH9K_HTC_OP_TX_DRAIN BIT(1) struct ath9k_htc_tx { u8 flags; int queued_cnt; - struct sk_buff_head tx_queue; + struct sk_buff_head mgmt_ep_queue; + struct sk_buff_head cab_ep_queue; + struct sk_buff_head data_be_queue; + struct sk_buff_head data_bk_queue; + struct sk_buff_head data_vi_queue; + struct sk_buff_head data_vo_queue; struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; @@ -465,8 +471,8 @@ struct ath9k_htc_priv { struct tasklet_struct swba_tasklet; struct tasklet_struct rx_tasklet; - struct tasklet_struct tx_tasklet; struct delayed_work ani_work; + struct tasklet_struct tx_failed_tasklet; struct work_struct ps_work; struct work_struct fatal_work; @@ -533,7 +539,6 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); -void ath9k_tx_tasklet(unsigned long data); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb, u8 slot, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); @@ -547,6 +552,9 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); +void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); +void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); +void ath9k_tx_failed_tasklet(unsigned long data); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index c270da7be10..afceeaa6b91 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, mutex_init(&priv->htc_pm_lock); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, (unsigned long)priv); - tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, + tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet, (unsigned long)priv); INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 0790070a7f6..a9b6bb1ef28 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -99,8 +99,8 @@ void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) spin_unlock_bh(&priv->tx.tx_lock); } -static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, - u16 qnum) +static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, + u16 qnum) { enum htc_endpoint_id epid; @@ -127,6 +127,30 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +static inline struct sk_buff_head* +get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct sk_buff_head *epid_queue = NULL; + + if (epid == priv->mgmt_ep) + epid_queue = &priv->tx.mgmt_ep_queue; + else if (epid == priv->cab_ep) + epid_queue = &priv->tx.cab_ep_queue; + else if (epid == priv->data_be_ep) + epid_queue = &priv->tx.data_be_queue; + else if (epid == priv->data_bk_ep) + epid_queue = &priv->tx.data_bk_queue; + else if (epid == priv->data_vi_ep) + epid_queue = &priv->tx.data_vi_queue; + else if (epid == priv->data_vo_ep) + epid_queue = &priv->tx.data_vo_queue; + else + ath_err(common, "Invalid EPID: %d\n", epid); + + return epid_queue; +} + /* * Removes the driver header and returns the TX slot number */ @@ -387,11 +411,15 @@ static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, } static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, - struct sk_buff *skb) + struct sk_buff *skb, + struct __wmi_event_txstatus *txs) { struct ieee80211_vif *vif; struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *rate; + struct ieee80211_conf *cur_conf = &priv->hw->conf; + struct ieee80211_supported_band *sband; bool txok; int slot; @@ -405,6 +433,8 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, txok = tx_ctl->txok; tx_info = IEEE80211_SKB_CB(skb); vif = tx_info->control.vif; + rate = &tx_info->status.rates[0]; + sband = priv->hw->wiphy->bands[cur_conf->channel->band]; memset(&tx_info->status, 0, sizeof(tx_info->status)); @@ -412,10 +442,32 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, * URB submission failed for this frame, it never reached * the target. */ - if (!txok || !vif) + if (!txok || !vif || !txs) goto send_mac80211; - tx_info->flags |= IEEE80211_TX_STAT_ACK; + if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT) + tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS) + rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; + + rate->count = 1; + rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE); + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) { + rate->flags |= IEEE80211_TX_RC_MCS; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + } else { + if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) + rate->idx += 4; /* No CCK rates */ + } ath9k_htc_check_tx_aggr(priv, vif, skb); @@ -431,37 +483,130 @@ send_mac80211: ieee80211_tx_status(priv->hw, skb); } +static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(queue)) != NULL) { + ath9k_htc_tx_process(priv, skb, NULL); + } +} + void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) { - struct sk_buff *skb = NULL; + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; + spin_unlock_bh(&priv->tx.tx_lock); /* * Ensure that all pending TX frames are flushed, - * and that the TX completion tasklet is killed. + * and that the TX completion/failed tasklets is killed. */ htc_stop(priv->htc); - tasklet_kill(&priv->tx_tasklet); + tasklet_kill(&priv->wmi->wmi_event_tasklet); + tasklet_kill(&priv->tx_failed_tasklet); - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - ath9k_htc_tx_process(priv, skb); - } + ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); - while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { - ath9k_htc_tx_process(priv, skb); - } + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; + spin_unlock_bh(&priv->tx.tx_lock); } -void ath9k_tx_tasklet(unsigned long data) +void ath9k_tx_failed_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - struct sk_buff *skb = NULL; - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - ath9k_htc_tx_process(priv, skb); + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { + spin_unlock_bh(&priv->tx.tx_lock); + return; } + spin_unlock_bh(&priv->tx.tx_lock); - while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { - ath9k_htc_tx_process(priv, skb); + ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); +} + +static inline bool check_cookie(struct ath9k_htc_priv *priv, + struct sk_buff *skb, + u8 cookie, u8 epid) +{ + u8 fcookie = 0; + + if (epid == priv->mgmt_ep) { + struct tx_mgmt_hdr *hdr; + hdr = (struct tx_mgmt_hdr *) skb->data; + fcookie = hdr->cookie; + } else if ((epid == priv->data_bk_ep) || + (epid == priv->data_be_ep) || + (epid == priv->data_vi_ep) || + (epid == priv->data_vo_ep) || + (epid == priv->cab_ep)) { + struct tx_frame_hdr *hdr; + hdr = (struct tx_frame_hdr *) skb->data; + fcookie = hdr->cookie; + } + + if (fcookie == cookie) + return true; + + return false; +} + +static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, + struct __wmi_event_txstatus *txs) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct sk_buff_head *epid_queue; + struct sk_buff *skb, *tmp; + unsigned long flags; + u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID); + + epid_queue = get_htc_epid_queue(priv, epid); + if (!epid_queue) + return NULL; + + spin_lock_irqsave(&epid_queue->lock, flags); + skb_queue_walk_safe(epid_queue, skb, tmp) { + if (check_cookie(priv, skb, txs->cookie, epid)) { + __skb_unlink(skb, epid_queue); + spin_unlock_irqrestore(&epid_queue->lock, flags); + return skb; + } + } + spin_unlock_irqrestore(&epid_queue->lock, flags); + + ath_dbg(common, ATH_DBG_XMIT, + "No matching packet for cookie: %d, epid: %d\n", + txs->cookie, epid); + + return NULL; +} + +void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) +{ + struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; + struct __wmi_event_txstatus *__txs; + struct sk_buff *skb; + int i; + + for (i = 0; i < txs->cnt; i++) { + WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); + + __txs = &txs->txstatus[i]; + + skb = ath9k_htc_tx_get_packet(priv, __txs); + if (!skb) + continue; + + ath9k_htc_tx_process(priv, skb, __txs); } /* Wake TX queues if needed */ @@ -473,21 +618,34 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; struct ath9k_htc_tx_ctl *tx_ctl; + struct sk_buff_head *epid_queue; tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; - if (txok) - skb_queue_tail(&priv->tx.tx_queue, skb); - else + if (!txok) { skb_queue_tail(&priv->tx.tx_failed, skb); + tasklet_schedule(&priv->tx_failed_tasklet); + return; + } + + epid_queue = get_htc_epid_queue(priv, ep_id); + if (!epid_queue) { + dev_kfree_skb_any(skb); + return; + } - tasklet_schedule(&priv->tx_tasklet); + skb_queue_tail(epid_queue, skb); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { - skb_queue_head_init(&priv->tx.tx_queue); + skb_queue_head_init(&priv->tx.mgmt_ep_queue); + skb_queue_head_init(&priv->tx.cab_ep_queue); + skb_queue_head_init(&priv->tx.data_be_queue); + skb_queue_head_init(&priv->tx.data_bk_queue); + skb_queue_head_init(&priv->tx.data_vi_queue); + skb_queue_head_init(&priv->tx.data_vo_queue); skb_queue_head_init(&priv->tx.tx_failed); return 0; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index e66f6c33302..3f5a4d1fe07 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -163,6 +163,16 @@ void ath9k_wmi_event_tasklet(unsigned long data) wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); #endif break; + case WMI_TXSTATUS_EVENTID: + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { + spin_unlock_bh(&priv->tx.tx_lock); + break; + } + spin_unlock_bh(&priv->tx.tx_lock); + + ath9k_htc_txstatus(priv, wmi_event); + break; default: break; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 8c877dc2e2e..44b17385374 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -45,9 +45,9 @@ struct wmi_event_swba { /* * 64 - HTC header - WMI header - 1 / txstatus * And some other hdr. space is also accounted for. - * 13 seems to be the magic number. + * 12 seems to be the magic number. */ -#define HTC_MAX_TX_STATUS 13 +#define HTC_MAX_TX_STATUS 12 #define ATH9K_HTC_TXSTAT_ACK BIT(0) #define ATH9K_HTC_TXSTAT_FILT BIT(1) -- cgit v1.2.3-70-g09d2 From 01f684de7cc0641a9ee968f2d2c45c3a67241252 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:26 +0530 Subject: ath9k_htc: Add a debugfs file to dump TX slot information Location: ath9k_htc/phy#/slot Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 42 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 6c103edf890..b9c7bec9dd4 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -338,6 +338,7 @@ struct ath9k_debug { struct dentry *debugfs_tgt_stats; struct dentry *debugfs_xmit; struct dentry *debugfs_recv; + struct dentry *debugfs_slot; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; u32 txrate; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 91a486cca32..119cc544cea 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -244,6 +244,41 @@ static const struct file_operations fops_recv = { .llseek = default_llseek, }; +static ssize_t read_file_slot(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + spin_lock_bh(&priv->tx.tx_lock); + + len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); + + len += bitmap_scnprintf(buf + len, sizeof(buf) - len, + priv->tx.tx_slot, MAX_TX_BUF_NUM); + + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + + len += snprintf(buf + len, sizeof(buf) - len, + "Used slots : %d\n", + bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); + + spin_unlock_bh(&priv->tx.tx_lock); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_slot = { + .read = read_file_slot, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath9k_htc_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -276,6 +311,12 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_recv) goto err; + priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_slot); + if (!priv->debug.debugfs_slot) + goto err; + return 0; err: @@ -288,6 +329,7 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); debugfs_remove(priv->debug.debugfs_tgt_stats); -- cgit v1.2.3-70-g09d2 From c4d04186c7023d54445b695da226b3e98e0a55f9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:31 +0530 Subject: ath9k_htc: Add a debugfs file showing endpoint status Location: ath9k_htc/phy#/queue Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 54 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b9c7bec9dd4..b40753ca670 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -339,6 +339,7 @@ struct ath9k_debug { struct dentry *debugfs_xmit; struct dentry *debugfs_recv; struct dentry *debugfs_slot; + struct dentry *debugfs_queue; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; u32 txrate; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 119cc544cea..961bec20d14 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -279,6 +279,53 @@ static const struct file_operations fops_slot = { .llseek = default_llseek, }; +static ssize_t read_file_queue(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Failed queue", skb_queue_len(&priv->tx.tx_failed)); + + spin_lock_bh(&priv->tx.tx_lock); + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Queued count", priv->tx.queued_cnt); + spin_unlock_bh(&priv->tx.tx_lock); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); + +} + +static const struct file_operations fops_queue = { + .read = read_file_queue, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath9k_htc_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -317,6 +364,12 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_slot) goto err; + priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_queue); + if (!priv->debug.debugfs_queue) + goto err; + return 0; err: @@ -329,6 +382,7 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + debugfs_remove(priv->debug.debugfs_queue); debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); -- cgit v1.2.3-70-g09d2 From 859c3ca1e4608615788dc6cbc199210fe4b5efa2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:39 +0530 Subject: ath9k_htc: Add a timer to cleanup WMI events Occasionally, a WMI event would arrive ahead of the TX URB completion handler. Discarding these events would exhaust the available TX slots, so handle them by running a timer cleaning up such events. Also, timeout packets for which TX completion events have not arrived. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 8 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 +++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 127 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/wmi.c | 3 + drivers/net/wireless/ath/ath9k/wmi.h | 9 ++ 6 files changed, 159 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b40753ca670..b413b46119b 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -262,7 +262,10 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; -#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ +#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ +#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_TIMEOUT_COUNT 20 #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) @@ -279,6 +282,7 @@ struct ath9k_htc_tx { struct sk_buff_head data_vo_queue; struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); + struct timer_list cleanup_timer; spinlock_t tx_lock; }; @@ -287,6 +291,7 @@ struct ath9k_htc_tx_ctl { u8 epid; u8 txok; u8 sta_idx; + unsigned long timestamp; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) @@ -557,6 +562,7 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); void ath9k_tx_failed_tasklet(unsigned long data); +void ath9k_htc_tx_cleanup_timer(unsigned long data); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index afceeaa6b91..0aec25920c0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -671,7 +671,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common->priv = priv; common->debug_mask = ath9k_debug; - spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); spin_lock_init(&priv->tx.tx_lock); mutex_init(&priv->mutex); @@ -683,6 +682,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); INIT_WORK(&priv->fatal_work, ath9k_fatal_work); + setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer, + (unsigned long)priv); /* * Cache line size is used to size and align various diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ae85cc4373f..4de38643cb5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -194,6 +194,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_stop_ani(priv); ieee80211_stop_queues(priv->hw); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_vif_reconfig(priv); ieee80211_wake_queues(priv->hw); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -251,6 +255,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, ath9k_htc_ps_wakeup(priv); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -301,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) ath9k_htc_vif_reconfig(priv); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + err: ath9k_htc_ps_restore(priv); return ret; @@ -937,6 +945,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, AR_STOMP_LOW_WLAN_WGHT); @@ -972,6 +983,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) tasklet_kill(&priv->rx_tasklet); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); ath9k_wmi_event_drain(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a9b6bb1ef28..86f5ce9b6e0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -495,6 +495,8 @@ static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) { + struct ath9k_htc_tx_event *event, *tmp; + spin_lock_bh(&priv->tx.tx_lock); priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; spin_unlock_bh(&priv->tx.tx_lock); @@ -515,6 +517,16 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); + /* + * The TX cleanup timer has already been killed. + */ + spin_lock_bh(&priv->wmi->event_lock); + list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { + list_del(&event->list); + kfree(event); + } + spin_unlock_bh(&priv->wmi->event_lock); + spin_lock_bh(&priv->tx.tx_lock); priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; spin_unlock_bh(&priv->tx.tx_lock); @@ -595,6 +607,7 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; struct __wmi_event_txstatus *__txs; struct sk_buff *skb; + struct ath9k_htc_tx_event *tx_pend; int i; for (i = 0; i < txs->cnt; i++) { @@ -603,8 +616,26 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) __txs = &txs->txstatus[i]; skb = ath9k_htc_tx_get_packet(priv, __txs); - if (!skb) + if (!skb) { + /* + * Store this event, so that the TX cleanup + * routine can check later for the needed packet. + */ + tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), + GFP_ATOMIC); + if (!tx_pend) + continue; + + memcpy(&tx_pend->txs, __txs, + sizeof(struct __wmi_event_txstatus)); + + spin_lock(&priv->wmi->event_lock); + list_add_tail(&tx_pend->list, + &priv->wmi->pending_tx_events); + spin_unlock(&priv->wmi->event_lock); + continue; + } ath9k_htc_tx_process(priv, skb, __txs); } @@ -622,6 +653,7 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; + tx_ctl->timestamp = jiffies; if (!txok) { skb_queue_tail(&priv->tx.tx_failed, skb); @@ -638,6 +670,99 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, skb_queue_tail(epid_queue, skb); } +static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if (time_after(jiffies, + tx_ctl->timestamp + + msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { + ath_dbg(common, ATH_DBG_XMIT, + "Dropping a packet due to TX timeout\n"); + return true; + } + + return false; +} + +static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv, + struct sk_buff_head *epid_queue) +{ + bool process = false; + unsigned long flags; + struct sk_buff *skb, *tmp; + struct sk_buff_head queue; + + skb_queue_head_init(&queue); + + spin_lock_irqsave(&epid_queue->lock, flags); + skb_queue_walk_safe(epid_queue, skb, tmp) { + if (check_packet(priv, skb)) { + __skb_unlink(skb, epid_queue); + __skb_queue_tail(&queue, skb); + process = true; + } + } + spin_unlock_irqrestore(&epid_queue->lock, flags); + + if (process) { + skb_queue_walk_safe(&queue, skb, tmp) { + __skb_unlink(skb, &queue); + ath9k_htc_tx_process(priv, skb, NULL); + } + } +} + +void ath9k_htc_tx_cleanup_timer(unsigned long data) +{ + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data; + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_event *event, *tmp; + struct sk_buff *skb; + + spin_lock(&priv->wmi->event_lock); + list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { + + skb = ath9k_htc_tx_get_packet(priv, &event->txs); + if (skb) { + ath_dbg(common, ATH_DBG_XMIT, + "Found packet for cookie: %d, epid: %d\n", + event->txs.cookie, + MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); + + ath9k_htc_tx_process(priv, skb, &event->txs); + list_del(&event->list); + kfree(event); + continue; + } + + if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) { + list_del(&event->list); + kfree(event); + } + } + spin_unlock(&priv->wmi->event_lock); + + /* + * Check if status-pending packets have to be cleaned up. + */ + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue); + + /* Wake TX queues if needed */ + ath9k_htc_check_wake_queues(priv); + + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); +} + int ath9k_tx_init(struct ath9k_htc_priv *priv) { skb_queue_head_init(&priv->tx.mgmt_ep_queue); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 3f5a4d1fe07..697e5af842c 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -91,9 +91,12 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) wmi->drv_priv = priv; wmi->stopped = false; skb_queue_head_init(&wmi->wmi_event_queue); + spin_lock_init(&wmi->wmi_lock); + spin_lock_init(&wmi->event_lock); mutex_init(&wmi->op_mutex); mutex_init(&wmi->multi_write_mutex); init_completion(&wmi->cmd_wait); + INIT_LIST_HEAD(&wmi->pending_tx_events); tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, (unsigned long)wmi); diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 44b17385374..310d94eaed1 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -130,6 +130,12 @@ struct register_write { __be32 val; }; +struct ath9k_htc_tx_event { + int count; + struct __wmi_event_txstatus txs; + struct list_head list; +}; + struct wmi { struct ath9k_htc_priv *drv_priv; struct htc_target *htc; @@ -144,6 +150,9 @@ struct wmi { u32 cmd_rsp_len; bool stopped; + struct list_head pending_tx_events; + spinlock_t event_lock; + spinlock_t wmi_lock; atomic_t mwrite_cnt; -- cgit v1.2.3-70-g09d2 From 2f80194c90caea3668d0e3739518bf100449a813 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:46 +0530 Subject: ath9k_htc: Use separate URB pool for management frames Beacon transmission needs to involve as little latency as possible after receiving a SWBA event from the target. Since packets are buffered to use TX stream mode, beacon frames sometimes gets queued up and are not sent out immediately. Fix this by decoupling management frame transmission from the normal data path and send them out immediately. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 116 ++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath9k/hif_usb.h | 1 + 2 files changed, 108 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 7fae79d1666..3b0efab6513 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -78,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) if (cmd) { ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, - cmd->skb, 1); + cmd->skb, true); kfree(cmd); } @@ -124,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, return ret; } +static void hif_usb_mgmt_cb(struct urb *urb) +{ + struct cmd_buf *cmd = (struct cmd_buf *)urb->context; + struct hif_device_usb *hif_dev = cmd->hif_dev; + bool txok = true; + + if (!cmd || !cmd->skb || !cmd->hif_dev) + return; + + switch (urb->status) { + case 0: + break; + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + txok = false; + + /* + * If the URBs are being flushed, no need to complete + * this packet. + */ + spin_lock(&hif_dev->tx.tx_lock); + if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { + spin_unlock(&hif_dev->tx.tx_lock); + dev_kfree_skb_any(cmd->skb); + kfree(cmd); + return; + } + spin_unlock(&hif_dev->tx.tx_lock); + + break; + default: + txok = false; + break; + } + + skb_pull(cmd->skb, 4); + ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, + cmd->skb, txok); + kfree(cmd); +} + +static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, + struct sk_buff *skb) +{ + struct urb *urb; + struct cmd_buf *cmd; + int ret = 0; + __le16 *hdr; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (urb == NULL) + return -ENOMEM; + + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + if (cmd == NULL) { + usb_free_urb(urb); + return -ENOMEM; + } + + cmd->skb = skb; + cmd->hif_dev = hif_dev; + + hdr = (__le16 *) skb_push(skb, 4); + *hdr++ = cpu_to_le16(skb->len - 4); + *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); + + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), + skb->data, skb->len, + hif_usb_mgmt_cb, cmd); + + usb_anchor_urb(urb, &hif_dev->mgmt_submitted); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) { + usb_unanchor_urb(urb); + kfree(cmd); + } + usb_free_urb(urb); + + return ret; +} + static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, struct sk_buff_head *list) { @@ -275,6 +359,7 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) { struct ath9k_htc_tx_ctl *tx_ctl; unsigned long flags; + int ret = 0; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); @@ -289,25 +374,33 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) return -ENOMEM; } - __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); - hif_dev->tx.tx_skb_cnt++; + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); tx_ctl = HTC_SKB_CB(skb); - /* Send normal/mgmt/beacon frames immediately */ - if (tx_ctl->type != ATH9K_HTC_AMPDU) - __hif_usb_tx(hif_dev); + /* Mgmt/Beacon frames don't use the TX buffer pool */ + if ((tx_ctl->type == ATH9K_HTC_MGMT) || + (tx_ctl->type == ATH9K_HTC_BEACON)) { + ret = hif_usb_send_mgmt(hif_dev, skb); + } + + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + + if ((tx_ctl->type == ATH9K_HTC_NORMAL) || + (tx_ctl->type == ATH9K_HTC_AMPDU)) { + __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); + hif_dev->tx.tx_skb_cnt++; + } /* Check if AMPDUs have to be sent immediately */ - if ((tx_ctl->type == ATH9K_HTC_AMPDU) && - (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && + if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && (hif_dev->tx.tx_skb_cnt < 2)) { __hif_usb_tx(hif_dev); } spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); - return 0; + return ret; } static void hif_usb_start(void *hif_handle) @@ -339,6 +432,8 @@ static void hif_usb_stop(void *hif_handle) &hif_dev->tx.tx_pending, list) { usb_kill_urb(tx_buf->urb); } + + usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) @@ -657,6 +752,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) kfree(tx_buf->buf); kfree(tx_buf); } + + usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) @@ -668,6 +765,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) INIT_LIST_HEAD(&hif_dev->tx.tx_pending); spin_lock_init(&hif_dev->tx.tx_lock); __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); + init_usb_anchor(&hif_dev->mgmt_submitted); for (i = 0; i < MAX_TX_URB_NUM; i++) { tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 8b98d646e91..f59df48a86e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -93,6 +93,7 @@ struct hif_device_usb { struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; struct usb_anchor reg_in_submitted; + struct usb_anchor mgmt_submitted; struct sk_buff *remain_skb; const char *fw_name; int rx_remain_len; -- cgit v1.2.3-70-g09d2 From 821f9414c0546fbc99a999e9dc613d1756e1de8a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:52 +0530 Subject: ath9k_htc: Use helper routines for transmission Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 227 ++++++++++++++------------ 1 file changed, 127 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 86f5ce9b6e0..723a3a9c5cd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -211,28 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, return error; } +static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv, + struct ath9k_htc_vif *avp, + struct sk_buff *skb, + u8 sta_idx, u8 vif_idx, u8 slot) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_mgmt *mgmt; + struct ieee80211_hdr *hdr; + struct tx_mgmt_hdr mgmt_hdr; + struct ath9k_htc_tx_ctl *tx_ctl; + u8 *tx_fhdr; + + tx_ctl = HTC_SKB_CB(skb); + hdr = (struct ieee80211_hdr *) skb->data; + + memset(tx_ctl, 0, sizeof(*tx_ctl)); + memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); + + /* + * Set the TSF adjust value for probe response + * frame also. + */ + if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.probe_resp.timestamp = avp->tsfadjust; + } + + tx_ctl->type = ATH9K_HTC_MGMT; + + mgmt_hdr.node_idx = sta_idx; + mgmt_hdr.vif_idx = vif_idx; + mgmt_hdr.tidno = 0; + mgmt_hdr.flags = 0; + mgmt_hdr.cookie = slot; + + mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); + if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) + mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; + else + mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; + + tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); + memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); + tx_ctl->epid = priv->mgmt_ep; +} + +static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct sk_buff *skb, + u8 sta_idx, u8 vif_idx, u8 slot, + bool is_cab) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr; + struct ath9k_htc_tx_ctl *tx_ctl; + struct tx_frame_hdr tx_hdr; + u32 flags = 0; + u8 *qc, *tx_fhdr; + u16 qnum; + + tx_ctl = HTC_SKB_CB(skb); + hdr = (struct ieee80211_hdr *) skb->data; + + memset(tx_ctl, 0, sizeof(*tx_ctl)); + memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); + + tx_hdr.node_idx = sta_idx; + tx_hdr.vif_idx = vif_idx; + tx_hdr.cookie = slot; + + /* + * This is a bit redundant but it helps to get + * the per-packet index quickly when draining the + * TX queue in the HIF layer. Otherwise we would + * have to parse the packet contents ... + */ + tx_ctl->sta_idx = sta_idx; + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + tx_ctl->type = ATH9K_HTC_AMPDU; + tx_hdr.data_type = ATH9K_HTC_AMPDU; + } else { + tx_ctl->type = ATH9K_HTC_NORMAL; + tx_hdr.data_type = ATH9K_HTC_NORMAL; + } + + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + } + + /* Check for RTS protection */ + if (priv->hw->wiphy->rts_threshold != (u32) -1) + if (skb->len > priv->hw->wiphy->rts_threshold) + flags |= ATH9K_HTC_TX_RTSCTS; + + /* CTS-to-self */ + if (!(flags & ATH9K_HTC_TX_RTSCTS) && + (vif && vif->bss_conf.use_cts_prot)) + flags |= ATH9K_HTC_TX_CTSONLY; + + tx_hdr.flags = cpu_to_be32(flags); + tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); + if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) + tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; + else + tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; + + tx_fhdr = skb_push(skb, sizeof(tx_hdr)); + memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); + + if (is_cab) { + CAB_STAT_INC; + tx_ctl->epid = priv->cab_ep; + return; + } + + qnum = skb_get_queue_mapping(skb); + tx_ctl->epid = get_htc_epid(priv, qnum); +} + int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb, u8 slot, bool is_cab) { struct ieee80211_hdr *hdr; - struct ieee80211_mgmt *mgmt; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; - struct ath9k_htc_tx_ctl *tx_ctl; - u16 qnum; - __le16 fc; - u8 *tx_fhdr; u8 sta_idx, vif_idx; - tx_ctl = HTC_SKB_CB(skb); - memset(tx_ctl, 0, sizeof(*tx_ctl)); - hdr = (struct ieee80211_hdr *) skb->data; - fc = hdr->frame_control; /* * Find out on which interface this packet has to be @@ -261,99 +373,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, sta_idx = priv->vif_sta_pos[vif_idx]; } - if (ieee80211_is_data(fc)) { - struct tx_frame_hdr tx_hdr; - u32 flags = 0; - u8 *qc; - - memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); - - tx_hdr.node_idx = sta_idx; - tx_hdr.vif_idx = vif_idx; - tx_hdr.cookie = slot; - - /* - * This is a bit redundant but it helps to get - * the per-packet index quickly when draining the - * TX queue in the HIF layer. Otherwise we would - * have to parse the packet contents ... - */ - tx_ctl->sta_idx = sta_idx; - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - tx_ctl->type = ATH9K_HTC_AMPDU; - tx_hdr.data_type = ATH9K_HTC_AMPDU; - } else { - tx_ctl->type = ATH9K_HTC_NORMAL; - tx_hdr.data_type = ATH9K_HTC_NORMAL; - } - - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); - tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - } - - /* Check for RTS protection */ - if (priv->hw->wiphy->rts_threshold != (u32) -1) - if (skb->len > priv->hw->wiphy->rts_threshold) - flags |= ATH9K_HTC_TX_RTSCTS; - - /* CTS-to-self */ - if (!(flags & ATH9K_HTC_TX_RTSCTS) && - (vif && vif->bss_conf.use_cts_prot)) - flags |= ATH9K_HTC_TX_CTSONLY; - - tx_hdr.flags = cpu_to_be32(flags); - tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); - if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) - tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; - else - tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; - - tx_fhdr = skb_push(skb, sizeof(tx_hdr)); - memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); - - if (is_cab) { - CAB_STAT_INC; - tx_ctl->epid = priv->cab_ep; - goto send; - } - - qnum = skb_get_queue_mapping(skb); - tx_ctl->epid = get_htc_epid(priv, qnum); - } else { - struct tx_mgmt_hdr mgmt_hdr; - - memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); - - /* - * Set the TSF adjust value for probe response - * frame also. - */ - if (avp && unlikely(ieee80211_is_probe_resp(fc))) { - mgmt = (struct ieee80211_mgmt *)skb->data; - mgmt->u.probe_resp.timestamp = avp->tsfadjust; - } - - tx_ctl->type = ATH9K_HTC_MGMT; - - mgmt_hdr.node_idx = sta_idx; - mgmt_hdr.vif_idx = vif_idx; - mgmt_hdr.tidno = 0; - mgmt_hdr.flags = 0; - mgmt_hdr.cookie = slot; + if (ieee80211_is_data(hdr->frame_control)) + ath9k_htc_tx_data(priv, vif, skb, + sta_idx, vif_idx, slot, is_cab); + else + ath9k_htc_tx_mgmt(priv, avp, skb, + sta_idx, vif_idx, slot); - mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); - if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) - mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; - else - mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; - tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); - memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); - tx_ctl->epid = priv->mgmt_ep; - } -send: return htc_send(priv->htc, skb); } -- cgit v1.2.3-70-g09d2 From fbc29d6c3da58bc51416f65a50bdb419d4ea85b8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:58 +0530 Subject: ath9k_htc: Add detailed firmware statistics New debugfs files: /ath9k_htc//tgt_int_stats /ath9k_htc//tgt_tx_stats /ath9k_htc//tgt_rx_stats Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 36 +++-- drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 185 +++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/wmi.c | 19 ++- drivers/net/wireless/ath/ath9k/wmi.h | 7 +- 4 files changed, 195 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b413b46119b..cc5d0a4b9da 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -175,12 +175,31 @@ struct ath9k_htc_target_rate { struct ath9k_htc_rate rates; }; -struct ath9k_htc_target_stats { - __be32 tx_shortretry; - __be32 tx_longretry; - __be32 tx_xretries; - __be32 ht_txunaggr_xretry; - __be32 ht_tx_xretries; +struct ath9k_htc_target_int_stats { + __be32 rx; + __be32 rxorn; + __be32 rxeol; + __be32 txurn; + __be32 txto; + __be32 cst; +} __packed; + +struct ath9k_htc_target_tx_stats { + __be32 xretries; + __be32 fifoerr; + __be32 filtered; + __be32 timer_exp; + __be32 shortretries; + __be32 longretries; + __be32 qnull; + __be32 encap_fail; + __be32 nobuf; +} __packed; + +struct ath9k_htc_target_rx_stats { + __be32 nobuf; + __be32 host_send; + __be32 host_done; } __packed; #define ATH9K_HTC_MAX_VIF 2 @@ -340,14 +359,15 @@ struct ath_rx_stats { struct ath9k_debug { struct dentry *debugfs_phy; - struct dentry *debugfs_tgt_stats; + struct dentry *debugfs_tgt_int_stats; + struct dentry *debugfs_tgt_tx_stats; + struct dentry *debugfs_tgt_rx_stats; struct dentry *debugfs_xmit; struct dentry *debugfs_recv; struct dentry *debugfs_slot; struct dentry *debugfs_queue; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; - u32 txrate; }; #else diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 961bec20d14..8d0de60e0c2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -24,39 +24,108 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) return 0; } -static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) { struct ath9k_htc_priv *priv = file->private_data; - struct ath9k_htc_target_stats cmd_rsp; + struct ath9k_htc_target_int_stats cmd_rsp; char buf[512]; unsigned int len = 0; int ret = 0; memset(&cmd_rsp, 0, sizeof(cmd_rsp)); - WMI_CMD(WMI_TGT_STATS_CMDID); + WMI_CMD(WMI_INT_STATS_CMDID); if (ret) return -EINVAL; + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RX", + be32_to_cpu(cmd_rsp.rx)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXORN", + be32_to_cpu(cmd_rsp.rxorn)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXEOL", + be32_to_cpu(cmd_rsp.rxeol)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXURN", + be32_to_cpu(cmd_rsp.txurn)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXTO", + be32_to_cpu(cmd_rsp.txto)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CST", + be32_to_cpu(cmd_rsp.cst)); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_int_stats = { + .read = read_file_tgt_int_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_tx_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_TX_STATS_CMDID); + if (ret) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Xretries", + be32_to_cpu(cmd_rsp.xretries)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "FifoErr", + be32_to_cpu(cmd_rsp.fifoerr)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Filtered", + be32_to_cpu(cmd_rsp.filtered)); len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Short Retries", - be32_to_cpu(cmd_rsp.tx_shortretry)); + "%20s : %10u\n", "TimerExp", + be32_to_cpu(cmd_rsp.timer_exp)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Long Retries", - be32_to_cpu(cmd_rsp.tx_longretry)); + "%20s : %10u\n", "ShortRetries", + be32_to_cpu(cmd_rsp.shortretries)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries", - be32_to_cpu(cmd_rsp.tx_xretries)); + "%20s : %10u\n", "LongRetries", + be32_to_cpu(cmd_rsp.longretries)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Unaggr. Xretries", - be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); + "%20s : %10u\n", "QueueNull", + be32_to_cpu(cmd_rsp.qnull)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries (HT)", - be32_to_cpu(cmd_rsp.ht_tx_xretries)); + "%20s : %10u\n", "EncapFail", + be32_to_cpu(cmd_rsp.encap_fail)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Rate", priv->debug.txrate); + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); if (len > sizeof(buf)) len = sizeof(buf); @@ -64,8 +133,48 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, len); } -static const struct file_operations fops_tgt_stats = { - .read = read_file_tgt_stats, +static const struct file_operations fops_tgt_tx_stats = { + .read = read_file_tgt_tx_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_rx_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_RX_STATS_CMDID); + if (ret) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostSend", + be32_to_cpu(cmd_rsp.host_send)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostDone", + be32_to_cpu(cmd_rsp.host_done)); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_rx_stats = { + .read = read_file_tgt_rx_stats, .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -286,29 +395,29 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, char buf[512]; unsigned int len = 0; - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Failed queue", skb_queue_len(&priv->tx.tx_failed)); spin_lock_bh(&priv->tx.tx_lock); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Queued count", priv->tx.queued_cnt); spin_unlock_bh(&priv->tx.tx_lock); @@ -339,12 +448,26 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_phy) goto err; - priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_stats); - if (!priv->debug.debugfs_tgt_stats) + priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_int_stats); + if (!priv->debug.debugfs_tgt_int_stats) goto err; + priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_tx_stats); + if (!priv->debug.debugfs_tgt_tx_stats) + goto err; + + priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_rx_stats); + if (!priv->debug.debugfs_tgt_rx_stats) + goto err; priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, @@ -386,7 +509,9 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); - debugfs_remove(priv->debug.debugfs_tgt_stats); + debugfs_remove(priv->debug.debugfs_tgt_int_stats); + debugfs_remove(priv->debug.debugfs_tgt_tx_stats); + debugfs_remove(priv->debug.debugfs_tgt_rx_stats); debugfs_remove(priv->debug.debugfs_phy); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 697e5af842c..8f095ad0a3d 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -67,12 +67,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_RC_RATE_UPDATE_CMDID"; case WMI_TARGET_IC_UPDATE_CMDID: return "WMI_TARGET_IC_UPDATE_CMDID"; - case WMI_TGT_STATS_CMDID: - return "WMI_TGT_STATS_CMDID"; case WMI_TX_AGGR_ENABLE_CMDID: return "WMI_TX_AGGR_ENABLE_CMDID"; case WMI_TGT_DETACH_CMDID: return "WMI_TGT_DETACH_CMDID"; + case WMI_NODE_UPDATE_CMDID: + return "WMI_NODE_UPDATE_CMDID"; + case WMI_INT_STATS_CMDID: + return "WMI_INT_STATS_CMDID"; + case WMI_TX_STATS_CMDID: + return "WMI_TX_STATS_CMDID"; + case WMI_RX_STATS_CMDID: + return "WMI_RX_STATS_CMDID"; case WMI_AGGR_LIMIT_CMD: return "WMI_AGGR_LIMIT_CMD"; } @@ -134,9 +140,6 @@ void ath9k_wmi_event_tasklet(unsigned long data) struct sk_buff *skb = NULL; unsigned long flags; u16 cmd_id; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif do { spin_lock_irqsave(&wmi->wmi_lock, flags); @@ -160,12 +163,6 @@ void ath9k_wmi_event_tasklet(unsigned long data) ieee80211_queue_work(wmi->drv_priv->hw, &wmi->drv_priv->fatal_work); break; - case WMI_TXRATE_EVENTID: -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; case WMI_TXSTATUS_EVENTID: spin_lock_bh(&priv->tx.tx_lock); if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 310d94eaed1..02ecb9f06db 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -17,7 +17,6 @@ #ifndef WMI_H #define WMI_H - struct wmi_event_txrate { __be32 txrate; struct { @@ -106,9 +105,12 @@ enum wmi_cmd_id { WMI_RC_STATE_CHANGE_CMDID, WMI_RC_RATE_UPDATE_CMDID, WMI_TARGET_IC_UPDATE_CMDID, - WMI_TGT_STATS_CMDID, WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, + WMI_NODE_UPDATE_CMDID, + WMI_INT_STATS_CMDID, + WMI_TX_STATS_CMDID, + WMI_RX_STATS_CMDID, WMI_AGGR_LIMIT_CMD = 0x0026, }; @@ -119,7 +121,6 @@ enum wmi_event_id { WMI_TXTO_EVENTID, WMI_BMISS_EVENTID, WMI_DELBA_EVENTID, - WMI_TXRATE_EVENTID, WMI_TXSTATUS_EVENTID, }; -- cgit v1.2.3-70-g09d2 From 09d5b94d2cbc6c3ebb70a9a318f6390d0b4cf010 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:27:06 +0530 Subject: ath9k_htc: Enable AP and P2P modes Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 0aec25920c0..22736eb901c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -752,7 +752,10 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -- cgit v1.2.3-70-g09d2 From dfa8fc69d92f8418e1296d762f3b1624df59f0ac Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 14 Apr 2011 10:38:22 -0400 Subject: ath9k: avoid using trinary operator w/ TX_STAT_INC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise, you get this: CC [M] drivers/net/wireless/ath/ath9k/hif_usb.o drivers/net/wireless/ath/ath9k/hif_usb.c: In function ‘ath9k_skb_queue_complete’: drivers/net/wireless/ath/ath9k/hif_usb.c:230:12: error: expected expression before ‘do’ make[2]: *** [drivers/net/wireless/ath/ath9k/hif_usb.o] Error 1 make[1]: *** [drivers/net/wireless/ath/ath9k] Error 2 make: *** [drivers/net/wireless/ath/] Error 2 The TX_STAT_INC macro should probably be changed to accomodate such usage, although using a trinary operator in place of an if-else seems questionable to me anyway. Signed-off-by: John W. Linville Acked-by: Sujith Manoharan --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 3b0efab6513..48bcc1a2107 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -227,7 +227,10 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, while ((skb = __skb_dequeue(queue)) != NULL) { ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, txok); - (txok) ? TX_STAT_INC(skb_success) : TX_STAT_INC(skb_failed); + if (txok) + TX_STAT_INC(skb_success); + else + TX_STAT_INC(skb_failed); } } -- cgit v1.2.3-70-g09d2 From 10add41f2b7a7bc1a74ba7bb535a6745cac318a2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Apr 2011 17:29:29 +0530 Subject: ath9k: Fix improper beacon slot selection in IBSS Request a re-configuration of Beacon related timers on the receipt of the first Beacon frame has to be set only for station mode. Setting beacon sync for IBSS is causing wrong beacon slot selection on beacon generation. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b56f69e7677..9193a385ceb 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -744,7 +744,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) cur_conf->dtim_period = 1; ath_set_beacon(sc); - sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; } void ath_set_beacon(struct ath_softc *sc) @@ -762,6 +761,12 @@ void ath_set_beacon(struct ath_softc *sc) break; case NL80211_IFTYPE_STATION: ath_beacon_config_sta(sc, cur_conf); + /* + * Request a re-configuration of Beacon related timers + * on the receipt of the first Beacon frame (i.e., + * after time sync with the AP). + */ + sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; break; default: ath_dbg(common, ATH_DBG_CONFIG, -- cgit v1.2.3-70-g09d2 From 7f94f05b24b47f6b70f2322b26876d0636329dfe Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:42 +0200 Subject: ath5k: disable 5 GHz support if a 2.4 GHz radio is detected On a dual-radio dual-band AR5312 device, the calibration data is shared between the 5 GHz and the 2.4 GHz radio/MAC. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/caps.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index f77e8a703c5..7dd88e1c3ff 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) } } + if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) + __clear_bit(AR5K_MODE_11A, caps->cap_mode); + /* Set number of supported TX queues */ if (ah->ah_version == AR5K_AR5210) caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; -- cgit v1.2.3-70-g09d2 From 0cb9e06b6359bfa82f46c38a0b43e72d90b84081 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:43 +0200 Subject: ath: unshare struct ath_bus_ops between ath5k and ath9k This struct is not used in any common code, and moving it out of the ath header makes it easier to add more driver specific ops. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 9 +-------- drivers/net/wireless/ath/ath5k/ath5k.h | 6 ++++++ drivers/net/wireless/ath/ath9k/hw.h | 8 ++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 6d7105b7e8f..7cf4317a2a8 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -123,14 +123,7 @@ struct ath_ops { }; struct ath_common; - -struct ath_bus_ops { - enum ath_bus_type ath_bus_type; - void (*read_cachesize)(struct ath_common *common, int *csz); - bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); - void (*bt_coex_prep)(struct ath_common *common); - void (*extn_synch_en)(struct ath_common *common); -}; +struct ath_bus_ops; struct ath_common { void *ah; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e303db7ee6f..266e548acf7 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1155,6 +1155,12 @@ struct ath5k_hw { struct ath5k_rx_status *); }; +struct ath_bus_ops { + enum ath_bus_type ath_bus_type; + void (*read_cachesize)(struct ath_common *common, int *csz); + bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); +}; + /* * Prototypes */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a778b66f443..073bc9e1c79 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -846,6 +846,14 @@ struct ath_hw { u32 ent_mode; }; +struct ath_bus_ops { + enum ath_bus_type ath_bus_type; + void (*read_cachesize)(struct ath_common *common, int *csz); + bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); + void (*bt_coex_prep)(struct ath_common *common); + void (*extn_synch_en)(struct ath_common *common); +}; + static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) { return &ah->common; -- cgit v1.2.3-70-g09d2 From fa9bfd61e03e8dbcf110a93b373234d17a732233 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:44 +0200 Subject: ath5k: add a new bus op for reading the mac address On AHB, the calibration data usually does not contain a valid MAC address, the correct MAC address is stored in the board config. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 18 ++++++++++++++++++ drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 2 +- drivers/net/wireless/ath/ath5k/eeprom.c | 29 ----------------------------- drivers/net/wireless/ath/ath5k/pci.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 82324e98efe..1374e647f4e 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "ath5k.h" #include "debug.h" @@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) return 0; } +static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + struct ath5k_softc *sc = ah->ah_sc; + struct platform_device *pdev = to_platform_device(sc->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; + u8 *cfg_mac; + + if (to_platform_device(sc->dev)->id == 0) + cfg_mac = bcfg->config->wlan0_mac; + else + cfg_mac = bcfg->config->wlan1_mac; + + memcpy(mac, cfg_mac, ETH_ALEN); + return 0; +} + static const struct ath_bus_ops ath_ahb_bus_ops = { .ath_bus_type = ATH_AHB, .read_cachesize = ath5k_ahb_read_cachesize, .eeprom_read = ath5k_ahb_eeprom_read, + .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, }; /*Initialization*/ diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 266e548acf7..bb50700436f 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1159,6 +1159,7 @@ struct ath_bus_ops { enum ath_bus_type ath_bus_type; void (*read_cachesize)(struct ath_common *common, int *csz); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); + int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac); }; /* @@ -1244,7 +1245,6 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah); /* EEPROM access functions */ int ath5k_eeprom_init(struct ath5k_hw *ah); void ath5k_eeprom_detach(struct ath5k_hw *ah); -int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); /* Protocol Control Unit Functions */ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c7da0045439..7583841fc29 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2880,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw) INIT_WORK(&sc->reset_work, ath5k_reset_work); INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); - ret = ath5k_eeprom_read_mac(ah, mac); + ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); if (ret) { ATH5K_ERR(sc, "unable to read address from EEPROM\n"); goto err_queues; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index fb12027e034..e9263e4c7f3 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1732,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) return ret; } -/* - * Read the MAC address from eeprom - */ -int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) -{ - u8 mac_d[ETH_ALEN] = {}; - u32 total, offset; - u16 data; - int octet; - - AR5K_EEPROM_READ(0x20, data); - - for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - AR5K_EEPROM_READ(offset, data); - - total += data; - mac_d[octet + 1] = data & 0xff; - mac_d[octet] = data >> 8; - octet += 2; - } - - if (!total || total == 3 * 0xffff) - return -EINVAL; - - memcpy(mac, mac_d, ETH_ALEN); - - return 0; -} - /***********************\ * Init/Detach functions * diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 66598a0d1df..5cc4a2fe47b 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "../ath.h" #include "ath5k.h" #include "debug.h" @@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) return 0; } +/* + * Read the MAC address from eeprom or platform_data + */ +static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + u8 mac_d[ETH_ALEN] = {}; + u32 total, offset; + u16 data; + int octet; + + AR5K_EEPROM_READ(0x20, data); + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { + AR5K_EEPROM_READ(offset, data); + + total += data; + mac_d[octet + 1] = data & 0xff; + mac_d[octet] = data >> 8; + octet += 2; + } + + if (!total || total == 3 * 0xffff) + return -EINVAL; + + memcpy(mac, mac_d, ETH_ALEN); + + return 0; +} + + /* Common ath_bus_opts structure */ static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath5k_pci_read_cachesize, .eeprom_read = ath5k_pci_eeprom_read, + .eeprom_read_mac = ath5k_pci_eeprom_read_mac, }; /********************\ -- cgit v1.2.3-70-g09d2 From 32377b6cf75247cbdd0640efb43bef992efe3b68 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:45 +0200 Subject: ath5k: fix the EEPROM check for hw AES crypto support EEPROM version 5.0 adds a new field for disabling AES support, having an older version means that AES is present. This patch fixes hw AES crypto support on AR5312 boards, which have an older EEPROM version. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index bc824056048..326d7c84c91 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -318,7 +318,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); if (srev >= AR5K_SREV_AR5212_V4 && - (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && + (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; -- cgit v1.2.3-70-g09d2 From 3a9dddea89eb2132ba919fe04cb3b44a3b1e6db7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:46 +0200 Subject: ath5k: disable 5 GHz support for the dualband PHY chip on dual-radio AR5312 There are two variants of AR5312 dual-band devices, one single-radio and the other one dual-radio. On the dual-radio board, the first MAC only supports 5 GHz, even though it has a dual-band PHY. The 2.4 GHz part of this phy is used in pass-through mode, connecting the second MAC with the second PHY. Disable 2.4 GHz for the first MAC on an AR5312, but only if the board configuration indicates a dual-radio device. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 10 ++++++++++ drivers/net/wireless/ath/ath5k/attach.c | 5 +++++ drivers/net/wireless/ath/ath5k/base.h | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 1374e647f4e..ea998278155 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -160,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev) else reg |= AR5K_AR5312_ENABLE_WLAN1; __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + + /* + * On a dual-band AR5312, the multiband radio is only + * used as pass-through. Disable 2 GHz support in the + * driver for it + */ + if (to_platform_device(sc->dev)->id == 0 && + (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) == + (BD_WLAN1|BD_WLAN0)) + __set_bit(ATH_STAT_2G_DISABLED, sc->status); } ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 326d7c84c91..1588401de3c 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -313,6 +313,11 @@ int ath5k_hw_init(struct ath5k_softc *sc) goto err; } + if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) { + __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); + __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); + } + /* Crypto settings */ common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 4c4e36064a3..b294f330501 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -193,12 +193,13 @@ struct ath5k_softc { dma_addr_t desc_daddr; /* DMA (physical) address */ size_t desc_len; /* size of TX/RX descriptors */ - DECLARE_BITMAP(status, 5); + DECLARE_BITMAP(status, 6); #define ATH_STAT_INVALID 0 /* disable hardware accesses */ #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ #define ATH_STAT_PROMISC 2 #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ +#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ struct ieee80211_channel *curchan; /* current h/w channel */ -- cgit v1.2.3-70-g09d2 From 600f5d909a54a8dccf8c8c23898fc2e91bc0953e Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 13 Apr 2011 17:27:06 -0700 Subject: mwifiex: cleanup ioctl wait queue and abstraction layer 1) remove mwifiex_alloc_fill_wait_queue() and mwifiex_request_ioctl() 2) avoid dynamic allocation of wait queue 3) remove unnecessary mwifiex_error_code macros that were used mainly by the wait queue status code 4) remove some abstraction functions 5) split mwifiex_prepare_cmd() to mwifiex_send_cmd_async() and mwifiex_send_sync() to handle asynchronous and synchronous commands respectively Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 13 +- drivers/net/wireless/mwifiex/11n_rxreorder.c | 2 +- drivers/net/wireless/mwifiex/README | 2 +- drivers/net/wireless/mwifiex/cfg80211.c | 113 ++- drivers/net/wireless/mwifiex/cmdevt.c | 179 ++--- drivers/net/wireless/mwifiex/debugfs.c | 4 +- drivers/net/wireless/mwifiex/decl.h | 24 +- drivers/net/wireless/mwifiex/init.c | 3 +- drivers/net/wireless/mwifiex/join.c | 90 +-- drivers/net/wireless/mwifiex/main.c | 71 +- drivers/net/wireless/mwifiex/main.h | 123 +--- drivers/net/wireless/mwifiex/scan.c | 126 +--- drivers/net/wireless/mwifiex/sdio.c | 11 +- drivers/net/wireless/mwifiex/sta_cmd.c | 60 +- drivers/net/wireless/mwifiex/sta_cmdresp.c | 29 +- drivers/net/wireless/mwifiex/sta_event.c | 25 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 1008 ++++---------------------- drivers/net/wireless/mwifiex/sta_tx.c | 2 +- drivers/net/wireless/mwifiex/util.c | 51 +- 19 files changed, 502 insertions(+), 1434 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 73a6e62f568..edf4c274fa9 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -541,9 +541,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; if (curr_tx_buf_size != tx_buf) - mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, - HostCmd_ACT_GEN_SET, 0, - NULL, &tx_buf); + mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, &tx_buf); return; } @@ -694,8 +693,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); /* We don't wait for the response of this command */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, - 0, 0, NULL, &add_ba_req); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, + 0, 0, &add_ba_req); return ret; } @@ -722,8 +721,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); /* We don't wait for the response of this command */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, - HostCmd_ACT_GEN_SET, 0, NULL, &delba); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, + HostCmd_ACT_GEN_SET, 0, &delba); return ret; } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 8e94e620e6f..ef46d0a8a6d 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -609,7 +609,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, delba.del_ba_param_set |= cpu_to_le16( (u16) event->origninator << DELBA_INITIATOR_POS); delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); - mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); + mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); return; } diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README index 338377f7093..b55badef466 100644 --- a/drivers/net/wireless/mwifiex/README +++ b/drivers/net/wireless/mwifiex/README @@ -157,7 +157,7 @@ info mp_wr_bitmap = cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> event_received = <0/1, no event to process/event received and yet to process> - ioctl_pending = + cmd_pending = tx_pending = rx_pending = diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ec0895f4e8d..a1ff490da83 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_power_cfg power_cfg; - ret = mwifiex_set_tx_power(priv, type, dbm); + if (type == NL80211_TX_POWER_FIXED) { + power_cfg.is_power_auto = 0; + power_cfg.power_level = dbm; + } else { + power_cfg.is_power_auto = 1; + } + + ret = mwifiex_set_tx_power(priv, &power_cfg); return ret; } @@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + u32 ps_mode; if (timeout) wiphy_dbg(wiphy, "info: ignoring the timeout value" " for IEEE power save\n"); - ret = mwifiex_drv_set_power(priv, enabled); + ps_mode = enabled; + ret = mwifiex_drv_set_power(priv, &ps_mode); return ret; } @@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; /* Send cmd to FW to set domain info */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) wiphy_err(wiphy, "11D: setting domain info in FW\n"); @@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, { struct mwifiex_chan_freq_power cfp; int ret = 0; - int status = 0; struct mwifiex_ds_band_cfg band_cfg; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; @@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, band_cfg.sec_chan_offset = mwifiex_cfg80211_channel_type_to_mwifiex_channels (channel_type); - status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, - &band_cfg); + ret = mwifiex_set_radio_band_cfg(priv, &band_cfg); - if (status) + if (ret) return -EFAULT; mwifiex_send_domain_info_cmd_fw(wiphy); } @@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, /* Convert frequency to channel */ cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); - status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); - if (status) + ret = mwifiex_bss_set_channel(priv, &cfp); + if (ret) return -EFAULT; ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); @@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, /* * This function sets the fragmentation threshold. * - * This function creates an IOCTL request, populates it accordingly - * and issues an IOCTL. - * - * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE + * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE * and MWIFIEX_FRAG_MAX_VALUE. */ static int mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || frag_thr > MWIFIEX_FRAG_MAX_VALUE) return -EINVAL; - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, FRAG_THRESH_I, + &frag_thr); - status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I, - HostCmd_ACT_GEN_SET, &frag_thr); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -EFAULT; - - kfree(wait); return ret; } /* * This function sets the RTS threshold. - * - * This function creates an IOCTL request, populates it accordingly - * and issues an IOCTL. + + * The rts value must lie between MWIFIEX_RTS_MIN_VALUE + * and MWIFIEX_RTS_MAX_VALUE. */ static int mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) rts_thr = MWIFIEX_RTS_MAX_VALUE; - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I, - HostCmd_ACT_GEN_SET, &rts_thr); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -EFAULT; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, RTS_THRESH_I, + &rts_thr); - kfree(wait); return ret; } @@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - struct mwifiex_wait_queue *wait = NULL; if (priv->bss_mode == type) { wiphy_warn(wiphy, "already set to required type\n"); @@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, return -EINVAL; } - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - mwifiex_deauthenticate(priv, wait, NULL); + mwifiex_deauthenticate(priv, NULL); priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, - HostCmd_ACT_GEN_SET, 0, wait, NULL); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, + HostCmd_ACT_GEN_SET, 0, NULL); - ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT); - if (ret) - ret = -EFAULT; - - kfree(wait); return ret; } @@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* Get signal information from the firmware */ memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); - if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { + if (mwifiex_get_signal_info(priv, &signal)) { dev_err(priv->adapter->dev, "getting signal information\n"); ret = -EFAULT; } @@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, return -EBUSY; priv->disconnect = 1; - if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" @@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, u8 element_id, element_len; memset(&scan_resp, 0, sizeof(scan_resp)); - if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) - return -EFAULT; + scan_resp.scan_table = (u8 *) priv->adapter->scan_table; + scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table; #define MAX_IE_BUF 2048 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); @@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } /* disconnect before try to associate */ - mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); + mwifiex_deauthenticate(priv, NULL); if (channel) ret = mwifiex_set_rf_channel(priv, channel, @@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } done: /* Do specific SSID scanning */ - if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { + if (mwifiex_request_scan(priv, &req_ssid)) { dev_err(priv->adapter->dev, "scan error\n"); return -EFAULT; } @@ -1055,8 +1030,7 @@ done: memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); if (mode != NL80211_IFTYPE_ADHOC) { - if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, - &ssid_bssid)) + if (mwifiex_find_best_bss(priv, &ssid_bssid)) return -EFAULT; /* Inform the BSS information to kernel, otherwise * kernel will give a panic after successful assoc */ @@ -1072,7 +1046,10 @@ done: /* Connect to BSS by ESSID */ memset(&ssid_bssid.bssid, 0, ETH_ALEN); - if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + + if (mwifiex_bss_start(priv, &ssid_bssid)) return -EFAULT; if (mode == NL80211_IFTYPE_ADHOC) { @@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", priv->cfg_bssid); - if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; queue_work(priv->workqueue, &priv->cfg_workqueue); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8676480ead9..bb6fecd7761 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -36,11 +36,12 @@ static void mwifiex_init_cmd_node(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node, - u32 cmd_oid, void *wait_queue, void *data_buf) + u32 cmd_oid, void *data_buf) { cmd_node->priv = priv; cmd_node->cmd_oid = cmd_oid; - cmd_node->wq_buf = wait_queue; + cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; + priv->adapter->cmd_wait_q_required = false; cmd_node->data_buf = data_buf; cmd_node->cmd_skb = cmd_node->skb; } @@ -86,8 +87,8 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, { cmd_node->cmd_oid = 0; cmd_node->cmd_flag = 0; - cmd_node->wq_buf = NULL; cmd_node->data_buf = NULL; + cmd_node->wait_q_enabled = false; if (cmd_node->resp_skb) { mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); @@ -97,30 +98,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, return; } -/* - * This function returns a command node from the pending queue which - * matches the given IOCTL request. - */ -static struct cmd_ctrl_node * -mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue) -{ - unsigned long flags; - struct cmd_ctrl_node *cmd_node; - - spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); - list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { - if (cmd_node->wq_buf == wait_queue) { - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, - flags); - return cmd_node; - } - } - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); - - return NULL; -} - /* * This function sends a host command to the firmware. * @@ -155,7 +132,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; struct host_cmd_ds_command *host_cmd; - struct mwifiex_wait_queue *wait_queue = NULL; uint16_t cmd_code; uint16_t cmd_size; struct timeval tstamp; @@ -165,15 +141,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, return -1; host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); - if (cmd_node->wq_buf) - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; /* Sanity test */ if (host_cmd == NULL || host_cmd->size == 0) { dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" " or cmd size is 0, not sending\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } @@ -210,8 +184,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, if (ret == -1) { dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); @@ -437,7 +411,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) } /* - * This function prepares a command before sending it to the firmware. + * This function is used to send synchronous command to the firmware. + * + * it allocates a wait queue for the command and wait for the command + * response. + */ +int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + + adapter->cmd_wait_q_required = true; + adapter->cmd_wait_q.condition = false; + + ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, + data_buf); + if (!ret) + ret = mwifiex_wait_queue_complete(adapter); + + return ret; +} + + +/* + * This function prepares a command and asynchronously send it to the firmware. * * Preparation includes - * - Sanity tests to make sure the card is still present or the FW @@ -447,9 +445,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) * - Fill up the non-default parameters and buffer pointers * - Add the command to pending queue */ -int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, - u16 cmd_action, u32 cmd_oid, - void *wait_queue, void *data_buf) +int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -487,7 +484,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, } /* Initialize the command node */ - mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); + mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); if (!cmd_node->cmd_skb) { dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); @@ -537,18 +534,13 @@ void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { - struct mwifiex_wait_queue *wait_queue = NULL; unsigned long flags; if (cmd_node == NULL) return; - if (cmd_node->wq_buf) { - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; - if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) - mwifiex_ioctl_complete(adapter, wait_queue, -1); - else - mwifiex_ioctl_complete(adapter, wait_queue, 0); - } + + if (cmd_node->wait_q_enabled) + mwifiex_complete_cmd(adapter); /* Clean the node */ mwifiex_clean_cmd_node(adapter, cmd_node); @@ -694,7 +686,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) uint16_t orig_cmdresp_no; uint16_t cmdresp_no; uint16_t cmdresp_result; - struct mwifiex_wait_queue *wait_queue = NULL; struct timeval tstamp; unsigned long flags; @@ -708,10 +699,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) return -1; } - if (adapter->curr_cmd->wq_buf) - wait_queue = (struct mwifiex_wait_queue *) - adapter->curr_cmd->wq_buf; - adapter->num_cmd_timeout = 0; resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; @@ -766,8 +753,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); @@ -783,8 +770,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) ret = mwifiex_ret_802_11_hs_cfg(priv, resp); } else { /* handle response */ - ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, - wait_queue); + ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp); } /* Check init command response */ @@ -799,10 +785,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) } if (adapter->curr_cmd) { - if (wait_queue && (!ret)) - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - else if (wait_queue && (ret == -1)) - wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; + if (adapter->curr_cmd->wait_q_enabled && (!ret)) + adapter->cmd_wait_q.status = 0; + else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) + adapter->cmd_wait_q.status = -1; /* Clean up and put current command back to cmd_free_q */ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); @@ -826,7 +812,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) struct mwifiex_adapter *adapter = (struct mwifiex_adapter *) function_context; struct cmd_ctrl_node *cmd_node = NULL; - struct mwifiex_wait_queue *wait_queue = NULL; struct timeval tstamp; adapter->num_cmd_timeout++; @@ -836,10 +821,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wq_buf) { - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; - wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT; - } + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -ETIMEDOUT; if (cmd_node) { adapter->dbg.timeout_cmd_id = @@ -903,18 +886,15 @@ void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; - struct mwifiex_wait_queue *wait_queue = NULL; unsigned long flags; /* Cancel current cmd */ - if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { - wait_queue = - (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf; + if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); - adapter->curr_cmd->wq_buf = NULL; + adapter->curr_cmd->wait_q_enabled = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); } /* Cancel all pending command */ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); @@ -923,12 +903,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); - if (cmd_node->wq_buf) { - wait_queue = - (struct mwifiex_wait_queue *) cmd_node->wq_buf; - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); - cmd_node->wq_buf = NULL; + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); + cmd_node->wait_q_enabled = false; } mwifiex_insert_cmd_to_free_q(adapter, cmd_node); spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); @@ -942,7 +920,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - cmd_node->wq_buf = NULL; + cmd_node->wait_q_enabled = false; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); } @@ -964,8 +942,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) * are cancelled. */ void -mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue) +mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; @@ -974,45 +951,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && - (adapter->curr_cmd->wq_buf == wait_queue)) { + (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); cmd_node = adapter->curr_cmd; - cmd_node->wq_buf = NULL; + cmd_node->wait_q_enabled = false; cmd_node->cmd_flag |= CMD_F_CANCELED; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); - } - - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); - while (1) { - cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue); - if (!cmd_node) - break; - spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); - - cmd_node->wq_buf = NULL; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + /* Cancel all pending scan command */ spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_pending_q_flags); list_for_each_entry_safe(cmd_node, tmp_node, &adapter->scan_pending_q, list) { - if (cmd_node->wq_buf == wait_queue) { - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - scan_pending_q_flags); - cmd_node->wq_buf = NULL; - mwifiex_insert_cmd_to_free_q(adapter, cmd_node); - spin_lock_irqsave(&adapter->scan_pending_q_lock, - scan_pending_q_flags); - cancel_scan_cmd = true; - } + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cmd_node->wait_q_enabled = false; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cancel_scan_cmd = true; } spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_pending_q_flags); @@ -1022,8 +987,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, adapter->scan_processing = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); return; } diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 63b09692f27..77d7c777ea6 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -129,8 +129,8 @@ static struct mwifiex_debug_data items[] = { item_addr(event_received), 1}, /* variables defined in struct mwifiex_adapter */ - {"ioctl_pending", adapter_item_size(ioctl_pending), - adapter_item_addr(ioctl_pending), 1}, + {"cmd_pending", adapter_item_size(cmd_pending), + adapter_item_addr(cmd_pending), 1}, {"tx_pending", adapter_item_size(tx_pending), adapter_item_addr(tx_pending), 1}, {"rx_pending", adapter_item_size(rx_pending), diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index c3c15f9e757..8364b62c329 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -61,23 +61,6 @@ #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) -enum mwifiex_error_code { - MWIFIEX_ERROR_NO_ERROR = 0, - MWIFIEX_ERROR_FW_NOT_READY = 0x00000001, - MWIFIEX_ERROR_FW_BUSY, - MWIFIEX_ERROR_FW_CMDRESP, - MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001, - MWIFIEX_ERROR_PKT_TIMEOUT, - MWIFIEX_ERROR_CMD_INVALID, - MWIFIEX_ERROR_CMD_TIMEOUT, - MWIFIEX_ERROR_CMD_DNLD_FAIL, - MWIFIEX_ERROR_CMD_CANCEL, - MWIFIEX_ERROR_CMD_RESP_FAIL, - MWIFIEX_ERROR_ASSOC_FAIL, - MWIFIEX_ERROR_EVENT_UNKNOWN, - MWIFIEX_ERROR_INVALID_PARAMETER, -}; - enum mwifiex_bss_type { MWIFIEX_BSS_TYPE_STA = 0, MWIFIEX_BSS_TYPE_UAP = 1, @@ -112,12 +95,9 @@ struct mwifiex_802_11_ssid { }; struct mwifiex_wait_queue { - u32 bss_index; - wait_queue_head_t *wait; - u16 *condition; - u32 start_time; + wait_queue_head_t wait; + u16 condition; int status; - u32 enabled; }; struct mwifiex_rxinfo { diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 8189862da1f..26931d5f950 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -35,7 +35,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bss_prio; - int status = 0; unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); @@ -59,7 +58,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] .bss_prio_lock, flags); - return status; + return 0; } /* diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 7a9e0b5962e..60d25c690c0 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -590,11 +590,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, * an association success (0) or failure (non-zero). */ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { + struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; struct ieee_types_assoc_rsp *assoc_rsp; struct mwifiex_bssdescriptor *bss_desc; u8 enable_data = true; @@ -718,16 +717,11 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, done: /* Need to indicate IOCTL complete */ - if (wait_queue) { - if (ret) { - if (assoc_rsp->status_code) - wait_queue->status = - le16_to_cpu(assoc_rsp->status_code); - else - wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; - } else { - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - } + if (adapter->curr_cmd->wait_q_enabled) { + if (ret) + adapter->cmd_wait_q.status = -1; + else + adapter->cmd_wait_q.status = 0; } return ret; @@ -885,9 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, - 0, NULL, &priv->curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); if (ret) { dev_err(adapter->dev, @@ -1066,9 +1060,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, priv-> curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, NULL, - &curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &curr_pkt_filter); if (ret) { dev_err(priv->adapter->dev, "ADHOC_J_CMD: G Protection config failed\n"); @@ -1192,11 +1186,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, * saves the beacon buffer. */ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { int ret = 0; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; + struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; struct mwifiex_bssdescriptor *bss_desc; u16 command = le16_to_cpu(resp->command); @@ -1264,11 +1257,11 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, done: /* Need to indicate IOCTL complete */ - if (wait_queue) { + if (adapter->curr_cmd->wait_q_enabled) { if (ret) - wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; + adapter->cmd_wait_q.status = -1; else - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + adapter->cmd_wait_q.status = 0; } @@ -1283,7 +1276,7 @@ done: * command to firmware. */ int mwifiex_associate(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) + struct mwifiex_bssdescriptor *bss_desc) { int ret = 0; u8 current_bssid[ETH_ALEN]; @@ -1301,9 +1294,8 @@ int mwifiex_associate(struct mwifiex_private *priv, retrieval */ priv->assoc_rsp_size = 0; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, - HostCmd_ACT_GEN_SET, 0, wait_queue, - bss_desc); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, + HostCmd_ACT_GEN_SET, 0, bss_desc); return ret; } @@ -1315,7 +1307,7 @@ int mwifiex_associate(struct mwifiex_private *priv, */ int mwifiex_adhoc_start(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) + struct mwifiex_802_11_ssid *adhoc_ssid) { int ret = 0; @@ -1326,9 +1318,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", priv->curr_bss_params.band); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, - HostCmd_ACT_GEN_SET, 0, wait_queue, - adhoc_ssid); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, + HostCmd_ACT_GEN_SET, 0, adhoc_ssid); return ret; } @@ -1340,7 +1331,7 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, * if already not connected to the requested SSID. */ int mwifiex_adhoc_join(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) + struct mwifiex_bssdescriptor *bss_desc) { int ret = 0; @@ -1369,9 +1360,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", priv->curr_bss_params.band); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, - HostCmd_ACT_GEN_SET, 0, wait_queue, - bss_desc); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, + HostCmd_ACT_GEN_SET, 0, bss_desc); return ret; } @@ -1380,9 +1370,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, * This function deauthenticates/disconnects from infra network by sending * deauthentication request. */ -static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 *mac) +static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) { u8 mac_address[ETH_ALEN]; int ret = 0; @@ -1400,11 +1388,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, bss_descriptor.mac_address, ETH_ALEN); } - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, - HostCmd_ACT_GEN_SET, 0, wait, &mac_address); - - if (!ret && wait) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, + HostCmd_ACT_GEN_SET, 0, &mac_address); return ret; } @@ -1415,26 +1400,23 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, * In case of infra made, it sends deauthentication request, and * in case of ad-hoc mode, a stop network request is sent to the firmware. */ -int mwifiex_deauthenticate(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u8 *mac) +int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) { int ret = 0; if (priv->media_connected) { if (priv->bss_mode == NL80211_IFTYPE_STATION) { - ret = mwifiex_deauthenticate_infra(priv, wait, mac); + ret = mwifiex_deauthenticate_infra(priv, mac); } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_AD_HOC_STOP, - HostCmd_ACT_GEN_SET, 0, wait, NULL); - - if (!ret && wait) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_AD_HOC_STOP, + HostCmd_ACT_GEN_SET, 0, NULL); } } return ret; } +EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); /* * This function converts band to radio type used in channel TLV. diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index ed89ca41a90..df665db8c43 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -597,16 +597,23 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct sockaddr *hw_addr = (struct sockaddr *) addr; + int ret = 0; memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); - if (mwifiex_request_set_mac_address(priv)) { - dev_err(priv->adapter->dev, "set MAC address failed\n"); - return -EFAULT; - } + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, + HostCmd_ACT_GEN_SET, 0, NULL); + + if (!ret) + memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); + else + dev_err(priv->adapter->dev, "set mac address failed: ret=%d" + "\n", ret); + memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); - return 0; + return ret; } /* @@ -615,7 +622,20 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) static void mwifiex_set_multicast_list(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - mwifiex_request_set_multicast_list(priv, dev); + struct mwifiex_multicast_list mcast_list; + + if (dev->flags & IFF_PROMISC) { + mcast_list.mode = MWIFIEX_PROMISC_MODE; + } else if (dev->flags & IFF_ALLMULTI || + netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { + mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; + } else { + mcast_list.mode = MWIFIEX_MULTICAST_MODE; + if (netdev_mc_count(dev)) + mcast_list.num_multicast_addr = + mwifiex_copy_mcast_addr(&mcast_list, dev); + } + mwifiex_request_set_multicast_list(priv, &mcast_list); } /* @@ -677,9 +697,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) { dev->netdev_ops = &mwifiex_netdev_ops; /* Initialize private structure */ - init_waitqueue_head(&priv->ioctl_wait_q); - init_waitqueue_head(&priv->cmd_wait_q); - init_waitqueue_head(&priv->w_stats_wait_q); priv->current_key_index = 0; priv->media_connected = false; memset(&priv->nick_name, 0, sizeof(priv->nick_name)); @@ -807,32 +824,6 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) return; } -/* - * Sends IOCTL request to shutdown firmware. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - - /* Allocate an IOCTL request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait, - MWIFIEX_FUNC_SHUTDOWN); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw); - /* * This function check if command is pending. */ @@ -927,6 +918,10 @@ mwifiex_add_card(void *card, struct semaphore *sem, adapter->is_suspended = false; adapter->hs_activated = false; init_waitqueue_head(&adapter->hs_activate_wait_q); + adapter->cmd_wait_q_required = false; + init_waitqueue_head(&adapter->cmd_wait_q.wait); + adapter->cmd_wait_q.condition = false; + adapter->cmd_wait_q.status = 0; /* Create workqueue */ adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); @@ -1038,12 +1033,12 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); if (atomic_read(&adapter->rx_pending) || atomic_read(&adapter->tx_pending) || - atomic_read(&adapter->ioctl_pending)) { + atomic_read(&adapter->cmd_pending)) { dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " - "ioctl_pending=%d\n", + "cmd_pending=%d\n", atomic_read(&adapter->rx_pending), atomic_read(&adapter->tx_pending), - atomic_read(&adapter->ioctl_pending)); + atomic_read(&adapter->cmd_pending)); } /* Remove interface */ diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 43ff149de9d..7ead15e1967 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -42,11 +42,8 @@ extern const char driver_version[]; extern struct mwifiex_adapter *g_adapter; enum { - MWIFIEX_NO_WAIT, - MWIFIEX_IOCTL_WAIT, - MWIFIEX_CMD_WAIT, - MWIFIEX_PROC_WAIT, - MWIFIEX_WSTATS_WAIT + MWIFIEX_ASYNC_CMD, + MWIFIEX_SYNC_CMD }; #define DRV_MODE_STA 0x1 @@ -468,10 +465,6 @@ struct mwifiex_private { u32 curr_bcn_size; /* spin lock for beacon buffer */ spinlock_t curr_bcn_buf_lock; - u16 ioctl_wait_q_woken; - wait_queue_head_t ioctl_wait_q; - u16 cmd_wait_q_woken; - wait_queue_head_t cmd_wait_q; struct wireless_dev *wdev; struct mwifiex_chan_freq_power cfp; char version_str[128]; @@ -480,8 +473,6 @@ struct mwifiex_private { #endif u8 nick_name[16]; struct iw_statistics w_stats; - u16 w_stats_wait_q_woken; - wait_queue_head_t w_stats_wait_q; u16 current_key_index; struct semaphore async_sem; u8 scan_pending_on_block; @@ -552,7 +543,7 @@ struct cmd_ctrl_node { struct sk_buff *cmd_skb; struct sk_buff *resp_skb; void *data_buf; - void *wq_buf; + u32 wait_q_enabled; struct sk_buff *skb; }; @@ -590,7 +581,7 @@ struct mwifiex_adapter { struct mwifiex_if_ops if_ops; atomic_t rx_pending; atomic_t tx_pending; - atomic_t ioctl_pending; + atomic_t cmd_pending; struct workqueue_struct *workqueue; struct work_struct main_work; struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; @@ -684,6 +675,8 @@ struct mwifiex_adapter { struct mwifiex_dbg dbg; u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; u32 arp_filter_size; + u16 cmd_wait_q_required; + struct mwifiex_wait_queue cmd_wait_q; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); @@ -707,29 +700,23 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_event(struct mwifiex_adapter *adapter); -int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *ioctl_wq, - int status); +int mwifiex_complete_cmd(struct mwifiex_adapter *adapter); -int mwifiex_prepare_cmd(struct mwifiex_private *priv, - uint16_t cmd_no, - u16 cmd_action, - u32 cmd_oid, - void *wait_queue, void *data_buf); +int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf); + +int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf); void mwifiex_cmd_timeout_func(unsigned long function_context); -int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue, - u32 func_init_shutdown); int mwifiex_get_debug_info(struct mwifiex_private *, struct mwifiex_debug_info *); int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); -void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *ioctl_wq); +void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node); @@ -772,24 +759,21 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, - void *cmd_buf, void *ioctl); + void *cmd_buf); int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_sta_event(struct mwifiex_private *); void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); -int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, - u16 action, - const struct mwifiex_user_scan_cfg - *user_scan_in, struct mwifiex_scan_resp *); +int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in); int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *ssid, u8 *bssid, u32 mode); @@ -799,23 +783,20 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *req_ssid_bssid); s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, struct mwifiex_802_11_ssid *ssid2); -int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); void mwifiex_reset_connect_state(struct mwifiex_private *priv); void mwifiex_2040_coex_event(struct mwifiex_private *priv); u8 mwifiex_band_to_radio_type(u8 band); -int mwifiex_deauthenticate(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait_queue, - u8 *mac); -int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); +int mwifiex_adhoc_start(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *adhoc_ssid); -int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, @@ -824,8 +805,7 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); @@ -943,52 +923,34 @@ mwifiex_netdev_get_priv(struct net_device *dev) return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); } -struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue( - struct mwifiex_private *, - u8 wait_option); struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index); -int mwifiex_shutdown_fw(struct mwifiex_private *, u8); - +int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, + u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, int maxlen); -int mwifiex_request_set_mac_address(struct mwifiex_private *priv); -void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, - struct net_device *dev); -int mwifiex_request_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *req, - int, u8 wait_option); -int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *); +int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct mwifiex_multicast_list *mcast_list); +int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, + struct net_device *dev); +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); int mwifiex_bss_start(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid); int mwifiex_set_hs_params(struct mwifiex_private *priv, - u16 action, u8 wait_option, + u16 action, int cmd_type, struct mwifiex_ds_hs_cfg *hscfg); -int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); +int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); -void mwifiex_process_ioctl_resp(struct mwifiex_private *priv, - struct mwifiex_wait_queue *req); -u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option); int mwifiex_get_signal_info(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ds_get_signal *signal); int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); -int mwifiex_get_channel_list(struct mwifiex_private *priv, - u8 wait_option, - struct mwifiex_chan_list *chanlist); -int mwifiex_get_scan_table(struct mwifiex_private *priv, - u8 wait_option, - struct mwifiex_scan_resp *scanresp); -int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); -int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_find_best_bss(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *ssid_bssid); int mwifiex_request_scan(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_802_11_ssid *req_ssid); int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req); @@ -1024,27 +986,22 @@ int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index); int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); -int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); +int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode); int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, int max_len); -int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); +int mwifiex_set_tx_power(struct mwifiex_private *priv, + struct mwifiex_power_cfg *power_cfg); int mwifiex_main_process(struct mwifiex_adapter *); -int mwifiex_bss_ioctl_channel(struct mwifiex_private *, - u16 action, - struct mwifiex_chan_freq_power *cfp); +int mwifiex_bss_set_channel(struct mwifiex_private *, + struct mwifiex_chan_freq_power *cfp); int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, - struct mwifiex_wait_queue *, struct mwifiex_ssid_bssid *); -int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, - u16 action, - struct mwifiex_ds_band_cfg *); -int mwifiex_snmp_mib_ioctl(struct mwifiex_private *, - struct mwifiex_wait_queue *, - u32 cmd_oid, u16 action, u32 *value); +int mwifiex_set_radio_band_cfg(struct mwifiex_private *, + struct mwifiex_ds_band_cfg *); int mwifiex_get_bss_info(struct mwifiex_private *, struct mwifiex_bss_info *); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6bb52d0e6cf..12fe021536d 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -178,9 +178,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, * with requisite parameters and calls the IOCTL handler. */ int mwifiex_find_best_bss(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) + struct mwifiex_ssid_bssid *ssid_bssid) { - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ssid_bssid tmp_ssid_bssid; int ret = 0; u8 *mac = NULL; @@ -188,14 +187,9 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, if (!ssid_bssid) return -1; - /* Allocate wait request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - memcpy(&tmp_ssid_bssid, ssid_bssid, sizeof(struct mwifiex_ssid_bssid)); - ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); + ret = mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid); if (!ret) { memcpy(ssid_bssid, &tmp_ssid_bssid, @@ -205,7 +199,6 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, " %pM\n", ssid_bssid->ssid.ssid, mac); } - kfree(wait); return ret; } @@ -221,22 +214,14 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req) { - struct mwifiex_wait_queue *wait = NULL; int status = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate an IOCTL request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, - scan_req, NULL); + priv->adapter->cmd_wait_q.condition = false; - status = mwifiex_request_ioctl(priv, wait, status, wait_option); + status = mwifiex_scan_networks(priv, scan_req); + if (!status) + status = mwifiex_wait_queue_complete(priv->adapter); - if (wait && (status != -EINPROGRESS)) - kfree(wait); return status; } @@ -674,7 +659,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, * along with the other TLVs, to the firmware. */ static int -mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, +mwifiex_scan_channel_list(struct mwifiex_private *priv, u32 max_chan_per_scan, u8 filtered_scan, struct mwifiex_scan_cmd_config *scan_cfg_out, struct mwifiex_ie_types_chan_list_param_set @@ -808,9 +793,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, /* Send the scan command to the firmware with the specified cfg */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, - HostCmd_ACT_GEN_SET, - 0, wait_buf, scan_cfg_out); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, + HostCmd_ACT_GEN_SET, 0, + scan_cfg_out); if (ret) break; } @@ -2271,9 +2256,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, * update the internal driver scan table. */ int mwifiex_scan_networks(struct mwifiex_private *priv, - void *wait_buf, u16 action, - const struct mwifiex_user_scan_cfg *user_scan_in, - struct mwifiex_scan_resp *scan_resp) + const struct mwifiex_user_scan_cfg *user_scan_in) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -2288,18 +2271,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, u8 max_chan_per_scan; unsigned long flags; - if (action == HostCmd_ACT_GEN_GET) { - if (scan_resp) { - scan_resp->scan_table = (u8 *) adapter->scan_table; - scan_resp->num_in_scan_table = - adapter->num_in_scan_table; - } else { - ret = -1; - } - return ret; - } - - if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + if (adapter->scan_processing) { dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); return ret; } @@ -2308,7 +2280,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->scan_processing = true; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + if (priv->scan_block) { dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); return ret; @@ -2348,9 +2320,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->bcn_buf_end = adapter->bcn_buf; } - ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, - filtered_scan, &scan_cfg_out->config, - chan_list_out, scan_chan_list); + ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, + &scan_cfg_out->config, chan_list_out, + scan_chan_list); /* Get scan command from scan_pending_q and put to cmd_pending_q */ if (!ret) { @@ -2367,7 +2339,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); } - ret = -EINPROGRESS; } else { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->scan_processing = true; @@ -2437,11 +2408,10 @@ int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, * .-------------------------------------------------------------. */ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; - struct mwifiex_wait_queue *wait_queue = NULL; struct cmd_ctrl_node *cmd_node = NULL; struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; struct mwifiex_bssdescriptor *bss_new_entry = NULL; @@ -2653,13 +2623,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, mwifiex_process_scan_results(priv); /* Need to indicate IOCTL complete */ - wait_queue = (struct mwifiex_wait_queue *) wq_buf; - if (wait_queue) { - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - - /* Indicate ioctl complete */ - mwifiex_ioctl_complete(adapter, - (struct mwifiex_wait_queue *) wait_queue, 0); + if (adapter->curr_cmd->wait_q_enabled) { + adapter->cmd_wait_q.status = 0; + mwifiex_complete_cmd(adapter); } if (priv->report_scan_result) priv->report_scan_result = false; @@ -2853,6 +2819,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; unsigned long flags; + cmd_node->wait_q_enabled = true; spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); list_add_tail(&cmd_node->list, &adapter->scan_pending_q); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -2899,9 +2866,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, * firmware, filtered on a specific SSID. */ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, - void *wait_buf, u16 action, - struct mwifiex_802_11_ssid *req_ssid, - struct mwifiex_scan_resp *scan_resp) + struct mwifiex_802_11_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; @@ -2910,24 +2875,12 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, if (!req_ssid) return -1; - if (action == HostCmd_ACT_GEN_GET) { - if (scan_resp) { - scan_resp->scan_table = - (u8 *) &priv->curr_bss_params.bss_descriptor; - scan_resp->num_in_scan_table = - adapter->num_in_scan_table; - } else { - ret = -1; - } - return ret; - } - - if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + if (adapter->scan_processing) { dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); return ret; } - if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + if (priv->scan_block) { dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); return ret; @@ -2945,7 +2898,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, req_ssid->ssid_len); scan_cfg->keep_previous_scan = true; - ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); + ret = mwifiex_scan_networks(priv, scan_cfg); kfree(scan_cfg); return ret; @@ -2960,12 +2913,10 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, * Scan command can be issued for both normal scan and specific SSID * scan, depending upon whether an SSID is provided or not. */ -int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_request_scan(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *req_ssid) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; if (down_interruptible(&priv->async_sem)) { dev_err(priv->adapter->dev, "%s: acquire semaphore\n", @@ -2974,32 +2925,23 @@ int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, } priv->scan_pending_on_block = true; - /* Allocate wait request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) { - ret = -1; - goto done; - } + priv->adapter->cmd_wait_q.condition = false; if (req_ssid && req_ssid->ssid_len != 0) /* Specific SSID scan */ - status = mwifiex_scan_specific_ssid(priv, wait, - HostCmd_ACT_GEN_SET, - req_ssid, NULL); + ret = mwifiex_scan_specific_ssid(priv, req_ssid); else /* Normal scan */ - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, - NULL, NULL); - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (status == -1) - ret = -1; -done: - if ((wait) && (status != -EINPROGRESS)) - kfree(wait); + ret = mwifiex_scan_networks(priv, NULL); + + if (!ret) + ret = mwifiex_wait_queue_complete(priv->adapter); + if (ret == -1) { priv->scan_pending_on_block = false; up(&priv->async_sem); } + return ret; } diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f21e5cd1983..f207756cbb7 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -208,7 +208,7 @@ static int mwifiex_sdio_resume(struct device *dev) /* Disable Host Sleep */ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_NO_WAIT); + MWIFIEX_ASYNC_CMD); return 0; } @@ -1745,13 +1745,12 @@ mwifiex_sdio_cleanup_module(void) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && adapter->priv[i]->media_connected) - mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, - NULL); + mwifiex_deauthenticate(adapter->priv[i], NULL); if (!adapter->surprise_removed) - mwifiex_shutdown_fw(mwifiex_get_priv - (adapter, MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_CMD_WAIT); + mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_FUNC_SHUTDOWN); exit: up(&add_remove_card_sem); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 19de6524d42..dec496369b9 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1135,65 +1135,66 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (first_sta) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return -1; /* Read MAC address from HW */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; /* Reconfigure tx buf size */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, - HostCmd_ACT_GEN_SET, 0, NULL, - &priv->adapter->tx_buf_size); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, + &priv->adapter->tx_buf_size); if (ret) return -1; /* Enable IEEE PS by default */ priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - EN_AUTO_PS, BITMAP_STA_PS, NULL, - NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_STA_PS, NULL); if (ret) return -1; } /* get tx rate */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; priv->data_rate = 0; /* get tx power */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; /* set ibss coalescing_status */ - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, - HostCmd_ACT_GEN_SET, 0, NULL, &enable); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, + HostCmd_ACT_GEN_SET, 0, &enable); if (ret) return -1; memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); amsdu_aggr_ctrl.enable = true; /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, - HostCmd_ACT_GEN_SET, 0, NULL, - (void *) &amsdu_aggr_ctrl); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, + HostCmd_ACT_GEN_SET, 0, + (void *) &amsdu_aggr_ctrl); if (ret) return -1; /* MAC Control must be the last command in init_fw */ /* set MAC Control */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, NULL, - &priv->curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); if (ret) return -1; @@ -1201,19 +1202,18 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) /* Enable auto deep sleep */ auto_ds.auto_ds = DEEP_SLEEP_ON; auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, - EN_AUTO_PS, BITMAP_AUTO_DS, NULL, - &auto_ds); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_AUTO_DS, + &auto_ds); if (ret) return -1; } /* Send cmd to FW to enable/disable 11D function */ state_11d = ENABLE_11D; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, - HostCmd_ACT_GEN_SET, DOT11D_I, - NULL, &state_11d); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); if (ret) dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 648df690f5d..8743c116bee 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -41,8 +41,7 @@ */ static void mwifiex_process_cmdresp_error(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - struct mwifiex_wait_queue *wq_buf) + struct host_cmd_ds_command *resp) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; struct mwifiex_adapter *adapter = priv->adapter; @@ -51,8 +50,9 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", resp->command, resp->result); - if (wq_buf) - wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; + + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = -1; switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: @@ -328,9 +328,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, if (priv->is_data_rate_auto) priv->data_rate = 0; else - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + HostCmd_ACT_GEN_GET, 0, NULL); if (data_buf) { ds_rate = (struct mwifiex_rate_cfg *) data_buf; @@ -833,19 +833,17 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, * response handlers based on the command ID. */ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, - u16 cmdresp_no, void *cmd_buf, void *wq_buf) + u16 cmdresp_no, void *cmd_buf) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_command *resp = (struct host_cmd_ds_command *) cmd_buf; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; void *data_buf = adapter->curr_cmd->data_buf; /* If the command is not successful, cleanup and return failure */ if (resp->result != HostCmd_RESULT_OK) { - mwifiex_process_cmdresp_error(priv, resp, wait_queue); + mwifiex_process_cmdresp_error(priv, resp); return -1; } /* Command successful, handle response */ @@ -865,12 +863,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); break; case HostCmd_CMD_802_11_SCAN: - ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); - wait_queue = NULL; - adapter->curr_cmd->wq_buf = NULL; + ret = mwifiex_ret_802_11_scan(priv, resp); + adapter->curr_cmd->wait_q_enabled = false; break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: - ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_scan(priv, resp); dev_dbg(adapter->dev, "info: CMD_RESP: BG_SCAN result is ready!\n"); break; @@ -884,14 +881,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, ret = mwifiex_ret_802_11_hs_cfg(priv, resp); break; case HostCmd_CMD_802_11_ASSOCIATE: - ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_associate(priv, resp); break; case HostCmd_CMD_802_11_DEAUTHENTICATE: ret = mwifiex_ret_802_11_deauthenticate(priv, resp); break; case HostCmd_CMD_802_11_AD_HOC_START: case HostCmd_CMD_802_11_AD_HOC_JOIN: - ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_ad_hoc(priv, resp); break; case HostCmd_CMD_802_11_AD_HOC_STOP: ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 936d7c175e7..fc265cab090 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -271,8 +271,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_HS_ACT_REQ: dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, - 0, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + 0, 0, NULL); break; case EVENT_MIC_ERR_UNICAST: @@ -303,9 +304,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); adapter->num_in_scan_table = 0; adapter->bcn_buf_end = adapter->bcn_buf; - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_BG_SCAN_QUERY, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_BG_SCAN_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL); break; case EVENT_PORT_RELEASE: @@ -314,8 +315,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_WMM_STATUS_CHANGE: dev_dbg(adapter->dev, "event: WMM status changed\n"); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, - 0, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, + 0, 0, NULL); break; case EVENT_RSSI_LOW: @@ -353,15 +354,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_IBSS_COALESCED: dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + HostCmd_ACT_GEN_GET, 0, NULL); break; case EVENT_ADDBA: dev_dbg(adapter->dev, "event: ADDBA Request\n"); - mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, - HostCmd_ACT_GEN_SET, 0, NULL, - adapter->event_body); + mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, + HostCmd_ACT_GEN_SET, 0, + adapter->event_body); break; case EVENT_DELBA: dev_dbg(adapter->dev, "event: DELBA Request\n"); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 2fcdbc224e0..5f2ce9459d2 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -33,9 +33,8 @@ * size, and the calling function must ensure enough memory is * available. */ -static int -mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, - struct net_device *dev) +int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, + struct net_device *dev) { int i = 0; struct netdev_hw_addr *ha; @@ -46,217 +45,52 @@ mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, return i; } -/* - * Allocate and fills a wait queue with proper parameters. - * - * This function needs to be called before an IOCTL request can be made. - * It can handle the following wait options: - * MWIFIEX_NO_WAIT - Waiting is disabled - * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue - * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue - * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue - */ -struct mwifiex_wait_queue * -mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv, - u8 wait_option) -{ - struct mwifiex_wait_queue *wait = NULL; - - wait = (struct mwifiex_wait_queue *) - kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC); - if (!wait) { - dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n", - __func__); - return wait; - } - - wait->bss_index = priv->bss_index; - - switch (wait_option) { - case MWIFIEX_NO_WAIT: - wait->enabled = 0; - break; - case MWIFIEX_IOCTL_WAIT: - priv->ioctl_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->ioctl_wait_q; - wait->condition = &priv->ioctl_wait_q_woken; - wait->enabled = 1; - break; - case MWIFIEX_CMD_WAIT: - priv->cmd_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->cmd_wait_q; - wait->condition = &priv->cmd_wait_q_woken; - wait->enabled = 1; - break; - case MWIFIEX_WSTATS_WAIT: - priv->w_stats_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->w_stats_wait_q; - wait->condition = &priv->w_stats_wait_q_woken; - wait->enabled = 1; - break; - } - - return wait; -} - /* * Wait queue completion handler. * - * This function waits on a particular wait queue. - * For NO_WAIT option, it returns immediately. It also cancels the - * pending IOCTL request after waking up, in case of errors. + * This function waits on a cmd wait queue. It also cancels the pending + * request after waking up, in case of errors. */ -static void -mwifiex_wait_ioctl_complete(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 wait_option) +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) { bool cancel_flag = false; + int status = adapter->cmd_wait_q.status; - switch (wait_option) { - case MWIFIEX_NO_WAIT: - break; - case MWIFIEX_IOCTL_WAIT: - wait_event_interruptible(priv->ioctl_wait_q, - priv->ioctl_wait_q_woken); - if (!priv->ioctl_wait_q_woken) - cancel_flag = true; - break; - case MWIFIEX_CMD_WAIT: - wait_event_interruptible(priv->cmd_wait_q, - priv->cmd_wait_q_woken); - if (!priv->cmd_wait_q_woken) - cancel_flag = true; - break; - case MWIFIEX_WSTATS_WAIT: - wait_event_interruptible(priv->w_stats_wait_q, - priv->w_stats_wait_q_woken); - if (!priv->w_stats_wait_q_woken) - cancel_flag = true; - break; - } - if (cancel_flag) { - mwifiex_cancel_pending_ioctl(priv->adapter, wait); - dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n", - wait, wait_option); - } + dev_dbg(adapter->dev, "cmd pending\n"); + atomic_inc(&adapter->cmd_pending); - return; -} + /* Status pending, wake up main process */ + queue_work(adapter->workqueue, &adapter->main_work); -/* - * The function waits for the request to complete and issues the - * completion handler, if required. - */ -int mwifiex_request_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - int status, u8 wait_option) -{ - switch (status) { - case -EINPROGRESS: - dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n", - wait, wait_option); - atomic_inc(&priv->adapter->ioctl_pending); - /* Status pending, wake up main process */ - queue_work(priv->adapter->workqueue, &priv->adapter->main_work); - - /* Wait for completion */ - if (wait_option) { - mwifiex_wait_ioctl_complete(priv, wait, wait_option); - status = wait->status; - } - break; - case 0: - case -1: - case -EBUSY: - default: - break; - } - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_request_ioctl); + /* Wait for completion */ + wait_event_interruptible(adapter->cmd_wait_q.wait, + adapter->cmd_wait_q.condition); + if (!adapter->cmd_wait_q.condition) + cancel_flag = true; -/* - * IOCTL request handler to set/get MAC address. - * - * This function prepares the correct firmware command and - * issues it to get the extended version information. - */ -static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 action, u8 *mac) -{ - int ret = 0; - - if ((action == HostCmd_ACT_GEN_GET) && mac) { - memcpy(mac, priv->curr_addr, ETH_ALEN); - return 0; + if (cancel_flag) { + mwifiex_cancel_pending_ioctl(adapter); + dev_dbg(adapter->dev, "cmd cancel\n"); } + adapter->cmd_wait_q.status = 0; - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS, - action, 0, wait, mac); - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * Sends IOCTL request to set MAC address. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_request_set_mac_address(struct mwifiex_private *priv) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - u8 wait_option = MWIFIEX_CMD_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET, - NULL); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (!status) - memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); - else - dev_err(priv->adapter->dev, "set mac address failed: status=%d" - " error_code=%#x\n", status, wait->status); - - kfree(wait); return status; } /* - * IOCTL request handler to set multicast list. - * * This function prepares the correct firmware command and * issues it to set the multicast list. * * This function can be used to enable promiscuous mode, or enable all * multicast packets, or to enable selective multicast. */ -static int -mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u16 action, - struct mwifiex_multicast_list *mcast_list) +int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct mwifiex_multicast_list *mcast_list) { int ret = 0; u16 old_pkt_filter; old_pkt_filter = priv->curr_pkt_filter; - if (action == HostCmd_ACT_GEN_GET) - return -1; if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); @@ -281,16 +115,15 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, /* Set multicast addresses to firmware */ if (old_pkt_filter == priv->curr_pkt_filter) { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_MULTICAST_ADR, - action, 0, wait, mcast_list); - if (!ret) - ret = -EINPROGRESS; + HostCmd_ACT_GEN_SET, 0, + mcast_list); } else { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_MULTICAST_ADR, - action, 0, NULL, + HostCmd_ACT_GEN_SET, 0, mcast_list); } } @@ -300,101 +133,21 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", old_pkt_filter, priv->curr_pkt_filter); if (old_pkt_filter != priv->curr_pkt_filter) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, - 0, wait, &priv->curr_pkt_filter); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, + 0, &priv->curr_pkt_filter); } return ret; } /* - * Sends IOCTL request to set multicast list. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -void -mwifiex_request_set_multicast_list(struct mwifiex_private *priv, - struct net_device *dev) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_multicast_list mcast_list; - u8 wait_option = MWIFIEX_NO_WAIT; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return; - - if (dev->flags & IFF_PROMISC) { - mcast_list.mode = MWIFIEX_PROMISC_MODE; - } else if (dev->flags & IFF_ALLMULTI || - netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { - mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; - } else { - mcast_list.mode = MWIFIEX_MULTICAST_MODE; - if (netdev_mc_count(dev)) - mcast_list.num_multicast_addr = - mwifiex_copy_mcast_addr(&mcast_list, dev); - } - status = mwifiex_bss_ioctl_multicast_list(priv, wait, - HostCmd_ACT_GEN_SET, - &mcast_list); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (wait && status != -EINPROGRESS) - kfree(wait); - - return; -} - -/* - * IOCTL request handler to disconnect from a BSS/IBSS. - */ -static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u8 *mac) -{ - return mwifiex_deauthenticate(priv, wait, mac); -} - -/* - * Sends IOCTL request to disconnect from a BSS. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_bss_ioctl_stop(priv, wait, mac); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_disconnect); - -/* - * IOCTL request handler to join a BSS/IBSS. - * * In Ad-Hoc mode, the IBSS is created if not found in scan list. * In both Ad-Hoc and infra mode, an deauthentication is performed * first. */ -static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ssid_bssid *ssid_bssid) +int mwifiex_bss_start(struct mwifiex_private *priv, + struct mwifiex_ssid_bssid *ssid_bssid) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -406,7 +159,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (priv->bss_mode == NL80211_IFTYPE_STATION) { /* Infra mode */ - ret = mwifiex_deauthenticate(priv, NULL, NULL); + ret = mwifiex_deauthenticate(priv, NULL); if (ret) return ret; @@ -427,7 +180,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, /* Clear any past association response stored for * application retrieval */ priv->assoc_rsp_size = 0; - ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); + ret = mwifiex_associate(priv, &adapter->scan_table[i]); if (ret) return ret; } else { @@ -441,7 +194,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, /* Exit Adhoc mode first */ dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); - ret = mwifiex_deauthenticate(priv, NULL, NULL); + ret = mwifiex_deauthenticate(priv, NULL); if (ret) return ret; @@ -460,75 +213,39 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (i >= 0) { dev_dbg(adapter->dev, "info: network found in scan" " list. Joining...\n"); - ret = mwifiex_adhoc_join(priv, wait, - &adapter->scan_table[i]); + ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); if (ret) return ret; } else { /* i >= 0 */ dev_dbg(adapter->dev, "info: Network not found in " "the list, creating adhoc with ssid = %s\n", ssid_bssid->ssid.ssid); - ret = mwifiex_adhoc_start(priv, wait, - &ssid_bssid->ssid); + ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid); if (ret) return ret; } } - if (!ret) - ret = -EINPROGRESS; - return ret; } -/* - * Sends IOCTL request to connect with a BSS. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option, - struct mwifiex_ssid_bssid *ssid_bssid) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_ssid_bssid tmp_ssid_bssid; - int status = 0; - - /* Stop the O.S. TX queue if needed */ - if (!netif_queue_stopped(priv->netdev)) - netif_stop_queue(priv->netdev); - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - if (ssid_bssid) - memcpy(&tmp_ssid_bssid, ssid_bssid, - sizeof(struct mwifiex_ssid_bssid)); - status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} - /* * IOCTL request handler to set host sleep configuration. * * This function prepares the correct firmware command and * issues it. */ -static int -mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u16 action, struct mwifiex_ds_hs_cfg *hs_cfg) +int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, + int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) + { struct mwifiex_adapter *adapter = priv->adapter; int status = 0; u32 prev_cond = 0; + if (!hs_cfg) + return -ENOMEM; + switch (action) { case HostCmd_ACT_GEN_SET: if (adapter->pps_uapsd_mode) { @@ -561,12 +278,16 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, status = -1; break; } - status = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_HS_CFG_ENH, - HostCmd_ACT_GEN_SET, - 0, wait, &adapter->hs_cfg); - if (!status) - status = -EINPROGRESS; + if (cmd_type == MWIFIEX_SYNC_CMD) + status = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + HostCmd_ACT_GEN_SET, 0, + &adapter->hs_cfg); + else + status = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + HostCmd_ACT_GEN_SET, 0, + &adapter->hs_cfg); if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) /* Restore previous condition */ adapter->hs_cfg.conditions = @@ -591,43 +312,13 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, return status; } -/* - * Sends IOCTL request to set Host Sleep parameters. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, - u8 wait_option, - struct mwifiex_ds_hs_cfg *hscfg) -{ - int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - - if (!hscfg) - return -ENOMEM; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg); - - ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); - - if (wait && (ret != -EINPROGRESS)) - kfree(wait); - return ret; -} - /* * Sends IOCTL request to cancel the existing Host Sleep configuration. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ -int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) +int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) { int ret = 0; struct mwifiex_ds_hs_cfg hscfg; @@ -636,7 +327,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) hscfg.conditions = HOST_SLEEP_CFG_CANCEL; hscfg.is_invoke_hostcmd = true; ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, - wait_option, &hscfg); + cmd_type, &hscfg); return ret; } @@ -665,8 +356,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - HostCmd_ACT_GEN_SET, - MWIFIEX_IOCTL_WAIT, &hscfg)) { + HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, + &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); return false; } @@ -678,69 +369,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } EXPORT_SYMBOL_GPL(mwifiex_enable_hs); -/* - * IOCTL request handler to get signal information. - * - * This function prepares the correct firmware command and - * issues it to get the signal (RSSI) information. - * - * This only works in the connected mode. - */ -static int mwifiex_get_info_signal(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_get_signal *signal) -{ - int ret = 0; - - if (!wait) { - dev_err(priv->adapter->dev, "WAIT information is not present\n"); - return -1; - } - - /* Signal info can be obtained only if connected */ - if (!priv->media_connected) { - dev_dbg(priv->adapter->dev, - "info: Can not get signal in disconnected state\n"); - return -1; - } - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO, - HostCmd_ACT_GEN_GET, 0, wait, signal); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to get statistics. - * - * This function prepares the correct firmware command and - * issues it to get the statistics (RSSI) information. - */ -static int mwifiex_get_info_stats(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_get_stats *log) -{ - int ret = 0; - - if (!wait) { - dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n"); - return -1; - } - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG, - HostCmd_ACT_GEN_GET, 0, wait, log); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - /* * IOCTL request handler to get BSS information. * @@ -813,90 +441,20 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, } /* - * IOCTL request handler to get extended version information. - * - * This function prepares the correct firmware command and - * issues it to get the extended version information. - */ -static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ver_ext *ver_ext) -{ - int ret = 0; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, wait, ver_ext); - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to set/get SNMP MIB parameters. - * - * This function prepares the correct firmware command and - * issues it. + * The function sets band configurations. * - * Currently the following parameters are supported - - * Set/get RTS Threshold - * Set/get fragmentation threshold - * Set/get retry count - */ -int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u32 cmd_oid, u16 action, u32 *value) -{ - int ret = 0; - - if (!value) - return -1; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, - action, cmd_oid, wait, value); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to set/get band configurations. - * - * For SET operation, it performs extra checks to make sure the Ad-Hoc + * it performs extra checks to make sure the Ad-Hoc * band and channel are compatible. Otherwise it returns an error. * - * For GET operation, this function retrieves the following information - - * - Infra bands - * - Ad-hoc band - * - Ad-hoc channel - * - Secondary channel offset */ -int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, - u16 action, - struct mwifiex_ds_band_cfg *radio_cfg) +int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, + struct mwifiex_ds_band_cfg *radio_cfg) { struct mwifiex_adapter *adapter = priv->adapter; u8 infra_band = 0; u8 adhoc_band = 0; u32 adhoc_channel = 0; - if (action == HostCmd_ACT_GEN_GET) { - /* Infra Bands */ - radio_cfg->config_bands = adapter->config_bands; - /* Adhoc Band */ - radio_cfg->adhoc_start_band = adapter->adhoc_start_band; - /* Adhoc channel */ - radio_cfg->adhoc_channel = priv->adhoc_channel; - /* Secondary channel offset */ - radio_cfg->sec_chan_offset = adapter->chan_offset; - return 0; - } - - /* For action = SET */ infra_band = (u8) radio_cfg->config_bands; adhoc_band = (u8) radio_cfg->adhoc_start_band; adhoc_channel = radio_cfg->adhoc_channel; @@ -950,8 +508,8 @@ int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, * This function performs validity checking on channel/frequency * compatibility and returns failure if not valid. */ -int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, - struct mwifiex_chan_freq_power *chan) +int mwifiex_bss_set_channel(struct mwifiex_private *priv, + struct mwifiex_chan_freq_power *chan) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_chan_freq_power *cfp = NULL; @@ -959,16 +517,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, if (!chan) return -1; - if (action == HostCmd_ACT_GEN_GET) { - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - priv->curr_bss_params.band, - (u16) priv->curr_bss_params.bss_descriptor. - channel); - chan->channel = cfp->channel; - chan->freq = cfp->freq; - - return 0; - } if (!chan->channel && !chan->freq) return -1; if (adapter->adhoc_start_band & BAND_AN) @@ -1024,7 +572,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, * issues it to set or get the ad-hoc channel. */ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u16 action, u16 *channel) { int ret = 0; @@ -1039,10 +586,8 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, - action, 0, wait, channel); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, + action, 0, channel); return ret; } @@ -1054,7 +599,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, * these are provided, just the best BSS (best RSSI) is returned. */ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ssid_bssid *ssid_bssid) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1114,10 +658,7 @@ int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) { int ret = 0; - int status = 0; struct mwifiex_bss_info bss_info; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; struct mwifiex_ssid_bssid ssid_bssid; u16 curr_chan = 0; @@ -1127,19 +668,10 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) if (mwifiex_get_bss_info(priv, &bss_info)) return -1; - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - /* Get current channel */ - status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, - &curr_chan); + ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, + &curr_chan); - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } if (curr_chan == channel) { ret = 0; goto done; @@ -1154,23 +686,13 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) /* Do disonnect */ memset(&ssid_bssid, 0, ETH_ALEN); - status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); + ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } - - status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET, - (u16 *) &channel); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } + ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, + (u16 *) &channel); /* Do specific SSID scanning */ - if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { + if (mwifiex_request_scan(priv, &bss_info.ssid)) { ret = -1; goto done; } @@ -1179,13 +701,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) memcpy(&ssid_bssid.ssid, &bss_info.ssid, sizeof(struct mwifiex_802_11_ssid)); - status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -1; - + ret = mwifiex_bss_start(priv, &ssid_bssid); done: - kfree(wait); return ret; } @@ -1198,7 +715,6 @@ done: * for the band. */ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1242,11 +758,9 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, } } else { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_TX_RATE_QUERY, - HostCmd_ACT_GEN_GET, 0, wait, NULL); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_TX_RATE_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL); } return ret; @@ -1261,7 +775,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, * The function also performs validation checking on the supplied value. */ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { u8 rates[MWIFIEX_SUPPORTED_RATES]; @@ -1316,10 +829,8 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, - HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_SET, 0, bitmap_rates); return ret; } @@ -1331,7 +842,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, * rate index. */ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { int status = 0; @@ -1340,11 +850,9 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, return -1; if (rate_cfg->action == HostCmd_ACT_GEN_GET) - status = mwifiex_rate_ioctl_get_rate_value( - priv, wait, rate_cfg); + status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); else - status = mwifiex_rate_ioctl_set_rate_value( - priv, wait, rate_cfg); + status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); return status; } @@ -1359,19 +867,11 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); rate->action = HostCmd_ACT_GEN_GET; - ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); + ret = mwifiex_rate_ioctl_cfg(priv, rate); - ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); if (!ret) { if (rate && rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv->adapter, @@ -1382,7 +882,6 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, ret = -1; } - kfree(wait); return ret; } @@ -1398,9 +897,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, * - Modulation class HTBW20 * - Modulation class HTBW40 */ -static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_power_cfg *power_cfg) +int mwifiex_set_tx_power(struct mwifiex_private *priv, + struct mwifiex_power_cfg *power_cfg) { int ret = 0; struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; @@ -1473,12 +971,10 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, pg->ht_bandwidth = HT_BW_40; } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, - HostCmd_ACT_GEN_SET, 0, wait, buf); - if (!ret) - ret = -EINPROGRESS; - kfree(buf); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_SET, 0, buf); + kfree(buf); return ret; } @@ -1488,33 +984,23 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, * This function prepares the correct firmware command and * issues it. */ -static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u32 *ps_mode, u16 action) +int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; u16 sub_cmd; - if (action == HostCmd_ACT_GEN_SET) { - if (*ps_mode) - adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; - else - adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; - sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - sub_cmd, BITMAP_STA_PS, wait, NULL); - if ((!ret) && (sub_cmd == DIS_AUTO_PS)) - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, - 0, NULL, NULL); - } else { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - GET_PS, 0, wait, NULL); - } - - if (!ret) - ret = -EINPROGRESS; + if (*ps_mode) + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + else + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + sub_cmd, BITMAP_STA_PS, NULL); + if ((!ret) && (sub_cmd == DIS_AUTO_PS)) + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, + 0, NULL); return ret; } @@ -1600,18 +1086,14 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, * This function prepares the correct firmware command and * issues it. */ -static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - wait, encrypt_key); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); return ret; } @@ -1622,12 +1104,10 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, * This function prepares the correct firmware command and * issues it, after validation checks. */ -static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; struct mwifiex_wep_key *wep_key = NULL; int index; @@ -1641,7 +1121,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, /* Copy the required key as the current key */ wep_key = &priv->wep_key[index]; if (!wep_key->key_length) { - dev_err(adapter->dev, + dev_err(priv->adapter->dev, "key not set, so cannot enable it\n"); return -1; } @@ -1661,8 +1141,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, } if (wep_key->key_length) { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return ret; } @@ -1672,11 +1153,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, wait, - &priv->curr_pkt_filter); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); return ret; } @@ -1691,18 +1170,16 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, * * This function can also be used to disable a currently set key. */ -static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; u8 remove_key = false; struct host_cmd_ds_802_11_key_material *ibss_key; /* Current driver only supports key length of up to 32 bytes */ if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { - dev_err(adapter->dev, "key length too long\n"); + dev_err(priv->adapter->dev, "key length too long\n"); return -1; } @@ -1713,9 +1190,10 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, */ /* Send the key as PTK to firmware */ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - NULL, encrypt_key); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); if (ret) return ret; @@ -1740,18 +1218,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, if (remove_key) /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, - !(KEY_INFO_ENABLED), - wait, encrypt_key); + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), + encrypt_key); else /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - wait, encrypt_key); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); return ret; } @@ -1764,21 +1240,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, */ static int mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ds_encrypt_key *encrypt_key) { int status = 0; - struct mwifiex_adapter *adapter = priv->adapter; if (encrypt_key->is_wapi_key) - status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) - status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key); else - status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key); return status; } @@ -1805,95 +1276,32 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, return 0; } -/* - * Sends IOCTL request to set Tx power. It can be set to either auto - * or a fixed value. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int -mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm) -{ - struct mwifiex_power_cfg power_cfg; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - int ret = 0; - - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - if (type == NL80211_TX_POWER_FIXED) { - power_cfg.is_power_auto = 0; - power_cfg.power_level = dbm; - } else { - power_cfg.is_power_auto = 1; - } - status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg); - - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); - return ret; -} - -/* - * Sends IOCTL request to get scan table. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, - struct mwifiex_scan_resp *scan_resp) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_scan_resp scan; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET, - NULL, &scan); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (!status) { - if (scan_resp) - memcpy(scan_resp, &scan, - sizeof(struct mwifiex_scan_resp)); - } - - if (wait && (status != -EINPROGRESS)) - kfree(wait); - return status; -} - /* * Sends IOCTL request to get signal information. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ -int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_get_signal_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal) { struct mwifiex_ds_get_signal info; - struct mwifiex_wait_queue *wait = NULL; int status = 0; - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - + memset(&info, 0, sizeof(struct mwifiex_ds_get_signal)); info.selector = ALL_RSSI_INFO_MASK; - status = mwifiex_get_info_signal(priv, wait, &info); + /* Signal info can be obtained only if connected */ + if (!priv->media_connected) { + dev_dbg(priv->adapter->dev, + "info: Can not get signal in disconnected state\n"); + return -1; + } + + /* Send request to firmware */ + status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, + HostCmd_ACT_GEN_GET, 0, signal); - status = mwifiex_request_ioctl(priv, wait, status, wait_option); if (!status) { if (signal) memcpy(signal, &info, @@ -1904,8 +1312,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, priv->w_stats.qual.noise = info.bcn_nf_avg; } - if (wait && (status != -EINPROGRESS)) - kfree(wait); return status; } @@ -1918,15 +1324,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable) { - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_encrypt_key encrypt_key; - int status = 0; int ret = 0; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); encrypt_key.key_len = key_len; if (!disable) { @@ -1937,40 +1337,8 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, encrypt_key.key_disable = true; } - status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); - - if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) - ret = -EFAULT; - - kfree(wait); - return ret; -} - -/* - * Sends IOCTL request to set power management parameters. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int -mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on) -{ - int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; - u32 ps_mode; - - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - ps_mode = power_on; - status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode, - HostCmd_ACT_GEN_SET); + ret = mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); return ret; } @@ -1984,26 +1352,17 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv) { struct mwifiex_ver_ext ver_ext; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; int ret = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; /* get fw version */ memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); - status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); - - ret = mwifiex_request_ioctl(priv, wait, status, wait_option); + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, + HostCmd_ACT_GEN_GET, 0, &ver_ext); if (ret) ret = -1; - kfree(wait); return ret; } @@ -2018,21 +1377,13 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *log) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_get_stats get_log; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); - status = mwifiex_get_info_stats(priv, wait, &get_log); + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, + HostCmd_ACT_GEN_GET, 0, &get_log); - /* Send IOCTL request to MWIFIEX */ - ret = mwifiex_request_ioctl(priv, wait, status, wait_option); if (!ret) { if (log) memcpy(log, &get_log, sizeof(struct @@ -2042,7 +1393,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, priv->w_stats.discard.misc = get_log.ack_failure; } - kfree(wait); return ret; } @@ -2060,7 +1410,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, * - CAU */ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ds_reg_rw *reg_rw, u16 action) { @@ -2088,10 +1437,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); return ret; } @@ -2107,23 +1453,13 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, u32 reg_offset, u32 reg_value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_reg_rw reg_rw; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - reg_rw.type = cpu_to_le32(reg_type); reg_rw.offset = cpu_to_le32(reg_offset); reg_rw.value = cpu_to_le32(reg_value); - status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, - HostCmd_ACT_GEN_SET); + ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); return ret; } @@ -2138,50 +1474,18 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, u32 reg_offset, u32 *value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_reg_rw reg_rw; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - reg_rw.type = cpu_to_le32(reg_type); reg_rw.offset = cpu_to_le32(reg_offset); - status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, - HostCmd_ACT_GEN_GET); + ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); if (ret) goto done; *value = le32_to_cpu(reg_rw.value); done: - kfree(wait); - return ret; -} - -/* - * IOCTL request handler to read EEPROM. - * - * This function prepares the correct firmware command and - * issues it. - */ -static int -mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_read_eeprom *rd_eeprom) -{ - int ret = 0; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, - HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom); - - if (!ret) - ret = -EINPROGRESS; - return ret; } @@ -2196,25 +1500,17 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, u8 *value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_read_eeprom rd_eeprom; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - rd_eeprom.offset = cpu_to_le16((u16) offset); rd_eeprom.byte_count = cpu_to_le16((u16) bytes); - status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - if (ret) - goto done; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, + HostCmd_ACT_GEN_GET, 0, &rd_eeprom); - memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); -done: - kfree(wait); + if (!ret) + memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); return ret; } diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index e8db6bd021c..b261d812c4d 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -51,7 +51,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, if (!skb->len) { dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); - tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; + tx_info->status_code = -1; return skb->data; } diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 205022aa52f..9f65587622f 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -55,17 +55,12 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) } /* - * IOCTL request handler to send function init/shutdown command + * This function sends init/shutdown command * to firmware. - * - * This function prepares the correct firmware command and - * issues it. */ -int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, - u32 func_init_shutdown) +int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, + u32 func_init_shutdown) { - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; int ret; u16 cmd; @@ -74,19 +69,16 @@ int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { cmd = HostCmd_CMD_FUNC_SHUTDOWN; } else { - dev_err(adapter->dev, "unsupported parameter\n"); + dev_err(priv->adapter->dev, "unsupported parameter\n"); return -1; } /* Send command to firmware */ - ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, - 0, wait, NULL); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); return ret; } +EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); /* * IOCTL request handler to set/get debug information. @@ -222,31 +214,18 @@ int mwifiex_recv_complete(struct mwifiex_adapter *adapter, * corresponding waiting function. Otherwise, it processes the * IOCTL response and frees the response buffer. */ -int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue, - int status) +int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) { - enum mwifiex_error_code status_code = - (enum mwifiex_error_code) wait_queue->status; - - atomic_dec(&adapter->ioctl_pending); + atomic_dec(&adapter->cmd_pending); + dev_dbg(adapter->dev, "cmd completed: status=%d\n", + adapter->cmd_wait_q.status); - dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," - " status_code=%#x\n", status, status_code); + adapter->cmd_wait_q.condition = true; - if (wait_queue->enabled) { - *wait_queue->condition = true; - wait_queue->status = status; - if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) - dev_err(adapter->dev, "cmd timeout\n"); - else - wake_up_interruptible(wait_queue->wait); - } else { - if (status) - dev_err(adapter->dev, "cmd failed: status_code=%#x\n", - status_code); - kfree(wait_queue); - } + if (adapter->cmd_wait_q.status == -ETIMEDOUT) + dev_err(adapter->dev, "cmd timeout\n"); + else + wake_up_interruptible(&adapter->cmd_wait_q.wait); return 0; } -- cgit v1.2.3-70-g09d2 From 19a898601ad192d8c59c3a8f1a4501919f53b94d Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 13 Apr 2011 17:27:07 -0700 Subject: mwifiex: remove redundant "return" at end of void function The return statement at the last line of a void function is not necessary. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 6 ------ drivers/net/wireless/mwifiex/11n_rxreorder.c | 4 ---- drivers/net/wireless/mwifiex/cfg80211.c | 2 -- drivers/net/wireless/mwifiex/cmdevt.c | 13 +------------ drivers/net/wireless/mwifiex/debugfs.c | 3 --- drivers/net/wireless/mwifiex/init.c | 6 ------ drivers/net/wireless/mwifiex/main.c | 3 --- drivers/net/wireless/mwifiex/sdio.c | 4 ---- drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 -- drivers/net/wireless/mwifiex/wmm.c | 2 -- 10 files changed, 1 insertion(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index edf4c274fa9..c57107a860d 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -543,8 +543,6 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, if (curr_tx_buf_size != tx_buf) mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, HostCmd_ACT_GEN_SET, 0, &tx_buf); - - return; } /* @@ -582,8 +580,6 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, list_del(&tx_ba_tsr_tbl->list); kfree(tx_ba_tsr_tbl); - - return; } /* @@ -662,8 +658,6 @@ void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); } - - return; } /* diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index ef46d0a8a6d..6736fc60484 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -309,8 +309,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - - return; } /* @@ -610,8 +608,6 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, (u16) event->origninator << DELBA_INITIATOR_POS); delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a1ff490da83..74b6cf20da0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1428,6 +1428,4 @@ done: memset(priv->cfg_bssid, 0, ETH_ALEN); priv->disconnect = 0; } - - return; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index bb6fecd7761..776146a104e 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -94,8 +94,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); cmd_node->resp_skb = NULL; } - - return; } /* @@ -536,7 +534,7 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, { unsigned long flags; - if (cmd_node == NULL) + if (!cmd_node) return; if (cmd_node->wait_q_enabled) @@ -548,8 +546,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); list_add_tail(&cmd_node->list, &adapter->cmd_free_q); spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); - - return; } /* @@ -594,8 +590,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); - - return; } /* @@ -871,8 +865,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); - - return; } /* @@ -989,8 +981,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) } adapter->cmd_wait_q.status = -1; mwifiex_complete_cmd(adapter); - - return; } /* @@ -1094,7 +1084,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->is_hs_configured = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY), false); - return; } /* diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 77d7c777ea6..7ddcb062f10 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -735,8 +735,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) MWIFIEX_DFS_ADD_FILE(getlog); MWIFIEX_DFS_ADD_FILE(regrdwr); MWIFIEX_DFS_ADD_FILE(rdeeprom); - - return; } /* @@ -749,7 +747,6 @@ mwifiex_dev_debugfs_remove(struct mwifiex_private *priv) return; debugfs_remove_recursive(priv->dfs_dev_dir); - return; } /* diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 26931d5f950..1b79a5ac921 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -299,8 +299,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; - - return; } /* @@ -339,8 +337,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter) adapter->if_ops.cleanup_if(adapter); dev_kfree_skb_any(adapter->sleep_cfm); - - return; } /* @@ -428,8 +424,6 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) list_del(&priv->rx_reorder_tbl_ptr); } } - - return; } /* diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index df665db8c43..77abfc3d6c3 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -505,7 +505,6 @@ mwifiex_fill_buffer(struct sk_buff *skb) */ do_gettimeofday(&tv); skb->tstamp = timeval_to_ktime(tv); - return; } /* @@ -820,8 +819,6 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) wiphy_unregister(priv->wdev->wiphy); wiphy_free(priv->wdev->wiphy); kfree(priv->wdev); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f207756cbb7..fa46df50975 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -859,8 +859,6 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) adapter->int_status |= sdio_ireg; spin_unlock_irqrestore(&adapter->int_lock, flags); } - - return; } /* @@ -891,8 +889,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) mwifiex_interrupt_status(adapter); queue_work(adapter->workqueue, &adapter->main_work); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 8743c116bee..20ce8cb3918 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -103,8 +103,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 1cfbc6bed69..6ce6f94e222 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1232,6 +1232,4 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) if (mwifiex_dequeue_tx_packet(adapter)) break; } while (true); - - return; } -- cgit v1.2.3-70-g09d2 From 572e8f3ead47ad223fb428a4f1db986317e8e0ec Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 13 Apr 2011 17:27:08 -0700 Subject: mwifiex: remove unused function parameters Some function parameters become useless after previous cleanup changes. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 13 +++----- drivers/net/wireless/mwifiex/11n.h | 50 ++++++++++------------------ drivers/net/wireless/mwifiex/11n_aggr.c | 5 ++- drivers/net/wireless/mwifiex/11n_rxreorder.c | 6 ++-- drivers/net/wireless/mwifiex/11n_rxreorder.h | 6 ++-- drivers/net/wireless/mwifiex/cfp.c | 9 ++--- drivers/net/wireless/mwifiex/main.h | 17 +++------- drivers/net/wireless/mwifiex/scan.c | 7 ++-- drivers/net/wireless/mwifiex/sdio.c | 18 +++++----- drivers/net/wireless/mwifiex/sta_cmd.c | 40 ++++++++++------------ drivers/net/wireless/mwifiex/sta_cmdresp.c | 13 +++----- drivers/net/wireless/mwifiex/sta_ioctl.c | 7 ++-- drivers/net/wireless/mwifiex/wmm.c | 17 +++++----- drivers/net/wireless/mwifiex/wmm.h | 8 ++--- 14 files changed, 80 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index c57107a860d..d64065ff235 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -242,9 +242,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *data_buf) +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) { struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; @@ -298,8 +296,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, * - Setting AMSDU control parameters (for SET only) * - Ensuring correct endian-ness */ -int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, int cmd_action, void *data_buf) { struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = @@ -331,8 +328,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, +int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, void *data_buf) { struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; @@ -357,8 +353,7 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, * - Setting HT Tx capability and HT Tx information fields * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 71a853e61b6..9128d2c9638 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -28,15 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf); -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf); - -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf); int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, @@ -67,24 +61,19 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, struct mwifiex_ds_rx_reorder_tbl *buf); int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, struct mwifiex_ds_tx_ba_stream_tbl *buf); -int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command - *resp, +int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, void *data_buf); int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, int cmd_action, void *data_buf); -int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - int cmd_action, - void *data_buf); +int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, + int cmd_action, void *data_buf); /* * This function checks whether AMPDU is allowed or not for a particular TID. */ static inline u8 -mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) +mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) { return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) ? true : false); @@ -94,8 +83,7 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, * This function checks whether AMSDU is allowed or not for a particular TID. */ static inline u8 -mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) +mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) { return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && ((priv->is_data_rate_auto) @@ -106,21 +94,18 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, /* * This function checks whether a BA stream is available or not. */ -static inline u8 -mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) +static inline u8 mwifiex_is_ba_stream_avail(struct mwifiex_adapter *adapter) { - struct mwifiex_private *pmpriv = NULL; - u8 i = 0; + struct mwifiex_private *priv; + u8 i; u32 ba_stream_num = 0; - for (i = 0; i < priv->adapter->priv_num; i++) { - pmpriv = priv->adapter->priv[i]; - if (pmpriv) - ba_stream_num += - mwifiex_wmm_list_len(priv->adapter, - (struct list_head - *) &pmpriv-> - tx_ba_stream_tbl_ptr); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (priv) + ba_stream_num += mwifiex_wmm_list_len( + (struct list_head *) + &priv->tx_ba_stream_tbl_ptr); } return ((ba_stream_num < @@ -133,8 +118,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) * Upon successfully locating, both the TID and the RA are returned. */ static inline u8 -mwifiex_find_stream_to_delete(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int ptr_tid, +mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, int *ptid, u8 *ra) { int tid; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index c2abced6695..c9fb0627de4 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -44,8 +44,7 @@ * MSDU => |DA|SA|Length|SNAP|...... ..| */ static int -mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, - struct sk_buff *skb_aggr, +mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, struct sk_buff *skb_src, int *pad) { @@ -324,7 +323,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); + mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); mwifiex_write_data_complete(adapter, skb_src, 0); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 6736fc60484..755e5d533c0 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -319,8 +319,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, * - Setting add BA request buffer * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_11n_addba_req *add_ba_req = (struct host_cmd_ds_11n_addba_req *) @@ -391,8 +390,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, * - Setting del BA request buffer * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) &cmd->params.del_ba; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 42f56903574..f3ca8c8c18f 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -49,14 +49,12 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); -int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 07187a405fe..bb73cfe14ae 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -75,8 +75,7 @@ u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; * This function maps an index in supported rates table into * the corresponding data rate. */ -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info) +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info) { u16 mcs_rate[4][8] = { {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} @@ -126,7 +125,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, * This function maps a data rate value into corresponding index in supported * rates table. */ -u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) +u8 mwifiex_data_rate_to_index(u32 rate) { u16 *ptr; @@ -265,9 +264,7 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv) /* * This function converts rate bitmap into rate index. */ -int -mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap, - int size) +int mwifiex_get_rate_index(u16 *rate_bitmap, int size) { int i; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 7ead15e1967..2d296dcc210 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -767,8 +767,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); int mwifiex_scan_networks(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in); -int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); @@ -806,9 +805,7 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, void *data_buf); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - void *data_buf); +int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); struct mwifiex_chan_freq_power * mwifiex_get_cfp_by_band_and_channel_from_cfg80211( struct mwifiex_private *priv, @@ -816,20 +813,16 @@ struct mwifiex_chan_freq_power * struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( struct mwifiex_private *priv, u8 band, u32 freq); -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info); +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, u8 **buffer); -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info); u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates); u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); -u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); +u8 mwifiex_data_rate_to_index(u32 rate); u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); -int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, - u16 *rateBitmap, int size); +int mwifiex_get_rate_index(u16 *rateBitmap, int size); extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; void mwifiex_save_curr_bcn(struct mwifiex_private *priv); void mwifiex_free_curr_bcn(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 12fe021536d..84742715893 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2364,8 +2364,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, * - Setting command ID, and proper size * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; struct mwifiex_scan_cmd_config *scan_cfg; @@ -2658,9 +2657,7 @@ done: * - Setting background scan flush parameter * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - void *data_buf) +int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd) { struct host_cmd_ds_802_11_bg_scan_query *bg_query = &cmd->params.bg_scan_query; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fa46df50975..41c087d3f0f 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -282,7 +282,7 @@ mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) */ static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, - u8 *buffer, u32 pkt_len, u32 port, u32 timeout) + u8 *buffer, u32 pkt_len, u32 port) { struct sdio_mmc_card *card = adapter->card; int ret = -1; @@ -314,9 +314,8 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter, /* * This function reads multiple data from SDIO card memory. */ -static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, - u8 *buffer, u32 len, - u32 port, u32 timeout, u8 claim) +static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, + u32 len, u32 port, u8 claim) { struct sdio_mmc_card *card = adapter->card; int ret = -1; @@ -430,8 +429,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, int ret = 0; do { - ret = mwifiex_write_data_sync(adapter, payload, pkt_len, - port, 0); + ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port); if (ret) { i++; dev_err(adapter->dev, "host_to_card, write iomem" @@ -630,7 +628,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, return -1; } - ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); + ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1); if (ret) { dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, @@ -769,7 +767,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * MWIFIEX_SDIO_BLOCK_SIZE, - adapter->ioport, 0); + adapter->ioport); if (ret) { dev_err(adapter->dev, "FW download, write iomem (%d)" " failed @ %d\n", i, offset); @@ -842,7 +840,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) unsigned long flags; if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, - REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, + REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) { dev_err(adapter->dev, "read mp_regs failed\n"); return; @@ -1050,7 +1048,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, card->mpa_rx.buf_len, (adapter->ioport | 0x1000 | (card->mpa_rx.ports << 4)) + - card->mpa_rx.start_port, 0, 1)) + card->mpa_rx.start_port, 1)) return -1; curr_ptr = card->mpa_rx.buf; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index dec496369b9..33c8ba1f5e3 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -190,8 +190,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int -mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd) +mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) { cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + @@ -272,8 +271,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, * (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct mwifiex_types_power_group *pg_tlv = NULL; @@ -407,8 +405,7 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, * - Setting MAC multicast address * - Ensuring correct endian-ness */ -static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct mwifiex_multicast_list *mcast_list = @@ -463,8 +460,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, * - Setting command ID and proper size * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd) +static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd) { cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); cmd->size = cpu_to_le16(S_DS_GEN); @@ -777,8 +773,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, * - Setting status to enable or disable (for SET only) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct host_cmd_ds_802_11_ibss_status *ibss_coal = @@ -946,7 +941,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, cmd_action); break; case HostCmd_CMD_MAC_MULTICAST_ADR: - ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_TX_RATE_CFG: @@ -954,7 +949,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_TXPWR_CFG: - ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_802_11_PS_MODE_ENH: @@ -966,11 +961,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, (struct mwifiex_hs_config_param *) data_buf); break; case HostCmd_CMD_802_11_SCAN: - ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: - ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, - data_buf); + ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr); break; case HostCmd_CMD_802_11_ASSOCIATE: ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); @@ -984,14 +978,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_802_11_GET_LOG: - ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); + ret = mwifiex_cmd_802_11_get_log(cmd_ptr); break; case HostCmd_CMD_802_11_AD_HOC_JOIN: ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, data_buf); break; case HostCmd_CMD_802_11_AD_HOC_STOP: - ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); + ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr); break; case HostCmd_CMD_RSSI_INFO: ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); @@ -1036,10 +1030,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, cmd_ptr->size = cpu_to_le16(S_DS_GEN); break; case HostCmd_CMD_11N_ADDBA_REQ: - ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf); break; case HostCmd_CMD_11N_DELBA: - ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf); break; case HostCmd_CMD_11N_ADDBA_RSP: ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); @@ -1058,11 +1052,11 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: - ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: @@ -1075,8 +1069,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = 0; break; case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: - ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, - cmd_action, data_buf); + ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, + data_buf); break; case HostCmd_CMD_MAC_REG_ACCESS: case HostCmd_CMD_BBP_REG_ACCESS: diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 20ce8cb3918..7f4f10b752f 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -280,7 +280,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, void *data_buf) { - struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_rate_cfg *ds_rate = NULL; struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; @@ -336,9 +335,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, if (priv->is_data_rate_auto) { ds_rate->is_rate_auto = 1; } else { - ds_rate->rate = - mwifiex_get_rate_index(adapter, - priv-> + ds_rate->rate = mwifiex_get_rate_index(priv-> bitmap_rates, sizeof(priv-> bitmap_rates)); @@ -514,13 +511,11 @@ static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv, static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - struct mwifiex_adapter *adapter = priv->adapter; - priv->tx_rate = resp->params.tx_rate.tx_rate; priv->tx_htinfo = resp->params.tx_rate.ht_info; if (!priv->is_data_rate_auto) priv->data_rate = - mwifiex_index_to_data_rate(adapter, priv->tx_rate, + mwifiex_index_to_data_rate(priv->tx_rate, priv->tx_htinfo); return 0; @@ -946,7 +941,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: - ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); + ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: ret = mwifiex_ret_wmm_get_status(priv, resp); @@ -965,7 +960,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, case HostCmd_CMD_SET_BSS_MODE: break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); + ret = mwifiex_ret_11n_cfg(resp, data_buf); break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 5f2ce9459d2..6489f264ef5 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -812,8 +812,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, } memset(bitmap_rates, 0, sizeof(bitmap_rates)); - rate_index = - mwifiex_data_rate_to_index(adapter, rate_cfg->rate); + rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); /* Only allow b/g rates to be set */ if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && @@ -874,8 +873,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate && rate->is_rate_auto) - rate->rate = mwifiex_index_to_data_rate(priv->adapter, - priv->tx_rate, priv->tx_htinfo); + rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, + priv->tx_htinfo); else if (rate) rate->rate = priv->data_rate; } else { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6ce6f94e222..57b98c59235 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -177,8 +177,7 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) * This function map ACs to TIDs. */ static void -mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, - u8 queue_priority[]) +mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) { int i; @@ -247,7 +246,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, } } - mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); + mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); } /* @@ -416,7 +415,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) priv = adapter->priv[j]; if (priv) { for (i = 0; i < MAX_NUM_TID; i++) - if (!mwifiex_wmm_is_ra_list_empty(adapter, + if (!mwifiex_wmm_is_ra_list_empty( &priv->wmm.tid_tbl_ptr[i].ra_list)) return false; } @@ -1161,7 +1160,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr) return -1; - tid = mwifiex_get_tid(priv->adapter, ptr); + tid = mwifiex_get_tid(ptr); dev_dbg(adapter->dev, "data: tid=%d\n", tid); @@ -1186,14 +1185,14 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) /* ra_list_spinlock has been freed in mwifiex_send_single_packet() */ } else { - if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { - if (mwifiex_is_ba_stream_avail(priv)) { + if (mwifiex_is_ampdu_allowed(priv, tid)) { + if (mwifiex_is_ba_stream_avail(adapter)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); mwifiex_send_addba(priv, tid, ptr->ra); } else if (mwifiex_find_stream_to_delete - (priv, ptr, tid, &tid_del, ra)) { + (priv, tid, &tid_del, ra)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); @@ -1202,7 +1201,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) } /* Minimum number of AMSDU */ #define MIN_NUM_AMSDU 2 - if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && + if (mwifiex_is_amsdu_allowed(priv, tid) && (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= MIN_NUM_AMSDU)) mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 241f1b0b77f..fcea1f68792 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -35,8 +35,7 @@ enum ieee_types_wmm_ecw_bitmasks { * This function retrieves the TID of the given RA list. */ static inline int -mwifiex_get_tid(struct mwifiex_adapter *adapter, - struct mwifiex_ra_list_tbl *ptr) +mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr) { struct sk_buff *skb; @@ -52,7 +51,7 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter, * This function gets the length of a list. */ static inline int -mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) +mwifiex_wmm_list_len(struct list_head *head) { struct list_head *pos; int count = 0; @@ -67,8 +66,7 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) * This function checks if a RA list is empty or not. */ static inline u8 -mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, - struct list_head *ra_list_hhead) +mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) { struct mwifiex_ra_list_tbl *ra_list; int is_list_empty; -- cgit v1.2.3-70-g09d2 From 53d7938e6a2ac6569476fc59b404e70c0537b42b Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 13 Apr 2011 17:27:09 -0700 Subject: mwifiex: rename function mwifiex_is_ba_stream_avail The old function name sounds like checking for existing BA stream. The function actually checks if we have room for creating new BA stream or not. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.h | 5 +++-- drivers/net/wireless/mwifiex/wmm.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 9128d2c9638..02602ff30cb 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -92,9 +92,10 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) } /* - * This function checks whether a BA stream is available or not. + * This function checks whether a space is available for new BA stream or not. */ -static inline u8 mwifiex_is_ba_stream_avail(struct mwifiex_adapter *adapter) +static inline u8 mwifiex_space_avail_for_new_ba_stream( + struct mwifiex_adapter *adapter) { struct mwifiex_private *priv; u8 i; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 57b98c59235..99e8431c1e9 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1186,7 +1186,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) mwifiex_send_single_packet() */ } else { if (mwifiex_is_ampdu_allowed(priv, tid)) { - if (mwifiex_is_ba_stream_avail(adapter)) { + if (mwifiex_space_avail_for_new_ba_stream(adapter)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); -- cgit v1.2.3-70-g09d2 From 9f219bd248d417c2144eedafdf2c683ba8baee84 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 13 Apr 2011 21:00:02 -0500 Subject: rtlwifi: Fix unitialized variable warnings In http://lkml.indiana.edu/hypermail/linux/kernel/1104.1/01955.html, Geerti Uytterhoeven reports the following warnings for the rtlwifi drivers. src/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c: warning: 'cck_index' may be used uninitialized in this function: => 637 src/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c: warning: 'cck_index_old' may be used uninitialized in this function: => 637 src/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c: warning: 'box_extreg' may be used uninitialized in this function: => 303 src/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c: warning: 'box_reg' may be used uninitialized in this function: => 303 src/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c: warning: 'chnlgroup' may be used uninitialized in this function: => 205 src/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c: warning: 'u4_regvalue' may be used uninitialized in this function: => 450 src/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c: warning: 'hq_sele' may be used uninitialized in this function: => 924 Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bb023274414..c228b9ee371 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -634,7 +634,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw u8 thermalvalue, delta, delta_lck, delta_iqk; long ele_a, ele_d, temp_cck, val_x, value32; long val_y, ele_c; - u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; + u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); u8 txpwr_level[2] = {0, 0}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index f107660f545..bc9d24134ac 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -293,7 +293,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 boxnum; - u16 box_reg, box_extreg; + u16 box_reg = 0, box_extreg = 0; u8 u1b_tmp; bool isfw_read = false; bool bwrite_sucess = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 669b1168dbe..e301b12e281 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -202,7 +202,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 i, chnlgroup, pwr_diff_limit[4]; + u8 i, chnlgroup = 0, pwr_diff_limit[4]; u32 writeVal, customer_limit, rf; for (rf = 0; rf < 2; rf++) { @@ -447,7 +447,7 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 u4_regvalue; + u32 u4_regvalue = 0; u8 rfpath; bool rtstatus; struct bb_reg_def *pphyreg; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 9444e76838c..e43be254782 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -921,7 +921,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, u8 out_ep_num, u8 queue_sel) { - u8 hq_sele; + u8 hq_sele = 0; struct rtl_priv *rtlpriv = rtl_priv(hw); switch (out_ep_num) { -- cgit v1.2.3-70-g09d2 From 34a0a2025c8bddc6505b56a58ef2e7333a4e4165 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Thu, 14 Apr 2011 16:41:30 +0530 Subject: ath: Add a missing world regulatory domain 0x6C Some customers use 0x6C world regulatory domain and this patch adds the support. Cc: Luis R. Rodriguez Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 7 ++++--- drivers/net/wireless/ath/regd_common.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f828f294ba8..7e3b29015dd 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { } }; -/* Can be used by 0x67, 0x6A and 0x68 */ -static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { +/* Can be used by 0x67, 0x68, 0x6A and 0x6C */ +static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { .n_reg_rules = 4, .alpha2 = "99", .reg_rules = { @@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) case 0x67: case 0x68: case 0x6A: - return &ath_world_regdom_67_68_6A; + case 0x6C: + return &ath_world_regdom_67_68_6A_6C; default: WARN_ON(1); return ath_default_world_regdomain(); diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h index 5c2cfe69415..24b53839fc3 100644 --- a/drivers/net/wireless/ath/regd_common.h +++ b/drivers/net/wireless/ath/regd_common.h @@ -86,6 +86,7 @@ enum EnumRd { WOR9_WORLD = 0x69, WORA_WORLD = 0x6A, WORB_WORLD = 0x6B, + WORC_WORLD = 0x6C, MKK3_MKKB = 0x80, MKK3_MKKA2 = 0x81, @@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { {WOR9_WORLD, NO_CTL, NO_CTL}, {WORA_WORLD, NO_CTL, NO_CTL}, {WORB_WORLD, NO_CTL, NO_CTL}, + {WORC_WORLD, NO_CTL, NO_CTL}, }; static struct country_code_to_enum_rd allCountries[] = { -- cgit v1.2.3-70-g09d2 From e79b1ca75bb48111e8d93fc576f50e24671f5f9d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 08:30:43 -0700 Subject: iwlagn: use direct call for led functions After driver split, no need to call led functions through callback Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 - drivers/net/wireless/iwlwifi/iwl-2000.c | 5 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 3 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 5 -- drivers/net/wireless/iwlwifi/iwl-agn-led.c | 73 ------------------------------ drivers/net/wireless/iwlwifi/iwl-agn-led.h | 33 -------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-led.c | 26 ++++++++++- drivers/net/wireless/iwlwifi/iwl-led.h | 1 + 11 files changed, 27 insertions(+), 125 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.h (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 3652931753e..bb6a737de61 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,6 +1,6 @@ # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o -iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o +iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index d1d7852f0ee..809117d7419 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -45,7 +45,6 @@ #include "iwl-agn.h" #include "iwl-helpers.h" #include "iwl-agn-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -226,7 +225,6 @@ static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index a31314fdb05..0a330d16ce7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -46,7 +46,6 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -310,7 +309,6 @@ static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -318,7 +316,6 @@ static const struct iwl_ops iwl2030_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -326,7 +323,6 @@ static const struct iwl_ops iwl200_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -334,7 +330,6 @@ static const struct iwl_ops iwl230_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 7c286662d26..79dd45c3aef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -45,7 +45,6 @@ #include "iwl-sta.h" #include "iwl-helpers.h" #include "iwl-agn.h" -#include "iwl-agn-led.h" #include "iwl-agn-hw.h" #include "iwl-5000-hw.h" #include "iwl-agn-debugfs.h" @@ -447,7 +446,6 @@ static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -455,7 +453,6 @@ static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 064981345c8..a35338e20b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -46,7 +46,6 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -397,7 +396,6 @@ static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -405,7 +403,6 @@ static const struct iwl_ops iwl6050_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .nic = &iwl6050_nic_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -414,7 +411,6 @@ static const struct iwl_ops iwl6150_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .nic = &iwl6150_nic_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -423,7 +419,6 @@ static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c deleted file mode 100644 index 4bb877e600c..00000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-commands.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-io.h" -#include "iwl-agn-led.h" - -/* Send led command */ -static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_LEDS_CMD, - .len = sizeof(struct iwl_led_cmd), - .data = led_cmd, - .flags = CMD_ASYNC, - .callback = NULL, - }; - u32 reg; - - reg = iwl_read32(priv, CSR_LED_REG); - if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) - iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); - - return iwl_send_cmd(priv, &cmd); -} - -/* Set led register off */ -void iwlagn_led_enable(struct iwl_priv *priv) -{ - iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); -} - -const struct iwl_led_ops iwlagn_led_ops = { - .cmd = iwl_send_led_cmd, -}; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h deleted file mode 100644 index c0b7611b72c..00000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_agn_led_h__ -#define __iwl_agn_led_h__ - -extern const struct iwl_led_ops iwlagn_led_ops; -void iwlagn_led_enable(struct iwl_priv *priv); - -#endif /* __iwl_agn_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 47a4cda9eb7..b4f7510f51e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -59,7 +59,6 @@ #include "iwl-sta.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" -#include "iwl-agn-led.h" /****************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6988335328e..240abdf4347 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -217,7 +217,6 @@ struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; - const struct iwl_led_ops *led; const struct iwl_nic_ops *nic; const struct iwl_legacy_ops *legacy; const struct ieee80211_ops *ieee80211_ops; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 0d90004e8b1..d798c2a152d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -61,6 +61,12 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { { .throughput = 300 * 1024 - 1, .blink_time = 50 }, }; +/* Set led register off */ +void iwlagn_led_enable(struct iwl_priv *priv) +{ + iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); +} + /* * Adjust led blink rate to compensate on a MAC Clock difference on every HW * Led blink rate analysis showed an average deviation of 20% on 5000 series @@ -84,6 +90,24 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv, return (u8)((time * compensation) >> 6); } +static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_LEDS_CMD, + .len = sizeof(struct iwl_led_cmd), + .data = led_cmd, + .flags = CMD_ASYNC, + .callback = NULL, + }; + u32 reg; + + reg = iwl_read32(priv, CSR_LED_REG); + if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) + iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + + return iwl_send_cmd(priv, &cmd); +} + /* Set led pattern command */ static int iwl_led_cmd(struct iwl_priv *priv, unsigned long on, @@ -108,7 +132,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, led_cmd.off = iwl_blink_compensation(priv, off, priv->cfg->base_params->led_compensation); - ret = priv->cfg->ops->led->cmd(priv, &led_cmd); + ret = iwl_send_led_cmd(priv, &led_cmd); if (!ret) { priv->blink_on = on; priv->blink_off = off; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 05b8e8f7dd4..1c93dfef693 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -50,6 +50,7 @@ enum iwl_led_mode { IWL_LED_BLINK, }; +void iwlagn_led_enable(struct iwl_priv *priv); void iwl_leds_init(struct iwl_priv *priv); void iwl_leds_exit(struct iwl_priv *priv); -- cgit v1.2.3-70-g09d2 From 3e41ace5deef7af16dd277d9d17f9d36dca0a10e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Apr 2011 09:12:37 -0700 Subject: iwlagn: remove most BUG_ON instances There are a number of things in the driver that may result in a BUG(), which is suboptimal since it's hard to get debugging information out of the driver in that case and the user experience is also not good :-) Almost all BUG_ON instances can be converted to WARN_ON with a few lines of appropriate error handling, so do that instead. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++++-- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 12 ++++++++---- drivers/net/wireless/iwlwifi/iwl-power.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-sta.c | 9 ++++++--- drivers/net/wireless/iwlwifi/iwl-tx.c | 25 +++++++++++++++++-------- 7 files changed, 42 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b4f7510f51e..0daededb0ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -394,7 +394,9 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, return -EINVAL; } - BUG_ON(addr & ~DMA_BIT_MASK(36)); + if (WARN_ON(addr & ~DMA_BIT_MASK(36))) + return -EINVAL; + if (unlikely(addr & ~IWL_TX_DMA_MASK)) IWL_ERR(priv, "Unaligned address = %llx\n", (unsigned long long)addr); @@ -718,7 +720,10 @@ static void iwl_rx_handle(struct iwl_priv *priv) /* If an RXB doesn't have a Rx queue slot associated with it, * then a bug has been introduced in the queue refilling * routines -- catch it here */ - BUG_ON(rxb == NULL); + if (WARN_ON(rxb == NULL)) { + i = (i + 1) & RX_QUEUE_MASK; + continue; + } rxq->queue[i] = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 859b94a1229..402733638f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -215,12 +215,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) return nvm_type; } -const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) -{ - BUG_ON(offset >= priv->cfg->base_params->eeprom_size); - return &priv->eeprom[offset]; -} - static int iwl_init_otp_access(struct iwl_priv *priv) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 0e9d9703636..9ce052573c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -309,7 +309,6 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); -const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); int iwl_init_channel_map(struct iwl_priv *priv); void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 9177b553fe5..8f0beb992cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -143,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { int ret; - BUG_ON(!(cmd->flags & CMD_ASYNC)); + if (WARN_ON(!(cmd->flags & CMD_ASYNC))) + return -EINVAL; /* An asynchronous command can not expect an SKB to be set. */ - BUG_ON(cmd->flags & CMD_WANT_SKB); + if (WARN_ON(cmd->flags & CMD_WANT_SKB)) + return -EINVAL; /* Assign a generic callback if one is not provided */ if (!cmd->callback) @@ -169,10 +171,12 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int cmd_idx; int ret; - lockdep_assert_held(&priv->mutex); + if (WARN_ON(cmd->flags & CMD_ASYNC)) + return -EINVAL; /* A synchronous command can not have a callback set. */ - BUG_ON((cmd->flags & CMD_ASYNC) || cmd->callback); + if (WARN_ON(cmd->callback)) + return -EINVAL; IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index ae176d8da9e..b7cd95820ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -188,9 +188,10 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, table = range_0; } - BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); - - *cmd = table[lvl].cmd; + if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM)) + memset(cmd, 0, sizeof(*cmd)); + else + *cmd = table[lvl].cmd; if (period == 0) { skip = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c2151564007..3c8cebde16c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -494,7 +494,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, priv->num_stations--; - BUG_ON(priv->num_stations < 0); + if (WARN_ON(priv->num_stations < 0)) + priv->num_stations = 0; spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -679,7 +680,8 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; priv->num_stations--; - BUG_ON(priv->num_stations < 0); + if (WARN_ON(priv->num_stations < 0)) + priv->num_stations = 0; kfree(priv->stations[i].lq); priv->stations[i].lq = NULL; } @@ -775,7 +777,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, spin_unlock_irqrestore(&priv->sta_lock, flags_spin); iwl_dump_lq_cmd(priv, lq); - BUG_ON(init && (cmd.flags & CMD_ASYNC)); + if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) + return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) ret = iwl_send_cmd(priv, &cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 3732380c4ff..e7faba57b6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -263,11 +263,13 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, /* count must be power-of-two size, otherwise iwl_queue_inc_wrap * and iwl_queue_dec_wrap are broken. */ - BUG_ON(!is_power_of_2(count)); + if (WARN_ON(!is_power_of_2(count))) + return -EINVAL; /* slots_num must be power-of-two size, otherwise * get_cmd_index is broken. */ - BUG_ON(!is_power_of_2(slots_num)); + if (WARN_ON(!is_power_of_2(slots_num))) + return -EINVAL; q->low_mark = q->n_window / 4; if (q->low_mark < 4) @@ -384,7 +386,9 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); /* Initialize queue's high/low-water marks, and head/tail indexes */ - iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + if (ret) + return ret; /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); @@ -446,14 +450,19 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); - /* If any of the command structures end up being larger than + /* + * If any of the command structures end up being larger than * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then * we will need to increase the size of the TFD entries * Also, check to see if command buffer should not exceed the size - * of device_cmd and max_cmd_size. */ - BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && - !(cmd->flags & CMD_SIZE_HUGE)); - BUG_ON(fix_size > IWL_MAX_CMD_SIZE); + * of device_cmd and max_cmd_size. + */ + if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && + !(cmd->flags & CMD_SIZE_HUGE))) + return -EINVAL; + + if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE)) + return -EINVAL; if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { IWL_WARN(priv, "Not sending command - %s KILL\n", -- cgit v1.2.3-70-g09d2 From 7b21f00ee6073909c01adeba317af3d78c3b9d0a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Apr 2011 09:22:10 -0700 Subject: iwlagn: verify that huge commands are synchronous Since huge commands all share a single buffer, there can only be a single one in flight at a time since otherwise they'd overwrite each other. This is true in the driver now, but it seems like a possible source of bugs, so add a test to verify that huge commands are always sent synchronously. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-tx.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e7faba57b6e..1b69507db5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -470,6 +470,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + /* + * As we only have a single huge buffer, check that the command + * is synchronous (otherwise buffers could end up being reused). + */ + + if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE))) + return -EINVAL; + spin_lock_irqsave(&priv->hcmd_lock, flags); if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { -- cgit v1.2.3-70-g09d2 From b4ebd28f23e3ae00af886aff1c00f800dee3b080 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Apr 2011 12:28:56 -0700 Subject: iwlagn: use huge command for beacon When testing some new P2P code, Angie found that the driver might crash because the beacon command ended up being bigger than a regular command. This is quite obvious -- a normal command is limited to roughly 360 bytes but a beacon may be much larger of course. To fix this, use the huge command buffer. Reported-by: Angie Chinchilla Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0daededb0ff..3cfd7ebb344 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -253,6 +253,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_frame *frame; unsigned int frame_size; int rc; + struct iwl_host_cmd cmd = { + .id = REPLY_TX_BEACON, + .flags = CMD_SIZE_HUGE, + }; frame = iwl_get_free_frame(priv); if (!frame) { @@ -268,8 +272,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) return -EINVAL; } - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, - &frame->u.cmd[0]); + cmd.len = frame_size; + cmd.data = &frame->u.cmd[0]; + + rc = iwl_send_cmd_sync(priv, &cmd); iwl_free_frame(priv, frame); -- cgit v1.2.3-70-g09d2 From b7af6a99690503a48c63ce5e587b4e4555f31cdb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Apr 2011 15:55:25 -0700 Subject: iwlagn: always support uCode trace All _agn devices support continuous uCode trace, remove checking Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +-- 6 files changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 809117d7419..e7844565ef5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -242,7 +242,6 @@ static struct iwl_base_params iwl1000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, - .ucode_tracing = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0a330d16ce7..dcd660818d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -348,7 +348,6 @@ static struct iwl_base_params iwl2000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; @@ -368,7 +367,6 @@ static struct iwl_base_params iwl2030_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79dd45c3aef..14b75f1de18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -467,7 +467,6 @@ static struct iwl_base_params iwl5000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a35338e20b1..81881aad875 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -437,7 +437,6 @@ static struct iwl_base_params iwl6000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; @@ -456,7 +455,6 @@ static struct iwl_base_params iwl6050_base_params = { .chain_noise_scale = 1500, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, - .ucode_tracing = true, .shadow_reg_enable = true, }; static struct iwl_base_params iwl6000_g2_base_params = { @@ -474,7 +472,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 240abdf4347..2e8c936e556 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -249,7 +249,6 @@ struct iwl_mod_params { * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging - * @ucode_tracing: support ucode continuous tracing * @shadow_reg_enable: HW shadhow register bit */ struct iwl_base_params { @@ -271,7 +270,6 @@ struct iwl_base_params { unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; - const bool ucode_tracing; const bool shadow_reg_enable; }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 897efacb96e..c272204fccf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1749,8 +1749,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); - if (priv->cfg->base_params->ucode_tracing) - DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); -- cgit v1.2.3-70-g09d2 From f42e7662815647c1a6f73e160abcdf812d3057d2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:30:09 -0700 Subject: iwlagn: temperature should be measure for all _agn devices Thermal throttling functions are available for all _agn devices, call the functions directly. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-5000.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-6000.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-core.h | 9 --------- drivers/net/wireless/iwlwifi/iwl-power.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-tx.c | 5 +---- 7 files changed, 3 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e7844565ef5..946c7dca440 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -214,11 +214,6 @@ static struct iwl_lib_ops iwl1000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index dcd660818d2..c8bb4a4930d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -298,11 +298,6 @@ static struct iwl_lib_ops iwl2000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl2000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 14b75f1de18..ced89f662bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -383,11 +383,6 @@ static struct iwl_lib_ops iwl5000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_lib_ops iwl5150_lib = { @@ -435,11 +430,6 @@ static struct iwl_lib_ops iwl5150_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 81881aad875..ed6a0ed0f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -323,11 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_lib_ops iwl6030_lib = { @@ -377,11 +372,6 @@ static struct iwl_lib_ops iwl6030_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_nic_ops iwl6050_nic_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2e8c936e556..abee5074d30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -139,12 +139,6 @@ struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); }; -struct iwl_tt_ops { - bool (*lower_power_detection)(struct iwl_priv *priv); - u8 (*tt_power_mode)(struct iwl_priv *priv); - bool (*ct_kill_check)(struct iwl_priv *priv); -}; - struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -190,9 +184,6 @@ struct iwl_lib_ops { void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); struct iwl_debugfs_ops debugfs_ops; - - /* thermal throttling */ - struct iwl_tt_ops tt_ops; }; struct iwl_led_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index b7cd95820ff..595c930b28a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -357,12 +357,10 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); - else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && - priv->cfg->ops->lib->tt_ops.tt_power_mode && - priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { + else if (iwl_tt_is_low_power_state(priv)) { /* in thermal throttling low power state */ iwl_static_sleep_cmd(priv, cmd, - priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); + iwl_tt_current_power_mode(priv), dtimper); } else if (!enabled) iwl_power_sleep_cam_cmd(priv, cmd); else if (priv->power_data.debug_sleep_level_override >= 0) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1b69507db5f..80c3565a66a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -484,10 +484,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) spin_unlock_irqrestore(&priv->hcmd_lock, flags); IWL_ERR(priv, "No space in command queue\n"); - if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { - is_ct_kill = - priv->cfg->ops->lib->tt_ops.ct_kill_check(priv); - } + is_ct_kill = iwl_check_for_ct_kill(priv); if (!is_ct_kill) { IWL_ERR(priv, "Restarting adapter due to queue full\n"); iwlagn_fw_error(priv, false); -- cgit v1.2.3-70-g09d2 From 5cab35e7f4feda1a0bfd4f48b7686391004be9de Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Apr 2011 15:55:27 -0700 Subject: iwlagn: no 5.2GHz/HT40 support for bgn devices For bgn devices, there were no HT40 channels value in EEPROM Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 946c7dca440..a01871801e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -195,7 +195,7 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REG_BAND_4_CHANNELS, EEPROM_REG_BAND_5_CHANNELS, EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS + EEPROM_REGULATORY_BAND_NO_HT40, }, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index c8bb4a4930d..0bd9b146bb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -278,7 +278,7 @@ static struct iwl_lib_ops iwl2000_lib = { EEPROM_REG_BAND_4_CHANNELS, EEPROM_REG_BAND_5_CHANNELS, EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS + EEPROM_REGULATORY_BAND_NO_HT40, }, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, -- cgit v1.2.3-70-g09d2 From 119ea186cad7643ea82b7290374ebb8e780c35b6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:34:06 -0700 Subject: iwlagn: remove un-necessary ieee80211_ops After driver split, no need to use ieee80211_ops, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn.c | 22 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 24 ------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- 7 files changed, 22 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index a01871801e5..baf80111efa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -220,7 +220,6 @@ static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl1000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0bd9b146bb9..e76e02c2892 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -304,28 +304,24 @@ static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl2030_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl200_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl230_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl2000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ced89f662bd..655afc19f68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -436,14 +436,12 @@ static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl5000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ed6a0ed0f50..905eb57f7ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -386,7 +386,6 @@ static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6050_ops = { @@ -394,7 +393,6 @@ static const struct iwl_ops iwl6050_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6050_nic_ops, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6150_ops = { @@ -402,14 +400,12 @@ static const struct iwl_ops iwl6150_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6150_nic_ops, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl6000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3cfd7ebb344..cdeb09eee73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3728,6 +3728,28 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; +/* This function both allocates and initializes hw and priv. */ +static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) +{ + struct iwl_priv *priv; + /* mac80211 allocates memory for this device instance, including + * space for this driver's private structure */ + struct ieee80211_hw *hw; + + hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); + if (hw == NULL) { + pr_err("%s: Can not allocate network device\n", + cfg->name); + goto out; + } + + priv = hw->priv; + priv->hw = hw; + +out: + return hw; +} + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0, i; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0e98a8703e5..885167f8168 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -67,30 +67,6 @@ u32 iwl_debug_level; const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - -/* This function both allocates and initializes hw and priv. */ -struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) -{ - struct iwl_priv *priv; - /* mac80211 allocates memory for this device instance, including - * space for this driver's private structure */ - struct ieee80211_hw *hw; - - hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), - cfg->ops->ieee80211_ops); - if (hw == NULL) { - pr_err("%s: Can not allocate network device\n", - cfg->name); - goto out; - } - - priv = hw->priv; - priv->hw = hw; - -out: - return hw; -} - #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index abee5074d30..0049790eab7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -210,7 +210,6 @@ struct iwl_ops { const struct iwl_hcmd_utils_ops *utils; const struct iwl_nic_ops *nic; const struct iwl_legacy_ops *legacy; - const struct ieee80211_ops *ieee80211_ops; }; struct iwl_mod_params { @@ -364,7 +363,6 @@ struct iwl_cfg { * L i b * ***************************/ -struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); -- cgit v1.2.3-70-g09d2 From e339807d97bcb4e214c9137bb5bbb2f685054624 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Apr 2011 10:21:52 -0700 Subject: iwlagn: remove legacy ops No longer used by _agn devices, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 0049790eab7..99a91bddd9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -195,21 +195,11 @@ struct iwl_nic_ops { void (*additional_nic_config)(struct iwl_priv *priv); }; -struct iwl_legacy_ops { - void (*post_associate)(struct iwl_priv *priv); - void (*config_ap)(struct iwl_priv *priv); - /* station management */ - int (*update_bcast_stations)(struct iwl_priv *priv); - int (*manage_ibss_station)(struct iwl_priv *priv, - struct ieee80211_vif *vif, bool add); -}; - struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; const struct iwl_nic_ops *nic; - const struct iwl_legacy_ops *legacy; }; struct iwl_mod_params { -- cgit v1.2.3-70-g09d2 From f212b43c4e4a8f6378c50ce18f3d271983b575a7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:36:30 -0700 Subject: iwlagn: remove led_ops No longer use, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 99a91bddd9e..32a990ff09a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -186,10 +186,6 @@ struct iwl_lib_ops { struct iwl_debugfs_ops debugfs_ops; }; -struct iwl_led_ops { - int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); -}; - /* NIC specific ops */ struct iwl_nic_ops { void (*additional_nic_config)(struct iwl_priv *priv); -- cgit v1.2.3-70-g09d2 From 2290a9c35df271cc33601b69e7836fa288e2fc7d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 14 Apr 2011 14:55:36 -0700 Subject: ath: fix 0x6C for beaconing/passive scan flags based on country IE The 0x6C regulatory domain is just like the 0x6A regulatory domain but differs in that 0x6C will allow adhoc and active scan on its channels only if we are associated to an AP with a country IE that allows those channels. The ath_reg_apply_beaconing_flags() does just this -- we respect the manufacturer's intent on only enabling beaconing modes of operation if and only if blessed by the country IE. Cc: David Quan Cc: Senthil Balasubramanian Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 7e3b29015dd..02b896208b1 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -334,6 +334,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, case 0x63: case 0x66: case 0x67: + case 0x6C: ath_reg_apply_beaconing_flags(wiphy, initiator); break; case 0x68: -- cgit v1.2.3-70-g09d2 From 00bca7e2f2b58b93ce408e92d18a8c42bbe8d6e5 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 15 Apr 2011 12:28:52 +0530 Subject: ath9k_htc: Add debugfs support to change debug mask Signed-off-by: Rajkumar Manoharan Acked-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 49 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index cc5d0a4b9da..852cdcfbcbb 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -366,6 +366,7 @@ struct ath9k_debug { struct dentry *debugfs_recv; struct dentry *debugfs_slot; struct dentry *debugfs_queue; + struct dentry *debugfs_debug; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; }; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 8d0de60e0c2..7394a1b9882 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -435,6 +435,47 @@ static const struct file_operations fops_queue = { .llseek = default_llseek, }; +static ssize_t read_file_debug(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath_common *common = ath9k_hw_common(priv->ah); + char buf[32]; + unsigned int len; + + len = sprintf(buf, "0x%08x\n", common->debug_mask); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_debug(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath_common *common = ath9k_hw_common(priv->ah); + unsigned long mask; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (strict_strtoul(buf, 0, &mask)) + return -EINVAL; + + common->debug_mask = mask; + return count; +} + +static const struct file_operations fops_debug = { + .read = read_file_debug, + .write = write_file_debug, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath9k_htc_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -493,6 +534,13 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_queue) goto err; + priv->debug.debugfs_debug = debugfs_create_file("debug", + S_IRUSR | S_IWUSR, + priv->debug.debugfs_phy, + priv, &fops_debug); + if (!priv->debug.debugfs_debug) + goto err; + return 0; err: @@ -512,6 +560,7 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) debugfs_remove(priv->debug.debugfs_tgt_int_stats); debugfs_remove(priv->debug.debugfs_tgt_tx_stats); debugfs_remove(priv->debug.debugfs_tgt_rx_stats); + debugfs_remove(priv->debug.debugfs_debug); debugfs_remove(priv->debug.debugfs_phy); } -- cgit v1.2.3-70-g09d2 From e5facc75fa9104f074c4610437a9c717c9e5ecde Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 15 Apr 2011 15:42:24 +0530 Subject: ath9k_htc: Cleanup HTC debugfs Move the ath9k_htc debugfs under ieee80211 to be inline with ath9k driver and it also helps to simplify debug code. Signed-off-by: Rajkumar Manoharan Acked-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 14 --- drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 113 +++++-------------------- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 37 ++------ 3 files changed, 27 insertions(+), 137 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 852cdcfbcbb..48a88557508 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -359,14 +359,6 @@ struct ath_rx_stats { struct ath9k_debug { struct dentry *debugfs_phy; - struct dentry *debugfs_tgt_int_stats; - struct dentry *debugfs_tgt_tx_stats; - struct dentry *debugfs_tgt_rx_stats; - struct dentry *debugfs_xmit; - struct dentry *debugfs_recv; - struct dentry *debugfs_slot; - struct dentry *debugfs_queue; - struct dentry *debugfs_debug; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; }; @@ -613,15 +605,9 @@ void ath9k_htc_suspend(struct htc_target *htc_handle); int ath9k_htc_resume(struct htc_target *htc_handle); #endif #ifdef CONFIG_ATH9K_HTC_DEBUGFS -int ath9k_htc_debug_create_root(void); -void ath9k_htc_debug_remove_root(void); int ath9k_htc_init_debug(struct ath_hw *ah); -void ath9k_htc_exit_debug(struct ath_hw *ah); #else -static inline int ath9k_htc_debug_create_root(void) { return 0; }; -static inline void ath9k_htc_debug_remove_root(void) {}; static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; -static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {}; #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #endif /* HTC_H */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 7394a1b9882..eca777497fe 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -16,8 +16,6 @@ #include "htc.h" -static struct dentry *ath9k_debugfs_root; - static int ath9k_debugfs_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -481,100 +479,27 @@ int ath9k_htc_init_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - if (!ath9k_debugfs_root) - return -ENOENT; - - priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), - ath9k_debugfs_root); + priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, + priv->hw->wiphy->debugfsdir); if (!priv->debug.debugfs_phy) - goto err; - - priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats", - S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_int_stats); - if (!priv->debug.debugfs_tgt_int_stats) - goto err; - - priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats", - S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_tx_stats); - if (!priv->debug.debugfs_tgt_tx_stats) - goto err; - - priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats", - S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_rx_stats); - if (!priv->debug.debugfs_tgt_rx_stats) - goto err; - - priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_xmit); - if (!priv->debug.debugfs_xmit) - goto err; - - priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_recv); - if (!priv->debug.debugfs_recv) - goto err; - - priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_slot); - if (!priv->debug.debugfs_slot) - goto err; - - priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_queue); - if (!priv->debug.debugfs_queue) - goto err; - - priv->debug.debugfs_debug = debugfs_create_file("debug", - S_IRUSR | S_IWUSR, - priv->debug.debugfs_phy, - priv, &fops_debug); - if (!priv->debug.debugfs_debug) - goto err; - - return 0; - -err: - ath9k_htc_exit_debug(ah); - return -ENOMEM; -} - -void ath9k_htc_exit_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - debugfs_remove(priv->debug.debugfs_queue); - debugfs_remove(priv->debug.debugfs_slot); - debugfs_remove(priv->debug.debugfs_recv); - debugfs_remove(priv->debug.debugfs_xmit); - debugfs_remove(priv->debug.debugfs_tgt_int_stats); - debugfs_remove(priv->debug.debugfs_tgt_tx_stats); - debugfs_remove(priv->debug.debugfs_tgt_rx_stats); - debugfs_remove(priv->debug.debugfs_debug); - debugfs_remove(priv->debug.debugfs_phy); -} + return -ENOMEM; -int ath9k_htc_debug_create_root(void) -{ - ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!ath9k_debugfs_root) - return -ENOENT; + debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_tgt_int_stats); + debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_tgt_tx_stats); + debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_tgt_rx_stats); + debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_xmit); + debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_recv); + debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_slot); + debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, + priv, &fops_queue); + debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, + priv, &fops_debug); return 0; } - -void ath9k_htc_debug_remove_root(void) -{ - debugfs_remove(ath9k_debugfs_root); - ath9k_debugfs_root = NULL; -} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 22736eb901c..06e043bffaf 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -140,7 +140,6 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) { - ath9k_htc_exit_debug(priv->ah); ath9k_hw_deinit(priv->ah); kfree(priv->ah); priv->ah = NULL; @@ -700,12 +699,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, goto err_hw; } - ret = ath9k_htc_init_debug(ah); - if (ret) { - ath_err(common, "Unable to create debugfs files\n"); - goto err_debug; - } - ret = ath9k_init_queues(priv); if (ret) goto err_queues; @@ -725,8 +718,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, return 0; err_queues: - ath9k_htc_exit_debug(ah); -err_debug: ath9k_hw_deinit(ah); err_hw: @@ -867,6 +858,12 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, goto err_world; } + error = ath9k_htc_init_debug(priv->ah); + if (error) { + ath_err(common, "Unable to create debugfs files\n"); + goto err_world; + } + ath_dbg(common, ATH_DBG_CONFIG, "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " "BE:%d, BK:%d, VI:%d, VO:%d\n", @@ -987,38 +984,20 @@ int ath9k_htc_resume(struct htc_target *htc_handle) static int __init ath9k_htc_init(void) { - int error; - - error = ath9k_htc_debug_create_root(); - if (error < 0) { - printk(KERN_ERR - "ath9k_htc: Unable to create debugfs root: %d\n", - error); - goto err_dbg; - } - - error = ath9k_hif_usb_init(); - if (error < 0) { + if (ath9k_hif_usb_init() < 0) { printk(KERN_ERR "ath9k_htc: No USB devices found," " driver not installed.\n"); - error = -ENODEV; - goto err_usb; + return -ENODEV; } return 0; - -err_usb: - ath9k_htc_debug_remove_root(); -err_dbg: - return error; } module_init(ath9k_htc_init); static void __exit ath9k_htc_exit(void) { ath9k_hif_usb_exit(); - ath9k_htc_debug_remove_root(); printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); } module_exit(ath9k_htc_exit); -- cgit v1.2.3-70-g09d2 From 0477ad72a12d4ee3f588de9349012948ea25702b Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 15 Apr 2011 19:23:11 +0400 Subject: iwlegacy: use pci_dev->revision Commit be663ab67077fac8e23eb8e231a8c1c94cb32e54 (iwlwifi: split the drivers for agn and legacy devices 3945/4965) added code to read the 4965's revision ID from the PCI configuration register while it's already stored by PCI subsystem in the 'revision' field of 'struct pci_dev'... Signed-off-by: Sergei Shtylyov Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl4965-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 91b3d8b9d7a..dd90619fdce 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -3179,7 +3179,7 @@ static void iwl4965_hw_detect(struct iwl_priv *priv) { priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV); priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG); - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); + priv->rev_id = priv->pci_dev->revision; IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); } -- cgit v1.2.3-70-g09d2 From 636c4598499eeacce0893dc8d91113b904bd531e Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Fri, 15 Apr 2011 20:50:40 -0700 Subject: mwifiex: remove redundant local variables and comments Remove some local variables (mainly function return values) that are used only once. Also, one dummy function and some wordy comments are removed. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 24 +---- drivers/net/wireless/mwifiex/cfg80211.c | 131 +++++++++------------------ drivers/net/wireless/mwifiex/cfp.c | 8 +- drivers/net/wireless/mwifiex/init.c | 5 +- drivers/net/wireless/mwifiex/join.c | 50 +++------- drivers/net/wireless/mwifiex/main.c | 19 ++-- drivers/net/wireless/mwifiex/scan.c | 23 ++--- drivers/net/wireless/mwifiex/sdio.c | 16 +--- drivers/net/wireless/mwifiex/sta_ioctl.c | 85 ++++------------- drivers/net/wireless/mwifiex/sta_tx.c | 6 +- drivers/net/wireless/mwifiex/txrx.c | 4 +- drivers/net/wireless/mwifiex/util.c | 6 +- drivers/net/wireless/mwifiex/wmm.c | 5 +- 13 files changed, 105 insertions(+), 277 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 755e5d533c0..a93c03fdea8 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -26,19 +26,6 @@ #include "11n.h" #include "11n_rxreorder.h" -/* - * This function processes a received packet and forwards - * it to the kernel/upper layer. - */ -static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload) -{ - int ret = 0; - struct mwifiex_adapter *adapter = priv->adapter; - - ret = mwifiex_process_rx_packet(adapter, (struct sk_buff *) payload); - return ret; -} - /* * This function dispatches all packets in the Rx reorder table. * @@ -51,7 +38,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, int start_win) { - int no_pkt_to_send, i, xchg; + int no_pkt_to_send, i; void *rx_tmp_ptr = NULL; unsigned long flags; @@ -68,7 +55,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, } spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); if (rx_tmp_ptr) - mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); + mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } spin_lock_irqsave(&priv->rx_pkt_lock, flags); @@ -76,8 +63,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, * We don't have a circular buffer, hence use rotation to simulate * circular buffer */ - xchg = rx_reor_tbl_ptr->win_size - no_pkt_to_send; - for (i = 0; i < xchg; ++i) { + for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { rx_reor_tbl_ptr->rx_reorder_ptr[i] = rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; @@ -114,7 +100,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); - mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); + mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } spin_lock_irqsave(&priv->rx_pkt_lock, flags); @@ -429,7 +415,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, tid, ta); if (!rx_reor_tbl_ptr) { if (pkt_type != PKT_TYPE_BAR) - mwifiex_11n_dispatch_pkt(priv, payload); + mwifiex_process_rx_packet(priv->adapter, payload); return 0; } start_win = rx_reor_tbl_ptr->start_win; diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 74b6cf20da0..b99ae2677d7 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -34,22 +34,17 @@ static int mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type channel_type) { - int channel; switch (channel_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: - channel = NO_SEC_CHANNEL; - break; + return NO_SEC_CHANNEL; case NL80211_CHAN_HT40PLUS: - channel = SEC_CHANNEL_ABOVE; - break; + return SEC_CHANNEL_ABOVE; case NL80211_CHAN_HT40MINUS: - channel = SEC_CHANNEL_BELOW; - break; + return SEC_CHANNEL_BELOW; default: - channel = NO_SEC_CHANNEL; + return NO_SEC_CHANNEL; } - return channel; } /* @@ -64,21 +59,16 @@ mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type static enum nl80211_channel_type mwifiex_channels_to_cfg80211_channel_type(int channel_type) { - int channel; switch (channel_type) { case NO_SEC_CHANNEL: - channel = NL80211_CHAN_HT20; - break; + return NL80211_CHAN_HT20; case SEC_CHANNEL_ABOVE: - channel = NL80211_CHAN_HT40PLUS; - break; + return NL80211_CHAN_HT40PLUS; case SEC_CHANNEL_BELOW: - channel = NL80211_CHAN_HT40MINUS; - break; + return NL80211_CHAN_HT40MINUS; default: - channel = NL80211_CHAN_HT20; + return NL80211_CHAN_HT20; } - return channel; } /* @@ -117,10 +107,8 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - int ret = 0; - ret = mwifiex_set_encode(priv, NULL, 0, key_index, 1); - if (ret) { + if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { wiphy_err(wiphy, "deleting the crypto keys\n"); return -EFAULT; } @@ -137,7 +125,6 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm) { - int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_power_cfg power_cfg; @@ -148,9 +135,7 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, power_cfg.is_power_auto = 1; } - ret = mwifiex_set_tx_power(priv, &power_cfg); - - return ret; + return mwifiex_set_tx_power(priv, &power_cfg); } /* @@ -163,7 +148,6 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { - int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); u32 ps_mode; @@ -173,9 +157,8 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, " for IEEE power save\n"); ps_mode = enabled; - ret = mwifiex_drv_set_power(priv, &ps_mode); - return ret; + return mwifiex_drv_set_power(priv, &ps_mode); } /* @@ -187,18 +170,15 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, bool multicast) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - int ret; /* Return if WEP key not configured */ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) return 0; - ret = mwifiex_set_encode(priv, NULL, 0, key_index, 0); - - wiphy_dbg(wiphy, "info: set default Tx key index\n"); - - if (ret) + if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { + wiphy_err(wiphy, "set default Tx key index\n"); return -EFAULT; + } return 0; } @@ -212,15 +192,12 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct key_params *params) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - int ret = 0; - ret = mwifiex_set_encode(priv, params->key, params->key_len, - key_index, 0); - - wiphy_dbg(wiphy, "info: crypto keys added\n"); - - if (ret) + if (mwifiex_set_encode(priv, params->key, params->key_len, + key_index, 0)) { + wiphy_err(wiphy, "crypto keys added\n"); return -EFAULT; + } return 0; } @@ -245,7 +222,6 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; - int ret = 0; /* Set country code */ domain_info->country_code[0] = priv->country_code[0]; @@ -300,13 +276,14 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) } domain_info->no_of_triplet = no_of_triplet; - /* Send cmd to FW to set domain info */ - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL); - if (ret) + + if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, + HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "11D: setting domain info in FW\n"); + return -1; + } - return ret; + return 0; } /* @@ -356,7 +333,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, enum nl80211_channel_type channel_type) { struct mwifiex_chan_freq_power cfp; - int ret = 0; struct mwifiex_ds_band_cfg band_cfg; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; @@ -375,14 +351,14 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, band_cfg.config_bands = config_bands; band_cfg.adhoc_start_band = config_bands; } - /* Set channel offset */ + band_cfg.sec_chan_offset = mwifiex_cfg80211_channel_type_to_mwifiex_channels (channel_type); - ret = mwifiex_set_radio_band_cfg(priv, &band_cfg); - if (ret) + if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) return -EFAULT; + mwifiex_send_domain_info_cmd_fw(wiphy); } @@ -390,20 +366,16 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, "mode %d\n", config_bands, band_cfg.sec_chan_offset, priv->bss_mode); if (!chan) - return ret; + return 0; memset(&cfp, 0, sizeof(cfp)); cfp.freq = chan->center_freq; - /* Convert frequency to channel */ cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); - ret = mwifiex_bss_set_channel(priv, &cfp); - if (ret) + if (mwifiex_bss_set_channel(priv, &cfp)) return -EFAULT; - ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); - - return ret; + return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); } /* @@ -459,17 +431,12 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) static int mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) { - int ret = 0; - if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) rts_thr = MWIFIEX_RTS_MAX_VALUE; - /* Send request to firmware */ - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, HostCmd_ACT_GEN_SET, RTS_THRESH_I, &rts_thr); - - return ret; } /* @@ -485,8 +452,11 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) int ret = 0; - if (changed & WIPHY_PARAM_RTS_THRESHOLD) + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { ret = mwifiex_set_rts(priv, wiphy->rts_threshold); + if (ret) + return ret; + } if (changed & WIPHY_PARAM_FRAG_THRESHOLD) ret = mwifiex_set_frag(priv, wiphy->frag_threshold); @@ -598,7 +568,6 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - int ret = 0; mwifiex_dump_station_info(priv, sinfo); @@ -607,10 +576,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) return -ENOENT; - - ret = mwifiex_dump_station_info(priv, sinfo); - - return ret; + return mwifiex_dump_station_info(priv, sinfo); } /* Supported rates to be advertised to the cfg80211 */ @@ -749,15 +715,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, */ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) { - int ret = 0; struct ieee80211_channel *chan; struct mwifiex_bss_info bss_info; int ie_len = 0; u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; - ret = mwifiex_get_bss_info(priv, &bss_info); - if (ret) - return ret; + if (mwifiex_get_bss_info(priv, &bss_info)) + return -1; ie_buf[0] = WLAN_EID_SSID; ie_buf[1] = bss_info.ssid.ssid_len; @@ -776,7 +740,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) 0, ie_buf, ie_len, 0, GFP_KERNEL); memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); - return ret; + return 0; } /* @@ -805,9 +769,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *scan_table; int i, j; struct ieee80211_channel *chan; - u8 *ie, *tmp, *ie_buf; + u8 *ie, *ie_buf; u32 ie_len; - u64 ts = 0; u8 *beacon; int beacon_size; u8 element_id, element_len; @@ -889,9 +852,9 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, case WLAN_EID_BSS_AC_ACCESS_DELAY: ie[0] = element_id; ie[1] = element_len; - tmp = (u8 *) beacon; memcpy(&ie[sizeof(struct ieee_types_header)], - tmp + sizeof(struct ieee_types_header), + (u8 *) beacon + + sizeof(struct ieee_types_header), element_len); ie_len += ie[1] + sizeof(struct ieee_types_header); @@ -908,7 +871,7 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, scan_table[i].freq); cfg80211_inform_bss(priv->wdev->wiphy, chan, scan_table[i].mac_address, - ts, scan_table[i].cap_info_bitmap, + 0, scan_table[i].cap_info_bitmap, scan_table[i].beacon_period, ie_buf, ie_len, scan_table[i].rssi, GFP_KERNEL); @@ -941,9 +904,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, struct mwifiex_802_11_ssid req_ssid; struct mwifiex_ssid_bssid ssid_bssid; int ret = 0; - int auth_type = 0, pairwise_encrypt_mode = 0; - int group_encrypt_mode = 0; - int alg_is_wep = 0; + int auth_type = 0; memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); @@ -1009,9 +970,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); if (sme->key) { - alg_is_wep = mwifiex_is_alg_wep(pairwise_encrypt_mode) - | mwifiex_is_alg_wep(group_encrypt_mode); - if (alg_is_wep) { + if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) { dev_dbg(priv->adapter->dev, "info: setting wep encryption" " with key len %d\n", sme->key_len); diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index bb73cfe14ae..d0cada5a29a 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -145,16 +145,12 @@ u8 mwifiex_data_rate_to_index(u32 rate) */ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) { - u32 k; - if (!priv->media_connected) - k = mwifiex_get_supported_rates(priv, rates); + return mwifiex_get_supported_rates(priv, rates); else - k = mwifiex_copy_rates(rates, 0, + return mwifiex_copy_rates(rates, 0, priv->curr_bss_params.data_rates, priv->curr_bss_params.num_of_rates); - - return k; } /* diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 1b79a5ac921..fc2c0c5728d 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -71,7 +71,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) static int mwifiex_init_priv(struct mwifiex_private *priv) { u32 i; - int ret = 0; priv->media_connected = false; memset(priv->curr_addr, 0xff, ETH_ALEN); @@ -139,9 +138,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) priv->scan_block = false; - ret = mwifiex_add_bss_prio_tbl(priv); - - return ret; + return mwifiex_add_bss_prio_tbl(priv); } /* diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 60d25c690c0..8e1cb4b3fbe 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -749,7 +749,7 @@ int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf) { - int ret = 0, rsn_ie_len = 0; + int rsn_ie_len = 0; struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start = &cmd->params.adhoc_start; @@ -879,11 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, HostCmd_ACT_GEN_SET, 0, - &priv->curr_pkt_filter); - - if (ret) { + &priv->curr_pkt_filter)) { dev_err(adapter->dev, "ADHOC_S_CMD: G Protection config failed\n"); return -1; @@ -1039,7 +1037,7 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf) { - int ret = 0, rsn_ie_len = 0; + int rsn_ie_len = 0; struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = &cmd->params.adhoc_join; struct mwifiex_bssdescriptor *bss_desc = @@ -1060,10 +1058,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, priv-> curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, HostCmd_ACT_GEN_SET, 0, - &curr_pkt_filter); - if (ret) { + &curr_pkt_filter)) { dev_err(priv->adapter->dev, "ADHOC_J_CMD: G Protection config failed\n"); return -1; @@ -1174,7 +1171,7 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); - return ret; + return 0; } /* @@ -1192,15 +1189,13 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; struct mwifiex_bssdescriptor *bss_desc; - u16 command = le16_to_cpu(resp->command); - u16 result = le16_to_cpu(resp->result); adhoc_result = &resp->params.adhoc_result; bss_desc = priv->attempted_bss_desc; /* Join result code 0 --> SUCCESS */ - if (result) { + if (le16_to_cpu(resp->result)) { dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n"); if (priv->media_connected) mwifiex_reset_connect_state(priv); @@ -1215,7 +1210,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, /* Send a Media Connected event, according to the Spec */ priv->media_connected = true; - if (command == HostCmd_CMD_802_11_AD_HOC_START) { + if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", bss_desc->ssid.ssid); @@ -1278,7 +1273,6 @@ done: int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc) { - int ret = 0; u8 current_bssid[ETH_ALEN]; /* Return error if the adapter or table entry is not marked as infra */ @@ -1294,10 +1288,8 @@ int mwifiex_associate(struct mwifiex_private *priv, retrieval */ priv->assoc_rsp_size = 0; - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, HostCmd_ACT_GEN_SET, 0, bss_desc); - - return ret; } /* @@ -1309,8 +1301,6 @@ int mwifiex_adhoc_start(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *adhoc_ssid) { - int ret = 0; - dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", @@ -1318,10 +1308,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", priv->curr_bss_params.band); - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, HostCmd_ACT_GEN_SET, 0, adhoc_ssid); - - return ret; } /* @@ -1333,8 +1321,6 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc) { - int ret = 0; - dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", priv->curr_bss_params.bss_descriptor.ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", @@ -1360,10 +1346,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", priv->curr_bss_params.band); - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, HostCmd_ACT_GEN_SET, 0, bss_desc); - - return ret; } /* @@ -1424,21 +1408,15 @@ EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); u8 mwifiex_band_to_radio_type(u8 band) { - u8 ret_radio_type; - switch (band) { case BAND_A: case BAND_AN: case BAND_A | BAND_AN: - ret_radio_type = HostCmd_SCAN_RADIO_TYPE_A; - break; + return HostCmd_SCAN_RADIO_TYPE_A; case BAND_B: case BAND_G: case BAND_B | BAND_G: default: - ret_radio_type = HostCmd_SCAN_RADIO_TYPE_BG; - break; + return HostCmd_SCAN_RADIO_TYPE_BG; } - - return ret_radio_type; } diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 77abfc3d6c3..2c376dd4ad5 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -68,7 +68,6 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, struct mwifiex_device *mdevice, void **padapter) { - int ret = 0; struct mwifiex_adapter *adapter = NULL; u8 i = 0; @@ -84,8 +83,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops)); /* card specific initialization has been deferred until now .. */ - ret = adapter->if_ops.init_if(adapter); - if (ret) + if (adapter->if_ops.init_if(adapter)) goto error; adapter->priv_num = 0; @@ -893,7 +891,6 @@ int mwifiex_add_card(void *card, struct semaphore *sem, struct mwifiex_if_ops *if_ops) { - int status = 0; int i; struct mwifiex_adapter *adapter = NULL; struct mwifiex_drv_mode *drv_mode_info = &mwifiex_drv_mode_tbl[0]; @@ -943,12 +940,9 @@ mwifiex_add_card(void *card, struct semaphore *sem, for (i = 0; i < drv_mode_info->intf_num; i++) { if (!mwifiex_add_interface(adapter, i, adapter->drv_mode->bss_attr[i].bss_type)) { - status = -1; - break; + goto err_add_intf; } } - if (status) - goto err_add_intf; up(sem); @@ -969,8 +963,8 @@ err_kmalloc: (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) { pr_debug("info: %s: shutdown mwifiex\n", __func__); adapter->init_wait_q_woken = false; - status = mwifiex_shutdown_drv(adapter); - if (status == -EINPROGRESS) + + if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) wait_event_interruptible(adapter->init_wait_q, adapter->init_wait_q_woken); } @@ -999,7 +993,6 @@ EXPORT_SYMBOL_GPL(mwifiex_add_card); int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) { struct mwifiex_private *priv = NULL; - int status; int i; if (down_interruptible(sem)) @@ -1023,8 +1016,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n"); adapter->init_wait_q_woken = false; - status = mwifiex_shutdown_drv(adapter); - if (status == -EINPROGRESS) + + if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) wait_event_interruptible(adapter->init_wait_q, adapter->init_wait_q_woken); dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 84742715893..68d905d5860 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -181,7 +181,6 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *ssid_bssid) { struct mwifiex_ssid_bssid tmp_ssid_bssid; - int ret = 0; u8 *mac = NULL; if (!ssid_bssid) @@ -189,17 +188,17 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, memcpy(&tmp_ssid_bssid, ssid_bssid, sizeof(struct mwifiex_ssid_bssid)); - ret = mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid); - if (!ret) { + if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) { memcpy(ssid_bssid, &tmp_ssid_bssid, sizeof(struct mwifiex_ssid_bssid)); mac = (u8 *) &ssid_bssid->bssid; dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s," " %pM\n", ssid_bssid->ssid.ssid, mac); + return 0; } - return ret; + return -1; } /* @@ -2061,19 +2060,13 @@ mwifiex_process_scan_results(struct mwifiex_private *priv) static u8 mwifiex_radio_type_to_band(u8 radio_type) { - u8 ret_band; - switch (radio_type) { case HostCmd_SCAN_RADIO_TYPE_A: - ret_band = BAND_A; - break; + return BAND_A; case HostCmd_SCAN_RADIO_TYPE_BG: default: - ret_band = BAND_G; - break; + return BAND_G; } - - return ret_band; } /* @@ -2226,8 +2219,7 @@ static int mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *del_ssid) { - int ret = -1; - s32 table_idx; + s32 table_idx = -1; dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n", del_ssid->ssid); @@ -2240,11 +2232,10 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: Scan: Delete SSID Entry: Found Idx = %d\n", table_idx); - ret = 0; mwifiex_scan_delete_table_entry(priv, table_idx); } - return ret; + return table_idx == -1 ? -1 : 0; } /* diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 41c087d3f0f..5148d0e0fad 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -347,12 +347,9 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, */ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { - int ret; - dev_dbg(adapter->dev, "event: wakeup device...\n"); - ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP); - return ret; + return mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP); } /* @@ -362,12 +359,9 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) */ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) { - int ret; - dev_dbg(adapter->dev, "cmd: wakeup device completed\n"); - ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); - return ret; + return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); } /* @@ -1703,13 +1697,9 @@ static struct mwifiex_if_ops sdio_ops = { static int mwifiex_sdio_init_module(void) { - int ret; - sema_init(&add_remove_card_sem, 1); - ret = sdio_register_driver(&mwifiex_sdio); - - return ret; + return sdio_register_driver(&mwifiex_sdio); } /* diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 6489f264ef5..03085a3b20d 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -216,7 +216,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); if (ret) return ret; - } else { /* i >= 0 */ + } else { dev_dbg(adapter->dev, "info: Network not found in " "the list, creating adhoc with ssid = %s\n", ssid_bssid->ssid.ssid); @@ -320,16 +320,13 @@ int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, */ int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) { - int ret = 0; struct mwifiex_ds_hs_cfg hscfg; - /* Cancel Host Sleep */ hscfg.conditions = HOST_SLEEP_CFG_CANCEL; hscfg.is_invoke_hostcmd = true; - ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, - cmd_type, &hscfg); - return ret; + return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, + cmd_type, &hscfg); } EXPORT_SYMBOL_GPL(mwifiex_cancel_hs); @@ -348,7 +345,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) return true; } - /* Enable Host Sleep */ adapter->hs_activate_wait_q_woken = false; memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); @@ -385,23 +381,17 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, if (!info) return -1; - /* Get current BSS info */ bss_desc = &priv->curr_bss_params.bss_descriptor; - /* BSS mode */ info->bss_mode = priv->bss_mode; - /* SSID */ memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct mwifiex_802_11_ssid)); - /* BSSID */ memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); - /* Channel */ info->bss_chan = bss_desc->channel; - /* Region code */ info->region_code = adapter->region_code; /* Scan table index if connected */ @@ -415,20 +405,15 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->scan_table_idx = tbl_idx; } - /* Connection status */ info->media_connected = priv->media_connected; - /* Tx power information */ info->max_power_level = priv->max_tx_power_level; info->min_power_level = priv->min_tx_power_level; - /* AdHoc state */ info->adhoc_state = priv->adhoc_state; - /* Last beacon NF */ info->bcn_nf_last = priv->bcn_nf_last; - /* wep status */ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) info->wep_status = true; else @@ -574,22 +559,17 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, u16 action, u16 *channel) { - int ret = 0; - if (action == HostCmd_ACT_GEN_GET) { if (!priv->media_connected) { *channel = priv->adhoc_channel; - return ret; + return 0; } } else { priv->adhoc_channel = (u8) *channel; } - /* Send request to firmware */ - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, action, 0, channel); - - return ret; } /* @@ -602,7 +582,6 @@ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *ssid_bssid) { struct mwifiex_adapter *adapter = priv->adapter; - int ret = 0; struct mwifiex_bssdescriptor *bss_desc; u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; u8 mac[ETH_ALEN]; @@ -631,10 +610,10 @@ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, bss_desc = &adapter->scan_table[i]; memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN); } else { - ret = mwifiex_find_best_network(priv, ssid_bssid); + return mwifiex_find_best_network(priv, ssid_bssid); } - return ret; + return 0; } /* @@ -718,7 +697,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate_cfg) { struct mwifiex_adapter *adapter = priv->adapter; - int ret = 0; rate_cfg->is_rate_auto = priv->is_data_rate_auto; if (!priv->media_connected) { @@ -757,13 +735,12 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, break; } } else { - /* Send request to firmware */ - ret = mwifiex_send_cmd_sync(priv, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); } - return ret; + return 0; } /* @@ -827,7 +804,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, } } - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_GEN_SET, 0, bitmap_rates); @@ -969,7 +945,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, pg->power_max = (s8) dbm; pg->ht_bandwidth = HT_BW_40; } - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, HostCmd_ACT_GEN_SET, 0, buf); @@ -1088,13 +1063,10 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { - int ret = 0; - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, encrypt_key); - - return ret; } /* @@ -1128,7 +1100,6 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; } else { wep_key = &priv->wep_key[index]; - /* Cleanup */ memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); /* Copy the key in the driver */ memcpy(wep_key->key_material, @@ -1151,7 +1122,6 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, else priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, HostCmd_ACT_GEN_SET, 0, &priv->curr_pkt_filter); @@ -1216,13 +1186,11 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; if (remove_key) - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), encrypt_key); else - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, @@ -1297,7 +1265,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, return -1; } - /* Send request to firmware */ status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, HostCmd_ACT_GEN_GET, 0, signal); @@ -1324,7 +1291,6 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable) { struct mwifiex_ds_encrypt_key encrypt_key; - int ret = 0; memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); encrypt_key.key_len = key_len; @@ -1336,9 +1302,7 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, encrypt_key.key_disable = true; } - ret = mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); - - return ret; + return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); } /* @@ -1351,18 +1315,13 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv) { struct mwifiex_ver_ext ver_ext; - int ret = 0; - /* get fw version */ memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); - /* Send request to firmware */ - ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, &ver_ext); - - if (ret) - ret = -1; + if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, + HostCmd_ACT_GEN_GET, 0, &ver_ext)) + return -1; - return ret; + return 0; } /* @@ -1379,7 +1338,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats get_log; memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); - /* Send request to firmware */ ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, HostCmd_ACT_GEN_GET, 0, &get_log); @@ -1412,7 +1370,6 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, struct mwifiex_ds_reg_rw *reg_rw, u16 action) { - int ret = 0; u16 cmd_no; switch (le32_to_cpu(reg_rw->type)) { @@ -1435,10 +1392,8 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, return -1; } - /* Send request to firmware */ - ret = mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); + return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); - return ret; } /* @@ -1451,15 +1406,13 @@ int mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, u32 reg_offset, u32 reg_value) { - int ret = 0; struct mwifiex_ds_reg_rw reg_rw; reg_rw.type = cpu_to_le32(reg_type); reg_rw.offset = cpu_to_le32(reg_offset); reg_rw.value = cpu_to_le32(reg_value); - ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); - return ret; + return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); } /* @@ -1638,7 +1591,6 @@ int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) { struct mwifiex_ds_misc_gen_ie gen_ie; - int status = 0; if (ie_len > IW_CUSTOM_MAX) return -EFAULT; @@ -1646,8 +1598,7 @@ mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; gen_ie.len = ie_len; memcpy(gen_ie.ie_data, ie, ie_len); - status = mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET); - if (status) + if (mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET)) return -EFAULT; return 0; diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index b261d812c4d..5d37ef16012 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -180,15 +180,11 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; u8 ret = false; - u8 prop_ps = true; if (!adapter->sleep_period.period) return ret; - if (mwifiex_wmm_lists_empty(adapter)) { - if ((priv->curr_bss_params.wmm_uapsd_enabled && - priv->wmm_qosinfo) || prop_ps) + if (mwifiex_wmm_lists_empty(adapter)) ret = true; - } if (ret && !adapter->cmd_sent && !adapter->curr_cmd && !is_command_pending(adapter)) { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index f06923cb1c4..ce772e078db 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -36,7 +36,6 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - int ret = 0; struct mwifiex_private *priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); struct rxpd *local_rx_pd; @@ -50,9 +49,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); rx_info->bss_index = priv->bss_index; - ret = mwifiex_process_sta_rx_packet(adapter, skb); - return ret; + return mwifiex_process_sta_rx_packet(adapter, skb); } EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 9f65587622f..7ab4fb279f8 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -61,7 +61,6 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown) { - int ret; u16 cmd; if (func_init_shutdown == MWIFIEX_FUNC_INIT) { @@ -73,10 +72,7 @@ int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, return -1; } - /* Send command to firmware */ - ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); - - return ret; + return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); } EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 99e8431c1e9..c009370f309 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -973,7 +973,6 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, struct sk_buff *skb, *skb_next; struct mwifiex_tx_param tx_param; struct mwifiex_adapter *adapter = priv->adapter; - int status = 0; struct mwifiex_txinfo *tx_info; if (skb_queue_empty(&ptr->skb_head)) { @@ -1000,9 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, tx_param.next_pkt_len = ((skb_next) ? skb_next->len + sizeof(struct txpd) : 0); - status = mwifiex_process_tx(priv, skb, &tx_param); - - if (status == -EBUSY) { + if (mwifiex_process_tx(priv, skb, &tx_param) == -EBUSY) { /* Queue the packet back at the head */ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); -- cgit v1.2.3-70-g09d2 From a37316586d926a10d66b5585c5d91683d6468f68 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 15 Apr 2011 20:50:41 -0700 Subject: mwifiex: remove some macro definitions use corresponding macros defined in include/linux/ieee80211.h Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 2 +- drivers/net/wireless/mwifiex/fw.h | 2 -- drivers/net/wireless/mwifiex/ioctl.h | 3 +-- drivers/net/wireless/mwifiex/join.c | 2 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index d64065ff235..e22d761f2ef 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -115,7 +115,7 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); /* Clear RD responder bit */ - RESETHT_EXTCAP_RDG(ht_ext_cap); + ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index f8c008f8f47..6d1c4545eda 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -134,7 +134,6 @@ enum MWIFIEX_802_11_WEP_STATUS { #define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096 #define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 -#define NON_GREENFIELD_STAS 0x04 #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) @@ -159,7 +158,6 @@ enum MWIFIEX_802_11_WEP_STATUS { #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) -#define RESETHT_EXTCAP_RDG(HTExtCap) (HTExtCap &= ~BIT(11)) #define SETHT_MCS32(x) (x[4] |= 1) #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 703a6d12ebf..5488e111fd2 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -268,14 +268,13 @@ struct mwifiex_debug_info { }; #define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 -#define MWIFIEX_MAX_KEY_LENGTH 32 #define WAPI_RXPN_LEN 16 struct mwifiex_ds_encrypt_key { u32 key_disable; u32 key_index; u32 key_len; - u8 key_material[MWIFIEX_MAX_KEY_LENGTH]; + u8 key_material[WLAN_MAX_KEY_LEN]; u8 mac_addr[ETH_ALEN]; u32 is_wapi_key; u8 wapi_rxpn[WAPI_RXPN_LEN]; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 8e1cb4b3fbe..23d2d0b9a52 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -995,7 +995,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; } ht_info->ht_info.operation_mode = - cpu_to_le16(NON_GREENFIELD_STAS); + cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); ht_info->ht_info.basic_set[0] = 0xff; pos += sizeof(struct mwifiex_ie_types_htinfo); cmd_append_size += diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 03085a3b20d..e7adaab3522 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -1147,7 +1147,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, struct host_cmd_ds_802_11_key_material *ibss_key; /* Current driver only supports key length of up to 32 bytes */ - if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { + if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) { dev_err(priv->adapter->dev, "key length too long\n"); return -1; } -- cgit v1.2.3-70-g09d2 From 2be7859f41e9bcef5b15bd23d63e01536344e3df Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 15 Apr 2011 20:50:42 -0700 Subject: mwifiex: optimize driver initialization code 1) removal of unnecessary mwifiex_device structure 2) avoid passing adapter pointer to mwifiex_init_sw() 3) remove local variable drv_mode_info in mwifiex_add_card() 4) type change in mwifiex_bss_attr to match mwifiex_private 5) removal of more wordy comments Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/decl.h | 14 +++---- drivers/net/wireless/mwifiex/main.c | 81 +++++++++++++------------------------ drivers/net/wireless/mwifiex/main.h | 2 +- 3 files changed, 33 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 8364b62c329..0e90b0986ed 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -113,11 +113,11 @@ struct mwifiex_txinfo { }; struct mwifiex_bss_attr { - u32 bss_type; - u32 frame_type; - u32 active; - u32 bss_priority; - u32 bss_num; + u8 bss_type; + u8 frame_type; + u8 active; + u8 bss_priority; + u8 bss_num; }; enum mwifiex_wmm_ac_e { @@ -126,8 +126,4 @@ enum mwifiex_wmm_ac_e { WMM_AC_VI, WMM_AC_VO } __packed; - -struct mwifiex_device { - struct mwifiex_bss_attr bss_attr[MWIFIEX_MAX_BSS_NUM]; -}; #endif /* !_MWIFIEX_DECL_H_ */ diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 2c376dd4ad5..c5971880e7b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -40,14 +40,10 @@ static char fw_name[32] = DEFAULT_FW_NAME; /* Supported drv_mode table */ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { { - /* drv_mode */ - .drv_mode = DRV_MODE_STA, - /* intf number */ - .intf_num = ARRAY_SIZE(mwifiex_bss_sta), - /* bss_attr */ - .bss_attr = mwifiex_bss_sta, - } - , + .drv_mode = DRV_MODE_STA, + .intf_num = ARRAY_SIZE(mwifiex_bss_sta), + .bss_attr = mwifiex_bss_sta, + }, }; /* @@ -66,13 +62,12 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, - struct mwifiex_device *mdevice, void **padapter) + struct mwifiex_drv_mode *drv_mode_ptr) { - struct mwifiex_adapter *adapter = NULL; - u8 i = 0; + struct mwifiex_adapter *adapter; + int i; adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); - /* Allocate memory for adapter structure */ if (!adapter) return -1; @@ -87,14 +82,13 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, goto error; adapter->priv_num = 0; - for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) { + for (i = 0; i < drv_mode_ptr->intf_num; i++) { adapter->priv[i] = NULL; - if (!mdevice->bss_attr[i].active) + if (!drv_mode_ptr->bss_attr[i].active) continue; - /* For valid bss_attr, - allocate memory for private structure */ + /* Allocate memory for private structure */ adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); if (!adapter->priv[i]) { @@ -104,26 +98,26 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, } adapter->priv_num++; - memset(adapter->priv[i], 0, - sizeof(struct mwifiex_private)); adapter->priv[i]->adapter = adapter; /* Save bss_type, frame_type & bss_priority */ - adapter->priv[i]->bss_type = (u8) mdevice->bss_attr[i].bss_type; + adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type; adapter->priv[i]->frame_type = - (u8) mdevice->bss_attr[i].frame_type; + drv_mode_ptr->bss_attr[i].frame_type; adapter->priv[i]->bss_priority = - (u8) mdevice->bss_attr[i].bss_priority; - if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA) + drv_mode_ptr->bss_attr[i].bss_priority; + + if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA) adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA; - else if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_UAP) + else if (drv_mode_ptr->bss_attr[i].bss_type == + MWIFIEX_BSS_TYPE_UAP) adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP; /* Save bss_index & bss_num */ adapter->priv[i]->bss_index = i; - adapter->priv[i]->bss_num = mdevice->bss_attr[i].bss_num; + adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num; } + adapter->drv_mode = drv_mode_ptr; - /* Initialize lock variables */ if (mwifiex_init_lock_list(adapter)) goto error; @@ -131,16 +125,13 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, adapter->cmd_timer.function = mwifiex_cmd_timeout_func; adapter->cmd_timer.data = (unsigned long) adapter; - /* Return pointer of struct mwifiex_adapter */ - *padapter = adapter; return 0; error: dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); - /* Free lock variables */ mwifiex_free_lock_list(adapter); - for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) + for (i = 0; i < drv_mode_ptr->intf_num; i++) kfree(adapter->priv[i]); kfree(adapter); @@ -335,10 +326,9 @@ exit_main_proc: * and initializing the private structures. */ static int -mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex) +mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) { int i; - struct mwifiex_device device; struct mwifiex_drv_mode *drv_mode_ptr; /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */ @@ -355,20 +345,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex) return -1; } - memset(&device, 0, sizeof(struct mwifiex_device)); - - for (i = 0; i < drv_mode_ptr->intf_num; i++) { - device.bss_attr[i].bss_type = - drv_mode_ptr->bss_attr[i].bss_type; - device.bss_attr[i].frame_type = - drv_mode_ptr->bss_attr[i].frame_type; - device.bss_attr[i].active = drv_mode_ptr->bss_attr[i].active; - device.bss_attr[i].bss_priority = - drv_mode_ptr->bss_attr[i].bss_priority; - device.bss_attr[i].bss_num = drv_mode_ptr->bss_attr[i].bss_num; - } - - if (mwifiex_register(card, if_ops, &device, pmwifiex)) + if (mwifiex_register(card, if_ops, drv_mode_ptr)) return -1; return 0; @@ -892,21 +869,19 @@ mwifiex_add_card(void *card, struct semaphore *sem, struct mwifiex_if_ops *if_ops) { int i; - struct mwifiex_adapter *adapter = NULL; - struct mwifiex_drv_mode *drv_mode_info = &mwifiex_drv_mode_tbl[0]; + struct mwifiex_adapter *adapter; if (down_interruptible(sem)) goto exit_sem_err; - if (mwifiex_init_sw(card, if_ops, (void **) &adapter)) { + if (mwifiex_init_sw(card, if_ops)) { pr_err("%s: software init failed\n", __func__); goto err_init_sw; } - adapter->drv_mode = drv_mode_info; + adapter = g_adapter; adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; - /* PnP and power profile */ adapter->surprise_removed = false; init_waitqueue_head(&adapter->init_wait_q); adapter->is_suspended = false; @@ -917,7 +892,6 @@ mwifiex_add_card(void *card, struct semaphore *sem, adapter->cmd_wait_q.condition = false; adapter->cmd_wait_q.status = 0; - /* Create workqueue */ adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); if (!adapter->workqueue) goto err_kmalloc; @@ -931,13 +905,13 @@ mwifiex_add_card(void *card, struct semaphore *sem, goto err_registerdev; } - /* Init FW and HW */ if (mwifiex_init_hw_fw(adapter)) { pr_err("%s: firmware init failed\n", __func__); goto err_init_fw; } + /* Add interfaces */ - for (i = 0; i < drv_mode_info->intf_num; i++) { + for (i = 0; i < adapter->drv_mode->intf_num; i++) { if (!mwifiex_add_interface(adapter, i, adapter->drv_mode->bss_attr[i].bss_type)) { goto err_add_intf; @@ -952,7 +926,6 @@ err_add_intf: for (i = 0; i < adapter->priv_num; i++) mwifiex_remove_interface(adapter, i); err_init_fw: - /* Unregister device */ pr_debug("info: %s: unregister device\n", __func__); adapter->if_ops.unregister_dev(adapter); err_registerdev: diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 2d296dcc210..1b503038270 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -872,7 +872,7 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len) */ static inline struct mwifiex_private * mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, - u32 bss_num, u32 bss_type) + u8 bss_num, u8 bss_type) { int i; -- cgit v1.2.3-70-g09d2 From cea3235cf578b5e952f5a0cec9bc6c2e862eb697 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 16 Apr 2011 14:17:39 +0530 Subject: ath9k_htc: Fix free slot value for cab queue ath9k_htc_tx_get_slot can return zero as valid index. Signed-off-by: Rajkumar Manoharan Acked-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index bf7ef1b7eb3..a157107b3f3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -322,7 +322,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, } tx_slot = ath9k_htc_tx_get_slot(priv); - if (tx_slot != 0) { + if (tx_slot < 0) { ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); dev_kfree_skb_any(skb); goto next; -- cgit v1.2.3-70-g09d2 From 8e22ad323fb5b7cefb572bd8730e3abef95cdf90 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sun, 17 Apr 2011 21:38:10 +0530 Subject: ath9k: Fix beacon generation on foreign channel While leaving the oper channel, beacon generation is stopped by mac80211 and beacon slots are marked as inactive. During the scan, ath9k configures beacon timers based on IEEE80211_CONF_OFFCHANNEL which inturn generates beacon alert even though bslot is inactive. ath9k fails to disable beacon alert while moving to offchannel if none of the beacon slot is active. This is causing beacon transmission on foreign channel. This patch enables swba based on active bslots. This issue was reported with two vifs (AP+STA) and triggered scan in STA vif in unassociated state. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 36 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 9193a385ceb..24f565ba998 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -746,6 +746,25 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) ath_set_beacon(sc); } +static bool ath_has_valid_bslot(struct ath_softc *sc) +{ + struct ath_vif *avp; + int slot; + bool found = false; + + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (sc->beacon.bslot[slot]) { + avp = (void *)sc->beacon.bslot[slot]->drv_priv; + if (avp->is_bslot_active) { + found = true; + break; + } + } + } + return found; +} + + void ath_set_beacon(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -753,7 +772,8 @@ void ath_set_beacon(struct ath_softc *sc) switch (sc->sc_ah->opmode) { case NL80211_IFTYPE_AP: - ath_beacon_config_ap(sc, cur_conf); + if (ath_has_valid_bslot(sc)) + ath_beacon_config_ap(sc, cur_conf); break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: @@ -780,20 +800,8 @@ void ath_set_beacon(struct ath_softc *sc) void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) { struct ath_hw *ah = sc->sc_ah; - struct ath_vif *avp; - int slot; - bool found = false; - for (slot = 0; slot < ATH_BCBUF; slot++) { - if (sc->beacon.bslot[slot]) { - avp = (void *)sc->beacon.bslot[slot]->drv_priv; - if (avp->is_bslot_active) { - found = true; - break; - } - } - } - if (!found) + if (!ath_has_valid_bslot(sc)) return; ath9k_ps_wakeup(sc); -- cgit v1.2.3-70-g09d2 From 5519541d5a5f19893546883547e2f0f2e5934df7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 17 Apr 2011 23:28:09 +0200 Subject: ath9k: fix powersave frame filtering/buffering in AP mode This patch fixes a long standing issue of pending packets in the queue being sent (and retransmitted many times) to sleeping stations. This was made worse by aggregation through driver-internal retransmitting of A-MDPU subframes. Previously the hardware tx filter was cleared unconditionally for every single packet - with this patch it uses the IEEE80211_TX_CTL_CLEAR_PS_FILT for unaggregated frames. A sta_notify driver op is added to stop aggregation for stations when they enter powersave mode. Subframes stay buffered inside the driver, to ensure that the BlockAck window keeps a sane state. Since the driver uses software aggregation, the clearing of the tx filter needs to be handled by the driver instead of mac80211 for aggregated frames. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 12 +++- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 12 +++- drivers/net/wireless/ath/ath9k/ath9k.h | 6 ++ drivers/net/wireless/ath/ath9k/hw-ops.h | 5 ++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/mac.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 22 ++++++ drivers/net/wireless/ath/ath9k/xmit.c | 101 ++++++++++++++++++++++++---- 8 files changed, 145 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 8dd8f630850..c338efbccf4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | SM(txPower, AR_XmitPower) | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) - | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); @@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, } } +static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) +{ + struct ar5416_desc *ads = AR5416DESC(ds); + + if (val) + ads->ds_ctl0 |= AR_ClrDestMask; + else + ads->ds_ctl0 &= ~AR_ClrDestMask; +} + static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, void *lastds, u32 durUpdateEn, u32 rtsctsRate, @@ -448,4 +457,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; ops->clr11n_aggr = ar9002_hw_clr11n_aggr; ops->set11n_burstduration = ar9002_hw_set11n_burstduration; + ops->set_clrdmask = ar9002_hw_set_clrdmask; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 724ac2464ad..c1264d60c49 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | SM(txpower, AR_XmitPower) | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) - | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); @@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, ads->ctl22 = 0; } +static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) +{ + struct ar9003_txc *ads = (struct ar9003_txc *) ds; + + if (val) + ads->ctl11 |= AR_ClrDestMask; + else + ads->ctl11 &= ~AR_ClrDestMask; +} + static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, void *lastds, u32 durUpdateEn, u32 rtsctsRate, @@ -510,6 +519,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; ops->clr11n_aggr = ar9003_hw_clr11n_aggr; ops->set11n_burstduration = ar9003_hw_set11n_burstduration; + ops->set_clrdmask = ar9003_hw_set_clrdmask; } void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 77ad407e9fa..a2ddabf0ca2 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -200,6 +200,7 @@ struct ath_atx_ac { int sched; struct list_head list; struct list_head tid_q; + bool clear_ps_filter; }; struct ath_frame_info { @@ -257,6 +258,8 @@ struct ath_node { struct ath_atx_ac ac[WME_NUM_AC]; u16 maxampdu; u8 mpdudensity; + + bool sleeping; }; #define AGGR_CLEANUP BIT(1) @@ -338,6 +341,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); +void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); +bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); + /********/ /* VIFs */ /********/ diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 22ee888b0ba..9dd90a85ad6 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -122,6 +122,11 @@ static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); } +static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) +{ + ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); +} + /* Private hardware call ops */ /* PHY ops */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 073bc9e1c79..1018d6cbd53 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -626,6 +626,7 @@ struct ath_hw_ops { void (*clr11n_aggr)(struct ath_hw *ah, void *ds); void (*set11n_burstduration)(struct ath_hw *ah, void *ds, u32 burstDuration); + void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); }; struct ath_nf_limits { diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index b2b2ff852c3..a60edb44127 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -239,7 +239,6 @@ struct ath_desc { void *ds_vdata; } __packed __aligned(4); -#define ATH9K_TXDESC_CLRDMASK 0x0001 #define ATH9K_TXDESC_NOACK 0x0002 #define ATH9K_TXDESC_RTSENA 0x0004 #define ATH9K_TXDESC_CTSENA 0x0008 diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a55a8929810..01df5876fda 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1749,6 +1749,27 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, return 0; } +static void ath9k_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + struct ath_softc *sc = hw->priv; + struct ath_node *an = (struct ath_node *) sta->drv_priv; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + an->sleeping = true; + if (ath_tx_aggr_sleep(sc, an)) + ieee80211_sta_set_tim(sta); + break; + case STA_NOTIFY_AWAKE: + an->sleeping = false; + ath_tx_aggr_wakeup(sc, an); + break; + } +} + static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { @@ -2230,6 +2251,7 @@ struct ieee80211_ops ath9k_ops = { .configure_filter = ath9k_configure_filter, .sta_add = ath9k_sta_add, .sta_remove = ath9k_sta_remove, + .sta_notify = ath9k_sta_notify, .conf_tx = ath9k_conf_tx, .bss_info_changed = ath9k_bss_info_changed, .set_key = ath9k_set_key, diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5943bdc4c8f..48ff8c22ba1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_frame_info *fi; int nframes; u8 tidno; + bool clear_filter; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -441,22 +442,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, /* transmit completion */ acked_cnt++; } else { - if (!(tid->state & AGGR_CLEANUP) && retry) { - if (fi->retries < ATH_MAX_SW_RETRIES) { - ath_tx_set_retry(sc, txq, bf->bf_mpdu); - txpending = 1; - } else { - bf->bf_state.bf_type |= BUF_XRETRY; - txfail = 1; - sendbar = 1; - txfail_cnt++; - } - } else { + if ((tid->state & AGGR_CLEANUP) || !retry) { /* * cleanup in progress, just fail * the un-acked sub-frames */ txfail = 1; + } else if (fi->retries < ATH_MAX_SW_RETRIES) { + if (!(ts->ts_status & ATH9K_TXERR_FILT) || + !an->sleeping) + ath_tx_set_retry(sc, txq, bf->bf_mpdu); + + clear_filter = true; + txpending = 1; + } else { + bf->bf_state.bf_type |= BUF_XRETRY; + txfail = 1; + sendbar = 1; + txfail_cnt++; } } @@ -496,6 +499,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !txfail, sendbar); } else { /* retry the un-acked ones */ + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { if (bf->bf_next == NULL && bf_last->bf_stale) { struct ath_buf *tbf; @@ -546,7 +550,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, /* prepend un-acked frames to the beginning of the pending frame queue */ if (!list_empty(&bf_pending)) { + if (an->sleeping) + ieee80211_sta_set_tim(sta); + spin_lock_bh(&txq->axq_lock); + if (clear_filter) + tid->ac->clear_ps_filter = true; list_splice(&bf_pending, &tid->buf_q); ath_tx_queue_tid(txq, tid); spin_unlock_bh(&txq->axq_lock); @@ -816,6 +825,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, bf = list_first_entry(&bf_q, struct ath_buf, list); bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); + if (tid->ac->clear_ps_filter) { + tid->ac->clear_ps_filter = false; + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); + } + /* if only one frame, send as non-aggregate */ if (bf == bf->bf_lastbf) { fi = get_frame_info(bf->bf_mpdu); @@ -896,6 +910,67 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) ath_tx_flush_tid(sc, txtid); } +bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) +{ + struct ath_atx_tid *tid; + struct ath_atx_ac *ac; + struct ath_txq *txq; + bool buffered = false; + int tidno; + + for (tidno = 0, tid = &an->tid[tidno]; + tidno < WME_NUM_TID; tidno++, tid++) { + + if (!tid->sched) + continue; + + ac = tid->ac; + txq = ac->txq; + + spin_lock_bh(&txq->axq_lock); + + if (!list_empty(&tid->buf_q)) + buffered = true; + + tid->sched = false; + list_del(&tid->list); + + if (ac->sched) { + ac->sched = false; + list_del(&ac->list); + } + + spin_unlock_bh(&txq->axq_lock); + } + + return buffered; +} + +void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) +{ + struct ath_atx_tid *tid; + struct ath_atx_ac *ac; + struct ath_txq *txq; + int tidno; + + for (tidno = 0, tid = &an->tid[tidno]; + tidno < WME_NUM_TID; tidno++, tid++) { + + ac = tid->ac; + txq = ac->txq; + + spin_lock_bh(&txq->axq_lock); + ac->clear_ps_filter = true; + + if (!list_empty(&tid->buf_q) && !tid->paused) { + ath_tx_queue_tid(txq, tid); + ath_txq_schedule(sc, txq); + } + + spin_unlock_bh(&txq->axq_lock); + } +} + void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) { struct ath_atx_tid *txtid; @@ -1491,7 +1566,6 @@ static int setup_tx_flags(struct sk_buff *skb) struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); int flags = 0; - flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ flags |= ATH9K_TXDESC_INTREQ; if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) @@ -1754,6 +1828,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, if (txctl->paprd) bf->bf_state.bfs_paprd_timestamp = jiffies; + if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); + ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); } -- cgit v1.2.3-70-g09d2 From 93ae2dd2230393566738a5f211ffbaa33b056d56 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 17 Apr 2011 23:28:10 +0200 Subject: ath9k: assign keycache slots to unencrypted stations Frame filtering relies on having a valid destination index (keycache slot), to keep track of the destination. Assigning a keycache slot (configured to unencrypted, with no key data attached) improves powersave handling in AP mode with no encryption. The dummy keycache entry for a station is cleared, when a real key gets added. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 22 ++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/xmit.c | 10 +++++++--- drivers/net/wireless/ath/key.c | 6 +++++- 4 files changed, 36 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a2ddabf0ca2..a6b53880225 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -256,6 +256,8 @@ struct ath_node { #endif struct ath_atx_tid tid[WME_NUM_TID]; struct ath_atx_ac ac[WME_NUM_AC]; + int ps_key; + u16 maxampdu; u8 mpdudensity; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 01df5876fda..e7d6d98ed1c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1732,18 +1732,37 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct ath_softc *sc = hw->priv; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_node *an = (struct ath_node *) sta->drv_priv; + struct ieee80211_key_conf ps_key = { }; ath_node_attach(sc, sta); + an->ps_key = ath_key_config(common, vif, sta, &ps_key); return 0; } +static void ath9k_del_ps_key(struct ath_softc *sc, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_node *an = (struct ath_node *) sta->drv_priv; + struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; + + if (!an->ps_key) + return; + + ath_key_delete(common, &ps_key); +} + static int ath9k_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct ath_softc *sc = hw->priv; + ath9k_del_ps_key(sc, vif, sta); ath_node_detach(sc, sta); return 0; @@ -1844,6 +1863,9 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: + if (sta) + ath9k_del_ps_key(sc, vif, sta); + ret = ath_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 48ff8c22ba1..65d46c6ebce 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1526,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr; struct ath_frame_info *fi = get_frame_info(skb); - struct ath_node *an; + struct ath_node *an = NULL; struct ath_atx_tid *tid; enum ath9k_key_type keytype; u16 seqno = 0; @@ -1534,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, keytype = ath9k_cmn_get_hw_crypto_keytype(skb); + if (sta) + an = (struct ath_node *) sta->drv_priv; + hdr = (struct ieee80211_hdr *)skb->data; - if (sta && ieee80211_is_data_qos(hdr->frame_control) && + if (an && ieee80211_is_data_qos(hdr->frame_control) && conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { - an = (struct ath_node *) sta->drv_priv; tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; /* @@ -1554,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, memset(fi, 0, sizeof(*fi)); if (hw_key) fi->keyix = hw_key->hw_key_idx; + else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) + fi->keyix = an->ps_key; else fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 0d4f39cbdca..a61ef3d6d89 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -483,6 +483,9 @@ int ath_key_config(struct ath_common *common, memset(&hk, 0, sizeof(hk)); switch (key->cipher) { + case 0: + hk.kv_type = ATH_CIPHER_CLR; + break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: hk.kv_type = ATH_CIPHER_WEP; @@ -498,7 +501,8 @@ int ath_key_config(struct ath_common *common, } hk.kv_len = key->keylen; - memcpy(hk.kv_val, key->key, key->keylen); + if (key->keylen) + memcpy(hk.kv_val, key->key, key->keylen); if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { switch (vif->type) { -- cgit v1.2.3-70-g09d2 From 44704e5d7d56625ff93d5a119ca846ae4de9061c Mon Sep 17 00:00:00 2001 From: Layne Edwards Date: Mon, 18 Apr 2011 15:26:00 +0200 Subject: rt2x00: Enable WLAN LED on Ralink SoC (rt305x) devices This patch adds WLAN LED support to the mac80211 rt2x00 driver for Ralink SoC (rt305x) devices. The current WLAN LED drivers in rt2800lib.c set the LED brightness via an MCU request, but do nothing for SoC. This patch checks for SoC and sets the register to enable the WLAN LED (instead of an MCU request). This enables the WLAN LED for RT305x devices. Signed-off-by: Layne Edwards Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 60 +++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 769c05c0cba..13ccc1bbeb4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -949,25 +949,49 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev, unsigned int ledmode = rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, EEPROM_FREQ_LED_MODE); + u32 reg; - if (led->type == LED_TYPE_RADIO) { - rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, - enabled ? 0x20 : 0); - } else if (led->type == LED_TYPE_ASSOC) { - rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, - enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); - } else if (led->type == LED_TYPE_QUALITY) { - /* - * The brightness is divided into 6 levels (0 - 5), - * The specs tell us the following levels: - * 0, 1 ,3, 7, 15, 31 - * to determine the level in a simple way we can simply - * work with bitshifting: - * (1 << level) - 1 - */ - rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, - (1 << brightness / (LED_FULL / 6)) - 1, - polarity); + /* Check for SoC (SOC devices don't support MCU requests) */ + if (rt2x00_is_soc(led->rt2x00dev)) { + rt2800_register_read(led->rt2x00dev, LED_CFG, ®); + + /* Set LED Polarity */ + rt2x00_set_field32(®, LED_CFG_LED_POLAR, polarity); + + /* Set LED Mode */ + if (led->type == LED_TYPE_RADIO) { + rt2x00_set_field32(®, LED_CFG_G_LED_MODE, + enabled ? 3 : 0); + } else if (led->type == LED_TYPE_ASSOC) { + rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, + enabled ? 3 : 0); + } else if (led->type == LED_TYPE_QUALITY) { + rt2x00_set_field32(®, LED_CFG_R_LED_MODE, + enabled ? 3 : 0); + } + + rt2800_register_write(led->rt2x00dev, LED_CFG, reg); + + } else { + if (led->type == LED_TYPE_RADIO) { + rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, + enabled ? 0x20 : 0); + } else if (led->type == LED_TYPE_ASSOC) { + rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, + enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); + } else if (led->type == LED_TYPE_QUALITY) { + /* + * The brightness is divided into 6 levels (0 - 5), + * The specs tell us the following levels: + * 0, 1 ,3, 7, 15, 31 + * to determine the level in a simple way we can simply + * work with bitshifting: + * (1 << level) - 1 + */ + rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, + (1 << brightness / (LED_FULL / 6)) - 1, + polarity); + } } } -- cgit v1.2.3-70-g09d2 From 62fe778412b36791b7897cfa139342906fbbf07b Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:26:37 +0200 Subject: rt2x00: Fix stuck queue in tx failure case Since commit 0b7fde54f94979edc67bbf86b5adba702ebfefe8 "rt2x00: Protect queue control with mutex" rt2x00 used rt2x00queue_pause_queue for stopping a tx queue in mac80211. But in case of a failure in the tx path rt2x00 still called ieee80211_stop_queue which stopped the queue but prevented rt2x00queue_unpause_queue to wake the queue up again resulting in a stuck tx queue. Fix this by also using rt2x00queue_pause_queue in case of tx failures. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 661c6baad2b..4a1c41b59fe 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -158,7 +158,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return; exit_fail: - ieee80211_stop_queue(rt2x00dev->hw, qid); + rt2x00queue_pause_queue(queue); dev_kfree_skb_any(skb); } EXPORT_SYMBOL_GPL(rt2x00mac_tx); -- cgit v1.2.3-70-g09d2 From 7dab73b37f5e8885cb73efd25e73861f9b4f0246 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 18 Apr 2011 15:27:06 +0200 Subject: rt2x00: Split rt2x00dev->flags The number of flags defined for the rt2x00dev->flags field, has been growing over the years. Currently we are approaching the maximum number of bits which are available in the field. A secondary problem, is that one part of the field are initialized only during boot, because the driver requirements are initialized or device requirements are loaded from the EEPROM. In both cases, the flags are fixed and will not change during device operation. The other flags are the device state, and will change frequently. So far this resulted in the fact that for some flags, the atomic bit accessors are used, while for the others the non-atomic variants are used. By splitting the flags up into a "flags" and "cap_flags" we can put all flags which are fixed inside "cap_flags". This field can then be read non-atomically. In the "flags" field we keep the device state, which is going to be read atomically. This adds more room for more flags in the future, and sanitizes the field access methods. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 10 ++-- drivers/net/wireless/rt2x00/rt2500pci.c | 10 ++-- drivers/net/wireless/rt2x00/rt2500usb.c | 12 ++-- drivers/net/wireless/rt2x00/rt2800lib.c | 20 +++---- drivers/net/wireless/rt2x00/rt2800pci.c | 22 ++++---- drivers/net/wireless/rt2x00/rt2800usb.c | 14 ++--- drivers/net/wireless/rt2x00/rt2x00.h | 84 ++++++++++++++++------------ drivers/net/wireless/rt2x00/rt2x00config.c | 4 +- drivers/net/wireless/rt2x00/rt2x00crypto.c | 4 +- drivers/net/wireless/rt2x00/rt2x00debug.c | 42 +++++++++++++- drivers/net/wireless/rt2x00/rt2x00dev.c | 14 ++--- drivers/net/wireless/rt2x00/rt2x00firmware.c | 2 +- drivers/net/wireless/rt2x00/rt2x00lib.h | 4 +- drivers/net/wireless/rt2x00/rt2x00link.c | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 12 ++-- drivers/net/wireless/rt2x00/rt2x00queue.c | 20 +++---- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +- drivers/net/wireless/rt2x00/rt61pci.c | 42 +++++++------- drivers/net/wireless/rt2x00/rt73usb.c | 32 +++++------ 19 files changed, 203 insertions(+), 153 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 137a24e520d..5d1654a8bda 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1536,13 +1536,13 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Detect if this device has an hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Check if the BBP tuning should be enabled. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); return 0; } @@ -1640,9 +1640,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) /* * This device requires the atim queue and DMA-mapped skbs. */ - __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); + __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 198fc0a0d77..3da954e1b4a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1687,14 +1687,14 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Detect if this device has an hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Check if the BBP tuning should be enabled. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); /* * Read the RSSI <-> dBm offset information. @@ -1958,9 +1958,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) /* * This device requires the atim queue and DMA-mapped skbs. */ - __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); + __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index eac788160f5..dbbd8bc851f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1519,7 +1519,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) * Detect if this device has an hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Read the RSSI <-> dBm offset information. @@ -1790,13 +1790,13 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) /* * This device requires the atim queue */ - __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); + __set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) { - __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags); } - __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); + __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 13ccc1bbeb4..c6f5584128e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1763,8 +1763,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { if (!rt2x00_rt(rt2x00dev, RT5390)) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, - &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, + &rt2x00dev->cap_flags)) { rt2800_bbp_write(rt2x00dev, 82, 0x62); rt2800_bbp_write(rt2x00dev, 75, 0x46); } else { @@ -1775,7 +1775,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, } else { rt2800_bbp_write(rt2x00dev, 82, 0xf2); - if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) rt2800_bbp_write(rt2x00dev, 75, 0x46); else rt2800_bbp_write(rt2x00dev, 75, 0x50); @@ -2008,7 +2008,7 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) return txpower; - if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { /* * Check if eirp txpower exceed txpower_limit. * We use OFDM 6M as criterion and its eirp txpower @@ -3309,8 +3309,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (!test_bit(CONFIG_EXTERNAL_LNA_BG, - &rt2x00dev->flags)) + if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, + &rt2x00dev->cap_flags)) rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); } rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); @@ -3733,15 +3733,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) - __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) - __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); /* * Detect if this device has an hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Store led settings, for correct led behaviour. @@ -3761,7 +3761,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < EIRP_MAX_TX_POWER_LIMIT) - __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags); + __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index adc3534254d..4241f194384 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -966,28 +966,28 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. */ - __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags); + __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags); /* * This device has a pre tbtt interrupt and thus fetches * a new beacon directly prior to transmission. */ - __set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags); + __set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags); /* * This device requires firmware. */ if (!rt2x00_is_soc(rt2x00dev)) - __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags); + __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) - __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index d2f5c87305a..f3ce5e854be 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -553,18 +553,18 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. */ - __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags); + __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags); /* * This device requires firmware. */ - __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); + __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) - __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index dd0f66ade6e..79c385accfa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -643,11 +643,11 @@ struct rt2x00_ops { }; /* - * rt2x00 device flags + * rt2x00 state flags */ -enum rt2x00_flags { +enum rt2x00_state_flags { /* - * Device state flags + * Device flags */ DEVICE_STATE_PRESENT, DEVICE_STATE_REGISTERED_HW, @@ -656,42 +656,47 @@ enum rt2x00_flags { DEVICE_STATE_ENABLED_RADIO, DEVICE_STATE_SCANNING, - /* - * Driver requirements - */ - DRIVER_REQUIRE_FIRMWARE, - DRIVER_REQUIRE_BEACON_GUARD, - DRIVER_REQUIRE_ATIM_QUEUE, - DRIVER_REQUIRE_DMA, - DRIVER_REQUIRE_COPY_IV, - DRIVER_REQUIRE_L2PAD, - DRIVER_REQUIRE_TXSTATUS_FIFO, - DRIVER_REQUIRE_TASKLET_CONTEXT, - DRIVER_REQUIRE_SW_SEQNO, - DRIVER_REQUIRE_HT_TX_DESC, - - /* - * Driver features - */ - CONFIG_SUPPORT_HW_BUTTON, - CONFIG_SUPPORT_HW_CRYPTO, - CONFIG_SUPPORT_POWER_LIMIT, - DRIVER_SUPPORT_CONTROL_FILTERS, - DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, - DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, - DRIVER_SUPPORT_LINK_TUNING, - /* * Driver configuration */ - CONFIG_FRAME_TYPE, - CONFIG_RF_SEQUENCE, - CONFIG_EXTERNAL_LNA_A, - CONFIG_EXTERNAL_LNA_BG, - CONFIG_DOUBLE_ANTENNA, CONFIG_CHANNEL_HT40, }; +/* + * rt2x00 capability flags + */ +enum rt2x00_capability_flags { + /* + * Requirements + */ + REQUIRE_FIRMWARE, + REQUIRE_BEACON_GUARD, + REQUIRE_ATIM_QUEUE, + REQUIRE_DMA, + REQUIRE_COPY_IV, + REQUIRE_L2PAD, + REQUIRE_TXSTATUS_FIFO, + REQUIRE_TASKLET_CONTEXT, + REQUIRE_SW_SEQNO, + REQUIRE_HT_TX_DESC, + + /* + * Capabilities + */ + CAPABILITY_HW_BUTTON, + CAPABILITY_HW_CRYPTO, + CAPABILITY_POWER_LIMIT, + CAPABILITY_CONTROL_FILTERS, + CAPABILITY_CONTROL_FILTER_PSPOLL, + CAPABILITY_PRE_TBTT_INTERRUPT, + CAPABILITY_LINK_TUNING, + CAPABILITY_FRAME_TYPE, + CAPABILITY_RF_SEQUENCE, + CAPABILITY_EXTERNAL_LNA_A, + CAPABILITY_EXTERNAL_LNA_BG, + CAPABILITY_DOUBLE_ANTENNA, +}; + /* * rt2x00 device structure. */ @@ -738,12 +743,19 @@ struct rt2x00_dev { #endif /* CONFIG_RT2X00_LIB_LEDS */ /* - * Device flags. - * In these flags the current status and some - * of the device capabilities are stored. + * Device state flags. + * In these flags the current status is stored. + * Access to these flags should occur atomically. */ unsigned long flags; + /* + * Device capabiltiy flags. + * In these flags the device/driver capabilities are stored. + * Access to these flags should occur non-atomically. + */ + unsigned long cap_flags; + /* * Device information, Bus IRQ and name (PCI, SoC) */ diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e7f67d5eda5..e225a66f59a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -176,10 +176,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { if (conf_is_ht40(conf)) { - __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); + set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = rt2x00ht_center_channel(rt2x00dev, conf); } else { - __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); + clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = conf->channel->hw_value; } diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 5e9074bf2b8..e1e0c51fcde 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -52,7 +52,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; - if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !hw_key) + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) return; __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); @@ -80,7 +80,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, struct ieee80211_key_conf *key = tx_info->control.hw_key; unsigned int overhead = 0; - if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !key) + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !key) return overhead; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 66166ef037f..78787fcc919 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -63,7 +63,8 @@ struct rt2x00debug_intf { * - driver folder * - driver file * - chipset file - * - device flags file + * - device state flags file + * - device capability flags file * - register folder * - csr offset/value files * - eeprom offset/value files @@ -78,6 +79,7 @@ struct rt2x00debug_intf { struct dentry *driver_entry; struct dentry *chipset_entry; struct dentry *dev_flags; + struct dentry *cap_flags; struct dentry *register_folder; struct dentry *csr_off_entry; struct dentry *csr_val_entry; @@ -553,6 +555,35 @@ static const struct file_operations rt2x00debug_fop_dev_flags = { .llseek = default_llseek, }; +static ssize_t rt2x00debug_read_cap_flags(struct file *file, + char __user *buf, + size_t length, + loff_t *offset) +{ + struct rt2x00debug_intf *intf = file->private_data; + char line[16]; + size_t size; + + if (*offset) + return 0; + + size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); + + if (copy_to_user(buf, line, size)) + return -EFAULT; + + *offset += size; + return size; +} + +static const struct file_operations rt2x00debug_fop_cap_flags = { + .owner = THIS_MODULE, + .read = rt2x00debug_read_cap_flags, + .open = rt2x00debug_file_open, + .release = rt2x00debug_file_release, + .llseek = default_llseek, +}; + static struct dentry *rt2x00debug_create_file_driver(const char *name, struct rt2x00debug_intf *intf, @@ -652,6 +683,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) if (IS_ERR(intf->dev_flags) || !intf->dev_flags) goto exit; + intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR, + intf->driver_folder, intf, + &rt2x00debug_fop_cap_flags); + if (IS_ERR(intf->cap_flags) || !intf->cap_flags) + goto exit; + intf->register_folder = debugfs_create_dir("register", intf->driver_folder); if (IS_ERR(intf->register_folder) || !intf->register_folder) @@ -705,7 +742,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) intf, &rt2x00debug_fop_queue_stats); #ifdef CONFIG_RT2X00_LIB_CRYPTO - if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) intf->crypto_stats_entry = debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, intf, &rt2x00debug_fop_crypto_stats); @@ -743,6 +780,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) debugfs_remove(intf->csr_off_entry); debugfs_remove(intf->register_folder); debugfs_remove(intf->dev_flags); + debugfs_remove(intf->cap_flags); debugfs_remove(intf->chipset_entry); debugfs_remove(intf->driver_entry); debugfs_remove(intf->driver_folder); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9bffe8438d1..af25b0152cb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -200,7 +200,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) * here as they will fetch the next beacon directly prior to * transmission. */ - if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags)) return; /* fetch next beacon */ @@ -271,7 +271,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * Remove L2 padding which was added during */ - if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) + if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) rt2x00queue_remove_l2pad(entry->skb, header_length); /* @@ -280,7 +280,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * mac80211 will expect the same data to be present it the * frame as it was passed to us. */ - if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) rt2x00crypto_tx_insert_iv(entry->skb, header_length); /* @@ -377,7 +377,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * send the status report back. */ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { - if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags)) + if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags)) ieee80211_tx_status(rt2x00dev->hw, entry->skb); else ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); @@ -806,15 +806,15 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) /* * Take TX headroom required for alignment into account. */ - if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) + if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; - else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) + else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; /* * Allocate tx status FIFO for driver use. */ - if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) { + if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) { /* * Allocate the txstatus fifo. In the worst case the tx * status fifo has to hold the tx status of all entries diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index be0ff78c1b1..f316aad3061 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -99,7 +99,7 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) { int retval; - if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) + if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags)) return 0; if (!rt2x00dev->fw) { diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 88f2f927552..bbee2cd4099 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -416,13 +416,13 @@ static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, */ static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) { - if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags)) wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy); } static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) { - if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags)) wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy); } diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 128b3615c08..ba0bb766e59 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -383,7 +383,7 @@ static void rt2x00link_tuner(struct work_struct *work) * do not support link tuning at all, while other devices can disable * the feature from the EEPROM. */ - if (test_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags)) rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4a1c41b59fe..4770156df1a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -119,7 +119,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * Use the ATIM queue if appropriate and present. */ if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && - test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) + test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) qid = QID_ATIM; queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); @@ -411,11 +411,11 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, * of different types, but has no a separate filter for PS Poll frames, * FIF_CONTROL flag implies FIF_PSPOLL. */ - if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) { + if (!test_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags)) { if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL) *total_flags |= FIF_CONTROL | FIF_PSPOLL; } - if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) { + if (!test_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags)) { if (*total_flags & FIF_CONTROL) *total_flags |= FIF_PSPOLL; } @@ -496,7 +496,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; - else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) + else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) return -EOPNOTSUPP; else if (key->keylen > 32) return -ENOSPC; @@ -562,7 +562,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_key); void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; - __set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); + set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); rt2x00link_stop_tuner(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); @@ -570,7 +570,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; - __clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); + clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); rt2x00link_start_tuner(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 9fc4a1ec4b4..d03eef28f03 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -60,7 +60,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) * at least 8 bytes bytes available in headroom for IV/EIV * and 8 bytes for ICV data as tailroon. */ - if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) { head_size += 8; tail_size += 8; } @@ -86,7 +86,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) memset(skbdesc, 0, sizeof(*skbdesc)); skbdesc->entry = entry; - if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { + if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) { skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, @@ -213,7 +213,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); - if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags)) + if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags)) return; /* @@ -396,7 +396,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, rt2x00crypto_create_tx_descriptor(entry, txdesc); rt2x00queue_create_tx_descriptor_seq(entry, txdesc); - if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags)) + if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); else rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); @@ -436,7 +436,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, /* * Map the skb to DMA. */ - if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) + if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) rt2x00queue_map_txskb(entry); return 0; @@ -529,7 +529,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, */ if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { - if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags)) + if (test_bit(REQUIRE_COPY_IV, &queue->rt2x00dev->cap_flags)) rt2x00crypto_tx_copy_iv(skb, &txdesc); else rt2x00crypto_tx_remove_iv(skb, &txdesc); @@ -543,9 +543,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * PCI and USB devices, while header alignment only is valid * for PCI devices. */ - if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags)) + if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); - else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) + else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) rt2x00queue_align_frame(entry->skb); /* @@ -1069,7 +1069,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) if (status) goto exit; - if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { + if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) { status = rt2x00queue_alloc_entries(rt2x00dev->atim, rt2x00dev->ops->atim); if (status) @@ -1121,7 +1121,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; enum data_queue_qid qid; unsigned int req_atim = - !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); + !!test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); /* * We need the following queues: diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fbe735f5b35..94047e9b2ec 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -387,7 +387,7 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry) * Kill guardian urb (if required by driver). */ if ((entry->queue->qid == QID_BEACON) && - (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) + (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) usb_kill_urb(bcn_priv->guardian_urb); } @@ -583,7 +583,7 @@ static int rt2x00usb_alloc_entries(struct data_queue *queue) * then we are done. */ if (queue->qid != QID_BEACON || - !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) + !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) return 0; for (i = 0; i < queue->limit; i++) { @@ -618,7 +618,7 @@ static void rt2x00usb_free_entries(struct data_queue *queue) * then we are done. */ if (queue->qid != QID_BEACON || - !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) + !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) return; for (i = 0; i < queue->limit; i++) { diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 8ee1514a794..c16c1501df1 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -683,7 +683,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529)); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); + !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); /* * Configure the RX antenna. @@ -811,10 +811,10 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { sel = antenna_sel_a; - lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); } else { sel = antenna_sel_bg; - lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) @@ -834,7 +834,7 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, else if (rt2x00_rf(rt2x00dev, RF2527)) rt61pci_config_antenna_2x(rt2x00dev, ant); else if (rt2x00_rf(rt2x00dev, RF2529)) { - if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) rt61pci_config_antenna_2x(rt2x00dev, ant); else rt61pci_config_antenna_2529(rt2x00dev, ant); @@ -848,13 +848,13 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, short lna_gain = 0; if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); } else { - if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); @@ -1050,14 +1050,14 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; - if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } } else { low_bound = 0x20; up_bound = 0x40; - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } @@ -2537,7 +2537,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Determine number of antennas. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) - __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); + __set_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags); /* * Identify default antenna configuration. @@ -2551,20 +2551,20 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Read the Frame type. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) - __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); + __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags); /* * Detect if this device has a hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Read frequency offset and RF programming sequence. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) - __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags); + __set_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags); rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); @@ -2574,9 +2574,9 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) - __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) - __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); /* * When working with a RF2529 chip without double antenna, @@ -2584,7 +2584,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * eeprom word. */ if (rt2x00_rf(rt2x00dev, RF2529) && - !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { + !test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) { rt2x00dev->default_ant.rx = ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); rt2x00dev->default_ant.tx = @@ -2799,7 +2799,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->supported_bands = SUPPORT_BAND_2GHZ; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; - if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { + if (!test_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags)) { spec->num_channels = 14; spec->channels = rf_vals_noseq; } else { @@ -2869,16 +2869,16 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) * This device has multiple filters for control frames, * but has no a separate filter for PS Poll frames. */ - __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); + __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); /* * This device requires firmware and DMA mapped skbs. */ - __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); - __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); + __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) - __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6593059f9c7..cdb026d076d 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -595,7 +595,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, switch (ant->rx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); - temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) + temp = !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags) && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); break; @@ -636,7 +636,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); + !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); /* * Configure the RX antenna. @@ -709,10 +709,10 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { sel = antenna_sel_a; - lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); } else { sel = antenna_sel_bg; - lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) @@ -740,7 +740,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev, short lna_gain = 0; if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); @@ -930,7 +930,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, low_bound = 0x28; up_bound = 0x48; - if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } @@ -946,7 +946,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, up_bound = 0x1c; } - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { low_bound += 0x14; up_bound += 0x10; } @@ -1661,7 +1661,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) } if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { - if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { if (lna == 3 || lna == 2) offset += 10; } else { @@ -1899,13 +1899,13 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) * Read the Frame type. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) - __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); + __set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags); /* * Detect if this device has an hardware controlled radio. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); /* * Read frequency offset. @@ -1919,8 +1919,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) { - __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); - __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); } /* @@ -2200,15 +2200,15 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) * This device has multiple filters for control frames, * but has no a separate filter for PS Poll frames. */ - __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); + __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); /* * This device requires firmware. */ - __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); + __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) - __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); + __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); /* * Set the rssi offset. -- cgit v1.2.3-70-g09d2 From 10e11568ca8b8a15f7478f6a4ceebabcbdba1018 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:27:43 +0200 Subject: rt2x00: Make rt2x00_queue_entry_for_each more flexible Allow passing a void pointer to rt2x00_queue_entry_for_each which in turn in provided to the callback function. Furthermore, allow the callback function to stop processing by returning true. And also notify the caller of rt2x00_queue_entry_for_each if the loop was canceled by the callback. No functional changes, just preparation for an upcoming patch. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 28 ++++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00queue.h | 10 ++++++++-- drivers/net/wireless/rt2x00/rt2x00usb.c | 32 +++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index d03eef28f03..458bb489bc7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, return ret; } -void rt2x00queue_for_each_entry(struct data_queue *queue, +bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - void (*fn)(struct queue_entry *entry)) + void *data, + bool (*fn)(struct queue_entry *entry, + void *data)) { unsigned long irqflags; unsigned int index_start; @@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, ERROR(queue->rt2x00dev, "Entry requested from invalid index range (%d - %d)\n", start, end); - return; + return true; } /* @@ -683,15 +685,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, * send out all frames in the correct order. */ if (index_start < index_end) { - for (i = index_start; i < index_end; i++) - fn(&queue->entries[i]); + for (i = index_start; i < index_end; i++) { + if (fn(&queue->entries[i], data)) + return true; + } } else { - for (i = index_start; i < queue->limit; i++) - fn(&queue->entries[i]); + for (i = index_start; i < queue->limit; i++) { + if (fn(&queue->entries[i], data)) + return true; + } - for (i = 0; i < index_end; i++) - fn(&queue->entries[i]); + for (i = 0; i < index_end; i++) { + if (fn(&queue->entries[i], data)) + return true; + } } + + return false; } EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 6ae82009399..6b664525135 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -580,16 +580,22 @@ struct data_queue_desc { * @queue: Pointer to @data_queue * @start: &enum queue_index Pointer to start index * @end: &enum queue_index Pointer to end index + * @data: Data to pass to the callback function * @fn: The function to call for each &struct queue_entry * * This will walk through all entries in the queue, in chronological * order. This means it will start at the current @start pointer * and will walk through the queue until it reaches the @end pointer. + * + * If fn returns true for an entry rt2x00queue_for_each_entry will stop + * processing and return true as well. */ -void rt2x00queue_for_each_entry(struct data_queue *queue, +bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - void (*fn)(struct queue_entry *entry)); + void *data, + bool (*fn)(struct queue_entry *entry, + void *data)); /** * rt2x00queue_empty - Check if the queue is empty. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 94047e9b2ec..0bc8dccd0f0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } -static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) +static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -240,7 +240,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return; + return true; /* * USB devices cannot blindly pass the skb->len as the @@ -261,6 +261,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); } + + return false; } /* @@ -323,7 +325,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); } -static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) +static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -332,7 +334,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return; + return true; rt2x00lib_dmastart(entry); @@ -348,6 +350,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); } + + return false; } void rt2x00usb_kick_queue(struct data_queue *queue) @@ -358,12 +362,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_AC_BE: case QID_AC_BK: if (!rt2x00queue_empty(queue)) - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00queue_for_each_entry(queue, + Q_INDEX_DONE, + Q_INDEX, + NULL, rt2x00usb_kick_tx_entry); break; case QID_RX: if (!rt2x00queue_full(queue)) - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00queue_for_each_entry(queue, + Q_INDEX_DONE, + Q_INDEX, + NULL, rt2x00usb_kick_rx_entry); break; default: @@ -372,14 +382,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); -static void rt2x00usb_flush_entry(struct queue_entry *entry) +static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) - return; + return true; usb_kill_urb(entry_priv->urb); @@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry) if ((entry->queue->qid == QID_BEACON) && (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) usb_kill_urb(bcn_priv->guardian_urb); + + return false; } void rt2x00usb_flush_queue(struct data_queue *queue) @@ -396,7 +408,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) struct work_struct *completion; unsigned int i; - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, rt2x00usb_flush_entry); /* @@ -489,7 +501,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) entry->flags = 0; if (entry->queue->qid == QID_RX) - rt2x00usb_kick_rx_entry(entry); + rt2x00usb_kick_rx_entry(entry, NULL); } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); -- cgit v1.2.3-70-g09d2 From 15a533c47f9ebb8dec8e440275136cbf9c493a1f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:28:04 +0200 Subject: rt2x00: Use correct TBTT_SYNC config in AP mode This seems to fix problems with some powersaving clients since a positive value in TBTT_SYNC_CFG_TBTT_ADJUST introduces beacon skew, which is not wanted in AP mode. Also update the rest of the TBTT_SYNC config according to the legacy drivers in AP mode. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c6f5584128e..e0fa559bfa3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1245,6 +1245,25 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + if (conf->sync == TSF_SYNC_AP_NONE) { + /* + * Tune beacon queue transmit parameters for AP mode + */ + rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 0); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 1); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); + rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 0); + rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); + } else { + rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 4); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 2); + rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); + rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 16); + rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); + } } if (flags & CONFIG_UPDATE_MAC) { -- cgit v1.2.3-70-g09d2 From 961636ba17fa45b27ee4674430e1e775b8966b0e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:28:27 +0200 Subject: rt2x00: Update TX_SW_CFG2 init value Bring the TX_SW_CFG2 initialisation for rt305x devices in sync with the ralink legacy drivers. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e0fa559bfa3..0e2c0061cfd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2427,7 +2427,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) } else if (rt2800_is_305x_soc(rt2x00dev)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); } else if (rt2x00_rt(rt2x00dev, RT5390)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); -- cgit v1.2.3-70-g09d2 From 8da3efbb4a18be30ed03dd05af18d0b026b15173 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:28:50 +0200 Subject: rt2x00: Use TXOP_HTTXOP for beacons Use TXOP_HTTXOP for beacons to stay in sync with the legacy drivers. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index e8c0c3e92c2..a30f68c7fd7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -92,14 +92,15 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, /* * Determine IFS values - * - Use TXOP_BACKOFF for management frames + * - Use TXOP_BACKOFF for management frames except beacons * - Use TXOP_SIFS for fragment bursts * - Use TXOP_HTTXOP for everything else * * Note: rt2800 devices won't use CTS protection (if used) * for frames not transmitted with TXOP_HTTXOP */ - if (ieee80211_is_mgmt(hdr->frame_control)) + if (ieee80211_is_mgmt(hdr->frame_control) && + !ieee80211_is_beacon(hdr->frame_control)) txdesc->u.ht.txop = TXOP_BACKOFF; else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) txdesc->u.ht.txop = TXOP_SIFS; -- cgit v1.2.3-70-g09d2 From 0e0d39e5f3a3e59c8513b59d4feeeadcb93b707d Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 18 Apr 2011 15:29:12 +0200 Subject: rt2800usb: read TX_STA_FIFO asynchronously Trying to fix the "TX status report missed" warnings by reading the TX_STA_FIFO entries as quickly as possible. The TX_STA_FIFO is too small in hardware, thus reading it only from the workqueue is too slow and entries get lost. Start an asynchronous read of the TX_STA_FIFO directly from the TX URB completion callback (atomic context, thus it cannot use the blocking rt2800_register_read()). If the async read returns a valid FIFO entry, it is pushed into a larger FIFO inside struct rt2x00_dev, until rt2800_txdone() picks it up. A .tx_dma_done callback is added to struct rt2x00lib_ops to trigger the async read from the URB completion callback. Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 34 +++++++-------------- drivers/net/wireless/rt2x00/rt2800usb.c | 31 +++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00usb.c | 53 +++++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00usb.h | 15 ++++++++++ 5 files changed, 110 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 0e2c0061cfd..d79c8fd4113 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -730,34 +730,20 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; struct queue_entry *entry; u32 reg; - u8 pid; - int i; + u8 qid; - /* - * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO - * at most X times and also stop processing once the TX_STA_FIFO_VALID - * flag is not set anymore. - * - * The legacy drivers use X=TX_RING_SIZE but state in a comment - * that the TX_STA_FIFO stack has a size of 16. We stick to our - * tx ring size for now. - */ - for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { - rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); - if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) - break; + while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - /* - * Skip this entry when it contains an invalid - * queue identication number. + /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus + * qid is guaranteed to be one of the TX QIDs */ - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); - if (pid >= QID_RX) - continue; - - queue = rt2x00queue_get_tx_queue(rt2x00dev, pid); - if (unlikely(!queue)) + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + if (unlikely(!queue)) { + WARNING(rt2x00dev, "Got TX status for an unavailable " + "queue %u, dropping\n", qid); continue; + } /* * Inside each queue, we process each entry in a chronological diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f3ce5e854be..862430e600a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -98,6 +98,35 @@ static void rt2800usb_stop_queue(struct data_queue *queue) } } +static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, + int urb_status, u32 tx_status) +{ + if (urb_status) { + WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); + return; + } + + /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ + if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { + WARNING(rt2x00dev, "TX status FIFO overrun, " + "drop tx status report.\n"); + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + } else + rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, + rt2800usb_tx_sta_fifo_read_completed); + } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); +} + +static void rt2800usb_tx_dma_done(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + + rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, + rt2800usb_tx_sta_fifo_read_completed); +} + /* * Firmware functions */ @@ -565,6 +594,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); + __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); /* * Set the rssi offset. @@ -635,6 +665,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .kick_queue = rt2x00usb_kick_queue, .stop_queue = rt2800usb_stop_queue, .flush_queue = rt2x00usb_flush_queue, + .tx_dma_done = rt2800usb_tx_dma_done, .write_tx_desc = rt2800usb_write_tx_desc, .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 79c385accfa..e3b9b5146bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -571,6 +571,7 @@ struct rt2x00lib_ops { void (*kick_queue) (struct data_queue *queue); void (*stop_queue) (struct data_queue *queue); void (*flush_queue) (struct data_queue *queue); + void (*tx_dma_done) (struct queue_entry *entry); /* * TX control handlers diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 0bc8dccd0f0..5fbab6f1970 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -165,6 +165,56 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); + +struct rt2x00_async_read_data { + __le32 reg; + struct usb_ctrlrequest cr; + struct rt2x00_dev *rt2x00dev; + void (*callback)(struct rt2x00_dev *,int,u32); +}; + +static void rt2x00usb_register_read_async_cb(struct urb *urb) +{ + struct rt2x00_async_read_data *rd = urb->context; + rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg)); + kfree(urb->context); +} + +void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void (*callback)(struct rt2x00_dev*,int,u32)) +{ + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); + struct urb *urb; + struct rt2x00_async_read_data *rd; + + rd = kmalloc(sizeof(*rd), GFP_ATOMIC); + if (!rd) + return; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree(rd); + return; + } + + rd->rt2x00dev = rt2x00dev; + rd->callback = callback; + rd->cr.bRequestType = USB_VENDOR_REQUEST_IN; + rd->cr.bRequest = USB_MULTI_READ; + rd->cr.wValue = 0; + rd->cr.wIndex = cpu_to_le16(offset); + rd->cr.wLength = cpu_to_le16(sizeof(u32)); + + usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0), + (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg), + rt2x00usb_register_read_async_cb, rd); + if (usb_submit_urb(urb, GFP_ATOMIC) < 0) + kfree(rd); + usb_free_urb(urb); +} +EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async); + /* * TX data handlers. */ @@ -212,6 +262,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + if (rt2x00dev->ops->lib->tx_dma_done) + rt2x00dev->ops->lib->tx_dma_done(entry); + /* * Report the frame as DMA done */ diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 6aaf51fc7ad..e3faca6d2a4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -345,6 +345,21 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, const struct rt2x00_field32 field, u32 *reg); +/** + * rt2x00usb_register_read_async - Asynchronously read 32bit register word + * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * @offset: Register offset + * @callback: Functon to call when read completes. + * + * Submit a control URB to read a 32bit register. This safe to + * be called from atomic context. The callback will be called + * when the URB completes. Otherwise the function is similar + * to rt2x00usb_register_read(). + */ +void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void (*callback)(struct rt2x00_dev*,int,u32)); + /* * Radio handlers */ -- cgit v1.2.3-70-g09d2 From 75256f0348d38f414b7ac50ac78d4a4532bb6762 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 18 Apr 2011 15:29:38 +0200 Subject: rt2x00: fix queue timeout checks Add a timestamp to each queue entry which is updated whenever the status of the entry changes, and remove the per-queue timestamps. The previous check was incorrect and caused both false positives and false negatives. With the corrected check it comes apparent that the TX status usually times out on rt2800usb unless there is sufficient traffic (i.e. the next TX will complete the previous TX status). Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2x00lib.h | 6 +++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 11 +++++------ drivers/net/wireless/rt2x00/rt2x00queue.h | 23 +++++++++++++---------- drivers/net/wireless/rt2x00/rt2x00usb.c | 20 ++++++++++++++++++-- 5 files changed, 43 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index af25b0152cb..2e490e0998d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -225,7 +225,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); void rt2x00lib_dmastart(struct queue_entry *entry) { set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + rt2x00queue_index_inc(entry, Q_INDEX); } EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); @@ -233,7 +233,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry) { set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags); clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); + rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE); } EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); @@ -392,7 +392,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + rt2x00queue_index_inc(entry, Q_INDEX_DONE); /* * If the data queue was below the threshold before the txdone @@ -559,7 +559,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry) submit_entry: entry->flags = 0; - rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + rt2x00queue_index_inc(entry, Q_INDEX_DONE); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00dev->ops->lib->clear_entry(entry); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index bbee2cd4099..57ede6ccf40 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -175,14 +175,14 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, /** * rt2x00queue_index_inc - Index incrementation function - * @queue: Queue (&struct data_queue) to perform the action on. + * @entry: Queue entry (&struct queue_entry) to perform the action on. * @index: Index type (&enum queue_index) to perform the action on. * - * This function will increase the requested index on the queue, + * This function will increase the requested index on the entry's queue, * it will grab the appropriate locks and handle queue overflow events by * resetting the index to the start of the queue. */ -void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); +void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index); /** * rt2x00queue_init_queues - Initialize all data queues diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 458bb489bc7..df8817fed09 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -561,7 +561,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, set_bit(ENTRY_DATA_PENDING, &entry->flags); - rt2x00queue_index_inc(queue, Q_INDEX); + rt2x00queue_index_inc(entry, Q_INDEX); rt2x00queue_write_tx_descriptor(entry, &txdesc); rt2x00queue_kick_tx_queue(queue, &txdesc); @@ -727,8 +727,9 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, } EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); -void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) +void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) { + struct data_queue *queue = entry->queue; unsigned long irqflags; if (unlikely(index >= Q_INDEX_MAX)) { @@ -743,7 +744,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) if (queue->index[index] >= queue->limit) queue->index[index] = 0; - queue->last_action[index] = jiffies; + entry->last_action = jiffies; if (index == Q_INDEX) { queue->length++; @@ -969,10 +970,8 @@ static void rt2x00queue_reset(struct data_queue *queue) queue->count = 0; queue->length = 0; - for (i = 0; i < Q_INDEX_MAX; i++) { + for (i = 0; i < Q_INDEX_MAX; i++) queue->index[i] = 0; - queue->last_action[i] = jiffies; - } spin_unlock_irqrestore(&queue->index_lock, irqflags); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 6b664525135..36f4d03eff6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -364,6 +364,7 @@ enum queue_entry_flags { * struct queue_entry: Entry inside the &struct data_queue * * @flags: Entry flags, see &enum queue_entry_flags. + * @last_action: Timestamp of last change. * @queue: The data queue (&struct data_queue) to which this entry belongs. * @skb: The buffer which is currently being transmitted (for TX queue), * or used to directly recieve data in (for RX queue). @@ -373,6 +374,7 @@ enum queue_entry_flags { */ struct queue_entry { unsigned long flags; + unsigned long last_action; struct data_queue *queue; @@ -463,7 +465,6 @@ struct data_queue { unsigned short threshold; unsigned short length; unsigned short index[Q_INDEX_MAX]; - unsigned long last_action[Q_INDEX_MAX]; unsigned short txop; unsigned short aifs; @@ -635,22 +636,24 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) /** * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports - * @queue: Queue to check. + * @entry: Queue entry to check. */ -static inline int rt2x00queue_status_timeout(struct data_queue *queue) +static inline int rt2x00queue_status_timeout(struct queue_entry *entry) { - return time_after(queue->last_action[Q_INDEX_DMA_DONE], - queue->last_action[Q_INDEX_DONE] + (HZ / 10)); + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); } /** - * rt2x00queue_timeout - Check if a timeout occured for DMA transfers - * @queue: Queue to check. + * rt2x00queuedma__timeout - Check if a timeout occured for DMA transfers + * @entry: Queue entry to check. */ -static inline int rt2x00queue_dma_timeout(struct data_queue *queue) +static inline int rt2x00queue_dma_timeout(struct queue_entry *entry) { - return time_after(queue->last_action[Q_INDEX], - queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return false; + return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); } /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 5fbab6f1970..14736e21794 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -521,15 +521,31 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); } +static int rt2x00usb_status_timeout(struct data_queue *queue) +{ + struct queue_entry *entry; + + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + return rt2x00queue_status_timeout(entry); +} + +static int rt2x00usb_dma_timeout(struct data_queue *queue) +{ + struct queue_entry *entry; + + entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE); + return rt2x00queue_dma_timeout(entry); +} + void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; tx_queue_for_each(rt2x00dev, queue) { if (!rt2x00queue_empty(queue)) { - if (rt2x00queue_dma_timeout(queue)) + if (rt2x00usb_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00queue_status_timeout(queue)) + if (rt2x00usb_status_timeout(queue)) rt2x00usb_watchdog_tx_status(queue); } } -- cgit v1.2.3-70-g09d2 From 6e6d6932a3f525d734f6c2f5845e9cadfaeddce9 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 18 Apr 2011 15:30:01 +0200 Subject: rt2800usb: handle TX status timeouts The watchdog just triggers rt2800usb_work_txdone() when it detects a TX status timeout, thus rt2800usb_work_txdone() needs to handle this case. Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 862430e600a..69004b96812 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -449,11 +449,14 @@ static void rt2800usb_work_txdone(struct work_struct *work) while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + else if (rt2x00queue_status_timeout(entry)) + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); + else break; - - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); } } } -- cgit v1.2.3-70-g09d2 From f0187a1987ed6524518ff2a533eaf8394ac1a500 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 18 Apr 2011 15:30:36 +0200 Subject: rt2800usb: add timer to handle TX_STA_FIFO TX status is reported by the hardware when a packet has been sent (or after TX failed after possible retries), which is some time after the DMA completion. Since the rt2800usb hardware can not signal interrupts we have to use a timer, otherwise the TX status would only be read by the next packet's TX DMA completion, or by the watchdog thread. Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 41 ++++++++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2x00.h | 6 +++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 1 + drivers/net/wireless/rt2x00/rt2x00usb.c | 5 +++- 4 files changed, 51 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 69004b96812..20059727ef8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -98,6 +98,22 @@ static void rt2800usb_stop_queue(struct data_queue *queue) } } +/* + * test if there is an entry in any TX queue for which DMA is done + * but the TX status has not been returned yet + */ +static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + tx_queue_for_each(rt2x00dev, queue) { + if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != + rt2x00queue_get_entry(queue, Q_INDEX_DONE)) + return true; + } + return false; +} + static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { @@ -115,8 +131,11 @@ static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, } else rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, rt2800usb_tx_sta_fifo_read_completed); - } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) + } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + } else if (rt2800usb_txstatus_pending(rt2x00dev)) { + mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); + } } static void rt2800usb_tx_dma_done(struct queue_entry *entry) @@ -127,6 +146,14 @@ static void rt2800usb_tx_dma_done(struct queue_entry *entry) rt2800usb_tx_sta_fifo_read_completed); } +static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + + rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, + rt2800usb_tx_sta_fifo_read_completed); +} + /* * Firmware functions */ @@ -459,6 +486,14 @@ static void rt2800usb_work_txdone(struct work_struct *work) break; } } + + /* + * The hw may delay sending the packet after DMA complete + * if the medium is busy, thus the TX_STA_FIFO entry is + * also delayed -> use a timer to retrieve it. + */ + if (rt2800usb_txstatus_pending(rt2x00dev)) + mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); } /* @@ -599,6 +634,10 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); + setup_timer(&rt2x00dev->txstatus_timer, + rt2800usb_tx_sta_fifo_timeout, + (unsigned long) rt2x00dev); + /* * Set the rssi offset. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index e3b9b5146bf..8f37121bb83 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -923,6 +924,11 @@ struct rt2x00_dev { */ DECLARE_KFIFO_PTR(txstatus_fifo, u32); + /* + * Timer to ensure tx status reports are read (rt2800usb). + */ + struct timer_list txstatus_timer; + /* * Tasklet for processing tx status reports (rt2800pci). */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 2e490e0998d..7776d9f1f29 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1071,6 +1071,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) /* * Stop all work. */ + del_timer_sync(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->intf_work); if (rt2x00_is_usb(rt2x00dev)) { cancel_work_sync(&rt2x00dev->rxdone_work); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 14736e21794..34b8a887831 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -280,7 +280,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Schedule the delayed work for reading the TX status * from the device. */ - queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) || + !kfifo_is_empty(&rt2x00dev->txstatus_fifo)) + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) @@ -816,6 +818,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); + init_timer(&rt2x00dev->txstatus_timer); retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) -- cgit v1.2.3-70-g09d2 From 152a599274b15028604e24ae2d9c9d7f49853977 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 18 Apr 2011 15:31:02 +0200 Subject: rt2x00: Decrease association time for USB devices When powersaving is enabled, assocaition times are very high (for WPA2 networks, the time can easily be around the 3 seconds). This is caused, because the flushing of the queues takes too much time. Without the flushing callback mac80211 assumes a timeout of 100ms while scanning. Limit all flush waiting loops to the same maximum. We can apply this maximum by passing the drop status to the driver, which makes sure the driver performs extra actions during the waiting for the queue to become empty. After these changes, association times fall within the healthy range of ~0.6 seconds with powersaving enabled. The difference between association time between powersaving enabled and disabled is now only ~0.1 second (which can also be due to the measuring method). Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 1 + drivers/net/wireless/rt2x00/rt2500pci.c | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 2 +- drivers/net/wireless/rt2x00/rt2x00pci.c | 9 +++++++++ drivers/net/wireless/rt2x00/rt2x00pci.h | 10 ++++++++++ drivers/net/wireless/rt2x00/rt2x00queue.c | 19 +++++-------------- drivers/net/wireless/rt2x00/rt2x00usb.c | 9 +++++---- drivers/net/wireless/rt2x00/rt2x00usb.h | 8 +++++--- drivers/net/wireless/rt2x00/rt61pci.c | 1 + 10 files changed, 39 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5d1654a8bda..6b7206eddfa 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1740,6 +1740,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .start_queue = rt2400pci_start_queue, .kick_queue = rt2400pci_kick_queue, .stop_queue = rt2400pci_stop_queue, + .flush_queue = rt2x00pci_flush_queue, .write_tx_desc = rt2400pci_write_tx_desc, .write_beacon = rt2400pci_write_beacon, .fill_rxdone = rt2400pci_fill_rxdone, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3da954e1b4a..82e8012c7c2 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -2033,6 +2033,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .start_queue = rt2500pci_start_queue, .kick_queue = rt2500pci_kick_queue, .stop_queue = rt2500pci_stop_queue, + .flush_queue = rt2x00pci_flush_queue, .write_tx_desc = rt2500pci_write_tx_desc, .write_beacon = rt2500pci_write_beacon, .fill_rxdone = rt2500pci_fill_rxdone, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4241f194384..d2fe5fd6f1e 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1057,6 +1057,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .start_queue = rt2800pci_start_queue, .kick_queue = rt2800pci_kick_queue, .stop_queue = rt2800pci_stop_queue, + .flush_queue = rt2x00pci_flush_queue, .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8f37121bb83..dcdc50d27ea 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -571,7 +571,7 @@ struct rt2x00lib_ops { void (*start_queue) (struct data_queue *queue); void (*kick_queue) (struct data_queue *queue); void (*stop_queue) (struct data_queue *queue); - void (*flush_queue) (struct data_queue *queue); + void (*flush_queue) (struct data_queue *queue, bool drop); void (*tx_dma_done) (struct queue_entry *entry); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 9649bd0cd71..695aecf6bd0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -99,6 +99,15 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) +{ + unsigned int i; + + for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) + msleep(10); +} +EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); + /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 07961b8b369..5d5887426f7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -107,6 +107,16 @@ struct queue_entry_priv_pci { */ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); +/** + * rt2x00pci_flush_queue - Flush data queue + * @queue: Data queue to stop + * @drop: True to drop all pending frames. + * + * This will wait for a maximum of 100ms, waiting for the queues + * to become empty. + */ +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); + /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index df8817fed09..0d79278a0a1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -849,7 +849,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) { - unsigned int i; bool started; bool tx_queue = (queue->qid == QID_AC_VO) || @@ -884,20 +883,12 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) } /* - * Check if driver supports flushing, we can only guarentee - * full support for flushing if the driver is able - * to cancel all pending frames (drop = true). - */ - if (drop && queue->rt2x00dev->ops->lib->flush_queue) - queue->rt2x00dev->ops->lib->flush_queue(queue); - - /* - * When we don't want to drop any frames, or when - * the driver doesn't fully flush the queue correcly, - * we must wait for the queue to become empty. + * Check if driver supports flushing, if that is the case we can + * defer the flushing to the driver. Otherwise we must use the + * alternative which just waits for the queue to become empty. */ - for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++) - msleep(10); + if (likely(queue->rt2x00dev->ops->lib->flush_queue)) + queue->rt2x00dev->ops->lib->flush_queue(queue, drop); /* * The queue flush has failed... diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 34b8a887831..9957579248c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -458,13 +458,14 @@ static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) return false; } -void rt2x00usb_flush_queue(struct data_queue *queue) +void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) { struct work_struct *completion; unsigned int i; - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, - rt2x00usb_flush_entry); + if (drop) + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, + rt2x00usb_flush_entry); /* * Obtain the queue completion handler @@ -483,7 +484,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) return; } - for (i = 0; i < 20; i++) { + for (i = 0; i < 10; i++) { /* * Check if the driver is already done, otherwise we * have to sleep a little while to give the driver/hw diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index e3faca6d2a4..6aeba71b665 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -404,11 +404,13 @@ void rt2x00usb_kick_queue(struct data_queue *queue); /** * rt2x00usb_flush_queue - Flush data queue * @queue: Data queue to stop + * @drop: True to drop all pending frames. * - * This will walk through all entries of the queue and kill all - * URB's which were send to the device. + * This will walk through all entries of the queue and will optionally + * kill all URB's which were send to the device, or at least wait until + * they have been returned from the device.. */ -void rt2x00usb_flush_queue(struct data_queue *queue); +void rt2x00usb_flush_queue(struct data_queue *queue, bool drop); /** * rt2x00usb_watchdog - Watchdog for USB communication diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index c16c1501df1..35c5d20105a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -3003,6 +3003,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .start_queue = rt61pci_start_queue, .kick_queue = rt61pci_kick_queue, .stop_queue = rt61pci_stop_queue, + .flush_queue = rt2x00pci_flush_queue, .write_tx_desc = rt61pci_write_tx_desc, .write_beacon = rt61pci_write_beacon, .clear_beacon = rt61pci_clear_beacon, -- cgit v1.2.3-70-g09d2 From 7a5a681a7df7d844b52f82a4388e078071eb883e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:31:31 +0200 Subject: rt2x00: Always inline rt2x00pci_enable_interrupt This allows the compiler to perform the necessary bitfield calculations during compile time instead of run time and thus reduces the number of instructions to run during each tasklet invocation. This should improve performance in the RX hotpath. This comes at the cost of a slight increase in the module size (for example rt2800pci): Before: text data bss dec hex filename 14133 832 4 14969 3a79 drivers/net/wireless/rt2x00/rt2800pci.ko After: text data bss dec hex filename 14149 832 4 14985 3a89 drivers/net/wireless/rt2x00/rt2800pci.ko Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt2500pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt2800pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 6b7206eddfa..01e951717f0 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1314,8 +1314,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, - struct rt2x00_field32 irq_field) +static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { u32 reg; diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 82e8012c7c2..c8deeeb9d81 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1446,8 +1446,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, - struct rt2x00_field32 irq_field) +static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { u32 reg; diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index d2fe5fd6f1e..46c3e3c83e3 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -768,8 +768,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) return !max_tx_done; } -static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, - struct rt2x00_field32 irq_field) +static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { u32 reg; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 35c5d20105a..264508f31a2 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2260,8 +2260,8 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } -static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, - struct rt2x00_field32 irq_field) +static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { u32 reg; -- cgit v1.2.3-70-g09d2 From ce2919c9fffe2aa52f9c3e327176d03764dbf9b5 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:31:50 +0200 Subject: rt2x00: Linksys WUSB600N rev2 is a RT3572 device. Move the USB ID entry from the unknown devices to the list of RT35xx based devices. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 20059727ef8..1bb9a7d09de 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -983,6 +983,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Linksys */ { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ @@ -1041,7 +1042,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Linksys */ { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Motorola */ { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ovislink */ -- cgit v1.2.3-70-g09d2 From e01ae27f8ce6bd3ee26ef33c704f62449ce8233b Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:32:13 +0200 Subject: rt2x00: Allow dynamic addition of PCI/USB IDs. Both USB and PCI drivers allow a system administrator to dynamically add USB/PCI IDs to the device table that a driver supports via the /sys/bus/{usb,pci,pci_express}/drivers//new_id files. However, for the rt2x00 drivers using this method currently crashes the system with a NULL pointer failure. This is due to the set-up of rt2x00 where the probe functions require a rt2x00_ops structure in the driver_info field of the probed device. As this field is empty for the dynamically added devices this fails for these devices. Fix this by introducing driver-specific probe wrappers that do nothing but calling the bus-specific probe functions with the rt2x00_ops structure as an argument, rather than depending on the driver_info field. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 11 +- drivers/net/wireless/rt2x00/rt2500pci.c | 10 +- drivers/net/wireless/rt2x00/rt2500usb.c | 70 ++--- drivers/net/wireless/rt2x00/rt2800pci.c | 58 +++-- drivers/net/wireless/rt2x00/rt2800usb.c | 440 ++++++++++++++++---------------- drivers/net/wireless/rt2x00/rt2x00pci.c | 3 +- drivers/net/wireless/rt2x00/rt2x00pci.h | 2 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 3 +- drivers/net/wireless/rt2x00/rt2x00usb.h | 8 +- drivers/net/wireless/rt2x00/rt61pci.c | 14 +- drivers/net/wireless/rt2x00/rt73usb.c | 154 +++++------ 11 files changed, 404 insertions(+), 369 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 01e951717f0..d4acdde7c75 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1802,10 +1802,11 @@ static const struct rt2x00_ops rt2400pci_ops = { * RT2400pci module information. */ static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = { - { PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) }, + { PCI_DEVICE(0x1814, 0x0101) }, { 0, } }; + MODULE_AUTHOR(DRV_PROJECT); MODULE_VERSION(DRV_VERSION); MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); @@ -1813,10 +1814,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards"); MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); MODULE_LICENSE("GPL"); +static int rt2400pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + return rt2x00pci_probe(pci_dev, &rt2400pci_ops); +} + static struct pci_driver rt2400pci_driver = { .name = KBUILD_MODNAME, .id_table = rt2400pci_device_table, - .probe = rt2x00pci_probe, + .probe = rt2400pci_probe, .remove = __devexit_p(rt2x00pci_remove), .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c8deeeb9d81..15f5649e2ca 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -2095,7 +2095,7 @@ static const struct rt2x00_ops rt2500pci_ops = { * RT2500pci module information. */ static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = { - { PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) }, + { PCI_DEVICE(0x1814, 0x0201) }, { 0, } }; @@ -2106,10 +2106,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards"); MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); MODULE_LICENSE("GPL"); +static int rt2500pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + return rt2x00pci_probe(pci_dev, &rt2500pci_ops); +} + static struct pci_driver rt2500pci_driver = { .name = KBUILD_MODNAME, .id_table = rt2500pci_device_table, - .probe = rt2x00pci_probe, + .probe = rt2500pci_probe, .remove = __devexit_p(rt2x00pci_remove), .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index dbbd8bc851f..d88c36712ef 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1904,54 +1904,54 @@ static const struct rt2x00_ops rt2500usb_ops = { */ static struct usb_device_id rt2500usb_device_table[] = { /* ASUS */ - { USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0b05, 0x1706) }, + { USB_DEVICE(0x0b05, 0x1707) }, /* Belkin */ - { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x050d, 0x7050) }, + { USB_DEVICE(0x050d, 0x7051) }, /* Cisco Systems */ - { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x13b1, 0x000d) }, + { USB_DEVICE(0x13b1, 0x0011) }, + { USB_DEVICE(0x13b1, 0x001a) }, /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c02) }, /* D-LINK */ - { USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x2001, 0x3c00) }, /* Gigabyte */ - { USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x1044, 0x8001) }, + { USB_DEVICE(0x1044, 0x8007) }, /* Hercules */ - { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x06f8, 0xe000) }, /* Melco */ - { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0411, 0x005e) }, + { USB_DEVICE(0x0411, 0x0066) }, + { USB_DEVICE(0x0411, 0x0067) }, + { USB_DEVICE(0x0411, 0x008b) }, + { USB_DEVICE(0x0411, 0x0097) }, /* MSI */ - { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0db0, 0x6861) }, + { USB_DEVICE(0x0db0, 0x6865) }, + { USB_DEVICE(0x0db0, 0x6869) }, /* Ralink */ - { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x148f, 0x1706) }, + { USB_DEVICE(0x148f, 0x2570) }, + { USB_DEVICE(0x148f, 0x9020) }, /* Sagem */ - { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x079b, 0x004b) }, /* Siemens */ - { USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0681, 0x3c06) }, /* SMC */ - { USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0707, 0xee13) }, /* Spairon */ - { USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x114b, 0x0110) }, /* SURECOM */ - { USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0769, 0x11f3) }, /* Trust */ - { USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0eb0, 0x9020) }, /* VTech */ - { USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x0f88, 0x3012) }, /* Zinwell */ - { USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x5a57, 0x0260) }, { 0, } }; @@ -1962,10 +1962,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards"); MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); MODULE_LICENSE("GPL"); +static int rt2500usb_probe(struct usb_interface *usb_intf, + const struct usb_device_id *id) +{ + return rt2x00usb_probe(usb_intf, &rt2500usb_ops); +} + static struct usb_driver rt2500usb_driver = { .name = KBUILD_MODNAME, .id_table = rt2500usb_device_table, - .probe = rt2x00usb_probe, + .probe = rt2500usb_probe, .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 46c3e3c83e3..6f91a9ad4d3 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1117,36 +1117,36 @@ static const struct rt2x00_ops rt2800pci_ops = { */ #ifdef CONFIG_PCI static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { - { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x0601) }, + { PCI_DEVICE(0x1814, 0x0681) }, + { PCI_DEVICE(0x1814, 0x0701) }, + { PCI_DEVICE(0x1814, 0x0781) }, + { PCI_DEVICE(0x1814, 0x3090) }, + { PCI_DEVICE(0x1814, 0x3091) }, + { PCI_DEVICE(0x1814, 0x3092) }, + { PCI_DEVICE(0x1432, 0x7708) }, + { PCI_DEVICE(0x1432, 0x7727) }, + { PCI_DEVICE(0x1432, 0x7728) }, + { PCI_DEVICE(0x1432, 0x7738) }, + { PCI_DEVICE(0x1432, 0x7748) }, + { PCI_DEVICE(0x1432, 0x7758) }, + { PCI_DEVICE(0x1432, 0x7768) }, + { PCI_DEVICE(0x1462, 0x891a) }, + { PCI_DEVICE(0x1a3b, 0x1059) }, #ifdef CONFIG_RT2800PCI_RT33XX - { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3390) }, #endif #ifdef CONFIG_RT2800PCI_RT35XX - { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1432, 0x7711) }, + { PCI_DEVICE(0x1432, 0x7722) }, + { PCI_DEVICE(0x1814, 0x3060) }, + { PCI_DEVICE(0x1814, 0x3062) }, + { PCI_DEVICE(0x1814, 0x3562) }, + { PCI_DEVICE(0x1814, 0x3592) }, + { PCI_DEVICE(0x1814, 0x3593) }, #endif #ifdef CONFIG_RT2800PCI_RT53XX - { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x5390) }, #endif { 0, } }; @@ -1182,10 +1182,16 @@ static struct platform_driver rt2800soc_driver = { #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ #ifdef CONFIG_PCI +static int rt2800pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + return rt2x00pci_probe(pci_dev, &rt2800pci_ops); +} + static struct pci_driver rt2800pci_driver = { .name = KBUILD_MODNAME, .id_table = rt2800pci_device_table, - .probe = rt2x00pci_probe, + .probe = rt2800pci_probe, .remove = __devexit_p(rt2x00pci_remove), .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 1bb9a7d09de..6f7c1617457 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -768,230 +768,230 @@ static const struct rt2x00_ops rt2800usb_ops = { */ static struct usb_device_id rt2800usb_device_table[] = { /* Abocom */ - { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x2870) }, + { USB_DEVICE(0x07b8, 0x2770) }, + { USB_DEVICE(0x07b8, 0x3070) }, + { USB_DEVICE(0x07b8, 0x3071) }, + { USB_DEVICE(0x07b8, 0x3072) }, + { USB_DEVICE(0x1482, 0x3c09) }, /* AirTies */ - { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1eda, 0x2310) }, /* Allwin */ - { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x2070) }, + { USB_DEVICE(0x8516, 0x2770) }, + { USB_DEVICE(0x8516, 0x2870) }, + { USB_DEVICE(0x8516, 0x3070) }, + { USB_DEVICE(0x8516, 0x3071) }, + { USB_DEVICE(0x8516, 0x3072) }, /* Alpha Networks */ - { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c2c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c06) }, + { USB_DEVICE(0x14b2, 0x3c07) }, + { USB_DEVICE(0x14b2, 0x3c09) }, + { USB_DEVICE(0x14b2, 0x3c12) }, + { USB_DEVICE(0x14b2, 0x3c23) }, + { USB_DEVICE(0x14b2, 0x3c25) }, + { USB_DEVICE(0x14b2, 0x3c27) }, + { USB_DEVICE(0x14b2, 0x3c28) }, + { USB_DEVICE(0x14b2, 0x3c2c) }, /* Amit */ - { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x15c5, 0x0008) }, /* Askey */ - { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1690, 0x0740) }, /* ASUS */ - { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0b05, 0x1731) }, + { USB_DEVICE(0x0b05, 0x1732) }, + { USB_DEVICE(0x0b05, 0x1742) }, + { USB_DEVICE(0x0b05, 0x1784) }, + { USB_DEVICE(0x1761, 0x0b05) }, /* AzureWave */ - { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3247) }, + { USB_DEVICE(0x13d3, 0x3273) }, + { USB_DEVICE(0x13d3, 0x3305) }, + { USB_DEVICE(0x13d3, 0x3307) }, + { USB_DEVICE(0x13d3, 0x3321) }, /* Belkin */ - { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x050d, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x050d, 0x8053) }, + { USB_DEVICE(0x050d, 0x805c) }, + { USB_DEVICE(0x050d, 0x815c) }, + { USB_DEVICE(0x050d, 0x825b) }, + { USB_DEVICE(0x050d, 0x935a) }, + { USB_DEVICE(0x050d, 0x935b) }, /* Buffalo */ - { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0411, 0x01a2), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0411, 0x00e8) }, + { USB_DEVICE(0x0411, 0x016f) }, + { USB_DEVICE(0x0411, 0x01a2) }, /* Corega */ - { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07aa, 0x002f) }, + { USB_DEVICE(0x07aa, 0x003c) }, + { USB_DEVICE(0x07aa, 0x003f) }, + { USB_DEVICE(0x18c5, 0x0012) }, /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c09) }, + { USB_DEVICE(0x07d1, 0x3c0a) }, + { USB_DEVICE(0x07d1, 0x3c0d) }, + { USB_DEVICE(0x07d1, 0x3c0e) }, + { USB_DEVICE(0x07d1, 0x3c0f) }, + { USB_DEVICE(0x07d1, 0x3c11) }, + { USB_DEVICE(0x07d1, 0x3c16) }, /* Draytek */ - { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07fa, 0x7712) }, /* Edimax */ - { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x7392, 0x7711) }, + { USB_DEVICE(0x7392, 0x7717) }, + { USB_DEVICE(0x7392, 0x7718) }, /* Encore */ - { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x203d, 0x1480) }, + { USB_DEVICE(0x203d, 0x14a9) }, /* EnGenius */ - { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9701) }, + { USB_DEVICE(0x1740, 0x9702) }, + { USB_DEVICE(0x1740, 0x9703) }, + { USB_DEVICE(0x1740, 0x9705) }, + { USB_DEVICE(0x1740, 0x9706) }, + { USB_DEVICE(0x1740, 0x9707) }, + { USB_DEVICE(0x1740, 0x9708) }, + { USB_DEVICE(0x1740, 0x9709) }, /* Gemtek */ - { USB_DEVICE(0x15a9, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x15a9, 0x0012) }, /* Gigabyte */ - { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1044, 0x800b) }, + { USB_DEVICE(0x1044, 0x800d) }, /* Hawking */ - { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e66, 0x0001) }, + { USB_DEVICE(0x0e66, 0x0003) }, + { USB_DEVICE(0x0e66, 0x0009) }, + { USB_DEVICE(0x0e66, 0x000b) }, + { USB_DEVICE(0x0e66, 0x0013) }, + { USB_DEVICE(0x0e66, 0x0017) }, + { USB_DEVICE(0x0e66, 0x0018) }, /* I-O DATA */ - { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x04bb, 0x0945) }, + { USB_DEVICE(0x04bb, 0x0947) }, + { USB_DEVICE(0x04bb, 0x0948) }, /* Linksys */ - { USB_DEVICE(0x13b1, 0x0031), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13b1, 0x0031) }, + { USB_DEVICE(0x1737, 0x0070) }, + { USB_DEVICE(0x1737, 0x0071) }, /* Logitec */ - { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0789, 0x0162) }, + { USB_DEVICE(0x0789, 0x0163) }, + { USB_DEVICE(0x0789, 0x0164) }, + { USB_DEVICE(0x0789, 0x0166) }, /* Motorola */ - { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x100d, 0x9031) }, /* MSI */ - { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x3820) }, + { USB_DEVICE(0x0db0, 0x3821) }, + { USB_DEVICE(0x0db0, 0x3822) }, + { USB_DEVICE(0x0db0, 0x3870) }, + { USB_DEVICE(0x0db0, 0x3871) }, + { USB_DEVICE(0x0db0, 0x6899) }, + { USB_DEVICE(0x0db0, 0x821a) }, + { USB_DEVICE(0x0db0, 0x822a) }, + { USB_DEVICE(0x0db0, 0x822b) }, + { USB_DEVICE(0x0db0, 0x822c) }, + { USB_DEVICE(0x0db0, 0x870a) }, + { USB_DEVICE(0x0db0, 0x871a) }, + { USB_DEVICE(0x0db0, 0x871b) }, + { USB_DEVICE(0x0db0, 0x871c) }, + { USB_DEVICE(0x0db0, 0x899a) }, /* Para */ - { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x20b8, 0x8888) }, /* Pegatron */ - { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1d4d, 0x000c) }, + { USB_DEVICE(0x1d4d, 0x000e) }, + { USB_DEVICE(0x1d4d, 0x0011) }, /* Philips */ - { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0471, 0x200f) }, /* Planex */ - { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x2019, 0xab25) }, + { USB_DEVICE(0x2019, 0xed06) }, /* Quanta */ - { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1a32, 0x0304) }, /* Ralink */ - { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x2070) }, + { USB_DEVICE(0x148f, 0x2770) }, + { USB_DEVICE(0x148f, 0x2870) }, + { USB_DEVICE(0x148f, 0x3070) }, + { USB_DEVICE(0x148f, 0x3071) }, + { USB_DEVICE(0x148f, 0x3072) }, /* Samsung */ - { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x04e8, 0x2018) }, /* Siemens */ - { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x129b, 0x1828) }, /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0017) }, + { USB_DEVICE(0x0df6, 0x002b) }, + { USB_DEVICE(0x0df6, 0x002c) }, + { USB_DEVICE(0x0df6, 0x002d) }, + { USB_DEVICE(0x0df6, 0x0039) }, + { USB_DEVICE(0x0df6, 0x003b) }, + { USB_DEVICE(0x0df6, 0x003d) }, + { USB_DEVICE(0x0df6, 0x003e) }, + { USB_DEVICE(0x0df6, 0x003f) }, + { USB_DEVICE(0x0df6, 0x0040) }, + { USB_DEVICE(0x0df6, 0x0042) }, + { USB_DEVICE(0x0df6, 0x0047) }, + { USB_DEVICE(0x0df6, 0x0048) }, /* SMC */ - { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0x6618) }, + { USB_DEVICE(0x083a, 0x7511) }, + { USB_DEVICE(0x083a, 0x7512) }, + { USB_DEVICE(0x083a, 0x7522) }, + { USB_DEVICE(0x083a, 0x8522) }, + { USB_DEVICE(0x083a, 0xa618) }, + { USB_DEVICE(0x083a, 0xa701) }, + { USB_DEVICE(0x083a, 0xa702) }, + { USB_DEVICE(0x083a, 0xa703) }, + { USB_DEVICE(0x083a, 0xb522) }, /* Sparklan */ - { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x15a9, 0x0006) }, /* Sweex */ - { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x177f, 0x0302) }, /* U-Media */ - { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x157e, 0x3013), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x157e, 0x300e) }, + { USB_DEVICE(0x157e, 0x3013) }, /* ZCOM */ - { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0cde, 0x0022) }, + { USB_DEVICE(0x0cde, 0x0025) }, /* Zinwell */ - { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x5a57, 0x0280) }, + { USB_DEVICE(0x5a57, 0x0282) }, + { USB_DEVICE(0x5a57, 0x0283) }, + { USB_DEVICE(0x5a57, 0x5257) }, /* Zyxel */ - { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0586, 0x341e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0586, 0x3416) }, + { USB_DEVICE(0x0586, 0x3418) }, + { USB_DEVICE(0x0586, 0x341e) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ - { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3370) }, + { USB_DEVICE(0x148f, 0x8070) }, /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0050) }, #endif #ifdef CONFIG_RT2800USB_RT35XX /* Allwin */ - { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3572) }, /* Askey */ - { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1690, 0x0744) }, /* Cisco */ - { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x167b, 0x4001) }, /* EnGenius */ - { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9801) }, /* I-O DATA */ - { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x04bb, 0x0944) }, /* Linksys */ - { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13b1, 0x002f) }, + { USB_DEVICE(0x1737, 0x0079) }, /* Ralink */ - { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3572) }, /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0041) }, /* Toshiba */ - { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0930, 0x0a07) }, /* Zinwell */ - { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x5a57, 0x0284) }, #endif #ifdef CONFIG_RT2800USB_UNKNOWN /* @@ -999,73 +999,73 @@ static struct usb_device_id rt2800usb_device_table[] = { * vendor linux driver). */ /* Alpha Networks */ - { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c08) }, + { USB_DEVICE(0x14b2, 0x3c11) }, /* Amigo */ - { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0e0b, 0x9031) }, + { USB_DEVICE(0x0e0b, 0x9041) }, /* ASUS */ - { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0b05, 0x1760) }, + { USB_DEVICE(0x0b05, 0x1761) }, + { USB_DEVICE(0x0b05, 0x1790) }, /* AzureWave */ - { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3262) }, + { USB_DEVICE(0x13d3, 0x3284) }, + { USB_DEVICE(0x13d3, 0x3322) }, /* Belkin */ - { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x050d, 0x825a) }, /* Buffalo */ - { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0411, 0x012e) }, + { USB_DEVICE(0x0411, 0x0148) }, + { USB_DEVICE(0x0411, 0x0150) }, + { USB_DEVICE(0x0411, 0x015d) }, /* Corega */ - { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07aa, 0x0041) }, + { USB_DEVICE(0x07aa, 0x0042) }, + { USB_DEVICE(0x18c5, 0x0008) }, /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c0b) }, + { USB_DEVICE(0x07d1, 0x3c13) }, + { USB_DEVICE(0x07d1, 0x3c15) }, + { USB_DEVICE(0x07d1, 0x3c17) }, /* Edimax */ - { USB_DEVICE(0x7392, 0x4085), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x7392, 0x4085) }, /* Encore */ - { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x203d, 0x14a1) }, /* Gemtek */ - { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x15a9, 0x0010) }, /* Gigabyte */ - { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1044, 0x800c) }, /* LevelOne */ - { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x0605) }, + { USB_DEVICE(0x1740, 0x0615) }, /* Linksys */ - { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1737, 0x0077) }, + { USB_DEVICE(0x1737, 0x0078) }, /* Motorola */ - { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x100d, 0x9032) }, /* Ovislink */ - { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1b75, 0x3071) }, + { USB_DEVICE(0x1b75, 0x3072) }, /* Pegatron */ - { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x05a6, 0x0101) }, + { USB_DEVICE(0x1d4d, 0x0002) }, + { USB_DEVICE(0x1d4d, 0x0010) }, /* Planex */ - { USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x2019, 0x5201) }, + { USB_DEVICE(0x2019, 0xab24) }, /* Qcom */ - { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x18e8, 0x6259) }, /* SMC */ - { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xa512) }, + { USB_DEVICE(0x083a, 0xc522) }, + { USB_DEVICE(0x083a, 0xd522) }, + { USB_DEVICE(0x083a, 0xf511) }, /* Sweex */ - { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x177f, 0x0153) }, + { USB_DEVICE(0x177f, 0x0313) }, /* Zyxel */ - { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0586, 0x341a) }, #endif { 0, } }; @@ -1078,10 +1078,16 @@ MODULE_DEVICE_TABLE(usb, rt2800usb_device_table); MODULE_FIRMWARE(FIRMWARE_RT2870); MODULE_LICENSE("GPL"); +static int rt2800usb_probe(struct usb_interface *usb_intf, + const struct usb_device_id *id) +{ + return rt2x00usb_probe(usb_intf, &rt2800usb_ops); +} + static struct usb_driver rt2800usb_driver = { .name = KBUILD_MODNAME, .id_table = rt2800usb_device_table, - .probe = rt2x00usb_probe, + .probe = rt2800usb_probe, .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 695aecf6bd0..17148bb2442 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -251,9 +251,8 @@ exit: return -ENOMEM; } -int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) +int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) { - struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data; struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 5d5887426f7..e2c99f2b9a1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -126,7 +126,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); /* * PCI driver handlers. */ -int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); +int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); void rt2x00pci_remove(struct pci_dev *pci_dev); #ifdef CONFIG_PM int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 9957579248c..570184ee163 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -791,10 +791,9 @@ exit: } int rt2x00usb_probe(struct usb_interface *usb_intf, - const struct usb_device_id *id) + const struct rt2x00_ops *ops) { struct usb_device *usb_dev = interface_to_usbdev(usb_intf); - struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info; struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 6aeba71b665..52b09d2e11d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -34,12 +34,6 @@ interface_to_usbdev(intf); \ }) -/* - * This variable should be used with the - * usb_driver structure initialization. - */ -#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) - /* * For USB vendor requests we need to pass a timeout * time in ms, for this we use the REGISTER_TIMEOUT, @@ -433,7 +427,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); * USB driver handlers. */ int rt2x00usb_probe(struct usb_interface *usb_intf, - const struct usb_device_id *id); + const struct rt2x00_ops *ops); void rt2x00usb_disconnect(struct usb_interface *usb_intf); #ifdef CONFIG_PM int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 264508f31a2..c5dccdb2f17 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -3061,11 +3061,11 @@ static const struct rt2x00_ops rt61pci_ops = { */ static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = { /* RT2561s */ - { PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) }, + { PCI_DEVICE(0x1814, 0x0301) }, /* RT2561 v2 */ - { PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) }, + { PCI_DEVICE(0x1814, 0x0302) }, /* RT2661 */ - { PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) }, + { PCI_DEVICE(0x1814, 0x0401) }, { 0, } }; @@ -3080,10 +3080,16 @@ MODULE_FIRMWARE(FIRMWARE_RT2561s); MODULE_FIRMWARE(FIRMWARE_RT2661); MODULE_LICENSE("GPL"); +static int rt61pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + return rt2x00pci_probe(pci_dev, &rt61pci_ops); +} + static struct pci_driver rt61pci_driver = { .name = KBUILD_MODNAME, .id_table = rt61pci_device_table, - .probe = rt2x00pci_probe, + .probe = rt61pci_probe, .remove = __devexit_p(rt2x00pci_remove), .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index cdb026d076d..be3eb5e894e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2388,113 +2388,113 @@ static const struct rt2x00_ops rt73usb_ops = { */ static struct usb_device_id rt73usb_device_table[] = { /* AboCom */ - { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07b8, 0xb21b) }, + { USB_DEVICE(0x07b8, 0xb21c) }, + { USB_DEVICE(0x07b8, 0xb21d) }, + { USB_DEVICE(0x07b8, 0xb21e) }, + { USB_DEVICE(0x07b8, 0xb21f) }, /* AL */ - { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c10) }, /* Amigo */ - { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x148f, 0x9021) }, + { USB_DEVICE(0x0eb0, 0x9021) }, /* AMIT */ - { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x18c5, 0x0002) }, /* Askey */ - { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1690, 0x0722) }, /* ASUS */ - { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0b05, 0x1723) }, + { USB_DEVICE(0x0b05, 0x1724) }, /* Belkin */ - { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x050d, 0x705a) }, + { USB_DEVICE(0x050d, 0x905b) }, + { USB_DEVICE(0x050d, 0x905c) }, /* Billionton */ - { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1631, 0xc019) }, + { USB_DEVICE(0x08dd, 0x0120) }, /* Buffalo */ - { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x00d8) }, + { USB_DEVICE(0x0411, 0x00d9) }, + { USB_DEVICE(0x0411, 0x00f4) }, + { USB_DEVICE(0x0411, 0x0116) }, + { USB_DEVICE(0x0411, 0x0119) }, + { USB_DEVICE(0x0411, 0x0137) }, /* CEIVA */ - { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x178d, 0x02be) }, /* CNet */ - { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1371, 0x9022) }, + { USB_DEVICE(0x1371, 0x9032) }, /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c22) }, /* Corega */ - { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07aa, 0x002e) }, /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c03) }, + { USB_DEVICE(0x07d1, 0x3c04) }, + { USB_DEVICE(0x07d1, 0x3c06) }, + { USB_DEVICE(0x07d1, 0x3c07) }, /* Edimax */ - { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x7392, 0x7318) }, + { USB_DEVICE(0x7392, 0x7618) }, /* EnGenius */ - { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1740, 0x3701) }, /* Gemtek */ - { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x15a9, 0x0004) }, /* Gigabyte */ - { USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1044, 0x8008) }, + { USB_DEVICE(0x1044, 0x800a) }, /* Huawei-3Com */ - { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1472, 0x0009) }, /* Hercules */ - { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x06f8, 0xe002) }, + { USB_DEVICE(0x06f8, 0xe010) }, + { USB_DEVICE(0x06f8, 0xe020) }, /* Linksys */ - { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x13b1, 0x0020) }, + { USB_DEVICE(0x13b1, 0x0023) }, + { USB_DEVICE(0x13b1, 0x0028) }, /* MSI */ - { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0db0, 0x4600) }, + { USB_DEVICE(0x0db0, 0x6877) }, + { USB_DEVICE(0x0db0, 0x6874) }, + { USB_DEVICE(0x0db0, 0xa861) }, + { USB_DEVICE(0x0db0, 0xa874) }, /* Ovislink */ - { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1b75, 0x7318) }, /* Ralink */ - { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x04bb, 0x093d) }, + { USB_DEVICE(0x148f, 0x2573) }, + { USB_DEVICE(0x148f, 0x2671) }, + { USB_DEVICE(0x0812, 0x3101) }, /* Qcom */ - { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x18e8, 0x6196) }, + { USB_DEVICE(0x18e8, 0x6229) }, + { USB_DEVICE(0x18e8, 0x6238) }, /* Samsung */ - { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x04e8, 0x4471) }, /* Senao */ - { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x1740, 0x7100) }, /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0df6, 0x0024) }, + { USB_DEVICE(0x0df6, 0x0027) }, + { USB_DEVICE(0x0df6, 0x002f) }, + { USB_DEVICE(0x0df6, 0x90ac) }, + { USB_DEVICE(0x0df6, 0x9712) }, /* Surecom */ - { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0769, 0x31f3) }, /* Tilgin */ - { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x6933, 0x5001) }, /* Philips */ - { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0471, 0x200a) }, /* Planex */ - { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x2019, 0xab01) }, + { USB_DEVICE(0x2019, 0xab50) }, /* WideTell */ - { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x7167, 0x3840) }, /* Zcom */ - { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0cde, 0x001c) }, /* ZyXEL */ - { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0586, 0x3415) }, { 0, } }; @@ -2506,10 +2506,16 @@ MODULE_DEVICE_TABLE(usb, rt73usb_device_table); MODULE_FIRMWARE(FIRMWARE_RT2571); MODULE_LICENSE("GPL"); +static int rt73usb_probe(struct usb_interface *usb_intf, + const struct usb_device_id *id) +{ + return rt2x00usb_probe(usb_intf, &rt73usb_ops); +} + static struct usb_driver rt73usb_driver = { .name = KBUILD_MODNAME, .id_table = rt73usb_device_table, - .probe = rt2x00usb_probe, + .probe = rt73usb_probe, .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, -- cgit v1.2.3-70-g09d2 From 87a3b89f34fb20f644b42fa57d579b1f2833fd4d Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:32:33 +0200 Subject: rt2x00: Add USB IDs. Add USB IDs that are listed in the latest Ralink Windows and/or Linux drivers. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6f7c1617457..fd8aa997fd2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -775,6 +775,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07b8, 0x3072) }, { USB_DEVICE(0x1482, 0x3c09) }, /* AirTies */ + { USB_DEVICE(0x1eda, 0x2012) }, { USB_DEVICE(0x1eda, 0x2310) }, /* Allwin */ { USB_DEVICE(0x8516, 0x2070) }, @@ -933,6 +934,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x0042) }, { USB_DEVICE(0x0df6, 0x0047) }, { USB_DEVICE(0x0df6, 0x0048) }, + { USB_DEVICE(0x0df6, 0x0051) }, + { USB_DEVICE(0x0df6, 0x005f) }, /* SMC */ { USB_DEVICE(0x083a, 0x6618) }, { USB_DEVICE(0x083a, 0x7511) }, @@ -963,6 +966,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0586, 0x3416) }, { USB_DEVICE(0x0586, 0x3418) }, { USB_DEVICE(0x0586, 0x341e) }, + { USB_DEVICE(0x0586, 0x343e) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ { USB_DEVICE(0x148f, 0x3370) }, @@ -998,6 +1002,9 @@ static struct usb_device_id rt2800usb_device_table[] = { * Unclear what kind of devices these are (they aren't supported by the * vendor linux driver). */ + /* Abocom */ + { USB_DEVICE(0x07b8, 0x3073) }, + { USB_DEVICE(0x07b8, 0x3074) }, /* Alpha Networks */ { USB_DEVICE(0x14b2, 0x3c08) }, { USB_DEVICE(0x14b2, 0x3c11) }, @@ -1005,14 +1012,17 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0e0b, 0x9031) }, { USB_DEVICE(0x0e0b, 0x9041) }, /* ASUS */ + { USB_DEVICE(0x0b05, 0x166a) }, { USB_DEVICE(0x0b05, 0x1760) }, { USB_DEVICE(0x0b05, 0x1761) }, { USB_DEVICE(0x0b05, 0x1790) }, + { USB_DEVICE(0x0b05, 0x179d) }, /* AzureWave */ { USB_DEVICE(0x13d3, 0x3262) }, { USB_DEVICE(0x13d3, 0x3284) }, { USB_DEVICE(0x13d3, 0x3322) }, /* Belkin */ + { USB_DEVICE(0x050d, 0x1003) }, { USB_DEVICE(0x050d, 0x825a) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x012e) }, @@ -1028,20 +1038,29 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c13) }, { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c17) }, + { USB_DEVICE(0x2001, 0x3c17) }, /* Edimax */ { USB_DEVICE(0x7392, 0x4085) }, + { USB_DEVICE(0x7392, 0x7722) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0010) }, /* Gigabyte */ { USB_DEVICE(0x1044, 0x800c) }, + /* Huawei */ + { USB_DEVICE(0x148f, 0xf101) }, + /* I-O DATA */ + { USB_DEVICE(0x04bb, 0x094b) }, /* LevelOne */ { USB_DEVICE(0x1740, 0x0605) }, { USB_DEVICE(0x1740, 0x0615) }, /* Linksys */ { USB_DEVICE(0x1737, 0x0077) }, { USB_DEVICE(0x1737, 0x0078) }, + /* Logitec */ + { USB_DEVICE(0x0789, 0x0168) }, + { USB_DEVICE(0x0789, 0x0169) }, /* Motorola */ { USB_DEVICE(0x100d, 0x9032) }, /* Ovislink */ @@ -1056,6 +1075,15 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x2019, 0xab24) }, /* Qcom */ { USB_DEVICE(0x18e8, 0x6259) }, + /* RadioShack */ + { USB_DEVICE(0x08b9, 0x1197) }, + /* Sitecom */ + { USB_DEVICE(0x0df6, 0x003c) }, + { USB_DEVICE(0x0df6, 0x004a) }, + { USB_DEVICE(0x0df6, 0x004d) }, + { USB_DEVICE(0x0df6, 0x0053) }, + { USB_DEVICE(0x0df6, 0x0060) }, + { USB_DEVICE(0x0df6, 0x0062) }, /* SMC */ { USB_DEVICE(0x083a, 0xa512) }, { USB_DEVICE(0x083a, 0xc522) }, -- cgit v1.2.3-70-g09d2 From ccd3caa4516c56540017d1af6c810940eff6afb8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:33:00 +0200 Subject: rt2x00: RT33xx device support is no longer experimental. The rt33xx devices support for both PCI and USB devices has been in the tree for a couple of months now, and seems to be functional and not in a worse shape than the support for rt28xx and rt30xx devices. No longer mark it as experimental and enable the support for these devices by default. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index f630552427b..e7e361e09f0 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -74,17 +74,13 @@ config RT2800PCI if RT2800PCI config RT2800PCI_RT33XX - bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)" - depends on EXPERIMENTAL - default n + bool "rt2800pci - Include support for rt33xx devices" + default y ---help--- This adds support for rt33xx wireless chipset family to the rt2800pci driver. Supported chips: RT3390 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - config RT2800PCI_RT35XX bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -153,17 +149,13 @@ config RT2800USB if RT2800USB config RT2800USB_RT33XX - bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)" - depends on EXPERIMENTAL - default n + bool "rt2800usb - Include support for rt33xx devices" + default y ---help--- This adds support for rt33xx wireless chipset family to the rt2800usb driver. Supported chips: RT3370 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - config RT2800USB_RT35XX bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL -- cgit v1.2.3-70-g09d2 From ea81966ccc2edd324c1fa382260a62a4400a032a Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:33:20 +0200 Subject: rt2x00: Enable support for RT53xx PCI devices by default. Code seems to be feature-complete, so no reason to not enable these devices by default. Also, remove the sentence about the support for these devices being non-functional. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index e7e361e09f0..d7e27b34836 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -96,15 +96,12 @@ config RT2800PCI_RT35XX config RT2800PCI_RT53XX bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL - default n + default y ---help--- This adds support for rt53xx wireless chipset family to the rt2800pci driver. Supported chips: RT5390 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - endif config RT2500USB -- cgit v1.2.3-70-g09d2 From 46a01ec00d05581c5bd0c37e680d5b37af4953b4 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 18 Apr 2011 15:33:41 +0200 Subject: rt2x00: Merge rt2x00ht.c contents in other files. The two functions that are in rt2x00ht.c can be much better placed closer to the places where the call-sites of these functions are (one in rt2x00config.c and one in rt2x00queue.c) allowing us to make these functions static. Also, conditional compilations doesn't seem to be necessary anymore as 802.11n support is quite common nowadays. This makes the code a bit easier readable and searchable. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 5 -- drivers/net/wireless/rt2x00/Makefile | 1 - drivers/net/wireless/rt2x00/rt2x00config.c | 28 ++++++ drivers/net/wireless/rt2x00/rt2x00ht.c | 137 ----------------------------- drivers/net/wireless/rt2x00/rt2x00lib.h | 24 ----- drivers/net/wireless/rt2x00/rt2x00queue.c | 81 ++++++++++++++++- 6 files changed, 108 insertions(+), 168 deletions(-) delete mode 100644 drivers/net/wireless/rt2x00/rt2x00ht.c (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index d7e27b34836..c4577310828 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -59,7 +59,6 @@ config RT2800PCI select RT2800_LIB select RT2X00_LIB_PCI if PCI select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X - select RT2X00_LIB_HT select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT @@ -133,7 +132,6 @@ config RT2800USB depends on USB select RT2800_LIB select RT2X00_LIB_USB - select RT2X00_LIB_HT select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT @@ -196,9 +194,6 @@ config RT2X00_LIB_USB config RT2X00_LIB tristate -config RT2X00_LIB_HT - boolean - config RT2X00_LIB_FIRMWARE boolean select FW_LOADER diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 97133985829..349d5b8284a 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile @@ -7,7 +7,6 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o -rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e225a66f59a..f70a2b45d43 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -163,6 +163,34 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, rt2x00queue_start_queue(rt2x00dev->rx); } +static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf) +{ + struct hw_mode_spec *spec = &rt2x00dev->spec; + int center_channel; + u16 i; + + /* + * Initialize center channel to current channel. + */ + center_channel = spec->channels[conf->channel->hw_value].channel; + + /* + * Adjust center channel to HT40+ and HT40- operation. + */ + if (conf_is_ht40_plus(conf)) + center_channel += 2; + else if (conf_is_ht40_minus(conf)) + center_channel -= (center_channel == 14) ? 1 : 2; + + for (i = 0; i < spec->num_channels; i++) + if (spec->channels[i].channel == center_channel) + return i; + + WARN_ON(1); + return conf->channel->hw_value; +} + void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, unsigned int ieee80211_flags) diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c deleted file mode 100644 index a30f68c7fd7..00000000000 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2004 - 2009 Ivo van Doorn - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Module: rt2x00lib - Abstract: rt2x00 HT specific routines. - */ - -#include -#include - -#include "rt2x00.h" -#include "rt2x00lib.h" - -void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, - struct txentry_desc *txdesc, - const struct rt2x00_rate *hwrate) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); - struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; - - if (tx_info->control.sta) - txdesc->u.ht.mpdu_density = - tx_info->control.sta->ht_cap.ampdu_density; - - txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ - - /* - * Only one STBC stream is supported for now. - */ - if (tx_info->flags & IEEE80211_TX_CTL_STBC) - txdesc->u.ht.stbc = 1; - - /* - * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the - * mcs rate to be used - */ - if (txrate->flags & IEEE80211_TX_RC_MCS) { - txdesc->u.ht.mcs = txrate->idx; - - /* - * MIMO PS should be set to 1 for STA's using dynamic SM PS - * when using more then one tx stream (>MCS7). - */ - if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && - ((tx_info->control.sta->ht_cap.cap & - IEEE80211_HT_CAP_SM_PS) >> - IEEE80211_HT_CAP_SM_PS_SHIFT) == - WLAN_HT_CAP_SM_PS_DYNAMIC) - __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); - } else { - txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); - if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - txdesc->u.ht.mcs |= 0x08; - } - - /* - * This frame is eligible for an AMPDU, however, don't aggregate - * frames that are intended to probe a specific tx rate. - */ - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && - !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) - __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); - - /* - * Set 40Mhz mode if necessary (for legacy rates this will - * duplicate the frame to both channels). - */ - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || - txrate->flags & IEEE80211_TX_RC_DUP_DATA) - __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); - if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) - __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); - - /* - * Determine IFS values - * - Use TXOP_BACKOFF for management frames except beacons - * - Use TXOP_SIFS for fragment bursts - * - Use TXOP_HTTXOP for everything else - * - * Note: rt2800 devices won't use CTS protection (if used) - * for frames not transmitted with TXOP_HTTXOP - */ - if (ieee80211_is_mgmt(hdr->frame_control) && - !ieee80211_is_beacon(hdr->frame_control)) - txdesc->u.ht.txop = TXOP_BACKOFF; - else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) - txdesc->u.ht.txop = TXOP_SIFS; - else - txdesc->u.ht.txop = TXOP_HTTXOP; -} - -u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf) -{ - struct hw_mode_spec *spec = &rt2x00dev->spec; - int center_channel; - u16 i; - - /* - * Initialize center channel to current channel. - */ - center_channel = spec->channels[conf->channel->hw_value].channel; - - /* - * Adjust center channel to HT40+ and HT40- operation. - */ - if (conf_is_ht40_plus(conf)) - center_channel += 2; - else if (conf_is_ht40_minus(conf)) - center_channel -= (center_channel == 14) ? 1 : 2; - - for (i = 0; i < spec->num_channels; i++) - if (spec->channels[i].channel == center_channel) - return i; - - WARN_ON(1); - return conf->channel->hw_value; -} diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 57ede6ccf40..322cc4f3de5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -387,30 +387,6 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, } #endif /* CONFIG_RT2X00_LIB_CRYPTO */ -/* - * HT handlers. - */ -#ifdef CONFIG_RT2X00_LIB_HT -void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, - struct txentry_desc *txdesc, - const struct rt2x00_rate *hwrate); - -u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf); -#else -static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, - struct txentry_desc *txdesc, - const struct rt2x00_rate *hwrate) -{ -} - -static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf) -{ - return conf->channel->hw_value; -} -#endif /* CONFIG_RT2X00_LIB_HT */ - /* * RFkill handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 0d79278a0a1..56f9d0df9c6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -302,6 +302,85 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, } } +static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, + struct txentry_desc *txdesc, + const struct rt2x00_rate *hwrate) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); + struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; + + if (tx_info->control.sta) + txdesc->u.ht.mpdu_density = + tx_info->control.sta->ht_cap.ampdu_density; + + txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ + + /* + * Only one STBC stream is supported for now. + */ + if (tx_info->flags & IEEE80211_TX_CTL_STBC) + txdesc->u.ht.stbc = 1; + + /* + * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the + * mcs rate to be used + */ + if (txrate->flags & IEEE80211_TX_RC_MCS) { + txdesc->u.ht.mcs = txrate->idx; + + /* + * MIMO PS should be set to 1 for STA's using dynamic SM PS + * when using more then one tx stream (>MCS7). + */ + if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && + ((tx_info->control.sta->ht_cap.cap & + IEEE80211_HT_CAP_SM_PS) >> + IEEE80211_HT_CAP_SM_PS_SHIFT) == + WLAN_HT_CAP_SM_PS_DYNAMIC) + __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); + } else { + txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); + if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + txdesc->u.ht.mcs |= 0x08; + } + + /* + * This frame is eligible for an AMPDU, however, don't aggregate + * frames that are intended to probe a specific tx rate. + */ + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && + !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) + __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); + + /* + * Set 40Mhz mode if necessary (for legacy rates this will + * duplicate the frame to both channels). + */ + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || + txrate->flags & IEEE80211_TX_RC_DUP_DATA) + __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); + if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) + __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); + + /* + * Determine IFS values + * - Use TXOP_BACKOFF for management frames except beacons + * - Use TXOP_SIFS for fragment bursts + * - Use TXOP_HTTXOP for everything else + * + * Note: rt2800 devices won't use CTS protection (if used) + * for frames not transmitted with TXOP_HTTXOP + */ + if (ieee80211_is_mgmt(hdr->frame_control) && + !ieee80211_is_beacon(hdr->frame_control)) + txdesc->u.ht.txop = TXOP_BACKOFF; + else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) + txdesc->u.ht.txop = TXOP_SIFS; + else + txdesc->u.ht.txop = TXOP_HTTXOP; +} + static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { @@ -397,7 +476,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, rt2x00queue_create_tx_descriptor_seq(entry, txdesc); if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) - rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); + rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate); else rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); } -- cgit v1.2.3-70-g09d2 From 9a8199961b22e61221a6114b8bbbc26ddcc243f7 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 18 Apr 2011 15:34:01 +0200 Subject: rt2x00: Optimize register access in rt2800pci All register reads/writes in rt2800pci were previously done with rt2800_register_read/rt2800_register_write. These however indirectly call rt2x00pci_register_read/rt2x00pci_register_write which adds an additional overhead of at least one call and several move instructions to each register access. Replacing the calls to rt2800_register_read/rt2800_register_write with direct calls to rt2x00pci_register_read/rt2x00pci_register_write gets rid of quite a number of instructions in the drivers hotpaths (IRQ handling and txdone handling). For consistency replace all references to rt2800_register_read/write with the rt2x00pci_register_read/write variants. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 158 +++++++++++++++++--------------- 1 file changed, 84 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 6f91a9ad4d3..b0c729b25c7 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -66,7 +66,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) return; for (i = 0; i < 200; i++) { - rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); + rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || @@ -80,8 +80,8 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) if (i == 200) ERROR(rt2x00dev, "MCU request failed, no response from hardware\n"); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) @@ -105,7 +105,7 @@ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg; - rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); @@ -127,7 +127,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, !!eeprom->reg_chip_select); - rt2800_register_write(rt2x00dev, E2PROM_CSR, reg); + rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); } static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) @@ -135,7 +135,7 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) struct eeprom_93cx6 eeprom; u32 reg; - rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt2800pci_eepromregister_read; @@ -195,9 +195,9 @@ static void rt2800pci_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: /* @@ -207,15 +207,15 @@ static void rt2800pci_start_queue(struct data_queue *queue) tasklet_enable(&rt2x00dev->tbtt_tasklet); tasklet_enable(&rt2x00dev->pretbtt_tasklet); - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); - rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); - rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); + rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); break; default: break; @@ -233,11 +233,13 @@ static void rt2800pci_kick_queue(struct data_queue *queue) case QID_AC_BE: case QID_AC_BK: entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), + entry->entry_idx); break; case QID_MGMT: entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5), + entry->entry_idx); break; default: break; @@ -251,20 +253,20 @@ static void rt2800pci_stop_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); - rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); - rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); + rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); /* * Wait for tbtt tasklets to finish. @@ -295,7 +297,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, */ reg = 0; rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg); + rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg); /* * Write firmware to device. @@ -303,11 +305,11 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); + rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); + rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); return 0; } @@ -351,7 +353,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) * Set RX IDX in register to inform hardware that we have * handled this entry and it is available for reuse again. */ - rt2800_register_write(rt2x00dev, RX_CRX_IDX, + rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); } else { rt2x00_desc_read(entry_priv->desc, 1, &word); @@ -369,45 +371,51 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) * Initialize registers. */ entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); - rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit); - rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0); - rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0); + rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); + rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0, + rt2x00dev->tx[0].limit); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0); + rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); - rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit); - rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0); - rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0); + rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); + rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1, + rt2x00dev->tx[1].limit); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0); + rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0); entry_priv = rt2x00dev->tx[2].entries[0].priv_data; - rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); - rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit); - rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0); - rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0); + rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); + rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2, + rt2x00dev->tx[2].limit); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0); + rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0); entry_priv = rt2x00dev->tx[3].entries[0].priv_data; - rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); - rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit); - rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0); - rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0); + rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); + rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3, + rt2x00dev->tx[3].limit); + rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0); + rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0); entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); - rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit); - rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1); - rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0); + rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); + rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, + rt2x00dev->rx[0].limit); + rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, + rt2x00dev->rx[0].limit - 1); + rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0); /* * Enable global DMA configuration */ - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00pci_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + rt2x00pci_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0); + rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0); return 0; } @@ -427,8 +435,8 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { - rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); /* * Enable tasklets. The beacon related tasklets are @@ -440,7 +448,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, } spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); @@ -459,7 +467,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); - rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); if (state == STATE_RADIO_IRQ_OFF) { @@ -480,7 +488,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) /* * Reset DMA indexes */ - rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); + rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, ®); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); @@ -488,26 +496,26 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); + rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); + rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); - rt2800_register_write(rt2x00dev, AUX_CTRL, reg); + rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg); } - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); return 0; } @@ -525,8 +533,8 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) { if (rt2x00_is_soc(rt2x00dev)) { rt2800_disable_radio(rt2x00dev); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); + rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0); } } @@ -537,8 +545,10 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); } else if (state == STATE_SLEEP) { - rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, + 0xffffffff); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, + 0xffffffff); rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); } @@ -778,9 +788,9 @@ static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, * access needs locking. */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 1); - rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -851,7 +861,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * need to lock the kfifo. */ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { - rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); + rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status); if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) break; @@ -873,8 +883,8 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) u32 reg, mask; /* Read status and ACK all interrupts */ - rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); if (!reg) return IRQ_NONE; @@ -914,9 +924,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) * the tasklet will reenable the appropriate interrupts. */ spin_lock(&rt2x00dev->irqmask_lock); - rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); reg &= mask; - rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock(&rt2x00dev->irqmask_lock); return IRQ_HANDLED; -- cgit v1.2.3-70-g09d2 From 8d0a2dcfb6f965781cde6d9dfbd4540ab22a0eb9 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 18 Apr 2011 15:34:22 +0200 Subject: rt2x00: Optimize register access in rt2800usb All register reads/writes in rt2800usb were previously done with rt2800_register_read/rt2800_register_write. These however indirectly call rt2x00usb_register_read/rt2x00usb_register_write which adds an additional overhead of at least one call and several move instructions to each register access. Replacing the calls to rt2800_register_read/rt2800_register_write with direct calls to rt2x00usb_register_read/rt2x00usb_register_write gets rid of quite a number of instructions in the drivers hotpaths (IRQ handling and txdone handling). For consistency replace all references to rt2800_register_read/write with the rt2x00usb_register_read/write variants. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index fd8aa997fd2..44ead759e20 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -59,16 +59,16 @@ static void rt2800usb_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); break; default: break; @@ -82,16 +82,16 @@ static void rt2800usb_stop_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); break; default: break; @@ -185,11 +185,11 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, /* * Write firmware to device. */ - rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, - data + offset, length); + rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, + data + offset, length); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); + rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); /* * Send firmware request to device to load firmware, @@ -204,7 +204,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, } msleep(10); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); return 0; } @@ -222,22 +222,22 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); + rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); + rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); + rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, USB_MODE_RESET, REGISTER_TIMEOUT); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); return 0; } @@ -249,7 +249,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) return -EIO; - rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); + rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, ®); rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); @@ -262,7 +262,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) / 1024) - 3); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); - rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); + rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg); return rt2800_enable_radio(rt2x00dev); } @@ -338,12 +338,12 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) unsigned int i; u32 reg; - rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { WARNING(rt2x00dev, "TX HW queue 0 timed out," " invoke forced kick\n"); - rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); + rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); for (i = 0; i < 10; i++) { udelay(10); @@ -351,15 +351,15 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) break; } - rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); } - rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { WARNING(rt2x00dev, "TX HW queue 1 timed out," " invoke forced kick\n"); - rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); + rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); for (i = 0; i < 10; i++) { udelay(10); @@ -367,7 +367,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) break; } - rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); } rt2x00usb_watchdog(rt2x00dev); -- cgit v1.2.3-70-g09d2 From e7dee444263a103a9a2ac5fd5d0b5e9dc177d57c Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 18 Apr 2011 15:34:41 +0200 Subject: rt2x00: Implement get_ringparam callback function With the get_ringparam callback function we can export ring parameters to ethtool through the mac80211 interface. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 1 + drivers/net/wireless/rt2x00/rt2500pci.c | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 2 ++ drivers/net/wireless/rt2x00/rt2x00mac.c | 16 ++++++++++++++++ drivers/net/wireless/rt2x00/rt61pci.c | 1 + drivers/net/wireless/rt2x00/rt73usb.c | 1 + 9 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index d4acdde7c75..bbe76f79b62 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1720,6 +1720,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .tx_last_beacon = rt2400pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 15f5649e2ca..6f489968e7a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -2013,6 +2013,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .tx_last_beacon = rt2500pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index d88c36712ef..5ef338671d7 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1823,6 +1823,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .conf_tx = rt2x00mac_conf_tx, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b0c729b25c7..08d3947fcb2 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1028,6 +1028,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .ampdu_action = rt2800_ampdu_action, .flush = rt2x00mac_flush, .get_survey = rt2800_get_survey, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2800_ops rt2800pci_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 44ead759e20..0d4e8fa3e1f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -673,6 +673,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .ampdu_action = rt2800_ampdu_action, .flush = rt2x00mac_flush, .get_survey = rt2800_get_survey, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2800_ops rt2800usb_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index dcdc50d27ea..f1d8f55d3ca 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1254,6 +1254,8 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); +void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, + u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); /* * Driver allocation handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4770156df1a..6d1d38329e5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -737,3 +737,19 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) rt2x00queue_flush_queue(queue, drop); } EXPORT_SYMBOL_GPL(rt2x00mac_flush); + +void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, + u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + + tx_queue_for_each(rt2x00dev, queue) { + *tx += queue->length; + *tx_max += queue->limit; + } + + *rx = rt2x00dev->rx->length; + *rx_max = rt2x00dev->rx->limit; +} +EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index c5dccdb2f17..eb540310839 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2979,6 +2979,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .get_tsf = rt61pci_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index be3eb5e894e..bf7fea4cb96 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2310,6 +2310,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .get_tsf = rt73usb_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .get_ringparam = rt2x00mac_get_ringparam, }; static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { -- cgit v1.2.3-70-g09d2 From 0ed7b3c04434788ef03d267190c5e9e6e3f8e9ce Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 18 Apr 2011 15:35:12 +0200 Subject: rt2x00: Implement get_antenna and set_antenna callback functions Implement the get_antenna and set_antenna callback functions, which will allow clients to control the antenna for all non-11n hardware (Antenna handling in rt2800 is still a bit magical, so we can't use the set_antenna for those drivers yet). To best support the set_antenna callback some modifications are needed in the diversity handling. We should never look at the default antenna settings to determine if software diversity is enabled. Instead we should set the diversity flag when possible, which will allow the link_tuner to automatically pick up the tuning. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 + drivers/net/wireless/rt2x00/rt2500pci.c | 2 + drivers/net/wireless/rt2x00/rt2500usb.c | 2 + drivers/net/wireless/rt2x00/rt2x00.h | 2 + drivers/net/wireless/rt2x00/rt2x00config.c | 45 ++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00link.c | 10 ----- drivers/net/wireless/rt2x00/rt2x00mac.c | 65 ++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt61pci.c | 2 + drivers/net/wireless/rt2x00/rt73usb.c | 2 + 9 files changed, 103 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index bbe76f79b62..937f9e8bf05 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1720,6 +1720,8 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .tx_last_beacon = rt2400pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .set_antenna = rt2x00mac_set_antenna, + .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, }; diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 6f489968e7a..d27d7b8ba3b 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -2013,6 +2013,8 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .tx_last_beacon = rt2500pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .set_antenna = rt2x00mac_set_antenna, + .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, }; diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 5ef338671d7..b21f81231a0 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1823,6 +1823,8 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .conf_tx = rt2x00mac_conf_tx, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .set_antenna = rt2x00mac_set_antenna, + .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, }; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index f1d8f55d3ca..acf561f7cde 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1254,6 +1254,8 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); +int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); +int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index f70a2b45d43..2a313b6d378 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -109,15 +109,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); } -static inline -enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant, - enum antenna default_ant) -{ - if (current_ant != ANTENNA_SW_DIVERSITY) - return current_ant; - return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B; -} - void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup config) { @@ -126,19 +117,35 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup *active = &rt2x00dev->link.ant.active; /* - * Failsafe: Make sure we are not sending the - * ANTENNA_SW_DIVERSITY state to the driver. - * If that happens, fallback to hardware defaults, - * or our own default. + * When the caller tries to send the SW diversity, + * we must update the ANTENNA_RX_DIVERSITY flag to + * enable the antenna diversity in the link tuner. + * + * Secondly, we must guarentee we never send the + * software antenna diversity command to the driver. */ - if (!(ant->flags & ANTENNA_RX_DIVERSITY)) - config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); - else if (config.rx == ANTENNA_SW_DIVERSITY) + if (!(ant->flags & ANTENNA_RX_DIVERSITY)) { + if (config.rx == ANTENNA_SW_DIVERSITY) { + ant->flags |= ANTENNA_RX_DIVERSITY; + + if (def->rx == ANTENNA_SW_DIVERSITY) + config.rx = ANTENNA_B; + else + config.rx = def->rx; + } + } else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; - if (!(ant->flags & ANTENNA_TX_DIVERSITY)) - config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); - else if (config.tx == ANTENNA_SW_DIVERSITY) + if (!(ant->flags & ANTENNA_TX_DIVERSITY)) { + if (config.tx == ANTENNA_SW_DIVERSITY) { + ant->flags |= ANTENNA_TX_DIVERSITY; + + if (def->tx == ANTENNA_SW_DIVERSITY) + config.tx = ANTENNA_B; + else + config.tx = def->tx; + } + } else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index ba0bb766e59..fa55399be19 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -192,17 +192,7 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) /* * Determine if software diversity is enabled for * either the TX or RX antenna (or both). - * Always perform this check since within the link - * tuner interval the configuration might have changed. */ - ant->flags &= ~ANTENNA_RX_DIVERSITY; - ant->flags &= ~ANTENNA_TX_DIVERSITY; - - if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) - ant->flags |= ANTENNA_RX_DIVERSITY; - if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) - ant->flags |= ANTENNA_TX_DIVERSITY; - if (!(ant->flags & ANTENNA_RX_DIVERSITY) && !(ant->flags & ANTENNA_TX_DIVERSITY)) { ant->flags = 0; diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 6d1d38329e5..93bec140e59 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -738,6 +738,71 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) } EXPORT_SYMBOL_GPL(rt2x00mac_flush); +int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct link_ant *ant = &rt2x00dev->link.ant; + struct antenna_setup *def = &rt2x00dev->default_ant; + struct antenna_setup setup; + + // The antenna value is not supposed to be 0, + // or exceed the maximum number of antenna's. + if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3)) + return -EINVAL; + + // When the client tried to configure the antenna to or from + // diversity mode, we must reset the default antenna as well + // as that controls the diversity switch. + if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3) + ant->flags &= ~ANTENNA_TX_DIVERSITY; + if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3) + ant->flags &= ~ANTENNA_RX_DIVERSITY; + + // If diversity is being enabled, check if we need hardware + // or software diversity. In the latter case, reset the value, + // and make sure we update the antenna flags to have the + // link tuner pick up the diversity tuning. + if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) { + tx_ant = ANTENNA_SW_DIVERSITY; + ant->flags |= ANTENNA_TX_DIVERSITY; + } + + if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) { + rx_ant = ANTENNA_SW_DIVERSITY; + ant->flags |= ANTENNA_RX_DIVERSITY; + } + + setup.tx = tx_ant; + setup.rx = rx_ant; + + rt2x00lib_config_antenna(rt2x00dev, setup); + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna); + +int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct link_ant *ant = &rt2x00dev->link.ant; + struct antenna_setup *active = &rt2x00dev->link.ant.active; + + // When software diversity is active, we must report this to the + // client and not the current active antenna state. + if (ant->flags & ANTENNA_TX_DIVERSITY) + *tx_ant = ANTENNA_HW_DIVERSITY; + else + *tx_ant = active->tx; + + if (ant->flags & ANTENNA_RX_DIVERSITY) + *rx_ant = ANTENNA_HW_DIVERSITY; + else + *rx_ant = active->rx; + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna); + void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) { diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index eb540310839..9d35ec16a3a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2979,6 +2979,8 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .get_tsf = rt61pci_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .set_antenna = rt2x00mac_set_antenna, + .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, }; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index bf7fea4cb96..a6ce7d6cbdf 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2310,6 +2310,8 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .get_tsf = rt73usb_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .flush = rt2x00mac_flush, + .set_antenna = rt2x00mac_set_antenna, + .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, }; -- cgit v1.2.3-70-g09d2