iwlagn: don't use CCK rates for P2P interfaces
authorJohannes Berg <johannes.berg@intel.com>
Wed, 22 Jun 2011 13:34:09 +0000 (06:34 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 24 Jun 2011 18:54:51 +0000 (11:54 -0700)
P2P interfaces must not use CCK rates, only OFDM
rates are allowed. To set this up, we need to set
up the broadcast station to start with 6M instead
of starting with 1M.

Since the interface type can change, also reset
the broadcast station when RXON changes.

This will affect beacons as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn.h

index a7c66c4..8fa43d4 100644 (file)
@@ -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) {
index 0bd722c..9b32f83 100644 (file)
@@ -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;
index 6d5584a..dcdf225 100644 (file)
@@ -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,