aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/debugfs_key.c6
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/mlme.c91
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/sta_info.h1
6 files changed, 78 insertions, 35 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 7439b63df5d..cf82acec913 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -265,7 +265,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
key = sdata->default_key;
if (key) {
sprintf(buf, "../keys/%d", key->debugfs.cnt);
- sdata->debugfs.default_key =
+ sdata->common_debugfs.default_key =
debugfs_create_symlink("default_key",
sdata->debugfsdir, buf);
} else
@@ -277,8 +277,8 @@ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
if (!sdata)
return;
- debugfs_remove(sdata->debugfs.default_key);
- sdata->debugfs.default_key = NULL;
+ debugfs_remove(sdata->common_debugfs.default_key);
+ sdata->common_debugfs.default_key = NULL;
}
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 570ae83c71b..c68d4df1119 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -498,8 +498,10 @@ struct ieee80211_sub_if_data {
struct {
struct dentry *mode;
} monitor;
- struct dentry *default_key;
} debugfs;
+ struct {
+ struct dentry *default_key;
+ } common_debugfs;
#ifdef CONFIG_MAC80211_MESH
struct dentry *mesh_stats_dir;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 638b75f36e2..396cfb2d0f4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1675,6 +1675,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
}
}
+ /* if low-level driver supports AP, we also support VLAN */
+ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
+ local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
+
+ /* mac80211 always supports monitor */
+ local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
return result;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7d53382f1a5..df12e746b03 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -508,7 +508,6 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu,
ifsta->assocreq_ies);
}
-
if (ifsta->assocresp_ies) {
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = ifsta->assocresp_ies_len;
@@ -2557,6 +2556,33 @@ u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
return supp_rates;
}
+static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local,
+ enum ieee80211_band band)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_rate *bitrates;
+ u64 mandatory_rates;
+ enum ieee80211_rate_flags mandatory_flag;
+ int i;
+
+ sband = local->hw.wiphy->bands[band];
+ if (!sband) {
+ WARN_ON(1);
+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ }
+
+ if (band == IEEE80211_BAND_2GHZ)
+ mandatory_flag = IEEE80211_RATE_MANDATORY_B;
+ else
+ mandatory_flag = IEEE80211_RATE_MANDATORY_A;
+
+ bitrates = sband->bitrates;
+ mandatory_rates = 0;
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (bitrates[i].flags & mandatory_flag)
+ mandatory_rates |= BIT(i);
+ return mandatory_rates;
+}
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
@@ -2568,9 +2594,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
int freq, clen;
struct ieee80211_sta_bss *bss;
struct sta_info *sta;
- u64 beacon_timestamp, rx_timestamp;
struct ieee80211_channel *channel;
+ u64 beacon_timestamp, rx_timestamp;
+ u64 supp_rates = 0;
bool beacon = ieee80211_is_beacon(mgmt->frame_control);
+ enum ieee80211_band band = rx_status->band;
DECLARE_MAC_BUF(mac);
DECLARE_MAC_BUF(mac2);
@@ -2578,30 +2606,41 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
elems->mesh_config && mesh_matches_local(elems, sdata)) {
- u64 rates = ieee80211_sta_get_rates(local, elems,
- rx_status->band);
+ supp_rates = ieee80211_sta_get_rates(local, elems, band);
- mesh_neighbour_update(mgmt->sa, rates, sdata,
+ mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
mesh_peer_accepts_plinks(elems));
}
rcu_read_lock();
if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
- memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
- (sta = sta_info_get(local, mgmt->sa))) {
- u64 prev_rates;
- u64 supp_rates = ieee80211_sta_get_rates(local, elems,
- rx_status->band);
-
- prev_rates = sta->supp_rates[rx_status->band];
- sta->supp_rates[rx_status->band] &= supp_rates;
- if (sta->supp_rates[rx_status->band] == 0) {
- /* No matching rates - this should not really happen.
- * Make sure that at least one rate is marked
- * supported to avoid issues with TX rate ctrl. */
- sta->supp_rates[rx_status->band] =
- sdata->u.sta.supp_rates_bits[rx_status->band];
+ memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
+
+ supp_rates = ieee80211_sta_get_rates(local, elems, band);
+
+ sta = sta_info_get(local, mgmt->sa);
+ if (sta) {
+ u64 prev_rates;
+
+ prev_rates = sta->supp_rates[band];
+ /* make sure mandatory rates are always added */
+ sta->supp_rates[band] = supp_rates |
+ ieee80211_sta_get_mandatory_rates(local, band);
+
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+ if (sta->supp_rates[band] != prev_rates)
+ printk(KERN_DEBUG "%s: updated supp_rates set "
+ "for %s based on beacon info (0x%llx | "
+ "0x%llx -> 0x%llx)\n",
+ sdata->dev->name, print_mac(mac, sta->addr),
+ (unsigned long long) prev_rates,
+ (unsigned long long) supp_rates,
+ (unsigned long long) sta->supp_rates[band]);
+#endif
+ } else {
+ ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
+ mgmt->sa, supp_rates);
}
}
@@ -2683,7 +2722,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
bss->supp_rates_len += clen;
}
- bss->band = rx_status->band;
+ bss->band = band;
bss->timestamp = beacon_timestamp;
bss->last_update = jiffies;
@@ -2738,7 +2777,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
* e.g: at 1 MBit that means mactime is 192 usec earlier
* (=24 bytes * 8 usecs/byte) than the beacon timestamp.
*/
- int rate = local->hw.wiphy->bands[rx_status->band]->
+ int rate = local->hw.wiphy->bands[band]->
bitrates[rx_status->rate_idx].bitrate;
rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
} else if (local && local->ops && local->ops->get_tsf)
@@ -2766,7 +2805,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
ieee80211_ibss_add_sta(sdata, NULL,
mgmt->bssid, mgmt->sa,
- BIT(rx_status->rate_idx));
+ supp_rates);
}
}
@@ -3032,7 +3071,6 @@ void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *
kfree_skb(skb);
}
-
static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
@@ -4316,10 +4354,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
set_sta_flags(sta, WLAN_STA_AUTHORIZED);
- if (supp_rates)
- sta->supp_rates[band] = supp_rates;
- else
- sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band];
+ /* make sure mandatory rates are always added */
+ sta->supp_rates[band] = supp_rates |
+ ieee80211_sta_get_mandatory_rates(local, band);
rate_control_rate_init(sta, local);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fd83ef760a3..7e09b30dd39 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1743,10 +1743,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
if (!bssid)
return 0;
if (ieee80211_is_beacon(hdr->frame_control)) {
- if (!rx->sta)
- rx->sta = ieee80211_ibss_add_sta(sdata,
- rx->skb, bssid, hdr->addr2,
- BIT(rx->status->rate_idx));
return 1;
}
else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 109db787ccb..4a581a5b576 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -204,6 +204,7 @@ struct sta_ampdu_mlme {
* @tx_fragments: number of transmitted MPDUs
* @txrate_idx: TBD
* @last_txrate_idx: TBD
+ * @tid_seq: TBD
* @wme_tx_queue: TBD
* @ampdu_mlme: TBD
* @timer_to_tid: identity mapping to ID timers