From 3fa507386dc4cdf731344cb9361e9cca373cedb9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 May 2011 07:50:38 -0700 Subject: iwlagn: prepare for multi-TB commands In a subsequent patch, I want to make commands use multiple TBs in a TFD. This is a simple change to prepare the data structures for this, with as of now still just a single TB supported. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 89b8da7..9f34cd7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -195,9 +195,9 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, - .len = sizeof(cmd), + .len = { sizeof(cmd), }, .flags = CMD_SYNC, - .data = &cmd, + .data = { &cmd, }, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 98f81df..09751f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -282,9 +282,9 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, - .len = sizeof(cmd), + .len = { sizeof(cmd), }, .flags = CMD_SYNC, - .data = &cmd, + .data = { &cmd, }, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a7921f9a..860c26e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -221,9 +221,9 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, - .len = sizeof(cmd), + .len = { sizeof(cmd), }, .flags = CMD_SYNC, - .data = &cmd, + .data = { &cmd, }, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 0f6bb9b..30e11c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -93,8 +93,8 @@ int iwl_send_calib_results(struct iwl_priv *priv) for (i = 0; i < IWL_CALIB_MAX; i++) { if ((BIT(i) & priv->hw_params.calib_init_cfg) && priv->calib_results[i].buf) { - hcmd.len = priv->calib_results[i].buf_len; - hcmd.data = priv->calib_results[i].buf; + hcmd.len[0] = priv->calib_results[i].buf_len; + hcmd.data[0] = priv->calib_results[i].buf; ret = iwl_send_cmd_sync(priv, &hcmd); if (ret) { IWL_ERR(priv, "Error %d iteration %d\n", @@ -456,9 +456,9 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) struct iwl_sensitivity_data *data = NULL; struct iwl_host_cmd cmd_out = { .id = SENSITIVITY_CMD, - .len = sizeof(struct iwl_sensitivity_cmd), + .len = { sizeof(struct iwl_sensitivity_cmd), }, .flags = CMD_ASYNC, - .data = &cmd, + .data = { &cmd, }, }; data = &(priv->sensitivity_data); @@ -491,9 +491,9 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) struct iwl_sensitivity_data *data = NULL; struct iwl_host_cmd cmd_out = { .id = SENSITIVITY_CMD, - .len = sizeof(struct iwl_enhance_sensitivity_cmd), + .len = { sizeof(struct iwl_enhance_sensitivity_cmd), }, .flags = CMD_ASYNC, - .data = &cmd, + .data = { &cmd, }, }; data = &(priv->sensitivity_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8e79653..576f45e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1140,7 +1140,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl_scan_cmd), + .len = { sizeof(struct iwl_scan_cmd), }, .flags = CMD_SIZE_HUGE, }; struct iwl_scan_cmd *scan; @@ -1425,10 +1425,10 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) return -EIO; } - cmd.len += le16_to_cpu(scan->tx_cmd.len) + + cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) + scan->channel_count * sizeof(struct iwl_scan_channel); - cmd.data = scan; - scan->len = cpu_to_le16(cmd.len); + cmd.data[0] = scan; + scan->len = cpu_to_le16(cmd.len[0]); /* set scan bit here for PAN params */ set_bit(STATUS_SCAN_HW, &priv->status); @@ -1520,9 +1520,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) struct iwl_txfifo_flush_cmd flush_cmd; struct iwl_host_cmd cmd = { .id = REPLY_TXFIFO_FLUSH, - .len = sizeof(struct iwl_txfifo_flush_cmd), + .len = { sizeof(struct iwl_txfifo_flush_cmd), }, .flags = CMD_SYNC, - .data = &flush_cmd, + .data = { &flush_cmd, }, }; might_sleep(); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 079275f..0bd722c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -144,7 +144,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, size_t cmd_size = sizeof(struct iwl_wep_cmd); struct iwl_host_cmd cmd = { .id = ctx->wep_key_cmd, - .data = wep_cmd, + .data = { wep_cmd, }, .flags = CMD_SYNC, }; @@ -172,7 +172,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; - cmd.len = cmd_size; + cmd.len[0] = cmd_size; if (not_empty || send_if_empty) return iwl_send_cmd(priv, &cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8bda0e8..e35755c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -217,8 +217,8 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) struct iwl_calib_cfg_cmd calib_cfg_cmd; struct iwl_host_cmd cmd = { .id = CALIBRATION_CFG_CMD, - .len = sizeof(struct iwl_calib_cfg_cmd), - .data = &calib_cfg_cmd, + .len = { sizeof(struct iwl_calib_cfg_cmd), }, + .data = { &calib_cfg_cmd, }, }; memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3ecc319..2713081 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -189,8 +189,8 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) rate_flags); /* Submit command */ - cmd.len = sizeof(*tx_beacon_cmd) + frame_size; - cmd.data = tx_beacon_cmd; + cmd.len[0] = sizeof(*tx_beacon_cmd) + frame_size; + cmd.data[0] = tx_beacon_cmd; err = iwl_send_cmd_sync(priv, &cmd); @@ -2114,8 +2114,8 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) struct iwl_calib_cfg_cmd calib_cfg_cmd; struct iwl_host_cmd cmd = { .id = CALIBRATION_CFG_CMD, - .len = sizeof(struct iwl_calib_cfg_cmd), - .data = &calib_cfg_cmd, + .len = { sizeof(struct iwl_calib_cfg_cmd), }, + .data = { &calib_cfg_cmd, }, }; memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 214e465..9daf964 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -277,15 +277,16 @@ struct iwl_device_cmd { #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) +#define IWL_MAX_CMD_TFDS 1 struct iwl_host_cmd { - const void *data; + const void *data[IWL_MAX_CMD_TFDS]; unsigned long reply_page; void (*callback)(struct iwl_priv *priv, struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt); u32 flags; - u16 len; + u16 len[IWL_MAX_CMD_TFDS]; u8 id; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 8f0beb9..1ff1f31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -264,8 +264,8 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) { struct iwl_host_cmd cmd = { .id = id, - .len = len, - .data = data, + .len = { len, }, + .data = { data, }, }; return iwl_send_cmd_sync(priv, &cmd); @@ -279,8 +279,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, { struct iwl_host_cmd cmd = { .id = id, - .len = len, - .data = data, + .len = { len, }, + .data = { data, }, }; cmd.flags |= CMD_ASYNC; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 439187f..7c23beb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -107,8 +107,8 @@ 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, + .len = { sizeof(struct iwl_led_cmd), }, + .data = { led_cmd, }, .flags = CMD_ASYNC, .callback = NULL, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 3c8cebd..7df2814 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -141,7 +141,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_host_cmd cmd = { .id = REPLY_ADD_STA, .flags = flags, - .data = data, + .data = { data, }, }; u8 sta_id __maybe_unused = sta->sta.sta_id; @@ -155,7 +155,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, might_sleep(); } - cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); + cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); ret = iwl_send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) @@ -401,9 +401,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, struct iwl_host_cmd cmd = { .id = REPLY_REMOVE_STA, - .len = sizeof(struct iwl_rem_sta_cmd), + .len = { sizeof(struct iwl_rem_sta_cmd), }, .flags = CMD_SYNC, - .data = &rm_sta_cmd, + .data = { &rm_sta_cmd, }, }; memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); @@ -760,9 +760,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_host_cmd cmd = { .id = REPLY_TX_LINK_QUALITY_CMD, - .len = sizeof(struct iwl_link_quality_cmd), + .len = { sizeof(struct iwl_link_quality_cmd), }, .flags = flags, - .data = lq, + .data = { lq, }, }; if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 89b6696..01a8ec9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -198,10 +198,10 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) } cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); - cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); - cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); + cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); + cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," - " len %d\n", cmd.id, cmd.flags, cmd.len); + " len %d\n", cmd.id, cmd.flags, cmd.len[0]); /* ok, let's submit the command to ucode */ return iwl_send_cmd(priv, &cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e69597e..7843195 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -446,7 +446,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) u16 fix_size; bool is_ct_kill = false; - fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); + fix_size = (u16)(cmd->len[0] + sizeof(out_cmd->hdr)); /* * If any of the command structures end up being larger than @@ -506,7 +506,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) out_meta->callback = cmd->callback; out_cmd->hdr.cmd = cmd->id; - memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); + memcpy(&out_cmd->cmd.payload, cmd->data[0], cmd->len[0]); /* At this point, the out_cmd now has all of the incoming cmd * information */ @@ -555,7 +555,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1, - U32_PAD(cmd->len)); + U32_PAD(cmd->len[0])); /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); -- cgit v0.10.2 From 214d14d4d323aab5d455b409e279f9e1e6631123 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 May 2011 07:50:44 -0700 Subject: iwlagn: clean up TXQ indirection All of these functions no longer need to be accessed indirectly since they're shared in all AGN devices. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index b4c8193..61d4a11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -171,10 +171,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) static struct iwl_lib_ops iwl1000_lib = { .set_hw_params = iwl1000_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .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, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 9f34cd7..86feec8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -252,10 +252,6 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv, static struct iwl_lib_ops iwl2000_lib = { .set_hw_params = iwl2000_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 09751f2..a70b8cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -339,10 +339,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, static struct iwl_lib_ops iwl5000_lib = { .set_hw_params = iwl5000_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .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, @@ -374,10 +370,6 @@ static struct iwl_lib_ops iwl5000_lib = { static struct iwl_lib_ops iwl5150_lib = { .set_hw_params = iwl5150_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .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, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 860c26e..f8c710d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -278,10 +278,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, static struct iwl_lib_ops iwl6000_lib = { .set_hw_params = iwl6000_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .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, @@ -314,10 +310,6 @@ static struct iwl_lib_ops iwl6000_lib = { static struct iwl_lib_ops iwl6030_lib = { .set_hw_params = iwl6000_hw_set_hw_params, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, .rx_handler_setup = iwlagn_bt_rx_handler_setup, .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 7c1becf..d34e103 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -750,12 +750,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) spin_unlock(&priv->sta_lock); /* Attach buffers to TFD */ - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - txcmd_phys, firstlen, 1, 0); + iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1, 0); if (secondlen > 0) - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - phys_addr, secondlen, - 0, 0); + iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, + secondlen, 0, 0); scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + offsetof(struct iwl_tx_cmd, scratch); @@ -911,7 +909,7 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); /* Turn off all Tx DMA fifos */ - priv->cfg->ops->lib->txq_set_sched(priv, 0); + iwlagn_txq_set_sched(priv, 0); /* Tell NIC where to find the "keep warm" buffer */ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); @@ -949,7 +947,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); /* Turn off all Tx DMA fifos */ - priv->cfg->ops->lib->txq_set_sched(priv, 0); + iwlagn_txq_set_sched(priv, 0); /* Tell NIC where to find the "keep warm" buffer */ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); @@ -975,7 +973,7 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) /* Turn off all Tx DMA fifos */ spin_lock_irqsave(&priv->lock, flags); - priv->cfg->ops->lib->txq_set_sched(priv, 0); + iwlagn_txq_set_sched(priv, 0); /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { @@ -1258,7 +1256,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) iwlagn_txq_inval_byte_cnt_tbl(priv, txq); - priv->cfg->ops->lib->txq_free_tfd(priv, txq); + iwlagn_txq_free_tfd(priv, txq); } return nfreed; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index e35755c..97de5d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -440,7 +440,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) IWL_MASK(0, priv->hw_params.max_txq_num)); /* Activate all Tx DMA/FIFO channels */ - priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); + iwlagn_txq_set_sched(priv, IWL_MASK(0, 7)); /* map queues to FIFOs */ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 2713081..2bb08d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -200,155 +200,6 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) return err; } -static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) -{ - struct iwl_tfd_tb *tb = &tfd->tbs[idx]; - - dma_addr_t addr = get_unaligned_le32(&tb->lo); - if (sizeof(dma_addr_t) > sizeof(u32)) - addr |= - ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; - - return addr; -} - -static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) -{ - struct iwl_tfd_tb *tb = &tfd->tbs[idx]; - - return le16_to_cpu(tb->hi_n_len) >> 4; -} - -static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, - dma_addr_t addr, u16 len) -{ - struct iwl_tfd_tb *tb = &tfd->tbs[idx]; - u16 hi_n_len = len << 4; - - put_unaligned_le32(addr, &tb->lo); - if (sizeof(dma_addr_t) > sizeof(u32)) - hi_n_len |= ((addr >> 16) >> 16) & 0xF; - - tb->hi_n_len = cpu_to_le16(hi_n_len); - - tfd->num_tbs = idx + 1; -} - -static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) -{ - return tfd->num_tbs & 0x1f; -} - -/** - * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] - * @priv - driver private data - * @txq - tx queue - * - * Does NOT advance any TFD circular buffer read/write indexes - * Does NOT free the TFD itself (which is within circular buffer) - */ -void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; - struct iwl_tfd *tfd; - struct pci_dev *dev = priv->pci_dev; - int index = txq->q.read_ptr; - int i; - int num_tbs; - - tfd = &tfd_tmp[index]; - - /* Sanity check on number of chunks */ - num_tbs = iwl_tfd_get_num_tbs(tfd); - - if (num_tbs >= IWL_NUM_OF_TBS) { - IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); - /* @todo issue fatal error, it is quite serious situation */ - return; - } - - /* Unmap tx_cmd */ - if (num_tbs) - pci_unmap_single(dev, - dma_unmap_addr(&txq->meta[index], mapping), - dma_unmap_len(&txq->meta[index], len), - PCI_DMA_BIDIRECTIONAL); - - /* Unmap chunks, if any. */ - for (i = 1; i < num_tbs; i++) - pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), - iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); - - /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; - - /* can be called from irqs-disabled context */ - if (skb) { - dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; - } - } -} - -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, - u8 reset, u8 pad) -{ - struct iwl_queue *q; - struct iwl_tfd *tfd, *tfd_tmp; - u32 num_tbs; - - q = &txq->q; - tfd_tmp = (struct iwl_tfd *)txq->tfds; - tfd = &tfd_tmp[q->write_ptr]; - - if (reset) - memset(tfd, 0, sizeof(*tfd)); - - num_tbs = iwl_tfd_get_num_tbs(tfd); - - /* Each TFD can point to a maximum 20 Tx buffers */ - if (num_tbs >= IWL_NUM_OF_TBS) { - IWL_ERR(priv, "Error can not send more than %d chunks\n", - IWL_NUM_OF_TBS); - return -EINVAL; - } - - 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); - - iwl_tfd_set_tb(tfd, num_tbs, addr, len); - - return 0; -} - -/* - * Tell nic where to find circular buffer of Tx Frame Descriptors for - * given Tx queue, and enable the DMA channel used for that queue. - * - * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA - * channels supported in hardware. - */ -int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq) -{ - int txq_id = txq->q.id; - - /* Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), - txq->q.dma_addr >> 8); - - return 0; -} - static void iwl_bg_beacon_update(struct work_struct *work) { struct iwl_priv *priv = diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index fe33fe8..269e0c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -191,12 +191,10 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); void iwl_setup_rx_handlers(struct iwl_priv *priv); /* tx */ -void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, +void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); +int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, dma_addr_t addr, u16 len, u8 reset, u8 pad); -int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, struct ieee80211_tx_info *info); int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5b5b0cce..3bb76f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -127,16 +127,6 @@ struct iwl_temp_ops { struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); - /* Handling TX */ - void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); - int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, - u16 len, u8 reset, u8 pad); - void (*txq_free_tfd)(struct iwl_priv *priv, - struct iwl_tx_queue *txq); - int (*txq_init)(struct iwl_priv *priv, - struct iwl_tx_queue *txq); /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); /* setup deferred work */ diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 7843195..302284b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -32,6 +32,7 @@ #include #include #include "iwl-eeprom.h" +#include "iwl-agn.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-sta.h" @@ -85,6 +86,154 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) txq->need_update = 0; } +static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + + dma_addr_t addr = get_unaligned_le32(&tb->lo); + if (sizeof(dma_addr_t) > sizeof(u32)) + addr |= + ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; + + return addr; +} + +static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + + return le16_to_cpu(tb->hi_n_len) >> 4; +} + +static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, + dma_addr_t addr, u16 len) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + u16 hi_n_len = len << 4; + + put_unaligned_le32(addr, &tb->lo); + if (sizeof(dma_addr_t) > sizeof(u32)) + hi_n_len |= ((addr >> 16) >> 16) & 0xF; + + tb->hi_n_len = cpu_to_le16(hi_n_len); + + tfd->num_tbs = idx + 1; +} + +static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) +{ + return tfd->num_tbs & 0x1f; +} + +/** + * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] + * @priv - driver private data + * @txq - tx queue + * + * Does NOT advance any TFD circular buffer read/write indexes + * Does NOT free the TFD itself (which is within circular buffer) + */ +void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; + struct iwl_tfd *tfd; + struct pci_dev *dev = priv->pci_dev; + int index = txq->q.read_ptr; + int i; + int num_tbs; + + tfd = &tfd_tmp[index]; + + /* Sanity check on number of chunks */ + num_tbs = iwl_tfd_get_num_tbs(tfd); + + if (num_tbs >= IWL_NUM_OF_TBS) { + IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); + /* @todo issue fatal error, it is quite serious situation */ + return; + } + + /* Unmap tx_cmd */ + if (num_tbs) + pci_unmap_single(dev, + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), + PCI_DMA_BIDIRECTIONAL); + + /* Unmap chunks, if any. */ + for (i = 1; i < num_tbs; i++) + pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), + iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); + + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; + } + } +} + +int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, + u8 reset, u8 pad) +{ + struct iwl_queue *q; + struct iwl_tfd *tfd, *tfd_tmp; + u32 num_tbs; + + q = &txq->q; + tfd_tmp = (struct iwl_tfd *)txq->tfds; + tfd = &tfd_tmp[q->write_ptr]; + + if (reset) + memset(tfd, 0, sizeof(*tfd)); + + num_tbs = iwl_tfd_get_num_tbs(tfd); + + /* Each TFD can point to a maximum 20 Tx buffers */ + if (num_tbs >= IWL_NUM_OF_TBS) { + IWL_ERR(priv, "Error can not send more than %d chunks\n", + IWL_NUM_OF_TBS); + return -EINVAL; + } + + 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); + + iwl_tfd_set_tb(tfd, num_tbs, addr, len); + + return 0; +} + +/* + * Tell nic where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * + * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * channels supported in hardware. + */ +static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + int txq_id = txq->q.id; + + /* Circular buffer (TFD queue in DRAM) physical base address */ + iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), + txq->q.dma_addr >> 8); + + return 0; +} + /** * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's */ @@ -97,7 +246,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) return; while (q->write_ptr != q->read_ptr) { - priv->cfg->ops->lib->txq_free_tfd(priv, txq); + iwlagn_txq_free_tfd(priv, txq); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } } @@ -391,7 +540,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, return ret; /* Tell device where to find queue */ - priv->cfg->ops->lib->txq_init(priv, txq); + iwlagn_tx_queue_init(priv, txq); return 0; err: @@ -420,7 +569,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); /* Tell device where to find queue */ - priv->cfg->ops->lib->txq_init(priv, txq); + iwlagn_tx_queue_init(priv, txq); } /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -553,9 +702,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - phys_addr, fix_size, 1, - U32_PAD(cmd->len[0])); + iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1, + U32_PAD(cmd->len[0])); /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); -- cgit v0.10.2 From 4c42db0f04e55d48f0ea9f424144a5211b7a155c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 May 2011 07:50:48 -0700 Subject: iwlagn: remove unused pad argument The pad argument to iwlagn_txq_free_tfd isn't used, remove it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index d34e103..9acf0e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -750,10 +750,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) spin_unlock(&priv->sta_lock); /* Attach buffers to TFD */ - iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1, 0); + iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1); if (secondlen > 0) iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, - secondlen, 0, 0); + secondlen, 0); scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + offsetof(struct iwl_tx_cmd, scratch); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 269e0c4..fc7dc06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -194,7 +194,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv); void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad); + dma_addr_t addr, u16 len, u8 reset); void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, struct ieee80211_tx_info *info); int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9daf964..38254bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -48,8 +48,6 @@ #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" -#define U32_PAD(n) ((4-(n))&0x3) - struct iwl_tx_queue; /* CT-KILL constants */ diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 302284b..a47558f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -182,7 +182,7 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, dma_addr_t addr, u16 len, - u8 reset, u8 pad) + u8 reset) { struct iwl_queue *q; struct iwl_tfd *tfd, *tfd_tmp; @@ -702,8 +702,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); - iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1, - U32_PAD(cmd->len[0])); + iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1); /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); -- cgit v0.10.2 From 4ce7cc2b09553a91d4aea014c39674685715173a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 13 May 2011 11:57:40 -0700 Subject: iwlagn: support multiple TBs per command The current "huge" command handling is a bit confusing, and very limited since only one command may be huge at a time. Additionally, we often copy data around quite pointlessly since we could instead map the existing scan buffer for example and use it directly. This patch makes that possible. The first change is that multiple buffers may be given to each command (this change was prepared earlier so callsites don't need to change). Each of those can be mapped attached to a TB in the TFD, and the command header can use a TB (the first one) in the TFD as well. Doing this allows getting rid of huge commands in favour of mapping existing buffers. The beacon transmission is also optimised to not copy the SKB at all but use multiple TBs. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 30e11c7..d39efcc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -87,7 +87,6 @@ int iwl_send_calib_results(struct iwl_priv *priv) struct iwl_host_cmd hcmd = { .id = REPLY_PHY_CALIBRATION_CMD, - .flags = CMD_SIZE_HUGE, }; for (i = 0; i < IWL_CALIB_MAX; i++) { @@ -95,6 +94,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) priv->calib_results[i].buf) { hcmd.len[0] = priv->calib_results[i].buf_len; hcmd.data[0] = priv->calib_results[i].buf; + hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; ret = iwl_send_cmd_sync(priv, &hcmd); if (ret) { IWL_ERR(priv, "Error %d iteration %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 576f45e..f803fb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1141,7 +1141,6 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, .len = { sizeof(struct iwl_scan_cmd), }, - .flags = CMD_SIZE_HUGE, }; struct iwl_scan_cmd *scan; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; @@ -1428,6 +1427,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) + scan->channel_count * sizeof(struct iwl_scan_channel); cmd.data[0] = scan; + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; scan->len = cpu_to_le16(cmd.len[0]); /* set scan bit here for PAN params */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 2bb08d7..675b9a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -134,12 +134,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_tx_beacon_cmd *tx_beacon_cmd; struct iwl_host_cmd cmd = { .id = REPLY_TX_BEACON, - .flags = CMD_SIZE_HUGE, }; u32 frame_size; u32 rate_flags; u32 rate; - int err; /* * We have to set up the TX command, the TX Beacon command, and the @@ -156,17 +154,15 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) if (WARN_ON(!priv->beacon_skb)) return -EINVAL; - /* Allocate beacon memory */ - tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len, - GFP_KERNEL); + /* Allocate beacon command */ + if (!priv->beacon_cmd) + priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL); + tx_beacon_cmd = priv->beacon_cmd; if (!tx_beacon_cmd) return -ENOMEM; frame_size = priv->beacon_skb->len; - /* Set up TX beacon contents */ - memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size); - /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; @@ -175,7 +171,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; /* Set up TX beacon command fields */ - iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, + iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data, frame_size); /* Set up packet rate and flags */ @@ -189,15 +185,14 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) rate_flags); /* Submit command */ - cmd.len[0] = sizeof(*tx_beacon_cmd) + frame_size; + cmd.len[0] = sizeof(*tx_beacon_cmd); cmd.data[0] = tx_beacon_cmd; + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; + cmd.len[1] = frame_size; + cmd.data[1] = priv->beacon_skb->data; + cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; - err = iwl_send_cmd_sync(priv, &cmd); - - /* Free temporary storage */ - kfree(tx_beacon_cmd); - - return err; + return iwl_send_cmd_sync(priv, &cmd); } static void iwl_bg_beacon_update(struct work_struct *work) @@ -3246,6 +3241,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) iwlcore_free_geos(priv); iwl_free_channel_map(priv); kfree(priv->scan_cmd); + kfree(priv->beacon_cmd); } struct ieee80211_ops iwlagn_hw_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 5fdad65..6ee5f1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -205,7 +205,6 @@ enum { #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) #define SEQ_TO_INDEX(s) ((s) & 0xff) #define INDEX_TO_SEQ(i) ((i) & 0xff) -#define SEQ_HUGE_FRAME cpu_to_le16(0x4000) #define SEQ_RX_FRAME cpu_to_le16(0x8000) /** @@ -234,9 +233,7 @@ struct iwl_cmd_header { * * 0:7 tfd index - position within TX queue * 8:12 TX queue id - * 13 reserved - * 14 huge - driver sets this to indicate command is in the - * 'huge' storage at the end of the command buffers + * 13:14 reserved * 15 unsolicited RX or uCode-originated notification */ __le16 sequence; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 38254bd..3e3b8b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -110,8 +110,6 @@ struct iwl_cmd_meta { struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt); - /* The CMD_SIZE_HUGE flag bit indicates that the command - * structure is stored at the end of the shared queue memory. */ u32 flags; DEFINE_DMA_UNMAP_ADDR(mapping); @@ -121,7 +119,23 @@ struct iwl_cmd_meta { /* * Generic queue structure * - * Contains common data for Rx and Tx queues + * Contains common data for Rx and Tx queues. + * + * Note the difference between n_bd and n_window: the hardware + * always assumes 256 descriptors, so n_bd is always 256 (unless + * there might be HW changes in the future). For the normal TX + * queues, n_window, which is the size of the software queue data + * is also 256; however, for the command queue, n_window is only + * 32 since we don't need so many commands pending. Since the HW + * still uses 256 BDs for DMA though, n_bd stays 256. As a result, + * the software buffers (in the variables @meta, @txb in struct + * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds + * in the same struct) have 256. + * This means that we end up with the following: + * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | + * SW entries: | 0 | ... | 31 | + * where N is a number between 0 and 7. This means that the SW + * data is a window overlayed over the HW queue. */ struct iwl_queue { int n_bd; /* number of BDs in this queue */ @@ -163,7 +177,7 @@ struct iwl_tx_info { struct iwl_tx_queue { struct iwl_queue q; - void *tfds; + struct iwl_tfd *tfds; struct iwl_device_cmd **cmd; struct iwl_cmd_meta *meta; struct iwl_tx_info *txb; @@ -245,7 +259,6 @@ enum { CMD_SYNC = 0, CMD_SIZE_NORMAL = 0, CMD_NO_SKB = 0, - CMD_SIZE_HUGE = (1 << 0), CMD_ASYNC = (1 << 1), CMD_WANT_SKB = (1 << 2), CMD_MAPPED = (1 << 3), @@ -257,8 +270,8 @@ enum { * struct iwl_device_cmd * * For allocation of the command and tx queues, this establishes the overall - * size of the largest command we send to uCode, except for a scan command - * (which is relatively huge; space is allocated separately). + * size of the largest command we send to uCode, except for commands that + * aren't fully copied and use other TFD space. */ struct iwl_device_cmd { struct iwl_cmd_header hdr; /* uCode API */ @@ -275,7 +288,11 @@ struct iwl_device_cmd { #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) -#define IWL_MAX_CMD_TFDS 1 +#define IWL_MAX_CMD_TFDS 2 + +enum iwl_hcmd_dataflag { + IWL_HCMD_DFL_NOCOPY = BIT(0), +}; struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; @@ -285,6 +302,7 @@ struct iwl_host_cmd { struct iwl_rx_packet *pkt); u32 flags; u16 len[IWL_MAX_CMD_TFDS]; + u8 dataflags[IWL_MAX_CMD_TFDS]; u8 id; }; @@ -687,17 +705,8 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i) } -static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) +static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) { - /* - * This is for init calibration result and scan command which - * required buffer > TFD_MAX_PAYLOAD_SIZE, - * the big buffer at end of command array - */ - if (is_huge) - return q->n_window; /* must be power of 2 */ - - /* Otherwise, use normal size buffers */ return index & (q->n_window - 1); } @@ -1451,6 +1460,7 @@ struct iwl_priv { struct work_struct beacon_update; struct iwl_rxon_context *beacon_ctx; struct sk_buff *beacon_skb; + void *beacon_cmd; struct work_struct tt_work; struct work_struct ct_enter; diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index f00172c..fc13186 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -137,20 +137,27 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, #define TRACE_SYSTEM iwlwifi TRACE_EVENT(iwlwifi_dev_hcmd, - TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), - TP_ARGS(priv, hcmd, len, flags), + TP_PROTO(struct iwl_priv *priv, u32 flags, + const void *hcmd0, size_t len0, + const void *hcmd1, size_t len1, + const void *hcmd2, size_t len2), + TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), TP_STRUCT__entry( PRIV_ENTRY - __dynamic_array(u8, hcmd, len) + __dynamic_array(u8, hcmd0, len0) + __dynamic_array(u8, hcmd1, len1) + __dynamic_array(u8, hcmd2, len2) __field(u32, flags) ), TP_fast_assign( PRIV_ASSIGN; - memcpy(__get_dynamic_array(hcmd), hcmd, len); + memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); + memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); + memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); __entry->flags = flags; ), TP_printk("[%p] hcmd %#.2x (%ssync)", - __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0], + __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], __entry->flags & CMD_ASYNC ? "a" : "") ); diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 01a8ec9..dd2904a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -200,6 +200,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," " len %d\n", cmd.id, cmd.flags, cmd.len[0]); /* ok, let's submit the command to ucode */ diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index a47558f..2f6b38c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -125,25 +125,13 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) return tfd->num_tbs & 0x1f; } -/** - * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] - * @priv - driver private data - * @txq - tx queue - * - * Does NOT advance any TFD circular buffer read/write indexes - * Does NOT free the TFD itself (which is within circular buffer) - */ -void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, + struct iwl_tfd *tfd) { - struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; - struct iwl_tfd *tfd; struct pci_dev *dev = priv->pci_dev; - int index = txq->q.read_ptr; int i; int num_tbs; - tfd = &tfd_tmp[index]; - /* Sanity check on number of chunks */ num_tbs = iwl_tfd_get_num_tbs(tfd); @@ -156,14 +144,30 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) /* Unmap tx_cmd */ if (num_tbs) pci_unmap_single(dev, - dma_unmap_addr(&txq->meta[index], mapping), - dma_unmap_len(&txq->meta[index], len), + dma_unmap_addr(meta, mapping), + dma_unmap_len(meta, len), PCI_DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); +} + +/** + * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] + * @priv - driver private data + * @txq - tx queue + * + * Does NOT advance any TFD circular buffer read/write indexes + * Does NOT free the TFD itself (which is within circular buffer) + */ +void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + struct iwl_tfd *tfd_tmp = txq->tfds; + int index = txq->q.read_ptr; + + iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]); /* free SKB */ if (txq->txb) { @@ -189,7 +193,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, u32 num_tbs; q = &txq->q; - tfd_tmp = (struct iwl_tfd *)txq->tfds; + tfd_tmp = txq->tfds; tfd = &tfd_tmp[q->write_ptr]; if (reset) @@ -303,7 +307,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) return; while (q->read_ptr != q->write_ptr) { - i = get_cmd_index(q, q->read_ptr, 0); + i = get_cmd_index(q, q->read_ptr); if (txq->meta[i].flags & CMD_MAPPED) { pci_unmap_single(priv->pci_dev, @@ -315,15 +319,6 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } - - i = q->n_window; - if (txq->meta[i].flags & CMD_MAPPED) { - pci_unmap_single(priv->pci_dev, - dma_unmap_addr(&txq->meta[i], mapping), - dma_unmap_len(&txq->meta[i], len), - PCI_DMA_BIDIRECTIONAL); - txq->meta[i].flags = 0; - } } /** @@ -343,7 +338,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) iwl_cmd_queue_unmap(priv); /* De-alloc array of command/tx buffers */ - for (i = 0; i <= TFD_CMD_SLOTS; i++) + for (i = 0; i < TFD_CMD_SLOTS; i++) kfree(txq->cmd[i]); /* De-alloc circular buffer of TFDs */ @@ -483,33 +478,17 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, { int i, len; int ret; - int actual_slots = slots_num; - - /* - * Alloc buffer array for commands (Tx or other types of commands). - * For the command queue (#4/#9), allocate command space + one big - * command for scan, since scan command is very huge; the system will - * not have two scans at the same time, so only one is needed. - * For normal Tx queues (all other queues), no super-size command - * space is needed. - */ - if (txq_id == priv->cmd_queue) - actual_slots++; - txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, + txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num, GFP_KERNEL); - txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots, + txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num, GFP_KERNEL); if (!txq->meta || !txq->cmd) goto out_free_arrays; len = sizeof(struct iwl_device_cmd); - for (i = 0; i < actual_slots; i++) { - /* only happens for cmd queue */ - if (i == slots_num) - len = IWL_MAX_CMD_SIZE; - + for (i = 0; i < slots_num; i++) { txq->cmd[i] = kmalloc(len, GFP_KERNEL); if (!txq->cmd[i]) goto err; @@ -544,7 +523,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, return 0; err: - for (i = 0; i < actual_slots; i++) + for (i = 0; i < slots_num; i++) kfree(txq->cmd[i]); out_free_arrays: kfree(txq->meta); @@ -592,23 +571,44 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) dma_addr_t phys_addr; unsigned long flags; u32 idx; - u16 fix_size; + u16 copy_size, cmd_size; bool is_ct_kill = false; + bool had_nocopy = false; + int i; + u8 *cmd_dest; +#ifdef CONFIG_IWLWIFI_DEVICE_TRACING + const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {}; + int trace_lens[IWL_MAX_CMD_TFDS + 1] = {}; + int trace_idx; +#endif - fix_size = (u16)(cmd->len[0] + sizeof(out_cmd->hdr)); + copy_size = sizeof(out_cmd->hdr); + cmd_size = sizeof(out_cmd->hdr); + + /* need one for the header if the first is NOCOPY */ + BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); + + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + if (!cmd->len[i]) + continue; + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { + had_nocopy = true; + } else { + /* NOCOPY must not be followed by normal! */ + if (WARN_ON(had_nocopy)) + return -EINVAL; + copy_size += cmd->len[i]; + } + cmd_size += cmd->len[i]; + } /* * 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. + * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically + * allocated into separate TFDs, then we will need to + * increase the size of the buffers. */ - 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)) + if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) return -EINVAL; if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { @@ -617,14 +617,6 @@ 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)) { @@ -639,7 +631,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -ENOSPC; } - idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); + idx = get_cmd_index(q, q->write_ptr); out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; @@ -654,55 +646,84 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (cmd->flags & CMD_ASYNC) out_meta->callback = cmd->callback; - out_cmd->hdr.cmd = cmd->id; - memcpy(&out_cmd->cmd.payload, cmd->data[0], cmd->len[0]); - - /* At this point, the out_cmd now has all of the incoming cmd - * information */ + /* set up the header */ + out_cmd->hdr.cmd = cmd->id; out_cmd->hdr.flags = 0; out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | - INDEX_TO_SEQ(q->write_ptr)); - if (cmd->flags & CMD_SIZE_HUGE) - out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; - -#ifdef CONFIG_IWLWIFI_DEBUG - switch (out_cmd->hdr.cmd) { - case REPLY_TX_LINK_QUALITY_CMD: - case SENSITIVITY_CMD: - IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, " - "%d bytes at %d[%d]:%d\n", - get_cmd_string(out_cmd->hdr.cmd), - out_cmd->hdr.cmd, - le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, priv->cmd_queue); - break; - default: - IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " - "%d bytes at %d[%d]:%d\n", - get_cmd_string(out_cmd->hdr.cmd), - out_cmd->hdr.cmd, - le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, priv->cmd_queue); + INDEX_TO_SEQ(q->write_ptr)); + + /* and copy the data that needs to be copied */ + + cmd_dest = &out_cmd->cmd.payload[0]; + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + if (!cmd->len[i]) + continue; + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) + break; + memcpy(cmd_dest, cmd->data[i], cmd->len[i]); + cmd_dest += cmd->len[i]; } -#endif + + IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " + "%d bytes at %d[%d]:%d\n", + get_cmd_string(out_cmd->hdr.cmd), + out_cmd->hdr.cmd, + le16_to_cpu(out_cmd->hdr.sequence), cmd_size, + q->write_ptr, idx, priv->cmd_queue); + phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, - fix_size, PCI_DMA_BIDIRECTIONAL); + copy_size, PCI_DMA_BIDIRECTIONAL); if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { idx = -ENOMEM; goto out; } dma_unmap_addr_set(out_meta, mapping, phys_addr); - dma_unmap_len_set(out_meta, len, fix_size); + dma_unmap_len_set(out_meta, len, copy_size); + + iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, copy_size, 1); +#ifdef CONFIG_IWLWIFI_DEVICE_TRACING + trace_bufs[0] = &out_cmd->hdr; + trace_lens[0] = copy_size; + trace_idx = 1; +#endif + + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + if (!cmd->len[i]) + continue; + if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) + continue; + phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], + cmd->len[i], PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { + iwlagn_unmap_tfd(priv, out_meta, + &txq->tfds[q->write_ptr]); + idx = -ENOMEM; + goto out; + } + + iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, + cmd->len[i], 0); +#ifdef CONFIG_IWLWIFI_DEVICE_TRACING + trace_bufs[trace_idx] = cmd->data[i]; + trace_lens[trace_idx] = cmd->len[i]; + trace_idx++; +#endif + } out_meta->flags = cmd->flags | CMD_MAPPED; txq->need_update = 1; - trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); - - iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, fix_size, 1); + /* check that tracing gets all possible blocks */ + BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); +#ifdef CONFIG_IWLWIFI_DEVICE_TRACING + trace_iwlwifi_dev_hcmd(priv, cmd->flags, + trace_bufs[0], trace_lens[0], + trace_bufs[1], trace_lens[1], + trace_bufs[2], trace_lens[2]); +#endif /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); @@ -761,7 +782,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); int cmd_index; - bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; @@ -779,14 +799,11 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) return; } - cmd_index = get_cmd_index(&txq->q, index, huge); + cmd_index = get_cmd_index(&txq->q, index); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; - pci_unmap_single(priv->pci_dev, - dma_unmap_addr(meta, mapping), - dma_unmap_len(meta, len), - PCI_DMA_BIDIRECTIONAL); + iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { -- cgit v0.10.2 From 5065054790b111bf677b1eccf3f8f76f20cc0ae6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 4 May 2011 16:56:52 -0700 Subject: iwlagn: more ucode error log info No functional changes, just logging more information when uCode crash, also change change the format. Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 675b9a6..a7054a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1622,10 +1622,7 @@ static const char *desc_lookup(u32 num) void iwl_dump_nic_error_log(struct iwl_priv *priv) { - u32 data2, line; - u32 desc, time, count, base, data1; - u32 blink1, blink2, ilink1, ilink2; - u32 pc, hcmd; + u32 base; struct iwl_error_event_table table; base = priv->device_pointers.error_event_table; @@ -1648,37 +1645,40 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); - count = table.valid; - - if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { + if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(priv, "Start IWL Error Log Dump:\n"); IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", - priv->status, count); - } - - desc = table.error_id; - priv->isr_stats.err_code = desc; - pc = table.pc; - blink1 = table.blink1; - blink2 = table.blink2; - ilink1 = table.ilink1; - ilink2 = table.ilink2; - data1 = table.data1; - data2 = table.data2; - line = table.line; - time = table.tsf_low; - hcmd = table.hcmd; - - trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, - blink1, blink2, ilink1, ilink2); - - IWL_ERR(priv, "Desc Time " - "data1 data2 line\n"); - IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", - desc_lookup(desc), desc, time, data1, data2, line); - IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); - IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", - pc, blink1, blink2, ilink1, ilink2, hcmd); + priv->status, table.valid); + } + + priv->isr_stats.err_code = table.error_id; + + trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low, + table.data1, table.data2, table.line, + table.blink1, table.blink2, table.ilink1, + table.ilink2, table.bcon_time, table.gp1, + table.gp2, table.gp3, table.ucode_ver, + table.hw_ver, table.brd_ver); + IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, + desc_lookup(table.error_id)); + IWL_ERR(priv, "0x%08X | uPc\n", table.pc); + IWL_ERR(priv, "0x%08X | branchlink1\n", table.blink1); + IWL_ERR(priv, "0x%08X | branchlink2\n", table.blink2); + IWL_ERR(priv, "0x%08X | interruptlink1\n", table.ilink1); + IWL_ERR(priv, "0x%08X | interruptlink2\n", table.ilink2); + IWL_ERR(priv, "0x%08X | data1\n", table.data1); + IWL_ERR(priv, "0x%08X | data2\n", table.data2); + IWL_ERR(priv, "0x%08X | line\n", table.line); + IWL_ERR(priv, "0x%08X | beacon time\n", table.bcon_time); + IWL_ERR(priv, "0x%08X | tsf low\n", table.tsf_low); + IWL_ERR(priv, "0x%08X | tsf hi\n", table.tsf_hi); + IWL_ERR(priv, "0x%08X | time gp1\n", table.gp1); + IWL_ERR(priv, "0x%08X | time gp2\n", table.gp2); + IWL_ERR(priv, "0x%08X | time gp3\n", table.gp3); + IWL_ERR(priv, "0x%08X | uCode version\n", table.ucode_ver); + IWL_ERR(priv, "0x%08X | hw version\n", table.hw_ver); + IWL_ERR(priv, "0x%08X | board version\n", table.brd_ver); + IWL_ERR(priv, "0x%08X | hcmd\n", table.hcmd); } #define EVENT_START_OFFSET (4 * sizeof(u32)) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index fc13186..2c84ba95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -209,15 +209,18 @@ TRACE_EVENT(iwlwifi_dev_tx, ); TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time, + TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low, u32 data1, u32 data2, u32 line, u32 blink1, - u32 blink2, u32 ilink1, u32 ilink2), - TP_ARGS(priv, desc, time, data1, data2, line, - blink1, blink2, ilink1, ilink2), + u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, + u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, + u32 brd_ver), + TP_ARGS(priv, desc, tsf_low, data1, data2, line, + blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, + gp3, ucode_ver, hw_ver, brd_ver), TP_STRUCT__entry( PRIV_ENTRY __field(u32, desc) - __field(u32, time) + __field(u32, tsf_low) __field(u32, data1) __field(u32, data2) __field(u32, line) @@ -225,11 +228,18 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __field(u32, blink2) __field(u32, ilink1) __field(u32, ilink2) + __field(u32, bcon_time) + __field(u32, gp1) + __field(u32, gp2) + __field(u32, gp3) + __field(u32, ucode_ver) + __field(u32, hw_ver) + __field(u32, brd_ver) ), TP_fast_assign( PRIV_ASSIGN; __entry->desc = desc; - __entry->time = time; + __entry->tsf_low = tsf_low; __entry->data1 = data1; __entry->data2 = data2; __entry->line = line; @@ -237,12 +247,25 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __entry->blink2 = blink2; __entry->ilink1 = ilink1; __entry->ilink2 = ilink2; + __entry->bcon_time = bcon_time; + __entry->gp1 = gp1; + __entry->gp2 = gp2; + __entry->gp3 = gp3; + __entry->ucode_ver = ucode_ver; + __entry->hw_ver = hw_ver; + __entry->brd_ver = brd_ver; ), TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " - "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X", - __entry->priv, __entry->desc, __entry->time, __entry->data1, + "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " + "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " + "hw 0x%08X brd 0x%08X", + __entry->priv, __entry->desc, __entry->tsf_low, + __entry->data1, __entry->data2, __entry->line, __entry->blink1, - __entry->blink2, __entry->ilink1, __entry->ilink2) + __entry->blink2, __entry->ilink1, __entry->ilink2, + __entry->bcon_time, __entry->gp1, __entry->gp2, + __entry->gp3, __entry->ucode_ver, __entry->hw_ver, + __entry->brd_ver) ); TRACE_EVENT(iwlwifi_dev_ucode_event, -- cgit v0.10.2 From 7a4e5281d1b3335a3dc90841415390473cccebf3 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 May 2011 10:21:28 -0700 Subject: iwlagn: add testmode trace command Adding testmode trace/debug capability Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a7054a5..e027f99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3659,6 +3659,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) */ set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_testmode_cleanup(priv); iwl_leds_exit(priv); if (priv->mac80211_registered) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index fc7dc06..2495fe7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -343,6 +343,7 @@ extern int iwl_alive_start(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); extern void iwl_testmode_init(struct iwl_priv *priv); +extern void iwl_testmode_cleanup(struct iwl_priv *priv); #else static inline int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) @@ -353,6 +354,10 @@ static inline void iwl_testmode_init(struct iwl_priv *priv) { } +static inline +void iwl_testmode_cleanup(struct iwl_priv *priv) +{ +} #endif #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 3e3b8b8..12fb2f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1179,6 +1179,14 @@ enum iwl_scan_type { IWL_SCAN_OFFCH_TX, }; +#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL +struct iwl_testmode_trace { + u8 *cpu_addr; + u8 *trace_addr; + dma_addr_t dma_addr; + bool trace_enabled; +}; +#endif struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1510,6 +1518,9 @@ struct iwl_priv { struct led_classdev led; unsigned long blink_on, blink_off; bool led_registered; +#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL + struct iwl_testmode_trace testmode_trace; +#endif }; /*iwl_priv */ static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index dd2904a..b778c3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -97,6 +97,10 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, + + [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, + }; /* @@ -167,6 +171,31 @@ nla_put_failure: void iwl_testmode_init(struct iwl_priv *priv) { priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + priv->testmode_trace.trace_enabled = false; +} + +static void iwl_trace_cleanup(struct iwl_priv *priv) +{ + struct device *dev = &priv->pci_dev->dev; + + if (priv->testmode_trace.trace_enabled) { + if (priv->testmode_trace.cpu_addr && + priv->testmode_trace.dma_addr) + dma_free_coherent(dev, + TRACE_TOTAL_SIZE, + priv->testmode_trace.cpu_addr, + priv->testmode_trace.dma_addr); + priv->testmode_trace.trace_enabled = false; + priv->testmode_trace.cpu_addr = NULL; + priv->testmode_trace.trace_addr = NULL; + priv->testmode_trace.dma_addr = 0; + } +} + + +void iwl_testmode_cleanup(struct iwl_priv *priv) +{ + iwl_trace_cleanup(priv); } /* @@ -400,6 +429,102 @@ nla_put_failure: return -EMSGSIZE; } + +/* + * This function handles the user application commands for uCode trace + * + * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the + * handlers respectively. + * + * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned + * value of the actual command execution is replied to the user application. + * + * @hw: ieee80211_hw object that represents the device + * @tb: gnl message fields from the user space + */ +static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) +{ + struct iwl_priv *priv = hw->priv; + struct sk_buff *skb; + int status = 0; + struct device *dev = &priv->pci_dev->dev; + + switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { + case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: + if (priv->testmode_trace.trace_enabled) + return -EBUSY; + + priv->testmode_trace.cpu_addr = + dma_alloc_coherent(dev, + TRACE_TOTAL_SIZE, + &priv->testmode_trace.dma_addr, + GFP_KERNEL); + if (!priv->testmode_trace.cpu_addr) + return -ENOMEM; + priv->testmode_trace.trace_enabled = true; + priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( + priv->testmode_trace.cpu_addr, 0x100); + memset(priv->testmode_trace.trace_addr, 0x03B, + TRACE_BUFF_SIZE); + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, + sizeof(priv->testmode_trace.dma_addr) + 20); + if (!skb) { + IWL_DEBUG_INFO(priv, + "Error allocating memory\n"); + iwl_trace_cleanup(priv); + return -ENOMEM; + } + NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR, + sizeof(priv->testmode_trace.dma_addr), + (u64 *)&priv->testmode_trace.dma_addr); + status = cfg80211_testmode_reply(skb); + if (status < 0) { + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", + status); + } + break; + + case IWL_TM_CMD_APP2DEV_END_TRACE: + iwl_trace_cleanup(priv); + break; + + case IWL_TM_CMD_APP2DEV_READ_TRACE: + if (priv->testmode_trace.trace_enabled && + priv->testmode_trace.trace_addr) { + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, + 20 + TRACE_BUFF_SIZE); + if (skb == NULL) { + IWL_DEBUG_INFO(priv, + "Error allocating memory\n"); + return -ENOMEM; + } + NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, + TRACE_BUFF_SIZE, + priv->testmode_trace.trace_addr); + status = cfg80211_testmode_reply(skb); + if (status < 0) { + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", status); + } + } else + return -EFAULT; + break; + + default: + IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); + return -ENOSYS; + } + return status; + +nla_put_failure: + kfree_skb(skb); + if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) == + IWL_TM_CMD_APP2DEV_BEGIN_TRACE) + iwl_trace_cleanup(priv); + return -EMSGSIZE; +} + /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then * invoke the corresponding handlers. @@ -459,6 +584,14 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; + + case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: + case IWL_TM_CMD_APP2DEV_END_TRACE: + case IWL_TM_CMD_APP2DEV_READ_TRACE: + IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n"); + result = iwl_testmode_trace(hw, tb); + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); result = -ENOSYS; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 31f8949..34634ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -91,6 +91,10 @@ enum iwl_tm_cmd_t { /* if there is other new command for the driver layer operation, * append them here */ + /* commands fom user space for uCode trace operations */ + IWL_TM_CMD_APP2DEV_BEGIN_TRACE, + IWL_TM_CMD_APP2DEV_END_TRACE, + IWL_TM_CMD_APP2DEV_READ_TRACE, /* commands from kernel space to carry the synchronous response * to user application */ @@ -144,8 +148,19 @@ enum iwl_tm_attr_t { * application */ IWL_TM_ATTR_UCODE_RX_PKT, + /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, + * The mandatory fields are: + * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address + */ + IWL_TM_ATTR_TRACE_ADDR, + IWL_TM_ATTR_TRACE_DATA, + IWL_TM_ATTR_MAX, }; +/* uCode trace buffer */ +#define TRACE_BUFF_SIZE 0x20000 +#define TRACE_BUFF_PADD 0x2000 +#define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD) #endif -- cgit v0.10.2 From 4babc358c0a1bced6bed2c9d6c77fc8803b8a22f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 3 May 2011 18:05:12 -0700 Subject: iwlagn: add eeprom command to testmode Add the capability to dump eeprom through testmode request Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index b778c3f..e77ccaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -98,6 +98,8 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, @@ -418,6 +420,29 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) "Error starting the device: %d\n", status); break; + case IWL_TM_CMD_APP2DEV_GET_EEPROM: + if (priv->eeprom) { + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, + priv->cfg->base_params->eeprom_size + 20); + if (!skb) { + IWL_DEBUG_INFO(priv, + "Error allocating memory\n"); + return -ENOMEM; + } + NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, + IWL_TM_CMD_DEV2APP_EEPROM_RSP); + NLA_PUT(skb, IWL_TM_ATTR_EEPROM, + priv->cfg->base_params->eeprom_size, + priv->eeprom); + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", + status); + } else + return -EFAULT; + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); return -ENOSYS; @@ -581,6 +606,7 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: + case IWL_TM_CMD_APP2DEV_GET_EEPROM: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 34634ec..4171d29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -88,6 +88,7 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, + IWL_TM_CMD_APP2DEV_GET_EEPROM, /* if there is other new command for the driver layer operation, * append them here */ @@ -103,6 +104,11 @@ enum iwl_tm_cmd_t { /* commands from kernel space to multicast the spontaneous messages * to user application */ IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, + + /* commands from kernel space to carry the eeprom response + * to user application */ + IWL_TM_CMD_DEV2APP_EEPROM_RSP, + IWL_TM_CMD_MAX, }; @@ -148,6 +154,12 @@ enum iwl_tm_attr_t { * application */ IWL_TM_ATTR_UCODE_RX_PKT, + /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM, + * The mandatory fields are: + * IWL_TM_ATTR_EEPROM for the data content responging to the user + * application */ + IWL_TM_ATTR_EEPROM, + /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, * The mandatory fields are: * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address -- cgit v0.10.2 From 6489854b9cbc2faa6709532e61c3ea221cf8583b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 3 May 2011 18:05:13 -0700 Subject: iwlagn: add testmode set fixed rate command Add support in testmode for setting fixed rate Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index dbe6295..432f839 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -335,6 +335,32 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data, return tid; } +#if defined(CONFIG_MAC80211_DEBUGFS) || defined(CONFIG_IWLWIFI_DEVICE_SVTOOL) +static void rs_program_fix_rate(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta) +{ + struct iwl_station_priv *sta_priv = + container_of(lq_sta, struct iwl_station_priv, lq_sta); + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ + lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + + lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate; + + IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", + lq_sta->lq.sta_id, priv->dbg_fixed_rate); + + if (priv->dbg_fixed_rate) { + rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate); + iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, + false); + } +} +#endif + /* get the traffic load value for tid */ @@ -1046,7 +1072,10 @@ done: /* See if there's a better rate or modulation mode to try. */ if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); - +#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL + if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate) + rs_program_fix_rate(priv, lq_sta); +#endif if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) rs_bt_update_lq(priv, ctx, lq_sta); } @@ -2871,6 +2900,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; + priv->dbg_fixed_rate = 0; #ifdef CONFIG_MAC80211_DEBUGFS lq_sta->dbg_fixed_rate = 0; #endif @@ -3045,7 +3075,6 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, IWL_DEBUG_RATE(priv, "leave\n"); } - #ifdef CONFIG_MAC80211_DEBUGFS static int open_file_generic(struct inode *inode, struct file *file) { @@ -3070,6 +3099,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); } else { lq_sta->dbg_fixed_rate = 0; + priv->dbg_fixed_rate = 0; IWL_ERR(priv, "Invalid antenna selection 0x%X, Valid is 0x%X\n", ant_sel_tx, valid_tx_ant); @@ -3088,9 +3118,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, char buf[64]; int buf_size; u32 parsed_rate; - struct iwl_station_priv *sta_priv = - container_of(lq_sta, struct iwl_station_priv, lq_sta); - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + priv = lq_sta->drv; memset(buf, 0, sizeof(buf)); @@ -3099,23 +3127,11 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, return -EFAULT; if (sscanf(buf, "%x", &parsed_rate) == 1) - lq_sta->dbg_fixed_rate = parsed_rate; + priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate; else - lq_sta->dbg_fixed_rate = 0; - - lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ - lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ - lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ - lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ - - IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", - lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); + priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0; - if (lq_sta->dbg_fixed_rate) { - rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); - iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, - false); - } + rs_program_fix_rate(priv, lq_sta); return count; } @@ -3143,7 +3159,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, lq_sta->total_failed, lq_sta->total_success, lq_sta->active_legacy_rate); desc += sprintf(buff+desc, "fixed rate 0x%X\n", - lq_sta->dbg_fixed_rate); + priv->dbg_fixed_rate); desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 12fb2f4..ab29ab5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1521,6 +1521,8 @@ struct iwl_priv { #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL struct iwl_testmode_trace testmode_trace; #endif + u32 dbg_fixed_rate; + }; /*iwl_priv */ static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index e77ccaa..69b7e6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -103,6 +103,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, }; /* @@ -443,6 +444,15 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) return -EFAULT; break; + case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: + if (!tb[IWL_TM_ATTR_FIXRATE]) { + IWL_DEBUG_INFO(priv, + "Error finding fixrate setting\n"); + return -ENOMSG; + } + priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); return -ENOSYS; @@ -607,6 +617,7 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: case IWL_TM_CMD_APP2DEV_GET_EEPROM: + case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 4171d29..a88085e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -89,6 +89,7 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, IWL_TM_CMD_APP2DEV_GET_EEPROM, + IWL_TM_CMD_APP2DEV_FIXRATE_REQ, /* if there is other new command for the driver layer operation, * append them here */ @@ -167,6 +168,12 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_TRACE_ADDR, IWL_TM_ATTR_TRACE_DATA, + /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, + * The mandatory fields are: + * IWL_TM_ATTR_FIXRATE for the fixed rate + */ + IWL_TM_ATTR_FIXRATE, + IWL_TM_ATTR_MAX, }; -- cgit v0.10.2 From dd5c940b42c1734e501d9494f7b99566b50a5a87 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 May 2011 17:06:43 -0700 Subject: iwlagn: clear STATUS_HCMD_ACTIVE bit if fail enqueue If fail to enqueue host command, clear the STATUS_hcmD_ACTIVE bit Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 1ff1f31..76f9966 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -188,6 +188,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) cmd_idx = iwl_enqueue_hcmd(priv, cmd); if (cmd_idx < 0) { ret = cmd_idx; + clear_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; -- cgit v0.10.2 From 3083d03c215a2d1642dd12ede7ad61e24601b583 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 May 2011 17:06:44 -0700 Subject: iwlagn: alwasy send RXON with disassociate falge before associate Before send the RXON command with associated flag set, always do disassociate first to make sure uCode is in the correct state. Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 0238743..7d40e2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -389,11 +389,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * AP station must be done after the BSSID is set to correctly * set up filters in the device. */ - if ((old_assoc && new_assoc) || !new_assoc) { - ret = iwlagn_rxon_disconn(priv, ctx); - if (ret) - return ret; - } + ret = iwlagn_rxon_disconn(priv, ctx); + if (ret) + return ret; if (new_assoc) return iwlagn_rxon_connect(priv, ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 2f6b38c..54a935f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -582,6 +582,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int trace_idx; #endif + if (test_bit(STATUS_FW_ERROR, &priv->status)) { + IWL_WARN(priv, "fw recovery, no hcmd send\n"); + return -EIO; + } + copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); -- cgit v0.10.2 From 70817b5e14760dad49a067fc3dd137bccd3c2960 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 11 May 2011 03:29:25 -0700 Subject: iwlagn: remove set but unused vars gcc is warning that a few variables in rate scaling are set but never otherwise used. This pointed out a few simplifications. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 432f839..c38ba7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2199,11 +2199,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) * setup rate table in uCode * return rate_n_flags as used in the table */ -static u32 rs_update_rate_tbl(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct iwl_lq_sta *lq_sta, - struct iwl_scale_tbl_info *tbl, - int index, u8 is_green) +static void rs_update_rate_tbl(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + int index, u8 is_green) { u32 rate; @@ -2211,8 +2211,6 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv, rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); rs_fill_link_cmd(priv, lq_sta, rate); iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); - - return rate; } /* @@ -2241,7 +2239,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, u8 update_lq = 0; struct iwl_scale_tbl_info *tbl, *tbl1; u16 rate_scale_index_msk = 0; - u32 rate; u8 is_green = 0; u8 active_tbl = 0; u8 done_search = 0; @@ -2328,8 +2325,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ index = iwl_hwrate_to_plcp_idx(tbl->current_rate); - rate = rs_update_rate_tbl(priv, ctx, lq_sta, - tbl, index, is_green); + rs_update_rate_tbl(priv, ctx, lq_sta, tbl, + index, is_green); } return; } @@ -2570,8 +2567,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - rate = rs_update_rate_tbl(priv, ctx, lq_sta, - tbl, index, is_green); + rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { /* Should we stay with this modulation mode, @@ -3270,14 +3266,10 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = { static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - char buff[120]; - int desc = 0; - struct iwl_lq_sta *lq_sta = file->private_data; - struct iwl_priv *priv; struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; - - priv = lq_sta->drv; + char buff[120]; + int desc = 0; if (is_Ht(tbl->lq_type)) desc += sprintf(buff+desc, diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c839796..47a56bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -216,15 +216,14 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv) static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) { - u32 otpgp; + iwl_read32(priv, CSR_OTP_GP_REG); - otpgp = iwl_read32(priv, CSR_OTP_GP_REG); if (mode == IWL_OTP_ACCESS_ABSOLUTE) iwl_clear_bit(priv, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_OTP_ACCESS_MODE); + CSR_OTP_GP_REG_OTP_ACCESS_MODE); else iwl_set_bit(priv, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_OTP_ACCESS_MODE); + CSR_OTP_GP_REG_OTP_ACCESS_MODE); } static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) -- cgit v0.10.2 From 51b7ef058c44c15af20ab4f7aed1dbb959cbd06d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 11 May 2011 08:17:20 -0700 Subject: iwlagn: change default beacon interval When the PAN context is active, but unused, it may still block scans that take more dwell time than its beacon interval (which is odd). Work around this problem by using a default beacon interval of 200 so scans will fit between. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ab29ab5..22a6e3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -81,7 +81,7 @@ struct iwl_tx_queue; #define MAX_RTS_THRESHOLD 2347U #define MAX_MSDU_SIZE 2304U #define MAX_MPDU_SIZE 2346U -#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_BEACON_INTERVAL 200U #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -- cgit v0.10.2 From 6dc0c7fc7cc0f5ec3d92a3076dfe45028540e526 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 11 May 2011 08:33:55 -0700 Subject: iwlagn: remove unused old_assoc parameter old_assoc not used, remove it Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 7d40e2d..a95ad84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -289,7 +289,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active = (void *)&ctx->active; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); - bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; lockdep_assert_held(&priv->mutex); -- cgit v0.10.2 From 9368a9a2378ab721f82f59430a135b4ce4ff5109 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 13 May 2011 21:47:23 +0200 Subject: p54usb: add zoom 4410 usbid Cc: Reported-by: Mark Davis Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index e183587..a8f3bc7 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -82,6 +82,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ + {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ -- cgit v0.10.2 From 011159a0a746e03ae42d559ce5c2a70138da3129 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 14 May 2011 00:12:48 +0300 Subject: airo: correct proc entry creation interfaces * use proc_mkdir_mode() instead of create_proc_entry(S_IFDIR|...), export proc_mkdir_mode() for that, oh well. * don't supply S_IFREG to proc_create_data(), it's unnecessary Signed-off-by: Alexey Dobriyan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 57a79b0..eb050ef 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -4500,17 +4500,15 @@ static int setup_proc_entry( struct net_device *dev, struct proc_dir_entry *entry; /* First setup the device directory */ strcpy(apriv->proc_name,dev->name); - apriv->proc_entry = create_proc_entry(apriv->proc_name, - S_IFDIR|airo_perm, - airo_entry); + apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, + airo_entry); if (!apriv->proc_entry) goto fail; apriv->proc_entry->uid = proc_uid; apriv->proc_entry->gid = proc_gid; /* Setup the StatsDelta */ - entry = proc_create_data("StatsDelta", - S_IFREG | (S_IRUGO&proc_perm), + entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev); if (!entry) goto fail_stats_delta; @@ -4518,8 +4516,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the Stats */ - entry = proc_create_data("Stats", - S_IFREG | (S_IRUGO&proc_perm), + entry = proc_create_data("Stats", S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev); if (!entry) goto fail_stats; @@ -4527,8 +4524,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the Status */ - entry = proc_create_data("Status", - S_IFREG | (S_IRUGO&proc_perm), + entry = proc_create_data("Status", S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev); if (!entry) goto fail_status; @@ -4536,8 +4532,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the Config */ - entry = proc_create_data("Config", - S_IFREG | proc_perm, + entry = proc_create_data("Config", proc_perm, apriv->proc_entry, &proc_config_ops, dev); if (!entry) goto fail_config; @@ -4545,8 +4540,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the SSID */ - entry = proc_create_data("SSID", - S_IFREG | proc_perm, + entry = proc_create_data("SSID", proc_perm, apriv->proc_entry, &proc_SSID_ops, dev); if (!entry) goto fail_ssid; @@ -4554,8 +4548,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the APList */ - entry = proc_create_data("APList", - S_IFREG | proc_perm, + entry = proc_create_data("APList", proc_perm, apriv->proc_entry, &proc_APList_ops, dev); if (!entry) goto fail_aplist; @@ -4563,8 +4556,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the BSSList */ - entry = proc_create_data("BSSList", - S_IFREG | proc_perm, + entry = proc_create_data("BSSList", proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev); if (!entry) goto fail_bsslist; @@ -4572,8 +4564,7 @@ static int setup_proc_entry( struct net_device *dev, entry->gid = proc_gid; /* Setup the WepKey */ - entry = proc_create_data("WepKey", - S_IFREG | proc_perm, + entry = proc_create_data("WepKey", proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev); if (!entry) goto fail_wepkey; @@ -5705,9 +5696,7 @@ static int __init airo_init_module( void ) { int i; - airo_entry = create_proc_entry("driver/aironet", - S_IFDIR | airo_perm, - NULL); + airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); if (airo_entry) { airo_entry->uid = proc_uid; diff --git a/fs/proc/generic.c b/fs/proc/generic.c index f128133..f1637f1 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -674,6 +674,7 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode, } return ent; } +EXPORT_SYMBOL(proc_mkdir_mode); struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, struct proc_dir_entry *parent) -- cgit v0.10.2 From d0df9eecf9f61f70fd847656f5eb113e06e46a03 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Fri, 13 May 2011 14:16:07 -0700 Subject: mac80211: Deactivate mesh path timers when freeing nodes Mesh paths are deleted via mesh_path_del() which properly deactivates the timer associated to a mesh path. But if paths were deleted by mesh_table_free(..., true) timers would not be deactivated. This fixes this case. Reported-by: Johannes Berg Signed-off-by: Javier Cardona Signed-off-by: John W. Linville diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 0aa96cd..f775202 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -719,8 +719,10 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs) struct mpath_node *node = hlist_entry(p, struct mpath_node, list); mpath = node->mpath; hlist_del_rcu(p); - if (free_leafs) + if (free_leafs) { + del_timer_sync(&mpath->timer); kfree(mpath); + } kfree(node); } -- cgit v0.10.2 From dedb1eb977d75f301b17190cc4b6e7d17dbf17db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 14 May 2011 00:04:38 +0200 Subject: b43: rename b43_wldev's field with ssb_device to sdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We free name "dev" for something generic (like dev abstraction layer). Additionaly code is cleaner now, especially magic dev->dev-dev chains. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index bd4cb75..fd69d6a 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -705,7 +705,7 @@ enum { /* Data structure for one wireless device (802.11 core) */ struct b43_wldev { - struct ssb_device *dev; + struct ssb_device *sdev; struct b43_wl *wl; /* The device initialization status. @@ -879,22 +879,22 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) { - return ssb_read16(dev->dev, offset); + return ssb_read16(dev->sdev, offset); } static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) { - ssb_write16(dev->dev, offset, value); + ssb_write16(dev->sdev, offset, value); } static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { - return ssb_read32(dev->dev, offset); + return ssb_read32(dev->sdev, offset); } static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) { - ssb_write32(dev->dev, offset, value); + ssb_write32(dev->sdev, offset, value); } static inline bool b43_using_pio_transfers(struct b43_wldev *dev) diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index ff0f5ba..10cfba3 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -80,7 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring, addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addr |= ssb_dma_translation(ring->dev->dev); + addr |= ssb_dma_translation(ring->dev->sdev); ctl = bufsize & B43_DMA32_DCTL_BYTECNT; if (slot == ring->nr_slots - 1) ctl |= B43_DMA32_DCTL_DTABLEEND; @@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring, addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addrhi |= (ssb_dma_translation(ring->dev->dev) << 1); + addrhi |= (ssb_dma_translation(ring->dev->sdev) << 1); if (slot == ring->nr_slots - 1) ctl0 |= B43_DMA64_DCTL0_DTABLEEND; if (start) @@ -333,10 +333,10 @@ static inline dma_addr_t dmaaddr; if (tx) { - dmaaddr = dma_map_single(ring->dev->dev->dma_dev, + dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, buf, len, DMA_TO_DEVICE); } else { - dmaaddr = dma_map_single(ring->dev->dev->dma_dev, + dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, buf, len, DMA_FROM_DEVICE); } @@ -348,10 +348,10 @@ static inline dma_addr_t addr, size_t len, int tx) { if (tx) { - dma_unmap_single(ring->dev->dev->dma_dev, + dma_unmap_single(ring->dev->sdev->dma_dev, addr, len, DMA_TO_DEVICE); } else { - dma_unmap_single(ring->dev->dev->dma_dev, + dma_unmap_single(ring->dev->sdev->dma_dev, addr, len, DMA_FROM_DEVICE); } } @@ -361,7 +361,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_cpu(ring->dev->dev->dma_dev, + dma_sync_single_for_cpu(ring->dev->sdev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -370,7 +370,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_device(ring->dev->dev->dma_dev, + dma_sync_single_for_device(ring->dev->sdev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) */ if (ring->type == B43_DMA_64BIT) flags |= GFP_DMA; - ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, + ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, &(ring->dmabase), flags); if (!ring->descbase) { @@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring) { - dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, + dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase, ring->dmabase); } @@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, dma_addr_t addr, size_t buffersize, bool dma_to_device) { - if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) + if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr))) return 1; switch (ring->type) { @@ -658,7 +658,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring) int err = 0; u32 value; u32 addrext; - u32 trans = ssb_dma_translation(ring->dev->dev); + u32 trans = ssb_dma_translation(ring->dev->sdev); if (ring->tx) { if (ring->type == B43_DMA_64BIT) { @@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->dev->dma_dev, + dma_test = dma_map_single(dev->sdev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = dma_map_single(dev->dev->dma_dev, + dma_test = dma_map_single(dev->sdev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, } } - dma_unmap_single(dev->dev->dma_dev, + dma_unmap_single(dev->sdev->dma_dev, dma_test, b43_txhdr_size(dev), DMA_TO_DEVICE); } @@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask(dev->dev->dma_dev, mask); + err = dma_set_mask(dev->sdev->dma_dev, mask); if (!err) { - err = dma_set_coherent_mask(dev->dev->dma_dev, mask); + err = dma_set_coherent_mask(dev->sdev->dma_dev, mask); if (!err) break; } @@ -1084,7 +1084,7 @@ int b43_dma_init(struct b43_wldev *dev) goto err_destroy_mcast; /* No support for the TX status DMA ring. */ - B43_WARN_ON(dev->dev->id.revision < 5); + B43_WARN_ON(dev->sdev->id.revision < 5); b43dbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type); diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index c587115..0cafafe 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, led->led_dev.default_trigger = default_trigger; led->led_dev.brightness_set = b43_led_brightness_set; - err = led_classdev_register(dev->dev->dev, &led->led_dev); + err = led_classdev_register(dev->sdev->dev, &led->led_dev); if (err) { b43warn(dev->wl, "LEDs: Failed to register %s\n", name); led->wl = NULL; @@ -215,7 +215,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, enum b43_led_behaviour *behaviour, bool *activelow) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; u8 sprom[4]; sprom[0] = bus->sprom.gpio0; diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 94e4f13..2ef7d4b 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, rfover |= pga; rfover |= lna; rfover |= trsw_rx; - if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) + if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && phy->rev > 6) rfover |= B43_PHY_RFOVERVAL_EXTLNA; @@ -387,7 +387,7 @@ struct lo_g_saved_values { static void lo_measure_setup(struct b43_wldev *dev, struct lo_g_saved_values *sav) { - struct ssb_sprom *sprom = &dev->dev->bus->sprom; + struct ssb_sprom *sprom = &dev->sdev->bus->sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_txpower_lo_control *lo = gphy->lo_control; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index a96e05a..ea58e27 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -547,7 +547,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) { u32 low, high; - B43_WARN_ON(dev->dev->id.revision < 3); + B43_WARN_ON(dev->sdev->id.revision < 3); /* The hardware guarantees us an atomic read, if we * read the low register first. */ @@ -585,7 +585,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) { u32 low, high; - B43_WARN_ON(dev->dev->id.revision < 3); + B43_WARN_ON(dev->sdev->id.revision < 3); low = tsf; high = (tsf >> 32); @@ -713,7 +713,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) b43_ram_write(dev, i * 4, buffer[i]); b43_write16(dev, 0x0568, 0x0000); - if (dev->dev->id.revision < 11) + if (dev->sdev->id.revision < 11) b43_write16(dev, 0x07C0, 0x0000); else b43_write16(dev, 0x07C0, 0x0100); @@ -1131,7 +1131,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit write */ b43_read32(dev, B43_MMIO_MACCTL); - if (awake && dev->dev->id.revision >= 5) { + if (awake && dev->sdev->id.revision >= 5) { /* Wait for the microcode to wake up. */ for (i = 0; i < 100; i++) { ucstat = b43_shm_read16(dev, B43_SHM_SHARED, @@ -1152,19 +1152,19 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) flags |= B43_TMSLOW_PHYRESET; if (dev->phy.type == B43_PHYTYPE_N) flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ - ssb_device_enable(dev->dev, flags); + ssb_device_enable(dev->sdev, flags); msleep(2); /* Wait for the PLL to turn on. */ /* Now take the PHY out of Reset again */ - tmslow = ssb_read32(dev->dev, SSB_TMSLOW); + tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); tmslow |= SSB_TMSLOW_FGC; tmslow &= ~B43_TMSLOW_PHYRESET; - ssb_write32(dev->dev, SSB_TMSLOW, tmslow); - ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ + ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ msleep(1); tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->dev, SSB_TMSLOW, tmslow); - ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ + ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ msleep(1); /* Turn Analog ON, but only if we already know the PHY-type. @@ -1214,7 +1214,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) { u32 dummy; - if (dev->dev->id.revision < 5) + if (dev->sdev->id.revision < 5) return; /* Read all entries from the microcode TXstatus FIFO * and throw them away. @@ -1420,9 +1420,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, /* Get the mask of available antennas. */ if (dev->phy.gmode) - antenna_mask = dev->dev->bus->sprom.ant_available_bg; + antenna_mask = dev->sdev->bus->sprom.ant_available_bg; else - antenna_mask = dev->dev->bus->sprom.ant_available_a; + antenna_mask = dev->sdev->bus->sprom.ant_available_a; if (!(antenna_mask & (1 << (antenna_nr - 1)))) { /* This antenna is not available. Fall back to default. */ @@ -1637,7 +1637,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) mutex_lock(&wl->mutex); dev = wl->current_dev; if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { - if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { /* wl->mutex is enough. */ b43_do_beacon_update_trigger_work(dev); mmiowb(); @@ -1682,7 +1682,7 @@ static void b43_update_templates(struct b43_wl *wl) static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) { b43_time_lock(dev); - if (dev->dev->id.revision >= 3) { + if (dev->sdev->id.revision >= 3) { b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); } else { @@ -2056,7 +2056,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, B43_WARN_ON(1); return -ENOSYS; } - err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); + err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); if (err == -ENOENT) { snprintf(ctx->errors[ctx->req_type], sizeof(ctx->errors[ctx->req_type]), @@ -2106,13 +2106,13 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) { struct b43_wldev *dev = ctx->dev; struct b43_firmware *fw = &ctx->dev->fw; - const u8 rev = ctx->dev->dev->id.revision; + const u8 rev = ctx->dev->sdev->id.revision; const char *filename; u32 tmshigh; int err; /* Get microcode */ - tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); if ((rev >= 5) && (rev <= 10)) filename = "ucode5"; else if ((rev >= 11) && (rev <= 12)) @@ -2440,7 +2440,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", dev->fw.rev, dev->fw.patch); - wiphy->hw_version = dev->dev->id.coreid; + wiphy->hw_version = dev->sdev->id.coreid; if (b43_is_old_txhdr_format(dev)) { /* We're over the deadline, but we keep support for old fw @@ -2558,7 +2558,7 @@ out: */ static int b43_gpio_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct ssb_device *gpiodev, *pcidev = NULL; u32 mask, set; @@ -2570,7 +2570,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask = 0x0000001F; set = 0x0000000F; - if (dev->dev->bus->chip_id == 0x4301) { + if (dev->sdev->bus->chip_id == 0x4301) { mask |= 0x0060; set |= 0x0060; } @@ -2581,14 +2581,14 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0180; set |= 0x0180; } - if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { + if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) | 0x0200); mask |= 0x0200; set |= 0x0200; } - if (dev->dev->id.revision >= 2) + if (dev->sdev->id.revision >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ #ifdef CONFIG_SSB_DRIVER_PCICORE @@ -2607,7 +2607,7 @@ static int b43_gpio_init(struct b43_wldev *dev) /* Turn off all GPIO stuff. Call this on module unload, for example. */ static void b43_gpio_cleanup(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct ssb_device *gpiodev, *pcidev = NULL; #ifdef CONFIG_SSB_DRIVER_PCICORE @@ -2688,12 +2688,12 @@ out: /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) { - u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); + u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); if (on) tmslow |= B43_TMSLOW_MACPHYCLKEN; else tmslow &= ~B43_TMSLOW_MACPHYCLKEN; - ssb_write32(dev->dev, SSB_TMSLOW, tmslow); + ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); } static void b43_adjust_opmode(struct b43_wldev *dev) @@ -2732,15 +2732,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev) /* Workaround: On old hardware the HW-MAC-address-filter * doesn't work properly, so always run promisc in filter * it in software. */ - if (dev->dev->id.revision <= 4) + if (dev->sdev->id.revision <= 4) ctl |= B43_MACCTL_PROMISC; b43_write32(dev, B43_MMIO_MACCTL, ctl); cfp_pretbtt = 2; if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { - if (dev->dev->bus->chip_id == 0x4306 && - dev->dev->bus->chip_rev == 3) + if (dev->sdev->bus->chip_id == 0x4306 && + dev->sdev->bus->chip_rev == 3) cfp_pretbtt = 100; else cfp_pretbtt = 50; @@ -2898,7 +2898,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write16(dev, 0x005E, value16); } b43_write32(dev, 0x0100, 0x01000000); - if (dev->dev->id.revision < 5) + if (dev->sdev->id.revision < 5) b43_write32(dev, 0x010C, 0x01000000); b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2913,7 +2913,7 @@ static int b43_chip_init(struct b43_wldev *dev) /* Initially set the wireless operation mode. */ b43_adjust_opmode(dev); - if (dev->dev->id.revision < 3) { + if (dev->sdev->id.revision < 3) { b43_write16(dev, 0x060E, 0x0000); b43_write16(dev, 0x0610, 0x8000); b43_write16(dev, 0x0604, 0x0000); @@ -2933,7 +2933,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_mac_phy_clock_set(dev, true); b43_write16(dev, B43_MMIO_POWERUP_DELAY, - dev->dev->bus->chipco.fast_pwrup_delay); + dev->sdev->bus->chipco.fast_pwrup_delay); err = 0; b43dbg(dev->wl, "Chip initialized\n"); @@ -3096,7 +3096,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); - if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) { + if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { /* The 32bit register shadows the two 16bit registers * with update sideeffects. Validate this. */ b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); @@ -3449,7 +3449,7 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) static void b43_put_phy_into_reset(struct b43_wldev *dev) { - struct ssb_device *sdev = dev->dev; + struct ssb_device *sdev = dev->sdev; u32 tmslow; tmslow = ssb_read32(sdev, SSB_TMSLOW); @@ -3945,7 +3945,7 @@ redo: /* Disable interrupts on the device. */ b43_set_status(dev, B43_STAT_INITIALIZED); - if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { /* wl->mutex is locked. That is enough. */ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ @@ -3958,11 +3958,11 @@ redo: /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ orig_dev = dev; mutex_unlock(&wl->mutex); - if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { b43_sdio_free_irq(dev); } else { - synchronize_irq(dev->dev->irq); - free_irq(dev->dev->irq, dev); + synchronize_irq(dev->sdev->irq); + free_irq(dev->sdev->irq, dev); } mutex_lock(&wl->mutex); dev = wl->current_dev; @@ -3995,18 +3995,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev) B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); drain_txstatus_queue(dev); - if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); if (err) { b43err(dev->wl, "Cannot request SDIO IRQ\n"); goto out; } } else { - err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, + err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, b43_interrupt_thread_handler, IRQF_SHARED, KBUILD_MODNAME, dev); if (err) { - b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); + b43err(dev->wl, "Cannot request IRQ-%d\n", + dev->sdev->irq); goto out; } } @@ -4086,10 +4087,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) analog_type, phy_type, phy_rev); /* Get RADIO versioning */ - if (dev->dev->bus->chip_id == 0x4317) { - if (dev->dev->bus->chip_rev == 0) + if (dev->sdev->bus->chip_id == 0x4317) { + if (dev->sdev->bus->chip_rev == 0) tmp = 0x3205017F; - else if (dev->dev->bus->chip_rev == 1) + else if (dev->sdev->bus->chip_rev == 1) tmp = 0x4205017F; else tmp = 0x5205017F; @@ -4194,7 +4195,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) static void b43_bluetooth_coext_enable(struct b43_wldev *dev) { - struct ssb_sprom *sprom = &dev->dev->bus->sprom; + struct ssb_sprom *sprom = &dev->sdev->bus->sprom; u64 hf; if (!modparam_btcoex) @@ -4221,16 +4222,16 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; u32 tmp; if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || (bus->chip_id == 0x4312)) { - tmp = ssb_read32(dev->dev, SSB_IMCFGLO); + tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); tmp &= ~SSB_IMCFGLO_REQTO; tmp &= ~SSB_IMCFGLO_SERTO; tmp |= 0x3; - ssb_write32(dev->dev, SSB_IMCFGLO, tmp); + ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); ssb_commit_settings(bus); } } @@ -4300,14 +4301,14 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) dev->wl->current_beacon = NULL; } - ssb_device_disable(dev->dev, 0); - ssb_bus_may_powerdown(dev->dev->bus); + ssb_device_disable(dev->sdev, 0); + ssb_bus_may_powerdown(dev->sdev->bus); } /* Initialize a wireless core */ static int b43_wireless_core_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct ssb_sprom *sprom = &bus->sprom; struct b43_phy *phy = &dev->phy; int err; @@ -4319,7 +4320,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) err = ssb_bus_powerup(bus, 0); if (err) goto out; - if (!ssb_device_is_enabled(dev->dev)) { + if (!ssb_device_is_enabled(dev->sdev)) { tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; b43_wireless_core_reset(dev, tmp); } @@ -4329,7 +4330,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) phy->ops->prepare_structs(dev); /* Enable IRQ routing to this device. */ - ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); + ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); b43_imcfglo_timeouts_workaround(dev); b43_bluetooth_coext_disable(dev); @@ -4342,7 +4343,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (err) goto err_busdown; b43_shm_write16(dev, B43_SHM_SHARED, - B43_SHM_SH_WLCOREREV, dev->dev->id.revision); + B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); hf = b43_hf_read(dev); if (phy->type == B43_PHYTYPE_G) { hf |= B43_HF_SYMW; @@ -4389,8 +4390,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) /* Maximum Contention Window */ b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); - if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || - (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || + if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || + (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || dev->use_pio) { dev->__using_pio_transfers = 1; err = b43_pio_init(dev); @@ -4727,7 +4728,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev) static int b43_wireless_core_attach(struct b43_wldev *dev) { struct b43_wl *wl = dev->wl; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; int err; bool have_2ghz_phy = 0, have_5ghz_phy = 0; @@ -4746,10 +4747,10 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) goto out; } /* Get the PHY type. */ - if (dev->dev->id.revision >= 5) { + if (dev->sdev->id.revision >= 5) { u32 tmshigh; - tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); } else @@ -4822,7 +4823,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) INIT_WORK(&dev->restart_work, b43_chip_reset); dev->phy.ops->switch_analog(dev, 0); - ssb_device_disable(dev->dev, 0); + ssb_device_disable(dev->sdev, 0); ssb_bus_may_powerdown(bus); out: @@ -4863,7 +4864,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) goto out; wldev->use_pio = b43_modparam_pio; - wldev->dev = dev; + wldev->sdev = dev; wldev->wl = wl; b43_set_status(wldev, B43_STAT_UNINIT); wldev->bad_frames_preempt = modparam_bad_frames_preempt; diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index b6428ec..b01c8ce 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -265,7 +265,7 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) void b43_phy_inita(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; /* This lowlevel A-PHY init is also called from G-PHY init. @@ -311,7 +311,7 @@ void b43_phy_inita(struct b43_wldev *dev) } if ((phy->type == B43_PHYTYPE_G) && - (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { + (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); } } @@ -323,17 +323,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_a *aphy = phy->a; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->dev->bus->sprom.pa1b0); - pab1 = (s16) (dev->dev->bus->sprom.pa1b1); - pab2 = (s16) (dev->dev->bus->sprom.pa1b2); + pab0 = (s16) (dev->sdev->bus->sprom.pa1b0); + pab1 = (s16) (dev->sdev->bus->sprom.pa1b1); + pab2 = (s16) (dev->sdev->bus->sprom.pa1b2); if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->dev->bus->sprom.itssi_a != 0 && - (s8) dev->dev->bus->sprom.itssi_a != -1) + if ((s8) dev->sdev->bus->sprom.itssi_a != 0 && + (s8) dev->sdev->bus->sprom.itssi_a != -1) aphy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.itssi_a); + (s8) (dev->sdev->bus->sprom.itssi_a); else aphy->tgt_idle_tssi = 62; aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index b5c5ce9..e46b2f4 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev) B43_WARN_ON(dev->phy.phy_locked); dev->phy.phy_locked = 1; #endif - B43_WARN_ON(dev->dev->id.revision < 3); + B43_WARN_ON(dev->sdev->id.revision < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); @@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev) B43_WARN_ON(!dev->phy.phy_locked); dev->phy.phy_locked = 0; #endif - B43_WARN_ON(dev->dev->id.revision < 3); + B43_WARN_ON(dev->sdev->id.revision < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, 0); @@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) /* The next check will be needed in two seconds, or later. */ phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); - if ((dev->dev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (dev->dev->bus->boardinfo.type == SSB_BOARD_BU4306)) + if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && + (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) return; /* No software txpower adjustment needed */ result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index be48281..1758a28 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev) B43_WARN_ON(phy->type != B43_PHYTYPE_G); if (!phy->gmode || - !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { + !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { tmp16 = b43_nrssi_hw_read(dev, 0x20); if (tmp16 >= 0x20) tmp16 -= 0x40; @@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, { struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; - struct ssb_sprom *sprom = &(dev->dev->bus->sprom); + struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); if (!phy->gmode) return 0; @@ -1491,7 +1491,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) static void b43_phy_initb5(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; u16 offset, value; @@ -1620,7 +1620,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x6B); b43_radio_write16(dev, 0x5C, 0x0F); - if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { + if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { b43_radio_write16(dev, 0x5D, 0xFA); b43_radio_write16(dev, 0x5E, 0xD8); } else { @@ -1787,7 +1787,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); - if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { + if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); @@ -1922,7 +1922,7 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) /* Initialize B/G PHY power control */ static void b43_phy_init_pctl(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_rfatt old_rfatt; @@ -2053,7 +2053,7 @@ static void b43_phy_initg(struct b43_wldev *dev) if (phy->rev >= 6) { b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); } - if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); else b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); @@ -2066,7 +2066,7 @@ static void b43_phy_initg(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } - if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { + if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. @@ -2088,8 +2088,8 @@ static void b43_phy_initg(struct b43_wldev *dev) /* FIXME: The spec says in the following if, the 0 should be replaced 'if OFDM may not be used in the current locale' but OFDM is legal everywhere */ - if ((dev->dev->bus->chip_id == 0x4306 - && dev->dev->bus->chip_package == 2) || 0) { + if ((dev->sdev->bus->chip_id == 0x4306 + && dev->sdev->bus->chip_package == 2) || 0) { b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); } @@ -2105,7 +2105,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); if (channel == 14) { - if (dev->dev->bus->sprom.country_code == + if (dev->sdev->bus->sprom.country_code == SSB_SPROM1CCODE_JAPAN) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACPR); @@ -2136,7 +2136,7 @@ static void default_baseband_attenuation(struct b43_wldev *dev, static void default_radio_attenuation(struct b43_wldev *dev, struct b43_rfatt *rf) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; rf->with_padmix = 0; @@ -2384,11 +2384,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_g *gphy = phy->g; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->dev->bus->sprom.pa0b0); - pab1 = (s16) (dev->dev->bus->sprom.pa0b1); - pab2 = (s16) (dev->dev->bus->sprom.pa0b2); + pab0 = (s16) (dev->sdev->bus->sprom.pa0b0); + pab1 = (s16) (dev->sdev->bus->sprom.pa0b1); + pab2 = (s16) (dev->sdev->bus->sprom.pa0b2); - B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) && + B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)); /* Not supported anymore */ gphy->dyn_tssi_tbl = 0; @@ -2396,10 +2396,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->dev->bus->sprom.itssi_bg != 0 && - (s8) dev->dev->bus->sprom.itssi_bg != -1) { + if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 && + (s8) dev->sdev->bus->sprom.itssi_bg != -1) { gphy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.itssi_bg); + (s8) (dev->sdev->bus->sprom.itssi_bg); } else gphy->tgt_idle_tssi = 62; gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, @@ -2840,7 +2840,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) B43_TXCTL_TXMIX; rfatt += 2; bbatt += 2; - } else if (dev->dev->bus->sprom. + } else if (dev->sdev->bus->sprom. boardflags_lo & B43_BFL_PACTRL) { bbatt += 4 * (rfatt - 2); @@ -2914,14 +2914,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); B43_WARN_ON(phy->type != B43_PHYTYPE_G); - max_pwr = dev->dev->bus->sprom.maxpwr_bg; - if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + max_pwr = dev->sdev->bus->sprom.maxpwr_bg; + if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) max_pwr -= 3; /* minus 0.75 */ if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { b43warn(dev->wl, "Invalid max-TX-power value in SPROM.\n"); max_pwr = INT_TO_Q52(20); /* fake it */ - dev->dev->bus->sprom.maxpwr_bg = max_pwr; + dev->sdev->bus->sprom.maxpwr_bg = max_pwr; } /* Get desired power (in Q5.2) */ @@ -3014,7 +3014,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; - if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) + if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) return; b43_mac_suspend(dev); diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index fd50eb1..012c8da 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -86,7 +86,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) static void lpphy_read_band_sprom(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; u16 cckpo, maxpwr; u32 ofdmpo; int i; @@ -214,7 +214,7 @@ static void lpphy_table_init(struct b43_wldev *dev) static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy_lp *lpphy = dev->phy.lp; u16 tmp, tmp2; @@ -412,7 +412,7 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy_lp *lpphy = dev->phy.lp; b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); @@ -519,7 +519,7 @@ struct b2062_freqdata { static void lpphy_2062_init(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; u32 crystalfreq, tmp, ref; unsigned int i; const struct b2062_freqdata *fd = NULL; @@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev) lpphy_sync_stx(dev); b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); - if (dev->dev->bus->chip_id == 0x4325) { + if (dev->sdev->bus->chip_id == 0x4325) { // TODO SSB PMU recalibration } } @@ -1289,7 +1289,7 @@ finish: static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; int i; @@ -1840,7 +1840,7 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct lpphy_tx_gains gains, oldgains; int old_txpctl, old_afe_ovr, old_rf, old_bbmult; @@ -1870,7 +1870,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, bool rx, bool pa, struct lpphy_tx_gains *gains) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; const struct lpphy_rx_iq_comp *iqcomp = NULL; struct lpphy_tx_gains nogains, oldgains; u16 tmp; @@ -2408,7 +2408,7 @@ static const struct b206x_channel b2063_chantbl[] = { static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); udelay(20); @@ -2432,7 +2432,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, unsigned int channel) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; @@ -2522,7 +2522,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev) static int lpphy_b2063_tune(struct b43_wldev *dev, unsigned int channel) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; static const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index b075a3f..9ed6515 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) static void b43_nphy_tx_power_fix(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->dev->bus->sprom); + struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); u8 txpi[2], bbmult, i; u16 tmp, radio_gain, dac_gain; @@ -423,8 +423,8 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) static void b43_radio_init2055_post(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->dev->bus->sprom); - struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); + struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); int i; u16 val; bool workaround = false; @@ -609,12 +609,12 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) if (dev->phy.type != B43_PHYTYPE_N) return; - tmslow = ssb_read32(dev->dev, SSB_TMSLOW); + tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); if (force) tmslow |= SSB_TMSLOW_FGC; else tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->dev, SSB_TMSLOW, tmslow); + ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ @@ -959,7 +959,7 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); - ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00, + ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00, 0xFC00); b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) & @@ -983,7 +983,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) { u16 tmp; - if (dev->dev->id.revision == 16) + if (dev->sdev->id.revision == 16) b43_mac_suspend(dev); tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); @@ -993,7 +993,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) tmp |= (val & mask); b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); - if (dev->dev->id.revision == 16) + if (dev->sdev->id.revision == 16) b43_mac_enable(dev); return tmp; @@ -1168,7 +1168,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->dev->bus->sprom); + struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); /* PHY rev 0, 1, 2 */ u8 i, j; @@ -1373,7 +1373,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ static void b43_nphy_workarounds(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; @@ -3586,7 +3586,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) */ int b43_phy_initn(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; u8 tx_pwr_state; @@ -3601,7 +3601,7 @@ int b43_phy_initn(struct b43_wldev *dev) if ((dev->phy.rev >= 3) && (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { - chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); + chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); } nphy->deaf_count = 0; b43_nphy_tables_init(dev); diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index aa12273..af0596d 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, B43_MMIO_PIO11_BASE5, }; - if (dev->dev->id.revision >= 11) { + if (dev->sdev->id.revision >= 11) { B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); return bases_rev11[index]; } @@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, static u16 pio_txqueue_offset(struct b43_wldev *dev) { - if (dev->dev->id.revision >= 11) + if (dev->sdev->id.revision >= 11) return 0x18; return 0; } static u16 pio_rxqueue_offset(struct b43_wldev *dev) { - if (dev->dev->id.revision >= 11) + if (dev->sdev->id.revision >= 11) return 0x38; return 8; } @@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->dev->id.revision; + q->rev = dev->sdev->id.revision; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_txqueue_offset(dev); q->index = index; @@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->dev->id.revision; + q->rev = dev->sdev->id.revision; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_rxqueue_offset(dev); @@ -339,7 +339,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; b43_piotx_write16(q, B43_PIO_TXCTL, ctl); - ssb_block_write(dev->dev, data, (data_len & ~1), + ssb_block_write(dev->sdev, data, (data_len & ~1), q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); if (data_len & 1) { @@ -351,7 +351,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, b43_piotx_write16(q, B43_PIO_TXCTL, ctl); tail[0] = data[data_len - 1]; tail[1] = 0; - ssb_block_write(dev->dev, tail, 2, + ssb_block_write(dev->sdev, tail, 2, q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); } @@ -393,7 +393,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); - ssb_block_write(dev->dev, data, (data_len & ~3), + ssb_block_write(dev->sdev, data, (data_len & ~3), q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); if (data_len & 3) { @@ -421,7 +421,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, break; } b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); - ssb_block_write(dev->dev, tail, 4, + ssb_block_write(dev->sdev, tail, 4, q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); } @@ -657,11 +657,11 @@ data_ready: /* Get the preamble (RX header) */ if (q->rev >= 8) { - ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), + ssb_block_read(dev->sdev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); } else { - ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), + ssb_block_read(dev->sdev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); } @@ -697,7 +697,7 @@ data_ready: skb_reserve(skb, 2); skb_put(skb, len + padding); if (q->rev >= 8) { - ssb_block_read(dev->dev, skb->data + padding, (len & ~3), + ssb_block_read(dev->sdev, skb->data + padding, (len & ~3), q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); if (len & 3) { @@ -705,7 +705,7 @@ data_ready: BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); /* Read the last few bytes. */ - ssb_block_read(dev->dev, tail, 4, + ssb_block_read(dev->sdev, tail, 4, q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); switch (len & 3) { @@ -724,7 +724,7 @@ data_ready: } } } else { - ssb_block_read(dev->dev, skb->data + padding, (len & ~1), + ssb_block_read(dev->sdev, skb->data + padding, (len & ~1), q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); if (len & 1) { @@ -732,7 +732,7 @@ data_ready: BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); /* Read the last byte. */ - ssb_block_read(dev->dev, tail, 2, + ssb_block_read(dev->sdev, tail, 2, q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); skb->data[len + padding - 1] = tail[0]; diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 86bc0a0..a617efe 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -37,7 +37,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; bool enabled; bool brought_up = false; @@ -47,7 +47,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) mutex_unlock(&wl->mutex); return; } - ssb_device_enable(dev->dev, 0); + ssb_device_enable(dev->sdev, 0); brought_up = true; } @@ -63,7 +63,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) } if (brought_up) { - ssb_device_disable(dev->dev, 0); + ssb_device_disable(dev->sdev, 0); ssb_bus_may_powerdown(bus); } diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 09e2dfd..808e25b 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) int b43_sdio_request_irq(struct b43_wldev *dev, void (*handler)(struct b43_wldev *dev)) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); int err; @@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev, void b43_sdio_free_irq(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index f1ae4e0..57af619 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c @@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644, int b43_sysfs_register(struct b43_wldev *wldev) { - struct device *dev = wldev->dev->dev; + struct device *dev = wldev->sdev->dev; B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); @@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev) void b43_sysfs_unregister(struct b43_wldev *wldev) { - struct device *dev = wldev->dev->dev; + struct device *dev = wldev->sdev->dev; device_remove_file(dev, &dev_attr_interference); } diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index 61027ee..59df3c6 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c @@ -2304,7 +2304,7 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev) void lpphy_rev2plus_table_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; int i; B43_WARN_ON(dev->phy.rev < 2); @@ -2416,7 +2416,7 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, void lpphy_init_tx_gain_table(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; switch (dev->phy.rev) { case 0: diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 9a335da..8f4db44 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c @@ -458,7 +458,7 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) static void b43_wa_boards_a(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && bus->boardinfo.type == SSB_BOARD_BU4306 && @@ -486,7 +486,7 @@ static void b43_wa_boards_a(struct b43_wldev *dev) static void b43_wa_boards_g(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->dev->bus; + struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index e5be381..c8f99ae 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, else tmp -= 3; } else { - if (dev->dev->bus->sprom. + if (dev->sdev->bus->sprom. boardflags_lo & B43_BFL_RSSI) { if (in_rssi > 63) in_rssi = 63; -- cgit v0.10.2 From df64962f7d74877624442c059e7878fdf7ec3c22 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 14 May 2011 02:42:38 +0200 Subject: carl9170: advertise interface combinations In order to provide multiple interfaces for a single device, the driver will be required to advertise all possible interface configurations to the stack. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index beb725d..771c021 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -286,6 +286,10 @@ struct ar9170 { unsigned int tx_seq_table; } fw; + /* interface configuration combinations */ + struct ieee80211_iface_limit if_comb_limits[1]; + struct ieee80211_iface_combination if_combs[1]; + /* reset / stuck frames/queue detection */ struct work_struct restart_work; struct work_struct ping_work; diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 9517ede..221957c 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -151,6 +151,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) const struct carl9170fw_chk_desc *chk_desc; const struct carl9170fw_last_desc *last_desc; const struct carl9170fw_txsq_desc *txsq_desc; + u16 if_comb_types; last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); @@ -268,6 +269,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (SUPP(CARL9170FW_WOL)) device_set_wakeup_enable(&ar->udev->dev, true); + if_comb_types = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + ar->fw.vif_num = otus_desc->vif_num; ar->fw.cmd_bufs = otus_desc->cmd_bufs; ar->fw.address = le32_to_cpu(otus_desc->fw_address); @@ -294,12 +298,25 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (SUPP(CARL9170FW_WLANTX_CAB)) { - ar->hw->wiphy->interface_modes |= + if_comb_types |= BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO); } } + ar->if_comb_limits[0].max = ar->fw.vif_num; + ar->if_comb_limits[0].types = if_comb_types; + + ar->if_combs[0].num_different_channels = 1; + ar->if_combs[0].max_interfaces = ar->fw.vif_num; + ar->if_combs[0].limits = ar->if_comb_limits; + ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); + + ar->hw->wiphy->iface_combinations = ar->if_combs; + ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); + + ar->hw->wiphy->interface_modes |= if_comb_types; + txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 7d5c65e..54d093c 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1570,14 +1570,8 @@ void *carl9170_alloc(size_t priv_size) INIT_LIST_HEAD(&ar->vif_list); init_completion(&ar->tx_flush); - /* - * Note: - * IBSS/ADHOC and AP mode are only enabled, if the firmware - * supports these modes. The code which will add the - * additional interface_modes is in fw.c. - */ - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT); + /* firmware decides which modes we support */ + hw->wiphy->interface_modes = 0; hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_REPORTS_TX_ACK_STATUS | -- cgit v0.10.2 From 8e621fc90b42fa2ca4ff65dd8d9cb21723e47837 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 14 May 2011 01:55:23 +0200 Subject: mac80211: verify IBSS in interface combinations Drivers shouldn't attempt to advertise support for more than one IBSS interface since mac80211 doesn't support that. Check and return an error from ieee80211_register_hw() in that case. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0d7b08d..96ab130 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -752,11 +752,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); - /* mac80211 doesn't support more than 1 channel */ - for (i = 0; i < hw->wiphy->n_iface_combinations; i++) - if (hw->wiphy->iface_combinations[i].num_different_channels > 1) + /* + * mac80211 doesn't support more than 1 channel, and also not more + * than one IBSS interface + */ + for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + int j; + + c = &hw->wiphy->iface_combinations[i]; + + if (c->num_different_channels > 1) return -EINVAL; + for (j = 0; j < c->n_limits; j++) + if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && + c->limits[j].max > 1) + return -EINVAL; + } + #ifndef CONFIG_MAC80211_MESH /* mesh depends on Kconfig, but drivers should set it if they want */ local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); -- cgit v0.10.2 From c29acf201007a6d73223f864f52406eb5ba19933 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 14 May 2011 09:43:28 +0530 Subject: mac80211: abort scan_work immediately when the device goes down As long as no delay is required b/w channel change, scan work is proceeding without scheduling a new work. In such case, we can not abort scan work when the card was unplugged. This patch completes the scanning immediately whenever the device goes down. Reviewed-by: Johannes Berg Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 0d00ac9..dee30ae 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -384,11 +384,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, int i; enum nl80211_channel_type orig_ct; + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + if (local->scan_sdata == sdata) ieee80211_scan_cancel(local); - clear_bit(SDATA_STATE_RUNNING, &sdata->state); - /* * Stop TX on this interface first. */ diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d20046b..27af672 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -719,6 +719,11 @@ void ieee80211_scan_work(struct work_struct *work) * without scheduling a new work */ do { + if (!ieee80211_sdata_running(sdata)) { + aborted = true; + goto out_complete; + } + switch (local->next_scan_state) { case SCAN_DECISION: /* if no more bands/channels left, complete scan */ -- cgit v0.10.2 From 9594b56dbed8cecc4694ed2ab7cf36c66623910e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 14 May 2011 10:31:46 +0200 Subject: bcma: add PCI ID of the card found in Thinkpad X120e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Gottfried Haider Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 99dd36e..ffd8797 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -171,6 +171,7 @@ static void bcma_host_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, -- cgit v0.10.2 From d07c7cf49ae7c488e778c4d668f4cc10bd2fa971 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 14 May 2011 11:04:51 +0200 Subject: mac80211: add missing rcu_barrier mac80211 uses call_rcu() with functions that are defined in the module, so it must use rcu_barrier() at module exit time. Luckily, this seems to not be a problem in practice as module unload and unregistration takes a long time and probably does multiple synchronize_rcu(). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 96ab130..866f269 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1090,6 +1090,8 @@ static void __exit ieee80211_exit(void) ieee80211s_stop(); ieee80211_iface_exit(); + + rcu_barrier(); } -- cgit v0.10.2 From 1928ecab620907a0953f811316d05f367f3f4dba Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 14 May 2011 11:00:52 +0200 Subject: mac80211: fix and simplify mesh locking The locking in mesh_{mpath,mpp}_table_grow not only has an rcu_read_unlock() missing, it's also racy (though really only technically since it's invoked from a single function only) since it obtains the new size of the table without any locking, so two invocations of the function could attempt the same resize. Additionally, it uses synchronize_rcu() which is rather expensive and can be avoided trivially here. Modify the functions to only use the table lock and use call_rcu() instead of synchronize_rcu(). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index e7c5fdd..eb733c0 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -120,6 +120,7 @@ struct mesh_path { * buckets * @mean_chain_len: maximum average length for the hash buckets' list, if it is * reached, the table will grow + * rcu_head: RCU head to free the table */ struct mesh_table { /* Number of buckets will be 2^N */ @@ -132,6 +133,8 @@ struct mesh_table { int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); int size_order; int mean_chain_len; + + struct rcu_head rcu_head; }; /* Recent multicast cache */ diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index f775202..7402136 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -370,52 +370,52 @@ err_path_alloc: return err; } +static void mesh_table_free_rcu(struct rcu_head *rcu) +{ + struct mesh_table *tbl = container_of(rcu, struct mesh_table, rcu_head); + + mesh_table_free(tbl, false); +} + void mesh_mpath_table_grow(void) { struct mesh_table *oldtbl, *newtbl; - rcu_read_lock(); - newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1); - if (!newtbl) - return; write_lock_bh(&pathtbl_resize_lock); + newtbl = mesh_table_alloc(mesh_paths->size_order + 1); + if (!newtbl) + goto out; oldtbl = mesh_paths; if (mesh_table_grow(mesh_paths, newtbl) < 0) { - rcu_read_unlock(); __mesh_table_free(newtbl); - write_unlock_bh(&pathtbl_resize_lock); - return; + goto out; } - rcu_read_unlock(); rcu_assign_pointer(mesh_paths, newtbl); - write_unlock_bh(&pathtbl_resize_lock); - synchronize_rcu(); - mesh_table_free(oldtbl, false); + call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu); + + out: + write_unlock_bh(&pathtbl_resize_lock); } void mesh_mpp_table_grow(void) { struct mesh_table *oldtbl, *newtbl; - rcu_read_lock(); - newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1); - if (!newtbl) - return; write_lock_bh(&pathtbl_resize_lock); + newtbl = mesh_table_alloc(mpp_paths->size_order + 1); + if (!newtbl) + goto out; oldtbl = mpp_paths; if (mesh_table_grow(mpp_paths, newtbl) < 0) { - rcu_read_unlock(); __mesh_table_free(newtbl); - write_unlock_bh(&pathtbl_resize_lock); - return; + goto out; } - rcu_read_unlock(); rcu_assign_pointer(mpp_paths, newtbl); - write_unlock_bh(&pathtbl_resize_lock); + call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu); - synchronize_rcu(); - mesh_table_free(oldtbl, false); + out: + write_unlock_bh(&pathtbl_resize_lock); } int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) -- cgit v0.10.2 From 349eb8cf45aadd35836fdfde75b3265a01b2aaa1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 14 May 2011 11:56:16 +0200 Subject: mac80211: annotate and fix RCU in mesh code This adds proper RCU annotations to the mesh path table code, and fixes a number of bugs in the code that I found while checking the sparse warnings I got as a result of the annotations. Some things like the changes in mesh_path_add() or mesh_pathtbl_init() only serve to shut up sparse, but other changes like the changes surrounding the for_each_mesh_entry() macro fix real RCU bugs in the code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index eb733c0..249e733 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -289,10 +289,6 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; } -#define for_each_mesh_entry(x, p, node, i) \ - for (i = 0; i <= x->hash_mask; i++) \ - hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) - void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7402136..2bda0ac 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -36,8 +36,8 @@ struct mpath_node { struct mesh_path *mpath; }; -static struct mesh_table *mesh_paths; -static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ +static struct mesh_table __rcu *mesh_paths; +static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ int mesh_paths_generation; @@ -48,6 +48,29 @@ int mesh_paths_generation; static DEFINE_RWLOCK(pathtbl_resize_lock); +static inline struct mesh_table *resize_dereference_mesh_paths(void) +{ + return rcu_dereference_protected(mesh_paths, + lockdep_is_held(&pathtbl_resize_lock)); +} + +static inline struct mesh_table *resize_dereference_mpp_paths(void) +{ + return rcu_dereference_protected(mpp_paths, + lockdep_is_held(&pathtbl_resize_lock)); +} + +/* + * CAREFUL -- "tbl" must not be an expression, + * in particular not an rcu_dereference(), since + * it's used twice. So it is illegal to do + * for_each_mesh_entry(rcu_dereference(...), ...) + */ +#define for_each_mesh_entry(tbl, p, node, i) \ + for (i = 0; i <= tbl->hash_mask; i++) \ + hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list) + + static struct mesh_table *mesh_table_alloc(int size_order) { int i; @@ -258,12 +281,13 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) */ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) { + struct mesh_table *tbl = rcu_dereference(mesh_paths); struct mpath_node *node; struct hlist_node *p; int i; int j = 0; - for_each_mesh_entry(mesh_paths, p, node, i) { + for_each_mesh_entry(tbl, p, node, i) { if (sdata && node->mpath->sdata != sdata) continue; if (j++ == idx) { @@ -293,6 +317,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_local *local = sdata->local; + struct mesh_table *tbl; struct mesh_path *mpath, *new_mpath; struct mpath_node *node, *new_node; struct hlist_head *bucket; @@ -332,10 +357,12 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) spin_lock_init(&new_mpath->state_lock); init_timer(&new_mpath->timer); - hash_idx = mesh_table_hash(dst, sdata, mesh_paths); - bucket = &mesh_paths->hash_buckets[hash_idx]; + tbl = resize_dereference_mesh_paths(); - spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); + hash_idx = mesh_table_hash(dst, sdata, tbl); + bucket = &tbl->hash_buckets[hash_idx]; + + spin_lock_bh(&tbl->hashwlock[hash_idx]); err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { @@ -345,13 +372,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) } hlist_add_head_rcu(&new_node->list, bucket); - if (atomic_inc_return(&mesh_paths->entries) >= - mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) + if (atomic_inc_return(&tbl->entries) >= + tbl->mean_chain_len * (tbl->hash_mask + 1)) grow = 1; mesh_paths_generation++; - spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); + spin_unlock_bh(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); if (grow) { set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); @@ -360,7 +387,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) return 0; err_exists: - spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); + spin_unlock_bh(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); kfree(new_node); err_node_alloc: @@ -382,11 +409,11 @@ void mesh_mpath_table_grow(void) struct mesh_table *oldtbl, *newtbl; write_lock_bh(&pathtbl_resize_lock); - newtbl = mesh_table_alloc(mesh_paths->size_order + 1); + oldtbl = resize_dereference_mesh_paths(); + newtbl = mesh_table_alloc(oldtbl->size_order + 1); if (!newtbl) goto out; - oldtbl = mesh_paths; - if (mesh_table_grow(mesh_paths, newtbl) < 0) { + if (mesh_table_grow(oldtbl, newtbl) < 0) { __mesh_table_free(newtbl); goto out; } @@ -403,11 +430,11 @@ void mesh_mpp_table_grow(void) struct mesh_table *oldtbl, *newtbl; write_lock_bh(&pathtbl_resize_lock); - newtbl = mesh_table_alloc(mpp_paths->size_order + 1); + oldtbl = resize_dereference_mpp_paths(); + newtbl = mesh_table_alloc(oldtbl->size_order + 1); if (!newtbl) goto out; - oldtbl = mpp_paths; - if (mesh_table_grow(mpp_paths, newtbl) < 0) { + if (mesh_table_grow(oldtbl, newtbl) < 0) { __mesh_table_free(newtbl); goto out; } @@ -422,6 +449,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_local *local = sdata->local; + struct mesh_table *tbl; struct mesh_path *mpath, *new_mpath; struct mpath_node *node, *new_node; struct hlist_head *bucket; @@ -456,10 +484,12 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) new_mpath->exp_time = jiffies; spin_lock_init(&new_mpath->state_lock); - hash_idx = mesh_table_hash(dst, sdata, mpp_paths); - bucket = &mpp_paths->hash_buckets[hash_idx]; + tbl = resize_dereference_mpp_paths(); - spin_lock_bh(&mpp_paths->hashwlock[hash_idx]); + hash_idx = mesh_table_hash(dst, sdata, tbl); + bucket = &tbl->hash_buckets[hash_idx]; + + spin_lock_bh(&tbl->hashwlock[hash_idx]); err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { @@ -469,11 +499,11 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) } hlist_add_head_rcu(&new_node->list, bucket); - if (atomic_inc_return(&mpp_paths->entries) >= - mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1)) + if (atomic_inc_return(&tbl->entries) >= + tbl->mean_chain_len * (tbl->hash_mask + 1)) grow = 1; - spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); + spin_unlock_bh(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); if (grow) { set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); @@ -482,7 +512,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) return 0; err_exists: - spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); + spin_unlock_bh(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); kfree(new_node); err_node_alloc: @@ -502,6 +532,7 @@ err_path_alloc: */ void mesh_plink_broken(struct sta_info *sta) { + struct mesh_table *tbl; static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct mesh_path *mpath; struct mpath_node *node; @@ -510,10 +541,11 @@ void mesh_plink_broken(struct sta_info *sta) int i; rcu_read_lock(); - for_each_mesh_entry(mesh_paths, p, node, i) { + tbl = rcu_dereference(mesh_paths); + for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; spin_lock_bh(&mpath->state_lock); - if (mpath->next_hop == sta && + if (rcu_dereference(mpath->next_hop) == sta && mpath->flags & MESH_PATH_ACTIVE && !(mpath->flags & MESH_PATH_FIXED)) { mpath->flags &= ~MESH_PATH_ACTIVE; @@ -542,30 +574,38 @@ void mesh_plink_broken(struct sta_info *sta) */ void mesh_path_flush_by_nexthop(struct sta_info *sta) { + struct mesh_table *tbl; struct mesh_path *mpath; struct mpath_node *node; struct hlist_node *p; int i; - for_each_mesh_entry(mesh_paths, p, node, i) { + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); + for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; - if (mpath->next_hop == sta) + if (rcu_dereference(mpath->next_hop) == sta) mesh_path_del(mpath->dst, mpath->sdata); } + rcu_read_unlock(); } void mesh_path_flush(struct ieee80211_sub_if_data *sdata) { + struct mesh_table *tbl; struct mesh_path *mpath; struct mpath_node *node; struct hlist_node *p; int i; - for_each_mesh_entry(mesh_paths, p, node, i) { + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); + for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; if (mpath->sdata == sdata) mesh_path_del(mpath->dst, mpath->sdata); } + rcu_read_unlock(); } static void mesh_path_node_reclaim(struct rcu_head *rp) @@ -589,6 +629,7 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) */ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) { + struct mesh_table *tbl; struct mesh_path *mpath; struct mpath_node *node; struct hlist_head *bucket; @@ -597,19 +638,20 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) int err = 0; read_lock_bh(&pathtbl_resize_lock); - hash_idx = mesh_table_hash(addr, sdata, mesh_paths); - bucket = &mesh_paths->hash_buckets[hash_idx]; + tbl = resize_dereference_mesh_paths(); + hash_idx = mesh_table_hash(addr, sdata, tbl); + bucket = &tbl->hash_buckets[hash_idx]; - spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); + spin_lock_bh(&tbl->hashwlock[hash_idx]); hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - memcmp(addr, mpath->dst, ETH_ALEN) == 0) { + memcmp(addr, mpath->dst, ETH_ALEN) == 0) { spin_lock_bh(&mpath->state_lock); mpath->flags |= MESH_PATH_RESOLVING; hlist_del_rcu(&node->list); call_rcu(&node->rcu, mesh_path_node_reclaim); - atomic_dec(&mesh_paths->entries); + atomic_dec(&tbl->entries); spin_unlock_bh(&mpath->state_lock); goto enddel; } @@ -618,7 +660,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) err = -ENXIO; enddel: mesh_paths_generation++; - spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); + spin_unlock_bh(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); return err; } @@ -747,52 +789,60 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) int mesh_pathtbl_init(void) { - mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); - if (!mesh_paths) + struct mesh_table *tbl_path, *tbl_mpp; + + tbl_path = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); + if (!tbl_path) return -ENOMEM; - mesh_paths->free_node = &mesh_path_node_free; - mesh_paths->copy_node = &mesh_path_node_copy; - mesh_paths->mean_chain_len = MEAN_CHAIN_LEN; + tbl_path->free_node = &mesh_path_node_free; + tbl_path->copy_node = &mesh_path_node_copy; + tbl_path->mean_chain_len = MEAN_CHAIN_LEN; - mpp_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); - if (!mpp_paths) { - mesh_table_free(mesh_paths, true); + tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); + if (!tbl_mpp) { + mesh_table_free(tbl_path, true); return -ENOMEM; } - mpp_paths->free_node = &mesh_path_node_free; - mpp_paths->copy_node = &mesh_path_node_copy; - mpp_paths->mean_chain_len = MEAN_CHAIN_LEN; + tbl_mpp->free_node = &mesh_path_node_free; + tbl_mpp->copy_node = &mesh_path_node_copy; + tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; + + /* Need no locking since this is during init */ + RCU_INIT_POINTER(mesh_paths, tbl_path); + RCU_INIT_POINTER(mpp_paths, tbl_mpp); return 0; } void mesh_path_expire(struct ieee80211_sub_if_data *sdata) { + struct mesh_table *tbl; struct mesh_path *mpath; struct mpath_node *node; struct hlist_node *p; int i; - read_lock_bh(&pathtbl_resize_lock); - for_each_mesh_entry(mesh_paths, p, node, i) { + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); + for_each_mesh_entry(tbl, p, node, i) { if (node->mpath->sdata != sdata) continue; mpath = node->mpath; spin_lock_bh(&mpath->state_lock); if ((!(mpath->flags & MESH_PATH_RESOLVING)) && (!(mpath->flags & MESH_PATH_FIXED)) && - time_after(jiffies, - mpath->exp_time + MESH_PATH_EXPIRE)) { + time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) { spin_unlock_bh(&mpath->state_lock); mesh_path_del(mpath->dst, mpath->sdata); } else spin_unlock_bh(&mpath->state_lock); } - read_unlock_bh(&pathtbl_resize_lock); + rcu_read_unlock(); } void mesh_pathtbl_unregister(void) { - mesh_table_free(mesh_paths, true); - mesh_table_free(mpp_paths, true); + /* no need for locking during exit path */ + mesh_table_free(rcu_dereference_raw(mesh_paths), true); + mesh_table_free(rcu_dereference_raw(mpp_paths), true); } -- cgit v0.10.2 From 099fb8ab1e57e5d609ac686cc0ab6d1835a79155 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 14 May 2011 10:15:17 -0500 Subject: rtlwifi: rtl8192c-common: rtl8192ce: Fix for HT40 regression The changes that were made to rtl8192ce when rtl8192cu was added broke HT40. The errors included a typo in rtlwifi, a missing routine in rtl8192ce and a missing callback of that routine in rtl8192c-common. This patch fixes the regression reported in Bug #35082. Signed-off-by: Larry Finger Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 2bb7119..39b0297 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -190,7 +190,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) ppsc->swrf_processing = true; - if (ppsc->inactive_pwrstate == ERFOFF && + if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index c5424ca..d2cc815 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -728,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, return; rtlphy->set_bwmode_inprogress = true; if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtlphy->set_bwmode_inprogress = false; + rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("FALSE driver sleep or unload\n")); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 73ae8a4..abe0fcc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -366,6 +366,75 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, return true; } +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz")) + + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { u8 tmpreg; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index ad58085..be2c92a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -257,5 +257,6 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, u8 configtype); bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, u8 configtype); +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 390bbb5..373dc78 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -232,6 +232,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, + .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, }; -- cgit v0.10.2 From 79d2b1570bcc31b846ccb2114a34e98ca87bf1d9 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 16 May 2011 18:23:23 +0530 Subject: ath9k: Fix power save wrappers in debug ops Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index bad1a87..7afe332 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -443,7 +443,9 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); len += snprintf(buf + len, sizeof(buf) - len, "addrmask: %pM\n", addr); + ath9k_ps_wakeup(sc); tmp = ath9k_hw_getrxfilter(sc->sc_ah); + ath9k_ps_restore(sc); len += snprintf(buf + len, sizeof(buf) - len, "rfilt: 0x%x", tmp); if (tmp & ATH9K_RX_FILTER_UCAST) @@ -725,6 +727,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, break; } + ath9k_ps_wakeup(sc); len += snprintf(buf + len, size - len, "curbssid: %pM\n" "OP-Mode: %s(%i)\n" @@ -734,6 +737,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, REG_READ(ah, AR_BEACON_PERIOD)); reg = REG_READ(ah, AR_TIMER_MODE); + ath9k_ps_restore(sc); len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", reg); if (reg & AR_TBTT_TIMER_EN) @@ -1050,7 +1054,9 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf, unsigned int len; u32 regval; + ath9k_ps_wakeup(sc); regval = REG_READ_D(ah, sc->debug.regidx); + ath9k_ps_restore(sc); len = sprintf(buf, "0x%08x\n", regval); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1072,7 +1078,9 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, if (strict_strtoul(buf, 0, ®val)) return -EINVAL; + ath9k_ps_wakeup(sc); REG_WRITE_D(ah, sc->debug.regidx, regval); + ath9k_ps_restore(sc); return count; } -- cgit v0.10.2 From ed9d01026f156db2d638cbb045231c7a8fde877d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 16 May 2011 19:40:15 +0300 Subject: cfg80211: Use consistent BSS matching between scan and sme cfg80211 scan code adds separate BSS entries if the same BSS shows up on multiple channels. However, sme implementation does not use the frequency when fetching the BSS entry. Fix this by adding channel information to cfg80211_roamed() and include it in cfg80211_get_bss() calls. Please note that drivers using cfg80211_roamed() need to be modified to fully implement this fix. This commit includes only minimal changes to avoid compilation issues; it maintains the old (broken) behavior for most drivers. ath6kl was the only one that I could test, so I updated it to provide the operating frequency in the roamed event. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 5665a1a..a414768 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -565,7 +565,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status) && iwm->conf.mode == UMAC_MODE_BSS) { cancel_delayed_work(&iwm->disconnect); - cfg80211_roamed(iwm_to_ndev(iwm), + cfg80211_roamed(iwm_to_ndev(iwm), NULL, complete->bssid, iwm->req_ie, iwm->req_ie_len, iwm->resp_ie, iwm->resp_ie_len, @@ -586,7 +586,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, WLAN_STATUS_SUCCESS, GFP_KERNEL); else - cfg80211_roamed(iwm_to_ndev(iwm), + cfg80211_roamed(iwm_to_ndev(iwm), NULL, complete->bssid, iwm->req_ie, iwm->req_ie_len, iwm->resp_ie, iwm->resp_ie_len, diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 518542b..29f9389 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2830,7 +2830,8 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) req_ie_len, resp_ie, resp_ie_len, 0, GFP_KERNEL); else - cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len, + cfg80211_roamed(usbdev->net, NULL, bssid, + req_ie, req_ie_len, resp_ie, resp_ie_len, GFP_KERNEL); } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index bcca394..5bda24e 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -570,7 +570,7 @@ ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, WLAN_STATUS_SUCCESS, GFP_KERNEL); } else { /* inform roam event to cfg80211 */ - cfg80211_roamed(ar->arNetDev, bssid, + cfg80211_roamed(ar->arNetDev, ibss_channel, bssid, assocReqIe, assocReqLen, assocRespIe, assocRespLen, GFP_KERNEL); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 555b056..7aaf99c 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -2630,7 +2630,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, wl_get_assoc_ies(wl); memcpy(&wl->bssid, &e->addr, ETH_ALEN); wl_update_bss_info(wl); - cfg80211_roamed(ndev, + cfg80211_roamed(ndev, NULL, (u8 *)&wl->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); @@ -2663,7 +2663,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, WL_DBG("Report connect result - connection %s\n", completed ? "succeeded" : "failed"); } else { - cfg80211_roamed(ndev, + cfg80211_roamed(ndev, NULL, (u8 *)&wl->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 6a71f52..4734388 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -695,7 +695,7 @@ void prism2_disconnected(wlandevice_t *wlandev) void prism2_roamed(wlandevice_t *wlandev) { - cfg80211_roamed(wlandev->netdev, wlandev->bssid, + cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid, NULL, 0, NULL, 0, GFP_KERNEL); } diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bfd6557..727131b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2878,6 +2878,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, * cfg80211_roamed - notify cfg80211 of roaming * * @dev: network device + * @channel: the channel of the new AP * @bssid: the BSSID of the new AP * @req_ie: association request IEs (maybe be %NULL) * @req_ie_len: association request IEs length @@ -2888,7 +2889,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, * It should be called by the underlying driver whenever it roamed * from one AP to another while connected. */ -void cfg80211_roamed(struct net_device *dev, const u8 *bssid, +void cfg80211_roamed(struct net_device *dev, + struct ieee80211_channel *channel, + const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); diff --git a/net/wireless/core.h b/net/wireless/core.h index bf0fb40..3dce1f1 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -245,6 +245,7 @@ struct cfg80211_event { u16 status; } cr; struct { + struct ieee80211_channel *channel; u8 bssid[ETH_ALEN]; const u8 *req_ie; const u8 *resp_ie; @@ -392,7 +393,9 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, int cfg80211_disconnect(struct cfg80211_registered_device *rdev, struct net_device *dev, u16 reason, bool wextev); -void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, +void __cfg80211_roamed(struct wireless_dev *wdev, + struct ieee80211_channel *channel, + const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len); int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/sme.c b/net/wireless/sme.c index e17b0be..b7b6ff8 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -250,7 +250,8 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) if (wdev->conn->params.privacy) capa |= WLAN_CAPABILITY_PRIVACY; - bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid, + bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, + wdev->conn->params.bssid, wdev->conn->params.ssid, wdev->conn->params.ssid_len, WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, @@ -470,7 +471,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, } if (!bss) - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, + bss = cfg80211_get_bss(wdev->wiphy, + wdev->conn ? wdev->conn->params.channel : + NULL, + bssid, wdev->ssid, wdev->ssid_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); @@ -538,7 +542,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, } EXPORT_SYMBOL(cfg80211_connect_result); -void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, +void __cfg80211_roamed(struct wireless_dev *wdev, + struct ieee80211_channel *channel, + const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len) { @@ -565,7 +571,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, wdev->ssid_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); @@ -603,7 +609,9 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, #endif } -void cfg80211_roamed(struct net_device *dev, const u8 *bssid, +void cfg80211_roamed(struct net_device *dev, + struct ieee80211_channel *channel, + const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) { @@ -619,6 +627,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid, return; ev->type = EVENT_ROAMED; + ev->rm.channel = channel; memcpy(ev->rm.bssid, bssid, ETH_ALEN); ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); ev->rm.req_ie_len = req_ie_len; diff --git a/net/wireless/util.c b/net/wireless/util.c index f0536d4..4d7b83f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -746,7 +746,7 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev) NULL); break; case EVENT_ROAMED: - __cfg80211_roamed(wdev, ev->rm.bssid, + __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid, ev->rm.req_ie, ev->rm.req_ie_len, ev->rm.resp_ie, ev->rm.resp_ie_len); break; -- cgit v0.10.2 From c6820f1e6c8273ca4b8f94c2354193d19e1a5c47 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 16 May 2011 23:22:00 +0200 Subject: ath9k: fix ad-hoc mode beacon selection In ad-hoc mode, beacon timers are configured differently compared to AP mode, and (depending on the scenario) can vary enough to make the beacon tasklet not detect slot 0 based on the TSF. Since staggered beacons are not (and cannot be) used in ad-hoc mode, it makes more sense to just hardcode slot 0 here, avoiding unnecessary TSF reads and calculations. Signed-off-by: Felix Fietkau Reported-by: Rajkumar Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 637dbc5..c7f4679 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -351,9 +351,7 @@ void ath_beacon_tasklet(unsigned long data) struct ath_buf *bf = NULL; struct ieee80211_vif *vif; int slot; - u32 bfaddr, bc = 0, tsftu; - u64 tsf; - u16 intval; + u32 bfaddr, bc = 0; /* * Check if the previous beacon has gone out. If @@ -388,17 +386,27 @@ void ath_beacon_tasklet(unsigned long data) * on the tsf to safeguard against missing an swba. */ - intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; - tsf = ath9k_hw_gettsf64(ah); - tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); - tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); - slot = (tsftu % (intval * ATH_BCBUF)) / intval; - vif = sc->beacon.bslot[slot]; + if (ah->opmode == NL80211_IFTYPE_AP) { + u16 intval; + u32 tsftu; + u64 tsf; + + intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; + tsf = ath9k_hw_gettsf64(ah); + tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); + tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); + slot = (tsftu % (intval * ATH_BCBUF)) / intval; + vif = sc->beacon.bslot[slot]; + + ath_dbg(common, ATH_DBG_BEACON, + "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", + slot, tsf, tsftu / ATH_BCBUF, intval, vif); + } else { + slot = 0; + vif = sc->beacon.bslot[slot]; + } - ath_dbg(common, ATH_DBG_BEACON, - "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", - slot, tsf, tsftu / ATH_BCBUF, intval, vif); bfaddr = 0; if (vif) { -- cgit v0.10.2 From 7176ba23f8b589b1df3229574ff46fb904ce9ec5 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 16 May 2011 14:41:48 -0700 Subject: net: rfkill: add generic gpio rfkill driver This adds a new generic gpio rfkill driver to support rfkill switches which are controlled by gpios. The driver also supports passing in data about the clock for the radio, so that when rfkill is blocking, it can disable the clock. This driver assumes platform data is passed from the board files to configure it for specific devices. Original-patch-by: Anantha Idapalapati Signed-off-by: Rhyland Klein Signed-off-by: John W. Linville diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill-gpio.h new file mode 100644 index 0000000..a175d05 --- /dev/null +++ b/include/linux/rfkill-gpio.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011, NVIDIA Corporation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef __RFKILL_GPIO_H +#define __RFKILL_GPIO_H + +#include +#include + +/** + * struct rfkill_gpio_platform_data - platform data for rfkill gpio device. + * for unused gpio's, the expected value is -1. + * @name: name for the gpio rf kill instance + * @reset_gpio: GPIO which is used for reseting rfkill switch + * @shutdown_gpio: GPIO which is used for shutdown of rfkill switch + * @power_clk_name: [optional] name of clk to turn off while blocked + */ + +struct rfkill_gpio_platform_data { + char *name; + int reset_gpio; + int shutdown_gpio; + const char *power_clk_name; + enum rfkill_type type; +}; + +#endif /* __RFKILL_GPIO_H */ diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 48464ca..78efe89 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -33,3 +33,12 @@ config RFKILL_REGULATOR To compile this driver as a module, choose M here: the module will be called rfkill-regulator. + +config RFKILL_GPIO + tristate "GPIO RFKILL driver" + depends on RFKILL && GPIOLIB && HAVE_CLK + default n + help + If you say yes here you get support of a generic gpio RFKILL + driver. The platform should fill in the appropriate fields in the + rfkill_gpio_platform_data structure and pass that to the driver. diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile index d9a5a58..3117687 100644 --- a/net/rfkill/Makefile +++ b/net/rfkill/Makefile @@ -6,3 +6,4 @@ rfkill-y += core.o rfkill-$(CONFIG_RFKILL_INPUT) += input.o obj-$(CONFIG_RFKILL) += rfkill.o obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o +obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c new file mode 100644 index 0000000..256c5dd --- /dev/null +++ b/net/rfkill/rfkill-gpio.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2011, NVIDIA Corporation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum rfkill_gpio_clk_state { + UNSPECIFIED = 0, + PWR_ENABLED, + PWR_DISABLED +}; + +#define PWR_CLK_SET(_RF, _EN) \ + ((_RF)->pwr_clk_enabled = (!(_EN) ? PWR_ENABLED : PWR_DISABLED)) +#define PWR_CLK_ENABLED(_RF) ((_RF)->pwr_clk_enabled == PWR_ENABLED) +#define PWR_CLK_DISABLED(_RF) ((_RF)->pwr_clk_enabled != PWR_ENABLED) + +struct rfkill_gpio_data { + struct rfkill_gpio_platform_data *pdata; + struct rfkill *rfkill_dev; + char *reset_name; + char *shutdown_name; + enum rfkill_gpio_clk_state pwr_clk_enabled; + struct clk *pwr_clk; +}; + +static int rfkill_gpio_set_power(void *data, bool blocked) +{ + struct rfkill_gpio_data *rfkill = data; + + if (blocked) { + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_direction_output(rfkill->pdata->shutdown_gpio, 0); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_direction_output(rfkill->pdata->reset_gpio, 0); + if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) + clk_disable(rfkill->pwr_clk); + } else { + if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill)) + clk_enable(rfkill->pwr_clk); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_direction_output(rfkill->pdata->reset_gpio, 1); + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_direction_output(rfkill->pdata->shutdown_gpio, 1); + } + + if (rfkill->pwr_clk) + PWR_CLK_SET(rfkill, blocked); + + return 0; +} + +static const struct rfkill_ops rfkill_gpio_ops = { + .set_block = rfkill_gpio_set_power, +}; + +static int rfkill_gpio_probe(struct platform_device *pdev) +{ + struct rfkill_gpio_data *rfkill; + struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; + int ret = 0; + int len = 0; + + if (!pdata) { + pr_warn("%s: No platform data specified\n", __func__); + return -EINVAL; + } + + /* make sure at-least one of the GPIO is defined and that + * a name is specified for this instance */ + if (!pdata->name || (!gpio_is_valid(pdata->reset_gpio) && + !gpio_is_valid(pdata->shutdown_gpio))) { + pr_warn("%s: invalid platform data\n", __func__); + return -EINVAL; + } + + rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); + if (!rfkill) + return -ENOMEM; + + rfkill->pdata = pdata; + + len = strlen(pdata->name); + rfkill->reset_name = kzalloc(len + 7, GFP_KERNEL); + if (!rfkill->reset_name) { + ret = -ENOMEM; + goto fail_alloc; + } + + rfkill->shutdown_name = kzalloc(len + 10, GFP_KERNEL); + if (!rfkill->shutdown_name) { + ret = -ENOMEM; + goto fail_reset_name; + } + + snprintf(rfkill->reset_name, len + 6 , "%s_reset", pdata->name); + snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", pdata->name); + + if (pdata->power_clk_name) { + rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); + if (IS_ERR(rfkill->pwr_clk)) { + pr_warn("%s: can't find pwr_clk.\n", __func__); + goto fail_shutdown_name; + } + } + + if (gpio_is_valid(pdata->reset_gpio)) { + ret = gpio_request(pdata->reset_gpio, rfkill->reset_name); + if (ret) { + pr_warn("%s: failed to get reset gpio.\n", __func__); + goto fail_clock; + } + } + + if (gpio_is_valid(pdata->shutdown_gpio)) { + ret = gpio_request(pdata->shutdown_gpio, rfkill->shutdown_name); + if (ret) { + pr_warn("%s: failed to get shutdown gpio.\n", __func__); + goto fail_reset; + } + } + + rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, + &rfkill_gpio_ops, rfkill); + if (!rfkill->rfkill_dev) + goto fail_shutdown; + + ret = rfkill_register(rfkill->rfkill_dev); + if (ret < 0) + goto fail_rfkill; + + platform_set_drvdata(pdev, rfkill); + + dev_info(&pdev->dev, "%s device registered.\n", pdata->name); + + return 0; + +fail_rfkill: + rfkill_destroy(rfkill->rfkill_dev); +fail_shutdown: + if (gpio_is_valid(pdata->shutdown_gpio)) + gpio_free(pdata->shutdown_gpio); +fail_reset: + if (gpio_is_valid(pdata->reset_gpio)) + gpio_free(pdata->reset_gpio); +fail_clock: + if (rfkill->pwr_clk) + clk_put(rfkill->pwr_clk); +fail_shutdown_name: + kfree(rfkill->shutdown_name); +fail_reset_name: + kfree(rfkill->reset_name); +fail_alloc: + kfree(rfkill); + + return ret; +} + +static int rfkill_gpio_remove(struct platform_device *pdev) +{ + struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); + + rfkill_unregister(rfkill->rfkill_dev); + rfkill_destroy(rfkill->rfkill_dev); + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_free(rfkill->pdata->shutdown_gpio); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_free(rfkill->pdata->reset_gpio); + if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) + clk_disable(rfkill->pwr_clk); + if (rfkill->pwr_clk) + clk_put(rfkill->pwr_clk); + kfree(rfkill->shutdown_name); + kfree(rfkill->reset_name); + kfree(rfkill); + + return 0; +} + +static struct platform_driver rfkill_gpio_driver = { + .probe = rfkill_gpio_probe, + .remove = __devexit_p(rfkill_gpio_remove), + .driver = { + .name = "rfkill_gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init rfkill_gpio_init(void) +{ + return platform_driver_register(&rfkill_gpio_driver); +} + +static void __exit rfkill_gpio_exit(void) +{ + platform_driver_unregister(&rfkill_gpio_driver); +} + +module_init(rfkill_gpio_init); +module_exit(rfkill_gpio_exit); + +MODULE_DESCRIPTION("gpio rfkill"); +MODULE_AUTHOR("NVIDIA"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f699254c7126d7df94491dfd4c3648f8ec0c0d51 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 16 May 2011 19:17:49 -0700 Subject: mwifiex: reduce CPU usage by tracking tx_pkts_queued This patch adds tx_pkts_queued to track number of packets being enqueued & dequeued so that mwifiex_wmm_lists_empty() evaluation is lightweight. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index d3d5e08..f807447 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -196,6 +196,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, if (skb_src) pra_list->total_pkts_size -= skb_src->len; + atomic_dec(&priv->wmm.tx_pkts_queued); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); @@ -257,6 +259,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, pra_list->total_pkts_size += skb_aggr->len; + atomic_inc(&priv->wmm.tx_pkts_queued); + tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 672701d..537b40d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -213,7 +213,8 @@ struct mwifiex_wmm_desc { u32 drv_pkt_delay_max; u8 queue_priority[IEEE80211_MAX_QUEUES]; u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ - + /* Number of transmit packets queued */ + atomic_t tx_pkts_queued; }; struct mwifiex_802_11_security { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index faa09e3..52d2185 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -399,6 +399,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; + + atomic_set(&priv->wmm.tx_pkts_queued, 0); } } @@ -408,17 +410,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) { - int i, j; + int i; struct mwifiex_private *priv; - for (j = 0; j < adapter->priv_num; ++j) { - priv = adapter->priv[j]; - if (priv) { - for (i = 0; i < MAX_NUM_TID; i++) - if (!mwifiex_wmm_is_ra_list_empty( - &priv->wmm.tid_tbl_ptr[i].ra_list)) - return false; - } + for (i = 0; i < adapter->priv_num; ++i) { + priv = adapter->priv[i]; + if (priv && atomic_read(&priv->wmm.tx_pkts_queued)) + return false; } return true; @@ -468,6 +466,8 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; i++) mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. ra_list); + + atomic_set(&priv->wmm.tx_pkts_queued, 0); } /* @@ -638,6 +638,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, ra_list->total_pkts_size += skb->len; + atomic_inc(&priv->wmm.tx_pkts_queued); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -1028,6 +1030,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, .bss_prio_cur->list, struct mwifiex_bss_prio_node, list); + atomic_dec(&priv->wmm.tx_pkts_queued); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); } @@ -1134,6 +1137,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, .bss_prio_cur->list, struct mwifiex_bss_prio_node, list); + atomic_dec(&priv->wmm.tx_pkts_queued); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); } -- cgit v0.10.2 From 49729ff616547d7abcb96924d14aa860320e7352 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 16 May 2011 19:17:50 -0700 Subject: mwifiex: reduce CPU usage by tracking highest_queued_prio This patch adds highest_queued_prio to track priority of packets as they are enqueued so that mwifiex_wmm_get_highest_priolist_ptr() starts checking at the first level where we have packets, instead of the highest. The function also lowers priority value to the level where first packet is found. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 537b40d..ea3184d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -215,6 +215,8 @@ struct mwifiex_wmm_desc { u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ /* Number of transmit packets queued */ atomic_t tx_pkts_queued; + /* Tracks highest priority with a packet queued */ + atomic_t highest_queued_prio; }; struct mwifiex_802_11_security { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 52d2185..f3d5f23 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -177,14 +177,20 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) * This function map ACs to TIDs. */ static void -mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) +mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) { + u8 *queue_priority = wmm->queue_priority; int i; for (i = 0; i < 4; ++i) { tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; } + + for (i = 0; i < MAX_NUM_TID; ++i) + tos_to_tid_inv[tos_to_tid[i]] = (u8)i; + + atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); } /* @@ -246,7 +252,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, } } - mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); + mwifiex_wmm_queue_priorities_tid(&priv->wmm); } /* @@ -401,6 +407,7 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; atomic_set(&priv->wmm.tx_pkts_queued, 0); + atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } } @@ -468,6 +475,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) ra_list); atomic_set(&priv->wmm.tx_pkts_queued, 0); + atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } /* @@ -640,6 +648,11 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, atomic_inc(&priv->wmm.tx_pkts_queued); + if (atomic_read(&priv->wmm.highest_queued_prio) < + tos_to_tid_inv[tid_down]) + atomic_set(&priv->wmm.highest_queued_prio, + tos_to_tid_inv[tid_down]); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -865,9 +878,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } do { + atomic_t *hqp; + spinlock_t *lock; + priv_tmp = bssprio_node->priv; + hqp = &priv_tmp->wmm.highest_queued_prio; + lock = &priv_tmp->wmm.ra_list_spinlock; - for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { + for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { tid_ptr = &(priv_tmp)->wmm. tid_tbl_ptr[tos_to_tid[i]]; @@ -905,6 +923,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, is_list_empty = skb_queue_empty(&ptr->skb_head); if (!is_list_empty) { + spin_lock_irqsave(lock, flags); + if (atomic_read(hqp) > i) + atomic_set(hqp, i); + spin_unlock_irqrestore(lock, + flags); *priv = priv_tmp; *tid = tos_to_tid[i]; return ptr; -- cgit v0.10.2 From 93968147874508e6dd534af1e236a7353269da3f Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 16 May 2011 19:17:51 -0700 Subject: mwifiex: check mwifiex_wmm_lists_empty() before dequeue add checks to mwifiex_wmm_process_tx() loop so it doesn't re-enter mwifiex_dequeue_tx_packet() to find it can't send. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index f3d5f23..784ad4c 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1254,5 +1254,5 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) if (mwifiex_dequeue_tx_packet(adapter)) break; - } while (true); + } while (!mwifiex_wmm_lists_empty(adapter)); } -- cgit v0.10.2 From 17e8cec87586c26b953c6541c8a045e906ea046c Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 16 May 2011 19:17:52 -0700 Subject: mwifiex: CPU mips optimization with NO_PKT_PRIO_TID If we go through the entire for loop in mwifiex_wmm_get_highest_priolist_ptr() and don't find any packets, set highest_queued_prio to NO_PKT_PRIO_TID (< LOW_PRIO_TID). Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index ea3184d..3154b0a 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -202,6 +202,7 @@ struct mwifiex_tid_tbl { #define WMM_HIGHEST_PRIORITY 7 #define HIGH_PRIO_TID 7 #define LOW_PRIO_TID 0 +#define NO_PKT_PRIO_TID (-1) struct mwifiex_wmm_desc { struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 784ad4c..91634da 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -946,6 +946,12 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } while (ptr != head); } + /* No packet at any TID for this priv. Mark as such + * to skip checking TIDs for this priv (until pkt is + * added). + */ + atomic_set(hqp, NO_PKT_PRIO_TID); + /* Get next bss priority node */ bssprio_node = list_first_entry(&bssprio_node->list, struct mwifiex_bss_prio_node, -- cgit v0.10.2 From 62a5b7dcee00c8e64e61ed98541c95fd38583116 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 16 May 2011 19:17:53 -0700 Subject: mwifiex: adjust high/low water marks for tx_pending queue This is to fix an issue that the throughput of the higher priority stream gets dropped when a lower priority stream is present. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3154b0a..8316b3c 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -69,7 +69,8 @@ struct mwifiex_drv_mode { #define MWIFIEX_TIMER_10S 10000 #define MWIFIEX_TIMER_1S 1000 -#define MAX_TX_PENDING 60 +#define MAX_TX_PENDING 100 +#define LOW_TX_PENDING 80 #define MWIFIEX_UPLD_SIZE (2312) diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 2101208..aaa50c0 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -140,7 +140,9 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, } else { priv->stats.tx_errors++; } - atomic_dec(&adapter->tx_pending); + + if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) + goto done; for (i = 0; i < adapter->priv_num; i++) { -- cgit v0.10.2 From 20ba2861b09ae942398eda6d2dc0bf1019a97ddb Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Mon, 16 May 2011 21:46:28 -0700 Subject: iwlwifi: remove unused parameter from iwl_hcmd_queue_reclaim cmd_index is never used. Signed-off-by: Daniel Halperin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 54a935f..686e176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -746,8 +746,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * need to be reclaimed. As result, some free space forms. If there is * enough free space (> low mark), wake the stack that feeds us. */ -static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, - int idx, int cmd_idx) +static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct iwl_queue *q = &txq->q; @@ -819,7 +818,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) spin_lock_irqsave(&priv->hcmd_lock, flags); - iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); + iwl_hcmd_queue_reclaim(priv, txq_id, index); if (!(meta->flags & CMD_ASYNC)) { clear_bit(STATUS_HCMD_ACTIVE, &priv->status); -- cgit v0.10.2 From c75197a779b6f5ee4c5b859423a0d5257475ebee Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:41:20 +0530 Subject: ath9k_htc: Fix mode selection Remove all the unsupported modes like FH, TURBO etc. Since this requires a FW update, increase the fw version to 1.3 Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 2bdcdbc..0d6ff79 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -18,7 +18,7 @@ #define HTC_USB_H #define MAJOR_VERSION_REQ 1 -#define MINOR_VERSION_REQ 2 +#define MINOR_VERSION_REQ 3 #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index dfc7a98..5ec214c 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -46,15 +46,8 @@ extern struct ieee80211_ops ath9k_htc_ops; extern int htc_modparam_nohwcrypt; enum htc_phymode { - HTC_MODE_AUTO = 0, - HTC_MODE_11A = 1, - HTC_MODE_11B = 2, - HTC_MODE_11G = 3, - HTC_MODE_FH = 4, - HTC_MODE_TURBO_A = 5, - HTC_MODE_TURBO_G = 6, - HTC_MODE_11NA = 7, - HTC_MODE_11NG = 8 + HTC_MODE_11NA = 0, + HTC_MODE_11NG = 1 }; enum htc_opmode { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5aa104f..6065c2f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -26,7 +26,7 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, { enum htc_phymode mode; - mode = HTC_MODE_AUTO; + mode = -EINVAL; switch (ichan->chanmode) { case CHANNEL_G: @@ -45,6 +45,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, break; } + WARN_ON(mode < 0); + return mode; } -- cgit v0.10.2 From 84dfa7308ccba190ad7efe655c25ca80793c029e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:41:31 +0530 Subject: ath9k_htc: Fix station flags The FW does absolutely nothing with the station flags, so remove them. But keep the field around since it might come in handy in the future. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 5ec214c..29dfdf8 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -116,18 +116,13 @@ struct ath9k_htc_target_vif { u8 pad; } __packed; -#define ATH_HTC_STA_AUTH 0x0001 -#define ATH_HTC_STA_QOS 0x0002 -#define ATH_HTC_STA_ERP 0x0004 -#define ATH_HTC_STA_HT 0x0008 - struct ath9k_htc_target_sta { u8 macaddr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 sta_index; u8 vif_index; u8 is_vif_sta; - __be16 flags; /* ATH_HTC_STA_* */ + __be16 flags; __be16 htcap; __be16 maxampdu; u8 pad; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 6065c2f..b1b8613 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -502,9 +502,6 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, tsta.maxampdu = cpu_to_be16(maxampdu); } - if (sta && sta->ht_cap.ht_supported) - tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); - WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { if (sta) -- cgit v0.10.2 From db32124a3f463e551ebffe3b4c6045924d3dfafd Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:41:41 +0530 Subject: ath9k_htc: Recalculate the BSSID mask on interface Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index b1b8613..8a82e82 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1164,6 +1164,8 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); + ath9k_htc_set_bssid_mask(priv, vif); + /* * Stop ANI only if there are no associated station interfaces. */ -- cgit v0.10.2 From 33a5315f97e5b3964183f0cf74768ac47eabe631 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:41:52 +0530 Subject: ath9k_htc: Fix RX filter calculation Choose the MY_BEACON filter only in case of a single interface. Also, set the ATH9K_RX_FILTER_MCAST_BCAST_ALL filter in case of interfaces. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a898dac..0ecc242 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -875,6 +875,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) rfilt |= ATH9K_RX_FILTER_CONTROL; if ((ah->opmode == NL80211_IFTYPE_STATION) && + (priv->nvifs <= 1) && !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC)) rfilt |= ATH9K_RX_FILTER_MYBEACON; else @@ -888,6 +889,9 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) if (priv->rxfilter & FIF_PSPOLL) rfilt |= ATH9K_RX_FILTER_PSPOLL; + if (priv->nvifs > 1) + rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; + return rfilt; #undef RX_FILTER_PRESERVE -- cgit v0.10.2 From 0cd075d74b319b88bbaad666c2b9b911859a5b0e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:42:03 +0530 Subject: ath9k_htc: Fix BSSID calculation The BSSID/AID has to be set for the first associated station interface. Subsequent interfaces may move out of assoc/disassoc status, in which case, the BSSID has to be re-calculated from the available interfaces. Also, ANI should be enabled or disabled based on the current opmode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 29dfdf8..fa5bb39 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -438,6 +438,7 @@ struct ath9k_htc_priv { u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; u8 num_ibss_vif; u8 num_sta_vif; + u8 num_sta_assoc_vif; u8 num_ap_vif; u16 op_flags; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8a82e82..6eedabb 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1436,6 +1436,37 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, return ret; } +static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + + ath9k_hw_write_associd(priv->ah); + ath_dbg(common, ATH_DBG_CONFIG, + "BSSID: %pM aid: 0x%x\n", + common->curbssid, common->curaid); +} + +static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) { + common->curaid = bss_conf->aid; + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + } +} + +static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) +{ + if (priv->num_sta_assoc_vif == 1) { + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_bss_iter, priv); + ath9k_htc_set_bssid(priv); + } +} + static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -1444,43 +1475,32 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); - bool set_assoc; mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); - /* - * Set the HW AID/BSSID only for the first station interface - * or in IBSS mode. - */ - set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) || - ((priv->ah->opmode == NL80211_IFTYPE_STATION) && - (priv->num_sta_vif == 1))); - - if (changed & BSS_CHANGED_ASSOC) { - if (set_assoc) { - ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", - bss_conf->assoc); + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", + bss_conf->assoc); - common->curaid = bss_conf->assoc ? - bss_conf->aid : 0; + bss_conf->assoc ? + priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; - if (bss_conf->assoc) + if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); - else + else if (priv->num_sta_assoc_vif == 0) ath9k_htc_stop_ani(priv); } } if (changed & BSS_CHANGED_BSSID) { - if (set_assoc) { + if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { + common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - ath9k_hw_write_associd(ah); - - ath_dbg(common, ATH_DBG_CONFIG, - "BSSID: %pM aid: 0x%x\n", - common->curbssid, common->curaid); + ath9k_htc_set_bssid(priv); + } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); } } -- cgit v0.10.2 From bd54879958f3e7efe249f69c75718cc9ee915cf8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:42:14 +0530 Subject: ath9k_htc: Fix max subframe handling Commit "ath9k_htc: Fix AMPDU subframe handling" registered the maximum subframe limit of the driver with mac80211, which was used in ADDBA negotiation. While technically correct, this causes inter-operability issues with a few APs. Revert to the older behavior to fix this. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index bfdc8a8..d222456 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -769,11 +769,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->channel_change_time = 5000; hw->max_listen_interval = 10; - if (AR_SREV_9271(priv->ah)) - hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271; - else - hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010; - hw->vif_data_size = sizeof(struct ath9k_htc_vif); hw->sta_data_size = sizeof(struct ath9k_htc_sta); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 6eedabb..bee100e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -581,7 +581,7 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); tcap.ampdu_limit = cpu_to_be32(0xffff); - tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; + tcap.ampdu_subframes = 0xff; tcap.enable_coex = enable_coex; tcap.tx_chainmask = priv->ah->caps.tx_chainmask; -- cgit v0.10.2 From d108e8b9320b77e3fa165757fd40f298bdd89d1c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:42:24 +0530 Subject: ath9k_htc: Change credit limit for UB94/95 Reduce the credit size for UB94/95 to fix target hangs. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index d222456..8657d26 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -258,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, */ if (IS_AR7010_DEVICE(drv_info)) - priv->htc->credits = 48; + priv->htc->credits = 45; else priv->htc->credits = 33; -- cgit v0.10.2 From 89ea674565611908e11f92f57b15bf50d82f1f22 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 12:42:34 +0530 Subject: ath9k_htc: Fix packet timeout The WMI tx status event timeout was not aligning with the TX cleanup timer threshold value. Fix this to handle dropped packets. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index fa5bb39..e09b20f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -273,9 +273,9 @@ struct ath9k_htc_rx { }; #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ -#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ +#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 3000 /* ms */ #define ATH9K_HTC_TX_RESERVE 10 -#define ATH9K_HTC_TX_TIMEOUT_COUNT 20 +#define ATH9K_HTC_TX_TIMEOUT_COUNT 40 #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) -- cgit v0.10.2 From a455c57ed3e4b2166c42286dd7987f36b5e00612 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 17 May 2011 13:05:05 +0530 Subject: ath_hw: Fix bssid mask documentation Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index 183c282..eda470b 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c @@ -43,7 +43,7 @@ * set of ~ ( MAC XOR BSSID ) for all bssids we handle. * * When you do this you are essentially computing the common bits of all your - * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with + * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with * the MAC address to obtain the relevant bits and compare the result with * (frame's BSSID & mask) to see if they match. * @@ -71,8 +71,8 @@ * On loop iteration for BSSID-02: * bssid_mask &= ~(0001 ^ 1001) * bssid_mask = (1010) & ~(0001 ^ 1001) - * bssid_mask = (1010) & ~(1001) - * bssid_mask = (1010) & (0110) + * bssid_mask = (1010) & ~(1000) + * bssid_mask = (1010) & (0111) * bssid_mask = 0010 * * A bssid_mask of 0010 means "only pay attention to the second least @@ -102,11 +102,9 @@ * * IFRAME-02: 0001 (we should allow) * - * allow = (0001 & 1010) == 1010 - * * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; - * --> allow = (0010) == (0010) + * --> allow = (0000) == (0000) * --> allow = 1 * * Other examples: -- cgit v0.10.2 From 5b68138e5659cbfd5df2879d17f9ba0b66477fec Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 May 2011 13:36:18 +0530 Subject: ath9k: Drag the driver to the year 2011 The Times They Are a-Changin'. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 6195639..5b49cd0 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-2011 Atheros Communications Inc. * Copyright (c) 2009 Gabor Juhos * Copyright (c) 2009 Imre Kaloz * diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 5a1f4f5..bfb6481 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 0cd6783..dbab5b9 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 36f7d06..234617c 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 4361704..4800dfe 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index 69a94c7..6d2e2f3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index cb611b2..015d974 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f44c84a..f344cc2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 6203eed..7573257 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7a332f1..077e8a6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index a57e963..2fe0a34 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 47780ef..453af6d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index f915a3d..e8ac70d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index f276cb9..f48051c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c7ad056..6a6125c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index afb0b5e..ab21a49 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -1,3 +1,19 @@ +/* + * 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. + */ + #ifndef AR9003_EEPROM_H #define AR9003_EEPROM_H diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index a55eddb..392bf0f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index be6adec..10d71f7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index 45cc7e8..c504493 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 356d2fd7..e4d6a87 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 25f3c2f..eee23ec 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index c7505b4..443090d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2010 Atheros Communications, Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index fbdde29..611ea6c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 03b37d7..b070f40 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index c7f4679..2f65994 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 23f15a7..41ce0b1 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2009-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 diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index a9efca8..234f776 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2009-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 diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 558b228..a1250c5 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 4420780..1bef41d 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 74535e6..fa6bd2d 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2009-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 diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 5124f14..77ec288 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2009-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 diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 7afe332..c21269c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 5488a32..8ce6ad8 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 8c18bed..e61404d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 3e31613..de99c0d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 6f714dd..5b1e894 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b87db47..7856f0d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index c031854..17f0a68 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0349b3a..bc713fc 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 2e3a33a..260f1f3 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 0d6ff79..794f630 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e09b20f..5bc0220 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 0ded2c6..aa6a731 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index af57fe5..db2352e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8657d26..61e6d39 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index bee100e..7b77968 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 0ecc242..2d81c70 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 5c76352..4d84295 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 91a5305..e1ffbb6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 8b8f044..2f3e072 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b75b5dc..72543ce 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7af2773..57435ce 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b172d15..45c585a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index bd6d2b9..c2091f1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index b60c130..8e848c4 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 45303bdb..8635cd2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index e83128c..f3cb54a 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 9441bf8..8b38030 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b877d96..133502b 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004 Video54 Technologies, Inc. - * Copyright (c) 2004-2009 Atheros Communications, Inc. + * Copyright (c) 2004-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 diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 5d984b8..c3d8502 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 Sam Leffler, Errno Consulting * Copyright (c) 2004 Video54 Technologies, Inc. - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 4f52e04..07e35e5 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 456f3ec..c18ee99 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index f9b1eb4..35422fc 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 6095eeb..fde6da6 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * 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 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 41469d7..fa821b9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-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 -- cgit v0.10.2 From ac56703e0e790509963ee42cddebe706fbd3b74c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 17 May 2011 10:34:12 +0200 Subject: ath9k: fix ad-hoc nexttbtt calculation rounding up the delta between last-beacon-tsf and tsf to intval is wrong and can lead to misconfigured timers which breaks beacon transmission. Fix this by adding intval and subtracting the offset of the tsf within the current slot. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 2f65994..61b501a 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -654,7 +654,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, delta = (tsf - sc->beacon.bc_tstamp); else delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); - nexttbtt = tsf + roundup(delta, intval); + nexttbtt = tsf + intval - (delta % intval); } ath_dbg(common, ATH_DBG_BEACON, -- cgit v0.10.2 From 620d785ba9066d5436857ec8e7c104c7b1c467e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 14:00:00 +0200 Subject: b43: add helpers for block R/W ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index fd69d6a..02eca18 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -897,6 +897,18 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) ssb_write32(dev->sdev, offset, value); } +static inline void b43_block_read(struct b43_wldev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_read(dev->sdev, buffer, count, offset, reg_width); +} + +static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_write(dev->sdev, buffer, count, offset, reg_width); +} + static inline bool b43_using_pio_transfers(struct b43_wldev *dev) { return dev->__using_pio_transfers; diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index af0596d..72ab94d 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -339,7 +339,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; b43_piotx_write16(q, B43_PIO_TXCTL, ctl); - ssb_block_write(dev->sdev, data, (data_len & ~1), + b43_block_write(dev, data, (data_len & ~1), q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); if (data_len & 1) { @@ -351,7 +351,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, b43_piotx_write16(q, B43_PIO_TXCTL, ctl); tail[0] = data[data_len - 1]; tail[1] = 0; - ssb_block_write(dev->sdev, tail, 2, + b43_block_write(dev, tail, 2, q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); } @@ -393,7 +393,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); - ssb_block_write(dev->sdev, data, (data_len & ~3), + b43_block_write(dev, data, (data_len & ~3), q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); if (data_len & 3) { @@ -421,7 +421,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, break; } b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); - ssb_block_write(dev->sdev, tail, 4, + b43_block_write(dev, tail, 4, q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); } @@ -657,11 +657,11 @@ data_ready: /* Get the preamble (RX header) */ if (q->rev >= 8) { - ssb_block_read(dev->sdev, rxhdr, sizeof(*rxhdr), + b43_block_read(dev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); } else { - ssb_block_read(dev->sdev, rxhdr, sizeof(*rxhdr), + b43_block_read(dev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); } @@ -697,7 +697,7 @@ data_ready: skb_reserve(skb, 2); skb_put(skb, len + padding); if (q->rev >= 8) { - ssb_block_read(dev->sdev, skb->data + padding, (len & ~3), + b43_block_read(dev, skb->data + padding, (len & ~3), q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); if (len & 3) { @@ -705,7 +705,7 @@ data_ready: BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); /* Read the last few bytes. */ - ssb_block_read(dev->sdev, tail, 4, + b43_block_read(dev, tail, 4, q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); switch (len & 3) { @@ -724,7 +724,7 @@ data_ready: } } } else { - ssb_block_read(dev->sdev, skb->data + padding, (len & ~1), + b43_block_read(dev, skb->data + padding, (len & ~1), q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); if (len & 1) { @@ -732,7 +732,7 @@ data_ready: BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); /* Read the last byte. */ - ssb_block_read(dev->sdev, tail, 2, + b43_block_read(dev, tail, 2, q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); skb->data[len + padding - 1] = tail[0]; -- cgit v0.10.2 From 0355a3452fe218b2bc61a7a571064ee86dd6bf4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 14:00:01 +0200 Subject: b43: make b43_wireless_init less bus specific MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ea58e27..fcbf670 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4925,19 +4925,16 @@ static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) ieee80211_free_hw(hw); } -static int b43_wireless_init(struct ssb_device *dev) +static struct b43_wl *b43_wireless_init(struct ssb_device *dev) { struct ssb_sprom *sprom = &dev->bus->sprom; struct ieee80211_hw *hw; struct b43_wl *wl; - int err = -ENOMEM; - - b43_sprom_fixup(dev->bus); hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); if (!hw) { b43err(NULL, "Could not allocate ieee80211 device\n"); - goto out; + return ERR_PTR(-ENOMEM); } wl = hw_to_b43_wl(hw); @@ -4971,12 +4968,9 @@ static int b43_wireless_init(struct ssb_device *dev) INIT_WORK(&wl->tx_work, b43_tx_work); skb_queue_head_init(&wl->tx_queue); - ssb_set_devtypedata(dev, wl); b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", dev->bus->chip_id, dev->id.revision); - err = 0; -out: - return err; + return wl; } static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) @@ -4989,11 +4983,14 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) if (!wl) { /* Probing the first core. Must setup common struct b43_wl */ first = 1; - err = b43_wireless_init(dev); - if (err) + b43_sprom_fixup(dev->bus); + wl = b43_wireless_init(dev); + if (IS_ERR(wl)) { + err = PTR_ERR(wl); goto out; - wl = ssb_get_devtypedata(dev); - B43_WARN_ON(!wl); + } + ssb_set_devtypedata(dev, wl); + B43_WARN_ON(ssb_get_devtypedata(dev) != wl); } err = b43_one_core_attach(dev, wl); if (err) -- cgit v0.10.2 From 05100a29cb65b7473bc0c71282df3e31b460b728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 14:00:02 +0200 Subject: b43: dma: cache translation (routing bits) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 02eca18..3c8200c 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -567,6 +567,8 @@ struct b43_dma { struct b43_dmaring *tx_ring_mcast; /* Multicast */ struct b43_dmaring *rx_ring; + + u32 translation; /* Routing bits */ }; struct b43_pio_txqueue; diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 10cfba3..47d44bc 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -80,7 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring, addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addr |= ssb_dma_translation(ring->dev->sdev); + addr |= ring->dev->dma.translation; ctl = bufsize & B43_DMA32_DCTL_BYTECNT; if (slot == ring->nr_slots - 1) ctl |= B43_DMA32_DCTL_DTABLEEND; @@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring, addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addrhi |= (ssb_dma_translation(ring->dev->sdev) << 1); + addrhi |= (ring->dev->dma.translation << 1); if (slot == ring->nr_slots - 1) ctl0 |= B43_DMA64_DCTL0_DTABLEEND; if (start) @@ -658,7 +658,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring) int err = 0; u32 value; u32 addrext; - u32 trans = ssb_dma_translation(ring->dev->sdev); + u32 trans = ring->dev->dma.translation; if (ring->tx) { if (ring->type == B43_DMA_64BIT) { @@ -1055,6 +1055,7 @@ int b43_dma_init(struct b43_wldev *dev) err = b43_dma_set_mask(dev, dmamask); if (err) return err; + dma->translation = ssb_dma_translation(dev->sdev); err = -ENOMEM; /* setup TX DMA channels. */ -- cgit v0.10.2 From c4a2a08165dd5a58e24eb342902839dca78887b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 18:57:27 +0200 Subject: b43: add helper for finding GPIO device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index fcbf670..7b3b3f7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2556,10 +2556,20 @@ out: /* Initialize the GPIOs * http://bcm-specs.sipsolutions.net/GPIO */ -static int b43_gpio_init(struct b43_wldev *dev) +static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; - struct ssb_device *gpiodev, *pcidev = NULL; + +#ifdef CONFIG_SSB_DRIVER_PCICORE + return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); +#else + return bus->chipco.dev; +#endif +} + +static int b43_gpio_init(struct b43_wldev *dev) +{ + struct ssb_device *gpiodev; u32 mask, set; b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2591,15 +2601,11 @@ static int b43_gpio_init(struct b43_wldev *dev) if (dev->sdev->id.revision >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ -#ifdef CONFIG_SSB_DRIVER_PCICORE - pcidev = bus->pcicore.dev; -#endif - gpiodev = bus->chipco.dev ? : pcidev; - if (!gpiodev) - return 0; - ssb_write32(gpiodev, B43_GPIO_CONTROL, - (ssb_read32(gpiodev, B43_GPIO_CONTROL) - & mask) | set); + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, + (ssb_read32(gpiodev, B43_GPIO_CONTROL) + & mask) | set); return 0; } @@ -2607,16 +2613,11 @@ static int b43_gpio_init(struct b43_wldev *dev) /* Turn off all GPIO stuff. Call this on module unload, for example. */ static void b43_gpio_cleanup(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - struct ssb_device *gpiodev, *pcidev = NULL; + struct ssb_device *gpiodev; -#ifdef CONFIG_SSB_DRIVER_PCICORE - pcidev = bus->pcicore.dev; -#endif - gpiodev = bus->chipco.dev ? : pcidev; - if (!gpiodev) - return; - ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); } /* http://bcm-specs.sipsolutions.net/EnableMac */ -- cgit v0.10.2 From 1495298ddd496131b8226a837ab10bdd5acb3480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 18:57:28 +0200 Subject: b43: separate ssb core reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7b3b3f7..1bc40eb 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1143,10 +1143,9 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) } } -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) +static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) { u32 tmslow; - u32 macctl; flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; @@ -1166,6 +1165,13 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ msleep(1); +} + +void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) +{ + u32 macctl; + + b43_ssb_wireless_core_reset(dev, flags); /* Turn Analog ON, but only if we already know the PHY-type. * This protects against very early setup where we don't know the -- cgit v0.10.2 From 755173291a86c6e77414e1eaf22279fde88ccd86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 17 May 2011 19:19:39 +0200 Subject: b43: read PHY info only when needed (for PHY-A) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We risk reading TMSHIGH register twice, but PHY-A are really rare and we do not support them at the moment. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1bc40eb..fff14ad 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2118,7 +2118,6 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) int err; /* Get microcode */ - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); if ((rev >= 5) && (rev <= 10)) filename = "ucode5"; else if ((rev >= 11) && (rev <= 12)) @@ -2157,6 +2156,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { + tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1initvals5"; else @@ -2201,6 +2201,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { + tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1bsinitvals5"; else -- cgit v0.10.2 From ba4903f97a275ed0967b58ff882f8ab41bec24ad Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 17 May 2011 21:09:54 +0200 Subject: ath9k: implement .tx_last_beacon() Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b070f40..f75068b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -397,6 +397,9 @@ struct ath_beacon { struct ath_descdma bdma; struct ath_txq *cabq; struct list_head bbuf; + + bool tx_processed; + bool tx_last; }; void ath_beacon_tasklet(unsigned long data); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 61b501a..d4d8cec 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -18,6 +18,12 @@ #define FUDGE 2 +static void ath9k_reset_beacon_status(struct ath_softc *sc) +{ + sc->beacon.tx_processed = false; + sc->beacon.tx_last = false; +} + /* * This function will modify certain transmit queue properties depending on * the operating mode of the station (AP or AdHoc). Parameters are AIFS @@ -72,6 +78,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, struct ieee80211_supported_band *sband; u8 rate = 0; + ath9k_reset_beacon_status(sc); + ds = bf->bf_desc; flags = ATH9K_TXDESC_NOACK; @@ -134,6 +142,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, struct ieee80211_tx_info *info; int cabq_depth; + ath9k_reset_beacon_status(sc); + avp = (void *)vif->drv_priv; cabq = sc->beacon.cabq; @@ -644,6 +654,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, struct ath_common *common = ath9k_hw_common(ah); u32 tsf, delta, intval, nexttbtt; + ath9k_reset_beacon_status(sc); + tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8635cd2..bd18b1d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2324,6 +2324,45 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) return false; } +int ath9k_tx_last_beacon(struct ieee80211_hw *hw) +{ + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + struct ieee80211_vif *vif; + struct ath_vif *avp; + struct ath_buf *bf; + struct ath_tx_status ts; + int status; + + vif = sc->beacon.bslot[0]; + if (!vif) + return 0; + + avp = (void *)vif->drv_priv; + if (!avp->is_bslot_active) + return 0; + + if (!sc->beacon.tx_processed) { + tasklet_disable(&sc->bcon_tasklet); + + bf = avp->av_bcbuf; + if (!bf || !bf->bf_mpdu) + goto skip; + + status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts); + if (status == -EINPROGRESS) + goto skip; + + sc->beacon.tx_processed = true; + sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); + +skip: + tasklet_enable(&sc->bcon_tasklet); + } + + return sc->beacon.tx_last; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2348,4 +2387,5 @@ struct ieee80211_ops ath9k_ops = { .set_coverage_class = ath9k_set_coverage_class, .flush = ath9k_flush, .tx_frames_pending = ath9k_tx_frames_pending, + .tx_last_beacon = ath9k_tx_last_beacon, }; -- cgit v0.10.2 From d676ff493d9dfb8b34892214665028a8c85e2056 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 17 May 2011 16:13:34 -0700 Subject: mac80211: Don't sleep when growing the mesh path After commit 1928ecab620907a0953f811316d05f367f3f4dba (mac80211: fix and simplify mesh locking) mesh table allocation is performed with the pathtbl_resize_lock taken. Under those conditions one should not sleep. This patch makes the allocations GFP_ATOMIC to prevent that. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 2bda0ac..51f6fe8 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -76,12 +76,12 @@ static struct mesh_table *mesh_table_alloc(int size_order) int i; struct mesh_table *newtbl; - newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); + newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC); if (!newtbl) return NULL; newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * - (1 << size_order), GFP_KERNEL); + (1 << size_order), GFP_ATOMIC); if (!newtbl->hash_buckets) { kfree(newtbl); @@ -89,7 +89,7 @@ static struct mesh_table *mesh_table_alloc(int size_order) } newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * - (1 << size_order), GFP_KERNEL); + (1 << size_order), GFP_ATOMIC); if (!newtbl->hashwlock) { kfree(newtbl->hash_buckets); kfree(newtbl); -- cgit v0.10.2 From a2cd43c52aa5c676b03d575177536e05ac672c75 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 18 May 2011 11:42:03 +0300 Subject: nl80211: remove some stack variables in trigger_scan and start_sched_scan Some stack variables (name *ssid and *channel) are only used to define the size of the memory block that needs to be allocated for the request structure in the nl80211_trigger_scan() and nl80211_start_sched_scan() functions. This is unnecessary because the sizes of the actual elements in the structure can be used instead. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2222ce0..ec83f41 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3294,8 +3294,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct cfg80211_scan_request *request; - struct cfg80211_ssid *ssid; - struct ieee80211_channel *channel; struct nlattr *attr; struct wiphy *wiphy; int err, tmp, n_ssids = 0, n_channels, i; @@ -3342,8 +3340,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) return -EINVAL; request = kzalloc(sizeof(*request) - + sizeof(*ssid) * n_ssids - + sizeof(channel) * n_channels + + sizeof(*request->ssids) * n_ssids + + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); if (!request) return -ENOMEM; @@ -3449,8 +3447,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, struct cfg80211_sched_scan_request *request; struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; - struct cfg80211_ssid *ssid; - struct ieee80211_channel *channel; struct nlattr *attr; struct wiphy *wiphy; int err, tmp, n_ssids = 0, n_channels, i; @@ -3507,8 +3503,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, return -EINVAL; request = kzalloc(sizeof(*request) - + sizeof(*ssid) * n_ssids - + sizeof(channel) * n_channels + + sizeof(*request->ssids) * n_ssids + + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); if (!request) return -ENOMEM; -- cgit v0.10.2 From c6e38c06cb51bee42ff80a36a0f7c67b485c4541 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 18 May 2011 17:56:00 +0530 Subject: ath9k: use PS wakeup before REG_READ otherwise we will get deadbeef when the station is in idle state Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c21269c..d55ffd7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -435,6 +435,7 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, conf->channel_type, channel_type_str(conf->channel_type)); + ath9k_ps_wakeup(sc); put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); len += snprintf(buf + len, sizeof(buf) - len, @@ -443,7 +444,6 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); len += snprintf(buf + len, sizeof(buf) - len, "addrmask: %pM\n", addr); - ath9k_ps_wakeup(sc); tmp = ath9k_hw_getrxfilter(sc->sc_ah); ath9k_ps_restore(sc); len += snprintf(buf + len, sizeof(buf) - len, -- cgit v0.10.2 From 54a430c0a4991951805df92efb8c42bdb1277ffd Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 20 May 2011 11:56:18 -0700 Subject: iwlagn: dbg_fixed_rate only used when CONFIG_MAC80211_DEBUGFS enabled Fix compiling error when CONFIG_MAC80211_DEBUGFS is not enabled drivers/net/wireless/iwlwifi/iwl-agn-rs.c:351: error: 'struct iwl_lq_sta' has no member named 'dbg_fixed_rate' drivers/net/wireless/iwlwifi/iwl-agn-rs.c:1076: error: 'struct iwl_lq_sta' has no member named 'dbg_fixed_rate' Reported-by: Randy Dunlap Signed-off-by: Wey-Yi Guy Acked-by: Randy Dunlap Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index fec0df0..592b0cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -335,7 +335,7 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data, return tid; } -#if defined(CONFIG_MAC80211_DEBUGFS) || defined(CONFIG_IWLWIFI_DEVICE_SVTOOL) +#ifdef CONFIG_MAC80211_DEBUGFS static void rs_program_fix_rate(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta) { @@ -1072,7 +1072,7 @@ done: /* See if there's a better rate or modulation mode to try. */ if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); -#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL +#ifdef CONFIG_MAC80211_DEBUGFS if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate) rs_program_fix_rate(priv, lq_sta); #endif -- cgit v0.10.2 From 1ba0145884de7993c5d4f02d629eb18c17527e6e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 22 May 2011 17:16:20 -0700 Subject: wireless: fix cfg80211.h new kernel-doc warnings Fix new kernel-doc warnings in : Warning(linux-2.6.39-git5/include/net/cfg80211.h:560): No description found for parameter 'bss_param' Warning(linux-2.6.39-git5/include/net/cfg80211.h:1555): Enum value 'WIPHY_FLAG_SUPPORTS_SCHED_SCAN' not described in enum 'wiphy_flags' Signed-off-by: Randy Dunlap Signed-off-by: John W. Linville diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 727131b..0589f55 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -531,6 +531,7 @@ struct sta_bss_parameters { * @tx_retries: cumulative retry counts * @tx_failed: number of failed transmissions (retries exceeded, no ACK) * @rx_dropped_misc: Dropped for un-specified reason. + * @bss_param: current BSS parameters * @generation: generation number for nl80211 dumps. * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that @@ -1537,7 +1538,7 @@ struct cfg80211_ops { * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. - * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans. + * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), -- cgit v0.10.2 From daf8cf608d57a0b9f22276036e420cc82cf6ab4f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 22 May 2011 17:22:45 -0700 Subject: wireless: fix fatal kernel-doc error + warning in mac80211.h Fix new kernel-doc Error and Warning in : Error(linux-2.6.39-git5/include/net/mac80211.h:550): cannot understand prototype: 'struct ieee80211_sched_scan_ies ' Warning(linux-2.6.39-git5/include/net/mac80211.h:2289): No description found for parameter 'sta' Signed-off-by: Randy Dunlap Signed-off-by: John W. Linville diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 62a1c22..03067fb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -538,7 +538,7 @@ struct ieee80211_tx_info { }; /** - * ieee80211_sched_scan_ies - scheduled scan IEs + * struct ieee80211_sched_scan_ies - scheduled scan IEs * * This structure is used to pass the appropriate IEs to be used in scheduled * scans for all bands. It contains both the IEs passed from the userspace @@ -2278,6 +2278,7 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta, /** * ieee80211_sta_set_tim - set the TIM bit for a sleeping station + * @sta: &struct ieee80211_sta pointer for the sleeping station * * If a driver buffers frames for a powersave station instead of passing * them back to mac80211 for retransmission, the station needs to be told -- cgit v0.10.2