RE: [PATCH 4/6] d80211: add IEEE802.11e/WMM Traffic Stream (TS) Management support
On Thu, 2006-12-14 at 21:45 -0800, Simon Barber wrote: > This policing of media time must be done in the qdisc - and made to > work > per DA (Destination Address) - in order that AP mode will work as well > as STA mode. In addition the count of used time should be updated > AFTER > the frame has been sent, not before, since the number of retries done > cannot be taken into account before. These MUST be counted. > > The API to the qdisc should be via TC - not cfg80211 or other. This is a good idea, but I have to think it more. AFAIK, tc works on the host side. For the TS management case, how about user makes a taffic stream request but the AP refuses it (or allowes the request but the medium_time is changed), there has to be a way for tc to get this information. Thanks, -yi - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] d80211: add IEEE802.11e/WMM Traffic Stream (TS) Management support
Some comments... In these cases > + init_timer(&ifsta->admit_timer); > + ifsta->admit_timer.data = (unsigned long) dev; > + ifsta->admit_timer.function = ieee80211_admit_refresh; > +void ieee80211_send_addts(struct net_device *dev, > + struct ieee802_11_elem_tspec *tspec) > +void wmm_send_addts(struct net_device *dev, struct ieee802_11_elem_tspec > *tspec) > +void ieee80211_send_delts(struct net_device *dev, u8 tsid, u8 direction, > + u32 medium_time) > +void wmm_send_delts(struct net_device *dev, u8 tsid, u8 direction, > + u32 medium_time) please don't use the device as the argument but rather the sdata. Using the device only to unwrap it to the sdata again isn't really nice. > + mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); > + memset(mgmt, 0, 24); > + memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); > + memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); > + memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); No need to zero out the structure if you set all fields anyway. > + mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); > + memset(mgmt, 0, 24); > + memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); > + memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); > + memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); > + mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, > +IEEE80211_STYPE_ACTION); same here. > + mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); > + memset(mgmt, 0, 24); and here, and in a few more places. > +static u32 calculate_mpdu_exchange_time(struct ieee802_11_elem_tspec *tspec) > +{ > + /* > + * MPDUExchangeTime = duration(Nominal MSDU Size, Min PHY Rate) + > + *SIFS + ACK duration > + */ > + return 5000; > +} Is this correct? Aren't some of those things variable? > + printk(KERN_DEBUG "Dialog_token: %d, TID: %u, Direction: %u, PSB: %d, " > +"UP: %d\n", mgmt->u.action.u.wme_action.dialog_token, > +tspec->ts_info.tsid, tspec->ts_info.direction, > +tspec->ts_info.apsd, tspec->ts_info.up); Can we have those printks optional? > +static void ieee80211_rx_mgmt_action(struct net_device *dev, > + if (len < 24 + 1) { > + printk(KERN_DEBUG "%s: too short (%zd) action frame " > +"received from " MAC_FMT " - ignored\n", > +dev->name, len, MAC_ARG(mgmt->sa)); > + return; > + } Do we really want this if in all possibilities where we use the data it needs to be 24+4 long? > + case WLAN_CATEGORY_DLS: > + case WLAN_CATEGORY_BACK: > + default: > + printk(KERN_ERR "%s: unsupported action category %d\n", > +dev->name, mgmt->u.action.category); > + break; I don't think these are KERN_ERR. johannes signature.asc Description: This is a digitally signed message part
RE: [PATCH 4/6] d80211: add IEEE802.11e/WMM Traffic Stream (TS) Management support
This policing of media time must be done in the qdisc - and made to work per DA (Destination Address) - in order that AP mode will work as well as STA mode. In addition the count of used time should be updated AFTER the frame has been sent, not before, since the number of retries done cannot be taken into account before. These MUST be counted. The API to the qdisc should be via TC - not cfg80211 or other. Simon -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Zhu Yi Sent: Wednesday, December 13, 2006 8:03 PM To: netdev@vger.kernel.org Subject: [PATCH 4/6] d80211: add IEEE802.11e/WMM Traffic Stream (TS) Management support The d80211 now maintains a sta_ts_data structure for every TSID and direction combination of all the Taffic Streams. For those admission control enabled Acesss Categories (AC), STA can initiatively request a traffic stream. The stack also maintains two variables to record the admitted time and used time for each TS. In every dot11EDCAAveragingPeriod, a timer is used to track how much time (in usec) has been used (vs the admitted time). If it finds the used time is less than the admitted time in current dot11EDCAAveragingPeriod period, the STA will continue to fulfil the admitted time in the next period. Otherwise the stack will reduce the admitted time until the TS has been throttled. Finally both the AP and STA are able to delete the TS by sending a DELTS MLME. Signed-off-by: Zhu Yi <[EMAIL PROTECTED]> --- net/d80211/ieee80211.c |4 net/d80211/ieee80211_i.h | 49 - net/d80211/ieee80211_iface.c |5 + net/d80211/ieee80211_sta.c | 403 ++ net/d80211/wme.c | 34 +++- 5 files changed, 480 insertions(+), 15 deletions(-) d4a326b8493fb465480a68696315c05558c03b2c diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c index 6e10db5..4eba18f 100644 --- a/net/d80211/ieee80211.c +++ b/net/d80211/ieee80211.c @@ -4599,6 +4599,10 @@ int ieee80211_register_hw(struct ieee802 goto fail_wep; } + /* Initialize QoS Params */ + local->dot11EDCAAveragingPeriod = 5; + local->MPDUExchangeTime = 0; + /* TODO: add rtnl locking around device creation and qdisc install */ ieee80211_install_qdisc(local->mdev); diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h index ef303da..e8929d3 100644 --- a/net/d80211/ieee80211_i.h +++ b/net/d80211/ieee80211_i.h @@ -56,6 +56,10 @@ struct ieee80211_local; * increased memory use (about 2 kB of RAM per entry). */ #define IEEE80211_FRAGMENT_MAX 4 +/* Minimum and Maximum TSID used by EDCA. HCCA uses 0~7; EDCA uses 8~15 +*/ #define EDCA_TSID_MIN 8 #define EDCA_TSID_MAX 15 + struct ieee80211_fragment_entry { unsigned long first_frag_time; unsigned int seq; @@ -241,6 +245,7 @@ struct ieee80211_if_sta { IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; struct work_struct work; + struct timer_list admit_timer; /* Recompute EDCA admitted time */ u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; size_t ssid_len; @@ -328,6 +333,19 @@ struct ieee80211_sub_if_data { #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev) +struct sta_ts_data { + enum { + TS_STATUS_UNUSED= 0, + TS_STATUS_ACTIVE= 1, + TS_STATUS_INACTIVE = 2, + TS_STATUS_THROTTLING= 3, + } status; + u8 dialog_token; + u8 up; + u32 admitted_time_usec; + u32 used_time_usec; +}; + struct ieee80211_local { /* embed the driver visible part. * don't cast (use the static inlines below), but we keep @@ -449,18 +467,19 @@ struct ieee80211_local { #ifdef CONFIG_HOSTAPD_WPA_TESTING u32 wpa_trigger; #endif /* CONFIG_HOSTAPD_WPA_TESTING */ -/* SNMP counters */ -/* dot11CountersTable */ -u32 dot11TransmittedFragmentCount; -u32 dot11MulticastTransmittedFrameCount; -u32 dot11FailedCount; + /* SNMP counters */ + /* dot11CountersTable */ + u32 dot11TransmittedFragmentCount; + u32 dot11MulticastTransmittedFrameCount; + u32 dot11FailedCount; u32 dot11RetryCount; u32 dot11MultipleRetryCount; u32 dot11FrameDuplicateCount; -u32 dot11ReceivedFragmentCount; -u32 dot11MulticastReceivedFrameCount; -u32 dot11TransmittedFrameCount; -u32 dot11WEPUndecryptableCount; + u32 dot11ReceivedFragmentCount; + u32 dot11MulticastReceivedFrameCount; + u32 dot11TransmittedFrameCount; + u32 dot11WEPUndecryptableCount; + u32 dot11EDCAAveragingPeriod; #ifdef CONFIG_D80211_LEDS int tx_led_counter, rx_led_counter; @@ -533,6 +552,17 @@ struct ieee80211_local { * (1 << MODE_*) */
[PATCH 4/6] d80211: add IEEE802.11e/WMM Traffic Stream (TS) Management support
The d80211 now maintains a sta_ts_data structure for every TSID and direction combination of all the Taffic Streams. For those admission control enabled Acesss Categories (AC), STA can initiatively request a traffic stream. The stack also maintains two variables to record the admitted time and used time for each TS. In every dot11EDCAAveragingPeriod, a timer is used to track how much time (in usec) has been used (vs the admitted time). If it finds the used time is less than the admitted time in current dot11EDCAAveragingPeriod period, the STA will continue to fulfil the admitted time in the next period. Otherwise the stack will reduce the admitted time until the TS has been throttled. Finally both the AP and STA are able to delete the TS by sending a DELTS MLME. Signed-off-by: Zhu Yi <[EMAIL PROTECTED]> --- net/d80211/ieee80211.c |4 net/d80211/ieee80211_i.h | 49 - net/d80211/ieee80211_iface.c |5 + net/d80211/ieee80211_sta.c | 403 ++ net/d80211/wme.c | 34 +++- 5 files changed, 480 insertions(+), 15 deletions(-) d4a326b8493fb465480a68696315c05558c03b2c diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c index 6e10db5..4eba18f 100644 --- a/net/d80211/ieee80211.c +++ b/net/d80211/ieee80211.c @@ -4599,6 +4599,10 @@ int ieee80211_register_hw(struct ieee802 goto fail_wep; } + /* Initialize QoS Params */ + local->dot11EDCAAveragingPeriod = 5; + local->MPDUExchangeTime = 0; + /* TODO: add rtnl locking around device creation and qdisc install */ ieee80211_install_qdisc(local->mdev); diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h index ef303da..e8929d3 100644 --- a/net/d80211/ieee80211_i.h +++ b/net/d80211/ieee80211_i.h @@ -56,6 +56,10 @@ struct ieee80211_local; * increased memory use (about 2 kB of RAM per entry). */ #define IEEE80211_FRAGMENT_MAX 4 +/* Minimum and Maximum TSID used by EDCA. HCCA uses 0~7; EDCA uses 8~15 */ +#define EDCA_TSID_MIN 8 +#define EDCA_TSID_MAX 15 + struct ieee80211_fragment_entry { unsigned long first_frag_time; unsigned int seq; @@ -241,6 +245,7 @@ struct ieee80211_if_sta { IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; struct work_struct work; + struct timer_list admit_timer; /* Recompute EDCA admitted time */ u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; size_t ssid_len; @@ -328,6 +333,19 @@ struct ieee80211_sub_if_data { #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev) +struct sta_ts_data { + enum { + TS_STATUS_UNUSED= 0, + TS_STATUS_ACTIVE= 1, + TS_STATUS_INACTIVE = 2, + TS_STATUS_THROTTLING= 3, + } status; + u8 dialog_token; + u8 up; + u32 admitted_time_usec; + u32 used_time_usec; +}; + struct ieee80211_local { /* embed the driver visible part. * don't cast (use the static inlines below), but we keep @@ -449,18 +467,19 @@ struct ieee80211_local { #ifdef CONFIG_HOSTAPD_WPA_TESTING u32 wpa_trigger; #endif /* CONFIG_HOSTAPD_WPA_TESTING */ -/* SNMP counters */ -/* dot11CountersTable */ -u32 dot11TransmittedFragmentCount; -u32 dot11MulticastTransmittedFrameCount; -u32 dot11FailedCount; + /* SNMP counters */ + /* dot11CountersTable */ + u32 dot11TransmittedFragmentCount; + u32 dot11MulticastTransmittedFrameCount; + u32 dot11FailedCount; u32 dot11RetryCount; u32 dot11MultipleRetryCount; u32 dot11FrameDuplicateCount; -u32 dot11ReceivedFragmentCount; -u32 dot11MulticastReceivedFrameCount; -u32 dot11TransmittedFrameCount; -u32 dot11WEPUndecryptableCount; + u32 dot11ReceivedFragmentCount; + u32 dot11MulticastReceivedFrameCount; + u32 dot11TransmittedFrameCount; + u32 dot11WEPUndecryptableCount; + u32 dot11EDCAAveragingPeriod; #ifdef CONFIG_D80211_LEDS int tx_led_counter, rx_led_counter; @@ -533,6 +552,17 @@ struct ieee80211_local { * (1 << MODE_*) */ int user_space_mlme; + + u32 MPDUExchangeTime; +#define STA_TSID_NUM 16 +#define STA_TSDIR_NUM 2 + /* HCCA: 0~7, EDCA: 8~15 */ + struct sta_ts_data ts_data[STA_TSID_NUM][STA_TSDIR_NUM]; +}; + +enum sta_link_direction { + STA_TS_UPLINK = 0, + STA_TS_DOWNLINK = 1, }; static inline struct ieee80211_local *hw_to_local( @@ -639,6 +669,7 @@ int ieee80211_set_compression(struct iee int ieee80211_init_client(struct net_device *dev); /* ieee80211_sta.c */ void ieee80211_sta_work(void *ptr); +void ieee80211_admit_refresh(unsigned long ptr); void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, struct ieee80211_rx_status