aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-10-23 12:15:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:24:54 -0500
commitbd50a8ab9f48787109f6ff761c8f0e185e3d0690 (patch)
treedef31b6c9cb8c1845187612174874fb68c91220a /drivers
parent2295c66b68ae160dde2e6e2dc4f3061105153bfc (diff)
iwlwifi: fix IBSS beaconing
My previous patch to clean up all RXON handling inadvertently broke IBSS because it failed to take into account that unlike in AP mode, IBSS requires beacons to be sent only after setting the RXON assoc. Fix this, clean up the code a bit, improve the error checking around this, and also react to beacon changes in IBSS mode from mac80211. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 58602457e415..11b3d8888360 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -72,6 +72,18 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
72 return ret; 72 return ret;
73} 73}
74 74
75static int iwlagn_update_beacon(struct iwl_priv *priv,
76 struct ieee80211_vif *vif)
77{
78 lockdep_assert_held(&priv->mutex);
79
80 dev_kfree_skb(priv->beacon_skb);
81 priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
82 if (!priv->beacon_skb)
83 return -ENOMEM;
84 return iwlagn_send_beacon_cmd(priv);
85}
86
75/** 87/**
76 * iwlagn_commit_rxon - commit staging_rxon to hardware 88 * iwlagn_commit_rxon - commit staging_rxon to hardware
77 * 89 *
@@ -201,17 +213,19 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
201 } 213 }
202 214
203 if (new_assoc) { 215 if (new_assoc) {
204 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP || 216 /*
205 ctx->vif->type == NL80211_IFTYPE_ADHOC)) { 217 * We'll run into this code path when beaconing is
206 /* 218 * enabled, but then we also need to send the beacon
207 * We'll run into this code path when beaconing is 219 * to the device.
208 * enabled, but then we also need to send the beacon 220 */
209 * to the device. 221 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
210 */ 222 ret = iwlagn_update_beacon(priv, ctx->vif);
211 dev_kfree_skb(priv->beacon_skb); 223 if (ret) {
212 priv->beacon_skb = ieee80211_beacon_get(priv->hw, 224 IWL_ERR(priv,
213 ctx->vif); 225 "Error sending required beacon (%d)!\n",
214 iwlagn_send_beacon_cmd(priv); 226 ret);
227 return ret;
228 }
215 } 229 }
216 230
217 priv->start_calib = 0; 231 priv->start_calib = 0;
@@ -228,6 +242,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
228 return ret; 242 return ret;
229 } 243 }
230 memcpy(active, &ctx->staging, sizeof(*active)); 244 memcpy(active, &ctx->staging, sizeof(*active));
245
246 /* IBSS beacon needs to be sent after setting assoc */
247 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
248 if (iwlagn_update_beacon(priv, ctx->vif))
249 IWL_ERR(priv, "Error sending IBSS beacon\n");
231 } 250 }
232 251
233 iwl_print_rx_config_cmd(priv, ctx); 252 iwl_print_rx_config_cmd(priv, ctx);
@@ -558,5 +577,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
558 bss_conf->bssid); 577 bss_conf->bssid);
559 } 578 }
560 579
580 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC &&
581 priv->beacon_ctx) {
582 if (iwlagn_update_beacon(priv, vif))
583 IWL_ERR(priv, "Error sending IBSS beacon\n");
584 }
585
561 mutex_unlock(&priv->mutex); 586 mutex_unlock(&priv->mutex);
562} 587}