diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a7c66c4e5f2a2953e3d98dbc0c6af0a9f8aa3e49..8fa43d4278114a1bad7ef73ea64020b2695cb8e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -210,6 +210,8 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, * keys, so we have to restore those afterwards. */ iwl_clear_ucode_stations(priv, ctx); + /* update -- might need P2P now */ + iwl_update_bcast_station(priv, ctx); iwl_restore_stations(priv, ctx); ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 0bd722cee5ae0cf3a3f2c8429fa07aa118bfbacf..9b32f83f0b7f68f7b0ba9d5aa260c24a56106dec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -35,7 +35,7 @@ #include "iwl-agn.h" static struct iwl_link_quality_cmd * -iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) +iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id) { int i, r; struct iwl_link_quality_cmd *link_cmd; @@ -47,10 +47,15 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); return NULL; } + + lockdep_assert_held(&priv->mutex); + /* Set up the rate scaling to start at selected rate, fall back * all the way down to 1M in IEEE order, and then spin on 1M */ if (priv->band == IEEE80211_BAND_5GHZ) r = IWL_RATE_6M_INDEX; + else if (ctx && ctx->vif && ctx->vif->p2p) + r = IWL_RATE_6M_INDEX; else r = IWL_RATE_1M_INDEX; @@ -115,7 +120,7 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx spin_unlock_irqrestore(&priv->sta_lock, flags); /* Set up default rate scaling table in device's station table */ - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", addr); @@ -554,7 +559,7 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, priv->stations[sta_id].used |= IWL_STA_BCAST; spin_unlock_irqrestore(&priv->sta_lock, flags); - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); @@ -574,14 +579,14 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, * Only used by iwlagn. Placed here to have all bcast station management * code together. */ -static int iwl_update_bcast_station(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) +int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { unsigned long flags; struct iwl_link_quality_cmd *link_cmd; u8 sta_id = ctx->bcast_sta_id; - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); return -ENOMEM; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 77ceb8deff7563a6f20d9c06b9eb8dc0f63a692a..e2f6b2ab0d45778f5656de9f15278d855ecdaa7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -132,6 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_host_cmd cmd = { .id = REPLY_TX_BEACON, }; + struct ieee80211_tx_info *info; u32 frame_size; u32 rate_flags; u32 rate; @@ -172,14 +173,31 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) frame_size); /* Set up packet rate and flags */ - rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); + info = IEEE80211_SKB_CB(priv->beacon_skb); + + /* + * Let's set up the rate at least somewhat correctly; + * it will currently not actually be used by the uCode, + * it uses the broadcast station's rate instead. + */ + if (info->control.rates[0].idx < 0 || + info->control.rates[0].flags & IEEE80211_TX_RC_MCS) + rate = 0; + else + rate = info->control.rates[0].idx; + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); - if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) + + /* In mac80211, rates for 5 GHz start at 0 */ + if (info->band == IEEE80211_BAND_5GHZ) + rate += IWL_FIRST_OFDM_RATE; + else if (rate >= IWL_FIRST_CCK_RATE && rate <= IWL_LAST_CCK_RATE) rate_flags |= RATE_MCS_CCK_MSK; - tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, - rate_flags); + + tx_beacon_cmd->tx.rate_n_flags = + iwl_hw_set_rate_n_flags(rate, rate_flags); /* Submit command */ cmd.len[0] = sizeof(*tx_beacon_cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 6d5584ae5ebff6b0ffd8e7d7bbd316fb91f23e69..dcdf2259520fc423f90302e1b12c822d9cd85037 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -304,6 +304,8 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid); void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); +int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwl_update_bcast_stations(struct iwl_priv *priv); void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index cde725326c32a4c7843991d4aa1a0e257f122755..f0eabbc07c95be28b44bc19637f5e98151659530 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -526,19 +526,6 @@ int iwl_full_rxon_required(struct iwl_priv *priv, return 0; } -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - /* - * Assign the lowest rate -- should really get this from - * the beacon skb from mac80211. - */ - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) - return IWL_RATE_1M_PLCP; - else - return IWL_RATE_6M_PLCP; -} - static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, struct iwl_rxon_context *ctx) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index adf9f9b2efb52d4e3e6e8145df9cec55f460e796..f881678be762c843986f938d02e97f111b778059 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -408,13 +408,6 @@ void iwl_setup_watchdog(struct iwl_priv *priv); ****************************************************/ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); -/******************************************************************************* - * Rate - ******************************************************************************/ - -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); - /******************************************************************************* * Scanning ******************************************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 7cdb1ec73b54b7a40f015a64ec1bd8bc2861951c..e3e5fb614178070b086c73bd3a9656ef0d977cce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -113,7 +113,7 @@ const char *get_cmd_string(u8 cmd) } } -#define HOST_COMPLETE_TIMEOUT (HZ / 2) +#define HOST_COMPLETE_TIMEOUT (2 * HZ) static void iwl_generic_cmd_callback(struct iwl_priv *priv, struct iwl_device_cmd *cmd, diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 7328fbff7f7b011189aaf8073bd690e0bc8f5a76..3927c802a5d8f3f158ac0b1111bc964825e5635a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -530,14 +530,7 @@ static int iwl_pci_resume(struct device *device) return iwl_resume(priv); } -static const struct dev_pm_ops iwl_dev_pm_ops = { - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, - .freeze = iwl_pci_suspend, - .thaw = iwl_pci_resume, - .poweroff = iwl_pci_suspend, - .restore = iwl_pci_resume, -}; +static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); #define IWL_PM_OPS (&iwl_dev_pm_ops) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index fd8aee9972c1663ccd7a9d0ba32d762c283c5d6a..cf8fc9afa1eaa5c0b30e4c6d3c8f43d8755cbaa2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -309,10 +309,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) i = get_cmd_index(q, q->read_ptr); if (txq->meta[i].flags & CMD_MAPPED) { - dma_unmap_single(priv->bus.dev, - dma_unmap_addr(&txq->meta[i], mapping), - dma_unmap_len(&txq->meta[i], len), - DMA_BIDIRECTIONAL); + iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i]); txq->meta[i].flags = 0; }