mac80211: IEEE802.11e/WMM TS management and DLS support
PATCH 2/3 mac80211: IEEE802.11e/WMM TS management and DLS support
This patch adds IEEE802.11e/WMM Traffic Stream (TS) Management and Direct Link Setup (DLS) non-AP QSTA mode support for mac80211.
Signed-off-by Zhu Yi <[email protected]>
--- net/mac80211/ieee80211.c | 18 +- net/mac80211/ieee80211_i.h | 53 +++ net/mac80211/ieee80211_iface.c | 8 + net/mac80211/ieee80211_sta.c | 792 +++++++++++++++++++++++++++++++++++++++- net/mac80211/sta_info.c | 34 ++- net/mac80211/sta_info.h | 10 +- net/mac80211/wme.c | 38 ++- 7 files changed, 931 insertions(+), 22 deletions(-)
net/mac80211/ieee80211.c +13 -5
@@ -1557,11 +1557,18 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,memcpy (hdr.addr4, skb->data +ETH_ALEN ,ETH_ALEN ); hdrlen =30 ; }else if (sdata->type ==IEEE80211_IF_TYPE_STA ) { - fc |=IEEE80211_FCTL_TODS ; -/* BSSID SA DA */ -memcpy (hdr.addr1, sdata->u.sta.bssid,ETH_ALEN ); -memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); -memcpy (hdr.addr3, skb->data,ETH_ALEN ); +if (dls_link_status (local, skb->data) ==DLS_STATUS_OK ){ +/* DA SA BSSID */ +memcpy (hdr.addr1, skb->data,ETH_ALEN ); +memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); +memcpy (hdr.addr3, sdata->u.sta.bssid,ETH_ALEN ); + }else { + fc |=IEEE80211_FCTL_TODS ; +/* BSSID SA DA */ +memcpy (hdr.addr1, sdata->u.sta.bssid,ETH_ALEN ); +memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); +memcpy (hdr.addr3, skb->data,ETH_ALEN ); + } hdrlen =24 ; }else if (sdata->type ==IEEE80211_IF_TYPE_IBSS ) {/* DA SA BSSID */
@@ -2281,6 +2288,7 @@ static void ieee80211_if_shutdown(struct net_device *dev)case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ;del_timer_sync (&sdata->u.sta.timer); +del_timer_sync (&sdata->u.sta.admit_timer);skb_queue_purge (&sdata->u.sta.skb_queue);if (!local->ops->hw_scan && local->scan_dev == sdata->dev) {
net/mac80211/ieee80211_i.h +53 -0
95 lines not on this page · raw message
net/mac80211/ieee80211_iface.c +8 -0
@@ -182,6 +182,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) (unsigned long) sdata);skb_queue_head_init (&ifsta->skb_queue); +init_timer (&ifsta->admit_timer); + ifsta->admit_timer.data = (unsigned long ) dev; + ifsta->admit_timer.function = ieee80211_admit_refresh; + ifsta->capab =WLAN_CAPABILITY_ESS ; ifsta->auth_algs =IEEE80211_AUTH_ALG_OPEN |IEEE80211_AUTH_ALG_SHARED_KEY ;
@@ -191,6 +195,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) ifsta->auto_channel_sel =1 ; ifsta->auto_bssid_sel =1 ; +/* Initialize non-AP QSTA QoS Params */ + ifsta->dot11EDCAAveragingPeriod =5 ; + ifsta->MPDUExchangeTime =0 ; + msdata =IEEE80211_DEV_TO_SUB_IF (sdata->local->mdev); sdata->bss = &msdata->u.ap;break ;
net/mac80211/ieee80211_sta.c +787 -5
853 lines not on this page · raw message
net/mac80211/sta_info.c +30 -4
@@ -33,7 +33,7 @@ static void sta_info_hash_add(struct ieee80211_local *local,/* Caller must hold local->sta_lock */ static void sta_info_hash_del (struct ieee80211_local *local, -struct sta_info *sta) +struct sta_info *sta,int dls) {struct sta_info *s;
@@ -41,15 +41,19 @@ static void sta_info_hash_del(struct ieee80211_local *local,if (!s)return ;if (memcmp (s->addr, sta->addr,ETH_ALEN ) ==0 ) { +if (dls && !s->dls_sta) +return ; local->sta_hash[STA_HASH (sta->addr)] = s->hnext;return ; }while (s->hnext &&memcmp (s->hnext->addr, sta->addr,ETH_ALEN ) !=0 ) s = s->hnext; -if (s->hnext) +if (s->hnext) { +if (dls && !s->hnext->dls_sta) +return ; s->hnext = s->hnext->hnext; -else + }else printk (KERN_ERR "%s: could not remove STA " MAC_FMT " from " "hash table\n" , local->mdev->name,MAC_ARG (sta->addr)); }
@@ -78,6 +82,28 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) }EXPORT_SYMBOL (sta_info_get); +struct sta_info *dls_info_get (struct ieee80211_local *local,u8 *addr) +{ +struct sta_info *sta; + +spin_lock_bh (&local->sta_lock); + sta = local->sta_hash[STA_HASH (addr)]; +while (sta) { +if (memcmp (sta->addr, addr,ETH_ALEN ) ==0 ) { +if (!sta->dls_sta) { + sta =NULL ; +break ; + } +__sta_info_get (sta); +break ; + } + sta = sta->hnext; + } +spin_unlock_bh (&local->sta_lock); + +return sta; +} +int sta_info_min_txrate_get (struct ieee80211_local *local) {struct sta_info *sta;
@@ -218,7 +244,7 @@ static void sta_info_remove(struct sta_info *sta)struct ieee80211_local *local = sta->local;struct ieee80211_sub_if_data *sdata; -sta_info_hash_del (local, sta); +sta_info_hash_del (local, sta,0 );list_del (&sta->list); sdata =IEEE80211_DEV_TO_SUB_IF (sta->dev);if (sta->flags &WLAN_STA_PS ) {
net/mac80211/sta_info.h +8 -2
@@ -102,8 +102,14 @@ struct sta_info {#ifdef CONFIG_MAC80211_DEBUGFS int debugfs_registered;#endif -int assoc_ap;/* whether this is an AP that we are -* associated with as a client */ + int assoc_ap:1; /* whether this is an AP that we are +* associated with as a client */ + int dls_sta:1; /* whether this stations is a DLS peer of us */ + +#define DLS_STATUS_OK 0 +#define DLS_STATUS_NOLINK 1 +int dls_status; +u32 dls_timeout;#ifdef CONFIG_HOSTAPD_WPA_TESTING u32 wpa_trigger;
net/mac80211/wme.c +32 -6
@@ -166,11 +166,13 @@ static inline int wme_downgrade_ac(struct sk_buff *skb)static inline int classify80211 (struct sk_buff *skb,struct Qdisc *qd) {struct ieee80211_local *local =wdev_priv (qd->dev->ieee80211_ptr); +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (qd->dev); +struct ieee80211_if_sta *ifsta = &sdata->u.sta;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; +int qos, tsid, dir;const int ieee802_1d_to_ac[8 ] = {2 ,3 ,3 ,2 ,1 ,1 ,0 ,0 };/* see if frame is data or non data frame */
@@ -197,14 +199,38 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) }/* use the data classifier to determine what 802.1d tag the -* data frame has */ +* data frame has */ skb->priority =classify_1d (skb, qd); + tsid =8 + skb->priority; + +/* FIXME: only uplink needs to be checked for Tx */ + dir =STA_TS_UPLINK ; + +if ((sdata->type ==IEEE80211_IF_TYPE_STA ) && + (local->wmm_acm &BIT (skb->priority))) { +switch (ifsta->ts_data[tsid][dir].status) { +case TS_STATUS_ACTIVE : +/* if TS Management is enabled, update used_time */ + ifsta->ts_data[tsid][dir].used_time_usec += + ifsta->MPDUExchangeTime; +break ; +case TS_STATUS_THROTTLING : +/* if admitted time is used up, refuse to send more */ +if (net_ratelimit ()) +printk (KERN_DEBUG "QoS packet throttling\n" ); +break ; +default : +break ; + } + } -/* incase we are a client verify acm is not set for this ac */ -while (unlikely (local->wmm_acm &BIT (skb->priority))) { +/* in case we are a client verify acm is not set for this ac */ +while ((local->wmm_acm &BIT (skb->priority)) && + !((sdata->type ==IEEE80211_IF_TYPE_STA ) && + (ifsta->ts_data[skb->priority +EDCA_TSID_MIN ][dir].status + ==TS_STATUS_ACTIVE ))) {if (wme_downgrade_ac (skb)) { -/* No AC with lower priority has acm=0, -* drop packet. */ +/* No AC with lower priority has acm=0, drop packet. */ return -1 ; } }
Signature · 1 line
1.5.0.rc2.g73a2