aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/Makefile1
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c89
-rw-r--r--net/mac80211/rx.c22
-rw-r--r--net/mac80211/spectmgmt.c86
5 files changed, 114 insertions, 89 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 1a7ac50910c3..2dc8f2bff27b 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -17,6 +17,7 @@ mac80211-y := \
17 aes_ccm.o \ 17 aes_ccm.o \
18 cfg.o \ 18 cfg.o \
19 rx.o \ 19 rx.o \
20 spectmgmt.o \
20 tx.o \ 21 tx.o \
21 key.o \ 22 key.o \
22 util.o \ 23 util.o \
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 60ec7ad27643..b2ca9e6122c6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -984,6 +984,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
984 struct ieee80211_mgmt *mgmt, 984 struct ieee80211_mgmt *mgmt,
985 size_t len); 985 size_t len);
986 986
987/* Spectrum management */
988void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
989 struct ieee80211_mgmt *mgmt,
990 size_t len);
991
987/* utility functions/constants */ 992/* utility functions/constants */
988extern void *mac80211_wiphy_privid; /* for wiphy privid */ 993extern void *mac80211_wiphy_privid; /* for wiphy privid */
989extern const unsigned char rfc1042_header[6]; 994extern const unsigned char rfc1042_header[6];
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 25f90f7ccf3e..f1ee9d22cf4b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -445,53 +445,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
445 ieee80211_sta_tx(sdata, skb, 0); 445 ieee80211_sta_tx(sdata, skb, 0);
446} 446}
447 447
448static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
449 struct ieee80211_msrment_ie *request_ie,
450 const u8 *da, const u8 *bssid,
451 u8 dialog_token)
452{
453 struct ieee80211_local *local = sdata->local;
454 struct sk_buff *skb;
455 struct ieee80211_mgmt *msr_report;
456
457 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
458 sizeof(struct ieee80211_msrment_ie));
459
460 if (!skb) {
461 printk(KERN_ERR "%s: failed to allocate buffer for "
462 "measurement report frame\n", sdata->dev->name);
463 return;
464 }
465
466 skb_reserve(skb, local->hw.extra_tx_headroom);
467 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
468 memset(msr_report, 0, 24);
469 memcpy(msr_report->da, da, ETH_ALEN);
470 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
471 memcpy(msr_report->bssid, bssid, ETH_ALEN);
472 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
473 IEEE80211_STYPE_ACTION);
474
475 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
476 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
477 msr_report->u.action.u.measurement.action_code =
478 WLAN_ACTION_SPCT_MSR_RPRT;
479 msr_report->u.action.u.measurement.dialog_token = dialog_token;
480
481 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
482 msr_report->u.action.u.measurement.length =
483 sizeof(struct ieee80211_msrment_ie);
484
485 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
486 sizeof(struct ieee80211_msrment_ie));
487 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
488 msr_report->u.action.u.measurement.msr_elem.mode |=
489 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
490 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
491
492 ieee80211_sta_tx(sdata, skb, 0);
493}
494
495/* MLME */ 448/* MLME */
496static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 449static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
497 struct ieee80211_sta_bss *bss) 450 struct ieee80211_sta_bss *bss)
@@ -1011,24 +964,6 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1011 elems.challenge_len + 2, 1); 964 elems.challenge_len + 2, 1);
1012} 965}
1013 966
1014static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1015 struct ieee80211_mgmt *mgmt,
1016 size_t len)
1017{
1018 /*
1019 * Ignoring measurement request is spec violation.
1020 * Mandatory measurements must be reported optional
1021 * measurements might be refused or reported incapable
1022 * For now just refuse
1023 * TODO: Answer basic measurement as unmeasured
1024 */
1025 ieee80211_send_refuse_measurement_request(sdata,
1026 &mgmt->u.action.u.measurement.msr_elem,
1027 mgmt->sa, mgmt->bssid,
1028 mgmt->u.action.u.measurement.dialog_token);
1029}
1030
1031
1032static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 967static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1033 struct ieee80211_if_sta *ifsta, 968 struct ieee80211_if_sta *ifsta,
1034 struct ieee80211_mgmt *mgmt, 969 struct ieee80211_mgmt *mgmt,
@@ -1870,32 +1805,16 @@ static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
1870 size_t len, 1805 size_t len,
1871 struct ieee80211_rx_status *rx_status) 1806 struct ieee80211_rx_status *rx_status)
1872{ 1807{
1873 struct ieee80211_local *local = sdata->local; 1808 /* currently we only handle mesh interface action frames here */
1874 1809 if (!ieee80211_vif_is_mesh(&sdata->vif))
1875 /* all categories we currently handle have action_code */
1876 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
1877 return; 1810 return;
1878 1811
1879 switch (mgmt->u.action.category) { 1812 switch (mgmt->u.action.category) {
1880 case WLAN_CATEGORY_SPECTRUM_MGMT:
1881 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
1882 break;
1883 switch (mgmt->u.action.u.measurement.action_code) {
1884 case WLAN_ACTION_SPCT_MSR_REQ:
1885 if (len < (IEEE80211_MIN_ACTION_SIZE +
1886 sizeof(mgmt->u.action.u.measurement)))
1887 break;
1888 ieee80211_sta_process_measurement_req(sdata, mgmt, len);
1889 break;
1890 }
1891 break;
1892 case PLINK_CATEGORY: 1813 case PLINK_CATEGORY:
1893 if (ieee80211_vif_is_mesh(&sdata->vif)) 1814 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
1894 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
1895 break; 1815 break;
1896 case MESH_PATH_SEL_CATEGORY: 1816 case MESH_PATH_SEL_CATEGORY:
1897 if (ieee80211_vif_is_mesh(&sdata->vif)) 1817 mesh_rx_path_sel_frame(sdata, mgmt, len);
1898 mesh_rx_path_sel_frame(sdata, mgmt, len);
1899 break; 1818 break;
1900 } 1819 }
1901} 1820}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 71cce0bcc5be..d00ace78bf8d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1561,12 +1561,26 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1561 ieee80211_process_delba(sdata, rx->sta, mgmt, len); 1561 ieee80211_process_delba(sdata, rx->sta, mgmt, len);
1562 break; 1562 break;
1563 } 1563 }
1564 rx->sta->rx_packets++; 1564 break;
1565 dev_kfree_skb(rx->skb); 1565 case WLAN_CATEGORY_SPECTRUM_MGMT:
1566 return RX_QUEUED; 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;
1567 } 1579 }
1568 1580
1569 return RX_CONTINUE; 1581 rx->sta->rx_packets++;
1582 dev_kfree_skb(rx->skb);
1583 return RX_QUEUED;
1570} 1584}
1571 1585
1572static ieee80211_rx_result debug_noinline 1586static ieee80211_rx_result debug_noinline
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
new file mode 100644
index 000000000000..b7129f4ae0c3
--- /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_sta_tx(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}