diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 85ff1552481f..4b4b47676ad8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -144,9 +144,6 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | 146 | ||
147 | /* station table will be cleared */ | ||
148 | priv->assoc_station_added = 0; | ||
149 | |||
150 | /* If we are currently associated and the new config requires | 147 | /* If we are currently associated and the new config requires |
151 | * an RXON_ASSOC and the new config wants the associated mask enabled, | 148 | * an RXON_ASSOC and the new config wants the associated mask enabled, |
152 | * we must clear the associated from the active configuration | 149 | * we must clear the associated from the active configuration |
@@ -198,25 +195,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
198 | } | 195 | } |
199 | 196 | ||
200 | priv->start_calib = 0; | 197 | priv->start_calib = 0; |
201 | |||
202 | /* If we have set the ASSOC_MSK and we are in BSS mode then | ||
203 | * add the IWL_AP_ID to the station rate table */ | ||
204 | if (new_assoc) { | 198 | if (new_assoc) { |
205 | if (priv->iw_mode == NL80211_IFTYPE_STATION) { | ||
206 | ret = iwl_rxon_add_station(priv, | ||
207 | priv->active_rxon.bssid_addr, 1); | ||
208 | if (ret == IWL_INVALID_STATION) { | ||
209 | IWL_ERR(priv, | ||
210 | "Error adding AP address for TX.\n"); | ||
211 | return -EIO; | ||
212 | } | ||
213 | priv->assoc_station_added = 1; | ||
214 | if (priv->default_wep_key && | ||
215 | iwl_send_static_wepkey_cmd(priv, 0)) | ||
216 | IWL_ERR(priv, | ||
217 | "Could not send WEP static key.\n"); | ||
218 | } | ||
219 | |||
220 | /* | 199 | /* |
221 | * allow CTS-to-self if possible for new association. | 200 | * allow CTS-to-self if possible for new association. |
222 | * this is relevant only for 5000 series and up, | 201 | * this is relevant only for 5000 series and up, |
@@ -2498,10 +2477,6 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2498 | return; | 2477 | return; |
2499 | } | 2478 | } |
2500 | 2479 | ||
2501 | IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", | ||
2502 | priv->assoc_id, priv->active_rxon.bssid_addr); | ||
2503 | |||
2504 | |||
2505 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2480 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2506 | return; | 2481 | return; |
2507 | 2482 | ||
@@ -2553,6 +2528,9 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2553 | 2528 | ||
2554 | iwlcore_commit_rxon(priv); | 2529 | iwlcore_commit_rxon(priv); |
2555 | 2530 | ||
2531 | IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", | ||
2532 | priv->assoc_id, priv->active_rxon.bssid_addr); | ||
2533 | |||
2556 | switch (priv->iw_mode) { | 2534 | switch (priv->iw_mode) { |
2557 | case NL80211_IFTYPE_STATION: | 2535 | case NL80211_IFTYPE_STATION: |
2558 | break; | 2536 | break; |
@@ -2562,7 +2540,7 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2562 | /* assume default assoc id */ | 2540 | /* assume default assoc id */ |
2563 | priv->assoc_id = 1; | 2541 | priv->assoc_id = 1; |
2564 | 2542 | ||
2565 | iwl_rxon_add_station(priv, priv->bssid, 0); | 2543 | iwl_add_local_station(priv, priv->bssid, true); |
2566 | iwl_send_beacon_cmd(priv); | 2544 | iwl_send_beacon_cmd(priv); |
2567 | 2545 | ||
2568 | break; | 2546 | break; |
@@ -2573,9 +2551,6 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2573 | break; | 2551 | break; |
2574 | } | 2552 | } |
2575 | 2553 | ||
2576 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) | ||
2577 | priv->assoc_station_added = 1; | ||
2578 | |||
2579 | spin_lock_irqsave(&priv->lock, flags); | 2554 | spin_lock_irqsave(&priv->lock, flags); |
2580 | iwl_activate_qos(priv, 0); | 2555 | iwl_activate_qos(priv, 0); |
2581 | spin_unlock_irqrestore(&priv->lock, flags); | 2556 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2974,18 +2949,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | |||
2974 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 2949 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
2975 | int sta_id; | 2950 | int sta_id; |
2976 | 2951 | ||
2977 | /* | ||
2978 | * TODO: We really should use this callback to | ||
2979 | * actually maintain the station table in | ||
2980 | * the device. | ||
2981 | */ | ||
2982 | |||
2983 | switch (cmd) { | 2952 | switch (cmd) { |
2984 | case STA_NOTIFY_ADD: | ||
2985 | atomic_set(&sta_priv->pending_frames, 0); | ||
2986 | if (vif->type == NL80211_IFTYPE_AP) | ||
2987 | sta_priv->client = true; | ||
2988 | break; | ||
2989 | case STA_NOTIFY_SLEEP: | 2953 | case STA_NOTIFY_SLEEP: |
2990 | WARN_ON(!sta_priv->client); | 2954 | WARN_ON(!sta_priv->client); |
2991 | sta_priv->asleep = true; | 2955 | sta_priv->asleep = true; |
@@ -3006,6 +2970,55 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | |||
3006 | } | 2970 | } |
3007 | } | 2971 | } |
3008 | 2972 | ||
2973 | /** | ||
2974 | * iwl_restore_wepkeys - Restore WEP keys to device | ||
2975 | */ | ||
2976 | static void iwl_restore_wepkeys(struct iwl_priv *priv) | ||
2977 | { | ||
2978 | mutex_lock(&priv->mutex); | ||
2979 | if (priv->iw_mode == NL80211_IFTYPE_STATION && | ||
2980 | priv->default_wep_key && | ||
2981 | iwl_send_static_wepkey_cmd(priv, 0)) | ||
2982 | IWL_ERR(priv, "Could not send WEP static key\n"); | ||
2983 | mutex_unlock(&priv->mutex); | ||
2984 | } | ||
2985 | |||
2986 | static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | ||
2987 | struct ieee80211_vif *vif, | ||
2988 | struct ieee80211_sta *sta) | ||
2989 | { | ||
2990 | struct iwl_priv *priv = hw->priv; | ||
2991 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
2992 | bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION; | ||
2993 | int ret; | ||
2994 | u8 sta_id; | ||
2995 | |||
2996 | IWL_DEBUG_INFO(priv, "received request to add station %pM\n", | ||
2997 | sta->addr); | ||
2998 | |||
2999 | atomic_set(&sta_priv->pending_frames, 0); | ||
3000 | if (vif->type == NL80211_IFTYPE_AP) | ||
3001 | sta_priv->client = true; | ||
3002 | |||
3003 | ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, | ||
3004 | &sta_id); | ||
3005 | if (ret) { | ||
3006 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | ||
3007 | sta->addr, ret); | ||
3008 | /* Should we return success if return code is EEXIST ? */ | ||
3009 | return ret; | ||
3010 | } | ||
3011 | |||
3012 | iwl_restore_wepkeys(priv); | ||
3013 | |||
3014 | /* Initialize rate scaling */ | ||
3015 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM \n", | ||
3016 | sta->addr); | ||
3017 | iwl_rs_rate_init(priv, sta, sta_id); | ||
3018 | |||
3019 | return ret; | ||
3020 | } | ||
3021 | |||
3009 | /***************************************************************************** | 3022 | /***************************************************************************** |
3010 | * | 3023 | * |
3011 | * sysfs attributes | 3024 | * sysfs attributes |
@@ -3359,6 +3372,8 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3359 | .ampdu_action = iwl_mac_ampdu_action, | 3372 | .ampdu_action = iwl_mac_ampdu_action, |
3360 | .hw_scan = iwl_mac_hw_scan, | 3373 | .hw_scan = iwl_mac_hw_scan, |
3361 | .sta_notify = iwl_mac_sta_notify, | 3374 | .sta_notify = iwl_mac_sta_notify, |
3375 | .sta_add = iwlagn_mac_sta_add, | ||
3376 | .sta_remove = iwl_mac_sta_remove, | ||
3362 | }; | 3377 | }; |
3363 | 3378 | ||
3364 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3379 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |