p54: put broadcast frames into the right queues
PATCH 2/3 p54: put broadcast frames into the right queues
stlc45xx's specs finally brought some light what all the 4 extra queues for. multicast & managment frames go now into their own queue.
---
drivers/net/wireless/p54/p54common.c +74 -14
@@ -902,6 +902,62 @@ free: }EXPORT_SYMBOL_GPL (p54_read_eeprom); +#ifndef WLAN_FC_GET_TYPE +#define WLAN_FC_GET_TYPE (fc) (fc & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE (fc) (fc & IEEE80211_FCTL_STYPE) +#endif + +static int p54_tx_fill (struct ieee80211_hw *dev,struct sk_buff *skb, +struct ieee80211_tx_info *info,u8 *queue,size_t *extra_len, +u16 *flags,u16 *aid) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +struct p54_common *priv = dev->priv; +u16 fc =le16_to_cpu (hdr->frame_control); +int ret =0 ; + +if (unlikely (WLAN_FC_GET_TYPE (fc) ==IEEE80211_FTYPE_MGMT )) { +switch (WLAN_FC_GET_STYPE (fc)) { +case IEEE80211_STYPE_BEACON : + *aid =0 ; + *queue =0 ; + *extra_len =IEEE80211_MAX_TIM_LEN ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP ; +return 0 ; +case IEEE80211_STYPE_PROBE_RESP : + *aid =0 ; + *queue =2 ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP | +P54_HDR_FLAG_DATA_OUT_NOCANCEL ; +return 0 ; +default : + *queue =2 ; + ret =0 ; + } + }else { + *queue +=4 ; + ret =1 ; + } + +switch (priv->mode) { +case NL80211_IFTYPE_STATION : + *aid =1 ; +break ; +case NL80211_IFTYPE_AP : +if (is_multicast_ether_addr (hdr->addr1)) { + *aid =0 ; + *queue =3 ; +return 0 ; + } +case NL80211_IFTYPE_ADHOC : +if (info->control.sta) + *aid = info->control.sta->aid; +else + *flags =P54_HDR_FLAG_DATA_OUT_NOCANCEL ; + } +return ret; +} +static int p54_tx (struct ieee80211_hw *dev,struct sk_buff *skb) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);
@@ -909,22 +965,26 @@ static int p54_tx(struct ieee80211_hw *dstruct p54_common *priv = dev->priv;struct p54_hdr *hdr;struct p54_tx_data *txhdr; -size_t padding, len; +size_t padding, len, tim_len;int i, j, ridx; -u16 hdr_flags =0 ; -u8 rate; +u16 hdr_flags =0 , aid =0 ; +u8 rate, queue;u8 cts_rate =0x20 ;u8 rc_flags;u8 calculated_tries[4 ];u8 nrates =0 , nremaining =8 ; - current_queue = &priv->tx_stats[skb_get_queue_mapping (skb) +4 ]; -if (unlikely (current_queue->len > current_queue->limit)) -return NETDEV_TX_BUSY ; - current_queue->len++; - current_queue->count++; -if (current_queue->len == current_queue->limit) -ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + queue =skb_get_queue_mapping (skb); + +if (p54_tx_fill (dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { + current_queue = &priv->tx_stats[queue]; +if (unlikely (current_queue->len > current_queue->limit)) +return NETDEV_TX_BUSY ; + current_queue->len++; + current_queue->count++; +if (current_queue->len == current_queue->limit) +ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + } padding = (unsigned long )(skb->data - (sizeof (*hdr) +sizeof (*txhdr))) &3 ; len = skb->len;
@@ -935,7 +995,7 @@ static int p54_tx(struct ieee80211_hw *dif (padding) hdr_flags |=P54_HDR_FLAG_DATA_ALIGN ; hdr->len =cpu_to_le16 (len); - hdr->type = (info->flags &IEEE80211_TX_CTL_NO_ACK ) ?0 :cpu_to_le16 (1 ); + hdr->type =cpu_to_le16 (aid); hdr->rts_tries = info->control.rates[0 ].count;/*
@@ -1013,7 +1073,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->rts_rate_idx =0 ; txhdr->key_type =0 ; txhdr->key_len =0 ; - txhdr->hw_queue =skb_get_queue_mapping (skb) +4 ; + txhdr->hw_queue = queue; txhdr->backlog =32 ;memset (txhdr->durations,0 ,sizeof (txhdr->durations)); txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
@@ -1024,7 +1084,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->align[0 ] = padding;/* modifies skb->cb and with it info, so must be last! */ -if (unlikely (p54_assign_address (dev, skb, hdr, skb->len))) { +if (unlikely (p54_assign_address (dev, skb, hdr, skb->len + tim_len))) {skb_pull (skb,sizeof (*hdr) +sizeof (*txhdr) + padding);if (current_queue) { current_queue->len--;
@@ -1341,7 +1401,7 @@ static int p54_config(struct ieee80211_hmutex_lock (&priv->conf_mutex); priv->rx_antenna =2 ;/* automatic */ priv->output_power = conf->power_level <<2 ; - ret =p54_set_freq (dev, conf->channel->center_freq); + ret =p54_set_freq (dev,cpu_to_le16 (conf->channel->center_freq));if (!ret) ret =p54_set_edcf (dev);mutex_unlock (&priv->conf_mutex);
PATCH v2 2/3 p54: put broadcast frames into the right queues
stlc45xx's specs finally brought some light what all the 4 extra queues for. multicast & managment frames go now into their own queue.
changes:
- p54_set_freq now takes the freq in u16. keep it that way
- remove WLAN_FC_XYZ MACROs
Thanks Harvey Harrison <[email protected]> for review
---
drivers/net/wireless/p54/p54common.c +66 -13
@@ -902,6 +902,55 @@ free: }EXPORT_SYMBOL_GPL (p54_read_eeprom); +static int p54_tx_fill (struct ieee80211_hw *dev,struct sk_buff *skb, +struct ieee80211_tx_info *info,u8 *queue,size_t *extra_len, +u16 *flags,u16 *aid) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +struct p54_common *priv = dev->priv; +int ret =0 ; + +if (unlikely (ieee80211_is_mgmt (hdr->frame_control))) { +if (ieee80211_is_beacon (hdr->frame_control)) { + *aid =0 ; + *queue =0 ; + *extra_len =IEEE80211_MAX_TIM_LEN ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP ; +return 0 ; + }else if (ieee80211_is_probe_resp (hdr->frame_control)) { + *aid =0 ; + *queue =2 ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP | +P54_HDR_FLAG_DATA_OUT_NOCANCEL ; +return 0 ; + }else { + *queue =2 ; + ret =0 ; + } + }else { + *queue +=4 ; + ret =1 ; + } + +switch (priv->mode) { +case NL80211_IFTYPE_STATION : + *aid =1 ; +break ; +case NL80211_IFTYPE_AP : +if (is_multicast_ether_addr (hdr->addr1)) { + *aid =0 ; + *queue =3 ; +return 0 ; + } +case NL80211_IFTYPE_ADHOC : +if (info->control.sta) + *aid = info->control.sta->aid; +else + *flags =P54_HDR_FLAG_DATA_OUT_NOCANCEL ; + } +return ret; +} +static int p54_tx (struct ieee80211_hw *dev,struct sk_buff *skb) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);
@@ -909,22 +958,26 @@ static int p54_tx(struct ieee80211_hw *dstruct p54_common *priv = dev->priv;struct p54_hdr *hdr;struct p54_tx_data *txhdr; -size_t padding, len; +size_t padding, len, tim_len;int i, j, ridx; -u16 hdr_flags =0 ; -u8 rate; +u16 hdr_flags =0 , aid =0 ; +u8 rate, queue;u8 cts_rate =0x20 ;u8 rc_flags;u8 calculated_tries[4 ];u8 nrates =0 , nremaining =8 ; - current_queue = &priv->tx_stats[skb_get_queue_mapping (skb) +4 ]; -if (unlikely (current_queue->len > current_queue->limit)) -return NETDEV_TX_BUSY ; - current_queue->len++; - current_queue->count++; -if (current_queue->len == current_queue->limit) -ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + queue =skb_get_queue_mapping (skb); + +if (p54_tx_fill (dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { + current_queue = &priv->tx_stats[queue]; +if (unlikely (current_queue->len > current_queue->limit)) +return NETDEV_TX_BUSY ; + current_queue->len++; + current_queue->count++; +if (current_queue->len == current_queue->limit) +ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + } padding = (unsigned long )(skb->data - (sizeof (*hdr) +sizeof (*txhdr))) &3 ; len = skb->len;
@@ -935,7 +988,7 @@ static int p54_tx(struct ieee80211_hw *dif (padding) hdr_flags |=P54_HDR_FLAG_DATA_ALIGN ; hdr->len =cpu_to_le16 (len); - hdr->type = (info->flags &IEEE80211_TX_CTL_NO_ACK ) ?0 :cpu_to_le16 (1 ); + hdr->type =cpu_to_le16 (aid); hdr->rts_tries = info->control.rates[0 ].count;/*
@@ -1013,7 +1066,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->rts_rate_idx =0 ; txhdr->key_type =0 ; txhdr->key_len =0 ; - txhdr->hw_queue =skb_get_queue_mapping (skb) +4 ; + txhdr->hw_queue = queue; txhdr->backlog =32 ;memset (txhdr->durations,0 ,sizeof (txhdr->durations)); txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
@@ -1024,7 +1077,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->align[0 ] = padding;/* modifies skb->cb and with it info, so must be last! */ -if (unlikely (p54_assign_address (dev, skb, hdr, skb->len))) { +if (unlikely (p54_assign_address (dev, skb, hdr, skb->len + tim_len))) {skb_pull (skb,sizeof (*hdr) +sizeof (*txhdr) + padding);if (current_queue) { current_queue->len--;
Johannes Berg
maintainerdrivers/net/wireless/p54/p54common.c free: · line 944
Quoted 6 lines · Christian Lamparter
drivers/net/wireless/p54/p54common.c +6
-0+case NL80211_IFTYPE_AP : +if (is_multicast_ether_addr (hdr->addr1)) { + *aid =0 ; + *queue =3 ; +return 0 ; + }
Are you sure this is right? I think you should use the mac80211 flag IEEE80211_TX_CTL_SEND_AFTER_DTIM maybe?
Also, there's a flag for IEEE80211_TX_CTL_ASSIGN_SEQ (inverted in firmware) that you should use.
johannes
Quoted 11 lines · On Saturday 18 October 2008 14:21:51 Johannes Berg wrote:
drivers/net/wireless/p54/p54common.c free: · line 944
Quoted 6 lines · Christian Lamparter
drivers/net/wireless/p54/p54common.c +6
-0+case NL80211_IFTYPE_AP : +if (is_multicast_ether_addr (hdr->addr1)) { + *aid =0 ; + *queue =3 ; +return 0 ; + }Are you sure this is right? I think you should use the mac80211 flag
IEEE80211_TX_CTL_SEND_AFTER_DTIMmaybe?
Ack will post updated patches.
Quoted 2 lines
Also, there's a flag for
IEEE80211_TX_CTL_ASSIGN_SEQ(inverted in firmware) that you should use.
?
[PATCH 1/3] p54: more definitions form lmac_longbow.h and pda.h adds in p54_tx(xyz):
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+ hdr_flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
+
+ /* TODO: enable bursting */
+ hdr->flags = cpu_to_le16(hdr_flags);
Regards,
Chr
PATCH v3 2/3 p54: put broadcast frames into the right queues
In reply to Johannes Bergstlc45xx's specs finally brought some light what all the 4 extra queues for. now CAB data and managment frames have their own queue.
---
drivers/net/wireless/p54/p54common.c +67 -15
@@ -902,6 +902,55 @@ free: }EXPORT_SYMBOL_GPL (p54_read_eeprom); +static int p54_tx_fill (struct ieee80211_hw *dev,struct sk_buff *skb, +struct ieee80211_tx_info *info,u8 *queue,size_t *extra_len, +u16 *flags,u16 *aid) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +struct p54_common *priv = dev->priv; +int ret =0 ; + +if (unlikely (ieee80211_is_mgmt (hdr->frame_control))) { +if (ieee80211_is_beacon (hdr->frame_control)) { + *aid =0 ; + *queue =0 ; + *extra_len =IEEE80211_MAX_TIM_LEN ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP ; +return 0 ; + }else if (ieee80211_is_probe_resp (hdr->frame_control)) { + *aid =0 ; + *queue =2 ; + *flags =P54_HDR_FLAG_DATA_OUT_TIMESTAMP | +P54_HDR_FLAG_DATA_OUT_NOCANCEL ; +return 0 ; + }else { + *queue =2 ; + ret =0 ; + } + }else { + *queue +=4 ; + ret =1 ; + } + +switch (priv->mode) { +case NL80211_IFTYPE_STATION : + *aid =1 ; +break ; +case NL80211_IFTYPE_AP : +case NL80211_IFTYPE_ADHOC : +if (info->flags &IEEE80211_TX_CTL_SEND_AFTER_DTIM ) { + *aid =0 ; + *queue =3 ; +return 0 ; + } +if (info->control.sta) + *aid = info->control.sta->aid; +else + *flags =P54_HDR_FLAG_DATA_OUT_NOCANCEL ; + } +return ret; +} +static int p54_tx (struct ieee80211_hw *dev,struct sk_buff *skb) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);
@@ -909,22 +958,26 @@ static int p54_tx(struct ieee80211_hw *dstruct p54_common *priv = dev->priv;struct p54_hdr *hdr;struct p54_tx_data *txhdr; -size_t padding, len; +size_t padding, len, tim_len;int i, j, ridx; -u16 hdr_flags =0 ; -u8 rate; +u16 hdr_flags =0 , aid =0 ; +u8 rate, queue;u8 cts_rate =0x20 ;u8 rc_flags;u8 calculated_tries[4 ];u8 nrates =0 , nremaining =8 ; - current_queue = &priv->tx_stats[skb_get_queue_mapping (skb) +4 ]; -if (unlikely (current_queue->len > current_queue->limit)) -return NETDEV_TX_BUSY ; - current_queue->len++; - current_queue->count++; -if (current_queue->len == current_queue->limit) -ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + queue =skb_get_queue_mapping (skb); + +if (p54_tx_fill (dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { + current_queue = &priv->tx_stats[queue]; +if (unlikely (current_queue->len > current_queue->limit)) +return NETDEV_TX_BUSY ; + current_queue->len++; + current_queue->count++; +if (current_queue->len == current_queue->limit) +ieee80211_stop_queue (dev,skb_get_queue_mapping (skb)); + } padding = (unsigned long )(skb->data - (sizeof (*hdr) +sizeof (*txhdr))) &3 ; len = skb->len;
@@ -935,7 +988,7 @@ static int p54_tx(struct ieee80211_hw *dif (padding) hdr_flags |=P54_HDR_FLAG_DATA_ALIGN ; hdr->len =cpu_to_le16 (len); - hdr->type = (info->flags &IEEE80211_TX_CTL_NO_ACK ) ?0 :cpu_to_le16 (1 ); + hdr->type =cpu_to_le16 (aid); hdr->rts_tries = info->control.rates[0 ].count;/*
@@ -1013,7 +1066,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->rts_rate_idx =0 ; txhdr->key_type =0 ; txhdr->key_len =0 ; - txhdr->hw_queue =skb_get_queue_mapping (skb) +4 ; + txhdr->hw_queue = queue; txhdr->backlog =32 ;memset (txhdr->durations,0 ,sizeof (txhdr->durations)); txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
@@ -1024,7 +1077,7 @@ static int p54_tx(struct ieee80211_hw *d txhdr->align[0 ] = padding;/* modifies skb->cb and with it info, so must be last! */ -if (unlikely (p54_assign_address (dev, skb, hdr, skb->len))) { +if (unlikely (p54_assign_address (dev, skb, hdr, skb->len + tim_len))) {skb_pull (skb,sizeof (*hdr) +sizeof (*txhdr) + padding);if (current_queue) { current_queue->len--;
@@ -1509,8 +1562,7 @@ struct ieee80211_hw *p54_init_common(siz priv = dev->priv; priv->mode =NL80211_IFTYPE_UNSPECIFIED ;skb_queue_head_init (&priv->tx_queue); - dev->flags =IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |/* not sure */ -IEEE80211_HW_RX_INCLUDES_FCS | + dev->flags =IEEE80211_HW_RX_INCLUDES_FCS |IEEE80211_HW_SIGNAL_DBM |IEEE80211_HW_NOISE_DBM ;
Quoted 4 lines · Christian Lamparter
stlc45xx's specs finally brought some light what all the 4 extra queues for. now CAB data and managment frames have their own queue.
Signed-off-by Christian Lamparter <[email protected]>
Doesn't apply...
Signature · 2 lines
John W. Linville Linux should be at the core [email protected] of your literate lifestyle.