aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c183
1 files changed, 76 insertions, 107 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 3e5bffb6034f..0f16c7d518f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -197,6 +197,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) 197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
198{ 198{
199 unsigned long flags; 199 unsigned long flags;
200 struct iwl_addsta_cmd sta_cmd;
200 201
201 spin_lock_irqsave(&priv->sta_lock, flags); 202 spin_lock_irqsave(&priv->sta_lock, flags);
202 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 203 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
@@ -205,11 +206,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
205 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 206 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
206 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 207 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
207 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 208 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
209 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
208 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
209 211
210 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
211 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); 213 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
212 return 0;
213} 214}
214 215
215static int iwl3945_set_dynamic_key(struct iwl_priv *priv, 216static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
@@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
474 u8 unicast; 475 u8 unicast;
475 u8 sta_id; 476 u8 sta_id;
476 u8 tid = 0; 477 u8 tid = 0;
477 u16 seq_number = 0;
478 __le16 fc; 478 __le16 fc;
479 u8 wait_write_ptr = 0; 479 u8 wait_write_ptr = 0;
480 u8 *qc = NULL;
481 unsigned long flags; 480 unsigned long flags;
482 481
483 spin_lock_irqsave(&priv->lock, flags); 482 spin_lock_irqsave(&priv->lock, flags);
@@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
510 hdr_len = ieee80211_hdrlen(fc); 509 hdr_len = ieee80211_hdrlen(fc);
511 510
512 /* Find index into station table for destination station */ 511 /* Find index into station table for destination station */
513 if (!info->control.sta) 512 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
514 sta_id = priv->hw_params.bcast_sta_id;
515 else
516 sta_id = iwl_sta_id(info->control.sta);
517 if (sta_id == IWL_INVALID_STATION) { 513 if (sta_id == IWL_INVALID_STATION) {
518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 514 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
519 hdr->addr1); 515 hdr->addr1);
@@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
523 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); 519 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
524 520
525 if (ieee80211_is_data_qos(fc)) { 521 if (ieee80211_is_data_qos(fc)) {
526 qc = ieee80211_get_qos_ctl(hdr); 522 u8 *qc = ieee80211_get_qos_ctl(hdr);
527 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 523 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
528 if (unlikely(tid >= MAX_TID_COUNT)) 524 if (unlikely(tid >= MAX_TID_COUNT))
529 goto drop; 525 goto drop;
530 seq_number = priv->stations[sta_id].tid[tid].seq_number &
531 IEEE80211_SCTL_SEQ;
532 hdr->seq_ctrl = cpu_to_le16(seq_number) |
533 (hdr->seq_ctrl &
534 cpu_to_le16(IEEE80211_SCTL_FRAG));
535 seq_number += 0x10;
536 } 526 }
537 527
538 /* Descriptor for chosen Tx queue */ 528 /* Descriptor for chosen Tx queue */
@@ -548,7 +538,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
548 538
549 /* Set up driver data for this TFD */ 539 /* Set up driver data for this TFD */
550 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 540 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
551 txq->txb[q->write_ptr].skb[0] = skb; 541 txq->txb[q->write_ptr].skb = skb;
552 542
553 /* Init first empty entry in queue's array of Tx/cmd buffers */ 543 /* Init first empty entry in queue's array of Tx/cmd buffers */
554 out_cmd = txq->cmd[idx]; 544 out_cmd = txq->cmd[idx];
@@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
591 581
592 if (!ieee80211_has_morefrags(hdr->frame_control)) { 582 if (!ieee80211_has_morefrags(hdr->frame_control)) {
593 txq->need_update = 1; 583 txq->need_update = 1;
594 if (qc)
595 priv->stations[sta_id].tid[tid].seq_number = seq_number;
596 } else { 584 } else {
597 wait_write_ptr = 1; 585 wait_write_ptr = 1;
598 txq->need_update = 0; 586 txq->need_update = 0;
@@ -631,8 +619,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
631 len, PCI_DMA_TODEVICE); 619 len, PCI_DMA_TODEVICE);
632 /* we do not map meta data ... so we can safely access address to 620 /* we do not map meta data ... so we can safely access address to
633 * provide to unmap command*/ 621 * provide to unmap command*/
634 pci_unmap_addr_set(out_meta, mapping, txcmd_phys); 622 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
635 pci_unmap_len_set(out_meta, len, len); 623 dma_unmap_len_set(out_meta, len, len);
636 624
637 /* Add buffer containing Tx command and MAC(!) header to TFD's 625 /* Add buffer containing Tx command and MAC(!) header to TFD's
638 * first entry */ 626 * first entry */
@@ -677,55 +665,6 @@ drop:
677 return -1; 665 return -1;
678} 666}
679 667
680#define BEACON_TIME_MASK_LOW 0x00FFFFFF
681#define BEACON_TIME_MASK_HIGH 0xFF000000
682#define TIME_UNIT 1024
683
684/*
685 * extended beacon time format
686 * time in usec will be changed into a 32-bit value in 8:24 format
687 * the high 1 byte is the beacon counts
688 * the lower 3 bytes is the time in usec within one beacon interval
689 */
690
691static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval)
692{
693 u32 quot;
694 u32 rem;
695 u32 interval = beacon_interval * 1024;
696
697 if (!interval || !usec)
698 return 0;
699
700 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
701 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
702
703 return (quot << 24) + rem;
704}
705
706/* base is usually what we get from ucode with each received frame,
707 * the same as HW timer counter counting down
708 */
709
710static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
711{
712 u32 base_low = base & BEACON_TIME_MASK_LOW;
713 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
714 u32 interval = beacon_interval * TIME_UNIT;
715 u32 res = (base & BEACON_TIME_MASK_HIGH) +
716 (addon & BEACON_TIME_MASK_HIGH);
717
718 if (base_low > addon_low)
719 res += base_low - addon_low;
720 else if (base_low < addon_low) {
721 res += interval + base_low - addon_low;
722 res += (1 << 24);
723 } else
724 res += (1 << 24);
725
726 return cpu_to_le32(res);
727}
728
729static int iwl3945_get_measurement(struct iwl_priv *priv, 668static int iwl3945_get_measurement(struct iwl_priv *priv,
730 struct ieee80211_measurement_params *params, 669 struct ieee80211_measurement_params *params,
731 u8 type) 670 u8 type)
@@ -743,8 +682,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
743 int duration = le16_to_cpu(params->duration); 682 int duration = le16_to_cpu(params->duration);
744 683
745 if (iwl_is_associated(priv)) 684 if (iwl_is_associated(priv))
746 add_time = 685 add_time = iwl_usecs_to_beacons(priv,
747 iwl3945_usecs_to_beacons(
748 le64_to_cpu(params->start_time) - priv->_3945.last_tsf, 686 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
749 le16_to_cpu(priv->rxon_timing.beacon_interval)); 687 le16_to_cpu(priv->rxon_timing.beacon_interval));
750 688
@@ -759,8 +697,8 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
759 697
760 if (iwl_is_associated(priv)) 698 if (iwl_is_associated(priv))
761 spectrum.start_time = 699 spectrum.start_time =
762 iwl3945_add_beacon_time(priv->_3945.last_beacon_time, 700 iwl_add_beacon_time(priv,
763 add_time, 701 priv->_3945.last_beacon_time, add_time,
764 le16_to_cpu(priv->rxon_timing.beacon_interval)); 702 le16_to_cpu(priv->rxon_timing.beacon_interval));
765 else 703 else
766 spectrum.start_time = 0; 704 spectrum.start_time = 0;
@@ -1844,6 +1782,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1844#endif 1782#endif
1845} 1783}
1846 1784
1785static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv,
1786 struct ieee80211_vif *vif,
1787 enum ieee80211_band band,
1788 struct iwl3945_scan_channel *scan_ch)
1789{
1790 const struct ieee80211_supported_band *sband;
1791 u16 passive_dwell = 0;
1792 u16 active_dwell = 0;
1793 int added = 0;
1794 u8 channel = 0;
1795
1796 sband = iwl_get_hw_mode(priv, band);
1797 if (!sband) {
1798 IWL_ERR(priv, "invalid band\n");
1799 return added;
1800 }
1801
1802 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
1803 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1804
1805 if (passive_dwell <= active_dwell)
1806 passive_dwell = active_dwell + 1;
1807
1808
1809 channel = iwl_get_single_channel_number(priv, band);
1810
1811 if (channel) {
1812 scan_ch->channel = channel;
1813 scan_ch->type = 0; /* passive */
1814 scan_ch->active_dwell = cpu_to_le16(active_dwell);
1815 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
1816 /* Set txpower levels to defaults */
1817 scan_ch->tpc.dsp_atten = 110;
1818 if (band == IEEE80211_BAND_5GHZ)
1819 scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
1820 else
1821 scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
1822 added++;
1823 } else
1824 IWL_ERR(priv, "no valid channel found\n");
1825 return added;
1826}
1827
1847static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, 1828static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1848 enum ieee80211_band band, 1829 enum ieee80211_band band,
1849 u8 is_active, u8 n_probes, 1830 u8 is_active, u8 n_probes,
@@ -2979,22 +2960,31 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2979 scan->tx_cmd.len = cpu_to_le16( 2960 scan->tx_cmd.len = cpu_to_le16(
2980 iwl_fill_probe_req(priv, 2961 iwl_fill_probe_req(priv,
2981 (struct ieee80211_mgmt *)scan->data, 2962 (struct ieee80211_mgmt *)scan->data,
2963 vif->addr,
2982 priv->scan_request->ie, 2964 priv->scan_request->ie,
2983 priv->scan_request->ie_len, 2965 priv->scan_request->ie_len,
2984 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2966 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2985 } else { 2967 } else {
2968 /* use bcast addr, will not be transmitted but must be valid */
2986 scan->tx_cmd.len = cpu_to_le16( 2969 scan->tx_cmd.len = cpu_to_le16(
2987 iwl_fill_probe_req(priv, 2970 iwl_fill_probe_req(priv,
2988 (struct ieee80211_mgmt *)scan->data, 2971 (struct ieee80211_mgmt *)scan->data,
2989 NULL, 0, 2972 iwl_bcast_addr, NULL, 0,
2990 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2973 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2991 } 2974 }
2992 /* select Rx antennas */ 2975 /* select Rx antennas */
2993 scan->flags |= iwl3945_get_antenna_flags(priv); 2976 scan->flags |= iwl3945_get_antenna_flags(priv);
2994 2977
2995 scan->channel_count = 2978 if (priv->is_internal_short_scan) {
2996 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, 2979 scan->channel_count =
2997 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); 2980 iwl3945_get_single_channel_for_scan(priv, vif, band,
2981 (void *)&scan->data[le16_to_cpu(
2982 scan->tx_cmd.len)]);
2983 } else {
2984 scan->channel_count =
2985 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
2986 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
2987 }
2998 2988
2999 if (scan->channel_count == 0) { 2989 if (scan->channel_count == 0) {
3000 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 2990 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
@@ -3108,19 +3098,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3108 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3098 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3109 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3099 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3110 3100
3111 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3101 if (vif->bss_conf.use_short_preamble)
3112 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3102 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3113 else 3103 else
3114 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3104 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3115 3105
3116 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3106 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3117 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3107 if (vif->bss_conf.use_short_slot)
3118 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3108 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3119 else 3109 else
3120 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3110 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3121
3122 if (vif->type == NL80211_IFTYPE_ADHOC)
3123 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3124 } 3111 }
3125 3112
3126 iwlcore_commit_rxon(priv); 3113 iwlcore_commit_rxon(priv);
@@ -3284,8 +3271,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3284 3271
3285 priv->staging_rxon.assoc_id = 0; 3272 priv->staging_rxon.assoc_id = 0;
3286 3273
3287 if (vif->bss_conf.assoc_capability & 3274 if (vif->bss_conf.use_short_preamble)
3288 WLAN_CAPABILITY_SHORT_PREAMBLE)
3289 priv->staging_rxon.flags |= 3275 priv->staging_rxon.flags |=
3290 RXON_FLG_SHORT_PREAMBLE_MSK; 3276 RXON_FLG_SHORT_PREAMBLE_MSK;
3291 else 3277 else
@@ -3293,17 +3279,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3293 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3279 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3294 3280
3295 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3281 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3296 if (vif->bss_conf.assoc_capability & 3282 if (vif->bss_conf.use_short_slot)
3297 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3298 priv->staging_rxon.flags |= 3283 priv->staging_rxon.flags |=
3299 RXON_FLG_SHORT_SLOT_MSK; 3284 RXON_FLG_SHORT_SLOT_MSK;
3300 else 3285 else
3301 priv->staging_rxon.flags &= 3286 priv->staging_rxon.flags &=
3302 ~RXON_FLG_SHORT_SLOT_MSK; 3287 ~RXON_FLG_SHORT_SLOT_MSK;
3303
3304 if (vif->type == NL80211_IFTYPE_ADHOC)
3305 priv->staging_rxon.flags &=
3306 ~RXON_FLG_SHORT_SLOT_MSK;
3307 } 3288 }
3308 /* restore RXON assoc */ 3289 /* restore RXON assoc */
3309 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3290 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -3336,17 +3317,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3336 static_key = !iwl_is_associated(priv); 3317 static_key = !iwl_is_associated(priv);
3337 3318
3338 if (!static_key) { 3319 if (!static_key) {
3339 if (!sta) { 3320 sta_id = iwl_sta_id_or_broadcast(priv, sta);
3340 sta_id = priv->hw_params.bcast_sta_id; 3321 if (sta_id == IWL_INVALID_STATION)
3341 } else { 3322 return -EINVAL;
3342 sta_id = iwl_sta_id(sta);
3343 if (sta_id == IWL_INVALID_STATION) {
3344 IWL_DEBUG_MAC80211(priv,
3345 "leave - %pM not in station map.\n",
3346 sta->addr);
3347 return -EINVAL;
3348 }
3349 }
3350 } 3323 }
3351 3324
3352 mutex_lock(&priv->mutex); 3325 mutex_lock(&priv->mutex);
@@ -3973,9 +3946,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3973 priv->pci_dev = pdev; 3946 priv->pci_dev = pdev;
3974 priv->inta_mask = CSR_INI_SET_MASK; 3947 priv->inta_mask = CSR_INI_SET_MASK;
3975 3948
3976#ifdef CONFIG_IWLWIFI_DEBUG
3977 atomic_set(&priv->restrict_refcnt, 0);
3978#endif
3979 if (iwl_alloc_traffic_mem(priv)) 3949 if (iwl_alloc_traffic_mem(priv))
3980 IWL_ERR(priv, "Not enough memory to generate traffic log\n"); 3950 IWL_ERR(priv, "Not enough memory to generate traffic log\n");
3981 3951
@@ -4044,9 +4014,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4044 } 4014 }
4045 /* MAC Address location in EEPROM same for 3945/4965 */ 4015 /* MAC Address location in EEPROM same for 3945/4965 */
4046 eeprom = (struct iwl3945_eeprom *)priv->eeprom; 4016 eeprom = (struct iwl3945_eeprom *)priv->eeprom;
4047 memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN); 4017 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address);
4048 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr); 4018 SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address);
4049 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
4050 4019
4051 /*********************** 4020 /***********************
4052 * 5. Setup HW Constants 4021 * 5. Setup HW Constants