summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/ht.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/wep.c8
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/mlme.c23
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/radiotap.c58
-rw-r--r--net/wireless/sysfs.c9
-rw-r--r--net/wireless/wext-compat.c4
16 files changed, 195 insertions, 82 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ecf9b7166ed1..18bd0e550600 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
STATION_INFO_TX_PACKETS |
STATION_INFO_TX_RETRIES |
STATION_INFO_TX_FAILED |
- STATION_INFO_TX_BITRATE;
+ STATION_INFO_TX_BITRATE |
+ STATION_INFO_RX_DROP_MISC;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
sinfo->rx_bytes = sta->rx_bytes;
@@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo->tx_packets = sta->tx_packets;
sinfo->tx_retries = sta->tx_retry_count;
sinfo->tx_failed = sta->tx_retry_failed;
+ sinfo->rx_dropped_misc = sta->rx_dropped;
if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
(sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1602,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
+static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
+ struct net_device *dev,
+ u16 frame_type, bool reg)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+ return;
+
+ if (reg)
+ local->probe_req_reg++;
+ else
+ local->probe_req_reg--;
+
+ ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -1653,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
.mgmt_tx = ieee80211_mgmt_tx,
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
+ .mgmt_frame_register = ieee80211_mgmt_frame_register,
};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4214bb6e12fc..75d679d75e63 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
smps_mode = IEEE80211_SMPS_AUTOMATIC;
+ sdata->u.mgd.driver_smps_mode = smps_mode;
+
ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.request_smps_work);
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f0610fa4fbe0..b80c38689927 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -707,7 +707,9 @@ struct ieee80211_local {
int open_count;
int monitors, cooked_mntrs;
/* number of interfaces with corresponding FIF_ flags */
- int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
+ int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+ fif_probe_req;
+ int probe_req_reg;
unsigned int filter_flags; /* FIF_* */
bool wiphy_ciphers_allocated;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e99d1b60557c..f9163b12c7f1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
ieee80211_start_mesh(sdata);
} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll++;
+ local->fif_probe_req++;
ieee80211_configure_filter(local);
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ local->fif_probe_req++;
}
changed |= ieee80211_reset_erp_info(sdata);
@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_dec(&local->iff_promiscs);
- if (sdata->vif.type == NL80211_IFTYPE_AP)
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll--;
+ local->fif_probe_req--;
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ local->fif_probe_req--;
+ }
netif_addr_lock_bh(sdata->dev);
spin_lock_bh(&local->filter_lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index eb0f59977676..22bc42b18991 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
if (local->monitors || local->scanning)
new_flags |= FIF_BCN_PRBRESP_PROMISC;
+ if (local->fif_probe_req || local->probe_req_reg)
+ new_flags |= FIF_PROBE_REQ;
+
if (local->fif_fcsfail)
new_flags |= FIF_FCSFAIL;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
enum plink_event event;
enum plink_frame_type ftype;
size_t baselen;
- bool deactivated;
+ bool deactivated, matches_local = true;
u8 ie_len;
u8 *baseaddr;
__le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
/* Now we will figure out the appropriate event... */
event = PLINK_UNDEFINED;
if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
+ matches_local = false;
switch (ftype) {
case PLINK_OPEN:
event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
/* avoid warning */
break;
}
- spin_lock_bh(&sta->lock);
+ }
+
+ if (!sta && !matches_local) {
+ rcu_read_unlock();
+ reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+ llid = 0;
+ mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
+ plid, reason);
+ return;
} else if (!sta) {
/* ftype == PLINK_OPEN */
u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
event = OPN_ACPT;
spin_lock_bh(&sta->lock);
- } else {
+ } else if (matches_local) {
spin_lock_bh(&sta->lock);
switch (ftype) {
case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
rcu_read_unlock();
return;
}
+ } else {
+ spin_lock_bh(&sta->lock);
}
mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5695c94c49aa..a3a9421555af 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "No probe response from AP %pM"
- " after %dms, try %d\n", bssid,
- (1000 * IEEE80211_PROBE_WAIT)/HZ,
- ifmgd->probe_send_count);
+ wiphy_debug(local->hw.wiphy,
+ "%s: No probe response from AP %pM"
+ " after %dms, try %d\n",
+ sdata->name,
+ bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
+ ifmgd->probe_send_count);
#endif
ieee80211_mgd_probe_ap_send(sdata);
} else {
@@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
*/
ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL);
- printk(KERN_DEBUG "No probe response from AP %pM"
- " after %dms, disconnecting.\n",
- bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+ wiphy_debug(local->hw.wiphy,
+ "%s: No probe response from AP %pM"
+ " after %dms, disconnecting.\n",
+ sdata->name,
+ bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
ieee80211_set_disassoc(sdata, true, true);
mutex_unlock(&ifmgd->mtx);
mutex_lock(&local->mtx);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- if (!info->status.ampdu_len) {
- info->status.ampdu_ack_len = 1;
+ if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
+ info->status.ampdu_ack_len =
+ (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
info->status.ampdu_len = 1;
}
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
group = minstrel_ht_get_group_idx(&ar[i]);
rate = &mi->groups[group].rates[ar[i].idx % 8];
- if (last && (info->flags & IEEE80211_TX_STAT_ACK))
+ if (last)
rate->success += info->status.ampdu_ack_len;
rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b67221def584..902b03ee8f60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
tid_agg_rx->buf_size;
}
+ /*
+ * Disable the reorder release timer for now.
+ *
+ * The current implementation lacks a proper locking scheme
+ * which would protect vital statistic and debug counters
+ * from being updated by two different but concurrent BHs.
+ *
+ * More information about the topic is available from:
+ * - thread: http://marc.info/?t=128635927000001
+ *
+ * What was wrong:
+ * => http://marc.info/?l=linux-wireless&m=128636170811964
+ * "Basically the thing is that until your patch, the data
+ * in the struct didn't actually need locking because it
+ * was accessed by the RX path only which is not concurrent."
+ *
+ * List of what needs to be fixed:
+ * => http://marc.info/?l=linux-wireless&m=128656352920957
+ *
+
if (tid_agg_rx->stored_mpdu_num) {
j = index = seq_sub(tid_agg_rx->head_seq_num,
tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
} else {
del_timer(&tid_agg_rx->reorder_timer);
}
+ */
+
+set_release_timer:
+ return;
}
/*
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index f27484c22b9f..2ff6d1e3ed21 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
struct ieee80211_key *key)
{
u32 klen;
- u8 *rc4key;
+ u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
u8 keyidx;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
unsigned int hdrlen;
@@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
klen = 3 + key->conf.keylen;
- rc4key = kmalloc(klen, GFP_ATOMIC);
- if (!rc4key)
- return -1;
-
/* Prepend 24-bit IV to RC4 key */
memcpy(rc4key, skb->data + hdrlen, 3);
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
len))
ret = -1;
- kfree(rc4key);
-
/* Trim ICV */
skb_trim(skb, skb->len - WEP_ICV_LEN);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1684ad91763c..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
char *newname)
{
struct cfg80211_registered_device *rdev2;
- int result;
+ int wiphy_idx, taken = -1, result, digits;
assert_cfg80211_lock();
+ /* prohibit calling the thing phy%d when %d is not its number */
+ sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
+ if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
+ /* count number of places needed to print wiphy_idx */
+ digits = 1;
+ while (wiphy_idx /= 10)
+ digits++;
+ /*
+ * deny the name if it is phy<idx> where <idx> is printed
+ * without leading zeroes. taken == strlen(newname) here
+ */
+ if (taken == strlen(PHY_NAME) + digits)
+ return -EINVAL;
+ }
+
+
/* Ignore nop renames */
if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
/* Ensure another device does not already have this name. */
list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
- return -EEXIST;
+ return -EINVAL;
result = device_rename(&rdev->wiphy.dev, newname);
if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
{
static int wiphy_counter;
- int i;
- struct cfg80211_registered_device *rdev, *rdev2;
+
+ struct cfg80211_registered_device *rdev;
int alloc_size;
- char nname[IFNAMSIZ + 1];
- bool found = false;
WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
wiphy_counter--;
- goto too_many_devs;
- }
-
- /* 64k wiphy devices is enough for anyone! */
- for (i = 0; i < 0xFFFF; i++) {
- found = false;
- snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
- nname[sizeof(nname)-1] = 0;
- list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
- if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
- found = true;
- break;
- }
-
- if (!found)
- break;
- }
-
- if (unlikely(found)) {
-too_many_devs:
mutex_unlock(&cfg80211_mutex);
- /* ugh, too many devices already! */
+ /* ugh, wrapped! */
kfree(rdev);
return NULL;
}
- /* give it a proper name */
- dev_set_name(&rdev->wiphy.dev, "%s", nname);
-
mutex_unlock(&cfg80211_mutex);
+ /* give it a proper name */
+ dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
+
mutex_init(&rdev->mtx);
mutex_init(&rdev->devlist_mtx);
INIT_LIST_HEAD(&rdev->netdev_list);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caf11a427507..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
u16 frame_type, const u8 *match_data,
int match_len)
{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
struct cfg80211_mgmt_registration *reg, *nreg;
int err = 0;
u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
nreg->frame_type = cpu_to_le16(frame_type);
list_add(&nreg->list, &wdev->mgmt_registrations);
+ if (rdev->ops->mgmt_frame_register)
+ rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+ frame_type, true);
+
out:
spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
return err;
}
void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
struct cfg80211_mgmt_registration *reg, *tmp;
spin_lock_bh(&wdev->mgmt_registrations_lock);
list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
- if (reg->nlpid == nlpid) {
- list_del(&reg->list);
- kfree(reg);
+ if (reg->nlpid != nlpid)
+ continue;
+
+ if (rdev->ops->mgmt_frame_register) {
+ u16 frame_type = le16_to_cpu(reg->frame_type);
+
+ rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+ frame_type, false);
}
+
+ list_del(&reg->list);
+ kfree(reg);
}
spin_unlock_bh(&wdev->mgmt_registrations_lock);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 882dc921103b..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
survey->noise);
if (survey->filled & SURVEY_INFO_IN_USE)
NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
+ survey->channel_time);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+ survey->channel_time_busy);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+ survey->channel_time_ext_busy);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+ survey->channel_time_rx);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+ survey->channel_time_tx);
nla_nest_end(msg, infoattr);
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
{
while (1) {
int hit = 0;
- int pad, align, size, subns, vnslen;
+ int pad, align, size, subns;
uint32_t oui;
/* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
if (pad)
iterator->_arg += align - pad;
+ if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
+ int vnslen;
+
+ if ((unsigned long)iterator->_arg + size -
+ (unsigned long)iterator->_rtheader >
+ (unsigned long)iterator->_max_length)
+ return -EINVAL;
+
+ oui = (*iterator->_arg << 16) |
+ (*(iterator->_arg + 1) << 8) |
+ *(iterator->_arg + 2);
+ subns = *(iterator->_arg + 3);
+
+ find_ns(iterator, oui, subns);
+
+ vnslen = get_unaligned_le16(iterator->_arg + 4);
+ iterator->_next_ns_data = iterator->_arg + size + vnslen;
+ if (!iterator->current_namespace)
+ size += vnslen;
+ }
+
/*
* this is what we will return to user, but we need to
* move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
/* these special ones are valid in each bitmap word */
switch (iterator->_arg_index % 32) {
case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
- iterator->_bitmap_shifter >>= 1;
- iterator->_arg_index++;
-
iterator->_reset_on_ext = 1;
- vnslen = get_unaligned_le16(iterator->this_arg + 4);
- iterator->_next_ns_data = iterator->_arg + vnslen;
- oui = (*iterator->this_arg << 16) |
- (*(iterator->this_arg + 1) << 8) |
- *(iterator->this_arg + 2);
- subns = *(iterator->this_arg + 3);
-
- find_ns(iterator, oui, subns);
-
iterator->is_radiotap_ns = 0;
- /* allow parsers to show this information */
+ /*
+ * If parser didn't register this vendor
+ * namespace with us, allow it to show it
+ * as 'raw. Do do that, set argument index
+ * to vendor namespace.
+ */
iterator->this_arg_index =
IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
- iterator->this_arg_size += vnslen;
- if ((unsigned long)iterator->this_arg +
- iterator->this_arg_size -
- (unsigned long)iterator->_rtheader >
- (unsigned long)(unsigned long)iterator->_max_length)
- return -EINVAL;
- hit = 1;
- break;
+ if (!iterator->current_namespace)
+ hit = 1;
+ goto next_entry;
case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
- iterator->_bitmap_shifter >>= 1;
- iterator->_arg_index++;
-
iterator->_reset_on_ext = 1;
iterator->current_namespace = &radiotap_ns;
iterator->is_radiotap_ns = 1;
- break;
+ goto next_entry;
case IEEE80211_RADIOTAP_EXT:
/*
* bit 31 was set, there is more
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 74a9e3cce452..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
+ return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
+}
+
+
static ssize_t addresses_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
__ATTR_RO(macaddress),
__ATTR_RO(address_mask),
__ATTR_RO(addresses),
+ __ATTR_RO(name),
{}
};
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6002265289c6..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
}
wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+ if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
+ wstats.discard.misc = sinfo.rx_dropped_misc;
+ if (sinfo.filled & STATION_INFO_TX_FAILED)
+ wstats.discard.retries = sinfo.tx_failed;
return &wstats;
}