diff options
Diffstat (limited to 'package/mac80211/patches/010-add-mgmt-iface.patch')
-rw-r--r-- | package/mac80211/patches/010-add-mgmt-iface.patch | 688 |
1 files changed, 0 insertions, 688 deletions
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 eae5ff6d5e..0000000000 --- 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; |