diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-05-15 01:54:04 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:47:58 -0400 |
commit | 4f40e4d9fb8fe028db9ba2a7b4d3ac7328f73bbc (patch) | |
tree | 2fee89bbf870a188fb36c0c6a1cecc5c48fe8173 | |
parent | 57bd1bea485bf6f37ff365dec2203ba6467b41a1 (diff) |
iwlwifi: move more station managment into iwl-sta.c
This patch moves station management functions into iwl-sta.c (iwlcore).
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 101 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 269 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 178 |
6 files changed, 283 insertions, 279 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index e2123aba202c..ce70f2b29b61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -2150,7 +2150,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2150 | if (sta_id == IWL_INVALID_STATION) { | 2150 | if (sta_id == IWL_INVALID_STATION) { |
2151 | IWL_DEBUG_RATE("LQ: ADD station %s\n", | 2151 | IWL_DEBUG_RATE("LQ: ADD station %s\n", |
2152 | print_mac(mac, hdr->addr1)); | 2152 | print_mac(mac, hdr->addr1)); |
2153 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, | 2153 | sta_id = iwl_add_station_flags(priv, hdr->addr1, |
2154 | 0, CMD_ASYNC, NULL); | 2154 | 0, CMD_ASYNC, NULL); |
2155 | } | 2155 | } |
2156 | if ((sta_id != IWL_INVALID_STATION)) { | 2156 | if ((sta_id != IWL_INVALID_STATION)) { |
@@ -2234,7 +2234,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2234 | if (sta_id == IWL_INVALID_STATION) { | 2234 | if (sta_id == IWL_INVALID_STATION) { |
2235 | IWL_DEBUG_RATE("LQ: ADD station %s\n", | 2235 | IWL_DEBUG_RATE("LQ: ADD station %s\n", |
2236 | print_mac(mac, sta->addr)); | 2236 | print_mac(mac, sta->addr)); |
2237 | sta_id = iwl4965_add_station_flags(priv, sta->addr, | 2237 | sta_id = iwl_add_station_flags(priv, sta->addr, |
2238 | 0, CMD_ASYNC, NULL); | 2238 | 0, CMD_ASYNC, NULL); |
2239 | } | 2239 | } |
2240 | if ((sta_id != IWL_INVALID_STATION)) { | 2240 | if ((sta_id != IWL_INVALID_STATION)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 44215a7ab0ad..aeaf5f789970 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -3433,109 +3433,8 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id, | |||
3433 | 3433 | ||
3434 | #endif /* CONFIG_IWL4965_HT */ | 3434 | #endif /* CONFIG_IWL4965_HT */ |
3435 | 3435 | ||
3436 | /** | ||
3437 | * iwl4965_add_station - Initialize a station's hardware rate table | ||
3438 | * | ||
3439 | * The uCode's station table contains a table of fallback rates | ||
3440 | * for automatic fallback during transmission. | ||
3441 | * | ||
3442 | * NOTE: This sets up a default set of values. These will be replaced later | ||
3443 | * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of | ||
3444 | * rc80211_simple. | ||
3445 | * | ||
3446 | * NOTE: Run REPLY_ADD_STA command to set up station table entry, before | ||
3447 | * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, | ||
3448 | * which requires station table entry to exist). | ||
3449 | */ | ||
3450 | void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | ||
3451 | { | ||
3452 | int i, r; | ||
3453 | struct iwl_link_quality_cmd link_cmd = { | ||
3454 | .reserved1 = 0, | ||
3455 | }; | ||
3456 | u16 rate_flags; | ||
3457 | |||
3458 | /* Set up the rate scaling to start at selected rate, fall back | ||
3459 | * all the way down to 1M in IEEE order, and then spin on 1M */ | ||
3460 | if (is_ap) | ||
3461 | r = IWL_RATE_54M_INDEX; | ||
3462 | else if (priv->band == IEEE80211_BAND_5GHZ) | ||
3463 | r = IWL_RATE_6M_INDEX; | ||
3464 | else | ||
3465 | r = IWL_RATE_1M_INDEX; | ||
3466 | |||
3467 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { | ||
3468 | rate_flags = 0; | ||
3469 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | ||
3470 | rate_flags |= RATE_MCS_CCK_MSK; | ||
3471 | |||
3472 | /* Use Tx antenna B only */ | ||
3473 | rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/ | ||
3474 | |||
3475 | link_cmd.rs_table[i].rate_n_flags = | ||
3476 | iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | ||
3477 | r = iwl4965_get_prev_ieee_rate(r); | ||
3478 | } | ||
3479 | |||
3480 | link_cmd.general_params.single_stream_ant_msk = 2; | ||
3481 | link_cmd.general_params.dual_stream_ant_msk = 3; | ||
3482 | link_cmd.agg_params.agg_dis_start_th = 3; | ||
3483 | link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); | ||
3484 | |||
3485 | /* Update the rate scaling for control frame Tx to AP */ | ||
3486 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; | ||
3487 | |||
3488 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, | ||
3489 | sizeof(link_cmd), &link_cmd, NULL); | ||
3490 | } | ||
3491 | 3436 | ||
3492 | #ifdef CONFIG_IWL4965_HT | 3437 | #ifdef CONFIG_IWL4965_HT |
3493 | |||
3494 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
3495 | struct ieee80211_ht_info *sta_ht_inf) | ||
3496 | { | ||
3497 | __le32 sta_flags; | ||
3498 | u8 mimo_ps_mode; | ||
3499 | |||
3500 | if (!sta_ht_inf || !sta_ht_inf->ht_supported) | ||
3501 | goto done; | ||
3502 | |||
3503 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2; | ||
3504 | |||
3505 | sta_flags = priv->stations[index].sta.station_flags; | ||
3506 | |||
3507 | sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); | ||
3508 | |||
3509 | switch (mimo_ps_mode) { | ||
3510 | case WLAN_HT_CAP_MIMO_PS_STATIC: | ||
3511 | sta_flags |= STA_FLG_MIMO_DIS_MSK; | ||
3512 | break; | ||
3513 | case WLAN_HT_CAP_MIMO_PS_DYNAMIC: | ||
3514 | sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; | ||
3515 | break; | ||
3516 | case WLAN_HT_CAP_MIMO_PS_DISABLED: | ||
3517 | break; | ||
3518 | default: | ||
3519 | IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode); | ||
3520 | break; | ||
3521 | } | ||
3522 | |||
3523 | sta_flags |= cpu_to_le32( | ||
3524 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); | ||
3525 | |||
3526 | sta_flags |= cpu_to_le32( | ||
3527 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | ||
3528 | |||
3529 | if (iwl_is_fat_tx_allowed(priv, sta_ht_inf)) | ||
3530 | sta_flags |= STA_FLG_FAT_EN_MSK; | ||
3531 | else | ||
3532 | sta_flags &= ~STA_FLG_FAT_EN_MSK; | ||
3533 | |||
3534 | priv->stations[index].sta.station_flags = sta_flags; | ||
3535 | done: | ||
3536 | return; | ||
3537 | } | ||
3538 | |||
3539 | static int iwl4965_rx_agg_start(struct iwl_priv *priv, | 3438 | static int iwl4965_rx_agg_start(struct iwl_priv *priv, |
3540 | const u8 *addr, int tid, u16 ssn) | 3439 | const u8 *addr, int tid, u16 ssn) |
3541 | { | 3440 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8809fe350b33..565d7dc31a71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -635,8 +635,8 @@ struct iwl_hw_params { | |||
635 | struct iwl_addsta_cmd; | 635 | struct iwl_addsta_cmd; |
636 | extern int iwl_send_add_sta(struct iwl_priv *priv, | 636 | extern int iwl_send_add_sta(struct iwl_priv *priv, |
637 | struct iwl_addsta_cmd *sta, u8 flags); | 637 | struct iwl_addsta_cmd *sta, u8 flags); |
638 | extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | 638 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, |
639 | int is_ap, u8 flags, void *ht_data); | 639 | u8 flags, struct ieee80211_ht_info *ht_info); |
640 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, | 640 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, |
641 | struct ieee80211_hdr *header); | 641 | struct ieee80211_hdr *header); |
642 | extern int iwl4965_power_init_handle(struct iwl_priv *priv); | 642 | extern int iwl4965_power_init_handle(struct iwl_priv *priv); |
@@ -731,8 +731,6 @@ extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); | |||
731 | extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | 731 | extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, |
732 | struct iwl_tx_queue *txq, | 732 | struct iwl_tx_queue *txq, |
733 | u16 byte_cnt); | 733 | u16 byte_cnt); |
734 | extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, | ||
735 | int is_ap); | ||
736 | extern int iwl4965_alive_notify(struct iwl_priv *priv); | 734 | extern int iwl4965_alive_notify(struct iwl_priv *priv); |
737 | extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); | 735 | extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); |
738 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); | 736 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); |
@@ -746,8 +744,6 @@ extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, | |||
746 | enum ieee80211_band band); | 744 | enum ieee80211_band band); |
747 | void iwl4965_set_rxon_ht(struct iwl_priv *priv, | 745 | void iwl4965_set_rxon_ht(struct iwl_priv *priv, |
748 | struct iwl_ht_info *ht_info); | 746 | struct iwl_ht_info *ht_info); |
749 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
750 | struct ieee80211_ht_info *sta_ht_inf); | ||
751 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 747 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
752 | enum ieee80211_ampdu_mlme_action action, | 748 | enum ieee80211_ampdu_mlme_action action, |
753 | const u8 *addr, u16 tid, u16 *ssn); | 749 | const u8 *addr, u16 tid, u16 *ssn); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index f2267047d102..c8e468fb3caa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -117,6 +117,130 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
117 | } | 117 | } |
118 | EXPORT_SYMBOL(iwl_send_add_sta); | 118 | EXPORT_SYMBOL(iwl_send_add_sta); |
119 | 119 | ||
120 | #ifdef CONFIG_IWL4965_HT | ||
121 | |||
122 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
123 | struct ieee80211_ht_info *sta_ht_inf) | ||
124 | { | ||
125 | __le32 sta_flags; | ||
126 | u8 mimo_ps_mode; | ||
127 | |||
128 | if (!sta_ht_inf || !sta_ht_inf->ht_supported) | ||
129 | goto done; | ||
130 | |||
131 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2; | ||
132 | |||
133 | sta_flags = priv->stations[index].sta.station_flags; | ||
134 | |||
135 | sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); | ||
136 | |||
137 | switch (mimo_ps_mode) { | ||
138 | case WLAN_HT_CAP_MIMO_PS_STATIC: | ||
139 | sta_flags |= STA_FLG_MIMO_DIS_MSK; | ||
140 | break; | ||
141 | case WLAN_HT_CAP_MIMO_PS_DYNAMIC: | ||
142 | sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; | ||
143 | break; | ||
144 | case WLAN_HT_CAP_MIMO_PS_DISABLED: | ||
145 | break; | ||
146 | default: | ||
147 | IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode); | ||
148 | break; | ||
149 | } | ||
150 | |||
151 | sta_flags |= cpu_to_le32( | ||
152 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); | ||
153 | |||
154 | sta_flags |= cpu_to_le32( | ||
155 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | ||
156 | |||
157 | if (iwl_is_fat_tx_allowed(priv, sta_ht_inf)) | ||
158 | sta_flags |= STA_FLG_FAT_EN_MSK; | ||
159 | else | ||
160 | sta_flags &= ~STA_FLG_FAT_EN_MSK; | ||
161 | |||
162 | priv->stations[index].sta.station_flags = sta_flags; | ||
163 | done: | ||
164 | return; | ||
165 | } | ||
166 | #else | ||
167 | static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
168 | struct ieee80211_ht_info *sta_ht_info) | ||
169 | { | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | /** | ||
174 | * iwl_add_station_flags - Add station to tables in driver and device | ||
175 | */ | ||
176 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | ||
177 | u8 flags, struct ieee80211_ht_info *ht_info) | ||
178 | { | ||
179 | int i; | ||
180 | int index = IWL_INVALID_STATION; | ||
181 | struct iwl_station_entry *station; | ||
182 | unsigned long flags_spin; | ||
183 | DECLARE_MAC_BUF(mac); | ||
184 | |||
185 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | ||
186 | if (is_ap) | ||
187 | index = IWL_AP_ID; | ||
188 | else if (is_broadcast_ether_addr(addr)) | ||
189 | index = priv->hw_params.bcast_sta_id; | ||
190 | else | ||
191 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { | ||
192 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | ||
193 | addr)) { | ||
194 | index = i; | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | if (!priv->stations[i].used && | ||
199 | index == IWL_INVALID_STATION) | ||
200 | index = i; | ||
201 | } | ||
202 | |||
203 | |||
204 | /* These two conditions have the same outcome, but keep them separate | ||
205 | since they have different meanings */ | ||
206 | if (unlikely(index == IWL_INVALID_STATION)) { | ||
207 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
208 | return index; | ||
209 | } | ||
210 | |||
211 | if (priv->stations[index].used && | ||
212 | !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) { | ||
213 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
214 | return index; | ||
215 | } | ||
216 | |||
217 | |||
218 | IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); | ||
219 | station = &priv->stations[index]; | ||
220 | station->used = 1; | ||
221 | priv->num_stations++; | ||
222 | |||
223 | /* Set up the REPLY_ADD_STA command to send to device */ | ||
224 | memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); | ||
225 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | ||
226 | station->sta.mode = 0; | ||
227 | station->sta.sta.sta_id = index; | ||
228 | station->sta.station_flags = 0; | ||
229 | |||
230 | /* BCAST station and IBSS stations do not work in HT mode */ | ||
231 | if (index != priv->hw_params.bcast_sta_id && | ||
232 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) | ||
233 | iwl_set_ht_add_station(priv, index, ht_info); | ||
234 | |||
235 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
236 | |||
237 | /* Add station to device's station table */ | ||
238 | iwl_send_add_sta(priv, &station->sta, flags); | ||
239 | return index; | ||
240 | |||
241 | } | ||
242 | EXPORT_SYMBOL(iwl_add_station_flags); | ||
243 | |||
120 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | 244 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) |
121 | { | 245 | { |
122 | int i; | 246 | int i; |
@@ -470,3 +594,148 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, | |||
470 | } | 594 | } |
471 | EXPORT_SYMBOL(iwl_send_lq_cmd); | 595 | EXPORT_SYMBOL(iwl_send_lq_cmd); |
472 | 596 | ||
597 | /** | ||
598 | * iwl_sta_init_lq - Initialize a station's hardware rate table | ||
599 | * | ||
600 | * The uCode's station table contains a table of fallback rates | ||
601 | * for automatic fallback during transmission. | ||
602 | * | ||
603 | * NOTE: This sets up a default set of values. These will be replaced later | ||
604 | * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of | ||
605 | * rc80211_simple. | ||
606 | * | ||
607 | * NOTE: Run REPLY_ADD_STA command to set up station table entry, before | ||
608 | * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, | ||
609 | * which requires station table entry to exist). | ||
610 | */ | ||
611 | static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) | ||
612 | { | ||
613 | int i, r; | ||
614 | struct iwl_link_quality_cmd link_cmd = { | ||
615 | .reserved1 = 0, | ||
616 | }; | ||
617 | u16 rate_flags; | ||
618 | |||
619 | /* Set up the rate scaling to start at selected rate, fall back | ||
620 | * all the way down to 1M in IEEE order, and then spin on 1M */ | ||
621 | if (is_ap) | ||
622 | r = IWL_RATE_54M_INDEX; | ||
623 | else if (priv->band == IEEE80211_BAND_5GHZ) | ||
624 | r = IWL_RATE_6M_INDEX; | ||
625 | else | ||
626 | r = IWL_RATE_1M_INDEX; | ||
627 | |||
628 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { | ||
629 | rate_flags = 0; | ||
630 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | ||
631 | rate_flags |= RATE_MCS_CCK_MSK; | ||
632 | |||
633 | /* Use Tx antenna B only */ | ||
634 | rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/ | ||
635 | |||
636 | link_cmd.rs_table[i].rate_n_flags = | ||
637 | iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | ||
638 | r = iwl4965_get_prev_ieee_rate(r); | ||
639 | } | ||
640 | |||
641 | link_cmd.general_params.single_stream_ant_msk = 2; | ||
642 | link_cmd.general_params.dual_stream_ant_msk = 3; | ||
643 | link_cmd.agg_params.agg_dis_start_th = 3; | ||
644 | link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); | ||
645 | |||
646 | /* Update the rate scaling for control frame Tx to AP */ | ||
647 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; | ||
648 | |||
649 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, | ||
650 | sizeof(link_cmd), &link_cmd, NULL); | ||
651 | } | ||
652 | /** | ||
653 | * iwl_rxon_add_station - add station into station table. | ||
654 | * | ||
655 | * there is only one AP station with id= IWL_AP_ID | ||
656 | * NOTE: mutex must be held before calling this fnction | ||
657 | */ | ||
658 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | ||
659 | { | ||
660 | u8 sta_id; | ||
661 | |||
662 | /* Add station to device's station table */ | ||
663 | #ifdef CONFIG_IWL4965_HT | ||
664 | struct ieee80211_conf *conf = &priv->hw->conf; | ||
665 | struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; | ||
666 | |||
667 | if ((is_ap) && | ||
668 | (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && | ||
669 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) | ||
670 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | ||
671 | 0, cur_ht_config); | ||
672 | else | ||
673 | #endif /* CONFIG_IWL4965_HT */ | ||
674 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | ||
675 | 0, NULL); | ||
676 | |||
677 | /* Set up default rate scaling table in device's station table */ | ||
678 | iwl_sta_init_lq(priv, addr, is_ap); | ||
679 | |||
680 | return sta_id; | ||
681 | } | ||
682 | EXPORT_SYMBOL(iwl_rxon_add_station); | ||
683 | |||
684 | |||
685 | /** | ||
686 | * iwl_get_sta_id - Find station's index within station table | ||
687 | * | ||
688 | * If new IBSS station, create new entry in station table | ||
689 | */ | ||
690 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | ||
691 | { | ||
692 | int sta_id; | ||
693 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
694 | DECLARE_MAC_BUF(mac); | ||
695 | |||
696 | /* If this frame is broadcast or management, use broadcast station id */ | ||
697 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | ||
698 | is_multicast_ether_addr(hdr->addr1)) | ||
699 | return priv->hw_params.bcast_sta_id; | ||
700 | |||
701 | switch (priv->iw_mode) { | ||
702 | |||
703 | /* If we are a client station in a BSS network, use the special | ||
704 | * AP station entry (that's the only station we communicate with) */ | ||
705 | case IEEE80211_IF_TYPE_STA: | ||
706 | return IWL_AP_ID; | ||
707 | |||
708 | /* If we are an AP, then find the station, or use BCAST */ | ||
709 | case IEEE80211_IF_TYPE_AP: | ||
710 | sta_id = iwl_find_station(priv, hdr->addr1); | ||
711 | if (sta_id != IWL_INVALID_STATION) | ||
712 | return sta_id; | ||
713 | return priv->hw_params.bcast_sta_id; | ||
714 | |||
715 | /* If this frame is going out to an IBSS network, find the station, | ||
716 | * or create a new station table entry */ | ||
717 | case IEEE80211_IF_TYPE_IBSS: | ||
718 | sta_id = iwl_find_station(priv, hdr->addr1); | ||
719 | if (sta_id != IWL_INVALID_STATION) | ||
720 | return sta_id; | ||
721 | |||
722 | /* Create new station table entry */ | ||
723 | sta_id = iwl_add_station_flags(priv, hdr->addr1, | ||
724 | 0, CMD_ASYNC, NULL); | ||
725 | |||
726 | if (sta_id != IWL_INVALID_STATION) | ||
727 | return sta_id; | ||
728 | |||
729 | IWL_DEBUG_DROP("Station %s not in station map. " | ||
730 | "Defaulting to broadcast...\n", | ||
731 | print_mac(mac, hdr->addr1)); | ||
732 | iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | ||
733 | return priv->hw_params.bcast_sta_id; | ||
734 | |||
735 | default: | ||
736 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | ||
737 | return priv->hw_params.bcast_sta_id; | ||
738 | } | ||
739 | } | ||
740 | EXPORT_SYMBOL(iwl_get_sta_id); | ||
741 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 38b1b0a98845..ee2564307084 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -39,4 +39,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
39 | struct ieee80211_key_conf *key, u8 sta_id); | 39 | struct ieee80211_key_conf *key, u8 sta_id); |
40 | int iwl_remove_dynamic_key(struct iwl_priv *priv, | 40 | int iwl_remove_dynamic_key(struct iwl_priv *priv, |
41 | struct ieee80211_key_conf *key, u8 sta_id); | 41 | struct ieee80211_key_conf *key, u8 sta_id); |
42 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | ||
43 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | ||
42 | #endif /* __iwl_sta_h__ */ | 44 | #endif /* __iwl_sta_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index bb820f35d602..88032ccc0ab5 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -258,79 +258,6 @@ out: | |||
258 | } | 258 | } |
259 | #endif | 259 | #endif |
260 | 260 | ||
261 | /** | ||
262 | * iwl4965_add_station_flags - Add station to tables in driver and device | ||
263 | */ | ||
264 | u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | ||
265 | int is_ap, u8 flags, void *ht_data) | ||
266 | { | ||
267 | int i; | ||
268 | int index = IWL_INVALID_STATION; | ||
269 | struct iwl_station_entry *station; | ||
270 | unsigned long flags_spin; | ||
271 | DECLARE_MAC_BUF(mac); | ||
272 | |||
273 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | ||
274 | if (is_ap) | ||
275 | index = IWL_AP_ID; | ||
276 | else if (is_broadcast_ether_addr(addr)) | ||
277 | index = priv->hw_params.bcast_sta_id; | ||
278 | else | ||
279 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { | ||
280 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | ||
281 | addr)) { | ||
282 | index = i; | ||
283 | break; | ||
284 | } | ||
285 | |||
286 | if (!priv->stations[i].used && | ||
287 | index == IWL_INVALID_STATION) | ||
288 | index = i; | ||
289 | } | ||
290 | |||
291 | |||
292 | /* These two conditions have the same outcome, but keep them separate | ||
293 | since they have different meanings */ | ||
294 | if (unlikely(index == IWL_INVALID_STATION)) { | ||
295 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
296 | return index; | ||
297 | } | ||
298 | |||
299 | if (priv->stations[index].used && | ||
300 | !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) { | ||
301 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
302 | return index; | ||
303 | } | ||
304 | |||
305 | |||
306 | IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); | ||
307 | station = &priv->stations[index]; | ||
308 | station->used = 1; | ||
309 | priv->num_stations++; | ||
310 | |||
311 | /* Set up the REPLY_ADD_STA command to send to device */ | ||
312 | memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); | ||
313 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | ||
314 | station->sta.mode = 0; | ||
315 | station->sta.sta.sta_id = index; | ||
316 | station->sta.station_flags = 0; | ||
317 | |||
318 | #ifdef CONFIG_IWL4965_HT | ||
319 | /* BCAST station and IBSS stations do not work in HT mode */ | ||
320 | if (index != priv->hw_params.bcast_sta_id && | ||
321 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) | ||
322 | iwl4965_set_ht_add_station(priv, index, | ||
323 | (struct ieee80211_ht_info *) ht_data); | ||
324 | #endif /*CONFIG_IWL4965_HT*/ | ||
325 | |||
326 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
327 | |||
328 | /* Add station to device's station table */ | ||
329 | iwl_send_add_sta(priv, &station->sta, flags); | ||
330 | return index; | ||
331 | |||
332 | } | ||
333 | |||
334 | 261 | ||
335 | 262 | ||
336 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | 263 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ |
@@ -434,38 +361,6 @@ static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | |||
434 | } | 361 | } |
435 | 362 | ||
436 | /** | 363 | /** |
437 | * iwl4965_rxon_add_station - add station into station table. | ||
438 | * | ||
439 | * there is only one AP station with id= IWL_AP_ID | ||
440 | * NOTE: mutex must be held before calling this fnction | ||
441 | */ | ||
442 | static int iwl4965_rxon_add_station(struct iwl_priv *priv, | ||
443 | const u8 *addr, int is_ap) | ||
444 | { | ||
445 | u8 sta_id; | ||
446 | |||
447 | /* Add station to device's station table */ | ||
448 | #ifdef CONFIG_IWL4965_HT | ||
449 | struct ieee80211_conf *conf = &priv->hw->conf; | ||
450 | struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; | ||
451 | |||
452 | if ((is_ap) && | ||
453 | (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && | ||
454 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) | ||
455 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, | ||
456 | 0, cur_ht_config); | ||
457 | else | ||
458 | #endif /* CONFIG_IWL4965_HT */ | ||
459 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, | ||
460 | 0, NULL); | ||
461 | |||
462 | /* Set up default rate scaling table in device's station table */ | ||
463 | iwl4965_add_station(priv, addr, is_ap); | ||
464 | |||
465 | return sta_id; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * iwl4965_check_rxon_cmd - validate RXON structure is valid | 364 | * iwl4965_check_rxon_cmd - validate RXON structure is valid |
470 | * | 365 | * |
471 | * NOTE: This is really only useful during development and can eventually | 366 | * NOTE: This is really only useful during development and can eventually |
@@ -691,7 +586,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
691 | } | 586 | } |
692 | 587 | ||
693 | /* Add the broadcast address so we can send broadcast frames */ | 588 | /* Add the broadcast address so we can send broadcast frames */ |
694 | if (iwl4965_rxon_add_station(priv, iwl_bcast_addr, 0) == | 589 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
695 | IWL_INVALID_STATION) { | 590 | IWL_INVALID_STATION) { |
696 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); | 591 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); |
697 | return -EIO; | 592 | return -EIO; |
@@ -701,7 +596,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
701 | * add the IWL_AP_ID to the station rate table */ | 596 | * add the IWL_AP_ID to the station rate table */ |
702 | if (iwl_is_associated(priv) && | 597 | if (iwl_is_associated(priv) && |
703 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { | 598 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { |
704 | if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) | 599 | if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) |
705 | == IWL_INVALID_STATION) { | 600 | == IWL_INVALID_STATION) { |
706 | IWL_ERROR("Error adding AP address for transmit.\n"); | 601 | IWL_ERROR("Error adding AP address for transmit.\n"); |
707 | return -EIO; | 602 | return -EIO; |
@@ -1702,63 +1597,6 @@ static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len) | |||
1702 | priv->tx_stats[idx].cnt++; | 1597 | priv->tx_stats[idx].cnt++; |
1703 | priv->tx_stats[idx].bytes += len; | 1598 | priv->tx_stats[idx].bytes += len; |
1704 | } | 1599 | } |
1705 | /** | ||
1706 | * iwl4965_get_sta_id - Find station's index within station table | ||
1707 | * | ||
1708 | * If new IBSS station, create new entry in station table | ||
1709 | */ | ||
1710 | static int iwl4965_get_sta_id(struct iwl_priv *priv, | ||
1711 | struct ieee80211_hdr *hdr) | ||
1712 | { | ||
1713 | int sta_id; | ||
1714 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
1715 | DECLARE_MAC_BUF(mac); | ||
1716 | |||
1717 | /* If this frame is broadcast or management, use broadcast station id */ | ||
1718 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | ||
1719 | is_multicast_ether_addr(hdr->addr1)) | ||
1720 | return priv->hw_params.bcast_sta_id; | ||
1721 | |||
1722 | switch (priv->iw_mode) { | ||
1723 | |||
1724 | /* If we are a client station in a BSS network, use the special | ||
1725 | * AP station entry (that's the only station we communicate with) */ | ||
1726 | case IEEE80211_IF_TYPE_STA: | ||
1727 | return IWL_AP_ID; | ||
1728 | |||
1729 | /* If we are an AP, then find the station, or use BCAST */ | ||
1730 | case IEEE80211_IF_TYPE_AP: | ||
1731 | sta_id = iwl_find_station(priv, hdr->addr1); | ||
1732 | if (sta_id != IWL_INVALID_STATION) | ||
1733 | return sta_id; | ||
1734 | return priv->hw_params.bcast_sta_id; | ||
1735 | |||
1736 | /* If this frame is going out to an IBSS network, find the station, | ||
1737 | * or create a new station table entry */ | ||
1738 | case IEEE80211_IF_TYPE_IBSS: | ||
1739 | sta_id = iwl_find_station(priv, hdr->addr1); | ||
1740 | if (sta_id != IWL_INVALID_STATION) | ||
1741 | return sta_id; | ||
1742 | |||
1743 | /* Create new station table entry */ | ||
1744 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, | ||
1745 | 0, CMD_ASYNC, NULL); | ||
1746 | |||
1747 | if (sta_id != IWL_INVALID_STATION) | ||
1748 | return sta_id; | ||
1749 | |||
1750 | IWL_DEBUG_DROP("Station %s not in station map. " | ||
1751 | "Defaulting to broadcast...\n", | ||
1752 | print_mac(mac, hdr->addr1)); | ||
1753 | iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | ||
1754 | return priv->hw_params.bcast_sta_id; | ||
1755 | |||
1756 | default: | ||
1757 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | ||
1758 | return priv->hw_params.bcast_sta_id; | ||
1759 | } | ||
1760 | } | ||
1761 | |||
1762 | /* | 1600 | /* |
1763 | * start REPLY_TX command process | 1601 | * start REPLY_TX command process |
1764 | */ | 1602 | */ |
@@ -1829,7 +1667,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
1829 | hdr_len = ieee80211_get_hdrlen(fc); | 1667 | hdr_len = ieee80211_get_hdrlen(fc); |
1830 | 1668 | ||
1831 | /* Find (or create) index into station table for destination station */ | 1669 | /* Find (or create) index into station table for destination station */ |
1832 | sta_id = iwl4965_get_sta_id(priv, hdr); | 1670 | sta_id = iwl_get_sta_id(priv, hdr); |
1833 | if (sta_id == IWL_INVALID_STATION) { | 1671 | if (sta_id == IWL_INVALID_STATION) { |
1834 | DECLARE_MAC_BUF(mac); | 1672 | DECLARE_MAC_BUF(mac); |
1835 | 1673 | ||
@@ -3585,7 +3423,7 @@ static void iwl4965_error_recovery(struct iwl_priv *priv) | |||
3585 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3423 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3586 | iwl4965_commit_rxon(priv); | 3424 | iwl4965_commit_rxon(priv); |
3587 | 3425 | ||
3588 | iwl4965_rxon_add_station(priv, priv->bssid, 1); | 3426 | iwl_rxon_add_station(priv, priv->bssid, 1); |
3589 | 3427 | ||
3590 | spin_lock_irqsave(&priv->lock, flags); | 3428 | spin_lock_irqsave(&priv->lock, flags); |
3591 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); | 3429 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); |
@@ -4911,8 +4749,8 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
4911 | /* clear out the station table */ | 4749 | /* clear out the station table */ |
4912 | iwlcore_clear_stations_table(priv); | 4750 | iwlcore_clear_stations_table(priv); |
4913 | 4751 | ||
4914 | iwl4965_rxon_add_station(priv, iwl_bcast_addr, 0); | 4752 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); |
4915 | iwl4965_rxon_add_station(priv, priv->bssid, 0); | 4753 | iwl_rxon_add_station(priv, priv->bssid, 0); |
4916 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); | 4754 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); |
4917 | iwl4965_send_beacon_cmd(priv); | 4755 | iwl4965_send_beacon_cmd(priv); |
4918 | 4756 | ||
@@ -5323,7 +5161,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
5323 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 5161 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
5324 | iwl4965_commit_rxon(priv); | 5162 | iwl4965_commit_rxon(priv); |
5325 | iwl4965_activate_qos(priv, 1); | 5163 | iwl4965_activate_qos(priv, 1); |
5326 | iwl4965_rxon_add_station(priv, iwl_bcast_addr, 0); | 5164 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); |
5327 | } | 5165 | } |
5328 | iwl4965_send_beacon_cmd(priv); | 5166 | iwl4965_send_beacon_cmd(priv); |
5329 | 5167 | ||
@@ -5412,7 +5250,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
5412 | else { | 5250 | else { |
5413 | rc = iwl4965_commit_rxon(priv); | 5251 | rc = iwl4965_commit_rxon(priv); |
5414 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) | 5252 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) |
5415 | iwl4965_rxon_add_station( | 5253 | iwl_rxon_add_station( |
5416 | priv, priv->active_rxon.bssid_addr, 1); | 5254 | priv, priv->active_rxon.bssid_addr, 1); |
5417 | } | 5255 | } |
5418 | 5256 | ||