diff options
author | Michael Büsch <mb@bu3sch.de> | 2008-02-15 22:47:47 +0000 |
---|---|---|
committer | Michael Büsch <mb@bu3sch.de> | 2008-02-15 22:47:47 +0000 |
commit | 99aaf500ed5ca39f30cebf79dc0ee9ff1fd8becf (patch) | |
tree | 382f2e40c89aea52fbc7223c66466e1cd4138def /package/mac80211/patches | |
parent | 4e45a1d1acaaf25be8bd435031634ad23a5a205d (diff) | |
download | mtk-20170518-99aaf500ed5ca39f30cebf79dc0ee9ff1fd8becf.zip mtk-20170518-99aaf500ed5ca39f30cebf79dc0ee9ff1fd8becf.tar.gz mtk-20170518-99aaf500ed5ca39f30cebf79dc0ee9ff1fd8becf.tar.bz2 |
Upgrade b43 and mac80211.
This also temporarly disables hostapd support for mac80211, as hostapd needs patches to compile against latest mac80211.
Will do that in a seperate patch.
SVN-Revision: 10466
Diffstat (limited to 'package/mac80211/patches')
20 files changed, 231 insertions, 4638 deletions
diff --git a/package/mac80211/patches/000-mac80211_update.patch b/package/mac80211/patches/000-mac80211_update.patch deleted file mode 100644 index 7a1a1e2..0000000 --- a/package/mac80211/patches/000-mac80211_update.patch +++ /dev/null @@ -1,933 +0,0 @@ -Index: mac80211/include/linux/ieee80211.h -=================================================================== ---- mac80211.orig/include/linux/ieee80211.h 2007-11-11 15:45:23.153490050 +0100 -+++ mac80211/include/linux/ieee80211.h 2007-11-11 15:45:30.417904025 +0100 -@@ -81,18 +81,18 @@ - - - /* miscellaneous IEEE 802.11 constants */ --#define IEEE80211_MAX_FRAG_THRESHOLD 2346 --#define IEEE80211_MAX_RTS_THRESHOLD 2347 -+#define IEEE80211_MAX_FRAG_THRESHOLD 2352 -+#define IEEE80211_MAX_RTS_THRESHOLD 2353 - #define IEEE80211_MAX_AID 2007 - #define IEEE80211_MAX_TIM_LEN 251 --#define IEEE80211_MAX_DATA_LEN 2304 - /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - -- The figure in section 7.1.2 suggests a body size of up to 2312 -- bytes is allowed, which is a bit confusing, I suspect this -- represents the 2304 bytes of real data, plus a possible 8 bytes of -- WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ -+ 802.11e clarifies the figure in section 7.1.2. The frame body is -+ up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */ -+#define IEEE80211_MAX_DATA_LEN 2304 -+/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */ -+#define IEEE80211_MAX_FRAME_LEN 2352 - - #define IEEE80211_MAX_SSID_LEN 32 - -Index: mac80211/include/linux/nl80211.h -=================================================================== ---- mac80211.orig/include/linux/nl80211.h 2007-11-11 15:45:23.161490506 +0100 -+++ mac80211/include/linux/nl80211.h 2007-11-11 15:45:30.421904255 +0100 -@@ -25,7 +25,7 @@ - * either a dump request on a %NL80211_ATTR_WIPHY or a specific get - * on an %NL80211_ATTR_IFINDEX is supported. - * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires -- %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. -+ * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. - * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response - * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, - * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also -Index: mac80211/include/net/mac80211.h -=================================================================== ---- mac80211.orig/include/net/mac80211.h 2007-11-11 15:45:23.169490961 +0100 -+++ mac80211/include/net/mac80211.h 2007-11-11 15:45:30.429904707 +0100 -@@ -706,11 +706,16 @@ - * - * @queues: number of available hardware transmit queues for - * data packets. WMM/QoS requires at least four. -+ * -+ * @rate_control_algorithm: rate control algorithm for this hardware. -+ * If unset (NULL), the default algorithm will be used. Must be -+ * set before calling ieee80211_register_hw(). - */ - struct ieee80211_hw { - struct ieee80211_conf conf; - struct wiphy *wiphy; - struct workqueue_struct *workqueue; -+ const char *rate_control_algorithm; - void *priv; - u32 flags; - unsigned int extra_tx_headroom; -@@ -936,27 +941,11 @@ - * and remove_interface calls, i.e. while the interface with the - * given local_address is enabled. - * -- * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card -- * to pass unencrypted EAPOL-Key frames even when encryption is -- * configured. If the wlan card does not require such a configuration, -- * this function pointer can be set to NULL. -- * -- * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be -- * authorized (@authorized=1) or unauthorized (=0). This function can be -- * used if the wlan hardware or low-level driver implements PAE. -- * mac80211 will filter frames based on authorization state in any case, -- * so this function pointer can be NULL if low-level driver does not -- * require event notification about port state changes. -- * - * @hw_scan: Ask the hardware to service the scan request, no need to start - * the scan state machine in stack. - * - * @get_stats: return low-level statistics - * -- * @set_privacy_invoked: For devices that generate their own beacons and probe -- * response or association responses this updates the state of privacy_invoked -- * returns 0 for success or an error number. -- * - * @get_sequence_counter: For devices that have internal sequence counters this - * callback allows mac80211 to access the current value of a counter. - * This callback seems not well-defined, tell us if you need it. -@@ -1029,14 +1018,9 @@ - int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, - const u8 *local_address, const u8 *address, - struct ieee80211_key_conf *key); -- int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x); -- int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr, -- int authorized); - int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len); - int (*get_stats)(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -- int (*set_privacy_invoked)(struct ieee80211_hw *hw, -- int privacy_invoked); - int (*get_sequence_counter)(struct ieee80211_hw *hw, - u8* addr, u8 keyidx, u8 txrx, - u32* iv32, u16* iv16); -Index: mac80211/net/mac80211/aes_ccm.c -=================================================================== ---- mac80211.orig/net/mac80211/aes_ccm.c 2007-11-11 15:45:23.177491419 +0100 -+++ mac80211/net/mac80211/aes_ccm.c 2007-11-11 15:45:30.433904936 +0100 -@@ -7,10 +7,10 @@ - * published by the Free Software Foundation. - */ - -+#include <linux/kernel.h> - #include <linux/types.h> - #include <linux/crypto.h> - #include <linux/err.h> --#include <asm/scatterlist.h> - - #include <net/mac80211.h> - #include "ieee80211_key.h" -@@ -63,7 +63,7 @@ - s_0 = scratch + AES_BLOCK_LEN; - e = scratch + 2 * AES_BLOCK_LEN; - -- num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; -+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last_len = data_len % AES_BLOCK_LEN; - aes_ccm_prepare(tfm, b_0, aad, b, s_0, b); - -@@ -102,7 +102,7 @@ - s_0 = scratch + AES_BLOCK_LEN; - a = scratch + 2 * AES_BLOCK_LEN; - -- num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; -+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last_len = data_len % AES_BLOCK_LEN; - aes_ccm_prepare(tfm, b_0, aad, b, s_0, a); - -Index: mac80211/net/mac80211/ieee80211.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211.c 2007-11-11 15:45:23.185491871 +0100 -+++ mac80211/net/mac80211/ieee80211.c 2007-11-11 15:45:30.437905164 +0100 -@@ -1061,7 +1061,8 @@ - ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); - ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); - -- result = ieee80211_init_rate_ctrl_alg(local, NULL); -+ result = ieee80211_init_rate_ctrl_alg(local, -+ hw->rate_control_algorithm); - if (result < 0) { - printk(KERN_DEBUG "%s: Failed to initialize rate control " - "algorithm\n", wiphy_name(local->hw.wiphy)); -@@ -1222,8 +1223,17 @@ - - BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); - -+#ifdef CONFIG_MAC80211_RCSIMPLE -+ ret = ieee80211_rate_control_register(&mac80211_rcsimple); -+ if (ret) -+ return ret; -+#endif -+ - ret = ieee80211_wme_register(); - if (ret) { -+#ifdef CONFIG_MAC80211_RCSIMPLE -+ ieee80211_rate_control_unregister(&mac80211_rcsimple); -+#endif - printk(KERN_DEBUG "ieee80211_init: failed to " - "initialize WME (err=%d)\n", ret); - return ret; -@@ -1237,6 +1247,10 @@ - - static void __exit ieee80211_exit(void) - { -+#ifdef CONFIG_MAC80211_RCSIMPLE -+ ieee80211_rate_control_unregister(&mac80211_rcsimple); -+#endif -+ - ieee80211_wme_unregister(); - ieee80211_debugfs_netdev_exit(); - } -Index: mac80211/net/mac80211/ieee80211_i.h -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_i.h 2007-11-11 15:45:23.189492100 +0100 -+++ mac80211/net/mac80211/ieee80211_i.h 2007-11-11 15:45:30.441905395 +0100 -@@ -232,6 +232,7 @@ - #define IEEE80211_STA_AUTO_SSID_SEL BIT(10) - #define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) - #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) -+#define IEEE80211_STA_PRIVACY_INVOKED BIT(13) - struct ieee80211_if_sta { - enum { - IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, -@@ -261,7 +262,6 @@ - unsigned long request; - struct sk_buff_head skb_queue; - -- int key_management_enabled; - unsigned long last_probe; - - #define IEEE80211_AUTH_ALG_OPEN BIT(0) -Index: mac80211/net/mac80211/ieee80211_ioctl.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:45:23.197492559 +0100 -+++ mac80211/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:45:30.441905395 +0100 -@@ -305,9 +305,12 @@ - ((chan->chan == channel) || (chan->freq == freq))) { - local->oper_channel = chan; - local->oper_hw_mode = mode; -- set++; -+ set = 1; -+ break; - } - } -+ if (set) -+ break; - } - - if (set) { -@@ -507,10 +510,11 @@ - - static int ieee80211_ioctl_siwscan(struct net_device *dev, - struct iw_request_info *info, -- struct iw_point *data, char *extra) -+ union iwreq_data *wrqu, char *extra) - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct iw_scan_req *req = NULL; - u8 *ssid = NULL; - size_t ssid_len = 0; - -@@ -535,6 +539,14 @@ - return -EOPNOTSUPP; - } - -+ /* if SSID was specified explicitly then use that */ -+ if (wrqu->data.length == sizeof(struct iw_scan_req) && -+ wrqu->data.flags & IW_SCAN_THIS_ESSID) { -+ req = (struct iw_scan_req *)extra; -+ ssid = req->essid; -+ ssid_len = req->essid_len; -+ } -+ - return ieee80211_sta_req_scan(dev, ssid, ssid_len); - } - -@@ -621,22 +633,35 @@ - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - bool need_reconfig = 0; -+ u8 new_power_level; - - if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) - return -EINVAL; - if (data->txpower.flags & IW_TXPOW_RANGE) - return -EINVAL; -- if (!data->txpower.fixed) -- return -EINVAL; - -- if (local->hw.conf.power_level != data->txpower.value) { -- local->hw.conf.power_level = data->txpower.value; -+ if (data->txpower.fixed) { -+ new_power_level = data->txpower.value; -+ } else { -+ /* Automatic power level. Get the px power from the current -+ * channel. */ -+ struct ieee80211_channel* chan = local->oper_channel; -+ if (!chan) -+ return -EINVAL; -+ -+ new_power_level = chan->power_level; -+ } -+ -+ if (local->hw.conf.power_level != new_power_level) { -+ local->hw.conf.power_level = new_power_level; - need_reconfig = 1; - } -+ - if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { - local->hw.conf.radio_enabled = !(data->txpower.disabled); - need_reconfig = 1; - } -+ - if (need_reconfig) { - ieee80211_hw_config(local); - /* The return value of hw_config is not of big interest here, -@@ -904,7 +929,6 @@ - struct iw_request_info *info, - struct iw_param *data, char *extra) - { -- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - int ret = 0; - -@@ -914,18 +938,21 @@ - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_WPA_ENABLED: - case IW_AUTH_RX_UNENCRYPTED_EAPOL: -- break; - case IW_AUTH_KEY_MGMT: -+ break; -+ case IW_AUTH_PRIVACY_INVOKED: - if (sdata->type != IEEE80211_IF_TYPE_STA) - ret = -EINVAL; - else { -+ sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; - /* -- * Key management was set by wpa_supplicant, -- * we only need this to associate to a network -- * that has privacy enabled regardless of not -- * having a key. -+ * Privacy invoked by wpa_supplicant, store the -+ * value and allow associating to a protected -+ * network without having a key up front. - */ -- sdata->u.sta.key_management_enabled = !!data->value; -+ if (data->value) -+ sdata->u.sta.flags |= -+ IEEE80211_STA_PRIVACY_INVOKED; - } - break; - case IW_AUTH_80211_AUTH_ALG: -@@ -935,11 +962,6 @@ - else - ret = -EOPNOTSUPP; - break; -- case IW_AUTH_PRIVACY_INVOKED: -- if (local->ops->set_privacy_invoked) -- ret = local->ops->set_privacy_invoked( -- local_to_hw(local), data->value); -- break; - default: - ret = -EOPNOTSUPP; - break; -Index: mac80211/net/mac80211/ieee80211_rate.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_rate.c 2007-11-11 15:45:23.205493011 +0100 -+++ mac80211/net/mac80211/ieee80211_rate.c 2007-11-11 15:45:30.441905395 +0100 -@@ -25,13 +25,25 @@ - { - struct rate_control_alg *alg; - -+ if (!ops->name) -+ return -EINVAL; -+ -+ mutex_lock(&rate_ctrl_mutex); -+ list_for_each_entry(alg, &rate_ctrl_algs, list) { -+ if (!strcmp(alg->ops->name, ops->name)) { -+ /* don't register an algorithm twice */ -+ WARN_ON(1); -+ return -EALREADY; -+ } -+ } -+ - alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) { -+ mutex_unlock(&rate_ctrl_mutex); - return -ENOMEM; - } - alg->ops = ops; - -- mutex_lock(&rate_ctrl_mutex); - list_add_tail(&alg->list, &rate_ctrl_algs); - mutex_unlock(&rate_ctrl_mutex); - -@@ -61,9 +73,12 @@ - struct rate_control_alg *alg; - struct rate_control_ops *ops = NULL; - -+ if (!name) -+ return NULL; -+ - mutex_lock(&rate_ctrl_mutex); - list_for_each_entry(alg, &rate_ctrl_algs, list) { -- if (!name || !strcmp(alg->ops->name, name)) -+ if (!strcmp(alg->ops->name, name)) - if (try_module_get(alg->ops->module)) { - ops = alg->ops; - break; -@@ -80,9 +95,12 @@ - { - struct rate_control_ops *ops; - -+ if (!name) -+ name = "simple"; -+ - ops = ieee80211_try_rate_control_ops_get(name); - if (!ops) { -- request_module("rc80211_%s", name ? name : "default"); -+ request_module("rc80211_%s", name); - ops = ieee80211_try_rate_control_ops_get(name); - } - return ops; -Index: mac80211/net/mac80211/ieee80211_rate.h -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_rate.h 2007-11-11 15:45:23.213493469 +0100 -+++ mac80211/net/mac80211/ieee80211_rate.h 2007-11-11 15:45:30.445905621 +0100 -@@ -65,6 +65,9 @@ - struct kref kref; - }; - -+/* default 'simple' algorithm */ -+extern struct rate_control_ops mac80211_rcsimple; -+ - int ieee80211_rate_control_register(struct rate_control_ops *ops); - void ieee80211_rate_control_unregister(struct rate_control_ops *ops); - -Index: mac80211/net/mac80211/ieee80211_sta.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_sta.c 2007-11-11 15:45:23.217493699 +0100 -+++ mac80211/net/mac80211/ieee80211_sta.c 2007-11-11 15:46:32.885463850 +0100 -@@ -12,7 +12,6 @@ - */ - - /* TODO: -- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs - * order BSS list by RSSI(?) ("quality of AP") - * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, - * SSID) -@@ -61,7 +60,8 @@ - static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, - u8 *ssid, size_t ssid_len); - static struct ieee80211_sta_bss * --ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); -+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, -+ u8 *ssid, u8 ssid_len); - static void ieee80211_rx_bss_put(struct net_device *dev, - struct ieee80211_sta_bss *bss); - static int ieee80211_sta_find_ibss(struct net_device *dev, -@@ -108,14 +108,11 @@ - u8 wmm_param_len; - }; - --enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 }; -- --static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, -- struct ieee802_11_elems *elems) -+static void ieee802_11_parse_elems(u8 *start, size_t len, -+ struct ieee802_11_elems *elems) - { - size_t left = len; - u8 *pos = start; -- int unknown = 0; - - memset(elems, 0, sizeof(*elems)); - -@@ -126,15 +123,8 @@ - elen = *pos++; - left -= 2; - -- if (elen > left) { --#if 0 -- if (net_ratelimit()) -- printk(KERN_DEBUG "IEEE 802.11 element parse " -- "failed (id=%d elen=%d left=%d)\n", -- id, elen, left); --#endif -- return ParseFailed; -- } -+ if (elen > left) -+ return; - - switch (id) { - case WLAN_EID_SSID: -@@ -201,28 +191,15 @@ - elems->ext_supp_rates_len = elen; - break; - default: --#if 0 -- printk(KERN_DEBUG "IEEE 802.11 element parse ignored " -- "unknown element (id=%d elen=%d)\n", -- id, elen); --#endif -- unknown++; - break; - } - - left -= elen; - pos += elen; - } -- -- /* Do not trigger error if left == 1 as Apple Airport base stations -- * send AssocResps that are one spurious byte too long. */ -- -- return unknown ? ParseUnknown : ParseOK; - } - - -- -- - static int ecw2cw(int ecw) - { - int cw = 1; -@@ -426,7 +403,9 @@ - if (sdata->type != IEEE80211_IF_TYPE_STA) - return; - -- bss = ieee80211_rx_bss_get(dev, ifsta->bssid); -+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, -+ local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len); - if (bss) { - if (bss->has_erp_value) - ieee80211_handle_erp_ie(dev, bss->erp_value); -@@ -571,7 +550,8 @@ - capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | - WLAN_CAPABILITY_SHORT_PREAMBLE; - } -- bss = ieee80211_rx_bss_get(dev, ifsta->bssid); -+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len); - if (bss) { - if (bss->capability & WLAN_CAPABILITY_PRIVACY) - capab |= WLAN_CAPABILITY_PRIVACY; -@@ -719,24 +699,30 @@ - static int ieee80211_privacy_mismatch(struct net_device *dev, - struct ieee80211_if_sta *ifsta) - { -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sta_bss *bss; -- int res = 0; -+ int bss_privacy; -+ int wep_privacy; -+ int privacy_invoked; - -- if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) || -- ifsta->key_management_enabled) -+ if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) - return 0; - -- bss = ieee80211_rx_bss_get(dev, ifsta->bssid); -+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len); - if (!bss) - return 0; - -- if (ieee80211_sta_wep_configured(dev) != -- !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) -- res = 1; -+ bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); -+ wep_privacy = !!ieee80211_sta_wep_configured(dev); -+ privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); - - ieee80211_rx_bss_put(dev, bss); - -- return res; -+ if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) -+ return 0; -+ -+ return 1; - } - - -@@ -920,12 +906,7 @@ - - printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); - pos = mgmt->u.auth.variable; -- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) -- == ParseFailed) { -- printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", -- dev->name); -- return; -- } -+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); - if (!elems.challenge) { - printk(KERN_DEBUG "%s: no challenge IE in shared key auth " - "frame\n", dev->name); -@@ -1214,12 +1195,7 @@ - } - - pos = mgmt->u.assoc_resp.variable; -- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) -- == ParseFailed) { -- printk(KERN_DEBUG "%s: failed to parse AssocResp\n", -- dev->name); -- return; -- } -+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); - - if (!elems.supp_rates) { - printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", -@@ -1231,7 +1207,9 @@ - * update our stored copy */ - if (elems.erp_info && elems.erp_info_len >= 1) { - struct ieee80211_sta_bss *bss -- = ieee80211_rx_bss_get(dev, ifsta->bssid); -+ = ieee80211_rx_bss_get(dev, ifsta->bssid, -+ local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len); - if (bss) { - bss->erp_value = elems.erp_info[0]; - bss->has_erp_value = 1; -@@ -1261,7 +1239,9 @@ - " AP\n", dev->name); - return; - } -- bss = ieee80211_rx_bss_get(dev, ifsta->bssid); -+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, -+ local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len); - if (bss) { - sta->last_rssi = bss->rssi; - sta->last_signal = bss->signal; -@@ -1337,7 +1317,8 @@ - - - static struct ieee80211_sta_bss * --ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) -+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, -+ u8 *ssid, u8 ssid_len) - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sta_bss *bss; -@@ -1348,6 +1329,11 @@ - atomic_inc(&bss->users); - atomic_inc(&bss->users); - memcpy(bss->bssid, bssid, ETH_ALEN); -+ bss->channel = channel; -+ if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { -+ memcpy(bss->ssid, ssid, ssid_len); -+ bss->ssid_len = ssid_len; -+ } - - spin_lock_bh(&local->sta_bss_lock); - /* TODO: order by RSSI? */ -@@ -1359,7 +1345,8 @@ - - - static struct ieee80211_sta_bss * --ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) -+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, -+ u8 *ssid, u8 ssid_len) - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sta_bss *bss; -@@ -1367,7 +1354,10 @@ - spin_lock_bh(&local->sta_bss_lock); - bss = local->sta_bss_hash[STA_HASH(bssid)]; - while (bss) { -- if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { -+ if (!memcmp(bss->bssid, bssid, ETH_ALEN) && -+ bss->channel == channel && -+ bss->ssid_len == ssid_len && -+ (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { - atomic_inc(&bss->users); - break; - } -@@ -1429,7 +1419,7 @@ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee802_11_elems elems; - size_t baselen; -- int channel, invalid = 0, clen; -+ int channel, clen; - struct ieee80211_sta_bss *bss; - struct sta_info *sta; - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -@@ -1473,9 +1463,7 @@ - #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - } - -- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, -- &elems) == ParseFailed) -- invalid = 1; -+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); - - if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && - memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && -@@ -1533,9 +1521,11 @@ - else - channel = rx_status->channel; - -- bss = ieee80211_rx_bss_get(dev, mgmt->bssid); -+ bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, -+ elems.ssid, elems.ssid_len); - if (!bss) { -- bss = ieee80211_rx_bss_add(dev, mgmt->bssid); -+ bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, -+ elems.ssid, elems.ssid_len); - if (!bss) - return; - } else { -@@ -1561,10 +1551,6 @@ - - bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); - bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); -- if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { -- memcpy(bss->ssid, elems.ssid, elems.ssid_len); -- bss->ssid_len = elems.ssid_len; -- } - - bss->supp_rates_len = 0; - if (elems.supp_rates) { -@@ -1635,7 +1621,6 @@ - - - bss->hw_mode = rx_status->phymode; -- bss->channel = channel; - bss->freq = rx_status->freq; - if (channel != rx_status->channel && - (bss->hw_mode == MODE_IEEE80211G || -@@ -1695,9 +1680,7 @@ - if (baselen > len) - return; - -- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, -- &elems) == ParseFailed) -- return; -+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); - - if (elems.erp_info && elems.erp_info_len >= 1) - ieee80211_handle_erp_ie(dev, elems.erp_info[0]); -@@ -2098,7 +2081,8 @@ - { - int tmp, hidden_ssid; - -- if (!memcmp(ifsta->ssid, ssid, ssid_len)) -+ if (ssid_len == ifsta->ssid_len && -+ !memcmp(ifsta->ssid, ssid, ssid_len)) - return 1; - - if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) -@@ -2357,7 +2341,7 @@ - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sta_bss *bss; -- struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_hw_mode *mode; - u8 bssid[ETH_ALEN], *pos; - int i; -@@ -2379,18 +2363,17 @@ - printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n", - dev->name, MAC_ARG(bssid)); - -- bss = ieee80211_rx_bss_add(dev, bssid); -+ bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, -+ sdata->u.sta.ssid, sdata->u.sta.ssid_len); - if (!bss) - return -ENOMEM; - -- sdata = IEEE80211_DEV_TO_SUB_IF(dev); - mode = local->oper_hw_mode; - - if (local->hw.conf.beacon_int == 0) - local->hw.conf.beacon_int = 100; - bss->beacon_int = local->hw.conf.beacon_int; - bss->hw_mode = local->hw.conf.phymode; -- bss->channel = local->hw.conf.channel; - bss->freq = local->hw.conf.freq; - bss->last_update = jiffies; - bss->capability = WLAN_CAPABILITY_IBSS; -@@ -2448,7 +2431,8 @@ - MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid)); - #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && -- (bss = ieee80211_rx_bss_get(dev, bssid))) { -+ (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, -+ ifsta->ssid, ifsta->ssid_len))) { - printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT - " based on configured SSID\n", - dev->name, MAC_ARG(bssid)); -Index: mac80211/net/mac80211/Kconfig -=================================================================== ---- mac80211.orig/net/mac80211/Kconfig 2007-11-11 15:45:23.225494151 +0100 -+++ mac80211/net/mac80211/Kconfig 2007-11-11 15:45:30.449905846 +0100 -@@ -13,6 +13,18 @@ - This option enables the hardware independent IEEE 802.11 - networking stack. - -+config MAC80211_RCSIMPLE -+ bool "'simple' rate control algorithm" if EMBEDDED -+ default y -+ depends on MAC80211 -+ help -+ This option allows you to turn off the 'simple' rate -+ control algorithm in mac80211. If you do turn it off, -+ you absolutely need another rate control algorithm. -+ -+ Say Y unless you know you will have another algorithm -+ available. -+ - config MAC80211_LEDS - bool "Enable LED triggers" - depends on MAC80211 && LEDS_TRIGGERS -Index: mac80211/net/mac80211/Makefile -=================================================================== ---- mac80211.orig/net/mac80211/Makefile 2007-11-11 15:45:23.233494609 +0100 -+++ mac80211/net/mac80211/Makefile 2007-11-11 15:45:30.449905846 +0100 -@@ -1,8 +1,9 @@ --obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o -+obj-$(CONFIG_MAC80211) += mac80211.o - - mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o - mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o - mac80211-objs-$(CONFIG_NET_SCHED) += wme.o -+mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o - - mac80211-objs := \ - ieee80211.o \ -Index: mac80211/net/mac80211/rc80211_simple.c -=================================================================== ---- mac80211.orig/net/mac80211/rc80211_simple.c 2007-11-11 15:45:23.237494839 +0100 -+++ mac80211/net/mac80211/rc80211_simple.c 2007-11-11 15:45:30.449905846 +0100 -@@ -7,7 +7,6 @@ - * published by the Free Software Foundation. - */ - --#include <linux/module.h> - #include <linux/init.h> - #include <linux/netdevice.h> - #include <linux/types.h> -@@ -29,8 +28,6 @@ - #define RATE_CONTROL_INTERVAL (HZ / 20) - #define RATE_CONTROL_MIN_TX 10 - --MODULE_ALIAS("rc80211_default"); -- - static void rate_control_rate_inc(struct ieee80211_local *local, - struct sta_info *sta) - { -@@ -393,8 +390,7 @@ - } - #endif - --static struct rate_control_ops rate_control_simple = { -- .module = THIS_MODULE, -+struct rate_control_ops mac80211_rcsimple = { - .name = "simple", - .tx_status = rate_control_simple_tx_status, - .get_rate = rate_control_simple_get_rate, -@@ -409,22 +405,3 @@ - .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs, - #endif - }; -- -- --static int __init rate_control_simple_init(void) --{ -- return ieee80211_rate_control_register(&rate_control_simple); --} -- -- --static void __exit rate_control_simple_exit(void) --{ -- ieee80211_rate_control_unregister(&rate_control_simple); --} -- -- --subsys_initcall(rate_control_simple_init); --module_exit(rate_control_simple_exit); -- --MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); --MODULE_LICENSE("GPL"); -Index: mac80211/net/mac80211/rx.c -=================================================================== ---- mac80211.orig/net/mac80211/rx.c 2007-11-11 15:45:23.245495291 +0100 -+++ mac80211/net/mac80211/rx.c 2007-11-11 15:45:30.449905846 +0100 -@@ -509,9 +509,11 @@ - rx->key->tx_rx_count++; - /* TODO: add threshold stuff again */ - } else { -+#ifdef CONFIG_MAC80211_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: RX protected frame," - " but have no key\n", rx->dev->name); -+#endif /* CONFIG_MAC80211_DEBUG */ - return TXRX_DROP; - } - -Index: mac80211/net/mac80211/wep.c -=================================================================== ---- mac80211.orig/net/mac80211/wep.c 2007-11-11 15:45:23.253495749 +0100 -+++ mac80211/net/mac80211/wep.c 2007-11-11 15:45:30.449905846 +0100 -@@ -16,7 +16,7 @@ - #include <linux/crypto.h> - #include <linux/err.h> - #include <linux/mm.h> --#include <asm/scatterlist.h> -+#include <linux/scatterlist.h> - - #include <net/mac80211.h> - #include "ieee80211_i.h" -@@ -138,9 +138,7 @@ - *icv = cpu_to_le32(~crc32_le(~0, data, data_len)); - - crypto_blkcipher_setkey(tfm, rc4key, klen); -- sg.page = virt_to_page(data); -- sg.offset = offset_in_page(data); -- sg.length = data_len + WEP_ICV_LEN; -+ sg_init_one(&sg, data, data_len + WEP_ICV_LEN); - crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); - } - -@@ -204,9 +202,7 @@ - __le32 crc; - - crypto_blkcipher_setkey(tfm, rc4key, klen); -- sg.page = virt_to_page(data); -- sg.offset = offset_in_page(data); -- sg.length = data_len + WEP_ICV_LEN; -+ sg_init_one(&sg, data, data_len + WEP_ICV_LEN); - crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); - - crc = cpu_to_le32(~crc32_le(~0, data, data_len)); -@@ -318,9 +314,11 @@ - - if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { - if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { -+#ifdef CONFIG_MAC80211_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: RX WEP frame, decrypt " - "failed\n", rx->dev->name); -+#endif /* CONFIG_MAC80211_DEBUG */ - return TXRX_DROP; - } - } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { -Index: mac80211/net/wireless/Kconfig -=================================================================== ---- mac80211.orig/net/wireless/Kconfig 2007-11-11 15:45:23.261496205 +0100 -+++ mac80211/net/wireless/Kconfig 2007-11-11 15:45:30.453906075 +0100 -@@ -3,7 +3,7 @@ - - config NL80211 - bool "nl80211 new netlink interface support" -- depends CFG80211 -+ depends on CFG80211 - default y - ---help--- - This option turns on the new netlink interface diff --git a/package/mac80211/patches/001-port-to-2.6.23.patch b/package/mac80211/patches/001-port-to-2.6.23.patch new file mode 100644 index 0000000..2e88d40 --- /dev/null +++ b/package/mac80211/patches/001-port-to-2.6.23.patch @@ -0,0 +1,231 @@ +Index: mac80211/net/mac80211/ieee80211.c +=================================================================== +--- mac80211.orig/net/mac80211/ieee80211.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/ieee80211.c 2008-02-15 22:21:01.000000000 +0100 +@@ -21,7 +21,6 @@ + #include <linux/wireless.h> + #include <linux/rtnetlink.h> + #include <linux/bitmap.h> +-#include <net/net_namespace.h> + #include <net/cfg80211.h> + + #include "ieee80211_i.h" +@@ -36,6 +35,15 @@ + + #define SUPP_MCS_SET_LEN 16 + ++ ++char *print_mac(char *buf, const u8 *addr) ++{ ++ sprintf(buf, MAC_FMT, ++ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); ++ return buf; ++} ++ ++ + /* + * For seeing transmitted packets on monitor interfaces + * we have a radiotap header too. +@@ -48,11 +56,13 @@ struct ieee80211_tx_status_rtap_hdr { + + /* common interface routines */ + ++#if 0 + static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) + { + memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ + return ETH_ALEN; + } ++#endif + + /* must be called under mdev tx lock */ + static void ieee80211_configure_filter(struct ieee80211_local *local) +@@ -800,6 +810,7 @@ static void ieee80211_set_multicast_list + dev_mc_sync(local->mdev, dev); + } + ++#if 0 + static const struct header_ops ieee80211_header_ops = { + .create = eth_header, + .parse = header_parse_80211, +@@ -807,6 +818,7 @@ static const struct header_ops ieee80211 + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, + }; ++#endif + + /* Must not be called for mdev */ + void ieee80211_if_setup(struct net_device *dev) +@@ -1455,7 +1467,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( + mdev->open = ieee80211_master_open; + mdev->stop = ieee80211_master_stop; + mdev->type = ARPHRD_IEEE80211; +- mdev->header_ops = &ieee80211_header_ops; ++// mdev->header_ops = &ieee80211_header_ops; + mdev->set_multicast_list = ieee80211_master_set_multicast_list; + + sdata->vif.type = IEEE80211_IF_TYPE_AP; +Index: mac80211/net/mac80211/ieee80211_i.h +=================================================================== +--- mac80211.orig/net/mac80211/ieee80211_i.h 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/ieee80211_i.h 2008-02-15 22:21:37.000000000 +0100 +@@ -26,6 +26,16 @@ + #include "ieee80211_key.h" + #include "sta_info.h" + ++ ++#define BIT(nr) (1 << (nr)) ++ ++#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" ++extern char *print_mac(char *buf, const u8 *addr); ++#define DECLARE_MAC_BUF(var) char var[18] __maybe_unused ++ ++#define CONFIG_MAC80211_RC_DEFAULT __stringify(__CONFIG_MAC80211_RC_DEFAULT) ++ ++ + /* ieee80211.o internal definitions, etc. These are not included into + * low-level drivers. */ + +Index: mac80211/net/mac80211/ieee80211_ioctl.c +=================================================================== +--- mac80211.orig/net/mac80211/ieee80211_ioctl.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/ieee80211_ioctl.c 2008-02-15 22:21:01.000000000 +0100 +@@ -207,7 +207,7 @@ static int ieee80211_ioctl_giwrange(stru + IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); + IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); + +- range->scan_capa |= IW_SCAN_CAPA_ESSID; ++// range->scan_capa |= IW_SCAN_CAPA_ESSID; + + return 0; + } +Index: mac80211/net/wireless/core.c +=================================================================== +--- mac80211.orig/net/wireless/core.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/wireless/core.c 2008-02-15 22:21:01.000000000 +0100 +@@ -69,7 +69,7 @@ __cfg80211_drv_from_info(struct genl_inf + + if (info->attrs[NL80211_ATTR_IFINDEX]) { + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); +- dev = dev_get_by_index(&init_net, ifindex); ++ dev = dev_get_by_index(ifindex); + if (dev) { + if (dev->ieee80211_ptr) + byifidx = +@@ -120,7 +120,7 @@ cfg80211_get_dev_from_ifindex(int ifinde + struct net_device *dev; + + mutex_lock(&cfg80211_drv_mutex); +- dev = dev_get_by_index(&init_net, ifindex); ++ dev = dev_get_by_index(ifindex); + if (!dev) + goto out; + if (dev->ieee80211_ptr) { +Index: mac80211/net/wireless/nl80211.c +=================================================================== +--- mac80211.orig/net/wireless/nl80211.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/wireless/nl80211.c 2008-02-15 22:21:01.000000000 +0100 +@@ -39,7 +39,7 @@ static int get_drv_dev_by_info_ifindex(s + return -EINVAL; + + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); +- *dev = dev_get_by_index(&init_net, ifindex); ++ *dev = dev_get_by_index(ifindex); + if (!*dev) + return -ENODEV; + +@@ -959,7 +959,7 @@ static int get_vlan(struct nlattr *vlana + *vlan = NULL; + + if (vlanattr) { +- *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr)); ++ *vlan = dev_get_by_index(nla_get_u32(vlanattr)); + if (!*vlan) + return -ENODEV; + if (!(*vlan)->ieee80211_ptr) +Index: mac80211/net/mac80211/cfg.c +=================================================================== +--- mac80211.orig/net/mac80211/cfg.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/cfg.c 2008-02-15 22:21:01.000000000 +0100 +@@ -9,7 +9,6 @@ + #include <linux/ieee80211.h> + #include <linux/nl80211.h> + #include <linux/rtnetlink.h> +-#include <net/net_namespace.h> + #include <linux/rcupdate.h> + #include <net/cfg80211.h> + #include "ieee80211_i.h" +@@ -68,7 +67,7 @@ static int ieee80211_del_iface(struct wi + return -ENODEV; + + /* we're under RTNL */ +- dev = __dev_get_by_index(&init_net, ifindex); ++ dev = __dev_get_by_index(ifindex); + if (!dev) + return 0; + +@@ -89,7 +88,7 @@ static int ieee80211_change_iface(struct + return -ENODEV; + + /* we're under RTNL */ +- dev = __dev_get_by_index(&init_net, ifindex); ++ dev = __dev_get_by_index(ifindex); + if (!dev) + return -ENODEV; + +Index: mac80211/net/mac80211/tx.c +=================================================================== +--- mac80211.orig/net/mac80211/tx.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/tx.c 2008-02-15 22:21:01.000000000 +0100 +@@ -18,7 +18,6 @@ + #include <linux/etherdevice.h> + #include <linux/bitmap.h> + #include <linux/rcupdate.h> +-#include <net/net_namespace.h> + #include <net/ieee80211_radiotap.h> + #include <net/cfg80211.h> + #include <net/mac80211.h> +@@ -1051,7 +1050,7 @@ static int ieee80211_tx_prepare(struct i + struct net_device *dev; + + pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; +- dev = dev_get_by_index(&init_net, pkt_data->ifindex); ++ dev = dev_get_by_index(pkt_data->ifindex); + if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { + dev_put(dev); + dev = NULL; +@@ -1265,7 +1264,7 @@ int ieee80211_master_start_xmit(struct s + memset(&control, 0, sizeof(struct ieee80211_tx_control)); + + if (pkt_data->ifindex) +- odev = dev_get_by_index(&init_net, pkt_data->ifindex); ++ odev = dev_get_by_index(pkt_data->ifindex); + if (unlikely(odev && !is_ieee80211_device(odev, dev))) { + dev_put(odev); + odev = NULL; +Index: mac80211/net/mac80211/util.c +=================================================================== +--- mac80211.orig/net/mac80211/util.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/mac80211/util.c 2008-02-15 22:21:01.000000000 +0100 +@@ -20,7 +20,6 @@ + #include <linux/if_arp.h> + #include <linux/wireless.h> + #include <linux/bitmap.h> +-#include <net/net_namespace.h> + #include <net/cfg80211.h> + #include <net/rtnetlink.h> + +Index: mac80211/net/wireless/sysfs.c +=================================================================== +--- mac80211.orig/net/wireless/sysfs.c 2008-02-15 22:20:53.000000000 +0100 ++++ mac80211/net/wireless/sysfs.c 2008-02-15 22:21:01.000000000 +0100 +@@ -53,7 +53,8 @@ static void wiphy_dev_release(struct dev + } + + #ifdef CONFIG_HOTPLUG +-static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env) ++static int wiphy_uevent(struct device *dev, char **envp, int num_envp, ++ char *buffer, int buffer_size) + { + /* TODO, we probably need stuff here */ + return 0; diff --git a/package/mac80211/patches/008-add-hostapd-ioctl-header.patch b/package/mac80211/patches/008-add-hostapd-ioctl-header.patch deleted file mode 100644 index acea0ce..0000000 --- a/package/mac80211/patches/008-add-hostapd-ioctl-header.patch +++ /dev/null @@ -1,110 +0,0 @@ ---- - net/mac80211/hostapd_ioctl.h | 103 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 103 insertions(+) - ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ everything/net/mac80211/hostapd_ioctl.h 2007-11-07 13:19:23.031516330 +0100 -@@ -0,0 +1,103 @@ -+/* -+ * Host AP (software wireless LAN access point) user space daemon for -+ * Host AP kernel driver -+ * Copyright 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> -+ * Copyright 2002-2004, Instant802 Networks, Inc. -+ * Copyright 2005, Devicescape Software, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef HOSTAPD_IOCTL_H -+#define HOSTAPD_IOCTL_H -+ -+#ifdef __KERNEL__ -+#include <linux/types.h> -+#endif /* __KERNEL__ */ -+ -+#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) -+#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1) -+#define PRISM2_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 3) -+ -+/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: -+ * This table is no longer added to, the whole sub-ioctl -+ * mess shall be deleted completely. */ -+enum { -+ PRISM2_PARAM_AP_BRIDGE_PACKETS = 10, -+ PRISM2_PARAM_IEEE_802_1X = 23, -+ -+ /* Instant802 additions */ -+ PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES = 1001, -+ PRISM2_PARAM_PREAMBLE = 1003, -+ PRISM2_PARAM_SHORT_SLOT_TIME = 1006, -+ PRISM2_PARAM_NEXT_MODE = 1008, -+ PRISM2_PARAM_PRIVACY_INVOKED = 1014, -+ PRISM2_PARAM_EAPOL = 1023, -+ PRISM2_PARAM_MGMT_IF = 1046, -+}; -+ -+/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: -+ * This table is no longer added to, the hostapd ioctl -+ * shall be deleted completely. */ -+enum { -+ PRISM2_HOSTAPD_FLUSH = 1, -+ -+ /* Instant802 additions */ -+ PRISM2_HOSTAPD_GET_HW_FEATURES = 1002, -+ PRISM2_HOSTAPD_SET_RATE_SETS = 1005, -+ PRISM2_HOSTAPD_SET_CHANNEL_FLAG = 1012, -+ PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN = 1013, -+ PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS = 1014, -+}; -+ -+#define PRISM2_HOSTAPD_MAX_BUF_SIZE 2048 -+#define ALIGNED __attribute__ ((aligned)) -+ -+struct prism2_hostapd_param { -+ u32 cmd; -+ u8 sta_addr[ETH_ALEN]; -+ u8 pad[2]; -+ union { -+ struct { -+ u16 num_modes; -+ u16 flags; -+ u8 data[0] ALIGNED; /* num_modes * feature data */ -+ } hw_features; -+ struct { -+ u16 mode; /* MODE_* */ -+ u16 num_supported_rates; -+ u16 num_basic_rates; -+ u8 data[0] ALIGNED; /* num_supported_rates * u16 + -+ * num_basic_rates * u16 */ -+ } set_rate_sets; -+ struct { -+ u16 mode; /* MODE_* */ -+ u16 chan; -+ u32 flag; -+ u8 power_level; /* regulatory limit in dBm */ -+ u8 antenna_max; -+ } set_channel_flag; -+ struct { -+ u32 rd; -+ } set_regulatory_domain; -+ struct { -+ u32 queue; -+ s32 aifs; -+ u32 cw_min; -+ u32 cw_max; -+ u32 burst_time; /* maximum burst time in 0.1 ms, i.e., -+ * 10 = 1 ms */ -+ } tx_queue_params; -+ } u; -+}; -+ -+/* Data structures used for get_hw_features ioctl */ -+struct hostapd_ioctl_hw_modes_hdr { -+ int mode; -+ int num_channels; -+ int num_rates; -+}; -+ -+#endif /* HOSTAPD_IOCTL_H */ diff --git a/package/mac80211/patches/009-add-old-ioctl-skeleton.patch b/package/mac80211/patches/009-add-old-ioctl-skeleton.patch deleted file mode 100644 index fb9f25f..0000000 --- a/package/mac80211/patches/009-add-old-ioctl-skeleton.patch +++ /dev/null @@ -1,187 +0,0 @@ ---- - net/mac80211/ieee80211.c | 5 + - net/mac80211/ieee80211_ioctl.c | 121 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 126 insertions(+) - ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:06:34.902124618 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:24.311521482 +0100 -@@ -21,6 +21,7 @@ - - #include <net/mac80211.h> - #include "ieee80211_i.h" -+#include "hostapd_ioctl.h" - #include "ieee80211_rate.h" - #include "wpa.h" - #include "aes_ccm.h" -@@ -124,6 +125,47 @@ static int ieee80211_ioctl_siwgenie(stru - return -EOPNOTSUPP; - } - -+ -+static int ieee80211_ioctl_priv_hostapd(struct net_device *dev, -+ struct iw_point *p) -+{ -+ struct prism2_hostapd_param *param; -+ int ret = 0; -+ -+ if (p->length < sizeof(struct prism2_hostapd_param) || -+ p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) { -+ printk(KERN_DEBUG "%s: hostapd ioctl: ptr=%p len=%d min=%d " -+ "max=%d\n", dev->name, p->pointer, p->length, -+ (int)sizeof(struct prism2_hostapd_param), -+ PRISM2_HOSTAPD_MAX_BUF_SIZE); -+ return -EINVAL; -+ } -+ -+ param = kmalloc(p->length, GFP_KERNEL); -+ if (!param) -+ return -ENOMEM; -+ -+ if (copy_from_user(param, p->pointer, p->length)) { -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ switch (param->cmd) { -+ default: -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ if (copy_to_user(p->pointer, param, p->length)) -+ ret = -EFAULT; -+ -+ out: -+ kfree(param); -+ -+ return ret; -+} -+ -+ - static int ieee80211_ioctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *name, char *extra) -@@ -819,6 +861,49 @@ static int ieee80211_ioctl_giwretry(stru - return 0; - } - -+static int ieee80211_ioctl_prism2_param(struct net_device *dev, -+ struct iw_request_info *info, -+ void *wrqu, char *extra) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ int *i = (int *) extra; -+ int param = *i; -+ int ret = 0; -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+ switch (param) { -+ default: -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ return ret; -+} -+ -+ -+static int ieee80211_ioctl_get_prism2_param(struct net_device *dev, -+ struct iw_request_info *info, -+ void *wrqu, char *extra) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ int *param = (int *) extra; -+ int ret = 0; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+ switch (*param) { -+ default: -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ return ret; -+} -+ - static int ieee80211_ioctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -@@ -1073,6 +1158,32 @@ static int ieee80211_ioctl_siwencodeext( - } - - -+static const struct iw_priv_args ieee80211_ioctl_priv[] = { -+ { PRISM2_IOCTL_PRISM2_PARAM, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" }, -+ { PRISM2_IOCTL_GET_PRISM2_PARAM, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" }, -+}; -+ -+ -+int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -+{ -+ struct iwreq *wrq = (struct iwreq *) rq; -+ -+ switch (cmd) { -+ /* Private ioctls (iwpriv) that have not yet been converted -+ * into new wireless extensions API */ -+ case PRISM2_IOCTL_HOSTAPD: -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ return ieee80211_ioctl_priv_hostapd(dev, &wrq->u.data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+ - /* Structures to export the Wireless Handlers */ - - static const iw_handler ieee80211_handler[] = -@@ -1135,9 +1246,19 @@ static const iw_handler ieee80211_handle - (iw_handler) NULL, /* -- hole -- */ - }; - -+static const iw_handler ieee80211_private_handler[] = -+{ /* SIOCIWFIRSTPRIV + */ -+ (iw_handler) ieee80211_ioctl_prism2_param, /* 0 */ -+ (iw_handler) ieee80211_ioctl_get_prism2_param, /* 1 */ -+}; -+ - const struct iw_handler_def ieee80211_iw_handler_def = - { - .num_standard = ARRAY_SIZE(ieee80211_handler), -+ .num_private = ARRAY_SIZE(ieee80211_private_handler), -+ .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv), - .standard = (iw_handler *) ieee80211_handler, -+ .private = (iw_handler *) ieee80211_private_handler, -+ .private_args = (struct iw_priv_args *) ieee80211_ioctl_priv, - .get_wireless_stats = ieee80211_get_wireless_stats, - }; ---- everything.orig/net/mac80211/ieee80211.c 2007-11-07 13:18:36.001511500 +0100 -+++ everything/net/mac80211/ieee80211.c 2007-11-07 13:19:24.311521482 +0100 -@@ -413,6 +413,9 @@ static const struct header_ops ieee80211 - .cache_update = eth_header_cache_update, - }; - -+/* HACK */ -+extern int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -+ - /* Must not be called for mdev */ - void ieee80211_if_setup(struct net_device *dev) - { -@@ -425,6 +428,8 @@ void ieee80211_if_setup(struct net_devic - dev->open = ieee80211_open; - dev->stop = ieee80211_stop; - dev->destructor = ieee80211_if_free; -+ -+ dev->do_ioctl = ieee80211_ioctl; - } - - /* WDS specialties */ diff --git a/package/mac80211/patches/010-add-mgmt-iface.patch b/package/mac80211/patches/010-add-mgmt-iface.patch deleted file mode 100644 index eae5ff6..0000000 --- a/package/mac80211/patches/010-add-mgmt-iface.patch +++ /dev/null @@ -1,688 +0,0 @@ ---- - include/net/mac80211.h | 1 - net/mac80211/ieee80211.c | 198 ++++++++++++++++++++++++++++++++++++++-- - net/mac80211/ieee80211_common.h | 64 ++++++++++++ - net/mac80211/ieee80211_i.h | 9 + - net/mac80211/ieee80211_iface.c | 66 +++++++++++++ - net/mac80211/ieee80211_ioctl.c | 21 ++++ - net/mac80211/ieee80211_rate.c | 3 - net/mac80211/ieee80211_rate.h | 2 - net/mac80211/ieee80211_sta.c | 2 - net/mac80211/rx.c | 29 ++++- - net/mac80211/tx.c | 14 ++ - net/mac80211/wme.c | 10 +- - 12 files changed, 399 insertions(+), 20 deletions(-) - -Index: mac80211/include/net/mac80211.h -=================================================================== ---- mac80211.orig/include/net/mac80211.h 2007-11-11 15:15:42.824034853 +0100 -+++ mac80211/include/net/mac80211.h 2007-11-11 15:15:53.784659457 +0100 -@@ -472,6 +472,7 @@ - enum ieee80211_if_types { - IEEE80211_IF_TYPE_INVALID, - IEEE80211_IF_TYPE_AP, -+ IEEE80211_IF_TYPE_MGMT, - IEEE80211_IF_TYPE_STA, - IEEE80211_IF_TYPE_IBSS, - IEEE80211_IF_TYPE_MNTR, -Index: mac80211/net/mac80211/ieee80211.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211.c 2007-11-11 15:15:51.536531354 +0100 -+++ mac80211/net/mac80211/ieee80211.c 2007-11-11 15:16:22.214279577 +0100 -@@ -23,6 +23,7 @@ - #include <linux/bitmap.h> - #include <net/cfg80211.h> - -+#include "ieee80211_common.h" - #include "ieee80211_i.h" - #include "ieee80211_rate.h" - #include "wep.h" -@@ -121,6 +122,152 @@ - ieee80211_configure_filter(local); - } - -+/* management interface */ -+ -+static void -+ieee80211_fill_frame_info(struct ieee80211_local *local, -+ struct ieee80211_frame_info *fi, -+ struct ieee80211_rx_status *status) -+{ -+ if (status) { -+ struct timespec ts; -+ struct ieee80211_rate *rate; -+ -+ jiffies_to_timespec(jiffies, &ts); -+ fi->hosttime = cpu_to_be64((u64) ts.tv_sec * 1000000 + -+ ts.tv_nsec / 1000); -+ fi->mactime = cpu_to_be64(status->mactime); -+ switch (status->phymode) { -+ case MODE_IEEE80211A: -+ fi->phytype = htonl(ieee80211_phytype_ofdm_dot11_a); -+ break; -+ case MODE_IEEE80211B: -+ fi->phytype = htonl(ieee80211_phytype_dsss_dot11_b); -+ break; -+ case MODE_IEEE80211G: -+ fi->phytype = htonl(ieee80211_phytype_pbcc_dot11_g); -+ break; -+ default: -+ fi->phytype = htonl(0xAAAAAAAA); -+ break; -+ } -+ fi->channel = htonl(status->channel); -+ rate = ieee80211_get_rate(local, status->phymode, -+ status->rate); -+ if (rate) { -+ fi->datarate = htonl(rate->rate); -+ if (rate->flags & IEEE80211_RATE_PREAMBLE2) { -+ if (status->rate == rate->val) -+ fi->preamble = htonl(2); /* long */ -+ else if (status->rate == rate->val2) -+ fi->preamble = htonl(1); /* short */ -+ } else -+ fi->preamble = htonl(0); -+ } else { -+ fi->datarate = htonl(0); -+ fi->preamble = htonl(0); -+ } -+ -+ fi->antenna = htonl(status->antenna); -+ fi->priority = htonl(0xffffffff); /* no clue */ -+ fi->ssi_type = htonl(ieee80211_ssi_raw); -+ fi->ssi_signal = htonl(status->ssi); -+ fi->ssi_noise = 0x00000000; -+ fi->encoding = 0; -+ } else { -+ /* clear everything because we really don't know. -+ * the msg_type field isn't present on monitor frames -+ * so we don't know whether it will be present or not, -+ * but it's ok to not clear it since it'll be assigned -+ * anyway */ -+ memset(fi, 0, sizeof(*fi) - sizeof(fi->msg_type)); -+ -+ fi->ssi_type = htonl(ieee80211_ssi_none); -+ } -+ fi->version = htonl(IEEE80211_FI_VERSION); -+ fi->length = cpu_to_be32(sizeof(*fi) - sizeof(fi->msg_type)); -+} -+ -+/* this routine is actually not just for this, but also -+ * for pushing fake 'management' frames into userspace. -+ * it shall be replaced by a netlink-based system. */ -+void -+ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb, -+ struct ieee80211_rx_status *status, u32 msg_type) -+{ -+ struct ieee80211_frame_info *fi; -+ const size_t hlen = sizeof(struct ieee80211_frame_info); -+ struct net_device *dev = local->apdev; -+ -+ skb->dev = dev; -+ -+ if (skb_headroom(skb) < hlen) { -+ I802_DEBUG_INC(local->rx_expand_skb_head); -+ if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) { -+ dev_kfree_skb(skb); -+ return; -+ } -+ } -+ -+ fi = (struct ieee80211_frame_info *) skb_push(skb, hlen); -+ -+ ieee80211_fill_frame_info(local, fi, status); -+ fi->msg_type = htonl(msg_type); -+ -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += skb->len; -+ -+ skb_set_mac_header(skb, 0); -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ skb->pkt_type = PACKET_OTHERHOST; -+ skb->protocol = htons(ETH_P_802_2); -+ memset(skb->cb, 0, sizeof(skb->cb)); -+ netif_rx(skb); -+} -+ -+static int ieee80211_mgmt_open(struct net_device *dev) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ -+ if (!netif_running(local->mdev)) -+ return -EOPNOTSUPP; -+ return 0; -+} -+ -+static int ieee80211_mgmt_stop(struct net_device *dev) -+{ -+ return 0; -+} -+ -+static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu) -+{ -+ /* FIX: what would be proper limits for MTU? -+ * This interface uses 802.11 frames. */ -+ if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) { -+ printk(KERN_WARNING "%s: invalid MTU %d\n", -+ dev->name, new_mtu); -+ return -EINVAL; -+ } -+ -+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG -+ printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); -+#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ -+ dev->mtu = new_mtu; -+ return 0; -+} -+ -+void ieee80211_if_mgmt_setup(struct net_device *dev) -+{ -+ ether_setup(dev); -+ dev->hard_start_xmit = ieee80211_mgmt_start_xmit; -+ dev->change_mtu = ieee80211_change_mtu_apdev; -+ dev->open = ieee80211_mgmt_open; -+ dev->stop = ieee80211_mgmt_stop; -+ dev->type = ARPHRD_IEEE80211_PRISM; -+ dev->hard_header_parse = &header_parse_80211; -+ dev->destructor = ieee80211_if_free; -+} -+ - /* regular interfaces */ - - static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) -@@ -198,6 +345,7 @@ - return -ENOLINK; - break; - case IEEE80211_IF_TYPE_AP: -+ case IEEE80211_IF_TYPE_MGMT: - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_MNTR: - case IEEE80211_IF_TYPE_IBSS: -@@ -262,6 +410,10 @@ - if (local->open_count == 0) { - res = dev_open(local->mdev); - WARN_ON(res); -+ if (local->apdev) { -+ res = dev_open(local->apdev); -+ WARN_ON(res); -+ } - tasklet_enable(&local->tx_pending_tasklet); - tasklet_enable(&local->tasklet); - } -@@ -347,6 +499,9 @@ - if (netif_running(local->mdev)) - dev_close(local->mdev); - -+ if (local->apdev) -+ dev_close(local->apdev); -+ - if (local->ops->stop) - local->ops->stop(local_to_hw(local)); - -@@ -646,6 +801,8 @@ - pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; - if (control->flags & IEEE80211_TXCTL_REQUEUE) - pkt_data->flags |= IEEE80211_TXPD_REQUEUE; -+ if (control->type == IEEE80211_IF_TYPE_MGMT) -+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE; - pkt_data->queue = control->queue; - - hdrlen = ieee80211_get_hdrlen_from_skb(skb); -@@ -698,6 +855,7 @@ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_local *local = hw_to_local(hw); - u16 frag, type; -+ u32 msg_type; - struct ieee80211_tx_status_rtap_hdr *rthdr; - struct ieee80211_sub_if_data *sdata; - int monitors; -@@ -812,9 +970,29 @@ - local->dot11FailedCount++; - } - -+ msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ? -+ ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail; -+ - /* this was a transmitted frame, but now we want to reuse it */ - skb_orphan(skb); - -+ if ((status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) && -+ local->apdev) { -+ if (local->monitors) { -+ skb2 = skb_clone(skb, GFP_ATOMIC); -+ } else { -+ skb2 = skb; -+ skb = NULL; -+ } -+ -+ if (skb2) -+ /* Send frame to hostapd */ -+ ieee80211_rx_mgmt(local, skb2, NULL, msg_type); -+ -+ if (!skb) -+ return; -+ } -+ - if (!local->monitors) { - dev_kfree_skb(skb); - return; -@@ -1161,6 +1339,8 @@ - BUG_ON(local->reg_state != IEEE80211_DEV_REGISTERED); - - local->reg_state = IEEE80211_DEV_UNREGISTERED; -+ if (local->apdev) -+ ieee80211_if_del_mgmt(local); - - /* - * At this point, interface list manipulations are fine -Index: mac80211/net/mac80211/ieee80211_i.h -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_i.h 2007-11-11 15:15:42.840035769 +0100 -+++ mac80211/net/mac80211/ieee80211_i.h 2007-11-11 15:15:53.792659922 +0100 -@@ -142,6 +142,7 @@ - * when using CTS protection with IEEE 802.11g. */ - struct ieee80211_rate *last_frag_rate; - int last_frag_hwrate; -+ int mgmt_interface; - - /* Extra fragments (in addition to the first fragment - * in skb) */ -@@ -163,6 +164,7 @@ - #define IEEE80211_TXPD_REQ_TX_STATUS BIT(0) - #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) - #define IEEE80211_TXPD_REQUEUE BIT(2) -+#define IEEE80211_TXPD_MGMT_IFACE BIT(3) - /* Stored in sk_buff->cb */ - struct ieee80211_tx_packet_data { - int ifindex; -@@ -408,6 +410,7 @@ - struct list_head modes_list; - - struct net_device *mdev; /* wmaster# - "master" 802.11 device */ -+ struct net_device *apdev; /* wlan#ap - management frames (hostapd) */ - int open_count; - int monitors; - unsigned int filter_flags; /* FIF_* */ -@@ -701,11 +704,14 @@ - int ieee80211_hw_config(struct ieee80211_local *local); - int ieee80211_if_config(struct net_device *dev); - int ieee80211_if_config_beacon(struct net_device *dev); -+void ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb, -+ struct ieee80211_rx_status *status, u32 msg_type); - void ieee80211_prepare_rates(struct ieee80211_local *local, - struct ieee80211_hw_mode *mode); - void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); - int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); - void ieee80211_if_setup(struct net_device *dev); -+void ieee80211_if_mgmt_setup(struct net_device *dev); - struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local, - int phymode, int hwrate); - -@@ -772,6 +778,8 @@ - int ieee80211_if_remove(struct net_device *dev, const char *name, int id); - void ieee80211_if_free(struct net_device *dev); - void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); -+int ieee80211_if_add_mgmt(struct ieee80211_local *local); -+void ieee80211_if_del_mgmt(struct ieee80211_local *local); - - /* regdomain.c */ - void ieee80211_regdomain_init(void); -@@ -788,6 +796,7 @@ - int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev); - int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); - int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); -+int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); - - /* utility functions/constants */ - extern void *mac80211_wiphy_privid; /* for wiphy privid */ -Index: mac80211/net/mac80211/ieee80211_iface.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_iface.c 2007-11-11 15:15:42.848036222 +0100 -+++ mac80211/net/mac80211/ieee80211_iface.c 2007-11-11 15:15:53.796660158 +0100 -@@ -96,6 +96,66 @@ - return ret; - } - -+int ieee80211_if_add_mgmt(struct ieee80211_local *local) -+{ -+ struct net_device *ndev; -+ struct ieee80211_sub_if_data *nsdata; -+ int ret; -+ -+ ASSERT_RTNL(); -+ -+ ndev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), "wmgmt%d", -+ ieee80211_if_mgmt_setup); -+ if (!ndev) -+ return -ENOMEM; -+ ret = dev_alloc_name(ndev, ndev->name); -+ if (ret < 0) -+ goto fail; -+ -+ memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); -+ SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); -+ -+ nsdata = IEEE80211_DEV_TO_SUB_IF(ndev); -+ ndev->ieee80211_ptr = &nsdata->wdev; -+ nsdata->wdev.wiphy = local->hw.wiphy; -+ nsdata->type = IEEE80211_IF_TYPE_MGMT; -+ nsdata->dev = ndev; -+ nsdata->local = local; -+ ieee80211_if_sdata_init(nsdata); -+ -+ ret = register_netdevice(ndev); -+ if (ret) -+ goto fail; -+ -+ /* -+ * Called even when register_netdevice fails, it would -+ * oops if assigned before initialising the rest. -+ */ -+ ndev->uninit = ieee80211_if_reinit; -+ -+ ieee80211_debugfs_add_netdev(nsdata); -+ -+ if (local->open_count > 0) -+ dev_open(ndev); -+ local->apdev = ndev; -+ return 0; -+ -+fail: -+ free_netdev(ndev); -+ return ret; -+} -+ -+void ieee80211_if_del_mgmt(struct ieee80211_local *local) -+{ -+ struct net_device *apdev; -+ -+ ASSERT_RTNL(); -+ apdev = local->apdev; -+ ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(apdev)); -+ local->apdev = NULL; -+ unregister_netdevice(apdev); -+} -+ - void ieee80211_if_set_type(struct net_device *dev, int type) - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -@@ -183,6 +243,9 @@ - ieee80211_if_sdata_deinit(sdata); - - switch (sdata->type) { -+ case IEEE80211_IF_TYPE_MGMT: -+ /* nothing to do */ -+ break; - case IEEE80211_IF_TYPE_INVALID: - /* cannot happen */ - WARN_ON(1); -@@ -294,8 +357,11 @@ - - void ieee80211_if_free(struct net_device *dev) - { -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - -+ /* local->apdev must be NULL when freeing management interface */ -+ BUG_ON(dev == local->apdev); - ieee80211_if_sdata_deinit(sdata); - free_netdev(dev); - } -Index: mac80211/net/mac80211/ieee80211_rate.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_rate.c 2007-11-11 15:15:42.852036451 +0100 -+++ mac80211/net/mac80211/ieee80211_rate.c 2007-11-11 15:15:53.800660386 +0100 -@@ -145,7 +145,8 @@ - struct rate_control_ref *ref, *old; - - ASSERT_RTNL(); -- if (local->open_count || netif_running(local->mdev)) -+ if (local->open_count || netif_running(local->mdev) || -+ (local->apdev && netif_running(local->apdev))) - return -EBUSY; - - ref = rate_control_alloc(name, local); -Index: mac80211/net/mac80211/ieee80211_rate.h -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_rate.h 2007-11-11 15:15:42.860036908 +0100 -+++ mac80211/net/mac80211/ieee80211_rate.h 2007-11-11 15:15:53.800660386 +0100 -@@ -30,6 +30,8 @@ - - /* parameters from the caller to rate_control_get_rate(): */ - struct ieee80211_hw_mode *mode; -+ int mgmt_data; /* this is data frame that is used for management -+ * (e.g., IEEE 802.1X EAPOL) */ - u16 ethertype; - }; - -Index: mac80211/net/mac80211/ieee80211_sta.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_sta.c 2007-11-11 15:15:42.868037362 +0100 -+++ mac80211/net/mac80211/ieee80211_sta.c 2007-11-11 15:15:53.800660386 +0100 -@@ -475,6 +475,8 @@ - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->ifindex = sdata->dev->ifindex; -+ if (sdata->type == IEEE80211_IF_TYPE_MGMT) -+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE; - if (!encrypt) - pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; - -Index: mac80211/net/mac80211/rx.c -=================================================================== ---- mac80211.orig/net/mac80211/rx.c 2007-11-11 15:15:42.872037591 +0100 -+++ mac80211/net/mac80211/rx.c 2007-11-11 15:15:53.804660611 +0100 -@@ -19,6 +19,7 @@ - - #include "ieee80211_i.h" - #include "ieee80211_led.h" -+#include "ieee80211_common.h" - #include "wep.h" - #include "wpa.h" - #include "tkip.h" -@@ -411,7 +412,12 @@ - return TXRX_DROP; - } - -- return TXRX_DROP; -+ if (!rx->local->apdev) -+ return TXRX_DROP; -+ -+ ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, -+ ieee80211_msg_sta_not_assoc); -+ return TXRX_QUEUED; - } - - return TXRX_CONTINUE; -@@ -953,8 +959,15 @@ - { - if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) && - rx->sdata->type != IEEE80211_IF_TYPE_STA && -- (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) -- return TXRX_CONTINUE; -+ (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) { -+ /* Pass both encrypted and unencrypted EAPOL frames to user -+ * space for processing. */ -+ if (!rx->local->apdev) -+ return TXRX_DROP; -+ ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, -+ ieee80211_msg_normal); -+ return TXRX_QUEUED; -+ } - - if (unlikely(rx->sdata->ieee802_1x && - (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && -@@ -1196,8 +1209,13 @@ - sdata->type == IEEE80211_IF_TYPE_IBSS) && - !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) - ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status); -- else -- return TXRX_DROP; -+ else { -+ /* Management frames are sent to hostapd for processing */ -+ if (!rx->local->apdev) -+ return TXRX_DROP; -+ ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, -+ ieee80211_msg_normal); -+ } - - return TXRX_QUEUED; - } -@@ -1407,6 +1425,7 @@ - /* take everything */ - break; - case IEEE80211_IF_TYPE_INVALID: -+ case IEEE80211_IF_TYPE_MGMT: - /* should never get here */ - WARN_ON(1); - break; -Index: mac80211/net/mac80211/tx.c -=================================================================== ---- mac80211.orig/net/mac80211/tx.c 2007-11-11 15:15:42.880038048 +0100 -+++ mac80211/net/mac80211/tx.c 2007-11-11 15:15:53.804660611 +0100 -@@ -258,7 +258,7 @@ - return TXRX_CONTINUE; - } - -- if (unlikely(/* !injected && */ tx->sdata->ieee802_1x && -+ if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x && - !(sta_flags & WLAN_STA_AUTHORIZED))) { - #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: dropped frame to " MAC_FMT -@@ -568,6 +568,8 @@ - memset(&extra, 0, sizeof(extra)); - extra.mode = tx->u.tx.mode; - extra.ethertype = tx->ethertype; -+ extra.mgmt_data = tx->sdata && -+ tx->sdata->type == IEEE80211_IF_TYPE_MGMT; - - tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev, - tx->skb, &extra); -@@ -1076,7 +1078,7 @@ - } - - static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, -- struct ieee80211_tx_control *control) -+ struct ieee80211_tx_control *control, int mgmt) - { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct sta_info *sta; -@@ -1107,6 +1109,7 @@ - rcu_read_lock(); - - sta = tx.sta; -+ tx.u.tx.mgmt_interface = mgmt; - tx.u.tx.mode = local->hw.conf.mode; - - for (handler = local->tx_handlers; *handler != NULL; -@@ -1253,7 +1256,8 @@ - control.flags |= IEEE80211_TXCTL_REQUEUE; - control.queue = pkt_data->queue; - -- ret = ieee80211_tx(odev, skb, &control); -+ ret = ieee80211_tx(odev, skb, &control, -+ control.type == IEEE80211_IF_TYPE_MGMT); - dev_put(odev); - - return ret; -@@ -1498,6 +1502,8 @@ - pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->ifindex = dev->ifindex; -+ if (sdata->type == IEEE80211_IF_TYPE_MGMT) -+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE; - - skb->dev = local->mdev; - dev->stats.tx_packets++; -@@ -1555,6 +1561,8 @@ - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->ifindex = sdata->dev->ifindex; -+ if (sdata->type == IEEE80211_IF_TYPE_MGMT) -+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE; - - skb->priority = 20; /* use hardcoded priority for mgmt TX queue */ - skb->dev = sdata->local->mdev; -Index: mac80211/net/mac80211/wme.c -=================================================================== ---- mac80211.orig/net/mac80211/wme.c 2007-11-11 15:15:42.888038502 +0100 -+++ mac80211/net/mac80211/wme.c 2007-11-11 15:15:53.804660611 +0100 -@@ -94,6 +94,8 @@ - static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) - { - struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); -+ struct ieee80211_tx_packet_data *pkt_data = -+ (struct ieee80211_tx_packet_data *) skb->cb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - unsigned short fc = le16_to_cpu(hdr->frame_control); - int qos; -@@ -106,8 +108,12 @@ - return IEEE80211_TX_QUEUE_DATA0; - } - -- if (0 /* injected */) { -- /* use AC from radiotap */ -+ if (unlikely(pkt_data->flags & IEEE80211_TXPD_MGMT_IFACE)) { -+ /* Data frames from hostapd (mainly, EAPOL) use AC_VO -+ * and they will include QoS control fields if -+ * the target STA is using WME. */ -+ skb->priority = 7; -+ return ieee802_1d_to_ac[skb->priority]; - } - - /* is this a QoS frame? */ -Index: mac80211/net/mac80211/ieee80211_ioctl.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:15:51.532531127 +0100 -+++ mac80211/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:15:53.808660833 +0100 -@@ -840,16 +840,29 @@ - void *wrqu, char *extra) - { - struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_local *local; - int *i = (int *) extra; - int param = *i; -+ int value = *(i + 1); - int ret = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ local = sdata->local; - - switch (param) { -+ case PRISM2_PARAM_MGMT_IF: -+ if (value == 1) { -+ if (!local->apdev) -+ ret = ieee80211_if_add_mgmt(local); -+ } else if (value == 0) { -+ if (local->apdev) -+ ieee80211_if_del_mgmt(local); -+ } else -+ ret = -EINVAL; -+ break; - default: - ret = -EOPNOTSUPP; - break; -@@ -864,12 +877,20 @@ - void *wrqu, char *extra) - { - struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_local *local; - int *param = (int *) extra; - int ret = 0; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ local = sdata->local; - - switch (*param) { -+ case PRISM2_PARAM_MGMT_IF: -+ if (local->apdev) -+ *param = local->apdev->ifindex; -+ else -+ ret = -ENOENT; -+ break; - default: - ret = -EOPNOTSUPP; - break; diff --git a/package/mac80211/patches/011-allow-ap-vlan-modes.patch b/package/mac80211/patches/011-allow-ap-vlan-modes.patch deleted file mode 100644 index d0edfe8..0000000 --- a/package/mac80211/patches/011-allow-ap-vlan-modes.patch +++ /dev/null @@ -1,37 +0,0 @@ -Subject: mac80211: allow AP and VLAN modes - -This adds AP/VLAN modes to the list of modes that a mac80211 -interface can be created in/switched into. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - net/mac80211/cfg.c | 4 ++++ - net/mac80211/ieee80211_ioctl.c | 3 +++ - 2 files changed, 7 insertions(+) - ---- everything.orig/net/mac80211/cfg.c 2007-10-30 15:33:43.227379286 +0100 -+++ everything/net/mac80211/cfg.c 2007-11-07 13:19:27.981515569 +0100 -@@ -25,6 +25,10 @@ nl80211_type_to_mac80211_type(enum nl802 - return IEEE80211_IF_TYPE_STA; - case NL80211_IFTYPE_MONITOR: - return IEEE80211_IF_TYPE_MNTR; -+ case NL80211_IFTYPE_AP: -+ return IEEE80211_IF_TYPE_AP; -+ case NL80211_IFTYPE_AP_VLAN: -+ return IEEE80211_IF_TYPE_VLAN; - default: - return IEEE80211_IF_TYPE_INVALID; - } ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:25.851524684 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:27.981515569 +0100 -@@ -284,6 +284,9 @@ static int ieee80211_ioctl_siwmode(struc - case IW_MODE_MONITOR: - type = IEEE80211_IF_TYPE_MNTR; - break; -+ case IW_MODE_MASTER: -+ type = IEEE80211_IF_TYPE_AP; -+ break; - default: - return -EINVAL; - } diff --git a/package/mac80211/patches/012-mac80211-allow-wds.patch b/package/mac80211/patches/012-mac80211-allow-wds.patch deleted file mode 100644 index d5c57cd..0000000 --- a/package/mac80211/patches/012-mac80211-allow-wds.patch +++ /dev/null @@ -1,22 +0,0 @@ -Subject: mac80211: allow WDS mode - -This allows creating interfaces in WDS mode or switching -existing ones into WDS mode (both via cfg80211.) - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - net/mac80211/cfg.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- everything.orig/net/mac80211/cfg.c 2007-11-07 13:19:27.981515569 +0100 -+++ everything/net/mac80211/cfg.c 2007-11-07 13:19:29.441515732 +0100 -@@ -29,6 +29,8 @@ nl80211_type_to_mac80211_type(enum nl802 - return IEEE80211_IF_TYPE_AP; - case NL80211_IFTYPE_AP_VLAN: - return IEEE80211_IF_TYPE_VLAN; -+ case NL80211_IFTYPE_WDS: -+ return IEEE80211_IF_TYPE_WDS; - default: - return IEEE80211_IF_TYPE_INVALID; - } diff --git a/package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch b/package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch deleted file mode 100644 index d418ad3..0000000 --- a/package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- - net/mac80211/ieee80211_ioctl.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:27.981515569 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:30.781513182 +0100 -@@ -882,6 +882,9 @@ static int ieee80211_ioctl_prism2_param( - local = sdata->local; - - switch (param) { -+ case PRISM2_PARAM_AP_BRIDGE_PACKETS: -+ local->bridge_packets = value; -+ break; - case PRISM2_PARAM_MGMT_IF: - if (value == 1) { - if (!local->apdev) -@@ -914,6 +917,9 @@ static int ieee80211_ioctl_get_prism2_pa - local = sdata->local; - - switch (*param) { -+ case PRISM2_PARAM_AP_BRIDGE_PACKETS: -+ *param = local->bridge_packets; -+ break; - case PRISM2_PARAM_MGMT_IF: - if (local->apdev) - *param = local->apdev->ifindex; diff --git a/package/mac80211/patches/014-prism2-ioctl-8021x.patch b/package/mac80211/patches/014-prism2-ioctl-8021x.patch deleted file mode 100644 index 5feb01e..0000000 --- a/package/mac80211/patches/014-prism2-ioctl-8021x.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- - net/mac80211/ieee80211_ioctl.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:30.781513182 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:32.281514919 +0100 -@@ -882,6 +882,9 @@ static int ieee80211_ioctl_prism2_param( - local = sdata->local; - - switch (param) { -+ case PRISM2_PARAM_IEEE_802_1X: -+ sdata->ieee802_1x = value; -+ break; - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - local->bridge_packets = value; - break; -@@ -917,6 +920,9 @@ static int ieee80211_ioctl_get_prism2_pa - local = sdata->local; - - switch (*param) { -+ case PRISM2_PARAM_IEEE_802_1X: -+ *param = sdata->ieee802_1x; -+ break; - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - *param = local->bridge_packets; - break; diff --git a/package/mac80211/patches/015-hostapd-ioctl-hw-features.patch b/package/mac80211/patches/015-hostapd-ioctl-hw-features.patch deleted file mode 100644 index d6e5dfd..0000000 --- a/package/mac80211/patches/015-hostapd-ioctl-hw-features.patch +++ /dev/null @@ -1,122 +0,0 @@ ---- - net/mac80211/ieee80211_ioctl.c | 102 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 102 insertions(+) - ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:32.281514919 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:33.681513453 +0100 -@@ -125,6 +125,105 @@ static int ieee80211_ioctl_siwgenie(stru - return -EOPNOTSUPP; - } - -+/* -+ * Wow. This ioctl interface is such crap, it's tied -+ * to internal definitions. I hope it dies soon. -+ */ -+static int mode_to_hostapd_mode(enum ieee80211_phymode mode) -+{ -+ switch (mode) { -+ case MODE_IEEE80211A: -+ return 0; -+ case MODE_IEEE80211B: -+ return 1; -+ case MODE_IEEE80211G: -+ return 3; -+ case NUM_IEEE80211_MODES: -+ WARN_ON(1); -+ break; -+ } -+ WARN_ON(1); -+ return -1; -+} -+ -+static int channel_flags_to_hostapd_flags(int flags) -+{ -+ int res = 0; -+ -+ if (flags & IEEE80211_CHAN_W_SCAN) -+ res |= 1; -+ if (flags & IEEE80211_CHAN_W_ACTIVE_SCAN) -+ res |= 2; -+ if (flags & IEEE80211_CHAN_W_IBSS) -+ res |= 4; -+ -+ return res; -+} -+ -+struct ieee80211_channel_data { -+ short chan; /* channel number (IEEE 802.11) */ -+ short freq; /* frequency in MHz */ -+ int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */ -+}; -+ -+struct ieee80211_rate_data { -+ int rate; /* rate in 100 kbps */ -+ int flags; /* IEEE80211_RATE_ flags */ -+}; -+ -+static int ieee80211_ioctl_get_hw_features(struct net_device *dev, -+ struct prism2_hostapd_param *param, -+ int param_len) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ u8 *pos = param->u.hw_features.data; -+ int left = param_len - (pos - (u8 *) param); -+ int i; -+ struct hostapd_ioctl_hw_modes_hdr *hdr; -+ struct ieee80211_rate_data *rate; -+ struct ieee80211_channel_data *chan; -+ struct ieee80211_hw_mode *mode; -+ -+ param->u.hw_features.flags = 0; -+ -+ param->u.hw_features.num_modes = 0; -+ list_for_each_entry(mode, &local->modes_list, list) { -+ int clen, rlen; -+ -+ param->u.hw_features.num_modes++; -+ clen = -+ mode->num_channels * sizeof(struct ieee80211_channel_data); -+ rlen = mode->num_rates * sizeof(struct ieee80211_rate_data); -+ if (left < sizeof(*hdr) + clen + rlen) -+ return -E2BIG; -+ left -= sizeof(*hdr) + clen + rlen; -+ -+ hdr = (struct hostapd_ioctl_hw_modes_hdr *)pos; -+ hdr->mode = mode_to_hostapd_mode(mode->mode); -+ hdr->num_channels = mode->num_channels; -+ hdr->num_rates = mode->num_rates; -+ -+ pos = (u8 *) (hdr + 1); -+ chan = (struct ieee80211_channel_data *)pos; -+ for (i = 0; i < mode->num_channels; i++) { -+ chan[i].chan = mode->channels[i].chan; -+ chan[i].freq = mode->channels[i].freq; -+ chan[i].flag = channel_flags_to_hostapd_flags( -+ mode->channels[i].flag); -+ } -+ pos += clen; -+ -+ rate = (struct ieee80211_rate_data *)pos; -+ for (i = 0; i < mode->num_rates; i++) { -+ rate[i].rate = mode->rates[i].rate; -+ rate[i].flags = mode->rates[i].flags; -+ } -+ pos += rlen; -+ } -+ -+ return 0; -+} -+ - - static int ieee80211_ioctl_priv_hostapd(struct net_device *dev, - struct iw_point *p) -@@ -151,6 +250,9 @@ static int ieee80211_ioctl_priv_hostapd( - } - - switch (param->cmd) { -+ case PRISM2_HOSTAPD_GET_HW_FEATURES: -+ ret = ieee80211_ioctl_get_hw_features(dev, param, p->length); -+ break; - default: - ret = -EOPNOTSUPP; - break; diff --git a/package/mac80211/patches/016-prism2-ioctl-eapol.patch b/package/mac80211/patches/016-prism2-ioctl-eapol.patch deleted file mode 100644 index 5ce5758..0000000 --- a/package/mac80211/patches/016-prism2-ioctl-eapol.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- - net/mac80211/ieee80211_ioctl.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- everything.orig/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:33.681513453 +0100 -+++ everything/net/mac80211/ieee80211_ioctl.c 2007-11-07 13:19:35.171517576 +0100 -@@ -984,6 +984,9 @@ static int ieee80211_ioctl_prism2_param( - local = sdata->local; - - switch (param) { -+ case PRISM2_PARAM_EAPOL: -+ sdata->eapol = value; -+ break; - case PRISM2_PARAM_IEEE_802_1X: - sdata->ieee802_1x = value; - break; -@@ -1022,6 +1025,9 @@ static int ieee80211_ioctl_get_prism2_pa - local = sdata->local; - - switch (*param) { -+ case PRISM2_PARAM_EAPOL: -+ *param = sdata->eapol; -+ break; - case PRISM2_PARAM_IEEE_802_1X: - *param = sdata->ieee802_1x; - break; diff --git a/package/mac80211/patches/017-nl80211-add-key-mgmt.patch b/package/mac80211/patches/017-nl80211-add-key-mgmt.patch deleted file mode 100644 index f5b1d45..0000000 --- a/package/mac80211/patches/017-nl80211-add-key-mgmt.patch +++ /dev/null @@ -1,470 +0,0 @@ -Subject: cfg80211/nl80211: introduce key handling - -This introduces key handling to cfg80211/nl80211. Default -and group keys can be added, changed and removed; sequence -counters for each key can be retrieved. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - include/linux/nl80211.h | 34 +++++ - include/net/cfg80211.h | 44 +++++++ - net/wireless/core.c | 3 - net/wireless/nl80211.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 370 insertions(+) - ---- everything.orig/include/linux/nl80211.h 2007-10-30 15:33:43.587381346 +0100 -+++ everything/include/linux/nl80211.h 2007-11-07 13:19:37.861516599 +0100 -@@ -37,6 +37,16 @@ - * userspace to request deletion of a virtual interface, then requires - * attribute %NL80211_ATTR_IFINDEX. - * -+ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified -+ * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. -+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT or -+ * %NL80211_ATTR_KEY_THRESHOLD. -+ * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, -+ * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER -+ * attributes. -+ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX -+ * or %NL80211_ATTR_MAC. -+ * - * @NL80211_CMD_MAX: highest used command number - * @__NL80211_CMD_AFTER_LAST: internal use - */ -@@ -54,6 +64,11 @@ enum nl80211_commands { - NL80211_CMD_NEW_INTERFACE, - NL80211_CMD_DEL_INTERFACE, - -+ NL80211_CMD_GET_KEY, -+ NL80211_CMD_SET_KEY, -+ NL80211_CMD_NEW_KEY, -+ NL80211_CMD_DEL_KEY, -+ - /* add commands here */ - - /* used to define NL80211_CMD_MAX below */ -@@ -75,6 +90,17 @@ enum nl80211_commands { - * @NL80211_ATTR_IFNAME: network interface name - * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype - * -+ * @NL80211_ATTR_MAC: MAC address (various uses) -+ * -+ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of -+ * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC -+ * keys -+ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3) -+ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 -+ * section 7.3.2.25.1, e.g. 0x000FAC04) -+ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and -+ * CCMP keys, each six bytes in little endian -+ * - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use - */ -@@ -89,6 +115,14 @@ enum nl80211_attrs { - NL80211_ATTR_IFNAME, - NL80211_ATTR_IFTYPE, - -+ NL80211_ATTR_MAC, -+ -+ NL80211_ATTR_KEY_DATA, -+ NL80211_ATTR_KEY_IDX, -+ NL80211_ATTR_KEY_CIPHER, -+ NL80211_ATTR_KEY_SEQ, -+ NL80211_ATTR_KEY_DEFAULT, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- everything.orig/net/wireless/nl80211.c 2007-10-30 15:33:43.637380153 +0100 -+++ everything/net/wireless/nl80211.c 2007-11-07 13:19:38.201511066 +0100 -@@ -61,6 +61,14 @@ static struct nla_policy nl80211_policy[ - [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, - [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, - [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, -+ -+ [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, -+ -+ [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, -+ .len = WLAN_MAX_KEY_LEN }, -+ [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, -+ [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, -+ [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, - }; - - /* message building helper */ -@@ -335,6 +343,263 @@ static int nl80211_del_interface(struct - return err; - } - -+struct get_key_cookie { -+ struct sk_buff *msg; -+ int error; -+}; -+ -+static void get_key_callback(void *c, struct key_params *params) -+{ -+ struct get_key_cookie *cookie = c; -+ -+ if (params->key) -+ NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA, -+ params->key_len, params->key); -+ -+ if (params->seq) -+ NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ, -+ params->seq_len, params->seq); -+ -+ if (params->cipher) -+ NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER, -+ params->cipher); -+ -+ return; -+ nla_put_failure: -+ cookie->error = 1; -+} -+ -+static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ u8 key_idx = 0; -+ u8 *mac_addr = NULL; -+ struct get_key_cookie cookie = { -+ .error = 0, -+ }; -+ void *hdr; -+ struct sk_buff *msg; -+ -+ if (info->attrs[NL80211_ATTR_KEY_IDX]) -+ key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); -+ -+ if (key_idx > 3) -+ return -EINVAL; -+ -+ if (info->attrs[NL80211_ATTR_MAC]) -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->get_key) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (!msg) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ NL80211_CMD_NEW_KEY); -+ -+ if (IS_ERR(hdr)) { -+ err = PTR_ERR(hdr); -+ goto out; -+ } -+ -+ cookie.msg = msg; -+ -+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -+ NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); -+ if (mac_addr) -+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); -+ -+ rtnl_lock(); -+ err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr, -+ &cookie, get_key_callback); -+ rtnl_unlock(); -+ -+ if (err) -+ goto out; -+ -+ if (cookie.error) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ err = genlmsg_unicast(msg, info->snd_pid); -+ goto out; -+ -+ nla_put_failure: -+ err = -ENOBUFS; -+ nlmsg_free(msg); -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ u8 key_idx; -+ -+ if (!info->attrs[NL80211_ATTR_KEY_IDX]) -+ return -EINVAL; -+ -+ key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); -+ -+ if (key_idx > 3) -+ return -EINVAL; -+ -+ /* currently only support setting default key */ -+ if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) -+ return -EINVAL; -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->set_default_key) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ struct key_params params; -+ u8 key_idx = 0; -+ u8 *mac_addr = NULL; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ if (!info->attrs[NL80211_ATTR_KEY_CIPHER]) -+ return -EINVAL; -+ -+ if (info->attrs[NL80211_ATTR_KEY_DATA]) { -+ params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]); -+ params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); -+ } -+ -+ if (info->attrs[NL80211_ATTR_KEY_IDX]) -+ key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); -+ -+ params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]); -+ -+ if (info->attrs[NL80211_ATTR_MAC]) -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ if (key_idx > 3) -+ return -EINVAL; -+ -+ /* -+ * Disallow pairwise keys with non-zero index unless it's WEP -+ * (because current deployments use pairwise WEP keys with -+ * non-zero indizes but 802.11i clearly specifies to use zero) -+ */ -+ if (mac_addr && key_idx && -+ params.cipher != WLAN_CIPHER_SUITE_WEP40 && -+ params.cipher != WLAN_CIPHER_SUITE_WEP104) -+ return -EINVAL; -+ -+ /* TODO: add definitions for the lengths to linux/ieee80211.h */ -+ switch (params.cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ if (params.key_len != 5) -+ return -EINVAL; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ if (params.key_len != 32) -+ return -EINVAL; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ if (params.key_len != 16) -+ return -EINVAL; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ if (params.key_len != 13) -+ return -EINVAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->add_key) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ u8 key_idx = 0; -+ u8 *mac_addr = NULL; -+ -+ if (info->attrs[NL80211_ATTR_KEY_IDX]) -+ key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); -+ -+ if (key_idx > 3) -+ return -EINVAL; -+ -+ if (info->attrs[NL80211_ATTR_MAC]) -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->del_key) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ - static struct genl_ops nl80211_ops[] = { - { - .cmd = NL80211_CMD_GET_WIPHY, -@@ -374,6 +639,30 @@ static struct genl_ops nl80211_ops[] = { - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - }, -+ { -+ .cmd = NL80211_CMD_GET_KEY, -+ .doit = nl80211_get_key, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_SET_KEY, -+ .doit = nl80211_set_key, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_NEW_KEY, -+ .doit = nl80211_new_key, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_DEL_KEY, -+ .doit = nl80211_del_key, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, - }; - - /* multicast groups */ ---- everything.orig/net/wireless/core.c 2007-10-30 15:33:43.677380478 +0100 -+++ everything/net/wireless/core.c 2007-11-07 13:19:38.221513833 +0100 -@@ -184,6 +184,9 @@ struct wiphy *wiphy_new(struct cfg80211_ - struct cfg80211_registered_device *drv; - int alloc_size; - -+ WARN_ON(!ops->add_key && ops->del_key); -+ WARN_ON(ops->add_key && !ops->del_key); -+ - alloc_size = sizeof(*drv) + sizeof_priv; - - drv = kzalloc(alloc_size, GFP_KERNEL); ---- everything.orig/include/net/cfg80211.h 2007-10-30 15:33:43.617381780 +0100 -+++ everything/include/net/cfg80211.h 2007-11-07 13:19:38.231512748 +0100 -@@ -49,6 +49,26 @@ extern int ieee80211_radiotap_iterator_n - struct ieee80211_radiotap_iterator *iterator); - - -+ /** -+ * struct key_params - key information -+ * -+ * Information about a key -+ * -+ * @key: key material -+ * @key_len: length of key material -+ * @cipher: cipher suite selector -+ * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used -+ * with the get_key() callback, must be in little endian, -+ * length given by @seq_len. -+ */ -+struct key_params { -+ u8 *key; -+ u8 *seq; -+ int key_len; -+ int seq_len; -+ u32 cipher; -+}; -+ - /* from net/wireless.h */ - struct wiphy; - -@@ -71,6 +91,18 @@ struct wiphy; - * - * @change_virtual_intf: change type of virtual interface - * -+ * @add_key: add a key with the given parameters. @mac_addr will be %NULL -+ * when adding a group key. -+ * -+ * @get_key: get information about the key with the given parameters. -+ * @mac_addr will be %NULL when requesting information for a group -+ * key. All pointers given to the @callback function need not be valid -+ * after it returns. -+ * -+ * @del_key: remove a key given the @mac_addr (%NULL for a group key) -+ * and @key_index -+ * -+ * @set_default_key: set the default key on an interface - */ - struct cfg80211_ops { - int (*add_virtual_intf)(struct wiphy *wiphy, char *name, -@@ -78,6 +110,18 @@ struct cfg80211_ops { - int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex); - int (*change_virtual_intf)(struct wiphy *wiphy, int ifindex, - enum nl80211_iftype type); -+ -+ int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, u8 *mac_addr, -+ struct key_params *params); -+ int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, u8 *mac_addr, void *cookie, -+ void (*callback)(void *cookie, struct key_params*)); -+ int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, -+ u8 key_index, u8 *mac_addr); -+ int (*set_default_key)(struct wiphy *wiphy, -+ struct net_device *netdev, -+ u8 key_index); - }; - - #endif /* __NET_CFG80211_H */ diff --git a/package/mac80211/patches/018-mac80211-cfg80211-keys.patch b/package/mac80211/patches/018-mac80211-cfg80211-keys.patch deleted file mode 100644 index 0c98623..0000000 --- a/package/mac80211/patches/018-mac80211-cfg80211-keys.patch +++ /dev/null @@ -1,120 +0,0 @@ -Subject: mac80211: support adding/removing keys via cfg80211 - -This adds the necessary hooks to mac80211 to allow userspace -to edit keys with cfg80211 (through nl80211.) - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - net/mac80211/cfg.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 91 insertions(+) - ---- everything.orig/net/mac80211/cfg.c 2007-11-07 13:19:29.441515732 +0100 -+++ everything/net/mac80211/cfg.c 2007-11-07 13:19:39.531517685 +0100 -@@ -6,6 +6,7 @@ - * This file is GPLv2 as found in COPYING. - */ - -+#include <linux/ieee80211.h> - #include <linux/nl80211.h> - #include <linux/rtnetlink.h> - #include <net/net_namespace.h> -@@ -105,8 +106,98 @@ static int ieee80211_change_iface(struct - return 0; - } - -+static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, u8 *mac_addr, -+ struct key_params *params) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct sta_info *sta = NULL; -+ enum ieee80211_key_alg alg; -+ int ret; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+ switch (params->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ case WLAN_CIPHER_SUITE_WEP104: -+ alg = ALG_WEP; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ alg = ALG_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ alg = ALG_CCMP; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (mac_addr) { -+ sta = sta_info_get(sdata->local, mac_addr); -+ if (!sta) -+ return -ENOENT; -+ } -+ -+ ret = 0; -+ if (!ieee80211_key_alloc(sdata, sta, alg, key_idx, -+ params->key_len, params->key)) -+ ret = -ENOMEM; -+ -+ if (sta) -+ sta_info_put(sta); -+ -+ return ret; -+} -+ -+static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, u8 *mac_addr) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct sta_info *sta; -+ int ret; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+ if (mac_addr) { -+ sta = sta_info_get(sdata->local, mac_addr); -+ if (!sta) -+ return -ENOENT; -+ -+ ret = 0; -+ if (sta->key) -+ ieee80211_key_free(sta->key); -+ else -+ ret = -ENOENT; -+ -+ sta_info_put(sta); -+ return ret; -+ } -+ -+ if (!sdata->keys[key_idx]) -+ return -ENOENT; -+ -+ ieee80211_key_free(sdata->keys[key_idx]); -+ -+ return 0; -+} -+ -+static int ieee80211_config_default_key(struct wiphy *wiphy, -+ struct net_device *dev, -+ u8 key_idx) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ ieee80211_set_default_key(sdata, key_idx); -+ -+ return 0; -+} -+ - struct cfg80211_ops mac80211_config_ops = { - .add_virtual_intf = ieee80211_add_iface, - .del_virtual_intf = ieee80211_del_iface, - .change_virtual_intf = ieee80211_change_iface, -+ .add_key = ieee80211_add_key, -+ .del_key = ieee80211_del_key, -+ .set_default_key = ieee80211_config_default_key, - }; diff --git a/package/mac80211/patches/019-mac80211-key-seq-nl80211.patch b/package/mac80211/patches/019-mac80211-key-seq-nl80211.patch deleted file mode 100644 index 5d0020b..0000000 --- a/package/mac80211/patches/019-mac80211-key-seq-nl80211.patch +++ /dev/null @@ -1,161 +0,0 @@ -Subject: mac80211: support getting key sequence counters via cfg80211 - -This implements cfg80211's get_key() to allow retrieving the sequence -counter for a TKIP or CCMP key from userspace. It also cleans up and -documents the associated low-level driver interface. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - include/net/mac80211.h | 14 ++------ - net/mac80211/cfg.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 89 insertions(+), 10 deletions(-) - -Index: mac80211/net/mac80211/cfg.c -=================================================================== ---- mac80211.orig/net/mac80211/cfg.c 2007-11-11 15:46:41.497954646 +0100 -+++ mac80211/net/mac80211/cfg.c 2007-11-11 15:46:51.346515884 +0100 -@@ -1,7 +1,7 @@ - /* - * mac80211 configuration hooks for cfg80211 - * -- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> -+ * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> - * - * This file is GPLv2 as found in COPYING. - */ -@@ -180,6 +180,88 @@ - return 0; - } - -+static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, u8 *mac_addr, void *cookie, -+ void (*callback)(void *cookie, -+ struct key_params *params)) -+{ -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct sta_info *sta = NULL; -+ u8 seq[6] = {0}; -+ struct key_params params; -+ struct ieee80211_key *key; -+ u32 iv32; -+ u16 iv16; -+ int err = -ENOENT; -+ -+ if (mac_addr) { -+ sta = sta_info_get(sdata->local, mac_addr); -+ if (!sta) -+ goto out; -+ -+ key = sta->key; -+ } else -+ key = sdata->keys[key_idx]; -+ -+ if (!key) -+ goto out; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ switch (key->conf.alg) { -+ case ALG_TKIP: -+ params.cipher = WLAN_CIPHER_SUITE_TKIP; -+ -+ iv32 = key->u.tkip.iv32; -+ iv16 = key->u.tkip.iv16; -+ -+ if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && -+ sdata->local->ops->get_tkip_seq) -+ sdata->local->ops->get_tkip_seq( -+ local_to_hw(sdata->local), -+ key->conf.hw_key_idx, -+ &iv32, &iv16); -+ -+ seq[0] = iv16 & 0xff; -+ seq[1] = (iv16 >> 8) & 0xff; -+ seq[2] = iv32 & 0xff; -+ seq[3] = (iv32 >> 8) & 0xff; -+ seq[4] = (iv32 >> 16) & 0xff; -+ seq[5] = (iv32 >> 24) & 0xff; -+ params.seq = seq; -+ params.seq_len = 6; -+ break; -+ case ALG_CCMP: -+ params.cipher = WLAN_CIPHER_SUITE_CCMP; -+ seq[0] = key->u.ccmp.tx_pn[5]; -+ seq[1] = key->u.ccmp.tx_pn[4]; -+ seq[2] = key->u.ccmp.tx_pn[3]; -+ seq[3] = key->u.ccmp.tx_pn[2]; -+ seq[4] = key->u.ccmp.tx_pn[1]; -+ seq[5] = key->u.ccmp.tx_pn[0]; -+ params.seq = seq; -+ params.seq_len = 6; -+ break; -+ case ALG_WEP: -+ if (key->conf.keylen == 5) -+ params.cipher = WLAN_CIPHER_SUITE_WEP40; -+ else -+ params.cipher = WLAN_CIPHER_SUITE_WEP104; -+ break; -+ } -+ -+ params.key = key->conf.key; -+ params.key_len = key->conf.keylen; -+ -+ callback(cookie, ¶ms); -+ err = 0; -+ -+ out: -+ if (sta) -+ sta_info_put(sta); -+ return err; -+} -+ - static int ieee80211_config_default_key(struct wiphy *wiphy, - struct net_device *dev, - u8 key_idx) -@@ -198,5 +280,6 @@ - .change_virtual_intf = ieee80211_change_iface, - .add_key = ieee80211_add_key, - .del_key = ieee80211_del_key, -+ .get_key = ieee80211_get_key, - .set_default_key = ieee80211_config_default_key, - }; -Index: mac80211/include/net/mac80211.h -=================================================================== ---- mac80211.orig/include/net/mac80211.h 2007-11-11 15:46:41.377947807 +0100 -+++ mac80211/include/net/mac80211.h 2007-11-11 15:47:08.183475366 +0100 -@@ -598,9 +598,6 @@ - u8 key[0]; - }; - --#define IEEE80211_SEQ_COUNTER_RX 0 --#define IEEE80211_SEQ_COUNTER_TX 1 -- - /** - * enum set_key_cmd - key command - * -@@ -947,9 +944,9 @@ - * - * @get_stats: return low-level statistics - * -- * @get_sequence_counter: For devices that have internal sequence counters this -- * callback allows mac80211 to access the current value of a counter. -- * This callback seems not well-defined, tell us if you need it. -+ * @get_tkip_seq: If your device implements TKIP encryption in hardware this -+ * callback should be provided to read the TKIP transmit IVs (both IV32 -+ * and IV16) for the given key from hardware. - * - * @set_rts_threshold: Configuration of RTS threshold (if device needs it) - * -@@ -1022,9 +1019,8 @@ - int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len); - int (*get_stats)(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -- int (*get_sequence_counter)(struct ieee80211_hw *hw, -- u8* addr, u8 keyidx, u8 txrx, -- u32* iv32, u16* iv16); -+ void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, -+ u32 *iv32, u16 *iv16); - int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); - int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); - int (*set_retry_limit)(struct ieee80211_hw *hw, diff --git a/package/mac80211/patches/020-nl80211-beacon-parameters.patch b/package/mac80211/patches/020-nl80211-beacon-parameters.patch deleted file mode 100644 index 51836f3..0000000 --- a/package/mac80211/patches/020-nl80211-beacon-parameters.patch +++ /dev/null @@ -1,279 +0,0 @@ -Subject: cfg80211/nl80211: add beacon settings - -This adds the necessary API to cfg80211/nl80211 to allow -changing beaconing settings. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - include/linux/nl80211.h | 24 ++++++++ - include/net/cfg80211.h | 33 +++++++++++ - net/wireless/nl80211.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 190 insertions(+) - ---- everything.orig/include/net/cfg80211.h 2007-11-08 11:50:57.412840007 +0100 -+++ everything/include/net/cfg80211.h 2007-11-08 16:50:38.421522842 +0100 -@@ -69,6 +69,26 @@ struct key_params { - u32 cipher; - }; - -+/** -+ * struct beacon_parameters - beacon parameters -+ * -+ * Used to configure the beacon for an interface. -+ * -+ * @head: head portion of beacon (before TIM IE) -+ * or %NULL if not changed -+ * @tail: tail portion of beacon (after TIM IE) -+ * or %NULL if not changed -+ * @interval: beacon interval or zero if not changed -+ * @dtim_period: DTIM period or zero if not changed -+ * @head_len: length of @head -+ * @tail_len: length of @tail -+ */ -+struct beacon_parameters { -+ u8 *head, *tail; -+ int interval, dtim_period; -+ int head_len, tail_len; -+}; -+ - /* from net/wireless.h */ - struct wiphy; - -@@ -103,6 +123,13 @@ struct wiphy; - * and @key_index - * - * @set_default_key: set the default key on an interface -+ * -+ * @add_beacon: Add a beacon with given parameters, @head, @interval -+ * and @dtim_period will be valid, @tail is optional. -+ * @set_beacon: Change the beacon parameters for an access point mode -+ * interface. This should reject the call when no beacon has been -+ * configured. -+ * @del_beacon: Remove beacon configuration and stop sending the beacon. - */ - struct cfg80211_ops { - int (*add_virtual_intf)(struct wiphy *wiphy, char *name, -@@ -122,6 +149,12 @@ struct cfg80211_ops { - int (*set_default_key)(struct wiphy *wiphy, - struct net_device *netdev, - u8 key_index); -+ -+ int (*add_beacon)(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *info); -+ int (*set_beacon)(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *info); -+ int (*del_beacon)(struct wiphy *wiphy, struct net_device *dev); - }; - - #endif /* __NET_CFG80211_H */ ---- everything.orig/include/linux/nl80211.h 2007-11-08 11:50:57.362839952 +0100 -+++ everything/include/linux/nl80211.h 2007-11-08 16:56:32.431522732 +0100 -@@ -47,6 +47,15 @@ - * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX - * or %NL80211_ATTR_MAC. - * -+ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a -+ * %NL80222_CMD_NEW_BEACON message) -+ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface -+ * using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD, -+ * %NL80211_BEACON_HEAD and %NL80211_BEACON_TAIL attributes. -+ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, -+ * parameters are like for %NL80211_CMD_SET_BEACON. -+ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it -+ * - * @NL80211_CMD_MAX: highest used command number - * @__NL80211_CMD_AFTER_LAST: internal use - */ -@@ -69,6 +78,11 @@ enum nl80211_commands { - NL80211_CMD_NEW_KEY, - NL80211_CMD_DEL_KEY, - -+ NL80211_CMD_GET_BEACON, -+ NL80211_CMD_SET_BEACON, -+ NL80211_CMD_NEW_BEACON, -+ NL80211_CMD_DEL_BEACON, -+ - /* add commands here */ - - /* used to define NL80211_CMD_MAX below */ -@@ -101,6 +115,11 @@ enum nl80211_commands { - * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and - * CCMP keys, each six bytes in little endian - * -+ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU -+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing -+ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE -+ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE -+ * - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use - */ -@@ -123,6 +142,11 @@ enum nl80211_attrs { - NL80211_ATTR_KEY_SEQ, - NL80211_ATTR_KEY_DEFAULT, - -+ NL80211_ATTR_BEACON_INTERVAL, -+ NL80211_ATTR_DTIM_PERIOD, -+ NL80211_ATTR_BEACON_HEAD, -+ NL80211_ATTR_BEACON_TAIL, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- everything.orig/net/wireless/nl80211.c 2007-11-08 11:50:57.382836589 +0100 -+++ everything/net/wireless/nl80211.c 2007-11-08 16:58:36.711524524 +0100 -@@ -69,6 +69,13 @@ static struct nla_policy nl80211_policy[ - [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, - [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, - [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, -+ -+ [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, -+ [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, -+ [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, -+ .len = IEEE80211_MAX_DATA_LEN }, -+ [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, -+ .len = IEEE80211_MAX_DATA_LEN }, - }; - - /* message building helper */ -@@ -600,6 +607,114 @@ static int nl80211_del_key(struct sk_buf - return err; - } - -+static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) -+{ -+ int (*call)(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *info); -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ struct beacon_parameters params; -+ int haveinfo = 0; -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ switch (info->genlhdr->cmd) { -+ case NL80211_CMD_NEW_BEACON: -+ /* these are required for NEW_BEACON */ -+ if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || -+ !info->attrs[NL80211_ATTR_DTIM_PERIOD] || -+ !info->attrs[NL80211_ATTR_BEACON_HEAD]) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ call = drv->ops->add_beacon; -+ break; -+ case NL80211_CMD_SET_BEACON: -+ call = drv->ops->set_beacon; -+ break; -+ default: -+ WARN_ON(1); -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ if (!call) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { -+ params.interval = -+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); -+ haveinfo = 1; -+ } -+ -+ if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { -+ params.dtim_period = -+ nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); -+ haveinfo = 1; -+ } -+ -+ if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { -+ params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); -+ params.head_len = -+ nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); -+ haveinfo = 1; -+ } -+ -+ if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { -+ params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); -+ params.tail_len = -+ nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); -+ haveinfo = 1; -+ } -+ -+ if (!haveinfo) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = call(&drv->wiphy, dev, ¶ms); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->del_beacon) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->del_beacon(&drv->wiphy, dev); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ - static struct genl_ops nl80211_ops[] = { - { - .cmd = NL80211_CMD_GET_WIPHY, -@@ -663,6 +778,24 @@ static struct genl_ops nl80211_ops[] = { - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - }, -+ { -+ .cmd = NL80211_CMD_SET_BEACON, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ .doit = nl80211_addset_beacon, -+ }, -+ { -+ .cmd = NL80211_CMD_NEW_BEACON, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ .doit = nl80211_addset_beacon, -+ }, -+ { -+ .cmd = NL80211_CMD_DEL_BEACON, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ .doit = nl80211_del_beacon, -+ }, - }; - - /* multicast groups */ diff --git a/package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch b/package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch deleted file mode 100644 index 702c68f..0000000 --- a/package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch +++ /dev/null @@ -1,484 +0,0 @@ -Subject: mac80211: add beacon configuration via cfg80211 - -This patch implements the cfg80211 hooks for configuring beaconing -on an access point interface in mac80211. While doing so, it fixes -a number of races that could badly crash the machine when the -beacon is changed while being requested by the driver. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- -The dtim_count field should possibly also be part of the beacon -structure, but the possible race there doesn't really matter, -worst thing is that one beacon will be sent with a wrong dtim -count if (and only if) userspace changes the dtim period during -operation. - - net/mac80211/cfg.c | 156 +++++++++++++++++++++++++++++++++++++++++ - net/mac80211/debugfs_netdev.c | 27 ------- - net/mac80211/ieee80211_i.h | 14 ++- - net/mac80211/ieee80211_iface.c | 4 - - net/mac80211/tx.c | 63 ++++++++++------ - 5 files changed, 204 insertions(+), 60 deletions(-) - -Index: mac80211/net/mac80211/cfg.c -=================================================================== ---- mac80211.orig/net/mac80211/cfg.c 2007-11-11 15:17:12.837164411 +0100 -+++ mac80211/net/mac80211/cfg.c 2007-11-11 15:18:36.853952256 +0100 -@@ -9,6 +9,7 @@ - #include <linux/ieee80211.h> - #include <linux/nl80211.h> - #include <linux/rtnetlink.h> -+#include <linux/rcupdate.h> - #include <net/cfg80211.h> - #include "ieee80211_i.h" - #include "cfg.h" -@@ -274,6 +275,158 @@ - return 0; - } - -+/* -+ * This handles both adding a beacon and setting new beacon info -+ */ -+static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, -+ struct beacon_parameters *params) -+{ -+ struct beacon_data *new, *old; -+ int new_head_len, new_tail_len; -+ int size; -+ int err = -EINVAL; -+ -+ old = sdata->u.ap.beacon; -+ -+ /* head must not be zero-length */ -+ if (params->head && !params->head_len) -+ return -EINVAL; -+ -+ /* -+ * This is a kludge. beacon interval should really be part -+ * of the beacon information. -+ */ -+ if (params->interval) { -+ sdata->local->hw.conf.beacon_int = params->interval; -+ if (ieee80211_hw_config(sdata->local)) -+ return -EINVAL; -+ /* -+ * We updated some parameter so if below bails out -+ * it's not an error. -+ */ -+ err = 0; -+ } -+ -+ /* Need to have a beacon head if we don't have one yet */ -+ if (!params->head && !old) -+ return err; -+ -+ /* sorry, no way to start beaconing without dtim period */ -+ if (!params->dtim_period && !old) -+ return err; -+ -+ /* new or old head? */ -+ if (params->head) -+ new_head_len = params->head_len; -+ else -+ new_head_len = old->head_len; -+ -+ /* new or old tail? */ -+ if (params->tail || !old) -+ /* params->tail_len will be zero for !params->tail */ -+ new_tail_len = params->tail_len; -+ else -+ new_tail_len = old->tail_len; -+ -+ size = sizeof(*new) + new_head_len + new_tail_len; -+ -+ new = kzalloc(size, GFP_KERNEL); -+ if (!new) -+ return -ENOMEM; -+ -+ /* start filling the new info now */ -+ -+ /* new or old dtim period? */ -+ if (params->dtim_period) -+ new->dtim_period = params->dtim_period; -+ else -+ new->dtim_period = old->dtim_period; -+ -+ /* -+ * pointers go into the block we allocated, -+ * memory is | beacon_data | head | tail | -+ */ -+ new->head = ((u8 *) new) + sizeof(*new); -+ new->tail = new->head + new_head_len; -+ new->head_len = new_head_len; -+ new->tail_len = new_tail_len; -+ -+ /* copy in head */ -+ if (params->head) -+ memcpy(new->head, params->head, new_head_len); -+ else -+ memcpy(new->head, old->head, new_head_len); -+ -+ /* copy in optional tail */ -+ if (params->tail) -+ memcpy(new->tail, params->tail, new_tail_len); -+ else -+ if (old) -+ memcpy(new->tail, old->tail, new_tail_len); -+ -+ rcu_assign_pointer(sdata->u.ap.beacon, new); -+ -+ synchronize_rcu(); -+ -+ kfree(old); -+ -+ return ieee80211_if_config_beacon(sdata->dev); -+} -+ -+static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *params) -+{ -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct beacon_data *old; -+ -+ if (sdata->type != IEEE80211_IF_TYPE_AP) -+ return -EINVAL; -+ -+ old = sdata->u.ap.beacon; -+ -+ if (old) -+ return -EALREADY; -+ -+ return ieee80211_config_beacon(sdata, params); -+} -+ -+static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *params) -+{ -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct beacon_data *old; -+ -+ if (sdata->type != IEEE80211_IF_TYPE_AP) -+ return -EINVAL; -+ -+ old = sdata->u.ap.beacon; -+ -+ if (!old) -+ return -ENOENT; -+ -+ return ieee80211_config_beacon(sdata, params); -+} -+ -+static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct beacon_data *old; -+ -+ if (sdata->type != IEEE80211_IF_TYPE_AP) -+ return -EINVAL; -+ -+ old = sdata->u.ap.beacon; -+ -+ if (!old) -+ return -ENOENT; -+ -+ rcu_assign_pointer(sdata->u.ap.beacon, NULL); -+ synchronize_rcu(); -+ kfree(old); -+ -+ return ieee80211_if_config_beacon(dev); -+} -+ - struct cfg80211_ops mac80211_config_ops = { - .add_virtual_intf = ieee80211_add_iface, - .del_virtual_intf = ieee80211_del_iface, -@@ -282,4 +435,7 @@ - .del_key = ieee80211_del_key, - .get_key = ieee80211_get_key, - .set_default_key = ieee80211_config_default_key, -+ .add_beacon = ieee80211_add_beacon, -+ .set_beacon = ieee80211_set_beacon, -+ .del_beacon = ieee80211_del_beacon, - }; -Index: mac80211/net/mac80211/debugfs_netdev.c -=================================================================== ---- mac80211.orig/net/mac80211/debugfs_netdev.c 2007-10-14 00:42:30.054156000 +0200 -+++ mac80211/net/mac80211/debugfs_netdev.c 2007-11-11 15:18:11.852527505 +0100 -@@ -124,7 +124,6 @@ - - /* AP attributes */ - IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); --IEEE80211_IF_FILE(dtim_period, u.ap.dtim_period, DEC); - IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); - IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); - IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC); -@@ -138,26 +137,6 @@ - } - __IEEE80211_IF_FILE(num_buffered_multicast); - --static ssize_t ieee80211_if_fmt_beacon_head_len( -- const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) --{ -- if (sdata->u.ap.beacon_head) -- return scnprintf(buf, buflen, "%d\n", -- sdata->u.ap.beacon_head_len); -- return scnprintf(buf, buflen, "\n"); --} --__IEEE80211_IF_FILE(beacon_head_len); -- --static ssize_t ieee80211_if_fmt_beacon_tail_len( -- const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) --{ -- if (sdata->u.ap.beacon_tail) -- return scnprintf(buf, buflen, "%d\n", -- sdata->u.ap.beacon_tail_len); -- return scnprintf(buf, buflen, "\n"); --} --__IEEE80211_IF_FILE(beacon_tail_len); -- - /* WDS attributes */ - IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); - -@@ -194,14 +173,11 @@ - DEBUGFS_ADD(eapol, ap); - DEBUGFS_ADD(ieee8021_x, ap); - DEBUGFS_ADD(num_sta_ps, ap); -- DEBUGFS_ADD(dtim_period, ap); - DEBUGFS_ADD(dtim_count, ap); - DEBUGFS_ADD(num_beacons, ap); - DEBUGFS_ADD(force_unicast_rateidx, ap); - DEBUGFS_ADD(max_ratectrl_rateidx, ap); - DEBUGFS_ADD(num_buffered_multicast, ap); -- DEBUGFS_ADD(beacon_head_len, ap); -- DEBUGFS_ADD(beacon_tail_len, ap); - } - - static void add_wds_files(struct ieee80211_sub_if_data *sdata) -@@ -287,14 +263,11 @@ - DEBUGFS_DEL(eapol, ap); - DEBUGFS_DEL(ieee8021_x, ap); - DEBUGFS_DEL(num_sta_ps, ap); -- DEBUGFS_DEL(dtim_period, ap); - DEBUGFS_DEL(dtim_count, ap); - DEBUGFS_DEL(num_beacons, ap); - DEBUGFS_DEL(force_unicast_rateidx, ap); - DEBUGFS_DEL(max_ratectrl_rateidx, ap); - DEBUGFS_DEL(num_buffered_multicast, ap); -- DEBUGFS_DEL(beacon_head_len, ap); -- DEBUGFS_DEL(beacon_tail_len, ap); - } - - static void del_wds_files(struct ieee80211_sub_if_data *sdata) -Index: mac80211/net/mac80211/ieee80211_i.h -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_i.h 2007-11-11 15:15:53.792659922 +0100 -+++ mac80211/net/mac80211/ieee80211_i.h 2007-11-11 15:18:11.864528190 +0100 -@@ -190,9 +190,14 @@ - typedef ieee80211_txrx_result (*ieee80211_rx_handler) - (struct ieee80211_txrx_data *rx); - -+struct beacon_data { -+ u8 *head, *tail; -+ int head_len, tail_len; -+ int dtim_period; -+}; -+ - struct ieee80211_if_ap { -- u8 *beacon_head, *beacon_tail; -- int beacon_head_len, beacon_tail_len; -+ struct beacon_data *beacon; - - struct list_head vlans; - -@@ -205,7 +210,7 @@ - u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; - atomic_t num_sta_ps; /* number of stations in PS mode */ - struct sk_buff_head ps_bc_buf; -- int dtim_period, dtim_count; -+ int dtim_count; - int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ - int max_ratectrl_rateidx; /* max TX rateidx for rate control */ - int num_beacons; /* number of TXed beacon frames for this BSS */ -@@ -361,14 +366,11 @@ - struct dentry *eapol; - struct dentry *ieee8021_x; - struct dentry *num_sta_ps; -- struct dentry *dtim_period; - struct dentry *dtim_count; - struct dentry *num_beacons; - struct dentry *force_unicast_rateidx; - struct dentry *max_ratectrl_rateidx; - struct dentry *num_buffered_multicast; -- struct dentry *beacon_head_len; -- struct dentry *beacon_tail_len; - } ap; - struct { - struct dentry *channel_use; -Index: mac80211/net/mac80211/ieee80211_iface.c -=================================================================== ---- mac80211.orig/net/mac80211/ieee80211_iface.c 2007-11-11 15:15:53.796660158 +0100 -+++ mac80211/net/mac80211/ieee80211_iface.c 2007-11-11 15:18:11.868528415 +0100 -@@ -187,7 +187,6 @@ - sdata->u.vlan.ap = NULL; - break; - case IEEE80211_IF_TYPE_AP: -- sdata->u.ap.dtim_period = 2; - sdata->u.ap.force_unicast_rateidx = -1; - sdata->u.ap.max_ratectrl_rateidx = -1; - skb_queue_head_init(&sdata->u.ap.ps_bc_buf); -@@ -271,8 +270,7 @@ - } - } - -- kfree(sdata->u.ap.beacon_head); -- kfree(sdata->u.ap.beacon_tail); -+ kfree(sdata->u.ap.beacon); - - while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { - local->total_ps_buffered--; -Index: mac80211/net/mac80211/tx.c -=================================================================== ---- mac80211.orig/net/mac80211/tx.c 2007-11-11 15:15:53.804660611 +0100 -+++ mac80211/net/mac80211/tx.c 2007-11-11 15:18:11.868528415 +0100 -@@ -1656,7 +1656,8 @@ - - static void ieee80211_beacon_add_tim(struct ieee80211_local *local, - struct ieee80211_if_ap *bss, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ struct beacon_data *beacon) - { - u8 *pos, *tim; - int aid0 = 0; -@@ -1672,7 +1673,7 @@ - IEEE80211_MAX_AID+1); - - if (bss->dtim_count == 0) -- bss->dtim_count = bss->dtim_period - 1; -+ bss->dtim_count = beacon->dtim_period - 1; - else - bss->dtim_count--; - -@@ -1680,7 +1681,7 @@ - *pos++ = WLAN_EID_TIM; - *pos++ = 4; - *pos++ = bss->dtim_count; -- *pos++ = bss->dtim_period; -+ *pos++ = beacon->dtim_period; - - if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) - aid0 = 1; -@@ -1728,8 +1729,9 @@ - struct ieee80211_if_ap *ap = NULL; - struct ieee80211_rate *rate; - struct rate_control_extra extra; -- u8 *b_head, *b_tail; -- int bh_len, bt_len; -+ struct beacon_data *beacon; -+ -+ rcu_read_lock(); - - bdev = dev_get_by_index(if_id); - if (bdev) { -@@ -1738,37 +1740,35 @@ - dev_put(bdev); - } - -- if (!ap || sdata->type != IEEE80211_IF_TYPE_AP || -- !ap->beacon_head) { -+ beacon = rcu_dereference(ap->beacon); -+ -+ if (!ap || sdata->type != IEEE80211_IF_TYPE_AP || !beacon) { - #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "no beacon data avail for idx=%d " - "(%s)\n", if_id, bdev ? bdev->name : "N/A"); - #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ -- return NULL; -+ skb = NULL; -+ goto out; - } - -- /* Assume we are generating the normal beacon locally */ -- b_head = ap->beacon_head; -- b_tail = ap->beacon_tail; -- bh_len = ap->beacon_head_len; -- bt_len = ap->beacon_tail_len; -- -- skb = dev_alloc_skb(local->tx_headroom + -- bh_len + bt_len + 256 /* maximum TIM len */); -+ /* headroom, head length, tail length and maximum TIM length */ -+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -+ beacon->tail_len + 256); - if (!skb) -- return NULL; -+ goto out; - - skb_reserve(skb, local->tx_headroom); -- memcpy(skb_put(skb, bh_len), b_head, bh_len); -+ memcpy(skb_put(skb, beacon->head_len), beacon->head, -+ beacon->head_len); - - ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data); - -- ieee80211_beacon_add_tim(local, ap, skb); -+ ieee80211_beacon_add_tim(local, ap, skb, beacon); - -- if (b_tail) { -- memcpy(skb_put(skb, bt_len), b_tail, bt_len); -- } -+ if (beacon->tail) -+ memcpy(skb_put(skb, beacon->tail_len), beacon->tail, -+ beacon->tail_len); - - if (control) { - memset(&extra, 0, sizeof(extra)); -@@ -1781,7 +1781,8 @@ - "found\n", wiphy_name(local->hw.wiphy)); - } - dev_kfree_skb(skb); -- return NULL; -+ skb = NULL; -+ goto out; - } - - control->tx_rate = -@@ -1796,6 +1797,9 @@ - } - - ap->num_beacons++; -+ -+ out: -+ rcu_read_unlock(); - return skb; - } - EXPORT_SYMBOL(ieee80211_beacon_get); -@@ -1844,6 +1848,7 @@ - struct net_device *bdev; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_ap *bss = NULL; -+ struct beacon_data *beacon; - - bdev = dev_get_by_index(if_id); - if (bdev) { -@@ -1851,9 +1856,19 @@ - bss = &sdata->u.ap; - dev_put(bdev); - } -- if (!bss || sdata->type != IEEE80211_IF_TYPE_AP || !bss->beacon_head) -+ -+ if (!bss) - return NULL; - -+ rcu_read_lock(); -+ beacon = rcu_dereference(bss->beacon); -+ -+ if (sdata->type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) { -+ rcu_read_unlock(); -+ return NULL; -+ } -+ rcu_read_unlock(); -+ - if (bss->dtim_count != 0) - return NULL; /* send buffered bc/mc only after DTIM beacon */ - memset(control, 0, sizeof(*control)); diff --git a/package/mac80211/patches/022-nl80211-sta.patch b/package/mac80211/patches/022-nl80211-sta.patch deleted file mode 100644 index 4d08721..0000000 --- a/package/mac80211/patches/022-nl80211-sta.patch +++ /dev/null @@ -1,464 +0,0 @@ -Subject: cfg80211/nl80211: station handling - -This patch adds station handling to cfg80211/nl80211. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - include/linux/nl80211.h | 68 +++++++++++++ - include/net/cfg80211.h | 54 ++++++++++ - net/wireless/nl80211.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 358 insertions(+) - ---- everything.orig/include/linux/nl80211.h 2007-11-08 16:56:32.431522732 +0100 -+++ everything/include/linux/nl80211.h 2007-11-08 17:15:15.961529840 +0100 -@@ -7,6 +7,18 @@ - */ - - /** -+ * DOC: Station handling -+ * -+ * Stations are added per interface, but a special case exists with VLAN -+ * interfaces. When a station is bound to an AP interface, it may be moved -+ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). -+ * The station is still assumed to belong to the AP interface it was added -+ * to. -+ * -+ * TODO: need more info? -+ */ -+ -+/** - * enum nl80211_commands - supported nl80211 commands - * - * @NL80211_CMD_UNSPEC: unspecified command to catch errors -@@ -56,6 +68,16 @@ - * parameters are like for %NL80211_CMD_SET_BEACON. - * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it - * -+ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by -+ * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. -+ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by -+ * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. -+ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the -+ * the interface identified by %NL80211_ATTR_IFINDEX. -+ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC -+ * or, if no MAC address given, all stations, on the interface identified -+ * by %NL80211_ATTR_IFINDEX. -+ * - * @NL80211_CMD_MAX: highest used command number - * @__NL80211_CMD_AFTER_LAST: internal use - */ -@@ -83,6 +105,11 @@ enum nl80211_commands { - NL80211_CMD_NEW_BEACON, - NL80211_CMD_DEL_BEACON, - -+ NL80211_CMD_GET_STATION, -+ NL80211_CMD_SET_STATION, -+ NL80211_CMD_NEW_STATION, -+ NL80211_CMD_DEL_STATION, -+ - /* add commands here */ - - /* used to define NL80211_CMD_MAX below */ -@@ -120,6 +147,17 @@ enum nl80211_commands { - * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE - * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE - * -+ * @NL80211_ATTR_STA_AID: Association ID for the station (u16) -+ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of -+ * &enum nl80211_sta_flags. -+ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by -+ * IEEE 802.11 7.3.1.6 (u16). -+ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported -+ * rates as defined by IEEE 802.11 7.3.2.2 but without the length -+ * restriction (at most %NL80211_MAX_SUPP_RATES). -+ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station -+ * to, or the AP interface the station was originally added to to. -+ * - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use - */ -@@ -147,12 +185,20 @@ enum nl80211_attrs { - NL80211_ATTR_BEACON_HEAD, - NL80211_ATTR_BEACON_TAIL, - -+ NL80211_ATTR_STA_AID, -+ NL80211_ATTR_STA_FLAGS, -+ NL80211_ATTR_STA_LISTEN_INTERVAL, -+ NL80211_ATTR_STA_SUPPORTED_RATES, -+ NL80211_ATTR_STA_VLAN, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, - NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 - }; - -+#define NL80211_MAX_SUPP_RATES 32 -+ - /** - * enum nl80211_iftype - (virtual) interface types - * -@@ -184,4 +230,26 @@ enum nl80211_iftype { - NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1 - }; - -+/** -+ * enum nl80211_sta_flags - station flags -+ * -+ * Station flags. When a station is added to an AP interface, it is -+ * assumed to be already associated (and hence authenticated.) -+ * -+ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) -+ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames -+ * with short barker preamble -+ * @NL80211_STA_FLAG_WME: station is WME/QoS capable -+ */ -+enum nl80211_sta_flags { -+ __NL80211_STA_FLAG_INVALID, -+ NL80211_STA_FLAG_AUTHORIZED, -+ NL80211_STA_FLAG_SHORT_PREAMBLE, -+ NL80211_STA_FLAG_WME, -+ -+ /* keep last */ -+ __NL80211_STA_FLAG_AFTER_LAST, -+ NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 -+}; -+ - #endif /* __LINUX_NL80211_H */ ---- everything.orig/include/net/cfg80211.h 2007-11-08 16:50:38.421522842 +0100 -+++ everything/include/net/cfg80211.h 2007-11-08 17:15:15.971532444 +0100 -@@ -89,6 +89,47 @@ struct beacon_parameters { - int head_len, tail_len; - }; - -+/** -+ * enum station_flags - station flags -+ * -+ * Station capability flags. Note that these must be the bits -+ * according to the nl80211 flags. -+ * -+ * @STATION_FLAG_CHANGED: station flags were changed -+ * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X) -+ * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames -+ * with short preambles -+ * @STATION_FLAG_WME: station is WME/QoS capable -+ */ -+enum station_flags { -+ STATION_FLAG_CHANGED = 1<<0, -+ STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED, -+ STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE, -+ STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME, -+}; -+ -+/** -+ * struct station_parameters - station parameters -+ * -+ * Used to change and create a new station. -+ * -+ * @vlan: vlan interface station should belong to -+ * @supported_rates: supported rates in IEEE 802.11 format -+ * (or NULL for no change) -+ * @supported_rates_len: number of supported rates -+ * @station_flags: station flags (see &enum station_flags) -+ * @listen_interval: listen interval or -1 for no change -+ * @aid: AID or zero for no change -+ */ -+struct station_parameters { -+ u8 *supported_rates; -+ struct net_device *vlan; -+ u32 station_flags; -+ int listen_interval; -+ u16 aid; -+ u8 supported_rates_len; -+}; -+ - /* from net/wireless.h */ - struct wiphy; - -@@ -130,6 +171,12 @@ struct wiphy; - * interface. This should reject the call when no beacon has been - * configured. - * @del_beacon: Remove beacon configuration and stop sending the beacon. -+ * -+ * @add_station: Add a new station. -+ * -+ * @del_station: Remove a station; @mac may be NULL to remove all stations. -+ * -+ * @change_station: Modify a given station. - */ - struct cfg80211_ops { - int (*add_virtual_intf)(struct wiphy *wiphy, char *name, -@@ -155,6 +202,13 @@ struct cfg80211_ops { - int (*set_beacon)(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *info); - int (*del_beacon)(struct wiphy *wiphy, struct net_device *dev); -+ -+ int (*add_station)(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_parameters *params); -+ int (*del_station)(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac); -+ int (*change_station)(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_parameters *params); - }; - - #endif /* __NET_CFG80211_H */ ---- everything.orig/net/wireless/nl80211.c 2007-11-08 16:58:36.711524524 +0100 -+++ everything/net/wireless/nl80211.c 2007-11-08 17:15:15.981533909 +0100 -@@ -76,6 +76,12 @@ static struct nla_policy nl80211_policy[ - .len = IEEE80211_MAX_DATA_LEN }, - [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, - .len = IEEE80211_MAX_DATA_LEN }, -+ [NL80211_ATTR_STA_AID] = { .type = NLA_U16 }, -+ [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED }, -+ [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 }, -+ [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, -+ .len = NL80211_MAX_SUPP_RATES }, -+ [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, - }; - - /* message building helper */ -@@ -715,6 +721,211 @@ static int nl80211_del_beacon(struct sk_ - return err; - } - -+static -+struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] __read_mostly = { -+ [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, -+ [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, -+ [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, -+}; -+ -+static int parse_station_flags(struct nlattr *nla, u32 *staflags) -+{ -+ struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; -+ int flag; -+ -+ *staflags = 0; -+ -+ if (!nla) -+ return 0; -+ -+ if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, -+ nla, sta_flags_policy)) -+ return -EINVAL; -+ -+ *staflags = STATION_FLAG_CHANGED; -+ -+ for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) -+ if (flags[flag]) -+ *staflags |= (1<<flag); -+ -+ return 0; -+} -+ -+static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) -+{ -+ return -EOPNOTSUPP; -+} -+ -+/* -+ * Get vlan interface making sure it is on the right wiphy. -+ */ -+static int get_vlan(struct nlattr *vlanattr, -+ struct cfg80211_registered_device *rdev, -+ struct net_device **vlan) -+{ -+ *vlan = NULL; -+ -+ if (vlanattr) { -+ *vlan = dev_get_by_index(nla_get_u32(vlanattr)); -+ if (!*vlan) -+ return -ENODEV; -+ if (!(*vlan)->ieee80211_ptr) -+ return -EINVAL; -+ if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy) -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ struct station_parameters params; -+ u8 *mac_addr = NULL; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ params.listen_interval = -1; -+ -+ if (info->attrs[NL80211_ATTR_STA_AID]) -+ return -EINVAL; -+ -+ if (!info->attrs[NL80211_ATTR_MAC]) -+ return -EINVAL; -+ -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) { -+ params.supported_rates = -+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); -+ params.supported_rates_len = -+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); -+ } -+ -+ if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) -+ params.listen_interval = -+ nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); -+ -+ if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], -+ ¶ms.station_flags)) -+ return -EINVAL; -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); -+ if (err) -+ goto out; -+ -+ if (!drv->ops->change_station) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms); -+ rtnl_unlock(); -+ -+ out: -+ if (params.vlan) -+ dev_put(params.vlan); -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ struct station_parameters params; -+ u8 *mac_addr = NULL; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ if (!info->attrs[NL80211_ATTR_MAC]) -+ return -EINVAL; -+ -+ if (!info->attrs[NL80211_ATTR_STA_AID]) -+ return -EINVAL; -+ -+ if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) -+ return -EINVAL; -+ -+ if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) -+ return -EINVAL; -+ -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ params.supported_rates = -+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); -+ params.supported_rates_len = -+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); -+ params.listen_interval = -+ nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); -+ params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); -+ -+ if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], -+ ¶ms.station_flags)) -+ return -EINVAL; -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); -+ if (err) -+ goto out; -+ -+ if (!drv->ops->add_station) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms); -+ rtnl_unlock(); -+ -+ out: -+ if (params.vlan) -+ dev_put(params.vlan); -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ -+static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ u8 *mac_addr = NULL; -+ -+ if (info->attrs[NL80211_ATTR_MAC]) -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->del_station) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->del_station(&drv->wiphy, dev, mac_addr); -+ rtnl_unlock(); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; -+} -+ - static struct genl_ops nl80211_ops[] = { - { - .cmd = NL80211_CMD_GET_WIPHY, -@@ -796,6 +1007,31 @@ static struct genl_ops nl80211_ops[] = { - .flags = GENL_ADMIN_PERM, - .doit = nl80211_del_beacon, - }, -+ { -+ .cmd = NL80211_CMD_GET_STATION, -+ .doit = nl80211_get_station, -+ /* TODO: implement dumpit */ -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_SET_STATION, -+ .doit = nl80211_set_station, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_NEW_STATION, -+ .doit = nl80211_new_station, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = NL80211_CMD_DEL_STATION, -+ .doit = nl80211_del_station, -+ .policy = nl80211_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, - }; - - /* multicast groups */ diff --git a/package/mac80211/patches/023-mac80211-implement-sta.patch b/package/mac80211/patches/023-mac80211-implement-sta.patch deleted file mode 100644 index 0950676..0000000 --- a/package/mac80211/patches/023-mac80211-implement-sta.patch +++ /dev/null @@ -1,224 +0,0 @@ -Subject: mac80211: implement cfg80211's station handling - -This implements station handling from userspace via cfg80211 -in mac80211. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - net/mac80211/cfg.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 192 insertions(+) - ---- everything.orig/net/mac80211/cfg.c 2007-11-08 17:11:52.351521702 +0100 -+++ everything/net/mac80211/cfg.c 2007-11-08 17:15:51.801523493 +0100 -@@ -14,6 +14,7 @@ - #include <net/cfg80211.h> - #include "ieee80211_i.h" - #include "cfg.h" -+#include "ieee80211_rate.h" - - static enum ieee80211_if_types - nl80211_type_to_mac80211_type(enum nl80211_iftype type) -@@ -428,6 +429,194 @@ static int ieee80211_del_beacon(struct w - return ieee80211_if_config_beacon(dev); - } - -+/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ -+struct iapp_layer2_update { -+ u8 da[ETH_ALEN]; /* broadcast */ -+ u8 sa[ETH_ALEN]; /* STA addr */ -+ __be16 len; /* 6 */ -+ u8 dsap; /* 0 */ -+ u8 ssap; /* 0 */ -+ u8 control; -+ u8 xid_info[3]; -+} __attribute__ ((packed)); -+ -+static void ieee80211_send_layer2_update(struct sta_info *sta) -+{ -+ struct iapp_layer2_update *msg; -+ struct sk_buff *skb; -+ -+ /* Send Level 2 Update Frame to update forwarding tables in layer 2 -+ * bridge devices */ -+ -+ skb = dev_alloc_skb(sizeof(*msg)); -+ if (!skb) -+ return; -+ msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg)); -+ -+ /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) -+ * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ -+ -+ memset(msg->da, 0xff, ETH_ALEN); -+ memcpy(msg->sa, sta->addr, ETH_ALEN); -+ msg->len = htons(6); -+ msg->dsap = 0; -+ msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ -+ msg->control = 0xaf; /* XID response lsb.1111F101. -+ * F=0 (no poll command; unsolicited frame) */ -+ msg->xid_info[0] = 0x81; /* XID format identifier */ -+ msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ -+ msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ -+ -+ skb->dev = sta->dev; -+ skb->protocol = eth_type_trans(skb, sta->dev); -+ memset(skb->cb, 0, sizeof(skb->cb)); -+ netif_rx(skb); -+} -+ -+static void sta_apply_parameters(struct ieee80211_local *local, -+ struct sta_info *sta, -+ struct station_parameters *params) -+{ -+ u32 rates; -+ int i, j; -+ struct ieee80211_hw_mode *mode; -+ -+ if (params->station_flags & STATION_FLAG_CHANGED) { -+ sta->flags &= ~WLAN_STA_AUTHORIZED; -+ if (params->station_flags & STATION_FLAG_AUTHORIZED) -+ sta->flags |= WLAN_STA_AUTHORIZED; -+ -+ sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; -+ if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) -+ sta->flags |= WLAN_STA_SHORT_PREAMBLE; -+ -+ sta->flags &= ~WLAN_STA_WME; -+ if (params->station_flags & STATION_FLAG_WME) -+ sta->flags |= WLAN_STA_WME; -+ } -+ -+ if (params->aid) { -+ sta->aid = params->aid; -+ if (sta->aid > IEEE80211_MAX_AID) -+ sta->aid = 0; /* XXX: should this be an error? */ -+ } -+ -+ if (params->listen_interval >= 0) -+ sta->listen_interval = params->listen_interval; -+ -+ if (params->supported_rates) { -+ rates = 0; -+ mode = local->oper_hw_mode; -+ for (i = 0; i < params->supported_rates_len; i++) { -+ int rate = (params->supported_rates[i] & 0x7f) * 5; -+ for (j = 0; j < mode->num_rates; j++) { -+ if (mode->rates[j].rate == rate) -+ rates |= BIT(j); -+ } -+ } -+ sta->supp_rates = rates; -+ } -+} -+ -+static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_parameters *params) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ struct sta_info *sta; -+ struct ieee80211_sub_if_data *sdata; -+ -+ /* Prevent a race with changing the rate control algorithm */ -+ if (!netif_running(dev)) -+ return -ENETDOWN; -+ -+ /* XXX: get sta belonging to dev */ -+ sta = sta_info_get(local, mac); -+ if (sta) { -+ sta_info_put(sta); -+ return -EEXIST; -+ } -+ -+ if (params->vlan) { -+ sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); -+ -+ if (sdata->type != IEEE80211_IF_TYPE_VLAN || -+ sdata->type != IEEE80211_IF_TYPE_AP) -+ return -EINVAL; -+ } else -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+ sta = sta_info_add(local, dev, mac, GFP_KERNEL); -+ if (!sta) -+ return -ENOMEM; -+ -+ sta->dev = sdata->dev; -+ if (sdata->type == IEEE80211_IF_TYPE_VLAN || -+ sdata->type == IEEE80211_IF_TYPE_AP) -+ ieee80211_send_layer2_update(sta); -+ -+ sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; -+ -+ sta_apply_parameters(local, sta, params); -+ -+ rate_control_rate_init(sta, local); -+ -+ sta_info_put(sta); -+ -+ return 0; -+} -+ -+static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ struct sta_info *sta; -+ -+ if (mac) { -+ /* XXX: get sta belonging to dev */ -+ sta = sta_info_get(local, mac); -+ if (!sta) -+ return -ENOENT; -+ -+ sta_info_free(sta); -+ sta_info_put(sta); -+ } else -+ sta_info_flush(local, dev); -+ -+ return 0; -+} -+ -+static int ieee80211_change_station(struct wiphy *wiphy, -+ struct net_device *dev, -+ u8 *mac, -+ struct station_parameters *params) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ struct sta_info *sta; -+ struct ieee80211_sub_if_data *vlansdata; -+ -+ /* XXX: get sta belonging to dev */ -+ sta = sta_info_get(local, mac); -+ if (!sta) -+ return -ENOENT; -+ -+ if (params->vlan && params->vlan != sta->dev) { -+ vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); -+ -+ if (vlansdata->type != IEEE80211_IF_TYPE_VLAN || -+ vlansdata->type != IEEE80211_IF_TYPE_AP) -+ return -EINVAL; -+ -+ sta->dev = params->vlan; -+ ieee80211_send_layer2_update(sta); -+ } -+ -+ sta_apply_parameters(local, sta, params); -+ -+ sta_info_put(sta); -+ -+ return 0; -+} -+ - struct cfg80211_ops mac80211_config_ops = { - .add_virtual_intf = ieee80211_add_iface, - .del_virtual_intf = ieee80211_del_iface, -@@ -439,4 +628,7 @@ struct cfg80211_ops mac80211_config_ops - .add_beacon = ieee80211_add_beacon, - .set_beacon = ieee80211_set_beacon, - .del_beacon = ieee80211_del_beacon, -+ .add_station = ieee80211_add_station, -+ .del_station = ieee80211_del_station, -+ .change_station = ieee80211_change_station, - }; diff --git a/package/mac80211/patches/024-nl80211-get-sta.patch b/package/mac80211/patches/024-nl80211-get-sta.patch deleted file mode 100644 index 198ad18..0000000 --- a/package/mac80211/patches/024-nl80211-get-sta.patch +++ /dev/null @@ -1,208 +0,0 @@ -Subject: cfg80211/nl80211: implement station attribute retrieval - -After a station is added to the kernel's structures, userspace -has to be able to retrieve statistics about that station, especially -whether the station was idle and how much bytes were transferred -to and from it. This adds the necessary code to nl80211. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - include/linux/nl80211.h | 28 ++++++++++++++++ - include/net/cfg80211.h | 35 ++++++++++++++++++++ - net/wireless/nl80211.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 144 insertions(+), 1 deletion(-) - ---- everything.orig/include/linux/nl80211.h 2007-11-08 17:15:15.961529840 +0100 -+++ everything/include/linux/nl80211.h 2007-11-08 17:17:00.891547364 +0100 -@@ -157,6 +157,9 @@ enum nl80211_commands { - * restriction (at most %NL80211_MAX_SUPP_RATES). - * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station - * to, or the AP interface the station was originally added to to. -+ * @NL80211_ATTR_STA_STATS: statistics for a station, part of station info -+ * given for %NL80211_CMD_GET_STATION, nested attribute containing -+ * info as possible, see &enum nl80211_sta_stats. - * - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -190,6 +193,7 @@ enum nl80211_attrs { - NL80211_ATTR_STA_LISTEN_INTERVAL, - NL80211_ATTR_STA_SUPPORTED_RATES, - NL80211_ATTR_STA_VLAN, -+ NL80211_ATTR_STA_STATS, - - /* add attributes here, update the policy in nl80211.c */ - -@@ -252,4 +256,28 @@ enum nl80211_sta_flags { - NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 - }; - -+/** -+ * enum nl80211_sta_stats - station statistics -+ * -+ * These attribute types are used with %NL80211_ATTR_STA_STATS -+ * when getting information about a station. -+ * -+ * @__NL80211_STA_STAT_INVALID: attribute number 0 is reserved -+ * @NL80211_STA_STAT_INACTIVE_TIME: time since last activity (u32, msecs) -+ * @NL80211_STA_STAT_RX_BYTES: total received bytes (u32, from this station) -+ * @NL80211_STA_STAT_TX_BYTES: total transmitted bytes (u32, to this station) -+ * @__NL80211_STA_STAT_AFTER_LAST: internal -+ * @NL80211_STA_STAT_MAX: highest possible station stats attribute -+ */ -+enum nl80211_sta_stats { -+ __NL80211_STA_STAT_INVALID, -+ NL80211_STA_STAT_INACTIVE_TIME, -+ NL80211_STA_STAT_RX_BYTES, -+ NL80211_STA_STAT_TX_BYTES, -+ -+ /* keep last */ -+ __NL80211_STA_STAT_AFTER_LAST, -+ NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1 -+}; -+ - #endif /* __LINUX_NL80211_H */ ---- everything.orig/include/net/cfg80211.h 2007-11-08 17:15:15.971532444 +0100 -+++ everything/include/net/cfg80211.h 2007-11-08 17:17:00.891547364 +0100 -@@ -130,6 +130,39 @@ struct station_parameters { - u8 supported_rates_len; - }; - -+/** -+ * enum station_stats_flags - station statistics flags -+ * -+ * Used by the driver to indicate which info in &struct station_stats -+ * it has filled in during get_station(). -+ * -+ * @STATION_STAT_INACTIVE_TIME: @inactive_time filled -+ * @STATION_STAT_RX_BYTES: @rx_bytes filled -+ * @STATION_STAT_TX_BYTES: @tx_bytes filled -+ */ -+enum station_stats_flags { -+ STATION_STAT_INACTIVE_TIME = 1<<0, -+ STATION_STAT_RX_BYTES = 1<<1, -+ STATION_STAT_TX_BYTES = 1<<2, -+}; -+ -+/** -+ * struct station_stats - station statistics -+ * -+ * Station information filled by driver for get_station(). -+ * -+ * @filled: bitflag of flags from &enum station_stats_flags -+ * @inactive_time: time since last station activity (tx/rx) in milliseconds -+ * @rx_bytes: bytes received from this station -+ * @tx_bytes: bytes transmitted to this station -+ */ -+struct station_stats { -+ u32 filled; -+ u32 inactive_time; -+ u32 rx_bytes; -+ u32 tx_bytes; -+}; -+ - /* from net/wireless.h */ - struct wiphy; - -@@ -209,6 +242,8 @@ struct cfg80211_ops { - u8 *mac); - int (*change_station)(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_parameters *params); -+ int (*get_station)(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_stats *stats); - }; - - #endif /* __NET_CFG80211_H */ ---- everything.orig/net/wireless/nl80211.c 2007-11-08 17:15:15.981533909 +0100 -+++ everything/net/wireless/nl80211.c 2007-11-08 17:17:00.901534235 +0100 -@@ -751,9 +751,89 @@ static int parse_station_flags(struct nl - return 0; - } - -+static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, -+ int flags, struct net_device *dev, -+ u8 *mac_addr, struct station_stats *stats) -+{ -+ void *hdr; -+ struct nlattr *statsattr; -+ -+ hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); -+ if (!hdr) -+ return -1; -+ -+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); -+ -+ statsattr = nla_nest_start(msg, NL80211_ATTR_STA_STATS); -+ if (!statsattr) -+ goto nla_put_failure; -+ if (stats->filled & STATION_STAT_INACTIVE_TIME) -+ NLA_PUT_U32(msg, NL80211_STA_STAT_INACTIVE_TIME, -+ stats->inactive_time); -+ if (stats->filled & STATION_STAT_RX_BYTES) -+ NLA_PUT_U32(msg, NL80211_STA_STAT_RX_BYTES, -+ stats->rx_bytes); -+ if (stats->filled & STATION_STAT_TX_BYTES) -+ NLA_PUT_U32(msg, NL80211_STA_STAT_TX_BYTES, -+ stats->tx_bytes); -+ -+ nla_nest_end(msg, statsattr); -+ -+ return genlmsg_end(msg, hdr); -+ -+ nla_put_failure: -+ return genlmsg_cancel(msg, hdr); -+} -+ -+ - static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) - { -- return -EOPNOTSUPP; -+ struct cfg80211_registered_device *drv; -+ int err; -+ struct net_device *dev; -+ struct station_stats stats; -+ struct sk_buff *msg; -+ u8 *mac_addr = NULL; -+ -+ memset(&stats, 0, sizeof(stats)); -+ -+ if (!info->attrs[NL80211_ATTR_MAC]) -+ return -EINVAL; -+ -+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); -+ -+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); -+ if (err) -+ return err; -+ -+ if (!drv->ops->get_station) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ rtnl_lock(); -+ err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &stats); -+ rtnl_unlock(); -+ -+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (!msg) -+ goto out; -+ -+ if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, -+ dev, mac_addr, &stats) < 0) -+ goto out_free; -+ -+ err = genlmsg_unicast(msg, info->snd_pid); -+ goto out; -+ -+ out_free: -+ nlmsg_free(msg); -+ -+ out: -+ cfg80211_put_dev(drv); -+ dev_put(dev); -+ return err; - } - - /* diff --git a/package/mac80211/patches/025-mac80211-get-sta.patch b/package/mac80211/patches/025-mac80211-get-sta.patch deleted file mode 100644 index 868ca86..0000000 --- a/package/mac80211/patches/025-mac80211-get-sta.patch +++ /dev/null @@ -1,51 +0,0 @@ -Subject: mac80211: implement station stats retrieval - -This implements the required cfg80211 callback in mac80211 -to allow userspace to get station statistics. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> - ---- - net/mac80211/cfg.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - ---- everything.orig/net/mac80211/cfg.c 2007-11-08 17:15:51.801523493 +0100 -+++ everything/net/mac80211/cfg.c 2007-11-08 17:17:01.921529351 +0100 -@@ -617,6 +617,31 @@ static int ieee80211_change_station(stru - return 0; - } - -+static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_stats *stats) -+{ -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ struct sta_info *sta; -+ -+ sta = sta_info_get(local, mac); -+ if (!sta) -+ return -ENOENT; -+ -+ /* XXX: verify sta->dev == dev */ -+ -+ stats->filled = STATION_STAT_INACTIVE_TIME | -+ STATION_STAT_RX_BYTES | -+ STATION_STAT_TX_BYTES; -+ -+ stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); -+ stats->rx_bytes = sta->rx_bytes; -+ stats->tx_bytes = sta->tx_bytes; -+ -+ sta_info_put(sta); -+ -+ return 0; -+} -+ - struct cfg80211_ops mac80211_config_ops = { - .add_virtual_intf = ieee80211_add_iface, - .del_virtual_intf = ieee80211_del_iface, -@@ -631,4 +656,5 @@ struct cfg80211_ops mac80211_config_ops - .add_station = ieee80211_add_station, - .del_station = ieee80211_del_station, - .change_station = ieee80211_change_station, -+ .get_station = ieee80211_get_station, - }; |