aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath9k/main.c2
-rw-r--r--drivers/net/wireless/b43/b43.h7
-rw-r--r--drivers/net/wireless/b43/main.c119
-rw-r--r--drivers/net/wireless/b43/phy_g.c1
-rw-r--r--drivers/net/wireless/b43legacy/phy.c32
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c163
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c9
-rw-r--r--drivers/net/wireless/libertas/cmd.c64
-rw-r--r--drivers/net/wireless/libertas/cmd.h6
-rw-r--r--drivers/net/wireless/libertas/defs.h9
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h24
-rw-r--r--drivers/net/wireless/libertas/main.c20
-rw-r--r--drivers/net/wireless/libertas/wext.c31
-rw-r--r--drivers/net/wireless/p54/p54.h9
-rw-r--r--drivers/net/wireless/p54/p54common.c256
-rw-r--r--drivers/net/wireless/p54/p54common.h23
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig75
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c50
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c20
-rw-r--r--include/linux/ieee80211.h30
-rw-r--r--include/net/mac80211.h2
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/ht.c992
-rw-r--r--net/mac80211/ieee80211_i.h79
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/main.c388
-rw-r--r--net/mac80211/mesh_hwmp.c8
-rw-r--r--net/mac80211/mesh_plink.c6
-rw-r--r--net/mac80211/mlme.c3121
-rw-r--r--net/mac80211/rx.c90
-rw-r--r--net/mac80211/scan.c933
-rw-r--r--net/mac80211/spectmgmt.c86
-rw-r--r--net/mac80211/util.c184
51 files changed, 3855 insertions, 3328 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 245b7308a9ad..57d7cc87cb0f 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -224,7 +224,7 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
224 224
225 ht_info->ht_supported = 1; 225 ht_info->ht_supported = 1;
226 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH 226 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
227 |(u16)IEEE80211_HT_CAP_MIMO_PS 227 |(u16)IEEE80211_HT_CAP_SM_PS
228 |(u16)IEEE80211_HT_CAP_SGI_40 228 |(u16)IEEE80211_HT_CAP_SGI_40
229 |(u16)IEEE80211_HT_CAP_DSSSCCK40; 229 |(u16)IEEE80211_HT_CAP_DSSSCCK40;
230 230
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f9c8161671d9..07d2825458ab 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -585,8 +585,6 @@ enum {
585struct b43_qos_params { 585struct b43_qos_params {
586 /* The QOS parameters */ 586 /* The QOS parameters */
587 struct ieee80211_tx_queue_params p; 587 struct ieee80211_tx_queue_params p;
588 /* Does this need to get uploaded to hardware? */
589 bool need_hw_update;
590}; 588};
591 589
592struct b43_wldev; 590struct b43_wldev;
@@ -648,11 +646,8 @@ struct b43_wl {
648 bool beacon_templates_virgin; /* Never wrote the templates? */ 646 bool beacon_templates_virgin; /* Never wrote the templates? */
649 struct work_struct beacon_update_trigger; 647 struct work_struct beacon_update_trigger;
650 648
651 /* The current QOS parameters for the 4 queues. 649 /* The current QOS parameters for the 4 queues. */
652 * This is protected by the irq_lock. */
653 struct b43_qos_params qos_params[4]; 650 struct b43_qos_params qos_params[4];
654 /* Workqueue for updating QOS parameters in hardware. */
655 struct work_struct qos_update_work;
656 651
657 /* Work for adjustment of the transmission power. 652 /* Work for adjustment of the transmission power.
658 * This is scheduled when we determine that the actual TX output 653 * This is scheduled when we determine that the actual TX output
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c836beceb10d..d4a356b11636 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3059,36 +3059,31 @@ static void b43_qos_params_upload(struct b43_wldev *dev,
3059 } 3059 }
3060} 3060}
3061 3061
3062/* Update the QOS parameters in hardware. */ 3062/* Mapping of mac80211 queue numbers to b43 QoS SHM offsets. */
3063static void b43_qos_update(struct b43_wldev *dev) 3063static const u16 b43_qos_shm_offsets[] = {
3064 /* [mac80211-queue-nr] = SHM_OFFSET, */
3065 [0] = B43_QOS_VOICE,
3066 [1] = B43_QOS_VIDEO,
3067 [2] = B43_QOS_BESTEFFORT,
3068 [3] = B43_QOS_BACKGROUND,
3069};
3070
3071/* Update all QOS parameters in hardware. */
3072static void b43_qos_upload_all(struct b43_wldev *dev)
3064{ 3073{
3065 struct b43_wl *wl = dev->wl; 3074 struct b43_wl *wl = dev->wl;
3066 struct b43_qos_params *params; 3075 struct b43_qos_params *params;
3067 unsigned long flags;
3068 unsigned int i; 3076 unsigned int i;
3069 3077
3070 /* Mapping of mac80211 queues to b43 SHM offsets. */ 3078 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3071 static const u16 qos_shm_offsets[] = { 3079 ARRAY_SIZE(wl->qos_params));
3072 [0] = B43_QOS_VOICE,
3073 [1] = B43_QOS_VIDEO,
3074 [2] = B43_QOS_BESTEFFORT,
3075 [3] = B43_QOS_BACKGROUND,
3076 };
3077 BUILD_BUG_ON(ARRAY_SIZE(qos_shm_offsets) != ARRAY_SIZE(wl->qos_params));
3078 3080
3079 b43_mac_suspend(dev); 3081 b43_mac_suspend(dev);
3080 spin_lock_irqsave(&wl->irq_lock, flags);
3081
3082 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) { 3082 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
3083 params = &(wl->qos_params[i]); 3083 params = &(wl->qos_params[i]);
3084 if (params->need_hw_update) { 3084 b43_qos_params_upload(dev, &(params->p),
3085 b43_qos_params_upload(dev, &(params->p), 3085 b43_qos_shm_offsets[i]);
3086 qos_shm_offsets[i]);
3087 params->need_hw_update = 0;
3088 }
3089 } 3086 }
3090
3091 spin_unlock_irqrestore(&wl->irq_lock, flags);
3092 b43_mac_enable(dev); 3087 b43_mac_enable(dev);
3093} 3088}
3094 3089
@@ -3097,25 +3092,50 @@ static void b43_qos_clear(struct b43_wl *wl)
3097 struct b43_qos_params *params; 3092 struct b43_qos_params *params;
3098 unsigned int i; 3093 unsigned int i;
3099 3094
3095 /* Initialize QoS parameters to sane defaults. */
3096
3097 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3098 ARRAY_SIZE(wl->qos_params));
3099
3100 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) { 3100 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
3101 params = &(wl->qos_params[i]); 3101 params = &(wl->qos_params[i]);
3102 3102
3103 memset(&(params->p), 0, sizeof(params->p)); 3103 switch (b43_qos_shm_offsets[i]) {
3104 params->p.aifs = -1; 3104 case B43_QOS_VOICE:
3105 params->need_hw_update = 1; 3105 params->p.txop = 0;
3106 params->p.aifs = 2;
3107 params->p.cw_min = 0x0001;
3108 params->p.cw_max = 0x0001;
3109 break;
3110 case B43_QOS_VIDEO:
3111 params->p.txop = 0;
3112 params->p.aifs = 2;
3113 params->p.cw_min = 0x0001;
3114 params->p.cw_max = 0x0001;
3115 break;
3116 case B43_QOS_BESTEFFORT:
3117 params->p.txop = 0;
3118 params->p.aifs = 3;
3119 params->p.cw_min = 0x0001;
3120 params->p.cw_max = 0x03FF;
3121 break;
3122 case B43_QOS_BACKGROUND:
3123 params->p.txop = 0;
3124 params->p.aifs = 7;
3125 params->p.cw_min = 0x0001;
3126 params->p.cw_max = 0x03FF;
3127 break;
3128 default:
3129 B43_WARN_ON(1);
3130 }
3106 } 3131 }
3107} 3132}
3108 3133
3109/* Initialize the core's QOS capabilities */ 3134/* Initialize the core's QOS capabilities */
3110static void b43_qos_init(struct b43_wldev *dev) 3135static void b43_qos_init(struct b43_wldev *dev)
3111{ 3136{
3112 struct b43_wl *wl = dev->wl;
3113 unsigned int i;
3114
3115 /* Upload the current QOS parameters. */ 3137 /* Upload the current QOS parameters. */
3116 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) 3138 b43_qos_upload_all(dev);
3117 wl->qos_params[i].need_hw_update = 1;
3118 b43_qos_update(dev);
3119 3139
3120 /* Enable QOS support. */ 3140 /* Enable QOS support. */
3121 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF); 3141 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
@@ -3124,25 +3144,13 @@ static void b43_qos_init(struct b43_wldev *dev)
3124 | B43_MMIO_IFSCTL_USE_EDCF); 3144 | B43_MMIO_IFSCTL_USE_EDCF);
3125} 3145}
3126 3146
3127static void b43_qos_update_work(struct work_struct *work)
3128{
3129 struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
3130 struct b43_wldev *dev;
3131
3132 mutex_lock(&wl->mutex);
3133 dev = wl->current_dev;
3134 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
3135 b43_qos_update(dev);
3136 mutex_unlock(&wl->mutex);
3137}
3138
3139static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue, 3147static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
3140 const struct ieee80211_tx_queue_params *params) 3148 const struct ieee80211_tx_queue_params *params)
3141{ 3149{
3142 struct b43_wl *wl = hw_to_b43_wl(hw); 3150 struct b43_wl *wl = hw_to_b43_wl(hw);
3143 unsigned long flags; 3151 struct b43_wldev *dev;
3144 unsigned int queue = (unsigned int)_queue; 3152 unsigned int queue = (unsigned int)_queue;
3145 struct b43_qos_params *p; 3153 int err = -ENODEV;
3146 3154
3147 if (queue >= ARRAY_SIZE(wl->qos_params)) { 3155 if (queue >= ARRAY_SIZE(wl->qos_params)) {
3148 /* Queue not available or don't support setting 3156 /* Queue not available or don't support setting
@@ -3150,16 +3158,25 @@ static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
3150 * confuse mac80211. */ 3158 * confuse mac80211. */
3151 return 0; 3159 return 0;
3152 } 3160 }
3161 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3162 ARRAY_SIZE(wl->qos_params));
3153 3163
3154 spin_lock_irqsave(&wl->irq_lock, flags); 3164 mutex_lock(&wl->mutex);
3155 p = &(wl->qos_params[queue]); 3165 dev = wl->current_dev;
3156 memcpy(&(p->p), params, sizeof(p->p)); 3166 if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED)))
3157 p->need_hw_update = 1; 3167 goto out_unlock;
3158 spin_unlock_irqrestore(&wl->irq_lock, flags);
3159 3168
3160 queue_work(hw->workqueue, &wl->qos_update_work); 3169 memcpy(&(wl->qos_params[queue].p), params, sizeof(*params));
3170 b43_mac_suspend(dev);
3171 b43_qos_params_upload(dev, &(wl->qos_params[queue].p),
3172 b43_qos_shm_offsets[queue]);
3173 b43_mac_enable(dev);
3174 err = 0;
3161 3175
3162 return 0; 3176out_unlock:
3177 mutex_unlock(&wl->mutex);
3178
3179 return err;
3163} 3180}
3164 3181
3165static int b43_op_get_tx_stats(struct ieee80211_hw *hw, 3182static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
@@ -4186,7 +4203,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4186 struct b43_wldev *dev = wl->current_dev; 4203 struct b43_wldev *dev = wl->current_dev;
4187 4204
4188 b43_rfkill_exit(dev); 4205 b43_rfkill_exit(dev);
4189 cancel_work_sync(&(wl->qos_update_work));
4190 cancel_work_sync(&(wl->beacon_update_trigger)); 4206 cancel_work_sync(&(wl->beacon_update_trigger));
4191 4207
4192 mutex_lock(&wl->mutex); 4208 mutex_lock(&wl->mutex);
@@ -4585,7 +4601,6 @@ static int b43_wireless_init(struct ssb_device *dev)
4585 spin_lock_init(&wl->shm_lock); 4601 spin_lock_init(&wl->shm_lock);
4586 mutex_init(&wl->mutex); 4602 mutex_init(&wl->mutex);
4587 INIT_LIST_HEAD(&wl->devlist); 4603 INIT_LIST_HEAD(&wl->devlist);
4588 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4589 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 4604 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
4590 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 4605 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
4591 4606
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index e8c012c9abb0..232181f6333c 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -386,7 +386,6 @@ static void b43_set_original_gains(struct b43_wldev *dev)
386void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val) 386void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val)
387{ 387{
388 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset); 388 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
389 mmiowb();
390 b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val); 389 b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val);
391} 390}
392 391
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 768cccb9b1ba..bed67a54250c 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -595,12 +595,14 @@ static void b43legacy_phy_initb5(struct b43legacy_wldev *dev)
595 0x0035) & 0xFFC0) | 0x0064); 595 0x0035) & 0xFFC0) | 0x0064);
596 b43legacy_phy_write(dev, 0x005D, (b43legacy_phy_read(dev, 596 b43legacy_phy_write(dev, 0x005D, (b43legacy_phy_read(dev,
597 0x005D) & 0xFF80) | 0x000A); 597 0x005D) & 0xFF80) | 0x000A);
598 b43legacy_phy_write(dev, 0x5B, 0x0000);
599 b43legacy_phy_write(dev, 0x5C, 0x0000);
598 } 600 }
599 601
600 if (dev->bad_frames_preempt) 602 if (dev->bad_frames_preempt)
601 b43legacy_phy_write(dev, B43legacy_PHY_RADIO_BITFIELD, 603 b43legacy_phy_write(dev, B43legacy_PHY_RADIO_BITFIELD,
602 b43legacy_phy_read(dev, 604 b43legacy_phy_read(dev,
603 B43legacy_PHY_RADIO_BITFIELD) | (1 << 11)); 605 B43legacy_PHY_RADIO_BITFIELD) | (1 << 12));
604 606
605 if (phy->analog == 1) { 607 if (phy->analog == 1) {
606 b43legacy_phy_write(dev, 0x0026, 0xCE00); 608 b43legacy_phy_write(dev, 0x0026, 0xCE00);
@@ -753,7 +755,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev)
753 b43legacy_radio_write16(dev, 0x0050, 0x0020); 755 b43legacy_radio_write16(dev, 0x0050, 0x0020);
754 } 756 }
755 if (phy->radio_rev <= 2) { 757 if (phy->radio_rev <= 2) {
756 b43legacy_radio_write16(dev, 0x007C, 0x0020); 758 b43legacy_radio_write16(dev, 0x0050, 0x0020);
757 b43legacy_radio_write16(dev, 0x005A, 0x0070); 759 b43legacy_radio_write16(dev, 0x005A, 0x0070);
758 b43legacy_radio_write16(dev, 0x005B, 0x007B); 760 b43legacy_radio_write16(dev, 0x005B, 0x007B);
759 b43legacy_radio_write16(dev, 0x005C, 0x00B0); 761 b43legacy_radio_write16(dev, 0x005C, 0x00B0);
@@ -771,7 +773,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev)
771 b43legacy_phy_write(dev, 0x002A, 0x8AC0); 773 b43legacy_phy_write(dev, 0x002A, 0x8AC0);
772 b43legacy_phy_write(dev, 0x0038, 0x0668); 774 b43legacy_phy_write(dev, 0x0038, 0x0668);
773 b43legacy_radio_set_txpower_bg(dev, 0xFFFF, 0xFFFF, 0xFFFF); 775 b43legacy_radio_set_txpower_bg(dev, 0xFFFF, 0xFFFF, 0xFFFF);
774 if (phy->radio_rev <= 5) 776 if (phy->radio_rev == 4 || phy->radio_rev == 5)
775 b43legacy_phy_write(dev, 0x005D, (b43legacy_phy_read(dev, 777 b43legacy_phy_write(dev, 0x005D, (b43legacy_phy_read(dev,
776 0x005D) & 0xFF80) | 0x0003); 778 0x005D) & 0xFF80) | 0x0003);
777 if (phy->radio_rev <= 2) 779 if (phy->radio_rev <= 2)
@@ -1010,7 +1012,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
1010 b43legacy_phy_initb5(dev); 1012 b43legacy_phy_initb5(dev);
1011 else 1013 else
1012 b43legacy_phy_initb6(dev); 1014 b43legacy_phy_initb6(dev);
1013 if (phy->rev >= 2 || phy->gmode) 1015 if (phy->rev >= 2 && phy->gmode)
1014 b43legacy_phy_inita(dev); 1016 b43legacy_phy_inita(dev);
1015 1017
1016 if (phy->rev >= 2) { 1018 if (phy->rev >= 2) {
@@ -1025,18 +1027,22 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
1025 b43legacy_phy_write(dev, 0x0811, 0x0400); 1027 b43legacy_phy_write(dev, 0x0811, 0x0400);
1026 b43legacy_phy_write(dev, 0x0015, 0x00C0); 1028 b43legacy_phy_write(dev, 0x0015, 0x00C0);
1027 } 1029 }
1028 if (phy->rev >= 2 || phy->gmode) { 1030 if (phy->gmode) {
1029 tmp = b43legacy_phy_read(dev, 0x0400) & 0xFF; 1031 tmp = b43legacy_phy_read(dev, 0x0400) & 0xFF;
1030 if (tmp == 3 || tmp == 5) { 1032 if (tmp == 3) {
1033 b43legacy_phy_write(dev, 0x04C2, 0x1816);
1034 b43legacy_phy_write(dev, 0x04C3, 0x8606);
1035 }
1036 if (tmp == 4 || tmp == 5) {
1031 b43legacy_phy_write(dev, 0x04C2, 0x1816); 1037 b43legacy_phy_write(dev, 0x04C2, 0x1816);
1032 b43legacy_phy_write(dev, 0x04C3, 0x8006); 1038 b43legacy_phy_write(dev, 0x04C3, 0x8006);
1033 if (tmp == 5) 1039 b43legacy_phy_write(dev, 0x04CC,
1034 b43legacy_phy_write(dev, 0x04CC, 1040 (b43legacy_phy_read(dev,
1035 (b43legacy_phy_read(dev, 1041 0x04CC) & 0x00FF) |
1036 0x04CC) & 0x00FF) | 1042 0x1F00);
1037 0x1F00);
1038 } 1043 }
1039 b43legacy_phy_write(dev, 0x047E, 0x0078); 1044 if (phy->rev >= 2)
1045 b43legacy_phy_write(dev, 0x047E, 0x0078);
1040 } 1046 }
1041 if (phy->radio_rev == 8) { 1047 if (phy->radio_rev == 8) {
1042 b43legacy_phy_write(dev, 0x0801, b43legacy_phy_read(dev, 0x0801) 1048 b43legacy_phy_write(dev, 0x0801, b43legacy_phy_read(dev, 0x0801)
@@ -1078,7 +1084,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
1078 else 1084 else
1079 b43legacy_phy_write(dev, 0x002F, 0x0202); 1085 b43legacy_phy_write(dev, 0x002F, 0x0202);
1080 } 1086 }
1081 if (phy->gmode || phy->rev >= 2) { 1087 if (phy->gmode) {
1082 b43legacy_phy_lo_adjust(dev, 0); 1088 b43legacy_phy_lo_adjust(dev, 0);
1083 b43legacy_phy_write(dev, 0x080F, 0x8078); 1089 b43legacy_phy_write(dev, 0x080F, 0x8078);
1084 } 1090 }
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index c5ca72aa59e7..6835064758fb 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -624,7 +624,7 @@ void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
624 tmp = hw->count; 624 tmp = hw->count;
625 status.frame_count = (tmp >> 4); 625 status.frame_count = (tmp >> 4);
626 status.rts_count = (tmp & 0x0F); 626 status.rts_count = (tmp & 0x0F);
627 tmp = hw->flags; 627 tmp = hw->flags << 1;
628 status.supp_reason = ((tmp & 0x1C) >> 2); 628 status.supp_reason = ((tmp & 0x1C) >> 2);
629 status.pm_indicated = !!(tmp & 0x80); 629 status.pm_indicated = !!(tmp & 0x80);
630 status.intermediate = !!(tmp & 0x40); 630 status.intermediate = !!(tmp & 0x40);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 1377c8190ecb..3d100e898249 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -681,19 +681,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
681 priv->last_rx_noise = rx_status.noise; 681 priv->last_rx_noise = rx_status.noise;
682 } 682 }
683 683
684 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { 684 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
685 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
686 return;
687 }
688
689 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
690 case IEEE80211_FTYPE_MGMT:
691 case IEEE80211_FTYPE_DATA:
692 /* fall through */
693 default:
694 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
695 break;
696 }
697} 685}
698 686
699int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, 687int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d9c4fdbf7f77..9838de5f4369 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1607,8 +1607,8 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1607 return ret; 1607 return ret;
1608} 1608}
1609 1609
1610 1610#ifdef IEEE80211_CONF_CHANNEL_SWITCH
1611int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) 1611static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1612{ 1612{
1613 int rc; 1613 int rc;
1614 u8 band = 0; 1614 u8 band = 0;
@@ -1648,6 +1648,7 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1648 rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); 1648 rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1649 return rc; 1649 return rc;
1650} 1650}
1651#endif
1651 1652
1652static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) 1653static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
1653{ 1654{
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 98f2c843b99e..c293e5b6cbb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -436,7 +436,7 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
436 /* Shift bitmap by one frame (throw away oldest history), 436 /* Shift bitmap by one frame (throw away oldest history),
437 * OR in "1", and increment "success" if this 437 * OR in "1", and increment "success" if this
438 * frame was successful. */ 438 * frame was successful. */
439 window->data <<= 1;; 439 window->data <<= 1;
440 if (successes > 0) { 440 if (successes > 0) {
441 window->success_counter++; 441 window->success_counter++;
442 window->data |= 0x1; 442 window->data |= 0x1;
@@ -1128,6 +1128,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
1128 1128
1129 /* Higher rate not available, use the original */ 1129 /* Higher rate not available, use the original */
1130 } else { 1130 } else {
1131 new_rate = rate;
1131 break; 1132 break;
1132 } 1133 }
1133 } 1134 }
@@ -1153,8 +1154,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1153 !sta->ht_info.ht_supported) 1154 !sta->ht_info.ht_supported)
1154 return -1; 1155 return -1;
1155 1156
1156 if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2) 1157 if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1157 == IWL_MIMO_PS_STATIC) 1158 == WLAN_HT_CAP_SM_PS_STATIC)
1158 return -1; 1159 return -1;
1159 1160
1160 /* Need both Tx chains/antennas to support MIMO */ 1161 /* Need both Tx chains/antennas to support MIMO */
@@ -1281,15 +1282,23 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1281 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1282 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1282 u8 start_action = tbl->action; 1283 u8 start_action = tbl->action;
1283 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1284 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1285 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1284 int ret = 0; 1286 int ret = 0;
1285 1287
1286 for (; ;) { 1288 for (; ;) {
1287 switch (tbl->action) { 1289 switch (tbl->action) {
1288 case IWL_LEGACY_SWITCH_ANTENNA: 1290 case IWL_LEGACY_SWITCH_ANTENNA1:
1291 case IWL_LEGACY_SWITCH_ANTENNA2:
1289 IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n"); 1292 IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
1290 1293
1291 lq_sta->action_counter++; 1294 lq_sta->action_counter++;
1292 1295
1296 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1297 tx_chains_num <= 1) ||
1298 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1299 tx_chains_num <= 2))
1300 break;
1301
1293 /* Don't change antenna if success has been great */ 1302 /* Don't change antenna if success has been great */
1294 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1303 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1295 break; 1304 break;
@@ -1299,7 +1308,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1299 1308
1300 if (rs_toggle_antenna(valid_tx_ant, 1309 if (rs_toggle_antenna(valid_tx_ant,
1301 &search_tbl->current_rate, search_tbl)) { 1310 &search_tbl->current_rate, search_tbl)) {
1302 lq_sta->search_better_tbl = 1; 1311 rs_set_expected_tpt_table(lq_sta, search_tbl);
1303 goto out; 1312 goto out;
1304 } 1313 }
1305 break; 1314 break;
@@ -1312,43 +1321,54 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1312 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1321 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1313 search_tbl, index); 1322 search_tbl, index);
1314 if (!ret) { 1323 if (!ret) {
1315 lq_sta->search_better_tbl = 1;
1316 lq_sta->action_counter = 0; 1324 lq_sta->action_counter = 0;
1317 goto out; 1325 goto out;
1318 } 1326 }
1319 1327
1320 break; 1328 break;
1321 case IWL_LEGACY_SWITCH_MIMO2: 1329 case IWL_LEGACY_SWITCH_MIMO2_AB:
1330 case IWL_LEGACY_SWITCH_MIMO2_AC:
1331 case IWL_LEGACY_SWITCH_MIMO2_BC:
1322 IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n"); 1332 IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
1323 1333
1324 /* Set up search table to try MIMO */ 1334 /* Set up search table to try MIMO */
1325 memcpy(search_tbl, tbl, sz); 1335 memcpy(search_tbl, tbl, sz);
1326 search_tbl->is_SGI = 0; 1336 search_tbl->is_SGI = 0;
1327 search_tbl->ant_type = ANT_AB;/*FIXME:RS*/ 1337
1328 /*FIXME:RS:need to check ant validity*/ 1338 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
1339 search_tbl->ant_type = ANT_AB;
1340 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1341 search_tbl->ant_type = ANT_AC;
1342 else
1343 search_tbl->ant_type = ANT_BC;
1344
1345 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1346 break;
1347
1329 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1348 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1330 search_tbl, index); 1349 search_tbl, index);
1331 if (!ret) { 1350 if (!ret) {
1332 lq_sta->search_better_tbl = 1;
1333 lq_sta->action_counter = 0; 1351 lq_sta->action_counter = 0;
1334 goto out; 1352 goto out;
1335 } 1353 }
1336 break; 1354 break;
1337 } 1355 }
1338 tbl->action++; 1356 tbl->action++;
1339 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) 1357 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
1340 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1358 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1341 1359
1342 if (tbl->action == start_action) 1360 if (tbl->action == start_action)
1343 break; 1361 break;
1344 1362
1345 } 1363 }
1364 search_tbl->lq_type = LQ_NONE;
1346 return 0; 1365 return 0;
1347 1366
1348 out: 1367out:
1368 lq_sta->search_better_tbl = 1;
1349 tbl->action++; 1369 tbl->action++;
1350 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) 1370 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
1351 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1371 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1352 return 0; 1372 return 0;
1353 1373
1354} 1374}
@@ -1370,34 +1390,51 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1370 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1390 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1371 u8 start_action = tbl->action; 1391 u8 start_action = tbl->action;
1372 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1392 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1393 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1373 int ret; 1394 int ret;
1374 1395
1375 for (;;) { 1396 for (;;) {
1376 lq_sta->action_counter++; 1397 lq_sta->action_counter++;
1377 switch (tbl->action) { 1398 switch (tbl->action) {
1378 case IWL_SISO_SWITCH_ANTENNA: 1399 case IWL_SISO_SWITCH_ANTENNA1:
1400 case IWL_SISO_SWITCH_ANTENNA2:
1379 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n"); 1401 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
1402
1403 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1404 tx_chains_num <= 1) ||
1405 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1406 tx_chains_num <= 2))
1407 break;
1408
1380 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1409 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1381 break; 1410 break;
1382 1411
1383 memcpy(search_tbl, tbl, sz); 1412 memcpy(search_tbl, tbl, sz);
1384 if (rs_toggle_antenna(valid_tx_ant, 1413 if (rs_toggle_antenna(valid_tx_ant,
1385 &search_tbl->current_rate, search_tbl)) { 1414 &search_tbl->current_rate, search_tbl))
1386 lq_sta->search_better_tbl = 1;
1387 goto out; 1415 goto out;
1388 }
1389 break; 1416 break;
1390 case IWL_SISO_SWITCH_MIMO2: 1417 case IWL_SISO_SWITCH_MIMO2_AB:
1418 case IWL_SISO_SWITCH_MIMO2_AC:
1419 case IWL_SISO_SWITCH_MIMO2_BC:
1391 IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n"); 1420 IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
1392 memcpy(search_tbl, tbl, sz); 1421 memcpy(search_tbl, tbl, sz);
1393 search_tbl->is_SGI = 0; 1422 search_tbl->is_SGI = 0;
1394 search_tbl->ant_type = ANT_AB; /*FIXME:RS*/ 1423
1424 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
1425 search_tbl->ant_type = ANT_AB;
1426 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1427 search_tbl->ant_type = ANT_AC;
1428 else
1429 search_tbl->ant_type = ANT_BC;
1430
1431 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1432 break;
1433
1395 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1434 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1396 search_tbl, index); 1435 search_tbl, index);
1397 if (!ret) { 1436 if (!ret)
1398 lq_sta->search_better_tbl = 1;
1399 goto out; 1437 goto out;
1400 }
1401 break; 1438 break;
1402 case IWL_SISO_SWITCH_GI: 1439 case IWL_SISO_SWITCH_GI:
1403 if (!tbl->is_fat && 1440 if (!tbl->is_fat &&
@@ -1427,22 +1464,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1427 } 1464 }
1428 search_tbl->current_rate = rate_n_flags_from_tbl( 1465 search_tbl->current_rate = rate_n_flags_from_tbl(
1429 search_tbl, index, is_green); 1466 search_tbl, index, is_green);
1430 lq_sta->search_better_tbl = 1;
1431 goto out; 1467 goto out;
1432 } 1468 }
1433 tbl->action++; 1469 tbl->action++;
1434 if (tbl->action > IWL_SISO_SWITCH_GI) 1470 if (tbl->action > IWL_SISO_SWITCH_GI)
1435 tbl->action = IWL_SISO_SWITCH_ANTENNA; 1471 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1436 1472
1437 if (tbl->action == start_action) 1473 if (tbl->action == start_action)
1438 break; 1474 break;
1439 } 1475 }
1476 search_tbl->lq_type = LQ_NONE;
1440 return 0; 1477 return 0;
1441 1478
1442 out: 1479 out:
1480 lq_sta->search_better_tbl = 1;
1443 tbl->action++; 1481 tbl->action++;
1444 if (tbl->action > IWL_SISO_SWITCH_GI) 1482 if (tbl->action > IWL_SISO_SWITCH_GI)
1445 tbl->action = IWL_SISO_SWITCH_ANTENNA; 1483 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1446 return 0; 1484 return 0;
1447} 1485}
1448 1486
@@ -1458,37 +1496,58 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1458 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1496 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1459 struct iwl_scale_tbl_info *search_tbl = 1497 struct iwl_scale_tbl_info *search_tbl =
1460 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1498 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1499 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1461 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1500 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1462 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1501 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1463 u8 start_action = tbl->action; 1502 u8 start_action = tbl->action;
1464 /*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/ 1503 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1504 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1465 int ret; 1505 int ret;
1466 1506
1467 for (;;) { 1507 for (;;) {
1468 lq_sta->action_counter++; 1508 lq_sta->action_counter++;
1469 switch (tbl->action) { 1509 switch (tbl->action) {
1470 case IWL_MIMO_SWITCH_ANTENNA_A: 1510 case IWL_MIMO2_SWITCH_ANTENNA1:
1471 case IWL_MIMO_SWITCH_ANTENNA_B: 1511 case IWL_MIMO2_SWITCH_ANTENNA2:
1512 IWL_DEBUG_RATE("LQ: MIMO toggle Antennas\n");
1513
1514 if (tx_chains_num <= 2)
1515 break;
1516
1517 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1518 break;
1519
1520 memcpy(search_tbl, tbl, sz);
1521 if (rs_toggle_antenna(valid_tx_ant,
1522 &search_tbl->current_rate, search_tbl))
1523 goto out;
1524 break;
1525 case IWL_MIMO2_SWITCH_SISO_A:
1526 case IWL_MIMO2_SWITCH_SISO_B:
1527 case IWL_MIMO2_SWITCH_SISO_C:
1472 IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n"); 1528 IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
1473 1529
1474 /* Set up new search table for SISO */ 1530 /* Set up new search table for SISO */
1475 memcpy(search_tbl, tbl, sz); 1531 memcpy(search_tbl, tbl, sz);
1476 1532
1477 /*FIXME:RS:need to check ant validity + C*/ 1533 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1478 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
1479 search_tbl->ant_type = ANT_A; 1534 search_tbl->ant_type = ANT_A;
1480 else 1535 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1481 search_tbl->ant_type = ANT_B; 1536 search_tbl->ant_type = ANT_B;
1537 else
1538 search_tbl->ant_type = ANT_C;
1539
1540 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1541 break;
1482 1542
1483 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1543 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1484 search_tbl, index); 1544 search_tbl, index);
1485 if (!ret) { 1545 if (!ret)
1486 lq_sta->search_better_tbl = 1;
1487 goto out; 1546 goto out;
1488 } 1547
1489 break; 1548 break;
1490 1549
1491 case IWL_MIMO_SWITCH_GI: 1550 case IWL_MIMO2_SWITCH_GI:
1492 if (!tbl->is_fat && 1551 if (!tbl->is_fat &&
1493 !(priv->current_ht_config.sgf & 1552 !(priv->current_ht_config.sgf &
1494 HT_SHORT_GI_20MHZ)) 1553 HT_SHORT_GI_20MHZ))
@@ -1517,23 +1576,23 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1517 } 1576 }
1518 search_tbl->current_rate = rate_n_flags_from_tbl( 1577 search_tbl->current_rate = rate_n_flags_from_tbl(
1519 search_tbl, index, is_green); 1578 search_tbl, index, is_green);
1520 lq_sta->search_better_tbl = 1;
1521 goto out; 1579 goto out;
1522 1580
1523 } 1581 }
1524 tbl->action++; 1582 tbl->action++;
1525 if (tbl->action > IWL_MIMO_SWITCH_GI) 1583 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1526 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; 1584 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1527 1585
1528 if (tbl->action == start_action) 1586 if (tbl->action == start_action)
1529 break; 1587 break;
1530 } 1588 }
1531 1589 search_tbl->lq_type = LQ_NONE;
1532 return 0; 1590 return 0;
1533 out: 1591 out:
1592 lq_sta->search_better_tbl = 1;
1534 tbl->action++; 1593 tbl->action++;
1535 if (tbl->action > IWL_MIMO_SWITCH_GI) 1594 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1536 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; 1595 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1537 return 0; 1596 return 0;
1538 1597
1539} 1598}
@@ -1748,19 +1807,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1748 rs_stay_in_table(lq_sta); 1807 rs_stay_in_table(lq_sta);
1749 1808
1750 goto out; 1809 goto out;
1810 }
1751 1811
1752 /* Else we have enough samples; calculate estimate of 1812 /* Else we have enough samples; calculate estimate of
1753 * actual average throughput */ 1813 * actual average throughput */
1754 } else { 1814
1755 /*FIXME:RS remove this else if we don't get this error*/ 1815 BUG_ON(window->average_tpt != ((window->success_ratio *
1756 if (window->average_tpt != ((window->success_ratio * 1816 tbl->expected_tpt[index] + 64) / 128));
1757 tbl->expected_tpt[index] + 64) / 128)) {
1758 IWL_ERROR("expected_tpt should have been calculated"
1759 " by now\n");
1760 window->average_tpt = ((window->success_ratio *
1761 tbl->expected_tpt[index] + 64) / 128);
1762 }
1763 }
1764 1817
1765 /* If we are searching for better modulation mode, check success. */ 1818 /* If we are searching for better modulation mode, check success. */
1766 if (lq_sta->search_better_tbl) { 1819 if (lq_sta->search_better_tbl) {
@@ -1770,7 +1823,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1770 * continuing to use the setup that we've been trying. */ 1823 * continuing to use the setup that we've been trying. */
1771 if (window->average_tpt > lq_sta->last_tpt) { 1824 if (window->average_tpt > lq_sta->last_tpt) {
1772 1825
1773 IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE " 1826 IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
1774 "suc=%d cur-tpt=%d old-tpt=%d\n", 1827 "suc=%d cur-tpt=%d old-tpt=%d\n",
1775 window->success_ratio, 1828 window->success_ratio,
1776 window->average_tpt, 1829 window->average_tpt,
@@ -2183,7 +2236,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2183 for (i = 0; i < IWL_RATE_COUNT; i++) 2236 for (i = 0; i < IWL_RATE_COUNT; i++)
2184 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2237 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2185 2238
2186 IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n"); 2239 IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
2187 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2240 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2188 * the lowest or the highest rate.. Could consider using RSSI from 2241 * the lowest or the highest rate.. Could consider using RSSI from
2189 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2242 * previous packets? Need to have IEEE 802.1X auth succeed immediately
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 84d4d1e33755..d148d73635eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -206,21 +206,28 @@ enum {
206#define IWL_RATE_DECREASE_TH 1920 /* 15% */ 206#define IWL_RATE_DECREASE_TH 1920 /* 15% */
207 207
208/* possible actions when in legacy mode */ 208/* possible actions when in legacy mode */
209#define IWL_LEGACY_SWITCH_ANTENNA 0 209#define IWL_LEGACY_SWITCH_ANTENNA1 0
210#define IWL_LEGACY_SWITCH_SISO 1 210#define IWL_LEGACY_SWITCH_ANTENNA2 1
211#define IWL_LEGACY_SWITCH_MIMO2 2 211#define IWL_LEGACY_SWITCH_SISO 2
212#define IWL_LEGACY_SWITCH_MIMO2_AB 3
213#define IWL_LEGACY_SWITCH_MIMO2_AC 4
214#define IWL_LEGACY_SWITCH_MIMO2_BC 5
212 215
213/* possible actions when in siso mode */ 216/* possible actions when in siso mode */
214#define IWL_SISO_SWITCH_ANTENNA 0 217#define IWL_SISO_SWITCH_ANTENNA1 0
215#define IWL_SISO_SWITCH_MIMO2 1 218#define IWL_SISO_SWITCH_ANTENNA2 1
216#define IWL_SISO_SWITCH_GI 2 219#define IWL_SISO_SWITCH_MIMO2_AB 2
220#define IWL_SISO_SWITCH_MIMO2_AC 3
221#define IWL_SISO_SWITCH_MIMO2_BC 4
222#define IWL_SISO_SWITCH_GI 5
217 223
218/* possible actions when in mimo mode */ 224/* possible actions when in mimo mode */
219#define IWL_MIMO_SWITCH_ANTENNA_A 0 225#define IWL_MIMO2_SWITCH_ANTENNA1 0
220#define IWL_MIMO_SWITCH_ANTENNA_B 1 226#define IWL_MIMO2_SWITCH_ANTENNA2 1
221#define IWL_MIMO_SWITCH_GI 2 227#define IWL_MIMO2_SWITCH_SISO_A 2
222 228#define IWL_MIMO2_SWITCH_SISO_B 3
223/*FIXME:RS:separate MIMO2/3 transitions*/ 229#define IWL_MIMO2_SWITCH_SISO_C 4
230#define IWL_MIMO2_SWITCH_GI 5
224 231
225/*FIXME:RS:add posible acctions for MIMO3*/ 232/*FIXME:RS:add posible acctions for MIMO3*/
226 233
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1547122e66fa..31ea28858896 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -485,7 +485,7 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
485 return IWL_RATE_6M_PLCP; 485 return IWL_RATE_6M_PLCP;
486} 486}
487 487
488unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, 488static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
489 struct iwl_frame *frame, u8 rate) 489 struct iwl_frame *frame, u8 rate)
490{ 490{
491 struct iwl_tx_beacon_cmd *tx_beacon_cmd; 491 struct iwl_tx_beacon_cmd *tx_beacon_cmd;
@@ -564,8 +564,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
564 if (!iwl_conf->is_ht) 564 if (!iwl_conf->is_ht)
565 return; 565 return;
566 566
567 priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
568
569 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) 567 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
570 iwl_conf->sgf |= HT_SHORT_GI_20MHZ; 568 iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
571 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) 569 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
@@ -586,6 +584,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
586 iwl_conf->supported_chan_width = 0; 584 iwl_conf->supported_chan_width = 0;
587 } 585 }
588 586
587 iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
588
589 memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); 589 memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
590 590
591 iwl_conf->control_channel = ht_bss_conf->primary_channel; 591 iwl_conf->control_channel = ht_bss_conf->primary_channel;
@@ -2558,7 +2558,11 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2558 iwl_activate_qos(priv, 0); 2558 iwl_activate_qos(priv, 0);
2559 spin_unlock_irqrestore(&priv->lock, flags); 2559 spin_unlock_irqrestore(&priv->lock, flags);
2560 2560
2561 iwl_power_enable_management(priv); 2561 /* the chain noise calibration will enabled PM upon completion
2562 * If chain noise has already been run, then we need to enable
2563 * power management here */
2564 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2565 iwl_power_enable_management(priv);
2562 2566
2563 /* Enable Rx differential gain and sensitivity calibrations */ 2567 /* Enable Rx differential gain and sensitivity calibrations */
2564 iwl_chain_noise_reset(priv); 2568 iwl_chain_noise_reset(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 35fb4a4f737d..72fbf47229db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -808,13 +808,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
808 } 808 }
809 } 809 }
810 810
811 /* Save for use within RXON, TX, SCAN commands, etc. */
812 priv->chain_noise_data.active_chains = active_chains;
811 IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n", 813 IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
812 active_chains); 814 active_chains);
813 815
814 /* Save for use within RXON, TX, SCAN commands, etc. */
815 /*priv->valid_antenna = active_chains;*/
816 /*FIXME: should be reflected in RX chains in RXON */
817
818 /* Analyze noise for rx balance */ 816 /* Analyze noise for rx balance */
819 average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS); 817 average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
820 average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS); 818 average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
@@ -839,6 +837,15 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
839 837
840 priv->cfg->ops->utils->gain_computation(priv, average_noise, 838 priv->cfg->ops->utils->gain_computation(priv, average_noise,
841 min_average_noise_antenna_i, min_average_noise); 839 min_average_noise_antenna_i, min_average_noise);
840
841 /* Some power changes may have been made during the calibration.
842 * Update and commit the RXON
843 */
844 if (priv->cfg->ops->lib->update_chain_flags)
845 priv->cfg->ops->lib->update_chain_flags(priv);
846
847 data->state = IWL_CHAIN_NOISE_DONE;
848 iwl_power_enable_management(priv);
842} 849}
843EXPORT_SYMBOL(iwl_chain_noise_calibration); 850EXPORT_SYMBOL(iwl_chain_noise_calibration);
844 851
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a0b86af25c83..36d08b0eec43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -399,8 +399,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
399 399
400 ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; 400 ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
401 ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; 401 ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
402 ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS & 402 ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS &
403 (IWL_MIMO_PS_NONE << 2)); 403 (WLAN_HT_CAP_SM_PS_DISABLED << 2));
404 404
405 max_bit_rate = MAX_BIT_RATE_20_MHZ; 405 max_bit_rate = MAX_BIT_RATE_20_MHZ;
406 if (priv->hw_params.fat_channel & BIT(band)) { 406 if (priv->hw_params.fat_channel & BIT(band)) {
@@ -709,7 +709,8 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
709 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 709 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
710 710
711 /* # of Rx chains to use when expecting MIMO. */ 711 /* # of Rx chains to use when expecting MIMO. */
712 if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) 712 if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
713 WLAN_HT_CAP_SM_PS_STATIC)))
713 return 2; 714 return 2;
714 else 715 else
715 return 3; 716 return 3;
@@ -720,17 +721,18 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
720 int idle_cnt; 721 int idle_cnt;
721 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 722 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
722 /* # Rx chains when idling and maybe trying to save power */ 723 /* # Rx chains when idling and maybe trying to save power */
723 switch (priv->ps_mode) { 724 switch (priv->current_ht_config.sm_ps) {
724 case IWL_MIMO_PS_STATIC: 725 case WLAN_HT_CAP_SM_PS_STATIC:
725 case IWL_MIMO_PS_DYNAMIC: 726 case WLAN_HT_CAP_SM_PS_DYNAMIC:
726 idle_cnt = (is_cam) ? 2 : 1; 727 idle_cnt = (is_cam) ? 2 : 1;
727 break; 728 break;
728 case IWL_MIMO_PS_NONE: 729 case WLAN_HT_CAP_SM_PS_DISABLED:
729 idle_cnt = (is_cam) ? active_cnt : 1; 730 idle_cnt = (is_cam) ? active_cnt : 1;
730 break; 731 break;
731 case IWL_MIMO_PS_INVALID: 732 case WLAN_HT_CAP_SM_PS_INVALID:
732 default: 733 default:
733 IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode); 734 IWL_ERROR("invalide mimo ps mode %d\n",
735 priv->current_ht_config.sm_ps);
734 WARN_ON(1); 736 WARN_ON(1);
735 idle_cnt = -1; 737 idle_cnt = -1;
736 break; 738 break;
@@ -738,6 +740,17 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
738 return idle_cnt; 740 return idle_cnt;
739} 741}
740 742
743/* up to 4 chains */
744static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
745{
746 u8 res;
747 res = (chain_bitmap & BIT(0)) >> 0;
748 res += (chain_bitmap & BIT(1)) >> 1;
749 res += (chain_bitmap & BIT(2)) >> 2;
750 res += (chain_bitmap & BIT(4)) >> 4;
751 return res;
752}
753
741/** 754/**
742 * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image 755 * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
743 * 756 *
@@ -748,25 +761,35 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
748{ 761{
749 bool is_single = is_single_rx_stream(priv); 762 bool is_single = is_single_rx_stream(priv);
750 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 763 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
751 u8 idle_rx_cnt, active_rx_cnt; 764 u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
765 u32 active_chains;
752 u16 rx_chain; 766 u16 rx_chain;
753 767
754 /* Tell uCode which antennas are actually connected. 768 /* Tell uCode which antennas are actually connected.
755 * Before first association, we assume all antennas are connected. 769 * Before first association, we assume all antennas are connected.
756 * Just after first association, iwl_chain_noise_calibration() 770 * Just after first association, iwl_chain_noise_calibration()
757 * checks which antennas actually *are* connected. */ 771 * checks which antennas actually *are* connected. */
758 rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; 772 if (priv->chain_noise_data.active_chains)
773 active_chains = priv->chain_noise_data.active_chains;
774 else
775 active_chains = priv->hw_params.valid_rx_ant;
776
777 rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
759 778
760 /* How many receivers should we use? */ 779 /* How many receivers should we use? */
761 active_rx_cnt = iwl_get_active_rx_chain_count(priv); 780 active_rx_cnt = iwl_get_active_rx_chain_count(priv);
762 idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); 781 idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
763 782
764 /* correct rx chain count accoridng hw settings */
765 if (priv->hw_params.rx_chains_num < active_rx_cnt)
766 active_rx_cnt = priv->hw_params.rx_chains_num;
767 783
768 if (priv->hw_params.rx_chains_num < idle_rx_cnt) 784 /* correct rx chain count according hw settings
769 idle_rx_cnt = priv->hw_params.rx_chains_num; 785 * and chain noise calibration
786 */
787 valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
788 if (valid_rx_cnt < active_rx_cnt)
789 active_rx_cnt = valid_rx_cnt;
790
791 if (valid_rx_cnt < idle_rx_cnt)
792 idle_rx_cnt = valid_rx_cnt;
770 793
771 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; 794 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
772 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; 795 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
@@ -778,7 +801,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
778 else 801 else
779 priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; 802 priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
780 803
781 IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n", 804 IWL_DEBUG_ASSOC("rx_chain=0x%X active=%d idle=%d\n",
782 priv->staging_rxon.rx_chain, 805 priv->staging_rxon.rx_chain,
783 active_rx_cnt, idle_rx_cnt); 806 active_rx_cnt, idle_rx_cnt);
784 807
@@ -912,7 +935,7 @@ int iwl_init_drv(struct iwl_priv *priv)
912 priv->iw_mode = IEEE80211_IF_TYPE_STA; 935 priv->iw_mode = IEEE80211_IF_TYPE_STA;
913 936
914 priv->use_ant_b_for_management_frame = 1; /* start with ant B */ 937 priv->use_ant_b_for_management_frame = 1; /* start with ant B */
915 priv->ps_mode = IWL_MIMO_PS_NONE; 938 priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
916 939
917 /* Choose which receivers/antennas to use */ 940 /* Choose which receivers/antennas to use */
918 iwl_set_rxon_chain(priv); 941 iwl_set_rxon_chain(priv);
@@ -1135,7 +1158,6 @@ int iwl_verify_ucode(struct iwl_priv *priv)
1135} 1158}
1136EXPORT_SYMBOL(iwl_verify_ucode); 1159EXPORT_SYMBOL(iwl_verify_ucode);
1137 1160
1138
1139static const char *desc_lookup(int i) 1161static const char *desc_lookup(int i)
1140{ 1162{
1141 switch (i) { 1163 switch (i) {
@@ -1216,9 +1238,9 @@ EXPORT_SYMBOL(iwl_dump_nic_error_log);
1216/** 1238/**
1217 * iwl_print_event_log - Dump error event log to syslog 1239 * iwl_print_event_log - Dump error event log to syslog
1218 * 1240 *
1219 * NOTE: Must be called with iwl4965_grab_nic_access() already obtained! 1241 * NOTE: Must be called with iwl_grab_nic_access() already obtained!
1220 */ 1242 */
1221void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, 1243static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1222 u32 num_events, u32 mode) 1244 u32 num_events, u32 mode)
1223{ 1245{
1224 u32 i; 1246 u32 i;
@@ -1259,8 +1281,6 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1259 } 1281 }
1260 } 1282 }
1261} 1283}
1262EXPORT_SYMBOL(iwl_print_event_log);
1263
1264 1284
1265void iwl_dump_nic_event_log(struct iwl_priv *priv) 1285void iwl_dump_nic_event_log(struct iwl_priv *priv)
1266{ 1286{
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b5db050b22d1..55a4b584ce07 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -184,7 +184,6 @@ struct iwl_cfg {
184struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 184struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
185 struct ieee80211_ops *hw_ops); 185 struct ieee80211_ops *hw_ops);
186void iwl_hw_detect(struct iwl_priv *priv); 186void iwl_hw_detect(struct iwl_priv *priv);
187
188void iwl_clear_stations_table(struct iwl_priv *priv); 187void iwl_clear_stations_table(struct iwl_priv *priv);
189void iwl_reset_qos(struct iwl_priv *priv); 188void iwl_reset_qos(struct iwl_priv *priv);
190void iwl_set_rxon_chain(struct iwl_priv *priv); 189void iwl_set_rxon_chain(struct iwl_priv *priv);
@@ -215,7 +214,6 @@ void iwl_rx_replenish(struct iwl_priv *priv);
215int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 214int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
216int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn); 215int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn);
217int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid); 216int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
218/* FIXME: remove when TX is moved to iwl core */
219int iwl_rx_queue_restock(struct iwl_priv *priv); 217int iwl_rx_queue_restock(struct iwl_priv *priv);
220int iwl_rx_queue_space(const struct iwl_rx_queue *q); 218int iwl_rx_queue_space(const struct iwl_rx_queue *q);
221void iwl_rx_allocate(struct iwl_priv *priv); 219void iwl_rx_allocate(struct iwl_priv *priv);
@@ -234,11 +232,7 @@ void iwl_rx_statistics(struct iwl_priv *priv,
234******************************************************/ 232******************************************************/
235int iwl_txq_ctx_reset(struct iwl_priv *priv); 233int iwl_txq_ctx_reset(struct iwl_priv *priv);
236int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); 234int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
237/* FIXME: remove when free Tx is fully merged into iwlcore */
238int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
239void iwl_hw_txq_ctx_free(struct iwl_priv *priv); 235void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
240int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
241 dma_addr_t addr, u16 len);
242int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 236int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
243int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); 237int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
244int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); 238int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -253,6 +247,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
253 * RF -Kill - here and not in iwl-rfkill.h to be available when 247 * RF -Kill - here and not in iwl-rfkill.h to be available when
254 * RF-kill subsystem is not compiled. 248 * RF-kill subsystem is not compiled.
255 ****************************************************/ 249 ****************************************************/
250void iwl_rf_kill(struct iwl_priv *priv);
256void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); 251void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
257int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); 252int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
258 253
@@ -283,7 +278,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
283void iwl_init_scan_params(struct iwl_priv *priv); 278void iwl_init_scan_params(struct iwl_priv *priv);
284int iwl_scan_cancel(struct iwl_priv *priv); 279int iwl_scan_cancel(struct iwl_priv *priv);
285int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 280int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
286const char *iwl_escape_essid(const char *essid, u8 essid_len);
287int iwl_scan_initiate(struct iwl_priv *priv); 281int iwl_scan_initiate(struct iwl_priv *priv);
288void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 282void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
289void iwl_setup_scan_deferred_work(struct iwl_priv *priv); 283void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
@@ -316,8 +310,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
316/***************************************************** 310/*****************************************************
317* Error Handling Debugging 311* Error Handling Debugging
318******************************************************/ 312******************************************************/
319void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
320 u32 num_events, u32 mode);
321void iwl_dump_nic_error_log(struct iwl_priv *priv); 313void iwl_dump_nic_error_log(struct iwl_priv *priv);
322void iwl_dump_nic_event_log(struct iwl_priv *priv); 314void iwl_dump_nic_event_log(struct iwl_priv *priv);
323 315
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 640ceea913c7..1823687e5820 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -406,6 +406,7 @@ struct iwl_ht_info {
406 /* self configuration data */ 406 /* self configuration data */
407 u8 is_ht; 407 u8 is_ht;
408 u8 supported_chan_width; 408 u8 supported_chan_width;
409 u8 sm_ps;
409 u8 is_green_field; 410 u8 is_green_field;
410 u8 sgf; /* HT_SHORT_GI_* short guard interval */ 411 u8 sgf; /* HT_SHORT_GI_* short guard interval */
411 u8 max_amsdu_size; 412 u8 max_amsdu_size;
@@ -564,50 +565,31 @@ struct iwl_hw_params {
564#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) 565#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
565#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) 566#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
566 567
567
568/******************************************************************************
569 *
570 * Functions implemented in iwl-base.c which are forward declared here
571 * for use by iwl-*.c
572 *
573 *****************************************************************************/
574struct iwl_addsta_cmd;
575extern int iwl_send_add_sta(struct iwl_priv *priv,
576 struct iwl_addsta_cmd *sta, u8 flags);
577u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
578 u8 flags, struct ieee80211_ht_info *ht_info);
579extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
580 struct ieee80211_hdr *hdr,
581 const u8 *dest, int left);
582extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
583int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
584extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
585
586extern const u8 iwl_bcast_addr[ETH_ALEN];
587
588/****************************************************************************** 568/******************************************************************************
589 * 569 *
590 * Functions implemented in iwl-[34]*.c which are forward declared here 570 * Functions implemented in core module which are forward declared here
591 * for use by iwl-base.c 571 * for use by iwl-[4-5].c
592 * 572 *
593 * NOTE: The implementation of these functions are hardware specific 573 * NOTE: The implementation of these functions are not hardware specific
594 * which is why they are in the hardware specific files (vs. iwl-base.c) 574 * which is why they are in the core module files.
595 * 575 *
596 * Naming convention -- 576 * Naming convention --
597 * iwl4965_ <-- Its part of iwlwifi (should be changed to iwl4965_) 577 * iwl_ <-- Is part of iwlwifi
598 * iwl4965_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW)
599 * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) 578 * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
600 * iwl4965_bg_ <-- Called from work queue context 579 * iwl4965_bg_ <-- Called from work queue context
601 * iwl4965_mac_ <-- mac80211 callback 580 * iwl4965_mac_ <-- mac80211 callback
602 * 581 *
603 ****************************************************************************/ 582 ****************************************************************************/
583struct iwl_addsta_cmd;
584extern int iwl_send_add_sta(struct iwl_priv *priv,
585 struct iwl_addsta_cmd *sta, u8 flags);
586extern u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
587 int is_ap, u8 flags, struct ieee80211_ht_info *ht_info);
588extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
589extern int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
590extern const u8 iwl_bcast_addr[ETH_ALEN];
604extern int iwl_rxq_stop(struct iwl_priv *priv); 591extern int iwl_rxq_stop(struct iwl_priv *priv);
605extern void iwl_txq_ctx_stop(struct iwl_priv *priv); 592extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
606extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
607 struct iwl_frame *frame, u8 rate);
608extern void iwl4965_disable_events(struct iwl_priv *priv);
609
610extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
611extern int iwl_queue_space(const struct iwl_queue *q); 593extern int iwl_queue_space(const struct iwl_queue *q);
612static inline int iwl_queue_used(const struct iwl_queue *q, int i) 594static inline int iwl_queue_used(const struct iwl_queue *q, int i)
613{ 595{
@@ -644,11 +626,6 @@ struct iwl_kw {
644#define IWL_CHANNEL_WIDTH_20MHZ 0 626#define IWL_CHANNEL_WIDTH_20MHZ 0
645#define IWL_CHANNEL_WIDTH_40MHZ 1 627#define IWL_CHANNEL_WIDTH_40MHZ 1
646 628
647#define IWL_MIMO_PS_STATIC 0
648#define IWL_MIMO_PS_NONE 3
649#define IWL_MIMO_PS_DYNAMIC 1
650#define IWL_MIMO_PS_INVALID 2
651
652#define IWL_OPERATION_MODE_AUTO 0 629#define IWL_OPERATION_MODE_AUTO 0
653#define IWL_OPERATION_MODE_HT_ONLY 1 630#define IWL_OPERATION_MODE_HT_ONLY 1
654#define IWL_OPERATION_MODE_MIXED 2 631#define IWL_OPERATION_MODE_MIXED 2
@@ -703,8 +680,9 @@ enum iwl4965_false_alarm_state {
703 680
704enum iwl4965_chain_noise_state { 681enum iwl4965_chain_noise_state {
705 IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ 682 IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
706 IWL_CHAIN_NOISE_ACCUMULATE = 1, 683 IWL_CHAIN_NOISE_ACCUMULATE,
707 IWL_CHAIN_NOISE_CALIBRATED = 2, 684 IWL_CHAIN_NOISE_CALIBRATED,
685 IWL_CHAIN_NOISE_DONE,
708}; 686};
709 687
710enum iwl4965_calib_enabled_state { 688enum iwl4965_calib_enabled_state {
@@ -762,17 +740,18 @@ struct iwl_sensitivity_data {
762 740
763/* Chain noise (differential Rx gain) calib data */ 741/* Chain noise (differential Rx gain) calib data */
764struct iwl_chain_noise_data { 742struct iwl_chain_noise_data {
765 u8 state; 743 u32 active_chains;
766 u16 beacon_count;
767 u32 chain_noise_a; 744 u32 chain_noise_a;
768 u32 chain_noise_b; 745 u32 chain_noise_b;
769 u32 chain_noise_c; 746 u32 chain_noise_c;
770 u32 chain_signal_a; 747 u32 chain_signal_a;
771 u32 chain_signal_b; 748 u32 chain_signal_b;
772 u32 chain_signal_c; 749 u32 chain_signal_c;
750 u16 beacon_count;
773 u8 disconn_array[NUM_RX_CHAINS]; 751 u8 disconn_array[NUM_RX_CHAINS];
774 u8 delta_gain_code[NUM_RX_CHAINS]; 752 u8 delta_gain_code[NUM_RX_CHAINS];
775 u8 radio_write; 753 u8 radio_write;
754 u8 state;
776}; 755};
777 756
778#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ 757#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
@@ -995,7 +974,6 @@ struct iwl_priv {
995 * hardware */ 974 * hardware */
996 u16 assoc_id; 975 u16 assoc_id;
997 u16 assoc_capability; 976 u16 assoc_capability;
998 u8 ps_mode;
999 977
1000 struct iwl_qos_info qos_data; 978 struct iwl_qos_info qos_data;
1001 979
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 16f834d0c486..55ec31ec9e15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -250,17 +250,26 @@ static int iwl_update_power_command(struct iwl_priv *priv,
250 250
251 251
252/* 252/*
253 * calucaute the final power mode index 253 * compute the final power mode index
254 */ 254 */
255int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh) 255int iwl_power_update_mode(struct iwl_priv *priv, bool force)
256{ 256{
257 struct iwl_power_mgr *setting = &(priv->power_data); 257 struct iwl_power_mgr *setting = &(priv->power_data);
258 int ret = 0; 258 int ret = 0;
259 u16 uninitialized_var(final_mode); 259 u16 uninitialized_var(final_mode);
260 260
261 /* If on battery, set to 3, 261 /* Don't update the RX chain when chain noise calibration is running */
262 * if plugged into AC power, set to CAM ("continuously aware mode"), 262 if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
263 * else user level */ 263 priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) {
264 IWL_DEBUG_POWER("Cannot update the power, chain noise "
265 "calibration running: %d\n",
266 priv->chain_noise_data.state);
267 return -EAGAIN;
268 }
269
270 /* If on battery, set to 3,
271 * if plugged into AC power, set to CAM ("continuously aware mode"),
272 * else user level */
264 273
265 switch (setting->system_power_setting) { 274 switch (setting->system_power_setting) {
266 case IWL_POWER_SYS_AUTO: 275 case IWL_POWER_SYS_AUTO:
@@ -285,7 +294,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
285 final_mode = IWL_POWER_MODE_CAM; 294 final_mode = IWL_POWER_MODE_CAM;
286 295
287 if (!iwl_is_rfkill(priv) && !setting->power_disabled && 296 if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
288 ((setting->power_mode != final_mode) || refresh)) { 297 ((setting->power_mode != final_mode) || force)) {
289 struct iwl_powertable_cmd cmd; 298 struct iwl_powertable_cmd cmd;
290 299
291 if (final_mode != IWL_POWER_MODE_CAM) 300 if (final_mode != IWL_POWER_MODE_CAM)
@@ -359,35 +368,26 @@ EXPORT_SYMBOL(iwl_power_enable_management);
359/* set user_power_setting */ 368/* set user_power_setting */
360int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) 369int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
361{ 370{
362 int ret = 0;
363
364 if (mode > IWL_POWER_LIMIT) 371 if (mode > IWL_POWER_LIMIT)
365 return -EINVAL; 372 return -EINVAL;
366 373
367 priv->power_data.user_power_setting = mode; 374 priv->power_data.user_power_setting = mode;
368 375
369 ret = iwl_power_update_mode(priv, 0); 376 return iwl_power_update_mode(priv, 0);
370
371 return ret;
372} 377}
373EXPORT_SYMBOL(iwl_power_set_user_mode); 378EXPORT_SYMBOL(iwl_power_set_user_mode);
374 379
375
376/* set system_power_setting. This should be set by over all 380/* set system_power_setting. This should be set by over all
377 * PM application. 381 * PM application.
378 */ 382 */
379int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode) 383int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
380{ 384{
381 int ret = 0;
382
383 if (mode > IWL_POWER_LIMIT) 385 if (mode > IWL_POWER_LIMIT)
384 return -EINVAL; 386 return -EINVAL;
385 387
386 priv->power_data.system_power_setting = mode; 388 priv->power_data.system_power_setting = mode;
387 389
388 ret = iwl_power_update_mode(priv, 0); 390 return iwl_power_update_mode(priv, 0);
389
390 return ret;
391} 391}
392EXPORT_SYMBOL(iwl_power_set_system_mode); 392EXPORT_SYMBOL(iwl_power_set_system_mode);
393 393
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index aa99f3647def..df484a90ae64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -72,7 +72,7 @@ struct iwl_power_mgr {
72 /* final power level that used to calculate final power command */ 72 /* final power level that used to calculate final power command */
73 u8 power_mode; 73 u8 power_mode;
74 u8 user_power_setting; /* set by user through mac80211 or sysfs */ 74 u8 user_power_setting; /* set by user through mac80211 or sysfs */
75 u8 system_power_setting; /* set by kernel syatem tools */ 75 u8 system_power_setting; /* set by kernel system tools */
76 u8 critical_power_setting; /* set if driver over heated */ 76 u8 critical_power_setting; /* set if driver over heated */
77 u8 is_battery_active; /* DC/AC power */ 77 u8 is_battery_active; /* DC/AC power */
78 u8 power_disabled; /* flag to disable using power saving level */ 78 u8 power_disabled; /* flag to disable using power saving level */
@@ -80,7 +80,7 @@ struct iwl_power_mgr {
80 80
81void iwl_setup_power_deferred_work(struct iwl_priv *priv); 81void iwl_setup_power_deferred_work(struct iwl_priv *priv);
82void iwl_power_cancel_timeout(struct iwl_priv *priv); 82void iwl_power_cancel_timeout(struct iwl_priv *priv);
83int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh); 83int iwl_power_update_mode(struct iwl_priv *priv, bool force);
84int iwl_power_disable_management(struct iwl_priv *priv, u32 ms); 84int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
85int iwl_power_enable_management(struct iwl_priv *priv); 85int iwl_power_enable_management(struct iwl_priv *priv);
86int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); 86int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 6c8ac3a87d54..d026aaf62335 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -88,7 +88,7 @@ static int iwl_is_empty_essid(const char *essid, int essid_len)
88 88
89 89
90 90
91const char *iwl_escape_essid(const char *essid, u8 essid_len) 91static const char *iwl_escape_essid(const char *essid, u8 essid_len)
92{ 92{
93 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; 93 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
94 const char *s = essid; 94 const char *s = essid;
@@ -111,7 +111,6 @@ const char *iwl_escape_essid(const char *essid, u8 essid_len)
111 *d = '\0'; 111 *d = '\0';
112 return escaped; 112 return escaped;
113} 113}
114EXPORT_SYMBOL(iwl_escape_essid);
115 114
116/** 115/**
117 * iwl_scan_cancel - Cancel any currently executing HW scan 116 * iwl_scan_cancel - Cancel any currently executing HW scan
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 5b7b05c8773f..a72569f1acb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -191,20 +191,20 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
191 if (!sta_ht_inf || !sta_ht_inf->ht_supported) 191 if (!sta_ht_inf || !sta_ht_inf->ht_supported)
192 goto done; 192 goto done;
193 193
194 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2; 194 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
195 195
196 sta_flags = priv->stations[index].sta.station_flags; 196 sta_flags = priv->stations[index].sta.station_flags;
197 197
198 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); 198 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
199 199
200 switch (mimo_ps_mode) { 200 switch (mimo_ps_mode) {
201 case WLAN_HT_CAP_MIMO_PS_STATIC: 201 case WLAN_HT_CAP_SM_PS_STATIC:
202 sta_flags |= STA_FLG_MIMO_DIS_MSK; 202 sta_flags |= STA_FLG_MIMO_DIS_MSK;
203 break; 203 break;
204 case WLAN_HT_CAP_MIMO_PS_DYNAMIC: 204 case WLAN_HT_CAP_SM_PS_DYNAMIC:
205 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; 205 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
206 break; 206 break;
207 case WLAN_HT_CAP_MIMO_PS_DISABLED: 207 case WLAN_HT_CAP_SM_PS_DISABLED:
208 break; 208 break;
209 default: 209 default:
210 IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode); 210 IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 9d485aadef96..9d5bcf46cbe9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -63,7 +63,7 @@ static const u16 default_tid_to_tx_fifo[] = {
63 * Does NOT advance any TFD circular buffer read/write indexes 63 * Does NOT advance any TFD circular buffer read/write indexes
64 * Does NOT free the TFD itself (which is within circular buffer) 64 * Does NOT free the TFD itself (which is within circular buffer)
65 */ 65 */
66int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) 66static int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
67{ 67{
68 struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; 68 struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
69 struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; 69 struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
@@ -115,10 +115,8 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
115 } 115 }
116 return 0; 116 return 0;
117} 117}
118EXPORT_SYMBOL(iwl_hw_txq_free_tfd);
119 118
120 119static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
121int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
122 dma_addr_t addr, u16 len) 120 dma_addr_t addr, u16 len)
123{ 121{
124 int index, is_odd; 122 int index, is_odd;
@@ -151,7 +149,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
151 149
152 return 0; 150 return 0;
153} 151}
154EXPORT_SYMBOL(iwl_hw_txq_attach_buf_to_tfd);
155 152
156/** 153/**
157 * iwl_txq_update_write_ptr - Send new write index to hardware 154 * iwl_txq_update_write_ptr - Send new write index to hardware
@@ -478,7 +475,6 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
478} 475}
479EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 476EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
480 477
481
482/** 478/**
483 * iwl_txq_ctx_reset - Reset TX queue context 479 * iwl_txq_ctx_reset - Reset TX queue context
484 * Destroys all DMA structures and initialise them again 480 * Destroys all DMA structures and initialise them again
@@ -545,6 +541,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
545 error_kw: 541 error_kw:
546 return ret; 542 return ret;
547} 543}
544
548/** 545/**
549 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory 546 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
550 */ 547 */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 802547e79671..5fef05f3cd00 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1971,6 +1971,70 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
1971} 1971}
1972 1972
1973 1973
1974/**
1975 * @brief Configures the transmission power control functionality.
1976 *
1977 * @param priv A pointer to struct lbs_private structure
1978 * @param enable Transmission power control enable
1979 * @param p0 Power level when link quality is good (dBm).
1980 * @param p1 Power level when link quality is fair (dBm).
1981 * @param p2 Power level when link quality is poor (dBm).
1982 * @param usesnr Use Signal to Noise Ratio in TPC
1983 *
1984 * @return 0 on success
1985 */
1986int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1987 int8_t p2, int usesnr)
1988{
1989 struct cmd_ds_802_11_tpc_cfg cmd;
1990 int ret;
1991
1992 memset(&cmd, 0, sizeof(cmd));
1993 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1994 cmd.action = cpu_to_le16(CMD_ACT_SET);
1995 cmd.enable = !!enable;
1996 cmd.usesnr = !!enable;
1997 cmd.P0 = p0;
1998 cmd.P1 = p1;
1999 cmd.P2 = p2;
2000
2001 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
2002
2003 return ret;
2004}
2005
2006/**
2007 * @brief Configures the power adaptation settings.
2008 *
2009 * @param priv A pointer to struct lbs_private structure
2010 * @param enable Power adaptation enable
2011 * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
2012 * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
2013 * @param p2 Power level for 48 and 54 Mbps (dBm).
2014 *
2015 * @return 0 on Success
2016 */
2017
2018int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
2019 int8_t p1, int8_t p2)
2020{
2021 struct cmd_ds_802_11_pa_cfg cmd;
2022 int ret;
2023
2024 memset(&cmd, 0, sizeof(cmd));
2025 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2026 cmd.action = cpu_to_le16(CMD_ACT_SET);
2027 cmd.enable = !!enable;
2028 cmd.P0 = p0;
2029 cmd.P1 = p1;
2030 cmd.P2 = p2;
2031
2032 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
2033
2034 return ret;
2035}
2036
2037
1974static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, 2038static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1975 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 2039 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1976 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 2040 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 11ac996e895e..336a181d857a 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -26,6 +26,12 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
26 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 26 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
27 unsigned long callback_arg); 27 unsigned long callback_arg);
28 28
29int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
30 int8_t p1, int8_t p2);
31
32int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
33 int8_t p2, int usesnr);
34
29int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, 35int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
30 struct cmd_header *resp); 36 struct cmd_header *resp);
31 37
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 4b2428ac2223..c89d7a1041a8 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -189,6 +189,15 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
189#define MRVDRV_CMD_UPLD_RDY 0x0008 189#define MRVDRV_CMD_UPLD_RDY 0x0008
190#define MRVDRV_CARDEVENT 0x0010 190#define MRVDRV_CARDEVENT 0x0010
191 191
192
193/* Automatic TX control default levels */
194#define POW_ADAPT_DEFAULT_P0 13
195#define POW_ADAPT_DEFAULT_P1 15
196#define POW_ADAPT_DEFAULT_P2 18
197#define TPC_DEFAULT_P0 5
198#define TPC_DEFAULT_P1 10
199#define TPC_DEFAULT_P2 13
200
192/** TxPD status */ 201/** TxPD status */
193 202
194/* Station firmware use TxPD status field to report final Tx transmit 203/* Station firmware use TxPD status field to report final Tx transmit
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index da618fc997ce..a916bb9bd5da 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -83,6 +83,7 @@
83#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067 83#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067
84#define CMD_802_11_SLEEP_PERIOD 0x0068 84#define CMD_802_11_SLEEP_PERIOD 0x0068
85#define CMD_802_11_TPC_CFG 0x0072 85#define CMD_802_11_TPC_CFG 0x0072
86#define CMD_802_11_PA_CFG 0x0073
86#define CMD_802_11_FW_WAKE_METHOD 0x0074 87#define CMD_802_11_FW_WAKE_METHOD 0x0074
87#define CMD_802_11_SUBSCRIBE_EVENT 0x0075 88#define CMD_802_11_SUBSCRIBE_EVENT 0x0075
88#define CMD_802_11_RATE_ADAPT_RATESET 0x0076 89#define CMD_802_11_RATE_ADAPT_RATESET 0x0076
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d27c276b2191..630b79967560 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -607,14 +607,28 @@ struct cmd_ds_802_11_eeprom_access {
607} __attribute__ ((packed)); 607} __attribute__ ((packed));
608 608
609struct cmd_ds_802_11_tpc_cfg { 609struct cmd_ds_802_11_tpc_cfg {
610 struct cmd_header hdr;
611
610 __le16 action; 612 __le16 action;
611 u8 enable; 613 uint8_t enable;
612 s8 P0; 614 int8_t P0;
613 s8 P1; 615 int8_t P1;
614 s8 P2; 616 int8_t P2;
615 u8 usesnr; 617 uint8_t usesnr;
616} __attribute__ ((packed)); 618} __attribute__ ((packed));
617 619
620
621struct cmd_ds_802_11_pa_cfg {
622 struct cmd_header hdr;
623
624 __le16 action;
625 uint8_t enable;
626 int8_t P0;
627 int8_t P1;
628 int8_t P2;
629} __attribute__ ((packed));
630
631
618struct cmd_ds_802_11_led_ctrl { 632struct cmd_ds_802_11_led_ctrl {
619 __le16 action; 633 __le16 action;
620 __le16 numled; 634 __le16 numled;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 2436634b6b7e..73dc8c72402a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1205,7 +1205,13 @@ void lbs_remove_card(struct lbs_private *priv)
1205 cancel_delayed_work_sync(&priv->scan_work); 1205 cancel_delayed_work_sync(&priv->scan_work);
1206 cancel_delayed_work_sync(&priv->assoc_work); 1206 cancel_delayed_work_sync(&priv->assoc_work);
1207 cancel_work_sync(&priv->mcast_work); 1207 cancel_work_sync(&priv->mcast_work);
1208
1209 /* worker thread destruction blocks on the in-flight command which
1210 * should have been cleared already in lbs_stop_card().
1211 */
1212 lbs_deb_main("destroying worker thread\n");
1208 destroy_workqueue(priv->work_thread); 1213 destroy_workqueue(priv->work_thread);
1214 lbs_deb_main("done destroying worker thread\n");
1209 1215
1210 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { 1216 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
1211 priv->psmode = LBS802_11POWERMODECAM; 1217 priv->psmode = LBS802_11POWERMODECAM;
@@ -1323,14 +1329,26 @@ void lbs_stop_card(struct lbs_private *priv)
1323 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1329 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1324 } 1330 }
1325 1331
1326 /* Flush pending command nodes */ 1332 /* Delete the timeout of the currently processing command */
1327 del_timer_sync(&priv->command_timer); 1333 del_timer_sync(&priv->command_timer);
1334
1335 /* Flush pending command nodes */
1328 spin_lock_irqsave(&priv->driver_lock, flags); 1336 spin_lock_irqsave(&priv->driver_lock, flags);
1337 lbs_deb_main("clearing pending commands\n");
1329 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { 1338 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1330 cmdnode->result = -ENOENT; 1339 cmdnode->result = -ENOENT;
1331 cmdnode->cmdwaitqwoken = 1; 1340 cmdnode->cmdwaitqwoken = 1;
1332 wake_up_interruptible(&cmdnode->cmdwait_q); 1341 wake_up_interruptible(&cmdnode->cmdwait_q);
1333 } 1342 }
1343
1344 /* Flush the command the card is currently processing */
1345 if (priv->cur_cmd) {
1346 lbs_deb_main("clearing current command\n");
1347 priv->cur_cmd->result = -ENOENT;
1348 priv->cur_cmd->cmdwaitqwoken = 1;
1349 wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
1350 }
1351 lbs_deb_main("done clearing commands\n");
1334 spin_unlock_irqrestore(&priv->driver_lock, flags); 1352 spin_unlock_irqrestore(&priv->driver_lock, flags);
1335 1353
1336 unregister_netdev(dev); 1354 unregister_netdev(dev);
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 426f1fe3bb42..e8cadad2c863 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1820,7 +1820,21 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1820 } 1820 }
1821 1821
1822 if (vwrq->fixed == 0) { 1822 if (vwrq->fixed == 0) {
1823 /* Auto power control */ 1823 /* User requests automatic tx power control, however there are
1824 * many auto tx settings. For now use firmware defaults until
1825 * we come up with a good way to expose these to the user. */
1826 if (priv->fwrelease < 0x09000000) {
1827 ret = lbs_set_power_adapt_cfg(priv, 1,
1828 POW_ADAPT_DEFAULT_P0,
1829 POW_ADAPT_DEFAULT_P1,
1830 POW_ADAPT_DEFAULT_P2);
1831 if (ret)
1832 goto out;
1833 }
1834 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1835 TPC_DEFAULT_P2, 1);
1836 if (ret)
1837 goto out;
1824 dbm = priv->txpower_max; 1838 dbm = priv->txpower_max;
1825 } else { 1839 } else {
1826 /* Userspace check in iwrange if it should use dBm or mW, 1840 /* Userspace check in iwrange if it should use dBm or mW,
@@ -1830,7 +1844,8 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1830 goto out; 1844 goto out;
1831 } 1845 }
1832 1846
1833 /* Validate requested power level against firmware allowed levels */ 1847 /* Validate requested power level against firmware allowed
1848 * levels */
1834 if (priv->txpower_min && (dbm < priv->txpower_min)) { 1849 if (priv->txpower_min && (dbm < priv->txpower_min)) {
1835 ret = -EINVAL; 1850 ret = -EINVAL;
1836 goto out; 1851 goto out;
@@ -1840,6 +1855,18 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1840 ret = -EINVAL; 1855 ret = -EINVAL;
1841 goto out; 1856 goto out;
1842 } 1857 }
1858 if (priv->fwrelease < 0x09000000) {
1859 ret = lbs_set_power_adapt_cfg(priv, 0,
1860 POW_ADAPT_DEFAULT_P0,
1861 POW_ADAPT_DEFAULT_P1,
1862 POW_ADAPT_DEFAULT_P2);
1863 if (ret)
1864 goto out;
1865 }
1866 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1867 TPC_DEFAULT_P2, 1);
1868 if (ret)
1869 goto out;
1843 } 1870 }
1844 1871
1845 /* If the radio was off, turn it on */ 1872 /* If the radio was off, turn it on */
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 98d4f8e7d84d..1d0704fe146f 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -80,6 +80,7 @@ struct p54_common {
80 struct pda_channel_output_limit *output_limit; 80 struct pda_channel_output_limit *output_limit;
81 unsigned int output_limit_len; 81 unsigned int output_limit_len;
82 struct pda_pa_curve_data *curve_data; 82 struct pda_pa_curve_data *curve_data;
83 unsigned int filter_flags;
83 u16 rxhw; 84 u16 rxhw;
84 u8 version; 85 u8 version;
85 u8 rx_antenna; 86 u8 rx_antenna;
@@ -87,7 +88,15 @@ struct p54_common {
87 void *cached_vdcf; 88 void *cached_vdcf;
88 unsigned int fw_var; 89 unsigned int fw_var;
89 unsigned int fw_interface; 90 unsigned int fw_interface;
91 unsigned int output_power;
92 u32 tsf_low32;
93 u32 tsf_high32;
90 struct ieee80211_tx_queue_stats tx_stats[8]; 94 struct ieee80211_tx_queue_stats tx_stats[8];
95 struct ieee80211_low_level_stats stats;
96 struct timer_list stats_timer;
97 struct completion stats_comp;
98 void *cached_stats;
99 int noise;
91 void *eeprom; 100 void *eeprom;
92 struct completion eeprom_comp; 101 struct completion eeprom_comp;
93}; 102};
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index f96f7c7e6af5..da51786254dc 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Softmac Prism54 common code");
27MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
28MODULE_ALIAS("prism54common"); 28MODULE_ALIAS("prism54common");
29 29
30static struct ieee80211_rate p54_rates[] = { 30static struct ieee80211_rate p54_bgrates[] = {
31 { .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 31 { .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
32 { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 32 { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
33 { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 33 { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
@@ -42,7 +42,7 @@ static struct ieee80211_rate p54_rates[] = {
42 { .bitrate = 540, .hw_value = 11, }, 42 { .bitrate = 540, .hw_value = 11, },
43}; 43};
44 44
45static struct ieee80211_channel p54_channels[] = { 45static struct ieee80211_channel p54_bgchannels[] = {
46 { .center_freq = 2412, .hw_value = 1, }, 46 { .center_freq = 2412, .hw_value = 1, },
47 { .center_freq = 2417, .hw_value = 2, }, 47 { .center_freq = 2417, .hw_value = 2, },
48 { .center_freq = 2422, .hw_value = 3, }, 48 { .center_freq = 2422, .hw_value = 3, },
@@ -60,10 +60,66 @@ static struct ieee80211_channel p54_channels[] = {
60}; 60};
61 61
62static struct ieee80211_supported_band band_2GHz = { 62static struct ieee80211_supported_band band_2GHz = {
63 .channels = p54_channels, 63 .channels = p54_bgchannels,
64 .n_channels = ARRAY_SIZE(p54_channels), 64 .n_channels = ARRAY_SIZE(p54_bgchannels),
65 .bitrates = p54_rates, 65 .bitrates = p54_bgrates,
66 .n_bitrates = ARRAY_SIZE(p54_rates), 66 .n_bitrates = ARRAY_SIZE(p54_bgrates),
67};
68
69static struct ieee80211_rate p54_arates[] = {
70 { .bitrate = 60, .hw_value = 4, },
71 { .bitrate = 90, .hw_value = 5, },
72 { .bitrate = 120, .hw_value = 6, },
73 { .bitrate = 180, .hw_value = 7, },
74 { .bitrate = 240, .hw_value = 8, },
75 { .bitrate = 360, .hw_value = 9, },
76 { .bitrate = 480, .hw_value = 10, },
77 { .bitrate = 540, .hw_value = 11, },
78};
79
80static struct ieee80211_channel p54_achannels[] = {
81 { .center_freq = 4920 },
82 { .center_freq = 4940 },
83 { .center_freq = 4960 },
84 { .center_freq = 4980 },
85 { .center_freq = 5040 },
86 { .center_freq = 5060 },
87 { .center_freq = 5080 },
88 { .center_freq = 5170 },
89 { .center_freq = 5180 },
90 { .center_freq = 5190 },
91 { .center_freq = 5200 },
92 { .center_freq = 5210 },
93 { .center_freq = 5220 },
94 { .center_freq = 5230 },
95 { .center_freq = 5240 },
96 { .center_freq = 5260 },
97 { .center_freq = 5280 },
98 { .center_freq = 5300 },
99 { .center_freq = 5320 },
100 { .center_freq = 5500 },
101 { .center_freq = 5520 },
102 { .center_freq = 5540 },
103 { .center_freq = 5560 },
104 { .center_freq = 5580 },
105 { .center_freq = 5600 },
106 { .center_freq = 5620 },
107 { .center_freq = 5640 },
108 { .center_freq = 5660 },
109 { .center_freq = 5680 },
110 { .center_freq = 5700 },
111 { .center_freq = 5745 },
112 { .center_freq = 5765 },
113 { .center_freq = 5785 },
114 { .center_freq = 5805 },
115 { .center_freq = 5825 },
116};
117
118static struct ieee80211_supported_band band_5GHz = {
119 .channels = p54_achannels,
120 .n_channels = ARRAY_SIZE(p54_achannels),
121 .bitrates = p54_arates,
122 .n_bitrates = ARRAY_SIZE(p54_arates),
67}; 123};
68 124
69int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) 125int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
@@ -252,6 +308,7 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
252 308
253const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette", 309const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
254 "Frisbee", "Xbow", "Longbow" }; 310 "Frisbee", "Xbow", "Longbow" };
311static int p54_init_xbow_synth(struct ieee80211_hw *dev);
255 312
256int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) 313int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
257{ 314{
@@ -371,20 +428,20 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
371 } 428 }
372 429
373 switch (priv->rxhw) { 430 switch (priv->rxhw) {
374 case 4: /* XBow */ 431 case 4: /* XBow */
375 case 1: /* Indigo? */ 432 p54_init_xbow_synth(dev);
376 case 2: /* Duette */ 433 case 1: /* Indigo? */
377 /* TODO: 5GHz initialization goes here */ 434 case 2: /* Duette */
378 435 dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
379 case 3: /* Frisbee */ 436 case 3: /* Frisbee */
380 case 5: /* Longbow */ 437 case 5: /* Longbow */
381 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; 438 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
382 break; 439 break;
383 default: 440 default:
384 printk(KERN_ERR "%s: unsupported RF-Chip\n", 441 printk(KERN_ERR "%s: unsupported RF-Chip\n",
385 wiphy_name(dev->wiphy)); 442 wiphy_name(dev->wiphy));
386 err = -EINVAL; 443 err = -EINVAL;
387 goto err; 444 goto err;
388 } 445 }
389 446
390 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { 447 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
@@ -424,21 +481,43 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
424} 481}
425EXPORT_SYMBOL_GPL(p54_parse_eeprom); 482EXPORT_SYMBOL_GPL(p54_parse_eeprom);
426 483
484static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
485{
486 /* TODO: get the rssi_add & rssi_mul data from the eeprom */
487 return ((rssi * 0x83) / 64 - 400) / 4;
488}
489
427static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) 490static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
428{ 491{
492 struct p54_common *priv = dev->priv;
429 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data; 493 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
430 struct ieee80211_rx_status rx_status = {0}; 494 struct ieee80211_rx_status rx_status = {0};
431 u16 freq = le16_to_cpu(hdr->freq); 495 u16 freq = le16_to_cpu(hdr->freq);
432 size_t header_len = sizeof(*hdr); 496 size_t header_len = sizeof(*hdr);
497 u32 tsf32;
433 498
434 rx_status.signal = hdr->rssi; 499 if (!(hdr->magic & cpu_to_le16(0x0001))) {
500 if (priv->filter_flags & FIF_FCSFAIL)
501 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
502 else
503 return 0;
504 }
505
506 rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi);
507 rx_status.noise = priv->noise;
435 /* XX correct? */ 508 /* XX correct? */
436 rx_status.qual = (100 * hdr->rssi) / 127; 509 rx_status.qual = (100 * hdr->rssi) / 127;
437 rx_status.rate_idx = hdr->rate & 0xf; 510 rx_status.rate_idx = hdr->rate & 0xf;
438 rx_status.freq = freq; 511 rx_status.freq = freq;
439 rx_status.band = IEEE80211_BAND_2GHZ; 512 rx_status.band = IEEE80211_BAND_2GHZ;
440 rx_status.antenna = hdr->antenna; 513 rx_status.antenna = hdr->antenna;
441 rx_status.mactime = le64_to_cpu(hdr->timestamp); 514
515 tsf32 = le32_to_cpu(hdr->tsf32);
516 if (tsf32 < priv->tsf_low32)
517 priv->tsf_high32++;
518 rx_status.mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
519 priv->tsf_low32 = tsf32;
520
442 rx_status.flag |= RX_FLAG_TSFT; 521 rx_status.flag |= RX_FLAG_TSFT;
443 522
444 if (hdr->magic & cpu_to_le16(0x4000)) 523 if (hdr->magic & cpu_to_le16(0x4000))
@@ -511,7 +590,8 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
511 info->status.excessive_retries = 1; 590 info->status.excessive_retries = 1;
512 } 591 }
513 info->status.retry_count = payload->retries - 1; 592 info->status.retry_count = payload->retries - 1;
514 info->status.ack_signal = le16_to_cpu(payload->ack_rssi); 593 info->status.ack_signal = p54_rssi_to_dbm(dev,
594 le16_to_cpu(payload->ack_rssi));
515 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); 595 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
516 ieee80211_tx_status_irqsafe(dev, entry); 596 ieee80211_tx_status_irqsafe(dev, entry);
517 goto out; 597 goto out;
@@ -542,6 +622,27 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
542 complete(&priv->eeprom_comp); 622 complete(&priv->eeprom_comp);
543} 623}
544 624
625static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
626{
627 struct p54_common *priv = dev->priv;
628 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
629 struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
630 u32 tsf32 = le32_to_cpu(stats->tsf32);
631
632 if (tsf32 < priv->tsf_low32)
633 priv->tsf_high32++;
634 priv->tsf_low32 = tsf32;
635
636 priv->stats.dot11RTSFailureCount = le32_to_cpu(stats->rts_fail);
637 priv->stats.dot11RTSSuccessCount = le32_to_cpu(stats->rts_success);
638 priv->stats.dot11FCSErrorCount = le32_to_cpu(stats->rx_bad_fcs);
639
640 priv->noise = p54_rssi_to_dbm(dev, le32_to_cpu(stats->noise));
641 complete(&priv->stats_comp);
642
643 mod_timer(&priv->stats_timer, jiffies + 5 * HZ);
644}
645
545static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) 646static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
546{ 647{
547 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; 648 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
@@ -552,6 +653,9 @@ static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
552 break; 653 break;
553 case P54_CONTROL_TYPE_BBP: 654 case P54_CONTROL_TYPE_BBP:
554 break; 655 break;
656 case P54_CONTROL_TYPE_STAT_READBACK:
657 p54_rx_stats(dev, skb);
658 break;
555 case P54_CONTROL_TYPE_EEPROM_READBACK: 659 case P54_CONTROL_TYPE_EEPROM_READBACK:
556 p54_rx_eeprom_readback(dev, skb); 660 p54_rx_eeprom_readback(dev, skb);
557 break; 661 break;
@@ -753,7 +857,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
753 txhdr->hw_queue = skb_get_queue_mapping(skb) + 4; 857 txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
754 txhdr->tx_antenna = (info->antenna_sel_tx == 0) ? 858 txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
755 2 : info->antenna_sel_tx - 1; 859 2 : info->antenna_sel_tx - 1;
756 txhdr->output_power = 0x7f; // HW Maximum 860 txhdr->output_power = priv->output_power;
757 txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 861 txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
758 0 : cts_rate; 862 0 : cts_rate;
759 if (padding) 863 if (padding)
@@ -1021,12 +1125,25 @@ static int p54_start(struct ieee80211_hw *dev)
1021 return -ENOMEM; 1125 return -ENOMEM;
1022 } 1126 }
1023 1127
1128 if (!priv->cached_stats) {
1129 priv->cached_stats = kzalloc(sizeof(struct p54_statistics) +
1130 priv->tx_hdr_len + sizeof(struct p54_control_hdr),
1131 GFP_KERNEL);
1132
1133 if (!priv->cached_stats) {
1134 kfree(priv->cached_vdcf);
1135 priv->cached_vdcf = NULL;
1136 return -ENOMEM;
1137 }
1138 }
1139
1024 err = priv->open(dev); 1140 err = priv->open(dev);
1025 if (!err) 1141 if (!err)
1026 priv->mode = IEEE80211_IF_TYPE_MNTR; 1142 priv->mode = IEEE80211_IF_TYPE_MNTR;
1027 1143
1028 p54_init_vdcf(dev); 1144 p54_init_vdcf(dev);
1029 1145
1146 mod_timer(&priv->stats_timer, jiffies + HZ);
1030 return err; 1147 return err;
1031} 1148}
1032 1149
@@ -1034,9 +1151,12 @@ static void p54_stop(struct ieee80211_hw *dev)
1034{ 1151{
1035 struct p54_common *priv = dev->priv; 1152 struct p54_common *priv = dev->priv;
1036 struct sk_buff *skb; 1153 struct sk_buff *skb;
1154
1155 del_timer(&priv->stats_timer);
1037 while ((skb = skb_dequeue(&priv->tx_queue))) 1156 while ((skb = skb_dequeue(&priv->tx_queue)))
1038 kfree_skb(skb); 1157 kfree_skb(skb);
1039 priv->stop(dev); 1158 priv->stop(dev);
1159 priv->tsf_high32 = priv->tsf_low32 = 0;
1040 priv->mode = IEEE80211_IF_TYPE_INVALID; 1160 priv->mode = IEEE80211_IF_TYPE_INVALID;
1041} 1161}
1042 1162
@@ -1091,6 +1211,7 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
1091 mutex_lock(&priv->conf_mutex); 1211 mutex_lock(&priv->conf_mutex);
1092 priv->rx_antenna = (conf->antenna_sel_rx == 0) ? 1212 priv->rx_antenna = (conf->antenna_sel_rx == 0) ?
1093 2 : conf->antenna_sel_tx - 1; 1213 2 : conf->antenna_sel_tx - 1;
1214 priv->output_power = conf->power_level << 2;
1094 ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq)); 1215 ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
1095 p54_set_vdcf(dev); 1216 p54_set_vdcf(dev);
1096 mutex_unlock(&priv->conf_mutex); 1217 mutex_unlock(&priv->conf_mutex);
@@ -1118,13 +1239,26 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
1118{ 1239{
1119 struct p54_common *priv = dev->priv; 1240 struct p54_common *priv = dev->priv;
1120 1241
1121 *total_flags &= FIF_BCN_PRBRESP_PROMISC; 1242 *total_flags &= FIF_BCN_PRBRESP_PROMISC |
1243 FIF_PROMISC_IN_BSS |
1244 FIF_FCSFAIL;
1245
1246 priv->filter_flags = *total_flags;
1122 1247
1123 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 1248 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
1124 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 1249 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
1125 p54_set_filter(dev, 0, NULL); 1250 p54_set_filter(dev, priv->filter_type, NULL);
1126 else 1251 else
1127 p54_set_filter(dev, 0, priv->bssid); 1252 p54_set_filter(dev, priv->filter_type, priv->bssid);
1253 }
1254
1255 if (changed_flags & FIF_PROMISC_IN_BSS) {
1256 if (*total_flags & FIF_PROMISC_IN_BSS)
1257 p54_set_filter(dev, priv->filter_type |
1258 cpu_to_le16(0x8), NULL);
1259 else
1260 p54_set_filter(dev, priv->filter_type &
1261 ~cpu_to_le16(0x8), priv->bssid);
1128 } 1262 }
1129} 1263}
1130 1264
@@ -1148,10 +1282,67 @@ static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
1148 return 0; 1282 return 0;
1149} 1283}
1150 1284
1285static int p54_init_xbow_synth(struct ieee80211_hw *dev)
1286{
1287 struct p54_common *priv = dev->priv;
1288 struct p54_control_hdr *hdr;
1289 struct p54_tx_control_xbow_synth *xbow;
1290
1291 hdr = kzalloc(sizeof(*hdr) + sizeof(*xbow) +
1292 priv->tx_hdr_len, GFP_KERNEL);
1293 if (!hdr)
1294 return -ENOMEM;
1295
1296 hdr = (void *)hdr + priv->tx_hdr_len;
1297 hdr->magic1 = cpu_to_le16(0x8001);
1298 hdr->len = cpu_to_le16(sizeof(*xbow));
1299 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_XBOW_SYNTH_CFG);
1300 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*xbow));
1301
1302 xbow = (struct p54_tx_control_xbow_synth *) hdr->data;
1303 xbow->magic1 = cpu_to_le16(0x1);
1304 xbow->magic2 = cpu_to_le16(0x2);
1305 xbow->freq = cpu_to_le16(5390);
1306
1307 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*xbow), 1);
1308
1309 return 0;
1310}
1311
1312static void p54_statistics_timer(unsigned long data)
1313{
1314 struct ieee80211_hw *dev = (struct ieee80211_hw *) data;
1315 struct p54_common *priv = dev->priv;
1316 struct p54_control_hdr *hdr;
1317 struct p54_statistics *stats;
1318
1319 BUG_ON(!priv->cached_stats);
1320
1321 hdr = (void *)priv->cached_stats + priv->tx_hdr_len;
1322 hdr->magic1 = cpu_to_le16(0x8000);
1323 hdr->len = cpu_to_le16(sizeof(*stats));
1324 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_STAT_READBACK);
1325 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*stats));
1326
1327 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*stats), 0);
1328}
1329
1151static int p54_get_stats(struct ieee80211_hw *dev, 1330static int p54_get_stats(struct ieee80211_hw *dev,
1152 struct ieee80211_low_level_stats *stats) 1331 struct ieee80211_low_level_stats *stats)
1153{ 1332{
1154 /* TODO */ 1333 struct p54_common *priv = dev->priv;
1334
1335 del_timer(&priv->stats_timer);
1336 p54_statistics_timer((unsigned long)dev);
1337
1338 if (!wait_for_completion_interruptible_timeout(&priv->stats_comp, HZ)) {
1339 printk(KERN_ERR "%s: device does not respond!\n",
1340 wiphy_name(dev->wiphy));
1341 return -EBUSY;
1342 }
1343
1344 memcpy(stats, &priv->stats, sizeof(*stats));
1345
1155 return 0; 1346 return 0;
1156} 1347}
1157 1348
@@ -1193,12 +1384,12 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1193 skb_queue_head_init(&priv->tx_queue); 1384 skb_queue_head_init(&priv->tx_queue);
1194 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ 1385 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
1195 IEEE80211_HW_RX_INCLUDES_FCS | 1386 IEEE80211_HW_RX_INCLUDES_FCS |
1196 IEEE80211_HW_SIGNAL_UNSPEC; 1387 IEEE80211_HW_SIGNAL_DBM |
1388 IEEE80211_HW_NOISE_DBM;
1197 1389
1198 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1390 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1199 1391
1200 dev->channel_change_time = 1000; /* TODO: find actual value */ 1392 dev->channel_change_time = 1000; /* TODO: find actual value */
1201 dev->max_signal = 127;
1202 1393
1203 priv->tx_stats[0].limit = 1; 1394 priv->tx_stats[0].limit = 1;
1204 priv->tx_stats[1].limit = 1; 1395 priv->tx_stats[1].limit = 1;
@@ -1206,11 +1397,15 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1206 priv->tx_stats[3].limit = 1; 1397 priv->tx_stats[3].limit = 1;
1207 priv->tx_stats[4].limit = 5; 1398 priv->tx_stats[4].limit = 5;
1208 dev->queues = 1; 1399 dev->queues = 1;
1400 priv->noise = -94;
1209 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + 1401 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
1210 sizeof(struct p54_tx_control_allocdata); 1402 sizeof(struct p54_tx_control_allocdata);
1211 1403
1212 mutex_init(&priv->conf_mutex); 1404 mutex_init(&priv->conf_mutex);
1213 init_completion(&priv->eeprom_comp); 1405 init_completion(&priv->eeprom_comp);
1406 init_completion(&priv->stats_comp);
1407 setup_timer(&priv->stats_timer, p54_statistics_timer,
1408 (unsigned long)dev);
1214 1409
1215 return dev; 1410 return dev;
1216} 1411}
@@ -1219,6 +1414,7 @@ EXPORT_SYMBOL_GPL(p54_init_common);
1219void p54_free_common(struct ieee80211_hw *dev) 1414void p54_free_common(struct ieee80211_hw *dev)
1220{ 1415{
1221 struct p54_common *priv = dev->priv; 1416 struct p54_common *priv = dev->priv;
1417 kfree(priv->cached_stats);
1222 kfree(priv->iq_autocal); 1418 kfree(priv->iq_autocal);
1223 kfree(priv->output_limit); 1419 kfree(priv->output_limit);
1224 kfree(priv->curve_data); 1420 kfree(priv->curve_data);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 73a9a2c923dd..4da736c789ac 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -185,7 +185,8 @@ struct p54_rx_hdr {
185 u8 rssi; 185 u8 rssi;
186 u8 quality; 186 u8 quality;
187 u16 unknown2; 187 u16 unknown2;
188 __le64 timestamp; 188 __le32 tsf32;
189 __le32 unalloc0;
189 u8 align[0]; 190 u8 align[0];
190} __attribute__ ((packed)); 191} __attribute__ ((packed));
191 192
@@ -300,4 +301,24 @@ struct p54_tx_control_vdcf {
300 __le16 frameburst; 301 __le16 frameburst;
301} __attribute__ ((packed)); 302} __attribute__ ((packed));
302 303
304struct p54_statistics {
305 __le32 rx_success;
306 __le32 rx_bad_fcs;
307 __le32 rx_abort;
308 __le32 rx_abort_phy;
309 __le32 rts_success;
310 __le32 rts_fail;
311 __le32 tsf32;
312 __le32 airtime;
313 __le32 noise;
314 __le32 unkn[10]; /* CCE / CCA / RADAR */
315} __attribute__ ((packed));
316
317struct p54_tx_control_xbow_synth {
318 __le16 magic1;
319 __le16 magic2;
320 __le16 freq;
321 u32 padding[5];
322} __attribute__ ((packed));
323
303#endif /* P54COMMON_H */ 324#endif /* P54COMMON_H */
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 11f590d63aff..b686dc45483e 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -40,11 +40,15 @@ config RT2X00_LIB_CRYPTO
40config RT2X00_LIB_RFKILL 40config RT2X00_LIB_RFKILL
41 boolean 41 boolean
42 depends on RT2X00_LIB 42 depends on RT2X00_LIB
43 select RFKILL 43 depends on RFKILL
44 default y
44 45
45config RT2X00_LIB_LEDS 46config RT2X00_LIB_LEDS
46 boolean 47 boolean
47 depends on RT2X00_LIB && NEW_LEDS 48 depends on RT2X00_LIB
49 depends on NEW_LEDS
50 depends on LEDS_CLASS
51 default y
48 52
49config RT2400PCI 53config RT2400PCI
50 tristate "Ralink rt2400 (PCI/PCMCIA) support" 54 tristate "Ralink rt2400 (PCI/PCMCIA) support"
@@ -57,23 +61,6 @@ config RT2400PCI
57 61
58 When compiled as a module, this driver will be called "rt2400pci.ko". 62 When compiled as a module, this driver will be called "rt2400pci.ko".
59 63
60config RT2400PCI_RFKILL
61 bool "Ralink rt2400 rfkill support"
62 depends on RT2400PCI
63 select RT2X00_LIB_RFKILL
64 ---help---
65 This adds support for integrated rt2400 hardware that features a
66 hardware button to control the radio state.
67 This feature depends on the RF switch subsystem rfkill.
68
69config RT2400PCI_LEDS
70 bool "Ralink rt2400 leds support"
71 depends on RT2400PCI && NEW_LEDS
72 select LEDS_CLASS
73 select RT2X00_LIB_LEDS
74 ---help---
75 This adds support for led triggers provided my mac80211.
76
77config RT2500PCI 64config RT2500PCI
78 tristate "Ralink rt2500 (PCI/PCMCIA) support" 65 tristate "Ralink rt2500 (PCI/PCMCIA) support"
79 depends on PCI 66 depends on PCI
@@ -85,23 +72,6 @@ config RT2500PCI
85 72
86 When compiled as a module, this driver will be called "rt2500pci.ko". 73 When compiled as a module, this driver will be called "rt2500pci.ko".
87 74
88config RT2500PCI_RFKILL
89 bool "Ralink rt2500 rfkill support"
90 depends on RT2500PCI
91 select RT2X00_LIB_RFKILL
92 ---help---
93 This adds support for integrated rt2500 hardware that features a
94 hardware button to control the radio state.
95 This feature depends on the RF switch subsystem rfkill.
96
97config RT2500PCI_LEDS
98 bool "Ralink rt2500 leds support"
99 depends on RT2500PCI && NEW_LEDS
100 select LEDS_CLASS
101 select RT2X00_LIB_LEDS
102 ---help---
103 This adds support for led triggers provided my mac80211.
104
105config RT61PCI 75config RT61PCI
106 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" 76 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
107 depends on PCI 77 depends on PCI
@@ -116,23 +86,6 @@ config RT61PCI
116 86
117 When compiled as a module, this driver will be called "rt61pci.ko". 87 When compiled as a module, this driver will be called "rt61pci.ko".
118 88
119config RT61PCI_RFKILL
120 bool "Ralink rt2501/rt61 rfkill support"
121 depends on RT61PCI
122 select RT2X00_LIB_RFKILL
123 ---help---
124 This adds support for integrated rt61 hardware that features a
125 hardware button to control the radio state.
126 This feature depends on the RF switch subsystem rfkill.
127
128config RT61PCI_LEDS
129 bool "Ralink rt2501/rt61 leds support"
130 depends on RT61PCI && NEW_LEDS
131 select LEDS_CLASS
132 select RT2X00_LIB_LEDS
133 ---help---
134 This adds support for led triggers provided my mac80211.
135
136config RT2500USB 89config RT2500USB
137 tristate "Ralink rt2500 (USB) support" 90 tristate "Ralink rt2500 (USB) support"
138 depends on USB 91 depends on USB
@@ -143,14 +96,6 @@ config RT2500USB
143 96
144 When compiled as a module, this driver will be called "rt2500usb.ko". 97 When compiled as a module, this driver will be called "rt2500usb.ko".
145 98
146config RT2500USB_LEDS
147 bool "Ralink rt2500 leds support"
148 depends on RT2500USB && NEW_LEDS
149 select LEDS_CLASS
150 select RT2X00_LIB_LEDS
151 ---help---
152 This adds support for led triggers provided my mac80211.
153
154config RT73USB 99config RT73USB
155 tristate "Ralink rt2501/rt73 (USB) support" 100 tristate "Ralink rt2501/rt73 (USB) support"
156 depends on USB 101 depends on USB
@@ -164,14 +109,6 @@ config RT73USB
164 109
165 When compiled as a module, this driver will be called "rt73usb.ko". 110 When compiled as a module, this driver will be called "rt73usb.ko".
166 111
167config RT73USB_LEDS
168 bool "Ralink rt2501/rt73 leds support"
169 depends on RT73USB && NEW_LEDS
170 select LEDS_CLASS
171 select RT2X00_LIB_LEDS
172 ---help---
173 This adds support for led triggers provided my mac80211.
174
175config RT2X00_LIB_DEBUGFS 112config RT2X00_LIB_DEBUGFS
176 bool "Ralink debugfs support" 113 bool "Ralink debugfs support"
177 depends on RT2X00_LIB && MAC80211_DEBUGFS 114 depends on RT2X00_LIB && MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 18b703c3fc2c..08cb9eec16a6 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -231,7 +231,7 @@ static const struct rt2x00debug rt2400pci_rt2x00debug = {
231}; 231};
232#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 232#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
233 233
234#ifdef CONFIG_RT2400PCI_RFKILL 234#ifdef CONFIG_RT2X00_LIB_RFKILL
235static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) 235static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
236{ 236{
237 u32 reg; 237 u32 reg;
@@ -241,9 +241,9 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
241} 241}
242#else 242#else
243#define rt2400pci_rfkill_poll NULL 243#define rt2400pci_rfkill_poll NULL
244#endif /* CONFIG_RT2400PCI_RFKILL */ 244#endif /* CONFIG_RT2X00_LIB_RFKILL */
245 245
246#ifdef CONFIG_RT2400PCI_LEDS 246#ifdef CONFIG_RT2X00_LIB_LEDS
247static void rt2400pci_brightness_set(struct led_classdev *led_cdev, 247static void rt2400pci_brightness_set(struct led_classdev *led_cdev,
248 enum led_brightness brightness) 248 enum led_brightness brightness)
249{ 249{
@@ -288,7 +288,7 @@ static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
288 led->led_dev.blink_set = rt2400pci_blink_set; 288 led->led_dev.blink_set = rt2400pci_blink_set;
289 led->flags = LED_INITIALIZED; 289 led->flags = LED_INITIALIZED;
290} 290}
291#endif /* CONFIG_RT2400PCI_LEDS */ 291#endif /* CONFIG_RT2X00_LIB_LEDS */
292 292
293/* 293/*
294 * Configuration handlers. 294 * Configuration handlers.
@@ -1374,22 +1374,22 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1374 /* 1374 /*
1375 * Store led mode, for correct led behaviour. 1375 * Store led mode, for correct led behaviour.
1376 */ 1376 */
1377#ifdef CONFIG_RT2400PCI_LEDS 1377#ifdef CONFIG_RT2X00_LIB_LEDS
1378 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1378 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1379 1379
1380 rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); 1380 rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
1381 if (value == LED_MODE_TXRX_ACTIVITY) 1381 if (value == LED_MODE_TXRX_ACTIVITY)
1382 rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual, 1382 rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
1383 LED_TYPE_ACTIVITY); 1383 LED_TYPE_ACTIVITY);
1384#endif /* CONFIG_RT2400PCI_LEDS */ 1384#endif /* CONFIG_RT2X00_LIB_LEDS */
1385 1385
1386 /* 1386 /*
1387 * Detect if this device has an hardware controlled radio. 1387 * Detect if this device has an hardware controlled radio.
1388 */ 1388 */
1389#ifdef CONFIG_RT2400PCI_RFKILL 1389#ifdef CONFIG_RT2X00_LIB_RFKILL
1390 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) 1390 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
1391 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); 1391 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
1392#endif /* CONFIG_RT2400PCI_RFKILL */ 1392#endif /* CONFIG_RT2X00_LIB_RFKILL */
1393 1393
1394 /* 1394 /*
1395 * Check if the BBP tuning should be enabled. 1395 * Check if the BBP tuning should be enabled.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 2a96a011f2ad..ef42cc04a2d7 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -231,7 +231,7 @@ static const struct rt2x00debug rt2500pci_rt2x00debug = {
231}; 231};
232#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 232#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
233 233
234#ifdef CONFIG_RT2500PCI_RFKILL 234#ifdef CONFIG_RT2X00_LIB_RFKILL
235static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) 235static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
236{ 236{
237 u32 reg; 237 u32 reg;
@@ -241,9 +241,9 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
241} 241}
242#else 242#else
243#define rt2500pci_rfkill_poll NULL 243#define rt2500pci_rfkill_poll NULL
244#endif /* CONFIG_RT2500PCI_RFKILL */ 244#endif /* CONFIG_RT2X00_LIB_RFKILL */
245 245
246#ifdef CONFIG_RT2500PCI_LEDS 246#ifdef CONFIG_RT2X00_LIB_LEDS
247static void rt2500pci_brightness_set(struct led_classdev *led_cdev, 247static void rt2500pci_brightness_set(struct led_classdev *led_cdev,
248 enum led_brightness brightness) 248 enum led_brightness brightness)
249{ 249{
@@ -288,7 +288,7 @@ static void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev,
288 led->led_dev.blink_set = rt2500pci_blink_set; 288 led->led_dev.blink_set = rt2500pci_blink_set;
289 led->flags = LED_INITIALIZED; 289 led->flags = LED_INITIALIZED;
290} 290}
291#endif /* CONFIG_RT2500PCI_LEDS */ 291#endif /* CONFIG_RT2X00_LIB_LEDS */
292 292
293/* 293/*
294 * Configuration handlers. 294 * Configuration handlers.
@@ -1533,22 +1533,22 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1533 /* 1533 /*
1534 * Store led mode, for correct led behaviour. 1534 * Store led mode, for correct led behaviour.
1535 */ 1535 */
1536#ifdef CONFIG_RT2500PCI_LEDS 1536#ifdef CONFIG_RT2X00_LIB_LEDS
1537 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1537 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1538 1538
1539 rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); 1539 rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
1540 if (value == LED_MODE_TXRX_ACTIVITY) 1540 if (value == LED_MODE_TXRX_ACTIVITY)
1541 rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, 1541 rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
1542 LED_TYPE_ACTIVITY); 1542 LED_TYPE_ACTIVITY);
1543#endif /* CONFIG_RT2500PCI_LEDS */ 1543#endif /* CONFIG_RT2X00_LIB_LEDS */
1544 1544
1545 /* 1545 /*
1546 * Detect if this device has an hardware controlled radio. 1546 * Detect if this device has an hardware controlled radio.
1547 */ 1547 */
1548#ifdef CONFIG_RT2500PCI_RFKILL 1548#ifdef CONFIG_RT2X00_LIB_RFKILL
1549 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) 1549 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
1550 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); 1550 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
1551#endif /* CONFIG_RT2500PCI_RFKILL */ 1551#endif /* CONFIG_RT2X00_LIB_RFKILL */
1552 1552
1553 /* 1553 /*
1554 * Check if the BBP tuning should be enabled. 1554 * Check if the BBP tuning should be enabled.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 0e008b606f70..cb5f2d01a9c3 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -288,7 +288,7 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
288}; 288};
289#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 289#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
290 290
291#ifdef CONFIG_RT2500USB_LEDS 291#ifdef CONFIG_RT2X00_LIB_LEDS
292static void rt2500usb_brightness_set(struct led_classdev *led_cdev, 292static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
293 enum led_brightness brightness) 293 enum led_brightness brightness)
294{ 294{
@@ -333,7 +333,7 @@ static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev,
333 led->led_dev.blink_set = rt2500usb_blink_set; 333 led->led_dev.blink_set = rt2500usb_blink_set;
334 led->flags = LED_INITIALIZED; 334 led->flags = LED_INITIALIZED;
335} 335}
336#endif /* CONFIG_RT2500USB_LEDS */ 336#endif /* CONFIG_RT2X00_LIB_LEDS */
337 337
338/* 338/*
339 * Configuration handlers. 339 * Configuration handlers.
@@ -1133,7 +1133,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1133 int pipe = usb_sndbulkpipe(usb_dev, 1); 1133 int pipe = usb_sndbulkpipe(usb_dev, 1);
1134 int length; 1134 int length;
1135 u16 reg; 1135 u16 reg;
1136 u32 word, len;
1137 1136
1138 /* 1137 /*
1139 * Add the descriptor in front of the skb. 1138 * Add the descriptor in front of the skb.
@@ -1143,17 +1142,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1143 skbdesc->desc = entry->skb->data; 1142 skbdesc->desc = entry->skb->data;
1144 1143
1145 /* 1144 /*
1146 * Adjust the beacon databyte count. The current number is
1147 * calculated before this function gets called, but falsely
1148 * assumes that the descriptor was already present in the SKB.
1149 */
1150 rt2x00_desc_read(skbdesc->desc, 0, &word);
1151 len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);
1152 len += skbdesc->desc_len;
1153 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);
1154 rt2x00_desc_write(skbdesc->desc, 0, word);
1155
1156 /*
1157 * Disable beaconing while we are reloading the beacon data, 1145 * Disable beaconing while we are reloading the beacon data,
1158 * otherwise we might be sending out invalid data. 1146 * otherwise we might be sending out invalid data.
1159 */ 1147 */
@@ -1485,14 +1473,14 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1485 /* 1473 /*
1486 * Store led mode, for correct led behaviour. 1474 * Store led mode, for correct led behaviour.
1487 */ 1475 */
1488#ifdef CONFIG_RT2500USB_LEDS 1476#ifdef CONFIG_RT2X00_LIB_LEDS
1489 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); 1477 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1490 1478
1491 rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); 1479 rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
1492 if (value == LED_MODE_TXRX_ACTIVITY) 1480 if (value == LED_MODE_TXRX_ACTIVITY)
1493 rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual, 1481 rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
1494 LED_TYPE_ACTIVITY); 1482 LED_TYPE_ACTIVITY);
1495#endif /* CONFIG_RT2500USB_LEDS */ 1483#endif /* CONFIG_RT2X00_LIB_LEDS */
1496 1484
1497 /* 1485 /*
1498 * Check if the BBP tuning should be disabled. 1486 * Check if the BBP tuning should be disabled.
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 8a2fefb365b7..55eff58f1889 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -45,16 +45,15 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
45 return 0; 45 return 0;
46 46
47 if (state == RFKILL_STATE_UNBLOCKED) { 47 if (state == RFKILL_STATE_UNBLOCKED) {
48 INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); 48 INFO(rt2x00dev, "RFKILL event: enabling radio.\n");
49 clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); 49 clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
50 retval = rt2x00lib_enable_radio(rt2x00dev); 50 retval = rt2x00lib_enable_radio(rt2x00dev);
51 } else if (state == RFKILL_STATE_SOFT_BLOCKED) { 51 } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
52 INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); 52 INFO(rt2x00dev, "RFKILL event: disabling radio.\n");
53 set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); 53 set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
54 rt2x00lib_disable_radio(rt2x00dev); 54 rt2x00lib_disable_radio(rt2x00dev);
55 } else { 55 } else {
56 WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n", 56 WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state);
57 state);
58 } 57 }
59 58
60 return retval; 59 return retval;
@@ -64,7 +63,12 @@ static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
64{ 63{
65 struct rt2x00_dev *rt2x00dev = data; 64 struct rt2x00_dev *rt2x00dev = data;
66 65
67 *state = rt2x00dev->rfkill->state; 66 /*
67 * rfkill_poll reports 1 when the key has been pressed and the
68 * radio should be blocked.
69 */
70 *state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
71 RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
68 72
69 return 0; 73 return 0;
70} 74}
@@ -73,19 +77,18 @@ static void rt2x00rfkill_poll(struct work_struct *work)
73{ 77{
74 struct rt2x00_dev *rt2x00dev = 78 struct rt2x00_dev *rt2x00dev =
75 container_of(work, struct rt2x00_dev, rfkill_work.work); 79 container_of(work, struct rt2x00_dev, rfkill_work.work);
76 int state; 80 enum rfkill_state state;
77 81
78 if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) 82 if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) ||
83 !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
79 return; 84 return;
80 85
81 /* 86 /*
82 * rfkill_poll reports 1 when the key has been pressed and the 87 * Poll latest state and report it to rfkill who should sort
83 * radio should be blocked. 88 * out if the state should be toggled or not.
84 */ 89 */
85 state = !rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ? 90 if (!rt2x00rfkill_get_state(rt2x00dev, &state))
86 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 91 rfkill_force_state(rt2x00dev->rfkill, state);
87
88 rfkill_force_state(rt2x00dev->rfkill, state);
89 92
90 queue_delayed_work(rt2x00dev->hw->workqueue, 93 queue_delayed_work(rt2x00dev->hw->workqueue,
91 &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL); 94 &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
@@ -93,8 +96,8 @@ static void rt2x00rfkill_poll(struct work_struct *work)
93 96
94void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) 97void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
95{ 98{
96 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || 99 if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
97 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) 100 test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
98 return; 101 return;
99 102
100 if (rfkill_register(rt2x00dev->rfkill)) { 103 if (rfkill_register(rt2x00dev->rfkill)) {
@@ -114,7 +117,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
114 117
115void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) 118void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
116{ 119{
117 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || 120 if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
118 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) 121 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
119 return; 122 return;
120 123
@@ -127,21 +130,25 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
127 130
128void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) 131void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
129{ 132{
130 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) 133 struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
134
135 if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
131 return; 136 return;
132 137
133 rt2x00dev->rfkill = 138 rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
134 rfkill_allocate(wiphy_dev(rt2x00dev->hw->wiphy), RFKILL_TYPE_WLAN);
135 if (!rt2x00dev->rfkill) { 139 if (!rt2x00dev->rfkill) {
136 ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); 140 ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
137 return; 141 return;
138 } 142 }
139 143
144 __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
145
140 rt2x00dev->rfkill->name = rt2x00dev->ops->name; 146 rt2x00dev->rfkill->name = rt2x00dev->ops->name;
141 rt2x00dev->rfkill->data = rt2x00dev; 147 rt2x00dev->rfkill->data = rt2x00dev;
142 rt2x00dev->rfkill->state = -1; 148 rt2x00dev->rfkill->state = -1;
143 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; 149 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
144 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state; 150 if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
151 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
145 152
146 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll); 153 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
147 154
@@ -150,8 +157,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
150 157
151void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) 158void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
152{ 159{
153 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || 160 if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags))
154 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
155 return; 161 return;
156 162
157 cancel_delayed_work_sync(&rt2x00dev->rfkill_work); 163 cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index d740f560ccd0..2c36b91ff4c7 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -163,7 +163,7 @@ rf_write:
163 rt2x00_rf_write(rt2x00dev, word, value); 163 rt2x00_rf_write(rt2x00dev, word, value);
164} 164}
165 165
166#ifdef CONFIG_RT61PCI_LEDS 166#ifdef CONFIG_RT2X00_LIB_LEDS
167/* 167/*
168 * This function is only called from rt61pci_led_brightness() 168 * This function is only called from rt61pci_led_brightness()
169 * make gcc happy by placing this function inside the 169 * make gcc happy by placing this function inside the
@@ -195,7 +195,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
195 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1); 195 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
196 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); 196 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
197} 197}
198#endif /* CONFIG_RT61PCI_LEDS */ 198#endif /* CONFIG_RT2X00_LIB_LEDS */
199 199
200static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 200static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
201{ 201{
@@ -271,7 +271,7 @@ static const struct rt2x00debug rt61pci_rt2x00debug = {
271}; 271};
272#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 272#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
273 273
274#ifdef CONFIG_RT61PCI_RFKILL 274#ifdef CONFIG_RT2X00_LIB_RFKILL
275static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) 275static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
276{ 276{
277 u32 reg; 277 u32 reg;
@@ -281,9 +281,9 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
281} 281}
282#else 282#else
283#define rt61pci_rfkill_poll NULL 283#define rt61pci_rfkill_poll NULL
284#endif /* CONFIG_RT61PCI_RFKILL */ 284#endif /* CONFIG_RT2X00_LIB_RFKILL */
285 285
286#ifdef CONFIG_RT61PCI_LEDS 286#ifdef CONFIG_RT2X00_LIB_LEDS
287static void rt61pci_brightness_set(struct led_classdev *led_cdev, 287static void rt61pci_brightness_set(struct led_classdev *led_cdev,
288 enum led_brightness brightness) 288 enum led_brightness brightness)
289{ 289{
@@ -348,7 +348,7 @@ static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev,
348 led->led_dev.blink_set = rt61pci_blink_set; 348 led->led_dev.blink_set = rt61pci_blink_set;
349 led->flags = LED_INITIALIZED; 349 led->flags = LED_INITIALIZED;
350} 350}
351#endif /* CONFIG_RT61PCI_LEDS */ 351#endif /* CONFIG_RT2X00_LIB_LEDS */
352 352
353/* 353/*
354 * Configuration handlers. 354 * Configuration handlers.
@@ -2313,10 +2313,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2313 /* 2313 /*
2314 * Detect if this device has an hardware controlled radio. 2314 * Detect if this device has an hardware controlled radio.
2315 */ 2315 */
2316#ifdef CONFIG_RT61PCI_RFKILL 2316#ifdef CONFIG_RT2X00_LIB_RFKILL
2317 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) 2317 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
2318 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); 2318 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
2319#endif /* CONFIG_RT61PCI_RFKILL */ 2319#endif /* CONFIG_RT2X00_LIB_RFKILL */
2320 2320
2321 /* 2321 /*
2322 * Read frequency offset and RF programming sequence. 2322 * Read frequency offset and RF programming sequence.
@@ -2374,7 +2374,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2374 * If the eeprom value is invalid, 2374 * If the eeprom value is invalid,
2375 * switch to default led mode. 2375 * switch to default led mode.
2376 */ 2376 */
2377#ifdef CONFIG_RT61PCI_LEDS 2377#ifdef CONFIG_RT2X00_LIB_LEDS
2378 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 2378 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
2379 value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); 2379 value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE);
2380 2380
@@ -2408,7 +2408,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2408 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, 2408 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A,
2409 rt2x00_get_field16(eeprom, 2409 rt2x00_get_field16(eeprom,
2410 EEPROM_LED_POLARITY_RDY_A)); 2410 EEPROM_LED_POLARITY_RDY_A));
2411#endif /* CONFIG_RT61PCI_LEDS */ 2411#endif /* CONFIG_RT2X00_LIB_LEDS */
2412 2412
2413 return 0; 2413 return 0;
2414} 2414}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e698ae0efbce..27dde3e34603 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -292,7 +292,7 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
292}; 292};
293#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 293#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
294 294
295#ifdef CONFIG_RT73USB_LEDS 295#ifdef CONFIG_RT2X00_LIB_LEDS
296static void rt73usb_brightness_set(struct led_classdev *led_cdev, 296static void rt73usb_brightness_set(struct led_classdev *led_cdev,
297 enum led_brightness brightness) 297 enum led_brightness brightness)
298{ 298{
@@ -359,7 +359,7 @@ static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev,
359 led->led_dev.blink_set = rt73usb_blink_set; 359 led->led_dev.blink_set = rt73usb_blink_set;
360 led->flags = LED_INITIALIZED; 360 led->flags = LED_INITIALIZED;
361} 361}
362#endif /* CONFIG_RT73USB_LEDS */ 362#endif /* CONFIG_RT2X00_LIB_LEDS */
363 363
364/* 364/*
365 * Configuration handlers. 365 * Configuration handlers.
@@ -1572,7 +1572,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1572 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 1572 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1573 unsigned int beacon_base; 1573 unsigned int beacon_base;
1574 u32 reg; 1574 u32 reg;
1575 u32 word, len;
1576 1575
1577 /* 1576 /*
1578 * Add the descriptor in front of the skb. 1577 * Add the descriptor in front of the skb.
@@ -1582,17 +1581,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1582 skbdesc->desc = entry->skb->data; 1581 skbdesc->desc = entry->skb->data;
1583 1582
1584 /* 1583 /*
1585 * Adjust the beacon databyte count. The current number is
1586 * calculated before this function gets called, but falsely
1587 * assumes that the descriptor was already present in the SKB.
1588 */
1589 rt2x00_desc_read(skbdesc->desc, 0, &word);
1590 len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);
1591 len += skbdesc->desc_len;
1592 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);
1593 rt2x00_desc_write(skbdesc->desc, 0, word);
1594
1595 /*
1596 * Disable beaconing while we are reloading the beacon data, 1584 * Disable beaconing while we are reloading the beacon data,
1597 * otherwise we might be sending out invalid data. 1585 * otherwise we might be sending out invalid data.
1598 */ 1586 */
@@ -1944,7 +1932,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1944 /* 1932 /*
1945 * Store led settings, for correct led behaviour. 1933 * Store led settings, for correct led behaviour.
1946 */ 1934 */
1947#ifdef CONFIG_RT73USB_LEDS 1935#ifdef CONFIG_RT2X00_LIB_LEDS
1948 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); 1936 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
1949 1937
1950 rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); 1938 rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
@@ -1977,7 +1965,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1977 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, 1965 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A,
1978 rt2x00_get_field16(eeprom, 1966 rt2x00_get_field16(eeprom,
1979 EEPROM_LED_POLARITY_RDY_A)); 1967 EEPROM_LED_POLARITY_RDY_A));
1980#endif /* CONFIG_RT73USB_LEDS */ 1968#endif /* CONFIG_RT2X00_LIB_LEDS */
1981 1969
1982 return 0; 1970 return 0;
1983} 1971}
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index be456450cd2e..abc1abc63bf0 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -643,6 +643,9 @@ struct ieee80211_mgmt {
643 } u; 643 } u;
644} __attribute__ ((packed)); 644} __attribute__ ((packed));
645 645
646/* mgmt header + 1 byte category code */
647#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
648
646 649
647/* Control frames */ 650/* Control frames */
648struct ieee80211_rts { 651struct ieee80211_rts {
@@ -708,7 +711,7 @@ struct ieee80211_ht_addt_info {
708 711
709/* 802.11n HT capabilities masks */ 712/* 802.11n HT capabilities masks */
710#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 713#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002
711#define IEEE80211_HT_CAP_MIMO_PS 0x000C 714#define IEEE80211_HT_CAP_SM_PS 0x000C
712#define IEEE80211_HT_CAP_GRN_FLD 0x0010 715#define IEEE80211_HT_CAP_GRN_FLD 0x0010
713#define IEEE80211_HT_CAP_SGI_20 0x0020 716#define IEEE80211_HT_CAP_SGI_20 0x0020
714#define IEEE80211_HT_CAP_SGI_40 0x0040 717#define IEEE80211_HT_CAP_SGI_40 0x0040
@@ -737,11 +740,26 @@ struct ieee80211_ht_addt_info {
737#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 740#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
738#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 741#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010
739 742
740/* MIMO Power Save Modes */ 743/* block-ack parameters */
741#define WLAN_HT_CAP_MIMO_PS_STATIC 0 744#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
742#define WLAN_HT_CAP_MIMO_PS_DYNAMIC 1 745#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
743#define WLAN_HT_CAP_MIMO_PS_INVALID 2 746#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
744#define WLAN_HT_CAP_MIMO_PS_DISABLED 3 747#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
748#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
749
750/*
751 * A-PMDU buffer sizes
752 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2)
753 */
754#define IEEE80211_MIN_AMPDU_BUF 0x8
755#define IEEE80211_MAX_AMPDU_BUF 0x40
756
757
758/* Spatial Multiplexing Power Save Modes */
759#define WLAN_HT_CAP_SM_PS_STATIC 0
760#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
761#define WLAN_HT_CAP_SM_PS_INVALID 2
762#define WLAN_HT_CAP_SM_PS_DISABLED 3
745 763
746/* Authentication algorithms */ 764/* Authentication algorithms */
747#define WLAN_AUTH_OPEN 0 765#define WLAN_AUTH_OPEN 0
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7c399a9c11da..fb9e62211c34 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1142,7 +1142,7 @@ enum ieee80211_ampdu_mlme_action {
1142 * of assocaited station or AP. 1142 * of assocaited station or AP.
1143 * 1143 *
1144 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), 1144 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
1145 * bursting) for a hardware TX queue. Must be atomic. 1145 * bursting) for a hardware TX queue.
1146 * 1146 *
1147 * @get_tx_stats: Get statistics of the current TX queue status. This is used 1147 * @get_tx_stats: Get statistics of the current TX queue status. This is used
1148 * to get number of currently queued packets (queue length), maximum queue 1148 * to get number of currently queued packets (queue length), maximum queue
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index a169b0201d61..2dc8f2bff27b 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -7,6 +7,8 @@ mac80211-y := \
7 sta_info.o \ 7 sta_info.o \
8 wep.o \ 8 wep.o \
9 wpa.o \ 9 wpa.o \
10 scan.o \
11 ht.o \
10 mlme.o \ 12 mlme.o \
11 iface.o \ 13 iface.o \
12 rate.o \ 14 rate.o \
@@ -15,6 +17,7 @@ mac80211-y := \
15 aes_ccm.o \ 17 aes_ccm.o \
16 cfg.o \ 18 cfg.o \
17 rx.o \ 19 rx.o \
20 spectmgmt.o \
18 tx.o \ 21 tx.o \
19 key.o \ 22 key.o \
20 util.o \ 23 util.o \
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
new file mode 100644
index 000000000000..4dc35c9dabc7
--- /dev/null
+++ b/net/mac80211/ht.c
@@ -0,0 +1,992 @@
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2008, Intel Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/ieee80211.h>
17#include <net/wireless.h>
18#include <net/mac80211.h>
19#include "ieee80211_i.h"
20#include "sta_info.h"
21#include "wme.h"
22
23int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
24 struct ieee80211_ht_info *ht_info)
25{
26
27 if (ht_info == NULL)
28 return -EINVAL;
29
30 memset(ht_info, 0, sizeof(*ht_info));
31
32 if (ht_cap_ie) {
33 u8 ampdu_info = ht_cap_ie->ampdu_params_info;
34
35 ht_info->ht_supported = 1;
36 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
37 ht_info->ampdu_factor =
38 ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
39 ht_info->ampdu_density =
40 (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
41 memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
42 } else
43 ht_info->ht_supported = 0;
44
45 return 0;
46}
47
48int ieee80211_ht_addt_info_ie_to_ht_bss_info(
49 struct ieee80211_ht_addt_info *ht_add_info_ie,
50 struct ieee80211_ht_bss_info *bss_info)
51{
52 if (bss_info == NULL)
53 return -EINVAL;
54
55 memset(bss_info, 0, sizeof(*bss_info));
56
57 if (ht_add_info_ie) {
58 u16 op_mode;
59 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
60
61 bss_info->primary_channel = ht_add_info_ie->control_chan;
62 bss_info->bss_cap = ht_add_info_ie->ht_param;
63 bss_info->bss_op_mode = (u8)(op_mode & 0xff);
64 }
65
66 return 0;
67}
68
69static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
70 const u8 *da, u16 tid,
71 u8 dialog_token, u16 start_seq_num,
72 u16 agg_size, u16 timeout)
73{
74 struct ieee80211_local *local = sdata->local;
75 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
76 struct sk_buff *skb;
77 struct ieee80211_mgmt *mgmt;
78 u16 capab;
79
80 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
81
82 if (!skb) {
83 printk(KERN_ERR "%s: failed to allocate buffer "
84 "for addba request frame\n", sdata->dev->name);
85 return;
86 }
87 skb_reserve(skb, local->hw.extra_tx_headroom);
88 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
89 memset(mgmt, 0, 24);
90 memcpy(mgmt->da, da, ETH_ALEN);
91 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
92 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
93 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
94 else
95 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
96
97 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
98 IEEE80211_STYPE_ACTION);
99
100 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
101
102 mgmt->u.action.category = WLAN_CATEGORY_BACK;
103 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
104
105 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
106 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
107 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
108 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
109
110 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
111
112 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
113 mgmt->u.action.u.addba_req.start_seq_num =
114 cpu_to_le16(start_seq_num << 4);
115
116 ieee80211_tx_skb(sdata, skb, 0);
117}
118
119static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
120 u8 dialog_token, u16 status, u16 policy,
121 u16 buf_size, u16 timeout)
122{
123 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
124 struct ieee80211_local *local = sdata->local;
125 struct sk_buff *skb;
126 struct ieee80211_mgmt *mgmt;
127 u16 capab;
128
129 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
130
131 if (!skb) {
132 printk(KERN_DEBUG "%s: failed to allocate buffer "
133 "for addba resp frame\n", sdata->dev->name);
134 return;
135 }
136
137 skb_reserve(skb, local->hw.extra_tx_headroom);
138 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
139 memset(mgmt, 0, 24);
140 memcpy(mgmt->da, da, ETH_ALEN);
141 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
142 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
143 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
144 else
145 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
146 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
147 IEEE80211_STYPE_ACTION);
148
149 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
150 mgmt->u.action.category = WLAN_CATEGORY_BACK;
151 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
152 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
153
154 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
155 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
156 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
157
158 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
159 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
160 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
161
162 ieee80211_tx_skb(sdata, skb, 0);
163}
164
165static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
166 const u8 *da, u16 tid,
167 u16 initiator, u16 reason_code)
168{
169 struct ieee80211_local *local = sdata->local;
170 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
171 struct sk_buff *skb;
172 struct ieee80211_mgmt *mgmt;
173 u16 params;
174
175 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
176
177 if (!skb) {
178 printk(KERN_ERR "%s: failed to allocate buffer "
179 "for delba frame\n", sdata->dev->name);
180 return;
181 }
182
183 skb_reserve(skb, local->hw.extra_tx_headroom);
184 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
185 memset(mgmt, 0, 24);
186 memcpy(mgmt->da, da, ETH_ALEN);
187 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
188 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
189 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
190 else
191 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
192 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
193 IEEE80211_STYPE_ACTION);
194
195 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
196
197 mgmt->u.action.category = WLAN_CATEGORY_BACK;
198 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
199 params = (u16)(initiator << 11); /* bit 11 initiator */
200 params |= (u16)(tid << 12); /* bit 15:12 TID number */
201
202 mgmt->u.action.u.delba.params = cpu_to_le16(params);
203 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
204
205 ieee80211_tx_skb(sdata, skb, 0);
206}
207
208void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
209{
210 struct ieee80211_local *local = sdata->local;
211 struct sk_buff *skb;
212 struct ieee80211_bar *bar;
213 u16 bar_control = 0;
214
215 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
216 if (!skb) {
217 printk(KERN_ERR "%s: failed to allocate buffer for "
218 "bar frame\n", sdata->dev->name);
219 return;
220 }
221 skb_reserve(skb, local->hw.extra_tx_headroom);
222 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
223 memset(bar, 0, sizeof(*bar));
224 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
225 IEEE80211_STYPE_BACK_REQ);
226 memcpy(bar->ra, ra, ETH_ALEN);
227 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
228 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
229 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
230 bar_control |= (u16)(tid << 12);
231 bar->control = cpu_to_le16(bar_control);
232 bar->start_seq_num = cpu_to_le16(ssn);
233
234 ieee80211_tx_skb(sdata, skb, 0);
235}
236
237void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
238 u16 initiator, u16 reason)
239{
240 struct ieee80211_local *local = sdata->local;
241 struct ieee80211_hw *hw = &local->hw;
242 struct sta_info *sta;
243 int ret, i;
244 DECLARE_MAC_BUF(mac);
245
246 rcu_read_lock();
247
248 sta = sta_info_get(local, ra);
249 if (!sta) {
250 rcu_read_unlock();
251 return;
252 }
253
254 /* check if TID is in operational state */
255 spin_lock_bh(&sta->lock);
256 if (sta->ampdu_mlme.tid_state_rx[tid]
257 != HT_AGG_STATE_OPERATIONAL) {
258 spin_unlock_bh(&sta->lock);
259 rcu_read_unlock();
260 return;
261 }
262 sta->ampdu_mlme.tid_state_rx[tid] =
263 HT_AGG_STATE_REQ_STOP_BA_MSK |
264 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
265 spin_unlock_bh(&sta->lock);
266
267 /* stop HW Rx aggregation. ampdu_action existence
268 * already verified in session init so we add the BUG_ON */
269 BUG_ON(!local->ops->ampdu_action);
270
271#ifdef CONFIG_MAC80211_HT_DEBUG
272 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
273 print_mac(mac, ra), tid);
274#endif /* CONFIG_MAC80211_HT_DEBUG */
275
276 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
277 ra, tid, NULL);
278 if (ret)
279 printk(KERN_DEBUG "HW problem - can not stop rx "
280 "aggregation for tid %d\n", tid);
281
282 /* shutdown timer has not expired */
283 if (initiator != WLAN_BACK_TIMER)
284 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
285
286 /* check if this is a self generated aggregation halt */
287 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
288 ieee80211_send_delba(sdata, ra, tid, 0, reason);
289
290 /* free the reordering buffer */
291 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
292 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
293 /* release the reordered frames */
294 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
295 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
296 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
297 }
298 }
299 /* free resources */
300 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
301 kfree(sta->ampdu_mlme.tid_rx[tid]);
302 sta->ampdu_mlme.tid_rx[tid] = NULL;
303 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
304
305 rcu_read_unlock();
306}
307
308
309/*
310 * After sending add Block Ack request we activated a timer until
311 * add Block Ack response will arrive from the recipient.
312 * If this timer expires sta_addba_resp_timer_expired will be executed.
313 */
314static void sta_addba_resp_timer_expired(unsigned long data)
315{
316 /* not an elegant detour, but there is no choice as the timer passes
317 * only one argument, and both sta_info and TID are needed, so init
318 * flow in sta_info_create gives the TID as data, while the timer_to_id
319 * array gives the sta through container_of */
320 u16 tid = *(u8 *)data;
321 struct sta_info *temp_sta = container_of((void *)data,
322 struct sta_info, timer_to_tid[tid]);
323
324 struct ieee80211_local *local = temp_sta->local;
325 struct ieee80211_hw *hw = &local->hw;
326 struct sta_info *sta;
327 u8 *state;
328
329 rcu_read_lock();
330
331 sta = sta_info_get(local, temp_sta->addr);
332 if (!sta) {
333 rcu_read_unlock();
334 return;
335 }
336
337 state = &sta->ampdu_mlme.tid_state_tx[tid];
338 /* check if the TID waits for addBA response */
339 spin_lock_bh(&sta->lock);
340 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
341 spin_unlock_bh(&sta->lock);
342 *state = HT_AGG_STATE_IDLE;
343#ifdef CONFIG_MAC80211_HT_DEBUG
344 printk(KERN_DEBUG "timer expired on tid %d but we are not "
345 "expecting addBA response there", tid);
346#endif
347 goto timer_expired_exit;
348 }
349
350#ifdef CONFIG_MAC80211_HT_DEBUG
351 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
352#endif
353
354 /* go through the state check in stop_BA_session */
355 *state = HT_AGG_STATE_OPERATIONAL;
356 spin_unlock_bh(&sta->lock);
357 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
358 WLAN_BACK_INITIATOR);
359
360timer_expired_exit:
361 rcu_read_unlock();
362}
363
364void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
365{
366 struct ieee80211_local *local = sdata->local;
367 int i;
368
369 for (i = 0; i < STA_TID_NUM; i++) {
370 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
371 WLAN_BACK_INITIATOR);
372 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
373 WLAN_BACK_RECIPIENT,
374 WLAN_REASON_QSTA_LEAVE_QBSS);
375 }
376}
377
378int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
379{
380 struct ieee80211_local *local = hw_to_local(hw);
381 struct sta_info *sta;
382 struct ieee80211_sub_if_data *sdata;
383 u16 start_seq_num;
384 u8 *state;
385 int ret;
386 DECLARE_MAC_BUF(mac);
387
388 if (tid >= STA_TID_NUM)
389 return -EINVAL;
390
391#ifdef CONFIG_MAC80211_HT_DEBUG
392 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
393 print_mac(mac, ra), tid);
394#endif /* CONFIG_MAC80211_HT_DEBUG */
395
396 rcu_read_lock();
397
398 sta = sta_info_get(local, ra);
399 if (!sta) {
400#ifdef CONFIG_MAC80211_HT_DEBUG
401 printk(KERN_DEBUG "Could not find the station\n");
402#endif
403 ret = -ENOENT;
404 goto exit;
405 }
406
407 spin_lock_bh(&sta->lock);
408
409 /* we have tried too many times, receiver does not want A-MPDU */
410 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
411 ret = -EBUSY;
412 goto err_unlock_sta;
413 }
414
415 state = &sta->ampdu_mlme.tid_state_tx[tid];
416 /* check if the TID is not in aggregation flow already */
417 if (*state != HT_AGG_STATE_IDLE) {
418#ifdef CONFIG_MAC80211_HT_DEBUG
419 printk(KERN_DEBUG "BA request denied - session is not "
420 "idle on tid %u\n", tid);
421#endif /* CONFIG_MAC80211_HT_DEBUG */
422 ret = -EAGAIN;
423 goto err_unlock_sta;
424 }
425
426 /* prepare A-MPDU MLME for Tx aggregation */
427 sta->ampdu_mlme.tid_tx[tid] =
428 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
429 if (!sta->ampdu_mlme.tid_tx[tid]) {
430#ifdef CONFIG_MAC80211_HT_DEBUG
431 if (net_ratelimit())
432 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
433 tid);
434#endif
435 ret = -ENOMEM;
436 goto err_unlock_sta;
437 }
438 /* Tx timer */
439 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
440 sta_addba_resp_timer_expired;
441 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
442 (unsigned long)&sta->timer_to_tid[tid];
443 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
444
445 /* create a new queue for this aggregation */
446 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
447
448 /* case no queue is available to aggregation
449 * don't switch to aggregation */
450 if (ret) {
451#ifdef CONFIG_MAC80211_HT_DEBUG
452 printk(KERN_DEBUG "BA request denied - queue unavailable for"
453 " tid %d\n", tid);
454#endif /* CONFIG_MAC80211_HT_DEBUG */
455 goto err_unlock_queue;
456 }
457 sdata = sta->sdata;
458
459 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
460 * call back right away, it must see that the flow has begun */
461 *state |= HT_ADDBA_REQUESTED_MSK;
462
463 /* This is slightly racy because the queue isn't stopped */
464 start_seq_num = sta->tid_seq[tid];
465
466 if (local->ops->ampdu_action)
467 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
468 ra, tid, &start_seq_num);
469
470 if (ret) {
471 /* No need to requeue the packets in the agg queue, since we
472 * held the tx lock: no packet could be enqueued to the newly
473 * allocated queue */
474 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
475#ifdef CONFIG_MAC80211_HT_DEBUG
476 printk(KERN_DEBUG "BA request denied - HW unavailable for"
477 " tid %d\n", tid);
478#endif /* CONFIG_MAC80211_HT_DEBUG */
479 *state = HT_AGG_STATE_IDLE;
480 goto err_unlock_queue;
481 }
482
483 /* Will put all the packets in the new SW queue */
484 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
485 spin_unlock_bh(&sta->lock);
486
487 /* send an addBA request */
488 sta->ampdu_mlme.dialog_token_allocator++;
489 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
490 sta->ampdu_mlme.dialog_token_allocator;
491 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
492
493
494 ieee80211_send_addba_request(sta->sdata, ra, tid,
495 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
496 sta->ampdu_mlme.tid_tx[tid]->ssn,
497 0x40, 5000);
498 /* activate the timer for the recipient's addBA response */
499 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
500 jiffies + ADDBA_RESP_INTERVAL;
501 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
502#ifdef CONFIG_MAC80211_HT_DEBUG
503 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
504#endif
505 goto exit;
506
507err_unlock_queue:
508 kfree(sta->ampdu_mlme.tid_tx[tid]);
509 sta->ampdu_mlme.tid_tx[tid] = NULL;
510 ret = -EBUSY;
511err_unlock_sta:
512 spin_unlock_bh(&sta->lock);
513exit:
514 rcu_read_unlock();
515 return ret;
516}
517EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
518
519int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
520 u8 *ra, u16 tid,
521 enum ieee80211_back_parties initiator)
522{
523 struct ieee80211_local *local = hw_to_local(hw);
524 struct sta_info *sta;
525 u8 *state;
526 int ret = 0;
527 DECLARE_MAC_BUF(mac);
528
529 if (tid >= STA_TID_NUM)
530 return -EINVAL;
531
532 rcu_read_lock();
533 sta = sta_info_get(local, ra);
534 if (!sta) {
535 rcu_read_unlock();
536 return -ENOENT;
537 }
538
539 /* check if the TID is in aggregation */
540 state = &sta->ampdu_mlme.tid_state_tx[tid];
541 spin_lock_bh(&sta->lock);
542
543 if (*state != HT_AGG_STATE_OPERATIONAL) {
544 ret = -ENOENT;
545 goto stop_BA_exit;
546 }
547
548#ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
550 print_mac(mac, ra), tid);
551#endif /* CONFIG_MAC80211_HT_DEBUG */
552
553 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
554
555 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
556 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
557
558 if (local->ops->ampdu_action)
559 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
560 ra, tid, NULL);
561
562 /* case HW denied going back to legacy */
563 if (ret) {
564 WARN_ON(ret != -EBUSY);
565 *state = HT_AGG_STATE_OPERATIONAL;
566 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
567 goto stop_BA_exit;
568 }
569
570stop_BA_exit:
571 spin_unlock_bh(&sta->lock);
572 rcu_read_unlock();
573 return ret;
574}
575EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
576
577void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
578{
579 struct ieee80211_local *local = hw_to_local(hw);
580 struct sta_info *sta;
581 u8 *state;
582 DECLARE_MAC_BUF(mac);
583
584 if (tid >= STA_TID_NUM) {
585#ifdef CONFIG_MAC80211_HT_DEBUG
586 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
587 tid, STA_TID_NUM);
588#endif
589 return;
590 }
591
592 rcu_read_lock();
593 sta = sta_info_get(local, ra);
594 if (!sta) {
595 rcu_read_unlock();
596#ifdef CONFIG_MAC80211_HT_DEBUG
597 printk(KERN_DEBUG "Could not find station: %s\n",
598 print_mac(mac, ra));
599#endif
600 return;
601 }
602
603 state = &sta->ampdu_mlme.tid_state_tx[tid];
604 spin_lock_bh(&sta->lock);
605
606 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
607#ifdef CONFIG_MAC80211_HT_DEBUG
608 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
609 *state);
610#endif
611 spin_unlock_bh(&sta->lock);
612 rcu_read_unlock();
613 return;
614 }
615
616 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
617
618 *state |= HT_ADDBA_DRV_READY_MSK;
619
620 if (*state == HT_AGG_STATE_OPERATIONAL) {
621#ifdef CONFIG_MAC80211_HT_DEBUG
622 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
623#endif
624 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
625 }
626 spin_unlock_bh(&sta->lock);
627 rcu_read_unlock();
628}
629EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
630
631void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
632{
633 struct ieee80211_local *local = hw_to_local(hw);
634 struct sta_info *sta;
635 u8 *state;
636 int agg_queue;
637 DECLARE_MAC_BUF(mac);
638
639 if (tid >= STA_TID_NUM) {
640#ifdef CONFIG_MAC80211_HT_DEBUG
641 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
642 tid, STA_TID_NUM);
643#endif
644 return;
645 }
646
647#ifdef CONFIG_MAC80211_HT_DEBUG
648 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
649 print_mac(mac, ra), tid);
650#endif /* CONFIG_MAC80211_HT_DEBUG */
651
652 rcu_read_lock();
653 sta = sta_info_get(local, ra);
654 if (!sta) {
655#ifdef CONFIG_MAC80211_HT_DEBUG
656 printk(KERN_DEBUG "Could not find station: %s\n",
657 print_mac(mac, ra));
658#endif
659 rcu_read_unlock();
660 return;
661 }
662 state = &sta->ampdu_mlme.tid_state_tx[tid];
663
664 /* NOTE: no need to use sta->lock in this state check, as
665 * ieee80211_stop_tx_ba_session will let only one stop call to
666 * pass through per sta/tid
667 */
668 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
669#ifdef CONFIG_MAC80211_HT_DEBUG
670 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
671#endif
672 rcu_read_unlock();
673 return;
674 }
675
676 if (*state & HT_AGG_STATE_INITIATOR_MSK)
677 ieee80211_send_delba(sta->sdata, ra, tid,
678 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
679
680 agg_queue = sta->tid_to_tx_q[tid];
681
682 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
683
684 /* We just requeued the all the frames that were in the
685 * removed queue, and since we might miss a softirq we do
686 * netif_schedule_queue. ieee80211_wake_queue is not used
687 * here as this queue is not necessarily stopped
688 */
689 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
690 spin_lock_bh(&sta->lock);
691 *state = HT_AGG_STATE_IDLE;
692 sta->ampdu_mlme.addba_req_num[tid] = 0;
693 kfree(sta->ampdu_mlme.tid_tx[tid]);
694 sta->ampdu_mlme.tid_tx[tid] = NULL;
695 spin_unlock_bh(&sta->lock);
696
697 rcu_read_unlock();
698}
699EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
700
701void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
702 const u8 *ra, u16 tid)
703{
704 struct ieee80211_local *local = hw_to_local(hw);
705 struct ieee80211_ra_tid *ra_tid;
706 struct sk_buff *skb = dev_alloc_skb(0);
707
708 if (unlikely(!skb)) {
709#ifdef CONFIG_MAC80211_HT_DEBUG
710 if (net_ratelimit())
711 printk(KERN_WARNING "%s: Not enough memory, "
712 "dropping start BA session", skb->dev->name);
713#endif
714 return;
715 }
716 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
717 memcpy(&ra_tid->ra, ra, ETH_ALEN);
718 ra_tid->tid = tid;
719
720 skb->pkt_type = IEEE80211_ADDBA_MSG;
721 skb_queue_tail(&local->skb_queue, skb);
722 tasklet_schedule(&local->tasklet);
723}
724EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
725
726void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
727 const u8 *ra, u16 tid)
728{
729 struct ieee80211_local *local = hw_to_local(hw);
730 struct ieee80211_ra_tid *ra_tid;
731 struct sk_buff *skb = dev_alloc_skb(0);
732
733 if (unlikely(!skb)) {
734#ifdef CONFIG_MAC80211_HT_DEBUG
735 if (net_ratelimit())
736 printk(KERN_WARNING "%s: Not enough memory, "
737 "dropping stop BA session", skb->dev->name);
738#endif
739 return;
740 }
741 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
742 memcpy(&ra_tid->ra, ra, ETH_ALEN);
743 ra_tid->tid = tid;
744
745 skb->pkt_type = IEEE80211_DELBA_MSG;
746 skb_queue_tail(&local->skb_queue, skb);
747 tasklet_schedule(&local->tasklet);
748}
749EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
750
751/*
752 * After accepting the AddBA Request we activated a timer,
753 * resetting it after each frame that arrives from the originator.
754 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
755 */
756static void sta_rx_agg_session_timer_expired(unsigned long data)
757{
758 /* not an elegant detour, but there is no choice as the timer passes
759 * only one argument, and various sta_info are needed here, so init
760 * flow in sta_info_create gives the TID as data, while the timer_to_id
761 * array gives the sta through container_of */
762 u8 *ptid = (u8 *)data;
763 u8 *timer_to_id = ptid - *ptid;
764 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
765 timer_to_tid[0]);
766
767#ifdef CONFIG_MAC80211_HT_DEBUG
768 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
769#endif
770 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->addr,
771 (u16)*ptid, WLAN_BACK_TIMER,
772 WLAN_REASON_QSTA_TIMEOUT);
773}
774
775void ieee80211_process_addba_request(struct ieee80211_local *local,
776 struct sta_info *sta,
777 struct ieee80211_mgmt *mgmt,
778 size_t len)
779{
780 struct ieee80211_hw *hw = &local->hw;
781 struct ieee80211_conf *conf = &hw->conf;
782 struct tid_ampdu_rx *tid_agg_rx;
783 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
784 u8 dialog_token;
785 int ret = -EOPNOTSUPP;
786 DECLARE_MAC_BUF(mac);
787
788 /* extract session parameters from addba request frame */
789 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
790 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
791 start_seq_num =
792 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
793
794 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
795 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
796 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
797 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
798
799 status = WLAN_STATUS_REQUEST_DECLINED;
800
801 /* sanity check for incoming parameters:
802 * check if configuration can support the BA policy
803 * and if buffer size does not exceeds max value */
804 if (((ba_policy != 1)
805 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
806 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
807 status = WLAN_STATUS_INVALID_QOS_PARAM;
808#ifdef CONFIG_MAC80211_HT_DEBUG
809 if (net_ratelimit())
810 printk(KERN_DEBUG "AddBA Req with bad params from "
811 "%s on tid %u. policy %d, buffer size %d\n",
812 print_mac(mac, mgmt->sa), tid, ba_policy,
813 buf_size);
814#endif /* CONFIG_MAC80211_HT_DEBUG */
815 goto end_no_lock;
816 }
817 /* determine default buffer size */
818 if (buf_size == 0) {
819 struct ieee80211_supported_band *sband;
820
821 sband = local->hw.wiphy->bands[conf->channel->band];
822 buf_size = IEEE80211_MIN_AMPDU_BUF;
823 buf_size = buf_size << sband->ht_info.ampdu_factor;
824 }
825
826
827 /* examine state machine */
828 spin_lock_bh(&sta->lock);
829
830 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
831#ifdef CONFIG_MAC80211_HT_DEBUG
832 if (net_ratelimit())
833 printk(KERN_DEBUG "unexpected AddBA Req from "
834 "%s on tid %u\n",
835 print_mac(mac, mgmt->sa), tid);
836#endif /* CONFIG_MAC80211_HT_DEBUG */
837 goto end;
838 }
839
840 /* prepare A-MPDU MLME for Rx aggregation */
841 sta->ampdu_mlme.tid_rx[tid] =
842 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
843 if (!sta->ampdu_mlme.tid_rx[tid]) {
844#ifdef CONFIG_MAC80211_HT_DEBUG
845 if (net_ratelimit())
846 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
847 tid);
848#endif
849 goto end;
850 }
851 /* rx timer */
852 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
853 sta_rx_agg_session_timer_expired;
854 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
855 (unsigned long)&sta->timer_to_tid[tid];
856 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
857
858 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
859
860 /* prepare reordering buffer */
861 tid_agg_rx->reorder_buf =
862 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
863 if (!tid_agg_rx->reorder_buf) {
864#ifdef CONFIG_MAC80211_HT_DEBUG
865 if (net_ratelimit())
866 printk(KERN_ERR "can not allocate reordering buffer "
867 "to tid %d\n", tid);
868#endif
869 kfree(sta->ampdu_mlme.tid_rx[tid]);
870 goto end;
871 }
872 memset(tid_agg_rx->reorder_buf, 0,
873 buf_size * sizeof(struct sk_buff *));
874
875 if (local->ops->ampdu_action)
876 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
877 sta->addr, tid, &start_seq_num);
878#ifdef CONFIG_MAC80211_HT_DEBUG
879 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
880#endif /* CONFIG_MAC80211_HT_DEBUG */
881
882 if (ret) {
883 kfree(tid_agg_rx->reorder_buf);
884 kfree(tid_agg_rx);
885 sta->ampdu_mlme.tid_rx[tid] = NULL;
886 goto end;
887 }
888
889 /* change state and send addba resp */
890 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
891 tid_agg_rx->dialog_token = dialog_token;
892 tid_agg_rx->ssn = start_seq_num;
893 tid_agg_rx->head_seq_num = start_seq_num;
894 tid_agg_rx->buf_size = buf_size;
895 tid_agg_rx->timeout = timeout;
896 tid_agg_rx->stored_mpdu_num = 0;
897 status = WLAN_STATUS_SUCCESS;
898end:
899 spin_unlock_bh(&sta->lock);
900
901end_no_lock:
902 ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
903 dialog_token, status, 1, buf_size, timeout);
904}
905
906void ieee80211_process_addba_resp(struct ieee80211_local *local,
907 struct sta_info *sta,
908 struct ieee80211_mgmt *mgmt,
909 size_t len)
910{
911 struct ieee80211_hw *hw = &local->hw;
912 u16 capab;
913 u16 tid;
914 u8 *state;
915
916 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
917 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
918
919 state = &sta->ampdu_mlme.tid_state_tx[tid];
920
921 spin_lock_bh(&sta->lock);
922
923 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
924 spin_unlock_bh(&sta->lock);
925 return;
926 }
927
928 if (mgmt->u.action.u.addba_resp.dialog_token !=
929 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
930 spin_unlock_bh(&sta->lock);
931#ifdef CONFIG_MAC80211_HT_DEBUG
932 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
933#endif /* CONFIG_MAC80211_HT_DEBUG */
934 return;
935 }
936
937 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
938#ifdef CONFIG_MAC80211_HT_DEBUG
939 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
940#endif /* CONFIG_MAC80211_HT_DEBUG */
941 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
942 == WLAN_STATUS_SUCCESS) {
943 *state |= HT_ADDBA_RECEIVED_MSK;
944 sta->ampdu_mlme.addba_req_num[tid] = 0;
945
946 if (*state == HT_AGG_STATE_OPERATIONAL)
947 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
948
949 spin_unlock_bh(&sta->lock);
950 } else {
951 sta->ampdu_mlme.addba_req_num[tid]++;
952 /* this will allow the state check in stop_BA_session */
953 *state = HT_AGG_STATE_OPERATIONAL;
954 spin_unlock_bh(&sta->lock);
955 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
956 WLAN_BACK_INITIATOR);
957 }
958}
959
960void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
961 struct sta_info *sta,
962 struct ieee80211_mgmt *mgmt, size_t len)
963{
964 struct ieee80211_local *local = sdata->local;
965 u16 tid, params;
966 u16 initiator;
967 DECLARE_MAC_BUF(mac);
968
969 params = le16_to_cpu(mgmt->u.action.u.delba.params);
970 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
971 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
972
973#ifdef CONFIG_MAC80211_HT_DEBUG
974 if (net_ratelimit())
975 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
976 print_mac(mac, mgmt->sa),
977 initiator ? "initiator" : "recipient", tid,
978 mgmt->u.action.u.delba.reason_code);
979#endif /* CONFIG_MAC80211_HT_DEBUG */
980
981 if (initiator == WLAN_BACK_INITIATOR)
982 ieee80211_sta_stop_rx_ba_session(sdata, sta->addr, tid,
983 WLAN_BACK_INITIATOR, 0);
984 else { /* WLAN_BACK_RECIPIENT */
985 spin_lock_bh(&sta->lock);
986 sta->ampdu_mlme.tid_state_tx[tid] =
987 HT_AGG_STATE_OPERATIONAL;
988 spin_unlock_bh(&sta->lock);
989 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
990 WLAN_BACK_RECIPIENT);
991 }
992}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c68d4df11196..6f334e4c3d66 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -53,6 +53,12 @@ struct ieee80211_local;
53 * increased memory use (about 2 kB of RAM per entry). */ 53 * increased memory use (about 2 kB of RAM per entry). */
54#define IEEE80211_FRAGMENT_MAX 4 54#define IEEE80211_FRAGMENT_MAX 4
55 55
56/*
57 * Time after which we ignore scan results and no longer report/use
58 * them in any way.
59 */
60#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
61
56struct ieee80211_fragment_entry { 62struct ieee80211_fragment_entry {
57 unsigned long first_frag_time; 63 unsigned long first_frag_time;
58 unsigned int seq; 64 unsigned int seq;
@@ -636,7 +642,7 @@ struct ieee80211_local {
636 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 642 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
637 unsigned long last_scan_completed; 643 unsigned long last_scan_completed;
638 struct delayed_work scan_work; 644 struct delayed_work scan_work;
639 struct net_device *scan_dev; 645 struct ieee80211_sub_if_data *scan_sdata;
640 struct ieee80211_channel *oper_channel, *scan_channel; 646 struct ieee80211_channel *oper_channel, *scan_channel;
641 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 647 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
642 size_t scan_ssid_len; 648 size_t scan_ssid_len;
@@ -903,29 +909,31 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
903void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 909void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
904 u32 changed); 910 u32 changed);
905u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); 911u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
906int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
907 struct ieee80211_ht_info *ht_info);
908int ieee80211_ht_addt_info_ie_to_ht_bss_info(
909 struct ieee80211_ht_addt_info *ht_add_info_ie,
910 struct ieee80211_ht_bss_info *bss_info);
911void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
912 u16 tid, u8 dialog_token, u16 start_seq_num,
913 u16 agg_size, u16 timeout);
914void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
915 u16 initiator, u16 reason_code);
916void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
917
918void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
919 u16 tid, u16 initiator, u16 reason);
920void sta_addba_resp_timer_expired(unsigned long data);
921void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr);
922u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 912u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
923 struct ieee802_11_elems *elems, 913 struct ieee802_11_elems *elems,
924 enum ieee80211_band band); 914 enum ieee80211_band band);
925void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 915void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
926 int encrypt); 916 u8 *ssid, size_t ssid_len);
927void ieee802_11_parse_elems(u8 *start, size_t len, 917void ieee802_11_parse_elems(u8 *start, size_t len,
928 struct ieee802_11_elems *elems); 918 struct ieee802_11_elems *elems);
919void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
920int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
921 u8 *ssid, size_t ssid_len);
922struct ieee80211_sta_bss *
923ieee80211_bss_info_update(struct ieee80211_local *local,
924 struct ieee80211_rx_status *rx_status,
925 struct ieee80211_mgmt *mgmt,
926 size_t len,
927 struct ieee802_11_elems *elems,
928 int freq, bool beacon);
929struct ieee80211_sta_bss *
930ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
931 u8 *ssid, u8 ssid_len);
932struct ieee80211_sta_bss *
933ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
934 u8 *ssid, u8 ssid_len);
935void ieee80211_rx_bss_put(struct ieee80211_local *local,
936 struct ieee80211_sta_bss *bss);
929 937
930#ifdef CONFIG_MAC80211_MESH 938#ifdef CONFIG_MAC80211_MESH
931void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 939void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
@@ -951,6 +959,34 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
951int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); 959int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
952int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 960int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
953 961
962/* HT */
963int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
964 struct ieee80211_ht_info *ht_info);
965int ieee80211_ht_addt_info_ie_to_ht_bss_info(
966 struct ieee80211_ht_addt_info *ht_add_info_ie,
967 struct ieee80211_ht_bss_info *bss_info);
968void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
969
970void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
971 u16 tid, u16 initiator, u16 reason);
972void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr);
973void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
974 struct sta_info *sta,
975 struct ieee80211_mgmt *mgmt, size_t len);
976void ieee80211_process_addba_resp(struct ieee80211_local *local,
977 struct sta_info *sta,
978 struct ieee80211_mgmt *mgmt,
979 size_t len);
980void ieee80211_process_addba_request(struct ieee80211_local *local,
981 struct sta_info *sta,
982 struct ieee80211_mgmt *mgmt,
983 size_t len);
984
985/* Spectrum management */
986void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
987 struct ieee80211_mgmt *mgmt,
988 size_t len);
989
954/* utility functions/constants */ 990/* utility functions/constants */
955extern void *mac80211_wiphy_privid; /* for wiphy privid */ 991extern void *mac80211_wiphy_privid; /* for wiphy privid */
956extern const unsigned char rfc1042_header[6]; 992extern const unsigned char rfc1042_header[6];
@@ -961,6 +997,9 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
961 int rate, int erp, int short_preamble); 997 int rate, int erp, int short_preamble);
962void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 998void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
963 struct ieee80211_hdr *hdr); 999 struct ieee80211_hdr *hdr);
1000void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1001void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1002 int encrypt);
964 1003
965#ifdef CONFIG_MAC80211_NOINLINE 1004#ifdef CONFIG_MAC80211_NOINLINE
966#define debug_noinline noinline 1005#define debug_noinline noinline
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 4a623b8e91fd..672cec60a2fb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -31,11 +31,11 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
31 int flushed; 31 int flushed;
32 int i; 32 int i;
33 33
34 ieee80211_debugfs_remove_netdev(sdata);
35
36 /* free extra data */ 34 /* free extra data */
37 ieee80211_free_keys(sdata); 35 ieee80211_free_keys(sdata);
38 36
37 ieee80211_debugfs_remove_netdev(sdata);
38
39 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 39 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
40 __skb_queue_purge(&sdata->fragments[i].skb_list); 40 __skb_queue_purge(&sdata->fragments[i].skb_list);
41 sdata->fragment_next = 0; 41 sdata->fragment_next = 0;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 396cfb2d0f46..6a7f4fae18c2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -399,8 +399,15 @@ static int ieee80211_open(struct net_device *dev)
399 atomic_inc(&local->iff_promiscs); 399 atomic_inc(&local->iff_promiscs);
400 400
401 local->open_count++; 401 local->open_count++;
402 if (need_hw_reconfig) 402 if (need_hw_reconfig) {
403 ieee80211_hw_config(local); 403 ieee80211_hw_config(local);
404 /*
405 * set default queue parameters so drivers don't
406 * need to initialise the hardware if the hardware
407 * doesn't start up with sane defaults
408 */
409 ieee80211_set_wmm_default(sdata);
410 }
404 411
405 /* 412 /*
406 * ieee80211_sta_work is disabled while network interface 413 * ieee80211_sta_work is disabled while network interface
@@ -551,7 +558,7 @@ static int ieee80211_stop(struct net_device *dev)
551 synchronize_rcu(); 558 synchronize_rcu();
552 skb_queue_purge(&sdata->u.sta.skb_queue); 559 skb_queue_purge(&sdata->u.sta.skb_queue);
553 560
554 if (local->scan_dev == sdata->dev) { 561 if (local->scan_sdata == sdata) {
555 if (!local->ops->hw_scan) { 562 if (!local->ops->hw_scan) {
556 local->sta_sw_scanning = 0; 563 local->sta_sw_scanning = 0;
557 cancel_delayed_work(&local->scan_work); 564 cancel_delayed_work(&local->scan_work);
@@ -593,379 +600,6 @@ static int ieee80211_stop(struct net_device *dev)
593 return 0; 600 return 0;
594} 601}
595 602
596int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
597{
598 struct ieee80211_local *local = hw_to_local(hw);
599 struct sta_info *sta;
600 struct ieee80211_sub_if_data *sdata;
601 u16 start_seq_num;
602 u8 *state;
603 int ret;
604 DECLARE_MAC_BUF(mac);
605
606 if (tid >= STA_TID_NUM)
607 return -EINVAL;
608
609#ifdef CONFIG_MAC80211_HT_DEBUG
610 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
611 print_mac(mac, ra), tid);
612#endif /* CONFIG_MAC80211_HT_DEBUG */
613
614 rcu_read_lock();
615
616 sta = sta_info_get(local, ra);
617 if (!sta) {
618#ifdef CONFIG_MAC80211_HT_DEBUG
619 printk(KERN_DEBUG "Could not find the station\n");
620#endif
621 ret = -ENOENT;
622 goto exit;
623 }
624
625 spin_lock_bh(&sta->lock);
626
627 /* we have tried too many times, receiver does not want A-MPDU */
628 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
629 ret = -EBUSY;
630 goto err_unlock_sta;
631 }
632
633 state = &sta->ampdu_mlme.tid_state_tx[tid];
634 /* check if the TID is not in aggregation flow already */
635 if (*state != HT_AGG_STATE_IDLE) {
636#ifdef CONFIG_MAC80211_HT_DEBUG
637 printk(KERN_DEBUG "BA request denied - session is not "
638 "idle on tid %u\n", tid);
639#endif /* CONFIG_MAC80211_HT_DEBUG */
640 ret = -EAGAIN;
641 goto err_unlock_sta;
642 }
643
644 /* prepare A-MPDU MLME for Tx aggregation */
645 sta->ampdu_mlme.tid_tx[tid] =
646 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
647 if (!sta->ampdu_mlme.tid_tx[tid]) {
648#ifdef CONFIG_MAC80211_HT_DEBUG
649 if (net_ratelimit())
650 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
651 tid);
652#endif
653 ret = -ENOMEM;
654 goto err_unlock_sta;
655 }
656 /* Tx timer */
657 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
658 sta_addba_resp_timer_expired;
659 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
660 (unsigned long)&sta->timer_to_tid[tid];
661 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
662
663 /* create a new queue for this aggregation */
664 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
665
666 /* case no queue is available to aggregation
667 * don't switch to aggregation */
668 if (ret) {
669#ifdef CONFIG_MAC80211_HT_DEBUG
670 printk(KERN_DEBUG "BA request denied - queue unavailable for"
671 " tid %d\n", tid);
672#endif /* CONFIG_MAC80211_HT_DEBUG */
673 goto err_unlock_queue;
674 }
675 sdata = sta->sdata;
676
677 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
678 * call back right away, it must see that the flow has begun */
679 *state |= HT_ADDBA_REQUESTED_MSK;
680
681 /* This is slightly racy because the queue isn't stopped */
682 start_seq_num = sta->tid_seq[tid];
683
684 if (local->ops->ampdu_action)
685 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
686 ra, tid, &start_seq_num);
687
688 if (ret) {
689 /* No need to requeue the packets in the agg queue, since we
690 * held the tx lock: no packet could be enqueued to the newly
691 * allocated queue */
692 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
693#ifdef CONFIG_MAC80211_HT_DEBUG
694 printk(KERN_DEBUG "BA request denied - HW unavailable for"
695 " tid %d\n", tid);
696#endif /* CONFIG_MAC80211_HT_DEBUG */
697 *state = HT_AGG_STATE_IDLE;
698 goto err_unlock_queue;
699 }
700
701 /* Will put all the packets in the new SW queue */
702 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
703 spin_unlock_bh(&sta->lock);
704
705 /* send an addBA request */
706 sta->ampdu_mlme.dialog_token_allocator++;
707 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
708 sta->ampdu_mlme.dialog_token_allocator;
709 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
710
711
712 ieee80211_send_addba_request(sta->sdata, ra, tid,
713 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
714 sta->ampdu_mlme.tid_tx[tid]->ssn,
715 0x40, 5000);
716 /* activate the timer for the recipient's addBA response */
717 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
718 jiffies + ADDBA_RESP_INTERVAL;
719 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
720#ifdef CONFIG_MAC80211_HT_DEBUG
721 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
722#endif
723 goto exit;
724
725err_unlock_queue:
726 kfree(sta->ampdu_mlme.tid_tx[tid]);
727 sta->ampdu_mlme.tid_tx[tid] = NULL;
728 ret = -EBUSY;
729err_unlock_sta:
730 spin_unlock_bh(&sta->lock);
731exit:
732 rcu_read_unlock();
733 return ret;
734}
735EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
736
737int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
738 u8 *ra, u16 tid,
739 enum ieee80211_back_parties initiator)
740{
741 struct ieee80211_local *local = hw_to_local(hw);
742 struct sta_info *sta;
743 u8 *state;
744 int ret = 0;
745 DECLARE_MAC_BUF(mac);
746
747 if (tid >= STA_TID_NUM)
748 return -EINVAL;
749
750 rcu_read_lock();
751 sta = sta_info_get(local, ra);
752 if (!sta) {
753 rcu_read_unlock();
754 return -ENOENT;
755 }
756
757 /* check if the TID is in aggregation */
758 state = &sta->ampdu_mlme.tid_state_tx[tid];
759 spin_lock_bh(&sta->lock);
760
761 if (*state != HT_AGG_STATE_OPERATIONAL) {
762 ret = -ENOENT;
763 goto stop_BA_exit;
764 }
765
766#ifdef CONFIG_MAC80211_HT_DEBUG
767 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
768 print_mac(mac, ra), tid);
769#endif /* CONFIG_MAC80211_HT_DEBUG */
770
771 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
772
773 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
774 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
775
776 if (local->ops->ampdu_action)
777 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
778 ra, tid, NULL);
779
780 /* case HW denied going back to legacy */
781 if (ret) {
782 WARN_ON(ret != -EBUSY);
783 *state = HT_AGG_STATE_OPERATIONAL;
784 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
785 goto stop_BA_exit;
786 }
787
788stop_BA_exit:
789 spin_unlock_bh(&sta->lock);
790 rcu_read_unlock();
791 return ret;
792}
793EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
794
795void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
796{
797 struct ieee80211_local *local = hw_to_local(hw);
798 struct sta_info *sta;
799 u8 *state;
800 DECLARE_MAC_BUF(mac);
801
802 if (tid >= STA_TID_NUM) {
803#ifdef CONFIG_MAC80211_HT_DEBUG
804 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
805 tid, STA_TID_NUM);
806#endif
807 return;
808 }
809
810 rcu_read_lock();
811 sta = sta_info_get(local, ra);
812 if (!sta) {
813 rcu_read_unlock();
814#ifdef CONFIG_MAC80211_HT_DEBUG
815 printk(KERN_DEBUG "Could not find station: %s\n",
816 print_mac(mac, ra));
817#endif
818 return;
819 }
820
821 state = &sta->ampdu_mlme.tid_state_tx[tid];
822 spin_lock_bh(&sta->lock);
823
824 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
825#ifdef CONFIG_MAC80211_HT_DEBUG
826 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
827 *state);
828#endif
829 spin_unlock_bh(&sta->lock);
830 rcu_read_unlock();
831 return;
832 }
833
834 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
835
836 *state |= HT_ADDBA_DRV_READY_MSK;
837
838 if (*state == HT_AGG_STATE_OPERATIONAL) {
839#ifdef CONFIG_MAC80211_HT_DEBUG
840 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
841#endif
842 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
843 }
844 spin_unlock_bh(&sta->lock);
845 rcu_read_unlock();
846}
847EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
848
849void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
850{
851 struct ieee80211_local *local = hw_to_local(hw);
852 struct sta_info *sta;
853 u8 *state;
854 int agg_queue;
855 DECLARE_MAC_BUF(mac);
856
857 if (tid >= STA_TID_NUM) {
858#ifdef CONFIG_MAC80211_HT_DEBUG
859 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
860 tid, STA_TID_NUM);
861#endif
862 return;
863 }
864
865#ifdef CONFIG_MAC80211_HT_DEBUG
866 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
867 print_mac(mac, ra), tid);
868#endif /* CONFIG_MAC80211_HT_DEBUG */
869
870 rcu_read_lock();
871 sta = sta_info_get(local, ra);
872 if (!sta) {
873#ifdef CONFIG_MAC80211_HT_DEBUG
874 printk(KERN_DEBUG "Could not find station: %s\n",
875 print_mac(mac, ra));
876#endif
877 rcu_read_unlock();
878 return;
879 }
880 state = &sta->ampdu_mlme.tid_state_tx[tid];
881
882 /* NOTE: no need to use sta->lock in this state check, as
883 * ieee80211_stop_tx_ba_session will let only one stop call to
884 * pass through per sta/tid
885 */
886 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
887#ifdef CONFIG_MAC80211_HT_DEBUG
888 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
889#endif
890 rcu_read_unlock();
891 return;
892 }
893
894 if (*state & HT_AGG_STATE_INITIATOR_MSK)
895 ieee80211_send_delba(sta->sdata, ra, tid,
896 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
897
898 agg_queue = sta->tid_to_tx_q[tid];
899
900 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
901
902 /* We just requeued the all the frames that were in the
903 * removed queue, and since we might miss a softirq we do
904 * netif_schedule_queue. ieee80211_wake_queue is not used
905 * here as this queue is not necessarily stopped
906 */
907 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
908 spin_lock_bh(&sta->lock);
909 *state = HT_AGG_STATE_IDLE;
910 sta->ampdu_mlme.addba_req_num[tid] = 0;
911 kfree(sta->ampdu_mlme.tid_tx[tid]);
912 sta->ampdu_mlme.tid_tx[tid] = NULL;
913 spin_unlock_bh(&sta->lock);
914
915 rcu_read_unlock();
916}
917EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
918
919void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
920 const u8 *ra, u16 tid)
921{
922 struct ieee80211_local *local = hw_to_local(hw);
923 struct ieee80211_ra_tid *ra_tid;
924 struct sk_buff *skb = dev_alloc_skb(0);
925
926 if (unlikely(!skb)) {
927#ifdef CONFIG_MAC80211_HT_DEBUG
928 if (net_ratelimit())
929 printk(KERN_WARNING "%s: Not enough memory, "
930 "dropping start BA session", skb->dev->name);
931#endif
932 return;
933 }
934 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
935 memcpy(&ra_tid->ra, ra, ETH_ALEN);
936 ra_tid->tid = tid;
937
938 skb->pkt_type = IEEE80211_ADDBA_MSG;
939 skb_queue_tail(&local->skb_queue, skb);
940 tasklet_schedule(&local->tasklet);
941}
942EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
943
944void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
945 const u8 *ra, u16 tid)
946{
947 struct ieee80211_local *local = hw_to_local(hw);
948 struct ieee80211_ra_tid *ra_tid;
949 struct sk_buff *skb = dev_alloc_skb(0);
950
951 if (unlikely(!skb)) {
952#ifdef CONFIG_MAC80211_HT_DEBUG
953 if (net_ratelimit())
954 printk(KERN_WARNING "%s: Not enough memory, "
955 "dropping stop BA session", skb->dev->name);
956#endif
957 return;
958 }
959 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
960 memcpy(&ra_tid->ra, ra, ETH_ALEN);
961 ra_tid->tid = tid;
962
963 skb->pkt_type = IEEE80211_DELBA_MSG;
964 skb_queue_tail(&local->skb_queue, skb);
965 tasklet_schedule(&local->tasklet);
966}
967EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
968
969static void ieee80211_set_multicast_list(struct net_device *dev) 603static void ieee80211_set_multicast_list(struct net_device *dev)
970{ 604{
971 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 605 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
@@ -1140,8 +774,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
1140 ht_conf.ht_supported = 1; 774 ht_conf.ht_supported = 1;
1141 775
1142 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; 776 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
1143 ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); 777 ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS);
1144 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; 778 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS;
1145 ht_bss_conf.primary_channel = req_bss_cap->primary_channel; 779 ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
1146 ht_bss_conf.bss_cap = req_bss_cap->bss_cap; 780 ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
1147 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; 781 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index eeb0ce2d5d37..210d6b852406 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -149,7 +149,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
149 pos += ETH_ALEN; 149 pos += ETH_ALEN;
150 memcpy(pos, &dst_dsn, 4); 150 memcpy(pos, &dst_dsn, 4);
151 151
152 ieee80211_sta_tx(sdata, skb, 0); 152 ieee80211_tx_skb(sdata, skb, 0);
153 return 0; 153 return 0;
154} 154}
155 155
@@ -198,7 +198,7 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
198 pos += ETH_ALEN; 198 pos += ETH_ALEN;
199 memcpy(pos, &dst_dsn, 4); 199 memcpy(pos, &dst_dsn, 4);
200 200
201 ieee80211_sta_tx(sdata, skb, 0); 201 ieee80211_tx_skb(sdata, skb, 0);
202 return 0; 202 return 0;
203} 203}
204 204
@@ -581,6 +581,10 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
581 size_t baselen; 581 size_t baselen;
582 u32 last_hop_metric; 582 u32 last_hop_metric;
583 583
584 /* need action_code */
585 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
586 return;
587
584 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; 588 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
585 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 589 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
586 len - baselen, &elems); 590 len - baselen, &elems);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 7714b0e6e4d7..7356462dee96 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -217,7 +217,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
217 memcpy(pos, &reason, 2); 217 memcpy(pos, &reason, 2);
218 } 218 }
219 219
220 ieee80211_sta_tx(sdata, skb, 0); 220 ieee80211_tx_skb(sdata, skb, 0);
221 return 0; 221 return 0;
222} 222}
223 223
@@ -421,6 +421,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
421 DECLARE_MAC_BUF(mac); 421 DECLARE_MAC_BUF(mac);
422#endif 422#endif
423 423
424 /* need action_code, aux */
425 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
426 return;
427
424 if (is_multicast_ether_addr(mgmt->da)) { 428 if (is_multicast_ether_addr(mgmt->da)) {
425 mpl_dbg("Mesh plink: ignore frame from multicast address"); 429 mpl_dbg("Mesh plink: ignore frame from multicast address");
426 return; 430 return;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index df12e746b03e..2c06f6965b7d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -11,11 +11,6 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14/* TODO:
15 * order BSS list by RSSI(?) ("quality of AP")
16 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
17 * SSID)
18 */
19#include <linux/delay.h> 14#include <linux/delay.h>
20#include <linux/if_ether.h> 15#include <linux/if_ether.h>
21#include <linux/skbuff.h> 16#include <linux/skbuff.h>
@@ -26,9 +21,8 @@
26#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
27#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
28#include <net/iw_handler.h> 23#include <net/iw_handler.h>
29#include <asm/types.h>
30
31#include <net/mac80211.h> 24#include <net/mac80211.h>
25
32#include "ieee80211_i.h" 26#include "ieee80211_i.h"
33#include "rate.h" 27#include "rate.h"
34#include "led.h" 28#include "led.h"
@@ -47,10 +41,6 @@
47#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) 41#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ)
48#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) 42#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ)
49 43
50#define IEEE80211_PROBE_DELAY (HZ / 33)
51#define IEEE80211_CHANNEL_TIME (HZ / 33)
52#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
53#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
54#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) 44#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
55#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) 45#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
56#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) 46#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
@@ -58,219 +48,396 @@
58#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 48#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
59 49
60 50
61#define ERP_INFO_USE_PROTECTION BIT(1) 51/* utils */
52static int ecw2cw(int ecw)
53{
54 return (1 << ecw) - 1;
55}
62 56
63/* mgmt header + 1 byte action code */ 57static u8 *ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie)
64#define IEEE80211_MIN_ACTION_SIZE (24 + 1) 58{
59 u8 *end, *pos;
65 60
66#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 61 pos = bss->ies;
67#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C 62 if (pos == NULL)
68#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 63 return NULL;
69#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 64 end = pos + bss->ies_len;
70#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
71 65
72/* next values represent the buffer size for A-MPDU frame. 66 while (pos + 1 < end) {
73 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */ 67 if (pos + 2 + pos[1] > end)
74#define IEEE80211_MIN_AMPDU_BUF 0x8 68 break;
75#define IEEE80211_MAX_AMPDU_BUF 0x40 69 if (pos[0] == ie)
70 return pos;
71 pos += 2 + pos[1];
72 }
76 73
77static void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 74 return NULL;
78 u8 *ssid, size_t ssid_len); 75}
79static struct ieee80211_sta_bss *
80ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
81 u8 *ssid, u8 ssid_len);
82static void ieee80211_rx_bss_put(struct ieee80211_local *local,
83 struct ieee80211_sta_bss *bss);
84static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
85 struct ieee80211_if_sta *ifsta);
86static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata);
87static int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *sdata,
88 u8 *ssid, size_t ssid_len);
89static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
90 struct ieee80211_if_sta *ifsta);
91static void sta_rx_agg_session_timer_expired(unsigned long data);
92 76
77static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
78 struct ieee80211_supported_band *sband,
79 u64 *rates)
80{
81 int i, j, count;
82 *rates = 0;
83 count = 0;
84 for (i = 0; i < bss->supp_rates_len; i++) {
85 int rate = (bss->supp_rates[i] & 0x7F) * 5;
86
87 for (j = 0; j < sband->n_bitrates; j++)
88 if (sband->bitrates[j].bitrate == rate) {
89 *rates |= BIT(j);
90 count++;
91 break;
92 }
93 }
93 94
94void ieee802_11_parse_elems(u8 *start, size_t len, 95 return count;
95 struct ieee802_11_elems *elems) 96}
97
98/* frame sending functions */
99static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
100 struct ieee80211_if_sta *ifsta,
101 int transaction, u8 *extra, size_t extra_len,
102 int encrypt)
96{ 103{
97 size_t left = len; 104 struct ieee80211_local *local = sdata->local;
98 u8 *pos = start; 105 struct sk_buff *skb;
106 struct ieee80211_mgmt *mgmt;
99 107
100 memset(elems, 0, sizeof(*elems)); 108 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
101 elems->ie_start = start; 109 sizeof(*mgmt) + 6 + extra_len);
102 elems->total_len = len; 110 if (!skb) {
111 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
112 "frame\n", sdata->dev->name);
113 return;
114 }
115 skb_reserve(skb, local->hw.extra_tx_headroom);
103 116
104 while (left >= 2) { 117 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
105 u8 id, elen; 118 memset(mgmt, 0, 24 + 6);
119 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
120 IEEE80211_STYPE_AUTH);
121 if (encrypt)
122 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
123 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
124 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
125 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
126 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg);
127 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
128 ifsta->auth_transaction = transaction + 1;
129 mgmt->u.auth.status_code = cpu_to_le16(0);
130 if (extra)
131 memcpy(skb_put(skb, extra_len), extra, extra_len);
106 132
107 id = *pos++; 133 ieee80211_tx_skb(sdata, skb, encrypt);
108 elen = *pos++; 134}
109 left -= 2;
110 135
111 if (elen > left) 136void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
112 return; 137 u8 *ssid, size_t ssid_len)
138{
139 struct ieee80211_local *local = sdata->local;
140 struct ieee80211_supported_band *sband;
141 struct sk_buff *skb;
142 struct ieee80211_mgmt *mgmt;
143 u8 *pos, *supp_rates, *esupp_rates = NULL;
144 int i;
113 145
114 switch (id) { 146 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
115 case WLAN_EID_SSID: 147 if (!skb) {
116 elems->ssid = pos; 148 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
117 elems->ssid_len = elen; 149 "request\n", sdata->dev->name);
118 break; 150 return;
119 case WLAN_EID_SUPP_RATES: 151 }
120 elems->supp_rates = pos; 152 skb_reserve(skb, local->hw.extra_tx_headroom);
121 elems->supp_rates_len = elen; 153
122 break; 154 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
123 case WLAN_EID_FH_PARAMS: 155 memset(mgmt, 0, 24);
124 elems->fh_params = pos; 156 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
125 elems->fh_params_len = elen; 157 IEEE80211_STYPE_PROBE_REQ);
126 break; 158 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
127 case WLAN_EID_DS_PARAMS: 159 if (dst) {
128 elems->ds_params = pos; 160 memcpy(mgmt->da, dst, ETH_ALEN);
129 elems->ds_params_len = elen; 161 memcpy(mgmt->bssid, dst, ETH_ALEN);
130 break; 162 } else {
131 case WLAN_EID_CF_PARAMS: 163 memset(mgmt->da, 0xff, ETH_ALEN);
132 elems->cf_params = pos; 164 memset(mgmt->bssid, 0xff, ETH_ALEN);
133 elems->cf_params_len = elen; 165 }
134 break; 166 pos = skb_put(skb, 2 + ssid_len);
135 case WLAN_EID_TIM: 167 *pos++ = WLAN_EID_SSID;
136 elems->tim = pos; 168 *pos++ = ssid_len;
137 elems->tim_len = elen; 169 memcpy(pos, ssid, ssid_len);
138 break; 170
139 case WLAN_EID_IBSS_PARAMS: 171 supp_rates = skb_put(skb, 2);
140 elems->ibss_params = pos; 172 supp_rates[0] = WLAN_EID_SUPP_RATES;
141 elems->ibss_params_len = elen; 173 supp_rates[1] = 0;
142 break; 174 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
143 case WLAN_EID_CHALLENGE: 175
144 elems->challenge = pos; 176 for (i = 0; i < sband->n_bitrates; i++) {
145 elems->challenge_len = elen; 177 struct ieee80211_rate *rate = &sband->bitrates[i];
146 break; 178 if (esupp_rates) {
147 case WLAN_EID_WPA: 179 pos = skb_put(skb, 1);
148 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 180 esupp_rates[1]++;
149 pos[2] == 0xf2) { 181 } else if (supp_rates[1] == 8) {
150 /* Microsoft OUI (00:50:F2) */ 182 esupp_rates = skb_put(skb, 3);
151 if (pos[3] == 1) { 183 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
152 /* OUI Type 1 - WPA IE */ 184 esupp_rates[1] = 1;
153 elems->wpa = pos; 185 pos = &esupp_rates[2];
154 elems->wpa_len = elen; 186 } else {
155 } else if (elen >= 5 && pos[3] == 2) { 187 pos = skb_put(skb, 1);
156 if (pos[4] == 0) { 188 supp_rates[1]++;
157 elems->wmm_info = pos; 189 }
158 elems->wmm_info_len = elen; 190 *pos = rate->bitrate / 5;
159 } else if (pos[4] == 1) { 191 }
160 elems->wmm_param = pos; 192
161 elems->wmm_param_len = elen; 193 ieee80211_tx_skb(sdata, skb, 0);
162 } 194}
163 } 195
164 } 196static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
165 break; 197 struct ieee80211_if_sta *ifsta)
166 case WLAN_EID_RSN: 198{
167 elems->rsn = pos; 199 struct ieee80211_local *local = sdata->local;
168 elems->rsn_len = elen; 200 struct sk_buff *skb;
169 break; 201 struct ieee80211_mgmt *mgmt;
170 case WLAN_EID_ERP_INFO: 202 u8 *pos, *ies, *ht_add_ie;
171 elems->erp_info = pos; 203 int i, len, count, rates_len, supp_rates_len;
172 elems->erp_info_len = elen; 204 u16 capab;
173 break; 205 struct ieee80211_sta_bss *bss;
174 case WLAN_EID_EXT_SUPP_RATES: 206 int wmm = 0;
175 elems->ext_supp_rates = pos; 207 struct ieee80211_supported_band *sband;
176 elems->ext_supp_rates_len = elen; 208 u64 rates = 0;
177 break; 209
178 case WLAN_EID_HT_CAPABILITY: 210 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
179 elems->ht_cap_elem = pos; 211 sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
180 elems->ht_cap_elem_len = elen; 212 ifsta->ssid_len);
181 break; 213 if (!skb) {
182 case WLAN_EID_HT_EXTRA_INFO: 214 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
183 elems->ht_info_elem = pos; 215 "frame\n", sdata->dev->name);
184 elems->ht_info_elem_len = elen; 216 return;
185 break; 217 }
186 case WLAN_EID_MESH_ID: 218 skb_reserve(skb, local->hw.extra_tx_headroom);
187 elems->mesh_id = pos; 219
188 elems->mesh_id_len = elen; 220 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
189 break; 221
190 case WLAN_EID_MESH_CONFIG: 222 capab = ifsta->capab;
191 elems->mesh_config = pos; 223
192 elems->mesh_config_len = elen; 224 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
193 break; 225 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
194 case WLAN_EID_PEER_LINK: 226 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
195 elems->peer_link = pos; 227 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
196 elems->peer_link_len = elen; 228 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
197 break; 229 }
198 case WLAN_EID_PREQ: 230
199 elems->preq = pos; 231 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
200 elems->preq_len = elen; 232 local->hw.conf.channel->center_freq,
201 break; 233 ifsta->ssid, ifsta->ssid_len);
202 case WLAN_EID_PREP: 234 if (bss) {
203 elems->prep = pos; 235 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
204 elems->prep_len = elen; 236 capab |= WLAN_CAPABILITY_PRIVACY;
205 break; 237 if (bss->wmm_used)
206 case WLAN_EID_PERR: 238 wmm = 1;
207 elems->perr = pos; 239
208 elems->perr_len = elen; 240 /* get all rates supported by the device and the AP as
209 break; 241 * some APs don't like getting a superset of their rates
210 case WLAN_EID_CHANNEL_SWITCH: 242 * in the association request (e.g. D-Link DAP 1353 in
211 elems->ch_switch_elem = pos; 243 * b-only mode) */
212 elems->ch_switch_elem_len = elen; 244 rates_len = ieee80211_compatible_rates(bss, sband, &rates);
213 break; 245
214 case WLAN_EID_QUIET: 246 if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
215 if (!elems->quiet_elem) { 247 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
216 elems->quiet_elem = pos; 248 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
217 elems->quiet_elem_len = elen; 249
250 ieee80211_rx_bss_put(local, bss);
251 } else {
252 rates = ~0;
253 rates_len = sband->n_bitrates;
254 }
255
256 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
257 memset(mgmt, 0, 24);
258 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
259 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
260 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
261
262 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
263 skb_put(skb, 10);
264 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
265 IEEE80211_STYPE_REASSOC_REQ);
266 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
267 mgmt->u.reassoc_req.listen_interval =
268 cpu_to_le16(local->hw.conf.listen_interval);
269 memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
270 ETH_ALEN);
271 } else {
272 skb_put(skb, 4);
273 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
274 IEEE80211_STYPE_ASSOC_REQ);
275 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
276 mgmt->u.reassoc_req.listen_interval =
277 cpu_to_le16(local->hw.conf.listen_interval);
278 }
279
280 /* SSID */
281 ies = pos = skb_put(skb, 2 + ifsta->ssid_len);
282 *pos++ = WLAN_EID_SSID;
283 *pos++ = ifsta->ssid_len;
284 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
285
286 /* add all rates which were marked to be used above */
287 supp_rates_len = rates_len;
288 if (supp_rates_len > 8)
289 supp_rates_len = 8;
290
291 len = sband->n_bitrates;
292 pos = skb_put(skb, supp_rates_len + 2);
293 *pos++ = WLAN_EID_SUPP_RATES;
294 *pos++ = supp_rates_len;
295
296 count = 0;
297 for (i = 0; i < sband->n_bitrates; i++) {
298 if (BIT(i) & rates) {
299 int rate = sband->bitrates[i].bitrate;
300 *pos++ = (u8) (rate / 5);
301 if (++count == 8)
302 break;
303 }
304 }
305
306 if (rates_len > count) {
307 pos = skb_put(skb, rates_len - count + 2);
308 *pos++ = WLAN_EID_EXT_SUPP_RATES;
309 *pos++ = rates_len - count;
310
311 for (i++; i < sband->n_bitrates; i++) {
312 if (BIT(i) & rates) {
313 int rate = sband->bitrates[i].bitrate;
314 *pos++ = (u8) (rate / 5);
218 } 315 }
219 elems->num_of_quiet_elem++;
220 break;
221 case WLAN_EID_COUNTRY:
222 elems->country_elem = pos;
223 elems->country_elem_len = elen;
224 break;
225 case WLAN_EID_PWR_CONSTRAINT:
226 elems->pwr_constr_elem = pos;
227 elems->pwr_constr_elem_len = elen;
228 break;
229 default:
230 break;
231 } 316 }
317 }
318
319 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
320 /* 1. power capabilities */
321 pos = skb_put(skb, 4);
322 *pos++ = WLAN_EID_PWR_CAPABILITY;
323 *pos++ = 2;
324 *pos++ = 0; /* min tx power */
325 *pos++ = local->hw.conf.channel->max_power; /* max tx power */
232 326
233 left -= elen; 327 /* 2. supported channels */
234 pos += elen; 328 /* TODO: get this in reg domain format */
329 pos = skb_put(skb, 2 * sband->n_channels + 2);
330 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
331 *pos++ = 2 * sband->n_channels;
332 for (i = 0; i < sband->n_channels; i++) {
333 *pos++ = ieee80211_frequency_to_channel(
334 sband->channels[i].center_freq);
335 *pos++ = 1; /* one channel in the subband*/
336 }
235 } 337 }
236}
237 338
339 if (ifsta->extra_ie) {
340 pos = skb_put(skb, ifsta->extra_ie_len);
341 memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
342 }
238 343
239static u8 * ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie) 344 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
240{ 345 pos = skb_put(skb, 9);
241 u8 *end, *pos; 346 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
347 *pos++ = 7; /* len */
348 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
349 *pos++ = 0x50;
350 *pos++ = 0xf2;
351 *pos++ = 2; /* WME */
352 *pos++ = 0; /* WME info */
353 *pos++ = 1; /* WME ver */
354 *pos++ = 0;
355 }
242 356
243 pos = bss->ies; 357 /* wmm support is a must to HT */
244 if (pos == NULL) 358 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
245 return NULL; 359 sband->ht_info.ht_supported &&
246 end = pos + bss->ies_len; 360 (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
361 struct ieee80211_ht_addt_info *ht_add_info =
362 (struct ieee80211_ht_addt_info *)ht_add_ie;
363 u16 cap = sband->ht_info.cap;
364 __le16 tmp;
365 u32 flags = local->hw.conf.channel->flags;
247 366
248 while (pos + 1 < end) { 367 switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
249 if (pos + 2 + pos[1] > end) 368 case IEEE80211_HT_IE_CHA_SEC_ABOVE:
369 if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
370 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
371 cap &= ~IEEE80211_HT_CAP_SGI_40;
372 }
250 break; 373 break;
251 if (pos[0] == ie) 374 case IEEE80211_HT_IE_CHA_SEC_BELOW:
252 return pos; 375 if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
253 pos += 2 + pos[1]; 376 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
377 cap &= ~IEEE80211_HT_CAP_SGI_40;
378 }
379 break;
380 }
381
382 tmp = cpu_to_le16(cap);
383 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
384 *pos++ = WLAN_EID_HT_CAPABILITY;
385 *pos++ = sizeof(struct ieee80211_ht_cap);
386 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
387 memcpy(pos, &tmp, sizeof(u16));
388 pos += sizeof(u16);
389 /* TODO: needs a define here for << 2 */
390 *pos++ = sband->ht_info.ampdu_factor |
391 (sband->ht_info.ampdu_density << 2);
392 memcpy(pos, sband->ht_info.supp_mcs_set, 16);
254 } 393 }
255 394
256 return NULL; 395 kfree(ifsta->assocreq_ies);
396 ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
397 ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
398 if (ifsta->assocreq_ies)
399 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);
400
401 ieee80211_tx_skb(sdata, skb, 0);
257} 402}
258 403
259 404
260static int ecw2cw(int ecw) 405static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
406 u16 stype, u16 reason)
261{ 407{
262 return (1 << ecw) - 1; 408 struct ieee80211_local *local = sdata->local;
263} 409 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
410 struct sk_buff *skb;
411 struct ieee80211_mgmt *mgmt;
264 412
413 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
414 if (!skb) {
415 printk(KERN_DEBUG "%s: failed to allocate buffer for "
416 "deauth/disassoc frame\n", sdata->dev->name);
417 return;
418 }
419 skb_reserve(skb, local->hw.extra_tx_headroom);
265 420
421 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
422 memset(mgmt, 0, 24);
423 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
424 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
425 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
426 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
427 skb_put(skb, 2);
428 /* u.deauth.reason_code == u.disassoc.reason_code */
429 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
430
431 ieee80211_tx_skb(sdata, skb, 0);
432}
433
434/* MLME */
266static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 435static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
267 struct ieee80211_sta_bss *bss, 436 struct ieee80211_sta_bss *bss)
268 int ibss)
269{ 437{
270 struct ieee80211_local *local = sdata->local; 438 struct ieee80211_local *local = sdata->local;
271 int i, have_higher_than_11mbit = 0; 439 int i, have_higher_than_11mbit = 0;
272 440
273
274 /* cf. IEEE 802.11 9.2.12 */ 441 /* cf. IEEE 802.11 9.2.12 */
275 for (i = 0; i < bss->supp_rates_len; i++) 442 for (i = 0; i < bss->supp_rates_len; i++)
276 if ((bss->supp_rates[i] & 0x7f) * 5 > 110) 443 if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
@@ -282,26 +449,7 @@ static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
282 else 449 else
283 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; 450 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
284 451
285 452 ieee80211_set_wmm_default(sdata);
286 if (local->ops->conf_tx) {
287 struct ieee80211_tx_queue_params qparam;
288
289 memset(&qparam, 0, sizeof(qparam));
290
291 qparam.aifs = 2;
292
293 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
294 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
295 qparam.cw_min = 31;
296 else
297 qparam.cw_min = 15;
298
299 qparam.cw_max = 1023;
300 qparam.txop = 0;
301
302 for (i = 0; i < local_to_hw(local)->queues; i++)
303 local->ops->conf_tx(local_to_hw(local), i, &qparam);
304 }
305} 453}
306 454
307static void ieee80211_sta_wmm_params(struct ieee80211_local *local, 455static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
@@ -451,50 +599,15 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
451 return changed; 599 return changed;
452} 600}
453 601
454int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, 602static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
455 struct ieee80211_ht_info *ht_info) 603 struct ieee80211_if_sta *ifsta)
456{ 604{
457 605 union iwreq_data wrqu;
458 if (ht_info == NULL) 606 memset(&wrqu, 0, sizeof(wrqu));
459 return -EINVAL; 607 if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
460 608 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
461 memset(ht_info, 0, sizeof(*ht_info)); 609 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
462 610 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
463 if (ht_cap_ie) {
464 u8 ampdu_info = ht_cap_ie->ampdu_params_info;
465
466 ht_info->ht_supported = 1;
467 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
468 ht_info->ampdu_factor =
469 ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
470 ht_info->ampdu_density =
471 (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
472 memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
473 } else
474 ht_info->ht_supported = 0;
475
476 return 0;
477}
478
479int ieee80211_ht_addt_info_ie_to_ht_bss_info(
480 struct ieee80211_ht_addt_info *ht_add_info_ie,
481 struct ieee80211_ht_bss_info *bss_info)
482{
483 if (bss_info == NULL)
484 return -EINVAL;
485
486 memset(bss_info, 0, sizeof(*bss_info));
487
488 if (ht_add_info_ie) {
489 u16 op_mode;
490 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
491
492 bss_info->primary_channel = ht_add_info_ie->control_chan;
493 bss_info->bss_cap = ht_add_info_ie->ht_param;
494 bss_info->bss_op_mode = (u8)(op_mode & 0xff);
495 }
496
497 return 0;
498} 611}
499 612
500static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, 613static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
@@ -518,134 +631,54 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
518 631
519 632
520static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 633static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
521 struct ieee80211_if_sta *ifsta, 634 struct ieee80211_if_sta *ifsta)
522 bool assoc)
523{ 635{
524 struct ieee80211_local *local = sdata->local; 636 struct ieee80211_local *local = sdata->local;
525 struct ieee80211_conf *conf = &local_to_hw(local)->conf; 637 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
526 union iwreq_data wrqu;
527 u32 changed = BSS_CHANGED_ASSOC; 638 u32 changed = BSS_CHANGED_ASSOC;
528 639
529 if (assoc) { 640 struct ieee80211_sta_bss *bss;
530 struct ieee80211_sta_bss *bss;
531
532 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
533
534 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
535 return;
536
537 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
538 conf->channel->center_freq,
539 ifsta->ssid, ifsta->ssid_len);
540 if (bss) {
541 /* set timing information */
542 sdata->bss_conf.beacon_int = bss->beacon_int;
543 sdata->bss_conf.timestamp = bss->timestamp;
544 sdata->bss_conf.dtim_period = bss->dtim_period;
545
546 changed |= ieee80211_handle_bss_capability(sdata, bss);
547 641
548 ieee80211_rx_bss_put(local, bss); 642 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
549 }
550 643
551 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { 644 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
552 changed |= BSS_CHANGED_HT; 645 return;
553 sdata->bss_conf.assoc_ht = 1;
554 sdata->bss_conf.ht_conf = &conf->ht_conf;
555 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
556 }
557 646
558 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; 647 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
559 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); 648 conf->channel->center_freq,
560 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); 649 ifsta->ssid, ifsta->ssid_len);
561 ieee80211_sta_send_associnfo(sdata, ifsta); 650 if (bss) {
562 } else { 651 /* set timing information */
563 netif_carrier_off(sdata->dev); 652 sdata->bss_conf.beacon_int = bss->beacon_int;
564 ieee80211_sta_tear_down_BA_sessions(sdata, ifsta->bssid); 653 sdata->bss_conf.timestamp = bss->timestamp;
565 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; 654 sdata->bss_conf.dtim_period = bss->dtim_period;
566 changed |= ieee80211_reset_erp_info(sdata);
567 655
568 sdata->bss_conf.assoc_ht = 0; 656 changed |= ieee80211_handle_bss_capability(sdata, bss);
569 sdata->bss_conf.ht_conf = NULL;
570 sdata->bss_conf.ht_bss_conf = NULL;
571 657
572 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 658 ieee80211_rx_bss_put(local, bss);
573 } 659 }
574 ifsta->last_probe = jiffies;
575 ieee80211_led_assoc(local, assoc);
576
577 sdata->bss_conf.assoc = assoc;
578 ieee80211_bss_info_change_notify(sdata, changed);
579
580 if (assoc)
581 netif_carrier_on(sdata->dev);
582
583 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
584 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
585}
586 660
587static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 661 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
588 struct ieee80211_if_sta *ifsta, int deauth) 662 changed |= BSS_CHANGED_HT;
589{ 663 sdata->bss_conf.assoc_ht = 1;
590 if (deauth) { 664 sdata->bss_conf.ht_conf = &conf->ht_conf;
591 ifsta->direct_probe_tries = 0; 665 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
592 ifsta->auth_tries = 0;
593 } 666 }
594 ifsta->assoc_scan_tries = 0;
595 ifsta->assoc_tries = 0;
596 ieee80211_set_associated(sdata, ifsta, 0);
597}
598
599void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
600 int encrypt)
601{
602 skb->dev = sdata->local->mdev;
603 skb_set_mac_header(skb, 0);
604 skb_set_network_header(skb, 0);
605 skb_set_transport_header(skb, 0);
606 667
607 skb->iif = sdata->dev->ifindex; 668 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
608 skb->do_not_encrypt = !encrypt; 669 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
670 ieee80211_sta_send_associnfo(sdata, ifsta);
609 671
610 dev_queue_xmit(skb); 672 ifsta->last_probe = jiffies;
611} 673 ieee80211_led_assoc(local, 1);
612
613
614static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
615 struct ieee80211_if_sta *ifsta,
616 int transaction, u8 *extra, size_t extra_len,
617 int encrypt)
618{
619 struct ieee80211_local *local = sdata->local;
620 struct sk_buff *skb;
621 struct ieee80211_mgmt *mgmt;
622 674
623 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 675 sdata->bss_conf.assoc = 1;
624 sizeof(*mgmt) + 6 + extra_len); 676 ieee80211_bss_info_change_notify(sdata, changed);
625 if (!skb) {
626 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
627 "frame\n", sdata->dev->name);
628 return;
629 }
630 skb_reserve(skb, local->hw.extra_tx_headroom);
631 677
632 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 678 netif_tx_start_all_queues(sdata->dev);
633 memset(mgmt, 0, 24 + 6); 679 netif_carrier_on(sdata->dev);
634 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
635 IEEE80211_STYPE_AUTH);
636 if (encrypt)
637 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
638 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
639 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
640 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
641 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg);
642 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
643 ifsta->auth_transaction = transaction + 1;
644 mgmt->u.auth.status_code = cpu_to_le16(0);
645 if (extra)
646 memcpy(skb_put(skb, extra_len), extra, extra_len);
647 680
648 ieee80211_sta_tx(sdata, skb, encrypt); 681 ieee80211_sta_send_apinfo(sdata, ifsta);
649} 682}
650 683
651static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, 684static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
@@ -702,294 +735,76 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
702 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); 735 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
703} 736}
704 737
705static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss, 738static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
706 struct ieee80211_supported_band *sband, 739 struct ieee80211_if_sta *ifsta, bool deauth,
707 u64 *rates) 740 bool self_disconnected, u16 reason)
708{
709 int i, j, count;
710 *rates = 0;
711 count = 0;
712 for (i = 0; i < bss->supp_rates_len; i++) {
713 int rate = (bss->supp_rates[i] & 0x7F) * 5;
714
715 for (j = 0; j < sband->n_bitrates; j++)
716 if (sband->bitrates[j].bitrate == rate) {
717 *rates |= BIT(j);
718 count++;
719 break;
720 }
721 }
722
723 return count;
724}
725
726static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
727 struct ieee80211_if_sta *ifsta)
728{ 741{
729 struct ieee80211_local *local = sdata->local; 742 struct ieee80211_local *local = sdata->local;
730 struct sk_buff *skb; 743 struct sta_info *sta;
731 struct ieee80211_mgmt *mgmt; 744 u32 changed = BSS_CHANGED_ASSOC;
732 u8 *pos, *ies, *ht_add_ie;
733 int i, len, count, rates_len, supp_rates_len;
734 u16 capab;
735 struct ieee80211_sta_bss *bss;
736 int wmm = 0;
737 struct ieee80211_supported_band *sband;
738 u64 rates = 0;
739
740 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
741 sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
742 ifsta->ssid_len);
743 if (!skb) {
744 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
745 "frame\n", sdata->dev->name);
746 return;
747 }
748 skb_reserve(skb, local->hw.extra_tx_headroom);
749
750 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
751
752 capab = ifsta->capab;
753
754 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
755 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
756 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
757 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
758 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
759 }
760
761 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
762 local->hw.conf.channel->center_freq,
763 ifsta->ssid, ifsta->ssid_len);
764 if (bss) {
765 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
766 capab |= WLAN_CAPABILITY_PRIVACY;
767 if (bss->wmm_used)
768 wmm = 1;
769
770 /* get all rates supported by the device and the AP as
771 * some APs don't like getting a superset of their rates
772 * in the association request (e.g. D-Link DAP 1353 in
773 * b-only mode) */
774 rates_len = ieee80211_compatible_rates(bss, sband, &rates);
775
776 if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
777 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
778 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
779
780 ieee80211_rx_bss_put(local, bss);
781 } else {
782 rates = ~0;
783 rates_len = sband->n_bitrates;
784 }
785
786 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
787 memset(mgmt, 0, 24);
788 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
789 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
790 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
791
792 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
793 skb_put(skb, 10);
794 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
795 IEEE80211_STYPE_REASSOC_REQ);
796 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
797 mgmt->u.reassoc_req.listen_interval =
798 cpu_to_le16(local->hw.conf.listen_interval);
799 memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
800 ETH_ALEN);
801 } else {
802 skb_put(skb, 4);
803 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
804 IEEE80211_STYPE_ASSOC_REQ);
805 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
806 mgmt->u.reassoc_req.listen_interval =
807 cpu_to_le16(local->hw.conf.listen_interval);
808 }
809
810 /* SSID */
811 ies = pos = skb_put(skb, 2 + ifsta->ssid_len);
812 *pos++ = WLAN_EID_SSID;
813 *pos++ = ifsta->ssid_len;
814 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
815
816 /* add all rates which were marked to be used above */
817 supp_rates_len = rates_len;
818 if (supp_rates_len > 8)
819 supp_rates_len = 8;
820 745
821 len = sband->n_bitrates; 746 rcu_read_lock();
822 pos = skb_put(skb, supp_rates_len + 2);
823 *pos++ = WLAN_EID_SUPP_RATES;
824 *pos++ = supp_rates_len;
825 747
826 count = 0; 748 sta = sta_info_get(local, ifsta->bssid);
827 for (i = 0; i < sband->n_bitrates; i++) { 749 if (!sta) {
828 if (BIT(i) & rates) { 750 rcu_read_unlock();
829 int rate = sband->bitrates[i].bitrate; 751 return;
830 *pos++ = (u8) (rate / 5);
831 if (++count == 8)
832 break;
833 }
834 } 752 }
835 753
836 if (rates_len > count) { 754 if (deauth) {
837 pos = skb_put(skb, rates_len - count + 2); 755 ifsta->direct_probe_tries = 0;
838 *pos++ = WLAN_EID_EXT_SUPP_RATES; 756 ifsta->auth_tries = 0;
839 *pos++ = rates_len - count;
840
841 for (i++; i < sband->n_bitrates; i++) {
842 if (BIT(i) & rates) {
843 int rate = sband->bitrates[i].bitrate;
844 *pos++ = (u8) (rate / 5);
845 }
846 }
847 } 757 }
758 ifsta->assoc_scan_tries = 0;
759 ifsta->assoc_tries = 0;
848 760
849 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { 761 netif_tx_stop_all_queues(sdata->dev);
850 /* 1. power capabilities */ 762 netif_carrier_off(sdata->dev);
851 pos = skb_put(skb, 4);
852 *pos++ = WLAN_EID_PWR_CAPABILITY;
853 *pos++ = 2;
854 *pos++ = 0; /* min tx power */
855 *pos++ = local->hw.conf.channel->max_power; /* max tx power */
856
857 /* 2. supported channels */
858 /* TODO: get this in reg domain format */
859 pos = skb_put(skb, 2 * sband->n_channels + 2);
860 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
861 *pos++ = 2 * sband->n_channels;
862 for (i = 0; i < sband->n_channels; i++) {
863 *pos++ = ieee80211_frequency_to_channel(
864 sband->channels[i].center_freq);
865 *pos++ = 1; /* one channel in the subband*/
866 }
867 }
868 763
869 if (ifsta->extra_ie) { 764 ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr);
870 pos = skb_put(skb, ifsta->extra_ie_len);
871 memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
872 }
873 765
874 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { 766 if (self_disconnected) {
875 pos = skb_put(skb, 9); 767 if (deauth)
876 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 768 ieee80211_send_deauth_disassoc(sdata,
877 *pos++ = 7; /* len */ 769 IEEE80211_STYPE_DEAUTH, reason);
878 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ 770 else
879 *pos++ = 0x50; 771 ieee80211_send_deauth_disassoc(sdata,
880 *pos++ = 0xf2; 772 IEEE80211_STYPE_DISASSOC, reason);
881 *pos++ = 2; /* WME */
882 *pos++ = 0; /* WME info */
883 *pos++ = 1; /* WME ver */
884 *pos++ = 0;
885 } 773 }
886 774
887 /* wmm support is a must to HT */ 775 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
888 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && 776 changed |= ieee80211_reset_erp_info(sdata);
889 sband->ht_info.ht_supported &&
890 (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
891 struct ieee80211_ht_addt_info *ht_add_info =
892 (struct ieee80211_ht_addt_info *)ht_add_ie;
893 u16 cap = sband->ht_info.cap;
894 __le16 tmp;
895 u32 flags = local->hw.conf.channel->flags;
896
897 switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
898 case IEEE80211_HT_IE_CHA_SEC_ABOVE:
899 if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
900 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
901 cap &= ~IEEE80211_HT_CAP_SGI_40;
902 }
903 break;
904 case IEEE80211_HT_IE_CHA_SEC_BELOW:
905 if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
906 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
907 cap &= ~IEEE80211_HT_CAP_SGI_40;
908 }
909 break;
910 }
911 777
912 tmp = cpu_to_le16(cap); 778 if (sdata->bss_conf.assoc_ht)
913 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); 779 changed |= BSS_CHANGED_HT;
914 *pos++ = WLAN_EID_HT_CAPABILITY;
915 *pos++ = sizeof(struct ieee80211_ht_cap);
916 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
917 memcpy(pos, &tmp, sizeof(u16));
918 pos += sizeof(u16);
919 /* TODO: needs a define here for << 2 */
920 *pos++ = sband->ht_info.ampdu_factor |
921 (sband->ht_info.ampdu_density << 2);
922 memcpy(pos, sband->ht_info.supp_mcs_set, 16);
923 }
924 780
925 kfree(ifsta->assocreq_ies); 781 sdata->bss_conf.assoc_ht = 0;
926 ifsta->assocreq_ies_len = (skb->data + skb->len) - ies; 782 sdata->bss_conf.ht_conf = NULL;
927 ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL); 783 sdata->bss_conf.ht_bss_conf = NULL;
928 if (ifsta->assocreq_ies)
929 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);
930 784
931 ieee80211_sta_tx(sdata, skb, 0); 785 ieee80211_led_assoc(local, 0);
932} 786 sdata->bss_conf.assoc = 0;
933 787
788 ieee80211_sta_send_apinfo(sdata, ifsta);
934 789
935static void ieee80211_send_deauth(struct ieee80211_sub_if_data *sdata, 790 if (self_disconnected)
936 struct ieee80211_if_sta *ifsta, u16 reason) 791 ifsta->state = IEEE80211_STA_MLME_DISABLED;
937{
938 struct ieee80211_local *local = sdata->local;
939 struct sk_buff *skb;
940 struct ieee80211_mgmt *mgmt;
941 792
942 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 793 sta_info_unlink(&sta);
943 if (!skb) {
944 printk(KERN_DEBUG "%s: failed to allocate buffer for deauth "
945 "frame\n", sdata->dev->name);
946 return;
947 }
948 skb_reserve(skb, local->hw.extra_tx_headroom);
949 794
950 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 795 rcu_read_unlock();
951 memset(mgmt, 0, 24);
952 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
953 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
954 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
955 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
956 IEEE80211_STYPE_DEAUTH);
957 skb_put(skb, 2);
958 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
959 796
960 ieee80211_sta_tx(sdata, skb, 0); 797 sta_info_destroy(sta);
961} 798}
962 799
963 800static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
964static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata,
965 struct ieee80211_if_sta *ifsta, u16 reason)
966{ 801{
967 struct ieee80211_local *local = sdata->local; 802 if (!sdata || !sdata->default_key ||
968 struct sk_buff *skb; 803 sdata->default_key->conf.alg != ALG_WEP)
969 struct ieee80211_mgmt *mgmt; 804 return 0;
970 805 return 1;
971 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
972 if (!skb) {
973 printk(KERN_DEBUG "%s: failed to allocate buffer for disassoc "
974 "frame\n", sdata->dev->name);
975 return;
976 }
977 skb_reserve(skb, local->hw.extra_tx_headroom);
978
979 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
980 memset(mgmt, 0, 24);
981 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
982 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
983 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
984 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
985 IEEE80211_STYPE_DISASSOC);
986 skb_put(skb, 2);
987 mgmt->u.disassoc.reason_code = cpu_to_le16(reason);
988
989 ieee80211_sta_tx(sdata, skb, 0);
990} 806}
991 807
992
993static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, 808static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
994 struct ieee80211_if_sta *ifsta) 809 struct ieee80211_if_sta *ifsta)
995{ 810{
@@ -1020,7 +835,6 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
1020 return 1; 835 return 1;
1021} 836}
1022 837
1023
1024static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, 838static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1025 struct ieee80211_if_sta *ifsta) 839 struct ieee80211_if_sta *ifsta)
1026{ 840{
@@ -1083,7 +897,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1083 "range\n", 897 "range\n",
1084 sdata->dev->name, print_mac(mac, ifsta->bssid)); 898 sdata->dev->name, print_mac(mac, ifsta->bssid));
1085 disassoc = 1; 899 disassoc = 1;
1086 sta_info_unlink(&sta);
1087 } else 900 } else
1088 ieee80211_send_probe_req(sdata, ifsta->bssid, 901 ieee80211_send_probe_req(sdata, ifsta->bssid,
1089 local->scan_ssid, 902 local->scan_ssid,
@@ -1103,86 +916,12 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1103 916
1104 rcu_read_unlock(); 917 rcu_read_unlock();
1105 918
1106 if (disassoc && sta) 919 if (disassoc)
1107 sta_info_destroy(sta); 920 ieee80211_set_disassoc(sdata, ifsta, true, true,
1108 921 WLAN_REASON_PREV_AUTH_NOT_VALID);
1109 if (disassoc) { 922 else
1110 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1111 ieee80211_set_associated(sdata, ifsta, 0);
1112 } else {
1113 mod_timer(&ifsta->timer, jiffies + 923 mod_timer(&ifsta->timer, jiffies +
1114 IEEE80211_MONITORING_INTERVAL); 924 IEEE80211_MONITORING_INTERVAL);
1115 }
1116}
1117
1118
1119static void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1120 u8 *ssid, size_t ssid_len)
1121{
1122 struct ieee80211_local *local = sdata->local;
1123 struct ieee80211_supported_band *sband;
1124 struct sk_buff *skb;
1125 struct ieee80211_mgmt *mgmt;
1126 u8 *pos, *supp_rates, *esupp_rates = NULL;
1127 int i;
1128
1129 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
1130 if (!skb) {
1131 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
1132 "request\n", sdata->dev->name);
1133 return;
1134 }
1135 skb_reserve(skb, local->hw.extra_tx_headroom);
1136
1137 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1138 memset(mgmt, 0, 24);
1139 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1140 IEEE80211_STYPE_PROBE_REQ);
1141 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1142 if (dst) {
1143 memcpy(mgmt->da, dst, ETH_ALEN);
1144 memcpy(mgmt->bssid, dst, ETH_ALEN);
1145 } else {
1146 memset(mgmt->da, 0xff, ETH_ALEN);
1147 memset(mgmt->bssid, 0xff, ETH_ALEN);
1148 }
1149 pos = skb_put(skb, 2 + ssid_len);
1150 *pos++ = WLAN_EID_SSID;
1151 *pos++ = ssid_len;
1152 memcpy(pos, ssid, ssid_len);
1153
1154 supp_rates = skb_put(skb, 2);
1155 supp_rates[0] = WLAN_EID_SUPP_RATES;
1156 supp_rates[1] = 0;
1157 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1158
1159 for (i = 0; i < sband->n_bitrates; i++) {
1160 struct ieee80211_rate *rate = &sband->bitrates[i];
1161 if (esupp_rates) {
1162 pos = skb_put(skb, 1);
1163 esupp_rates[1]++;
1164 } else if (supp_rates[1] == 8) {
1165 esupp_rates = skb_put(skb, 3);
1166 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
1167 esupp_rates[1] = 1;
1168 pos = &esupp_rates[2];
1169 } else {
1170 pos = skb_put(skb, 1);
1171 supp_rates[1]++;
1172 }
1173 *pos = rate->bitrate / 5;
1174 }
1175
1176 ieee80211_sta_tx(sdata, skb, 0);
1177}
1178
1179
1180static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
1181{
1182 if (!sdata || !sdata->default_key ||
1183 sdata->default_key->conf.alg != ALG_WEP)
1184 return 0;
1185 return 1;
1186} 925}
1187 926
1188 927
@@ -1211,652 +950,6 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1211 elems.challenge_len + 2, 1); 950 elems.challenge_len + 2, 1);
1212} 951}
1213 952
1214static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
1215 u8 dialog_token, u16 status, u16 policy,
1216 u16 buf_size, u16 timeout)
1217{
1218 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1219 struct ieee80211_local *local = sdata->local;
1220 struct sk_buff *skb;
1221 struct ieee80211_mgmt *mgmt;
1222 u16 capab;
1223
1224 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1225
1226 if (!skb) {
1227 printk(KERN_DEBUG "%s: failed to allocate buffer "
1228 "for addba resp frame\n", sdata->dev->name);
1229 return;
1230 }
1231
1232 skb_reserve(skb, local->hw.extra_tx_headroom);
1233 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1234 memset(mgmt, 0, 24);
1235 memcpy(mgmt->da, da, ETH_ALEN);
1236 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1237 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1238 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1239 else
1240 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1241 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1242 IEEE80211_STYPE_ACTION);
1243
1244 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
1245 mgmt->u.action.category = WLAN_CATEGORY_BACK;
1246 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
1247 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
1248
1249 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
1250 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
1251 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
1252
1253 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
1254 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
1255 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
1256
1257 ieee80211_sta_tx(sdata, skb, 0);
1258
1259 return;
1260}
1261
1262void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
1263 u16 tid, u8 dialog_token, u16 start_seq_num,
1264 u16 agg_size, u16 timeout)
1265{
1266 struct ieee80211_local *local = sdata->local;
1267 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1268 struct sk_buff *skb;
1269 struct ieee80211_mgmt *mgmt;
1270 u16 capab;
1271
1272 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1273
1274 if (!skb) {
1275 printk(KERN_ERR "%s: failed to allocate buffer "
1276 "for addba request frame\n", sdata->dev->name);
1277 return;
1278 }
1279 skb_reserve(skb, local->hw.extra_tx_headroom);
1280 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1281 memset(mgmt, 0, 24);
1282 memcpy(mgmt->da, da, ETH_ALEN);
1283 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1284 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1285 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1286 else
1287 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1288
1289 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1290 IEEE80211_STYPE_ACTION);
1291
1292 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
1293
1294 mgmt->u.action.category = WLAN_CATEGORY_BACK;
1295 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
1296
1297 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
1298 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
1299 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
1300 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
1301
1302 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
1303
1304 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
1305 mgmt->u.action.u.addba_req.start_seq_num =
1306 cpu_to_le16(start_seq_num << 4);
1307
1308 ieee80211_sta_tx(sdata, skb, 0);
1309}
1310
1311static void ieee80211_sta_process_addba_request(struct ieee80211_local *local,
1312 struct ieee80211_mgmt *mgmt,
1313 size_t len)
1314{
1315 struct ieee80211_hw *hw = &local->hw;
1316 struct ieee80211_conf *conf = &hw->conf;
1317 struct sta_info *sta;
1318 struct tid_ampdu_rx *tid_agg_rx;
1319 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1320 u8 dialog_token;
1321 int ret = -EOPNOTSUPP;
1322 DECLARE_MAC_BUF(mac);
1323
1324 rcu_read_lock();
1325
1326 sta = sta_info_get(local, mgmt->sa);
1327 if (!sta) {
1328 rcu_read_unlock();
1329 return;
1330 }
1331
1332 /* extract session parameters from addba request frame */
1333 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
1334 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
1335 start_seq_num =
1336 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1337
1338 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
1339 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
1340 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1341 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
1342
1343 status = WLAN_STATUS_REQUEST_DECLINED;
1344
1345 /* sanity check for incoming parameters:
1346 * check if configuration can support the BA policy
1347 * and if buffer size does not exceeds max value */
1348 if (((ba_policy != 1)
1349 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
1350 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
1351 status = WLAN_STATUS_INVALID_QOS_PARAM;
1352#ifdef CONFIG_MAC80211_HT_DEBUG
1353 if (net_ratelimit())
1354 printk(KERN_DEBUG "AddBA Req with bad params from "
1355 "%s on tid %u. policy %d, buffer size %d\n",
1356 print_mac(mac, mgmt->sa), tid, ba_policy,
1357 buf_size);
1358#endif /* CONFIG_MAC80211_HT_DEBUG */
1359 goto end_no_lock;
1360 }
1361 /* determine default buffer size */
1362 if (buf_size == 0) {
1363 struct ieee80211_supported_band *sband;
1364
1365 sband = local->hw.wiphy->bands[conf->channel->band];
1366 buf_size = IEEE80211_MIN_AMPDU_BUF;
1367 buf_size = buf_size << sband->ht_info.ampdu_factor;
1368 }
1369
1370
1371 /* examine state machine */
1372 spin_lock_bh(&sta->lock);
1373
1374 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1375#ifdef CONFIG_MAC80211_HT_DEBUG
1376 if (net_ratelimit())
1377 printk(KERN_DEBUG "unexpected AddBA Req from "
1378 "%s on tid %u\n",
1379 print_mac(mac, mgmt->sa), tid);
1380#endif /* CONFIG_MAC80211_HT_DEBUG */
1381 goto end;
1382 }
1383
1384 /* prepare A-MPDU MLME for Rx aggregation */
1385 sta->ampdu_mlme.tid_rx[tid] =
1386 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
1387 if (!sta->ampdu_mlme.tid_rx[tid]) {
1388#ifdef CONFIG_MAC80211_HT_DEBUG
1389 if (net_ratelimit())
1390 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
1391 tid);
1392#endif
1393 goto end;
1394 }
1395 /* rx timer */
1396 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
1397 sta_rx_agg_session_timer_expired;
1398 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
1399 (unsigned long)&sta->timer_to_tid[tid];
1400 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1401
1402 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
1403
1404 /* prepare reordering buffer */
1405 tid_agg_rx->reorder_buf =
1406 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
1407 if (!tid_agg_rx->reorder_buf) {
1408#ifdef CONFIG_MAC80211_HT_DEBUG
1409 if (net_ratelimit())
1410 printk(KERN_ERR "can not allocate reordering buffer "
1411 "to tid %d\n", tid);
1412#endif
1413 kfree(sta->ampdu_mlme.tid_rx[tid]);
1414 goto end;
1415 }
1416 memset(tid_agg_rx->reorder_buf, 0,
1417 buf_size * sizeof(struct sk_buff *));
1418
1419 if (local->ops->ampdu_action)
1420 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1421 sta->addr, tid, &start_seq_num);
1422#ifdef CONFIG_MAC80211_HT_DEBUG
1423 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1424#endif /* CONFIG_MAC80211_HT_DEBUG */
1425
1426 if (ret) {
1427 kfree(tid_agg_rx->reorder_buf);
1428 kfree(tid_agg_rx);
1429 sta->ampdu_mlme.tid_rx[tid] = NULL;
1430 goto end;
1431 }
1432
1433 /* change state and send addba resp */
1434 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1435 tid_agg_rx->dialog_token = dialog_token;
1436 tid_agg_rx->ssn = start_seq_num;
1437 tid_agg_rx->head_seq_num = start_seq_num;
1438 tid_agg_rx->buf_size = buf_size;
1439 tid_agg_rx->timeout = timeout;
1440 tid_agg_rx->stored_mpdu_num = 0;
1441 status = WLAN_STATUS_SUCCESS;
1442end:
1443 spin_unlock_bh(&sta->lock);
1444
1445end_no_lock:
1446 ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
1447 dialog_token, status, 1, buf_size, timeout);
1448 rcu_read_unlock();
1449}
1450
1451static void ieee80211_sta_process_addba_resp(struct ieee80211_local *local,
1452 struct ieee80211_mgmt *mgmt,
1453 size_t len)
1454{
1455 struct ieee80211_hw *hw = &local->hw;
1456 struct sta_info *sta;
1457 u16 capab;
1458 u16 tid;
1459 u8 *state;
1460
1461 rcu_read_lock();
1462
1463 sta = sta_info_get(local, mgmt->sa);
1464 if (!sta) {
1465 rcu_read_unlock();
1466 return;
1467 }
1468
1469 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1470 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1471
1472 state = &sta->ampdu_mlme.tid_state_tx[tid];
1473
1474 spin_lock_bh(&sta->lock);
1475
1476 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1477 spin_unlock_bh(&sta->lock);
1478 goto addba_resp_exit;
1479 }
1480
1481 if (mgmt->u.action.u.addba_resp.dialog_token !=
1482 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1483 spin_unlock_bh(&sta->lock);
1484#ifdef CONFIG_MAC80211_HT_DEBUG
1485 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1486#endif /* CONFIG_MAC80211_HT_DEBUG */
1487 goto addba_resp_exit;
1488 }
1489
1490 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1491#ifdef CONFIG_MAC80211_HT_DEBUG
1492 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1493#endif /* CONFIG_MAC80211_HT_DEBUG */
1494 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1495 == WLAN_STATUS_SUCCESS) {
1496 *state |= HT_ADDBA_RECEIVED_MSK;
1497 sta->ampdu_mlme.addba_req_num[tid] = 0;
1498
1499 if (*state == HT_AGG_STATE_OPERATIONAL)
1500 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1501
1502 spin_unlock_bh(&sta->lock);
1503 } else {
1504 sta->ampdu_mlme.addba_req_num[tid]++;
1505 /* this will allow the state check in stop_BA_session */
1506 *state = HT_AGG_STATE_OPERATIONAL;
1507 spin_unlock_bh(&sta->lock);
1508 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1509 WLAN_BACK_INITIATOR);
1510 }
1511
1512addba_resp_exit:
1513 rcu_read_unlock();
1514}
1515
1516void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
1517 u16 initiator, u16 reason_code)
1518{
1519 struct ieee80211_local *local = sdata->local;
1520 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1521 struct sk_buff *skb;
1522 struct ieee80211_mgmt *mgmt;
1523 u16 params;
1524
1525 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1526
1527 if (!skb) {
1528 printk(KERN_ERR "%s: failed to allocate buffer "
1529 "for delba frame\n", sdata->dev->name);
1530 return;
1531 }
1532
1533 skb_reserve(skb, local->hw.extra_tx_headroom);
1534 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1535 memset(mgmt, 0, 24);
1536 memcpy(mgmt->da, da, ETH_ALEN);
1537 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1538 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1539 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1540 else
1541 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1542 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1543 IEEE80211_STYPE_ACTION);
1544
1545 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
1546
1547 mgmt->u.action.category = WLAN_CATEGORY_BACK;
1548 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
1549 params = (u16)(initiator << 11); /* bit 11 initiator */
1550 params |= (u16)(tid << 12); /* bit 15:12 TID number */
1551
1552 mgmt->u.action.u.delba.params = cpu_to_le16(params);
1553 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
1554
1555 ieee80211_sta_tx(sdata, skb, 0);
1556}
1557
1558void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
1559{
1560 struct ieee80211_local *local = sdata->local;
1561 struct sk_buff *skb;
1562 struct ieee80211_bar *bar;
1563 u16 bar_control = 0;
1564
1565 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
1566 if (!skb) {
1567 printk(KERN_ERR "%s: failed to allocate buffer for "
1568 "bar frame\n", sdata->dev->name);
1569 return;
1570 }
1571 skb_reserve(skb, local->hw.extra_tx_headroom);
1572 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
1573 memset(bar, 0, sizeof(*bar));
1574 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
1575 IEEE80211_STYPE_BACK_REQ);
1576 memcpy(bar->ra, ra, ETH_ALEN);
1577 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
1578 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
1579 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
1580 bar_control |= (u16)(tid << 12);
1581 bar->control = cpu_to_le16(bar_control);
1582 bar->start_seq_num = cpu_to_le16(ssn);
1583
1584 ieee80211_sta_tx(sdata, skb, 0);
1585}
1586
1587void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
1588 u16 initiator, u16 reason)
1589{
1590 struct ieee80211_local *local = sdata->local;
1591 struct ieee80211_hw *hw = &local->hw;
1592 struct sta_info *sta;
1593 int ret, i;
1594 DECLARE_MAC_BUF(mac);
1595
1596 rcu_read_lock();
1597
1598 sta = sta_info_get(local, ra);
1599 if (!sta) {
1600 rcu_read_unlock();
1601 return;
1602 }
1603
1604 /* check if TID is in operational state */
1605 spin_lock_bh(&sta->lock);
1606 if (sta->ampdu_mlme.tid_state_rx[tid]
1607 != HT_AGG_STATE_OPERATIONAL) {
1608 spin_unlock_bh(&sta->lock);
1609 rcu_read_unlock();
1610 return;
1611 }
1612 sta->ampdu_mlme.tid_state_rx[tid] =
1613 HT_AGG_STATE_REQ_STOP_BA_MSK |
1614 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1615 spin_unlock_bh(&sta->lock);
1616
1617 /* stop HW Rx aggregation. ampdu_action existence
1618 * already verified in session init so we add the BUG_ON */
1619 BUG_ON(!local->ops->ampdu_action);
1620
1621#ifdef CONFIG_MAC80211_HT_DEBUG
1622 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
1623 print_mac(mac, ra), tid);
1624#endif /* CONFIG_MAC80211_HT_DEBUG */
1625
1626 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1627 ra, tid, NULL);
1628 if (ret)
1629 printk(KERN_DEBUG "HW problem - can not stop rx "
1630 "aggregation for tid %d\n", tid);
1631
1632 /* shutdown timer has not expired */
1633 if (initiator != WLAN_BACK_TIMER)
1634 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1635
1636 /* check if this is a self generated aggregation halt */
1637 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1638 ieee80211_send_delba(sdata, ra, tid, 0, reason);
1639
1640 /* free the reordering buffer */
1641 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1642 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1643 /* release the reordered frames */
1644 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1645 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1646 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1647 }
1648 }
1649 /* free resources */
1650 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1651 kfree(sta->ampdu_mlme.tid_rx[tid]);
1652 sta->ampdu_mlme.tid_rx[tid] = NULL;
1653 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1654
1655 rcu_read_unlock();
1656}
1657
1658
1659static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1660 struct ieee80211_mgmt *mgmt, size_t len)
1661{
1662 struct ieee80211_local *local = sdata->local;
1663 struct sta_info *sta;
1664 u16 tid, params;
1665 u16 initiator;
1666 DECLARE_MAC_BUF(mac);
1667
1668 rcu_read_lock();
1669
1670 sta = sta_info_get(local, mgmt->sa);
1671 if (!sta) {
1672 rcu_read_unlock();
1673 return;
1674 }
1675
1676 params = le16_to_cpu(mgmt->u.action.u.delba.params);
1677 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
1678 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
1679
1680#ifdef CONFIG_MAC80211_HT_DEBUG
1681 if (net_ratelimit())
1682 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
1683 print_mac(mac, mgmt->sa),
1684 initiator ? "initiator" : "recipient", tid,
1685 mgmt->u.action.u.delba.reason_code);
1686#endif /* CONFIG_MAC80211_HT_DEBUG */
1687
1688 if (initiator == WLAN_BACK_INITIATOR)
1689 ieee80211_sta_stop_rx_ba_session(sdata, sta->addr, tid,
1690 WLAN_BACK_INITIATOR, 0);
1691 else { /* WLAN_BACK_RECIPIENT */
1692 spin_lock_bh(&sta->lock);
1693 sta->ampdu_mlme.tid_state_tx[tid] =
1694 HT_AGG_STATE_OPERATIONAL;
1695 spin_unlock_bh(&sta->lock);
1696 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1697 WLAN_BACK_RECIPIENT);
1698 }
1699 rcu_read_unlock();
1700}
1701
1702/*
1703 * After sending add Block Ack request we activated a timer until
1704 * add Block Ack response will arrive from the recipient.
1705 * If this timer expires sta_addba_resp_timer_expired will be executed.
1706 */
1707void sta_addba_resp_timer_expired(unsigned long data)
1708{
1709 /* not an elegant detour, but there is no choice as the timer passes
1710 * only one argument, and both sta_info and TID are needed, so init
1711 * flow in sta_info_create gives the TID as data, while the timer_to_id
1712 * array gives the sta through container_of */
1713 u16 tid = *(u8 *)data;
1714 struct sta_info *temp_sta = container_of((void *)data,
1715 struct sta_info, timer_to_tid[tid]);
1716
1717 struct ieee80211_local *local = temp_sta->local;
1718 struct ieee80211_hw *hw = &local->hw;
1719 struct sta_info *sta;
1720 u8 *state;
1721
1722 rcu_read_lock();
1723
1724 sta = sta_info_get(local, temp_sta->addr);
1725 if (!sta) {
1726 rcu_read_unlock();
1727 return;
1728 }
1729
1730 state = &sta->ampdu_mlme.tid_state_tx[tid];
1731 /* check if the TID waits for addBA response */
1732 spin_lock_bh(&sta->lock);
1733 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1734 spin_unlock_bh(&sta->lock);
1735 *state = HT_AGG_STATE_IDLE;
1736#ifdef CONFIG_MAC80211_HT_DEBUG
1737 printk(KERN_DEBUG "timer expired on tid %d but we are not "
1738 "expecting addBA response there", tid);
1739#endif
1740 goto timer_expired_exit;
1741 }
1742
1743#ifdef CONFIG_MAC80211_HT_DEBUG
1744 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1745#endif
1746
1747 /* go through the state check in stop_BA_session */
1748 *state = HT_AGG_STATE_OPERATIONAL;
1749 spin_unlock_bh(&sta->lock);
1750 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1751 WLAN_BACK_INITIATOR);
1752
1753timer_expired_exit:
1754 rcu_read_unlock();
1755}
1756
1757/*
1758 * After accepting the AddBA Request we activated a timer,
1759 * resetting it after each frame that arrives from the originator.
1760 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
1761 */
1762static void sta_rx_agg_session_timer_expired(unsigned long data)
1763{
1764 /* not an elegant detour, but there is no choice as the timer passes
1765 * only one argument, and various sta_info are needed here, so init
1766 * flow in sta_info_create gives the TID as data, while the timer_to_id
1767 * array gives the sta through container_of */
1768 u8 *ptid = (u8 *)data;
1769 u8 *timer_to_id = ptid - *ptid;
1770 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
1771 timer_to_tid[0]);
1772
1773#ifdef CONFIG_MAC80211_HT_DEBUG
1774 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
1775#endif
1776 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->addr,
1777 (u16)*ptid, WLAN_BACK_TIMER,
1778 WLAN_REASON_QSTA_TIMEOUT);
1779}
1780
1781void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
1782{
1783 struct ieee80211_local *local = sdata->local;
1784 int i;
1785
1786 for (i = 0; i < STA_TID_NUM; i++) {
1787 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
1788 WLAN_BACK_INITIATOR);
1789 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
1790 WLAN_BACK_RECIPIENT,
1791 WLAN_REASON_QSTA_LEAVE_QBSS);
1792 }
1793}
1794
1795static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
1796 struct ieee80211_msrment_ie *request_ie,
1797 const u8 *da, const u8 *bssid,
1798 u8 dialog_token)
1799{
1800 struct ieee80211_local *local = sdata->local;
1801 struct sk_buff *skb;
1802 struct ieee80211_mgmt *msr_report;
1803
1804 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
1805 sizeof(struct ieee80211_msrment_ie));
1806
1807 if (!skb) {
1808 printk(KERN_ERR "%s: failed to allocate buffer for "
1809 "measurement report frame\n", sdata->dev->name);
1810 return;
1811 }
1812
1813 skb_reserve(skb, local->hw.extra_tx_headroom);
1814 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
1815 memset(msr_report, 0, 24);
1816 memcpy(msr_report->da, da, ETH_ALEN);
1817 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
1818 memcpy(msr_report->bssid, bssid, ETH_ALEN);
1819 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1820 IEEE80211_STYPE_ACTION);
1821
1822 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
1823 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
1824 msr_report->u.action.u.measurement.action_code =
1825 WLAN_ACTION_SPCT_MSR_RPRT;
1826 msr_report->u.action.u.measurement.dialog_token = dialog_token;
1827
1828 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
1829 msr_report->u.action.u.measurement.length =
1830 sizeof(struct ieee80211_msrment_ie);
1831
1832 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
1833 sizeof(struct ieee80211_msrment_ie));
1834 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
1835 msr_report->u.action.u.measurement.msr_elem.mode |=
1836 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
1837 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
1838
1839 ieee80211_sta_tx(sdata, skb, 0);
1840}
1841
1842static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1843 struct ieee80211_mgmt *mgmt,
1844 size_t len)
1845{
1846 /*
1847 * Ignoring measurement request is spec violation.
1848 * Mandatory measurements must be reported optional
1849 * measurements might be refused or reported incapable
1850 * For now just refuse
1851 * TODO: Answer basic measurement as unmeasured
1852 */
1853 ieee80211_send_refuse_measurement_request(sdata,
1854 &mgmt->u.action.u.measurement.msr_elem,
1855 mgmt->sa, mgmt->bssid,
1856 mgmt->u.action.u.measurement.dialog_token);
1857}
1858
1859
1860static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 953static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1861 struct ieee80211_if_sta *ifsta, 954 struct ieee80211_if_sta *ifsta,
1862 struct ieee80211_mgmt *mgmt, 955 struct ieee80211_mgmt *mgmt,
@@ -1977,7 +1070,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1977 IEEE80211_RETRY_AUTH_INTERVAL); 1070 IEEE80211_RETRY_AUTH_INTERVAL);
1978 } 1071 }
1979 1072
1980 ieee80211_set_disassoc(sdata, ifsta, 1); 1073 ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1981 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED; 1074 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1982} 1075}
1983 1076
@@ -2007,7 +1100,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2007 IEEE80211_RETRY_AUTH_INTERVAL); 1100 IEEE80211_RETRY_AUTH_INTERVAL);
2008 } 1101 }
2009 1102
2010 ieee80211_set_disassoc(sdata, ifsta, 0); 1103 ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
2011} 1104}
2012 1105
2013 1106
@@ -2201,209 +1294,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2201 * ieee80211_set_associated() will tell the driver */ 1294 * ieee80211_set_associated() will tell the driver */
2202 bss_conf->aid = aid; 1295 bss_conf->aid = aid;
2203 bss_conf->assoc_capability = capab_info; 1296 bss_conf->assoc_capability = capab_info;
2204 ieee80211_set_associated(sdata, ifsta, 1); 1297 ieee80211_set_associated(sdata, ifsta);
2205 1298
2206 ieee80211_associated(sdata, ifsta); 1299 ieee80211_associated(sdata, ifsta);
2207} 1300}
2208 1301
2209 1302
2210/* Caller must hold local->sta_bss_lock */
2211static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
2212 struct ieee80211_sta_bss *bss)
2213{
2214 u8 hash_idx;
2215
2216 if (bss_mesh_cfg(bss))
2217 hash_idx = mesh_id_hash(bss_mesh_id(bss),
2218 bss_mesh_id_len(bss));
2219 else
2220 hash_idx = STA_HASH(bss->bssid);
2221
2222 bss->hnext = local->sta_bss_hash[hash_idx];
2223 local->sta_bss_hash[hash_idx] = bss;
2224}
2225
2226
2227/* Caller must hold local->sta_bss_lock */
2228static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
2229 struct ieee80211_sta_bss *bss)
2230{
2231 struct ieee80211_sta_bss *b, *prev = NULL;
2232 b = local->sta_bss_hash[STA_HASH(bss->bssid)];
2233 while (b) {
2234 if (b == bss) {
2235 if (!prev)
2236 local->sta_bss_hash[STA_HASH(bss->bssid)] =
2237 bss->hnext;
2238 else
2239 prev->hnext = bss->hnext;
2240 break;
2241 }
2242 prev = b;
2243 b = b->hnext;
2244 }
2245}
2246
2247
2248static struct ieee80211_sta_bss *
2249ieee80211_rx_bss_add(struct ieee80211_sub_if_data *sdata, u8 *bssid, int freq,
2250 u8 *ssid, u8 ssid_len)
2251{
2252 struct ieee80211_local *local = sdata->local;
2253 struct ieee80211_sta_bss *bss;
2254
2255 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2256 if (!bss)
2257 return NULL;
2258 atomic_inc(&bss->users);
2259 atomic_inc(&bss->users);
2260 memcpy(bss->bssid, bssid, ETH_ALEN);
2261 bss->freq = freq;
2262 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
2263 memcpy(bss->ssid, ssid, ssid_len);
2264 bss->ssid_len = ssid_len;
2265 }
2266
2267 spin_lock_bh(&local->sta_bss_lock);
2268 /* TODO: order by RSSI? */
2269 list_add_tail(&bss->list, &local->sta_bss_list);
2270 __ieee80211_rx_bss_hash_add(local, bss);
2271 spin_unlock_bh(&local->sta_bss_lock);
2272 return bss;
2273}
2274
2275static struct ieee80211_sta_bss *
2276ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
2277 u8 *ssid, u8 ssid_len)
2278{
2279 struct ieee80211_sta_bss *bss;
2280
2281 spin_lock_bh(&local->sta_bss_lock);
2282 bss = local->sta_bss_hash[STA_HASH(bssid)];
2283 while (bss) {
2284 if (!bss_mesh_cfg(bss) &&
2285 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
2286 bss->freq == freq &&
2287 bss->ssid_len == ssid_len &&
2288 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
2289 atomic_inc(&bss->users);
2290 break;
2291 }
2292 bss = bss->hnext;
2293 }
2294 spin_unlock_bh(&local->sta_bss_lock);
2295 return bss;
2296}
2297
2298#ifdef CONFIG_MAC80211_MESH
2299static struct ieee80211_sta_bss *
2300ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2301 u8 *mesh_cfg, int freq)
2302{
2303 struct ieee80211_sta_bss *bss;
2304
2305 spin_lock_bh(&local->sta_bss_lock);
2306 bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
2307 while (bss) {
2308 if (bss_mesh_cfg(bss) &&
2309 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
2310 bss->freq == freq &&
2311 mesh_id_len == bss->mesh_id_len &&
2312 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
2313 mesh_id_len))) {
2314 atomic_inc(&bss->users);
2315 break;
2316 }
2317 bss = bss->hnext;
2318 }
2319 spin_unlock_bh(&local->sta_bss_lock);
2320 return bss;
2321}
2322
2323static struct ieee80211_sta_bss *
2324ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2325 u8 *mesh_cfg, int mesh_config_len, int freq)
2326{
2327 struct ieee80211_sta_bss *bss;
2328
2329 if (mesh_config_len != MESH_CFG_LEN)
2330 return NULL;
2331
2332 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2333 if (!bss)
2334 return NULL;
2335
2336 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
2337 if (!bss->mesh_cfg) {
2338 kfree(bss);
2339 return NULL;
2340 }
2341
2342 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
2343 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
2344 if (!bss->mesh_id) {
2345 kfree(bss->mesh_cfg);
2346 kfree(bss);
2347 return NULL;
2348 }
2349 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
2350 }
2351
2352 atomic_inc(&bss->users);
2353 atomic_inc(&bss->users);
2354 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
2355 bss->mesh_id_len = mesh_id_len;
2356 bss->freq = freq;
2357 spin_lock_bh(&local->sta_bss_lock);
2358 /* TODO: order by RSSI? */
2359 list_add_tail(&bss->list, &local->sta_bss_list);
2360 __ieee80211_rx_bss_hash_add(local, bss);
2361 spin_unlock_bh(&local->sta_bss_lock);
2362 return bss;
2363}
2364#endif
2365
2366static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2367{
2368 kfree(bss->ies);
2369 kfree(bss_mesh_id(bss));
2370 kfree(bss_mesh_cfg(bss));
2371 kfree(bss);
2372}
2373
2374
2375static void ieee80211_rx_bss_put(struct ieee80211_local *local,
2376 struct ieee80211_sta_bss *bss)
2377{
2378 local_bh_disable();
2379 if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
2380 local_bh_enable();
2381 return;
2382 }
2383
2384 __ieee80211_rx_bss_hash_del(local, bss);
2385 list_del(&bss->list);
2386 spin_unlock_bh(&local->sta_bss_lock);
2387 ieee80211_rx_bss_free(bss);
2388}
2389
2390
2391void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
2392{
2393 spin_lock_init(&local->sta_bss_lock);
2394 INIT_LIST_HEAD(&local->sta_bss_list);
2395}
2396
2397
2398void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
2399{
2400 struct ieee80211_sta_bss *bss, *tmp;
2401
2402 list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
2403 ieee80211_rx_bss_put(local, bss);
2404}
2405
2406
2407static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 1303static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2408 struct ieee80211_if_sta *ifsta, 1304 struct ieee80211_if_sta *ifsta,
2409 struct ieee80211_sta_bss *bss) 1305 struct ieee80211_sta_bss *bss)
@@ -2508,7 +1404,7 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2508 } 1404 }
2509 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; 1405 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2510 1406
2511 ieee80211_sta_def_wmm_params(sdata, bss, 1); 1407 ieee80211_sta_def_wmm_params(sdata, bss);
2512 1408
2513 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED; 1409 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2514 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 1410 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
@@ -2588,21 +1484,29 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2588 struct ieee80211_mgmt *mgmt, 1484 struct ieee80211_mgmt *mgmt,
2589 size_t len, 1485 size_t len,
2590 struct ieee80211_rx_status *rx_status, 1486 struct ieee80211_rx_status *rx_status,
2591 struct ieee802_11_elems *elems) 1487 struct ieee802_11_elems *elems,
1488 bool beacon)
2592{ 1489{
2593 struct ieee80211_local *local = sdata->local; 1490 struct ieee80211_local *local = sdata->local;
2594 int freq, clen; 1491 int freq;
2595 struct ieee80211_sta_bss *bss; 1492 struct ieee80211_sta_bss *bss;
2596 struct sta_info *sta; 1493 struct sta_info *sta;
2597 struct ieee80211_channel *channel; 1494 struct ieee80211_channel *channel;
2598 u64 beacon_timestamp, rx_timestamp; 1495 u64 beacon_timestamp, rx_timestamp;
2599 u64 supp_rates = 0; 1496 u64 supp_rates = 0;
2600 bool beacon = ieee80211_is_beacon(mgmt->frame_control);
2601 enum ieee80211_band band = rx_status->band; 1497 enum ieee80211_band band = rx_status->band;
2602 DECLARE_MAC_BUF(mac); 1498 DECLARE_MAC_BUF(mac);
2603 DECLARE_MAC_BUF(mac2); 1499 DECLARE_MAC_BUF(mac2);
2604 1500
2605 beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); 1501 if (elems->ds_params && elems->ds_params_len == 1)
1502 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
1503 else
1504 freq = rx_status->freq;
1505
1506 channel = ieee80211_get_channel(local->hw.wiphy, freq);
1507
1508 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
1509 return;
2606 1510
2607 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && 1511 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2608 elems->mesh_config && mesh_matches_local(elems, sdata)) { 1512 elems->mesh_config && mesh_matches_local(elems, sdata)) {
@@ -2612,13 +1516,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2612 mesh_peer_accepts_plinks(elems)); 1516 mesh_peer_accepts_plinks(elems));
2613 } 1517 }
2614 1518
2615 rcu_read_lock();
2616
2617 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && 1519 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
2618 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) { 1520 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2619
2620 supp_rates = ieee80211_sta_get_rates(local, elems, band); 1521 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2621 1522
1523 rcu_read_lock();
1524
2622 sta = sta_info_get(local, mgmt->sa); 1525 sta = sta_info_get(local, mgmt->sa);
2623 if (sta) { 1526 if (sta) {
2624 u64 prev_rates; 1527 u64 prev_rates;
@@ -2642,95 +1545,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2642 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid, 1545 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
2643 mgmt->sa, supp_rates); 1546 mgmt->sa, supp_rates);
2644 } 1547 }
2645 }
2646
2647 rcu_read_unlock();
2648
2649 if (elems->ds_params && elems->ds_params_len == 1)
2650 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
2651 else
2652 freq = rx_status->freq;
2653
2654 channel = ieee80211_get_channel(local->hw.wiphy, freq);
2655
2656 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
2657 return;
2658
2659#ifdef CONFIG_MAC80211_MESH
2660 if (elems->mesh_config)
2661 bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
2662 elems->mesh_id_len, elems->mesh_config, freq);
2663 else
2664#endif
2665 bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
2666 elems->ssid, elems->ssid_len);
2667 if (!bss) {
2668#ifdef CONFIG_MAC80211_MESH
2669 if (elems->mesh_config)
2670 bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
2671 elems->mesh_id_len, elems->mesh_config,
2672 elems->mesh_config_len, freq);
2673 else
2674#endif
2675 bss = ieee80211_rx_bss_add(sdata, mgmt->bssid, freq,
2676 elems->ssid, elems->ssid_len);
2677 if (!bss)
2678 return;
2679 } else {
2680#if 0
2681 /* TODO: order by RSSI? */
2682 spin_lock_bh(&local->sta_bss_lock);
2683 list_move_tail(&bss->list, &local->sta_bss_list);
2684 spin_unlock_bh(&local->sta_bss_lock);
2685#endif
2686 }
2687 1548
2688 /* save the ERP value so that it is available at association time */ 1549 rcu_read_unlock();
2689 if (elems->erp_info && elems->erp_info_len >= 1) {
2690 bss->erp_value = elems->erp_info[0];
2691 bss->has_erp_value = 1;
2692 }
2693
2694 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2695 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2696
2697 if (elems->tim) {
2698 struct ieee80211_tim_ie *tim_ie =
2699 (struct ieee80211_tim_ie *)elems->tim;
2700 bss->dtim_period = tim_ie->dtim_period;
2701 } 1550 }
2702 1551
2703 /* set default value for buggy APs */ 1552 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
2704 if (!elems->tim || bss->dtim_period == 0) 1553 freq, beacon);
2705 bss->dtim_period = 1; 1554 if (!bss)
2706 1555 return;
2707 bss->supp_rates_len = 0;
2708 if (elems->supp_rates) {
2709 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2710 if (clen > elems->supp_rates_len)
2711 clen = elems->supp_rates_len;
2712 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
2713 clen);
2714 bss->supp_rates_len += clen;
2715 }
2716 if (elems->ext_supp_rates) {
2717 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2718 if (clen > elems->ext_supp_rates_len)
2719 clen = elems->ext_supp_rates_len;
2720 memcpy(&bss->supp_rates[bss->supp_rates_len],
2721 elems->ext_supp_rates, clen);
2722 bss->supp_rates_len += clen;
2723 }
2724 1556
2725 bss->band = band; 1557 /* was just updated in ieee80211_bss_info_update */
1558 beacon_timestamp = bss->timestamp;
2726 1559
2727 bss->timestamp = beacon_timestamp;
2728 bss->last_update = jiffies;
2729 bss->signal = rx_status->signal;
2730 bss->noise = rx_status->noise;
2731 bss->qual = rx_status->qual;
2732 if (!beacon)
2733 bss->last_probe_resp = jiffies;
2734 /* 1560 /*
2735 * In STA mode, the remaining parameters should not be overridden 1561 * In STA mode, the remaining parameters should not be overridden
2736 * by beacons because they're not necessarily accurate there. 1562 * by beacons because they're not necessarily accurate there.
@@ -2741,21 +1567,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2741 return; 1567 return;
2742 } 1568 }
2743 1569
2744 if (bss->ies == NULL || bss->ies_len < elems->total_len) {
2745 kfree(bss->ies);
2746 bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
2747 }
2748 if (bss->ies) {
2749 memcpy(bss->ies, elems->ie_start, elems->total_len);
2750 bss->ies_len = elems->total_len;
2751 } else
2752 bss->ies_len = 0;
2753
2754 bss->wmm_used = elems->wmm_param || elems->wmm_info;
2755
2756 /* check if we need to merge IBSS */ 1570 /* check if we need to merge IBSS */
2757 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && 1571 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
2758 !local->sta_sw_scanning && !local->sta_hw_scanning &&
2759 bss->capability & WLAN_CAPABILITY_IBSS && 1572 bss->capability & WLAN_CAPABILITY_IBSS &&
2760 bss->freq == local->oper_channel->center_freq && 1573 bss->freq == local->oper_channel->center_freq &&
2761 elems->ssid_len == sdata->u.sta.ssid_len && 1574 elems->ssid_len == sdata->u.sta.ssid_len &&
@@ -2832,7 +1645,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2832 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, 1645 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
2833 &elems); 1646 &elems);
2834 1647
2835 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 1648 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
2836 1649
2837 /* direct probe may be part of the association flow */ 1650 /* direct probe may be part of the association flow */
2838 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE, 1651 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
@@ -2863,7 +1676,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2863 1676
2864 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 1677 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
2865 1678
2866 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 1679 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
2867 1680
2868 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 1681 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2869 return; 1682 return;
@@ -2876,12 +1689,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2876 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, 1689 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2877 elems.wmm_param_len); 1690 elems.wmm_param_len);
2878 1691
2879 /* Do not send changes to driver if we are scanning. This removes
2880 * requirement that driver's bss_info_changed function needs to be
2881 * atomic. */
2882 if (local->sta_sw_scanning || local->sta_hw_scanning)
2883 return;
2884
2885 if (elems.erp_info && elems.erp_info_len >= 1) 1692 if (elems.erp_info && elems.erp_info_len >= 1)
2886 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); 1693 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2887 else { 1694 else {
@@ -2975,7 +1782,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2975 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", 1782 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
2976 sdata->dev->name, print_mac(mac, resp->da)); 1783 sdata->dev->name, print_mac(mac, resp->da));
2977#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1784#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2978 ieee80211_sta_tx(sdata, skb, 0); 1785 ieee80211_tx_skb(sdata, skb, 0);
2979} 1786}
2980 1787
2981static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, 1788static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
@@ -2984,53 +1791,16 @@ static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
2984 size_t len, 1791 size_t len,
2985 struct ieee80211_rx_status *rx_status) 1792 struct ieee80211_rx_status *rx_status)
2986{ 1793{
2987 struct ieee80211_local *local = sdata->local; 1794 /* currently we only handle mesh interface action frames here */
2988 1795 if (!ieee80211_vif_is_mesh(&sdata->vif))
2989 if (len < IEEE80211_MIN_ACTION_SIZE)
2990 return; 1796 return;
2991 1797
2992 switch (mgmt->u.action.category) { 1798 switch (mgmt->u.action.category) {
2993 case WLAN_CATEGORY_SPECTRUM_MGMT:
2994 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
2995 break;
2996 switch (mgmt->u.action.u.chan_switch.action_code) {
2997 case WLAN_ACTION_SPCT_MSR_REQ:
2998 if (len < (IEEE80211_MIN_ACTION_SIZE +
2999 sizeof(mgmt->u.action.u.measurement)))
3000 break;
3001 ieee80211_sta_process_measurement_req(sdata, mgmt, len);
3002 break;
3003 }
3004 break;
3005 case WLAN_CATEGORY_BACK:
3006 switch (mgmt->u.action.u.addba_req.action_code) {
3007 case WLAN_ACTION_ADDBA_REQ:
3008 if (len < (IEEE80211_MIN_ACTION_SIZE +
3009 sizeof(mgmt->u.action.u.addba_req)))
3010 break;
3011 ieee80211_sta_process_addba_request(local, mgmt, len);
3012 break;
3013 case WLAN_ACTION_ADDBA_RESP:
3014 if (len < (IEEE80211_MIN_ACTION_SIZE +
3015 sizeof(mgmt->u.action.u.addba_resp)))
3016 break;
3017 ieee80211_sta_process_addba_resp(local, mgmt, len);
3018 break;
3019 case WLAN_ACTION_DELBA:
3020 if (len < (IEEE80211_MIN_ACTION_SIZE +
3021 sizeof(mgmt->u.action.u.delba)))
3022 break;
3023 ieee80211_sta_process_delba(sdata, mgmt, len);
3024 break;
3025 }
3026 break;
3027 case PLINK_CATEGORY: 1799 case PLINK_CATEGORY:
3028 if (ieee80211_vif_is_mesh(&sdata->vif)) 1800 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
3029 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
3030 break; 1801 break;
3031 case MESH_PATH_SEL_CATEGORY: 1802 case MESH_PATH_SEL_CATEGORY:
3032 if (ieee80211_vif_is_mesh(&sdata->vif)) 1803 mesh_rx_path_sel_frame(sdata, mgmt, len);
3033 mesh_rx_path_sel_frame(sdata, mgmt, len);
3034 break; 1804 break;
3035 } 1805 }
3036} 1806}
@@ -3120,41 +1890,6 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3120} 1890}
3121 1891
3122 1892
3123ieee80211_rx_result
3124ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
3125 struct ieee80211_rx_status *rx_status)
3126{
3127 struct ieee80211_mgmt *mgmt;
3128 __le16 fc;
3129
3130 if (skb->len < 2)
3131 return RX_DROP_UNUSABLE;
3132
3133 mgmt = (struct ieee80211_mgmt *) skb->data;
3134 fc = mgmt->frame_control;
3135
3136 if (ieee80211_is_ctl(fc))
3137 return RX_CONTINUE;
3138
3139 if (skb->len < 24)
3140 return RX_DROP_MONITOR;
3141
3142 if (ieee80211_is_probe_resp(fc)) {
3143 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
3144 dev_kfree_skb(skb);
3145 return RX_QUEUED;
3146 }
3147
3148 if (ieee80211_is_beacon(fc)) {
3149 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3150 dev_kfree_skb(skb);
3151 return RX_QUEUED;
3152 }
3153
3154 return RX_CONTINUE;
3155}
3156
3157
3158static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) 1893static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
3159{ 1894{
3160 struct ieee80211_local *local = sdata->local; 1895 struct ieee80211_local *local = sdata->local;
@@ -3259,95 +1994,6 @@ void ieee80211_sta_timer(unsigned long data)
3259 queue_work(local->hw.workqueue, &ifsta->work); 1994 queue_work(local->hw.workqueue, &ifsta->work);
3260} 1995}
3261 1996
3262void ieee80211_sta_work(struct work_struct *work)
3263{
3264 struct ieee80211_sub_if_data *sdata =
3265 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
3266 struct ieee80211_local *local = sdata->local;
3267 struct ieee80211_if_sta *ifsta;
3268 struct sk_buff *skb;
3269
3270 if (!netif_running(sdata->dev))
3271 return;
3272
3273 if (local->sta_sw_scanning || local->sta_hw_scanning)
3274 return;
3275
3276 if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA &&
3277 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
3278 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
3279 return;
3280 ifsta = &sdata->u.sta;
3281
3282 while ((skb = skb_dequeue(&ifsta->skb_queue)))
3283 ieee80211_sta_rx_queued_mgmt(sdata, skb);
3284
3285#ifdef CONFIG_MAC80211_MESH
3286 if (ifsta->preq_queue_len &&
3287 time_after(jiffies,
3288 ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
3289 mesh_path_start_discovery(sdata);
3290#endif
3291
3292 if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
3293 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
3294 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
3295 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3296 if (ifsta->scan_ssid_len)
3297 ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
3298 else
3299 ieee80211_sta_start_scan(sdata, NULL, 0);
3300 return;
3301 }
3302
3303 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3304 if (ieee80211_sta_config_auth(sdata, ifsta))
3305 return;
3306 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
3307 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
3308 return;
3309
3310 switch (ifsta->state) {
3311 case IEEE80211_STA_MLME_DISABLED:
3312 break;
3313 case IEEE80211_STA_MLME_DIRECT_PROBE:
3314 ieee80211_direct_probe(sdata, ifsta);
3315 break;
3316 case IEEE80211_STA_MLME_AUTHENTICATE:
3317 ieee80211_authenticate(sdata, ifsta);
3318 break;
3319 case IEEE80211_STA_MLME_ASSOCIATE:
3320 ieee80211_associate(sdata, ifsta);
3321 break;
3322 case IEEE80211_STA_MLME_ASSOCIATED:
3323 ieee80211_associated(sdata, ifsta);
3324 break;
3325 case IEEE80211_STA_MLME_IBSS_SEARCH:
3326 ieee80211_sta_find_ibss(sdata, ifsta);
3327 break;
3328 case IEEE80211_STA_MLME_IBSS_JOINED:
3329 ieee80211_sta_merge_ibss(sdata, ifsta);
3330 break;
3331#ifdef CONFIG_MAC80211_MESH
3332 case IEEE80211_STA_MLME_MESH_UP:
3333 ieee80211_mesh_housekeeping(sdata, ifsta);
3334 break;
3335#endif
3336 default:
3337 WARN_ON(1);
3338 break;
3339 }
3340
3341 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
3342 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3343 "mixed-cell disabled - disassociate\n", sdata->dev->name);
3344
3345 ieee80211_send_disassoc(sdata, ifsta, WLAN_REASON_UNSPECIFIED);
3346 ieee80211_set_disassoc(sdata, ifsta, 0);
3347 }
3348}
3349
3350
3351static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata, 1997static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3352 struct ieee80211_if_sta *ifsta) 1998 struct ieee80211_if_sta *ifsta)
3353{ 1999{
@@ -3375,6 +2021,7 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3375 ifsta->direct_probe_tries = 0; 2021 ifsta->direct_probe_tries = 0;
3376 ifsta->auth_tries = 0; 2022 ifsta->auth_tries = 0;
3377 ifsta->assoc_tries = 0; 2023 ifsta->assoc_tries = 0;
2024 netif_tx_stop_all_queues(sdata->dev);
3378 netif_carrier_off(sdata->dev); 2025 netif_carrier_off(sdata->dev);
3379} 2026}
3380 2027
@@ -3388,9 +2035,14 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
3388 return; 2035 return;
3389 2036
3390 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET | 2037 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3391 IEEE80211_STA_AUTO_BSSID_SEL)) && 2038 IEEE80211_STA_AUTO_BSSID_SEL)) &&
3392 (ifsta->flags & (IEEE80211_STA_SSID_SET | 2039 (ifsta->flags & (IEEE80211_STA_SSID_SET |
3393 IEEE80211_STA_AUTO_SSID_SEL))) { 2040 IEEE80211_STA_AUTO_SSID_SEL))) {
2041
2042 if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED)
2043 ieee80211_set_disassoc(sdata, ifsta, true, true,
2044 WLAN_REASON_DEAUTH_LEAVING);
2045
3394 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request); 2046 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3395 queue_work(local->hw.workqueue, &ifsta->work); 2047 queue_work(local->hw.workqueue, &ifsta->work);
3396 } 2048 }
@@ -3426,85 +2078,6 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
3426 return 0; 2078 return 0;
3427} 2079}
3428 2080
3429static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
3430 struct ieee80211_if_sta *ifsta)
3431{
3432 struct ieee80211_local *local = sdata->local;
3433 struct ieee80211_sta_bss *bss, *selected = NULL;
3434 int top_rssi = 0, freq;
3435
3436 spin_lock_bh(&local->sta_bss_lock);
3437 freq = local->oper_channel->center_freq;
3438 list_for_each_entry(bss, &local->sta_bss_list, list) {
3439 if (!(bss->capability & WLAN_CAPABILITY_ESS))
3440 continue;
3441
3442 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
3443 IEEE80211_STA_AUTO_BSSID_SEL |
3444 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
3445 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
3446 !!sdata->default_key))
3447 continue;
3448
3449 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
3450 bss->freq != freq)
3451 continue;
3452
3453 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
3454 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
3455 continue;
3456
3457 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
3458 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3459 continue;
3460
3461 if (!selected || top_rssi < bss->signal) {
3462 selected = bss;
3463 top_rssi = bss->signal;
3464 }
3465 }
3466 if (selected)
3467 atomic_inc(&selected->users);
3468 spin_unlock_bh(&local->sta_bss_lock);
3469
3470 if (selected) {
3471 ieee80211_set_freq(sdata, selected->freq);
3472 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
3473 ieee80211_sta_set_ssid(sdata, selected->ssid,
3474 selected->ssid_len);
3475 ieee80211_sta_set_bssid(sdata, selected->bssid);
3476 ieee80211_sta_def_wmm_params(sdata, selected, 0);
3477
3478 /* Send out direct probe if no probe resp was received or
3479 * the one we have is outdated
3480 */
3481 if (!selected->last_probe_resp ||
3482 time_after(jiffies, selected->last_probe_resp
3483 + IEEE80211_SCAN_RESULT_EXPIRE))
3484 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
3485 else
3486 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3487
3488 ieee80211_rx_bss_put(local, selected);
3489 ieee80211_sta_reset_auth(sdata, ifsta);
3490 return 0;
3491 } else {
3492 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
3493 ifsta->assoc_scan_tries++;
3494 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
3495 ieee80211_sta_start_scan(sdata, NULL, 0);
3496 else
3497 ieee80211_sta_start_scan(sdata, ifsta->ssid,
3498 ifsta->ssid_len);
3499 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3500 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3501 } else
3502 ifsta->state = IEEE80211_STA_MLME_DISABLED;
3503 }
3504 return -1;
3505}
3506
3507
3508static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, 2081static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3509 struct ieee80211_if_sta *ifsta) 2082 struct ieee80211_if_sta *ifsta)
3510{ 2083{
@@ -3533,7 +2106,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3533 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2106 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
3534 sdata->dev->name, print_mac(mac, bssid)); 2107 sdata->dev->name, print_mac(mac, bssid));
3535 2108
3536 bss = ieee80211_rx_bss_add(sdata, bssid, 2109 bss = ieee80211_rx_bss_add(local, bssid,
3537 local->hw.conf.channel->center_freq, 2110 local->hw.conf.channel->center_freq,
3538 sdata->u.sta.ssid, sdata->u.sta.ssid_len); 2111 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
3539 if (!bss) 2112 if (!bss)
@@ -3762,544 +2335,6 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
3762} 2335}
3763 2336
3764 2337
3765static void ieee80211_send_nullfunc(struct ieee80211_local *local,
3766 struct ieee80211_sub_if_data *sdata,
3767 int powersave)
3768{
3769 struct sk_buff *skb;
3770 struct ieee80211_hdr *nullfunc;
3771 __le16 fc;
3772
3773 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
3774 if (!skb) {
3775 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
3776 "frame\n", sdata->dev->name);
3777 return;
3778 }
3779 skb_reserve(skb, local->hw.extra_tx_headroom);
3780
3781 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
3782 memset(nullfunc, 0, 24);
3783 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
3784 IEEE80211_FCTL_TODS);
3785 if (powersave)
3786 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
3787 nullfunc->frame_control = fc;
3788 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
3789 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
3790 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
3791
3792 ieee80211_sta_tx(sdata, skb, 0);
3793}
3794
3795
3796static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3797{
3798 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
3799 ieee80211_vif_is_mesh(&sdata->vif))
3800 ieee80211_sta_timer((unsigned long)sdata);
3801}
3802
3803void ieee80211_scan_completed(struct ieee80211_hw *hw)
3804{
3805 struct ieee80211_local *local = hw_to_local(hw);
3806 struct net_device *dev = local->scan_dev;
3807 struct ieee80211_sub_if_data *sdata;
3808 union iwreq_data wrqu;
3809
3810 local->last_scan_completed = jiffies;
3811 memset(&wrqu, 0, sizeof(wrqu));
3812 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3813
3814 if (local->sta_hw_scanning) {
3815 local->sta_hw_scanning = 0;
3816 if (ieee80211_hw_config(local))
3817 printk(KERN_DEBUG "%s: failed to restore operational "
3818 "channel after scan\n", dev->name);
3819 /* Restart STA timer for HW scan case */
3820 rcu_read_lock();
3821 list_for_each_entry_rcu(sdata, &local->interfaces, list)
3822 ieee80211_restart_sta_timer(sdata);
3823 rcu_read_unlock();
3824
3825 goto done;
3826 }
3827
3828 local->sta_sw_scanning = 0;
3829 if (ieee80211_hw_config(local))
3830 printk(KERN_DEBUG "%s: failed to restore operational "
3831 "channel after scan\n", dev->name);
3832
3833
3834 netif_tx_lock_bh(local->mdev);
3835 netif_addr_lock(local->mdev);
3836 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
3837 local->ops->configure_filter(local_to_hw(local),
3838 FIF_BCN_PRBRESP_PROMISC,
3839 &local->filter_flags,
3840 local->mdev->mc_count,
3841 local->mdev->mc_list);
3842
3843 netif_addr_unlock(local->mdev);
3844 netif_tx_unlock_bh(local->mdev);
3845
3846 rcu_read_lock();
3847 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3848 /* Tell AP we're back */
3849 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
3850 sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)
3851 ieee80211_send_nullfunc(local, sdata, 0);
3852
3853 ieee80211_restart_sta_timer(sdata);
3854
3855 netif_wake_queue(sdata->dev);
3856 }
3857 rcu_read_unlock();
3858
3859done:
3860 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3861 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
3862 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3863 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
3864 (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
3865 !ieee80211_sta_active_ibss(sdata)))
3866 ieee80211_sta_find_ibss(sdata, ifsta);
3867 }
3868}
3869EXPORT_SYMBOL(ieee80211_scan_completed);
3870
3871void ieee80211_sta_scan_work(struct work_struct *work)
3872{
3873 struct ieee80211_local *local =
3874 container_of(work, struct ieee80211_local, scan_work.work);
3875 struct net_device *dev = local->scan_dev;
3876 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3877 struct ieee80211_supported_band *sband;
3878 struct ieee80211_channel *chan;
3879 int skip;
3880 unsigned long next_delay = 0;
3881
3882 if (!local->sta_sw_scanning)
3883 return;
3884
3885 switch (local->scan_state) {
3886 case SCAN_SET_CHANNEL:
3887 /*
3888 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
3889 * after we successfully scanned the last channel of the last
3890 * band (and the last band is supported by the hw)
3891 */
3892 if (local->scan_band < IEEE80211_NUM_BANDS)
3893 sband = local->hw.wiphy->bands[local->scan_band];
3894 else
3895 sband = NULL;
3896
3897 /*
3898 * If we are at an unsupported band and have more bands
3899 * left to scan, advance to the next supported one.
3900 */
3901 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
3902 local->scan_band++;
3903 sband = local->hw.wiphy->bands[local->scan_band];
3904 local->scan_channel_idx = 0;
3905 }
3906
3907 /* if no more bands/channels left, complete scan */
3908 if (!sband || local->scan_channel_idx >= sband->n_channels) {
3909 ieee80211_scan_completed(local_to_hw(local));
3910 return;
3911 }
3912 skip = 0;
3913 chan = &sband->channels[local->scan_channel_idx];
3914
3915 if (chan->flags & IEEE80211_CHAN_DISABLED ||
3916 (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3917 chan->flags & IEEE80211_CHAN_NO_IBSS))
3918 skip = 1;
3919
3920 if (!skip) {
3921 local->scan_channel = chan;
3922 if (ieee80211_hw_config(local)) {
3923 printk(KERN_DEBUG "%s: failed to set freq to "
3924 "%d MHz for scan\n", dev->name,
3925 chan->center_freq);
3926 skip = 1;
3927 }
3928 }
3929
3930 /* advance state machine to next channel/band */
3931 local->scan_channel_idx++;
3932 if (local->scan_channel_idx >= sband->n_channels) {
3933 /*
3934 * scan_band may end up == IEEE80211_NUM_BANDS, but
3935 * we'll catch that case above and complete the scan
3936 * if that is the case.
3937 */
3938 local->scan_band++;
3939 local->scan_channel_idx = 0;
3940 }
3941
3942 if (skip)
3943 break;
3944
3945 next_delay = IEEE80211_PROBE_DELAY +
3946 usecs_to_jiffies(local->hw.channel_change_time);
3947 local->scan_state = SCAN_SEND_PROBE;
3948 break;
3949 case SCAN_SEND_PROBE:
3950 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
3951 local->scan_state = SCAN_SET_CHANNEL;
3952
3953 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
3954 break;
3955 ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
3956 local->scan_ssid_len);
3957 next_delay = IEEE80211_CHANNEL_TIME;
3958 break;
3959 }
3960
3961 if (local->sta_sw_scanning)
3962 queue_delayed_work(local->hw.workqueue, &local->scan_work,
3963 next_delay);
3964}
3965
3966
3967static int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
3968 u8 *ssid, size_t ssid_len)
3969{
3970 struct ieee80211_local *local = scan_sdata->local;
3971 struct ieee80211_sub_if_data *sdata;
3972
3973 if (ssid_len > IEEE80211_MAX_SSID_LEN)
3974 return -EINVAL;
3975
3976 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
3977 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
3978 * BSSID: MACAddress
3979 * SSID
3980 * ScanType: ACTIVE, PASSIVE
3981 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
3982 * a Probe frame during active scanning
3983 * ChannelList
3984 * MinChannelTime (>= ProbeDelay), in TU
3985 * MaxChannelTime: (>= MinChannelTime), in TU
3986 */
3987
3988 /* MLME-SCAN.confirm
3989 * BSSDescriptionSet
3990 * ResultCode: SUCCESS, INVALID_PARAMETERS
3991 */
3992
3993 if (local->sta_sw_scanning || local->sta_hw_scanning) {
3994 if (local->scan_dev == scan_sdata->dev)
3995 return 0;
3996 return -EBUSY;
3997 }
3998
3999 if (local->ops->hw_scan) {
4000 int rc = local->ops->hw_scan(local_to_hw(local),
4001 ssid, ssid_len);
4002 if (!rc) {
4003 local->sta_hw_scanning = 1;
4004 local->scan_dev = scan_sdata->dev;
4005 }
4006 return rc;
4007 }
4008
4009 local->sta_sw_scanning = 1;
4010
4011 rcu_read_lock();
4012 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
4013 netif_stop_queue(sdata->dev);
4014 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
4015 (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED))
4016 ieee80211_send_nullfunc(local, sdata, 1);
4017 }
4018 rcu_read_unlock();
4019
4020 if (ssid) {
4021 local->scan_ssid_len = ssid_len;
4022 memcpy(local->scan_ssid, ssid, ssid_len);
4023 } else
4024 local->scan_ssid_len = 0;
4025 local->scan_state = SCAN_SET_CHANNEL;
4026 local->scan_channel_idx = 0;
4027 local->scan_band = IEEE80211_BAND_2GHZ;
4028 local->scan_dev = scan_sdata->dev;
4029
4030 netif_addr_lock_bh(local->mdev);
4031 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
4032 local->ops->configure_filter(local_to_hw(local),
4033 FIF_BCN_PRBRESP_PROMISC,
4034 &local->filter_flags,
4035 local->mdev->mc_count,
4036 local->mdev->mc_list);
4037 netif_addr_unlock_bh(local->mdev);
4038
4039 /* TODO: start scan as soon as all nullfunc frames are ACKed */
4040 queue_delayed_work(local->hw.workqueue, &local->scan_work,
4041 IEEE80211_CHANNEL_TIME);
4042
4043 return 0;
4044}
4045
4046
4047int ieee80211_sta_req_scan(struct ieee80211_sub_if_data *sdata, u8 *ssid, size_t ssid_len)
4048{
4049 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4050 struct ieee80211_local *local = sdata->local;
4051
4052 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
4053 return ieee80211_sta_start_scan(sdata, ssid, ssid_len);
4054
4055 if (local->sta_sw_scanning || local->sta_hw_scanning) {
4056 if (local->scan_dev == sdata->dev)
4057 return 0;
4058 return -EBUSY;
4059 }
4060
4061 ifsta->scan_ssid_len = ssid_len;
4062 if (ssid_len)
4063 memcpy(ifsta->scan_ssid, ssid, ssid_len);
4064 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
4065 queue_work(local->hw.workqueue, &ifsta->work);
4066 return 0;
4067}
4068
4069
4070static void ieee80211_sta_add_scan_ies(struct iw_request_info *info,
4071 struct ieee80211_sta_bss *bss,
4072 char **current_ev, char *end_buf)
4073{
4074 u8 *pos, *end, *next;
4075 struct iw_event iwe;
4076
4077 if (bss == NULL || bss->ies == NULL)
4078 return;
4079
4080 /*
4081 * If needed, fragment the IEs buffer (at IE boundaries) into short
4082 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
4083 */
4084 pos = bss->ies;
4085 end = pos + bss->ies_len;
4086
4087 while (end - pos > IW_GENERIC_IE_MAX) {
4088 next = pos + 2 + pos[1];
4089 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
4090 next = next + 2 + next[1];
4091
4092 memset(&iwe, 0, sizeof(iwe));
4093 iwe.cmd = IWEVGENIE;
4094 iwe.u.data.length = next - pos;
4095 *current_ev = iwe_stream_add_point(info, *current_ev,
4096 end_buf, &iwe, pos);
4097
4098 pos = next;
4099 }
4100
4101 if (end > pos) {
4102 memset(&iwe, 0, sizeof(iwe));
4103 iwe.cmd = IWEVGENIE;
4104 iwe.u.data.length = end - pos;
4105 *current_ev = iwe_stream_add_point(info, *current_ev,
4106 end_buf, &iwe, pos);
4107 }
4108}
4109
4110
4111static char *
4112ieee80211_sta_scan_result(struct ieee80211_local *local,
4113 struct iw_request_info *info,
4114 struct ieee80211_sta_bss *bss,
4115 char *current_ev, char *end_buf)
4116{
4117 struct iw_event iwe;
4118
4119 if (time_after(jiffies,
4120 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
4121 return current_ev;
4122
4123 memset(&iwe, 0, sizeof(iwe));
4124 iwe.cmd = SIOCGIWAP;
4125 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4126 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4127 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4128 IW_EV_ADDR_LEN);
4129
4130 memset(&iwe, 0, sizeof(iwe));
4131 iwe.cmd = SIOCGIWESSID;
4132 if (bss_mesh_cfg(bss)) {
4133 iwe.u.data.length = bss_mesh_id_len(bss);
4134 iwe.u.data.flags = 1;
4135 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4136 &iwe, bss_mesh_id(bss));
4137 } else {
4138 iwe.u.data.length = bss->ssid_len;
4139 iwe.u.data.flags = 1;
4140 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4141 &iwe, bss->ssid);
4142 }
4143
4144 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
4145 || bss_mesh_cfg(bss)) {
4146 memset(&iwe, 0, sizeof(iwe));
4147 iwe.cmd = SIOCGIWMODE;
4148 if (bss_mesh_cfg(bss))
4149 iwe.u.mode = IW_MODE_MESH;
4150 else if (bss->capability & WLAN_CAPABILITY_ESS)
4151 iwe.u.mode = IW_MODE_MASTER;
4152 else
4153 iwe.u.mode = IW_MODE_ADHOC;
4154 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4155 &iwe, IW_EV_UINT_LEN);
4156 }
4157
4158 memset(&iwe, 0, sizeof(iwe));
4159 iwe.cmd = SIOCGIWFREQ;
4160 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
4161 iwe.u.freq.e = 0;
4162 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4163 IW_EV_FREQ_LEN);
4164
4165 memset(&iwe, 0, sizeof(iwe));
4166 iwe.cmd = SIOCGIWFREQ;
4167 iwe.u.freq.m = bss->freq;
4168 iwe.u.freq.e = 6;
4169 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4170 IW_EV_FREQ_LEN);
4171 memset(&iwe, 0, sizeof(iwe));
4172 iwe.cmd = IWEVQUAL;
4173 iwe.u.qual.qual = bss->qual;
4174 iwe.u.qual.level = bss->signal;
4175 iwe.u.qual.noise = bss->noise;
4176 iwe.u.qual.updated = local->wstats_flags;
4177 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4178 IW_EV_QUAL_LEN);
4179
4180 memset(&iwe, 0, sizeof(iwe));
4181 iwe.cmd = SIOCGIWENCODE;
4182 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
4183 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4184 else
4185 iwe.u.data.flags = IW_ENCODE_DISABLED;
4186 iwe.u.data.length = 0;
4187 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4188 &iwe, "");
4189
4190 ieee80211_sta_add_scan_ies(info, bss, &current_ev, end_buf);
4191
4192 if (bss && bss->supp_rates_len > 0) {
4193 /* display all supported rates in readable format */
4194 char *p = current_ev + iwe_stream_lcp_len(info);
4195 int i;
4196
4197 memset(&iwe, 0, sizeof(iwe));
4198 iwe.cmd = SIOCGIWRATE;
4199 /* Those two flags are ignored... */
4200 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4201
4202 for (i = 0; i < bss->supp_rates_len; i++) {
4203 iwe.u.bitrate.value = ((bss->supp_rates[i] &
4204 0x7f) * 500000);
4205 p = iwe_stream_add_value(info, current_ev, p,
4206 end_buf, &iwe, IW_EV_PARAM_LEN);
4207 }
4208 current_ev = p;
4209 }
4210
4211 if (bss) {
4212 char *buf;
4213 buf = kmalloc(30, GFP_ATOMIC);
4214 if (buf) {
4215 memset(&iwe, 0, sizeof(iwe));
4216 iwe.cmd = IWEVCUSTOM;
4217 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
4218 iwe.u.data.length = strlen(buf);
4219 current_ev = iwe_stream_add_point(info, current_ev,
4220 end_buf,
4221 &iwe, buf);
4222 memset(&iwe, 0, sizeof(iwe));
4223 iwe.cmd = IWEVCUSTOM;
4224 sprintf(buf, " Last beacon: %dms ago",
4225 jiffies_to_msecs(jiffies - bss->last_update));
4226 iwe.u.data.length = strlen(buf);
4227 current_ev = iwe_stream_add_point(info, current_ev,
4228 end_buf, &iwe, buf);
4229 kfree(buf);
4230 }
4231 }
4232
4233 if (bss_mesh_cfg(bss)) {
4234 char *buf;
4235 u8 *cfg = bss_mesh_cfg(bss);
4236 buf = kmalloc(50, GFP_ATOMIC);
4237 if (buf) {
4238 memset(&iwe, 0, sizeof(iwe));
4239 iwe.cmd = IWEVCUSTOM;
4240 sprintf(buf, "Mesh network (version %d)", cfg[0]);
4241 iwe.u.data.length = strlen(buf);
4242 current_ev = iwe_stream_add_point(info, current_ev,
4243 end_buf,
4244 &iwe, buf);
4245 sprintf(buf, "Path Selection Protocol ID: "
4246 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
4247 cfg[4]);
4248 iwe.u.data.length = strlen(buf);
4249 current_ev = iwe_stream_add_point(info, current_ev,
4250 end_buf,
4251 &iwe, buf);
4252 sprintf(buf, "Path Selection Metric ID: "
4253 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
4254 cfg[8]);
4255 iwe.u.data.length = strlen(buf);
4256 current_ev = iwe_stream_add_point(info, current_ev,
4257 end_buf,
4258 &iwe, buf);
4259 sprintf(buf, "Congestion Control Mode ID: "
4260 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
4261 cfg[11], cfg[12]);
4262 iwe.u.data.length = strlen(buf);
4263 current_ev = iwe_stream_add_point(info, current_ev,
4264 end_buf,
4265 &iwe, buf);
4266 sprintf(buf, "Channel Precedence: "
4267 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
4268 cfg[15], cfg[16]);
4269 iwe.u.data.length = strlen(buf);
4270 current_ev = iwe_stream_add_point(info, current_ev,
4271 end_buf,
4272 &iwe, buf);
4273 kfree(buf);
4274 }
4275 }
4276
4277 return current_ev;
4278}
4279
4280
4281int ieee80211_sta_scan_results(struct ieee80211_local *local,
4282 struct iw_request_info *info,
4283 char *buf, size_t len)
4284{
4285 char *current_ev = buf;
4286 char *end_buf = buf + len;
4287 struct ieee80211_sta_bss *bss;
4288
4289 spin_lock_bh(&local->sta_bss_lock);
4290 list_for_each_entry(bss, &local->sta_bss_list, list) {
4291 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
4292 spin_unlock_bh(&local->sta_bss_lock);
4293 return -E2BIG;
4294 }
4295 current_ev = ieee80211_sta_scan_result(local, info, bss,
4296 current_ev, end_buf);
4297 }
4298 spin_unlock_bh(&local->sta_bss_lock);
4299 return current_ev - buf;
4300}
4301
4302
4303int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len) 2338int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
4304{ 2339{
4305 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2340 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
@@ -4367,6 +2402,85 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
4367} 2402}
4368 2403
4369 2404
2405static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2406 struct ieee80211_if_sta *ifsta)
2407{
2408 struct ieee80211_local *local = sdata->local;
2409 struct ieee80211_sta_bss *bss, *selected = NULL;
2410 int top_rssi = 0, freq;
2411
2412 spin_lock_bh(&local->sta_bss_lock);
2413 freq = local->oper_channel->center_freq;
2414 list_for_each_entry(bss, &local->sta_bss_list, list) {
2415 if (!(bss->capability & WLAN_CAPABILITY_ESS))
2416 continue;
2417
2418 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
2419 IEEE80211_STA_AUTO_BSSID_SEL |
2420 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
2421 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
2422 !!sdata->default_key))
2423 continue;
2424
2425 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
2426 bss->freq != freq)
2427 continue;
2428
2429 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
2430 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
2431 continue;
2432
2433 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
2434 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
2435 continue;
2436
2437 if (!selected || top_rssi < bss->signal) {
2438 selected = bss;
2439 top_rssi = bss->signal;
2440 }
2441 }
2442 if (selected)
2443 atomic_inc(&selected->users);
2444 spin_unlock_bh(&local->sta_bss_lock);
2445
2446 if (selected) {
2447 ieee80211_set_freq(sdata, selected->freq);
2448 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
2449 ieee80211_sta_set_ssid(sdata, selected->ssid,
2450 selected->ssid_len);
2451 ieee80211_sta_set_bssid(sdata, selected->bssid);
2452 ieee80211_sta_def_wmm_params(sdata, selected);
2453
2454 /* Send out direct probe if no probe resp was received or
2455 * the one we have is outdated
2456 */
2457 if (!selected->last_probe_resp ||
2458 time_after(jiffies, selected->last_probe_resp
2459 + IEEE80211_SCAN_RESULT_EXPIRE))
2460 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2461 else
2462 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2463
2464 ieee80211_rx_bss_put(local, selected);
2465 ieee80211_sta_reset_auth(sdata, ifsta);
2466 return 0;
2467 } else {
2468 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
2469 ifsta->assoc_scan_tries++;
2470 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
2471 ieee80211_sta_start_scan(sdata, NULL, 0);
2472 else
2473 ieee80211_sta_start_scan(sdata, ifsta->ssid,
2474 ifsta->ssid_len);
2475 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2476 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
2477 } else
2478 ifsta->state = IEEE80211_STA_MLME_DISABLED;
2479 }
2480 return -1;
2481}
2482
2483
4370int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason) 2484int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
4371{ 2485{
4372 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2486 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
@@ -4378,8 +2492,7 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
4378 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 2492 sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
4379 return -EINVAL; 2493 return -EINVAL;
4380 2494
4381 ieee80211_send_deauth(sdata, ifsta, reason); 2495 ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4382 ieee80211_set_disassoc(sdata, ifsta, 1);
4383 return 0; 2496 return 0;
4384} 2497}
4385 2498
@@ -4397,8 +2510,7 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4397 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED)) 2510 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4398 return -1; 2511 return -1;
4399 2512
4400 ieee80211_send_disassoc(sdata, ifsta, reason); 2513 ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4401 ieee80211_set_disassoc(sdata, ifsta, 0);
4402 return 0; 2514 return 0;
4403} 2515}
4404 2516
@@ -4422,3 +2534,102 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw,
4422 } 2534 }
4423} 2535}
4424EXPORT_SYMBOL(ieee80211_notify_mac); 2536EXPORT_SYMBOL(ieee80211_notify_mac);
2537
2538void ieee80211_sta_work(struct work_struct *work)
2539{
2540 struct ieee80211_sub_if_data *sdata =
2541 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
2542 struct ieee80211_local *local = sdata->local;
2543 struct ieee80211_if_sta *ifsta;
2544 struct sk_buff *skb;
2545
2546 if (!netif_running(sdata->dev))
2547 return;
2548
2549 if (local->sta_sw_scanning || local->sta_hw_scanning)
2550 return;
2551
2552 if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA &&
2553 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
2554 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
2555 return;
2556 ifsta = &sdata->u.sta;
2557
2558 while ((skb = skb_dequeue(&ifsta->skb_queue)))
2559 ieee80211_sta_rx_queued_mgmt(sdata, skb);
2560
2561#ifdef CONFIG_MAC80211_MESH
2562 if (ifsta->preq_queue_len &&
2563 time_after(jiffies,
2564 ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
2565 mesh_path_start_discovery(sdata);
2566#endif
2567
2568 if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
2569 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
2570 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
2571 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
2572 ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
2573 return;
2574 }
2575
2576 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
2577 if (ieee80211_sta_config_auth(sdata, ifsta))
2578 return;
2579 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
2580 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
2581 return;
2582
2583 switch (ifsta->state) {
2584 case IEEE80211_STA_MLME_DISABLED:
2585 break;
2586 case IEEE80211_STA_MLME_DIRECT_PROBE:
2587 ieee80211_direct_probe(sdata, ifsta);
2588 break;
2589 case IEEE80211_STA_MLME_AUTHENTICATE:
2590 ieee80211_authenticate(sdata, ifsta);
2591 break;
2592 case IEEE80211_STA_MLME_ASSOCIATE:
2593 ieee80211_associate(sdata, ifsta);
2594 break;
2595 case IEEE80211_STA_MLME_ASSOCIATED:
2596 ieee80211_associated(sdata, ifsta);
2597 break;
2598 case IEEE80211_STA_MLME_IBSS_SEARCH:
2599 ieee80211_sta_find_ibss(sdata, ifsta);
2600 break;
2601 case IEEE80211_STA_MLME_IBSS_JOINED:
2602 ieee80211_sta_merge_ibss(sdata, ifsta);
2603 break;
2604#ifdef CONFIG_MAC80211_MESH
2605 case IEEE80211_STA_MLME_MESH_UP:
2606 ieee80211_mesh_housekeeping(sdata, ifsta);
2607 break;
2608#endif
2609 default:
2610 WARN_ON(1);
2611 break;
2612 }
2613
2614 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
2615 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
2616 "mixed-cell disabled - disassociate\n", sdata->dev->name);
2617
2618 ieee80211_set_disassoc(sdata, ifsta, false, true,
2619 WLAN_REASON_UNSPECIFIED);
2620 }
2621}
2622
2623void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2624{
2625 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2626 struct ieee80211_if_sta *ifsta;
2627
2628 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
2629 ifsta = &sdata->u.sta;
2630 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
2631 (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
2632 !ieee80211_sta_active_ibss(sdata)))
2633 ieee80211_sta_find_ibss(sdata, ifsta);
2634 }
2635}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7e09b30dd393..d0803797902b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1511,22 +1511,95 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1511} 1511}
1512 1512
1513static ieee80211_rx_result debug_noinline 1513static ieee80211_rx_result debug_noinline
1514ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1515{
1516 struct ieee80211_local *local = rx->local;
1517 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1518 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1519 int len = rx->skb->len;
1520
1521 if (!ieee80211_is_action(mgmt->frame_control))
1522 return RX_CONTINUE;
1523
1524 if (!rx->sta)
1525 return RX_DROP_MONITOR;
1526
1527 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1528 return RX_DROP_MONITOR;
1529
1530 /* all categories we currently handle have action_code */
1531 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
1532 return RX_DROP_MONITOR;
1533
1534 /*
1535 * FIXME: revisit this, I'm sure we should handle most
1536 * of these frames in other modes as well!
1537 */
1538 if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
1539 sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1540 return RX_DROP_MONITOR;
1541
1542 switch (mgmt->u.action.category) {
1543 case WLAN_CATEGORY_BACK:
1544 switch (mgmt->u.action.u.addba_req.action_code) {
1545 case WLAN_ACTION_ADDBA_REQ:
1546 if (len < (IEEE80211_MIN_ACTION_SIZE +
1547 sizeof(mgmt->u.action.u.addba_req)))
1548 return RX_DROP_MONITOR;
1549 ieee80211_process_addba_request(local, rx->sta, mgmt, len);
1550 break;
1551 case WLAN_ACTION_ADDBA_RESP:
1552 if (len < (IEEE80211_MIN_ACTION_SIZE +
1553 sizeof(mgmt->u.action.u.addba_resp)))
1554 return RX_DROP_MONITOR;
1555 ieee80211_process_addba_resp(local, rx->sta, mgmt, len);
1556 break;
1557 case WLAN_ACTION_DELBA:
1558 if (len < (IEEE80211_MIN_ACTION_SIZE +
1559 sizeof(mgmt->u.action.u.delba)))
1560 return RX_DROP_MONITOR;
1561 ieee80211_process_delba(sdata, rx->sta, mgmt, len);
1562 break;
1563 }
1564 break;
1565 case WLAN_CATEGORY_SPECTRUM_MGMT:
1566 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
1567 return RX_DROP_MONITOR;
1568 switch (mgmt->u.action.u.measurement.action_code) {
1569 case WLAN_ACTION_SPCT_MSR_REQ:
1570 if (len < (IEEE80211_MIN_ACTION_SIZE +
1571 sizeof(mgmt->u.action.u.measurement)))
1572 return RX_DROP_MONITOR;
1573 ieee80211_process_measurement_req(sdata, mgmt, len);
1574 break;
1575 }
1576 break;
1577 default:
1578 return RX_CONTINUE;
1579 }
1580
1581 rx->sta->rx_packets++;
1582 dev_kfree_skb(rx->skb);
1583 return RX_QUEUED;
1584}
1585
1586static ieee80211_rx_result debug_noinline
1514ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) 1587ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1515{ 1588{
1516 struct ieee80211_sub_if_data *sdata; 1589 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1517 1590
1518 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1591 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1519 return RX_DROP_MONITOR; 1592 return RX_DROP_MONITOR;
1520 1593
1521 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 1594 if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
1522 if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || 1595 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1523 sdata->vif.type == IEEE80211_IF_TYPE_IBSS || 1596 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
1524 sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) && 1597 return RX_DROP_MONITOR;
1525 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) 1598
1526 ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status); 1599 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
1527 else
1528 return RX_DROP_MONITOR; 1600 return RX_DROP_MONITOR;
1529 1601
1602 ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
1530 return RX_QUEUED; 1603 return RX_QUEUED;
1531} 1604}
1532 1605
@@ -1689,6 +1762,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1689 CALL_RXH(ieee80211_rx_h_mesh_fwding); 1762 CALL_RXH(ieee80211_rx_h_mesh_fwding);
1690 CALL_RXH(ieee80211_rx_h_data) 1763 CALL_RXH(ieee80211_rx_h_data)
1691 CALL_RXH(ieee80211_rx_h_ctrl) 1764 CALL_RXH(ieee80211_rx_h_ctrl)
1765 CALL_RXH(ieee80211_rx_h_action)
1692 CALL_RXH(ieee80211_rx_h_mgmt) 1766 CALL_RXH(ieee80211_rx_h_mgmt)
1693 1767
1694#undef CALL_RXH 1768#undef CALL_RXH
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
new file mode 100644
index 000000000000..010781b806f3
--- /dev/null
+++ b/net/mac80211/scan.c
@@ -0,0 +1,933 @@
1/*
2 * Scanning implementation
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15/* TODO:
16 * order BSS list by RSSI(?) ("quality of AP")
17 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
18 * SSID)
19 */
20
21#include <linux/wireless.h>
22#include <linux/if_arp.h>
23#include <net/mac80211.h>
24#include <net/iw_handler.h>
25
26#include "ieee80211_i.h"
27#include "mesh.h"
28
29#define IEEE80211_PROBE_DELAY (HZ / 33)
30#define IEEE80211_CHANNEL_TIME (HZ / 33)
31#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
32
33void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
34{
35 spin_lock_init(&local->sta_bss_lock);
36 INIT_LIST_HEAD(&local->sta_bss_list);
37}
38
39void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
40{
41 struct ieee80211_sta_bss *bss, *tmp;
42
43 list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
44 ieee80211_rx_bss_put(local, bss);
45}
46
47struct ieee80211_sta_bss *
48ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
49 u8 *ssid, u8 ssid_len)
50{
51 struct ieee80211_sta_bss *bss;
52
53 spin_lock_bh(&local->sta_bss_lock);
54 bss = local->sta_bss_hash[STA_HASH(bssid)];
55 while (bss) {
56 if (!bss_mesh_cfg(bss) &&
57 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
58 bss->freq == freq &&
59 bss->ssid_len == ssid_len &&
60 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
61 atomic_inc(&bss->users);
62 break;
63 }
64 bss = bss->hnext;
65 }
66 spin_unlock_bh(&local->sta_bss_lock);
67 return bss;
68}
69
70/* Caller must hold local->sta_bss_lock */
71static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
72 struct ieee80211_sta_bss *bss)
73{
74 u8 hash_idx;
75
76 if (bss_mesh_cfg(bss))
77 hash_idx = mesh_id_hash(bss_mesh_id(bss),
78 bss_mesh_id_len(bss));
79 else
80 hash_idx = STA_HASH(bss->bssid);
81
82 bss->hnext = local->sta_bss_hash[hash_idx];
83 local->sta_bss_hash[hash_idx] = bss;
84}
85
86/* Caller must hold local->sta_bss_lock */
87static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
88 struct ieee80211_sta_bss *bss)
89{
90 struct ieee80211_sta_bss *b, *prev = NULL;
91 b = local->sta_bss_hash[STA_HASH(bss->bssid)];
92 while (b) {
93 if (b == bss) {
94 if (!prev)
95 local->sta_bss_hash[STA_HASH(bss->bssid)] =
96 bss->hnext;
97 else
98 prev->hnext = bss->hnext;
99 break;
100 }
101 prev = b;
102 b = b->hnext;
103 }
104}
105
106struct ieee80211_sta_bss *
107ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
108 u8 *ssid, u8 ssid_len)
109{
110 struct ieee80211_sta_bss *bss;
111
112 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
113 if (!bss)
114 return NULL;
115 atomic_set(&bss->users, 2);
116 memcpy(bss->bssid, bssid, ETH_ALEN);
117 bss->freq = freq;
118 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
119 memcpy(bss->ssid, ssid, ssid_len);
120 bss->ssid_len = ssid_len;
121 }
122
123 spin_lock_bh(&local->sta_bss_lock);
124 /* TODO: order by RSSI? */
125 list_add_tail(&bss->list, &local->sta_bss_list);
126 __ieee80211_rx_bss_hash_add(local, bss);
127 spin_unlock_bh(&local->sta_bss_lock);
128 return bss;
129}
130
131#ifdef CONFIG_MAC80211_MESH
132static struct ieee80211_sta_bss *
133ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
134 u8 *mesh_cfg, int freq)
135{
136 struct ieee80211_sta_bss *bss;
137
138 spin_lock_bh(&local->sta_bss_lock);
139 bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
140 while (bss) {
141 if (bss_mesh_cfg(bss) &&
142 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
143 bss->freq == freq &&
144 mesh_id_len == bss->mesh_id_len &&
145 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
146 mesh_id_len))) {
147 atomic_inc(&bss->users);
148 break;
149 }
150 bss = bss->hnext;
151 }
152 spin_unlock_bh(&local->sta_bss_lock);
153 return bss;
154}
155
156static struct ieee80211_sta_bss *
157ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
158 u8 *mesh_cfg, int mesh_config_len, int freq)
159{
160 struct ieee80211_sta_bss *bss;
161
162 if (mesh_config_len != MESH_CFG_LEN)
163 return NULL;
164
165 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
166 if (!bss)
167 return NULL;
168
169 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
170 if (!bss->mesh_cfg) {
171 kfree(bss);
172 return NULL;
173 }
174
175 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
176 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
177 if (!bss->mesh_id) {
178 kfree(bss->mesh_cfg);
179 kfree(bss);
180 return NULL;
181 }
182 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
183 }
184
185 atomic_set(&bss->users, 2);
186 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
187 bss->mesh_id_len = mesh_id_len;
188 bss->freq = freq;
189 spin_lock_bh(&local->sta_bss_lock);
190 /* TODO: order by RSSI? */
191 list_add_tail(&bss->list, &local->sta_bss_list);
192 __ieee80211_rx_bss_hash_add(local, bss);
193 spin_unlock_bh(&local->sta_bss_lock);
194 return bss;
195}
196#endif
197
198static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
199{
200 kfree(bss->ies);
201 kfree(bss_mesh_id(bss));
202 kfree(bss_mesh_cfg(bss));
203 kfree(bss);
204}
205
206void ieee80211_rx_bss_put(struct ieee80211_local *local,
207 struct ieee80211_sta_bss *bss)
208{
209 local_bh_disable();
210 if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
211 local_bh_enable();
212 return;
213 }
214
215 __ieee80211_rx_bss_hash_del(local, bss);
216 list_del(&bss->list);
217 spin_unlock_bh(&local->sta_bss_lock);
218 ieee80211_rx_bss_free(bss);
219}
220
221struct ieee80211_sta_bss *
222ieee80211_bss_info_update(struct ieee80211_local *local,
223 struct ieee80211_rx_status *rx_status,
224 struct ieee80211_mgmt *mgmt,
225 size_t len,
226 struct ieee802_11_elems *elems,
227 int freq, bool beacon)
228{
229 struct ieee80211_sta_bss *bss;
230 int clen;
231
232#ifdef CONFIG_MAC80211_MESH
233 if (elems->mesh_config)
234 bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
235 elems->mesh_id_len, elems->mesh_config, freq);
236 else
237#endif
238 bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
239 elems->ssid, elems->ssid_len);
240 if (!bss) {
241#ifdef CONFIG_MAC80211_MESH
242 if (elems->mesh_config)
243 bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
244 elems->mesh_id_len, elems->mesh_config,
245 elems->mesh_config_len, freq);
246 else
247#endif
248 bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq,
249 elems->ssid, elems->ssid_len);
250 if (!bss)
251 return NULL;
252 } else {
253#if 0
254 /* TODO: order by RSSI? */
255 spin_lock_bh(&local->sta_bss_lock);
256 list_move_tail(&bss->list, &local->sta_bss_list);
257 spin_unlock_bh(&local->sta_bss_lock);
258#endif
259 }
260
261 /* save the ERP value so that it is available at association time */
262 if (elems->erp_info && elems->erp_info_len >= 1) {
263 bss->erp_value = elems->erp_info[0];
264 bss->has_erp_value = 1;
265 }
266
267 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
268 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
269
270 if (elems->tim) {
271 struct ieee80211_tim_ie *tim_ie =
272 (struct ieee80211_tim_ie *)elems->tim;
273 bss->dtim_period = tim_ie->dtim_period;
274 }
275
276 /* set default value for buggy APs */
277 if (!elems->tim || bss->dtim_period == 0)
278 bss->dtim_period = 1;
279
280 bss->supp_rates_len = 0;
281 if (elems->supp_rates) {
282 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
283 if (clen > elems->supp_rates_len)
284 clen = elems->supp_rates_len;
285 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
286 clen);
287 bss->supp_rates_len += clen;
288 }
289 if (elems->ext_supp_rates) {
290 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
291 if (clen > elems->ext_supp_rates_len)
292 clen = elems->ext_supp_rates_len;
293 memcpy(&bss->supp_rates[bss->supp_rates_len],
294 elems->ext_supp_rates, clen);
295 bss->supp_rates_len += clen;
296 }
297
298 bss->band = rx_status->band;
299
300 bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
301 bss->last_update = jiffies;
302 bss->signal = rx_status->signal;
303 bss->noise = rx_status->noise;
304 bss->qual = rx_status->qual;
305 bss->wmm_used = elems->wmm_param || elems->wmm_info;
306
307 if (!beacon)
308 bss->last_probe_resp = jiffies;
309
310 /*
311 * For probe responses, or if we don't have any information yet,
312 * use the IEs from the beacon.
313 */
314 if (!bss->ies || !beacon) {
315 if (bss->ies == NULL || bss->ies_len < elems->total_len) {
316 kfree(bss->ies);
317 bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
318 }
319 if (bss->ies) {
320 memcpy(bss->ies, elems->ie_start, elems->total_len);
321 bss->ies_len = elems->total_len;
322 } else
323 bss->ies_len = 0;
324 }
325
326 return bss;
327}
328
329ieee80211_rx_result
330ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
331 struct ieee80211_rx_status *rx_status)
332{
333 struct ieee80211_mgmt *mgmt;
334 struct ieee80211_sta_bss *bss;
335 u8 *elements;
336 struct ieee80211_channel *channel;
337 size_t baselen;
338 int freq;
339 __le16 fc;
340 bool presp, beacon = false;
341 struct ieee802_11_elems elems;
342
343 if (skb->len < 2)
344 return RX_DROP_UNUSABLE;
345
346 mgmt = (struct ieee80211_mgmt *) skb->data;
347 fc = mgmt->frame_control;
348
349 if (ieee80211_is_ctl(fc))
350 return RX_CONTINUE;
351
352 if (skb->len < 24)
353 return RX_DROP_MONITOR;
354
355 presp = ieee80211_is_probe_resp(fc);
356 if (presp) {
357 /* ignore ProbeResp to foreign address */
358 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
359 return RX_DROP_MONITOR;
360
361 presp = true;
362 elements = mgmt->u.probe_resp.variable;
363 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
364 } else {
365 beacon = ieee80211_is_beacon(fc);
366 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
367 elements = mgmt->u.beacon.variable;
368 }
369
370 if (!presp && !beacon)
371 return RX_CONTINUE;
372
373 if (baselen > skb->len)
374 return RX_DROP_MONITOR;
375
376 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
377
378 if (elems.ds_params && elems.ds_params_len == 1)
379 freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
380 else
381 freq = rx_status->freq;
382
383 channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
384
385 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
386 return RX_DROP_MONITOR;
387
388 bss = ieee80211_bss_info_update(sdata->local, rx_status,
389 mgmt, skb->len, &elems,
390 freq, beacon);
391 ieee80211_rx_bss_put(sdata->local, bss);
392
393 dev_kfree_skb(skb);
394 return RX_QUEUED;
395}
396
397static void ieee80211_send_nullfunc(struct ieee80211_local *local,
398 struct ieee80211_sub_if_data *sdata,
399 int powersave)
400{
401 struct sk_buff *skb;
402 struct ieee80211_hdr *nullfunc;
403 __le16 fc;
404
405 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
406 if (!skb) {
407 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
408 "frame\n", sdata->dev->name);
409 return;
410 }
411 skb_reserve(skb, local->hw.extra_tx_headroom);
412
413 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
414 memset(nullfunc, 0, 24);
415 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
416 IEEE80211_FCTL_TODS);
417 if (powersave)
418 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
419 nullfunc->frame_control = fc;
420 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
421 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
422 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
423
424 ieee80211_tx_skb(sdata, skb, 0);
425}
426
427static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
428{
429 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
430 ieee80211_vif_is_mesh(&sdata->vif))
431 ieee80211_sta_timer((unsigned long)sdata);
432}
433
434void ieee80211_scan_completed(struct ieee80211_hw *hw)
435{
436 struct ieee80211_local *local = hw_to_local(hw);
437 struct ieee80211_sub_if_data *sdata;
438 union iwreq_data wrqu;
439
440 local->last_scan_completed = jiffies;
441 memset(&wrqu, 0, sizeof(wrqu));
442 wireless_send_event(local->scan_sdata->dev, SIOCGIWSCAN, &wrqu, NULL);
443
444 if (local->sta_hw_scanning) {
445 local->sta_hw_scanning = 0;
446 if (ieee80211_hw_config(local))
447 printk(KERN_DEBUG "%s: failed to restore operational "
448 "channel after scan\n", wiphy_name(local->hw.wiphy));
449 /* Restart STA timer for HW scan case */
450 rcu_read_lock();
451 list_for_each_entry_rcu(sdata, &local->interfaces, list)
452 ieee80211_restart_sta_timer(sdata);
453 rcu_read_unlock();
454
455 goto done;
456 }
457
458 local->sta_sw_scanning = 0;
459 if (ieee80211_hw_config(local))
460 printk(KERN_DEBUG "%s: failed to restore operational "
461 "channel after scan\n", wiphy_name(local->hw.wiphy));
462
463
464 netif_tx_lock_bh(local->mdev);
465 netif_addr_lock(local->mdev);
466 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
467 local->ops->configure_filter(local_to_hw(local),
468 FIF_BCN_PRBRESP_PROMISC,
469 &local->filter_flags,
470 local->mdev->mc_count,
471 local->mdev->mc_list);
472
473 netif_addr_unlock(local->mdev);
474 netif_tx_unlock_bh(local->mdev);
475
476 rcu_read_lock();
477 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
478 /* Tell AP we're back */
479 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
480 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
481 ieee80211_send_nullfunc(local, sdata, 0);
482 netif_tx_wake_all_queues(sdata->dev);
483 }
484 } else
485 netif_tx_wake_all_queues(sdata->dev);
486
487 ieee80211_restart_sta_timer(sdata);
488 }
489 rcu_read_unlock();
490
491 done:
492 ieee80211_mlme_notify_scan_completed(local);
493}
494EXPORT_SYMBOL(ieee80211_scan_completed);
495
496
497void ieee80211_sta_scan_work(struct work_struct *work)
498{
499 struct ieee80211_local *local =
500 container_of(work, struct ieee80211_local, scan_work.work);
501 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
502 struct ieee80211_supported_band *sband;
503 struct ieee80211_channel *chan;
504 int skip;
505 unsigned long next_delay = 0;
506
507 if (!local->sta_sw_scanning)
508 return;
509
510 switch (local->scan_state) {
511 case SCAN_SET_CHANNEL:
512 /*
513 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
514 * after we successfully scanned the last channel of the last
515 * band (and the last band is supported by the hw)
516 */
517 if (local->scan_band < IEEE80211_NUM_BANDS)
518 sband = local->hw.wiphy->bands[local->scan_band];
519 else
520 sband = NULL;
521
522 /*
523 * If we are at an unsupported band and have more bands
524 * left to scan, advance to the next supported one.
525 */
526 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
527 local->scan_band++;
528 sband = local->hw.wiphy->bands[local->scan_band];
529 local->scan_channel_idx = 0;
530 }
531
532 /* if no more bands/channels left, complete scan */
533 if (!sband || local->scan_channel_idx >= sband->n_channels) {
534 ieee80211_scan_completed(local_to_hw(local));
535 return;
536 }
537 skip = 0;
538 chan = &sband->channels[local->scan_channel_idx];
539
540 if (chan->flags & IEEE80211_CHAN_DISABLED ||
541 (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
542 chan->flags & IEEE80211_CHAN_NO_IBSS))
543 skip = 1;
544
545 if (!skip) {
546 local->scan_channel = chan;
547 if (ieee80211_hw_config(local)) {
548 printk(KERN_DEBUG "%s: failed to set freq to "
549 "%d MHz for scan\n", wiphy_name(local->hw.wiphy),
550 chan->center_freq);
551 skip = 1;
552 }
553 }
554
555 /* advance state machine to next channel/band */
556 local->scan_channel_idx++;
557 if (local->scan_channel_idx >= sband->n_channels) {
558 /*
559 * scan_band may end up == IEEE80211_NUM_BANDS, but
560 * we'll catch that case above and complete the scan
561 * if that is the case.
562 */
563 local->scan_band++;
564 local->scan_channel_idx = 0;
565 }
566
567 if (skip)
568 break;
569
570 next_delay = IEEE80211_PROBE_DELAY +
571 usecs_to_jiffies(local->hw.channel_change_time);
572 local->scan_state = SCAN_SEND_PROBE;
573 break;
574 case SCAN_SEND_PROBE:
575 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
576 local->scan_state = SCAN_SET_CHANNEL;
577
578 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
579 break;
580 ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
581 local->scan_ssid_len);
582 next_delay = IEEE80211_CHANNEL_TIME;
583 break;
584 }
585
586 if (local->sta_sw_scanning)
587 queue_delayed_work(local->hw.workqueue, &local->scan_work,
588 next_delay);
589}
590
591
592int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
593 u8 *ssid, size_t ssid_len)
594{
595 struct ieee80211_local *local = scan_sdata->local;
596 struct ieee80211_sub_if_data *sdata;
597
598 if (ssid_len > IEEE80211_MAX_SSID_LEN)
599 return -EINVAL;
600
601 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
602 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
603 * BSSID: MACAddress
604 * SSID
605 * ScanType: ACTIVE, PASSIVE
606 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
607 * a Probe frame during active scanning
608 * ChannelList
609 * MinChannelTime (>= ProbeDelay), in TU
610 * MaxChannelTime: (>= MinChannelTime), in TU
611 */
612
613 /* MLME-SCAN.confirm
614 * BSSDescriptionSet
615 * ResultCode: SUCCESS, INVALID_PARAMETERS
616 */
617
618 if (local->sta_sw_scanning || local->sta_hw_scanning) {
619 if (local->scan_sdata == scan_sdata)
620 return 0;
621 return -EBUSY;
622 }
623
624 if (local->ops->hw_scan) {
625 int rc = local->ops->hw_scan(local_to_hw(local),
626 ssid, ssid_len);
627 if (!rc) {
628 local->sta_hw_scanning = 1;
629 local->scan_sdata = scan_sdata;
630 }
631 return rc;
632 }
633
634 local->sta_sw_scanning = 1;
635
636 rcu_read_lock();
637 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
638 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
639 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
640 netif_tx_stop_all_queues(sdata->dev);
641 ieee80211_send_nullfunc(local, sdata, 1);
642 }
643 } else
644 netif_tx_stop_all_queues(sdata->dev);
645 }
646 rcu_read_unlock();
647
648 if (ssid) {
649 local->scan_ssid_len = ssid_len;
650 memcpy(local->scan_ssid, ssid, ssid_len);
651 } else
652 local->scan_ssid_len = 0;
653 local->scan_state = SCAN_SET_CHANNEL;
654 local->scan_channel_idx = 0;
655 local->scan_band = IEEE80211_BAND_2GHZ;
656 local->scan_sdata = scan_sdata;
657
658 netif_addr_lock_bh(local->mdev);
659 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
660 local->ops->configure_filter(local_to_hw(local),
661 FIF_BCN_PRBRESP_PROMISC,
662 &local->filter_flags,
663 local->mdev->mc_count,
664 local->mdev->mc_list);
665 netif_addr_unlock_bh(local->mdev);
666
667 /* TODO: start scan as soon as all nullfunc frames are ACKed */
668 queue_delayed_work(local->hw.workqueue, &local->scan_work,
669 IEEE80211_CHANNEL_TIME);
670
671 return 0;
672}
673
674
675int ieee80211_sta_req_scan(struct ieee80211_sub_if_data *sdata, u8 *ssid, size_t ssid_len)
676{
677 struct ieee80211_local *local = sdata->local;
678 struct ieee80211_if_sta *ifsta;
679
680 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
681 return ieee80211_sta_start_scan(sdata, ssid, ssid_len);
682
683 /*
684 * STA has a state machine that might need to defer scanning
685 * while it's trying to associate/authenticate, therefore we
686 * queue it up to the state machine in that case.
687 */
688
689 if (local->sta_sw_scanning || local->sta_hw_scanning) {
690 if (local->scan_sdata == sdata)
691 return 0;
692 return -EBUSY;
693 }
694
695 ifsta = &sdata->u.sta;
696
697 ifsta->scan_ssid_len = ssid_len;
698 if (ssid_len)
699 memcpy(ifsta->scan_ssid, ssid, ssid_len);
700 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
701 queue_work(local->hw.workqueue, &ifsta->work);
702
703 return 0;
704}
705
706
707static void ieee80211_sta_add_scan_ies(struct iw_request_info *info,
708 struct ieee80211_sta_bss *bss,
709 char **current_ev, char *end_buf)
710{
711 u8 *pos, *end, *next;
712 struct iw_event iwe;
713
714 if (bss == NULL || bss->ies == NULL)
715 return;
716
717 /*
718 * If needed, fragment the IEs buffer (at IE boundaries) into short
719 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
720 */
721 pos = bss->ies;
722 end = pos + bss->ies_len;
723
724 while (end - pos > IW_GENERIC_IE_MAX) {
725 next = pos + 2 + pos[1];
726 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
727 next = next + 2 + next[1];
728
729 memset(&iwe, 0, sizeof(iwe));
730 iwe.cmd = IWEVGENIE;
731 iwe.u.data.length = next - pos;
732 *current_ev = iwe_stream_add_point(info, *current_ev,
733 end_buf, &iwe, pos);
734
735 pos = next;
736 }
737
738 if (end > pos) {
739 memset(&iwe, 0, sizeof(iwe));
740 iwe.cmd = IWEVGENIE;
741 iwe.u.data.length = end - pos;
742 *current_ev = iwe_stream_add_point(info, *current_ev,
743 end_buf, &iwe, pos);
744 }
745}
746
747
748static char *
749ieee80211_sta_scan_result(struct ieee80211_local *local,
750 struct iw_request_info *info,
751 struct ieee80211_sta_bss *bss,
752 char *current_ev, char *end_buf)
753{
754 struct iw_event iwe;
755 char *buf;
756
757 if (time_after(jiffies,
758 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
759 return current_ev;
760
761 memset(&iwe, 0, sizeof(iwe));
762 iwe.cmd = SIOCGIWAP;
763 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
764 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
765 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
766 IW_EV_ADDR_LEN);
767
768 memset(&iwe, 0, sizeof(iwe));
769 iwe.cmd = SIOCGIWESSID;
770 if (bss_mesh_cfg(bss)) {
771 iwe.u.data.length = bss_mesh_id_len(bss);
772 iwe.u.data.flags = 1;
773 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
774 &iwe, bss_mesh_id(bss));
775 } else {
776 iwe.u.data.length = bss->ssid_len;
777 iwe.u.data.flags = 1;
778 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
779 &iwe, bss->ssid);
780 }
781
782 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
783 || bss_mesh_cfg(bss)) {
784 memset(&iwe, 0, sizeof(iwe));
785 iwe.cmd = SIOCGIWMODE;
786 if (bss_mesh_cfg(bss))
787 iwe.u.mode = IW_MODE_MESH;
788 else if (bss->capability & WLAN_CAPABILITY_ESS)
789 iwe.u.mode = IW_MODE_MASTER;
790 else
791 iwe.u.mode = IW_MODE_ADHOC;
792 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
793 &iwe, IW_EV_UINT_LEN);
794 }
795
796 memset(&iwe, 0, sizeof(iwe));
797 iwe.cmd = SIOCGIWFREQ;
798 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
799 iwe.u.freq.e = 0;
800 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
801 IW_EV_FREQ_LEN);
802
803 memset(&iwe, 0, sizeof(iwe));
804 iwe.cmd = SIOCGIWFREQ;
805 iwe.u.freq.m = bss->freq;
806 iwe.u.freq.e = 6;
807 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
808 IW_EV_FREQ_LEN);
809 memset(&iwe, 0, sizeof(iwe));
810 iwe.cmd = IWEVQUAL;
811 iwe.u.qual.qual = bss->qual;
812 iwe.u.qual.level = bss->signal;
813 iwe.u.qual.noise = bss->noise;
814 iwe.u.qual.updated = local->wstats_flags;
815 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
816 IW_EV_QUAL_LEN);
817
818 memset(&iwe, 0, sizeof(iwe));
819 iwe.cmd = SIOCGIWENCODE;
820 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
821 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
822 else
823 iwe.u.data.flags = IW_ENCODE_DISABLED;
824 iwe.u.data.length = 0;
825 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
826 &iwe, "");
827
828 ieee80211_sta_add_scan_ies(info, bss, &current_ev, end_buf);
829
830 if (bss->supp_rates_len > 0) {
831 /* display all supported rates in readable format */
832 char *p = current_ev + iwe_stream_lcp_len(info);
833 int i;
834
835 memset(&iwe, 0, sizeof(iwe));
836 iwe.cmd = SIOCGIWRATE;
837 /* Those two flags are ignored... */
838 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
839
840 for (i = 0; i < bss->supp_rates_len; i++) {
841 iwe.u.bitrate.value = ((bss->supp_rates[i] &
842 0x7f) * 500000);
843 p = iwe_stream_add_value(info, current_ev, p,
844 end_buf, &iwe, IW_EV_PARAM_LEN);
845 }
846 current_ev = p;
847 }
848
849 buf = kmalloc(30, GFP_ATOMIC);
850 if (buf) {
851 memset(&iwe, 0, sizeof(iwe));
852 iwe.cmd = IWEVCUSTOM;
853 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
854 iwe.u.data.length = strlen(buf);
855 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
856 &iwe, buf);
857 memset(&iwe, 0, sizeof(iwe));
858 iwe.cmd = IWEVCUSTOM;
859 sprintf(buf, " Last beacon: %dms ago",
860 jiffies_to_msecs(jiffies - bss->last_update));
861 iwe.u.data.length = strlen(buf);
862 current_ev = iwe_stream_add_point(info, current_ev,
863 end_buf, &iwe, buf);
864 kfree(buf);
865 }
866
867 if (bss_mesh_cfg(bss)) {
868 u8 *cfg = bss_mesh_cfg(bss);
869 buf = kmalloc(50, GFP_ATOMIC);
870 if (buf) {
871 memset(&iwe, 0, sizeof(iwe));
872 iwe.cmd = IWEVCUSTOM;
873 sprintf(buf, "Mesh network (version %d)", cfg[0]);
874 iwe.u.data.length = strlen(buf);
875 current_ev = iwe_stream_add_point(info, current_ev,
876 end_buf,
877 &iwe, buf);
878 sprintf(buf, "Path Selection Protocol ID: "
879 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
880 cfg[4]);
881 iwe.u.data.length = strlen(buf);
882 current_ev = iwe_stream_add_point(info, current_ev,
883 end_buf,
884 &iwe, buf);
885 sprintf(buf, "Path Selection Metric ID: "
886 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
887 cfg[8]);
888 iwe.u.data.length = strlen(buf);
889 current_ev = iwe_stream_add_point(info, current_ev,
890 end_buf,
891 &iwe, buf);
892 sprintf(buf, "Congestion Control Mode ID: "
893 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
894 cfg[11], cfg[12]);
895 iwe.u.data.length = strlen(buf);
896 current_ev = iwe_stream_add_point(info, current_ev,
897 end_buf,
898 &iwe, buf);
899 sprintf(buf, "Channel Precedence: "
900 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
901 cfg[15], cfg[16]);
902 iwe.u.data.length = strlen(buf);
903 current_ev = iwe_stream_add_point(info, current_ev,
904 end_buf,
905 &iwe, buf);
906 kfree(buf);
907 }
908 }
909
910 return current_ev;
911}
912
913
914int ieee80211_sta_scan_results(struct ieee80211_local *local,
915 struct iw_request_info *info,
916 char *buf, size_t len)
917{
918 char *current_ev = buf;
919 char *end_buf = buf + len;
920 struct ieee80211_sta_bss *bss;
921
922 spin_lock_bh(&local->sta_bss_lock);
923 list_for_each_entry(bss, &local->sta_bss_list, list) {
924 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
925 spin_unlock_bh(&local->sta_bss_lock);
926 return -E2BIG;
927 }
928 current_ev = ieee80211_sta_scan_result(local, info, bss,
929 current_ev, end_buf);
930 }
931 spin_unlock_bh(&local->sta_bss_lock);
932 return current_ev - buf;
933}
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
new file mode 100644
index 000000000000..f72bad636d8e
--- /dev/null
+++ b/net/mac80211/spectmgmt.c
@@ -0,0 +1,86 @@
1/*
2 * spectrum management
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2008, Intel Corporation
10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/ieee80211.h>
18#include <net/wireless.h>
19#include <net/mac80211.h>
20#include "ieee80211_i.h"
21#include "sta_info.h"
22#include "wme.h"
23
24static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
25 struct ieee80211_msrment_ie *request_ie,
26 const u8 *da, const u8 *bssid,
27 u8 dialog_token)
28{
29 struct ieee80211_local *local = sdata->local;
30 struct sk_buff *skb;
31 struct ieee80211_mgmt *msr_report;
32
33 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
34 sizeof(struct ieee80211_msrment_ie));
35
36 if (!skb) {
37 printk(KERN_ERR "%s: failed to allocate buffer for "
38 "measurement report frame\n", sdata->dev->name);
39 return;
40 }
41
42 skb_reserve(skb, local->hw.extra_tx_headroom);
43 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
44 memset(msr_report, 0, 24);
45 memcpy(msr_report->da, da, ETH_ALEN);
46 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
47 memcpy(msr_report->bssid, bssid, ETH_ALEN);
48 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
49 IEEE80211_STYPE_ACTION);
50
51 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
52 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
53 msr_report->u.action.u.measurement.action_code =
54 WLAN_ACTION_SPCT_MSR_RPRT;
55 msr_report->u.action.u.measurement.dialog_token = dialog_token;
56
57 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
58 msr_report->u.action.u.measurement.length =
59 sizeof(struct ieee80211_msrment_ie);
60
61 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
62 sizeof(struct ieee80211_msrment_ie));
63 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
64 msr_report->u.action.u.measurement.msr_elem.mode |=
65 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
66 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
67
68 ieee80211_tx_skb(sdata, skb, 0);
69}
70
71void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
72 struct ieee80211_mgmt *mgmt,
73 size_t len)
74{
75 /*
76 * Ignoring measurement request is spec violation.
77 * Mandatory measurements must be reported optional
78 * measurements might be refused or reported incapable
79 * For now just refuse
80 * TODO: Answer basic measurement as unmeasured
81 */
82 ieee80211_send_refuse_measurement_request(sdata,
83 &mgmt->u.action.u.measurement.msr_elem,
84 mgmt->sa, mgmt->bssid,
85 mgmt->u.action.u.measurement.dialog_token);
86}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index f40c060341ae..c3a22ab2ad2e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -428,3 +428,187 @@ void ieee80211_iterate_active_interfaces_atomic(
428 rcu_read_unlock(); 428 rcu_read_unlock();
429} 429}
430EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 430EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
431
432void ieee802_11_parse_elems(u8 *start, size_t len,
433 struct ieee802_11_elems *elems)
434{
435 size_t left = len;
436 u8 *pos = start;
437
438 memset(elems, 0, sizeof(*elems));
439 elems->ie_start = start;
440 elems->total_len = len;
441
442 while (left >= 2) {
443 u8 id, elen;
444
445 id = *pos++;
446 elen = *pos++;
447 left -= 2;
448
449 if (elen > left)
450 return;
451
452 switch (id) {
453 case WLAN_EID_SSID:
454 elems->ssid = pos;
455 elems->ssid_len = elen;
456 break;
457 case WLAN_EID_SUPP_RATES:
458 elems->supp_rates = pos;
459 elems->supp_rates_len = elen;
460 break;
461 case WLAN_EID_FH_PARAMS:
462 elems->fh_params = pos;
463 elems->fh_params_len = elen;
464 break;
465 case WLAN_EID_DS_PARAMS:
466 elems->ds_params = pos;
467 elems->ds_params_len = elen;
468 break;
469 case WLAN_EID_CF_PARAMS:
470 elems->cf_params = pos;
471 elems->cf_params_len = elen;
472 break;
473 case WLAN_EID_TIM:
474 elems->tim = pos;
475 elems->tim_len = elen;
476 break;
477 case WLAN_EID_IBSS_PARAMS:
478 elems->ibss_params = pos;
479 elems->ibss_params_len = elen;
480 break;
481 case WLAN_EID_CHALLENGE:
482 elems->challenge = pos;
483 elems->challenge_len = elen;
484 break;
485 case WLAN_EID_WPA:
486 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
487 pos[2] == 0xf2) {
488 /* Microsoft OUI (00:50:F2) */
489 if (pos[3] == 1) {
490 /* OUI Type 1 - WPA IE */
491 elems->wpa = pos;
492 elems->wpa_len = elen;
493 } else if (elen >= 5 && pos[3] == 2) {
494 if (pos[4] == 0) {
495 elems->wmm_info = pos;
496 elems->wmm_info_len = elen;
497 } else if (pos[4] == 1) {
498 elems->wmm_param = pos;
499 elems->wmm_param_len = elen;
500 }
501 }
502 }
503 break;
504 case WLAN_EID_RSN:
505 elems->rsn = pos;
506 elems->rsn_len = elen;
507 break;
508 case WLAN_EID_ERP_INFO:
509 elems->erp_info = pos;
510 elems->erp_info_len = elen;
511 break;
512 case WLAN_EID_EXT_SUPP_RATES:
513 elems->ext_supp_rates = pos;
514 elems->ext_supp_rates_len = elen;
515 break;
516 case WLAN_EID_HT_CAPABILITY:
517 elems->ht_cap_elem = pos;
518 elems->ht_cap_elem_len = elen;
519 break;
520 case WLAN_EID_HT_EXTRA_INFO:
521 elems->ht_info_elem = pos;
522 elems->ht_info_elem_len = elen;
523 break;
524 case WLAN_EID_MESH_ID:
525 elems->mesh_id = pos;
526 elems->mesh_id_len = elen;
527 break;
528 case WLAN_EID_MESH_CONFIG:
529 elems->mesh_config = pos;
530 elems->mesh_config_len = elen;
531 break;
532 case WLAN_EID_PEER_LINK:
533 elems->peer_link = pos;
534 elems->peer_link_len = elen;
535 break;
536 case WLAN_EID_PREQ:
537 elems->preq = pos;
538 elems->preq_len = elen;
539 break;
540 case WLAN_EID_PREP:
541 elems->prep = pos;
542 elems->prep_len = elen;
543 break;
544 case WLAN_EID_PERR:
545 elems->perr = pos;
546 elems->perr_len = elen;
547 break;
548 case WLAN_EID_CHANNEL_SWITCH:
549 elems->ch_switch_elem = pos;
550 elems->ch_switch_elem_len = elen;
551 break;
552 case WLAN_EID_QUIET:
553 if (!elems->quiet_elem) {
554 elems->quiet_elem = pos;
555 elems->quiet_elem_len = elen;
556 }
557 elems->num_of_quiet_elem++;
558 break;
559 case WLAN_EID_COUNTRY:
560 elems->country_elem = pos;
561 elems->country_elem_len = elen;
562 break;
563 case WLAN_EID_PWR_CONSTRAINT:
564 elems->pwr_constr_elem = pos;
565 elems->pwr_constr_elem_len = elen;
566 break;
567 default:
568 break;
569 }
570
571 left -= elen;
572 pos += elen;
573 }
574}
575
576void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
577{
578 struct ieee80211_local *local = sdata->local;
579 struct ieee80211_tx_queue_params qparam;
580 int i;
581
582 if (!local->ops->conf_tx)
583 return;
584
585 memset(&qparam, 0, sizeof(qparam));
586
587 qparam.aifs = 2;
588
589 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
590 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
591 qparam.cw_min = 31;
592 else
593 qparam.cw_min = 15;
594
595 qparam.cw_max = 1023;
596 qparam.txop = 0;
597
598 for (i = 0; i < local_to_hw(local)->queues; i++)
599 local->ops->conf_tx(local_to_hw(local), i, &qparam);
600}
601
602void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
603 int encrypt)
604{
605 skb->dev = sdata->local->mdev;
606 skb_set_mac_header(skb, 0);
607 skb_set_network_header(skb, 0);
608 skb_set_transport_header(skb, 0);
609
610 skb->iif = sdata->dev->ifindex;
611 skb->do_not_encrypt = !encrypt;
612
613 dev_queue_xmit(skb);
614}