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 a7c66c4e5f2a2953e3d98dbc0c6af0a9f8aa3e49..8fa43d4278114a1bad7ef73ea64020b2695cb8e8 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 0bd722cee5ae0cf3a3f2c8429fa07aa118bfbacf..9b32f83f0b7f68f7b0ba9d5aa260c24a56106dec 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 6d5584ae5ebff6b0ffd8e7d7bbd316fb91f23e69..dcdf2259520fc423f90302e1b12c822d9cd85037 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,