aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorAssaf Krauss <assaf.krauss@intel.com>2008-06-16 09:09:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 16:49:14 -0400
commitb662348662f9661f9259c7186c1bdb65620045f1 (patch)
tree3010967b8be537cf0743ed2f0f872140f5f8011a /net/mac80211
parentf2df38596a81b6c24f4586b0b4befeaebf3e02db (diff)
mac80211: 11h - Handling measurement request
This patch handles the 11h measurement request information element. This is minimal requested implementation - refuse measurement. Signed-off-by: Assaf Krauss <assaf.krauss@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mlme.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 32453561fe32..6d9a4facf9dd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1720,6 +1720,71 @@ void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr)
1720 } 1720 }
1721} 1721}
1722 1722
1723static void ieee80211_send_refuse_measurement_request(struct net_device *dev,
1724 struct ieee80211_msrment_ie *request_ie,
1725 const u8 *da, const u8 *bssid,
1726 u8 dialog_token)
1727{
1728 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1729 struct sk_buff *skb;
1730 struct ieee80211_mgmt *msr_report;
1731
1732 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
1733 sizeof(struct ieee80211_msrment_ie));
1734
1735 if (!skb) {
1736 printk(KERN_ERR "%s: failed to allocate buffer for "
1737 "measurement report frame\n", dev->name);
1738 return;
1739 }
1740
1741 skb_reserve(skb, local->hw.extra_tx_headroom);
1742 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
1743 memset(msr_report, 0, 24);
1744 memcpy(msr_report->da, da, ETH_ALEN);
1745 memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN);
1746 memcpy(msr_report->bssid, bssid, ETH_ALEN);
1747 msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1748 IEEE80211_STYPE_ACTION);
1749
1750 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
1751 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
1752 msr_report->u.action.u.measurement.action_code =
1753 WLAN_ACTION_SPCT_MSR_RPRT;
1754 msr_report->u.action.u.measurement.dialog_token = dialog_token;
1755
1756 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
1757 msr_report->u.action.u.measurement.length =
1758 sizeof(struct ieee80211_msrment_ie);
1759
1760 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
1761 sizeof(struct ieee80211_msrment_ie));
1762 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
1763 msr_report->u.action.u.measurement.msr_elem.mode |=
1764 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
1765 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
1766
1767 ieee80211_sta_tx(dev, skb, 0);
1768}
1769
1770static void ieee80211_sta_process_measurement_req(struct net_device *dev,
1771 struct ieee80211_mgmt *mgmt,
1772 size_t len)
1773{
1774 /*
1775 * Ignoring measurement request is spec violation.
1776 * Mandatory measurements must be reported optional
1777 * measurements might be refused or reported incapable
1778 * For now just refuse
1779 * TODO: Answer basic measurement as unmeasured
1780 */
1781 ieee80211_send_refuse_measurement_request(dev,
1782 &mgmt->u.action.u.measurement.msr_elem,
1783 mgmt->sa, mgmt->bssid,
1784 mgmt->u.action.u.measurement.dialog_token);
1785}
1786
1787
1723static void ieee80211_rx_mgmt_auth(struct net_device *dev, 1788static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1724 struct ieee80211_if_sta *ifsta, 1789 struct ieee80211_if_sta *ifsta,
1725 struct ieee80211_mgmt *mgmt, 1790 struct ieee80211_mgmt *mgmt,
@@ -3044,11 +3109,24 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev,
3044 struct ieee80211_rx_status *rx_status) 3109 struct ieee80211_rx_status *rx_status)
3045{ 3110{
3046 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3111 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3112 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3047 3113
3048 if (len < IEEE80211_MIN_ACTION_SIZE) 3114 if (len < IEEE80211_MIN_ACTION_SIZE)
3049 return; 3115 return;
3050 3116
3051 switch (mgmt->u.action.category) { 3117 switch (mgmt->u.action.category) {
3118 case WLAN_CATEGORY_SPECTRUM_MGMT:
3119 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
3120 break;
3121 switch (mgmt->u.action.u.chan_switch.action_code) {
3122 case WLAN_ACTION_SPCT_MSR_REQ:
3123 if (len < (IEEE80211_MIN_ACTION_SIZE +
3124 sizeof(mgmt->u.action.u.measurement)))
3125 break;
3126 ieee80211_sta_process_measurement_req(dev, mgmt, len);
3127 break;
3128 }
3129 break;
3052 case WLAN_CATEGORY_BACK: 3130 case WLAN_CATEGORY_BACK:
3053 switch (mgmt->u.action.u.addba_req.action_code) { 3131 switch (mgmt->u.action.u.addba_req.action_code) {
3054 case WLAN_ACTION_ADDBA_REQ: 3132 case WLAN_ACTION_ADDBA_REQ: