aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-10-18 17:18:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-10 15:10:16 -0500
commit94585b090baf982a850678a1dc3395bce0c1e302 (patch)
treed77c0abac8629b6c73b8e5d44b516b1cefe90f7d /drivers/net/wireless/p54
parent9e7f3f8e4acdc480584d6b5e6a6be5d1f7bda8fa (diff)
p54: put broadcast frames into the right queues
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 <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r--drivers/net/wireless/p54/p54common.c82
1 files changed, 67 insertions, 15 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index ae8d1f666314..e93bca8263cd 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -902,6 +902,55 @@ free:
902} 902}
903EXPORT_SYMBOL_GPL(p54_read_eeprom); 903EXPORT_SYMBOL_GPL(p54_read_eeprom);
904 904
905static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
906 struct ieee80211_tx_info *info, u8 *queue, size_t *extra_len,
907 u16 *flags, u16 *aid)
908{
909 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
910 struct p54_common *priv = dev->priv;
911 int ret = 0;
912
913 if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
914 if (ieee80211_is_beacon(hdr->frame_control)) {
915 *aid = 0;
916 *queue = 0;
917 *extra_len = IEEE80211_MAX_TIM_LEN;
918 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
919 return 0;
920 } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
921 *aid = 0;
922 *queue = 2;
923 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
924 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
925 return 0;
926 } else {
927 *queue = 2;
928 ret = 0;
929 }
930 } else {
931 *queue += 4;
932 ret = 1;
933 }
934
935 switch (priv->mode) {
936 case NL80211_IFTYPE_STATION:
937 *aid = 1;
938 break;
939 case NL80211_IFTYPE_AP:
940 case NL80211_IFTYPE_ADHOC:
941 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
942 *aid = 0;
943 *queue = 3;
944 return 0;
945 }
946 if (info->control.sta)
947 *aid = info->control.sta->aid;
948 else
949 *flags = P54_HDR_FLAG_DATA_OUT_NOCANCEL;
950 }
951 return ret;
952}
953
905static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 954static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
906{ 955{
907 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 956 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -909,22 +958,26 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
909 struct p54_common *priv = dev->priv; 958 struct p54_common *priv = dev->priv;
910 struct p54_hdr *hdr; 959 struct p54_hdr *hdr;
911 struct p54_tx_data *txhdr; 960 struct p54_tx_data *txhdr;
912 size_t padding, len; 961 size_t padding, len, tim_len;
913 int i, j, ridx; 962 int i, j, ridx;
914 u16 hdr_flags = 0; 963 u16 hdr_flags = 0, aid = 0;
915 u8 rate; 964 u8 rate, queue;
916 u8 cts_rate = 0x20; 965 u8 cts_rate = 0x20;
917 u8 rc_flags; 966 u8 rc_flags;
918 u8 calculated_tries[4]; 967 u8 calculated_tries[4];
919 u8 nrates = 0, nremaining = 8; 968 u8 nrates = 0, nremaining = 8;
920 969
921 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb) + 4]; 970 queue = skb_get_queue_mapping(skb);
922 if (unlikely(current_queue->len > current_queue->limit)) 971
923 return NETDEV_TX_BUSY; 972 if (p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) {
924 current_queue->len++; 973 current_queue = &priv->tx_stats[queue];
925 current_queue->count++; 974 if (unlikely(current_queue->len > current_queue->limit))
926 if (current_queue->len == current_queue->limit) 975 return NETDEV_TX_BUSY;
927 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); 976 current_queue->len++;
977 current_queue->count++;
978 if (current_queue->len == current_queue->limit)
979 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
980 }
928 981
929 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; 982 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
930 len = skb->len; 983 len = skb->len;
@@ -935,7 +988,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
935 if (padding) 988 if (padding)
936 hdr_flags |= P54_HDR_FLAG_DATA_ALIGN; 989 hdr_flags |= P54_HDR_FLAG_DATA_ALIGN;
937 hdr->len = cpu_to_le16(len); 990 hdr->len = cpu_to_le16(len);
938 hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1); 991 hdr->type = cpu_to_le16(aid);
939 hdr->rts_tries = info->control.rates[0].count; 992 hdr->rts_tries = info->control.rates[0].count;
940 993
941 /* 994 /*
@@ -1013,7 +1066,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
1013 txhdr->rts_rate_idx = 0; 1066 txhdr->rts_rate_idx = 0;
1014 txhdr->key_type = 0; 1067 txhdr->key_type = 0;
1015 txhdr->key_len = 0; 1068 txhdr->key_len = 0;
1016 txhdr->hw_queue = skb_get_queue_mapping(skb) + 4; 1069 txhdr->hw_queue = queue;
1017 txhdr->backlog = 32; 1070 txhdr->backlog = 32;
1018 memset(txhdr->durations, 0, sizeof(txhdr->durations)); 1071 memset(txhdr->durations, 0, sizeof(txhdr->durations));
1019 txhdr->tx_antenna = (info->antenna_sel_tx == 0) ? 1072 txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
@@ -1024,7 +1077,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
1024 txhdr->align[0] = padding; 1077 txhdr->align[0] = padding;
1025 1078
1026 /* modifies skb->cb and with it info, so must be last! */ 1079 /* modifies skb->cb and with it info, so must be last! */
1027 if (unlikely(p54_assign_address(dev, skb, hdr, skb->len))) { 1080 if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len))) {
1028 skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding); 1081 skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
1029 if (current_queue) { 1082 if (current_queue) {
1030 current_queue->len--; 1083 current_queue->len--;
@@ -1509,8 +1562,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1509 priv = dev->priv; 1562 priv = dev->priv;
1510 priv->mode = NL80211_IFTYPE_UNSPECIFIED; 1563 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
1511 skb_queue_head_init(&priv->tx_queue); 1564 skb_queue_head_init(&priv->tx_queue);
1512 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ 1565 dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1513 IEEE80211_HW_RX_INCLUDES_FCS |
1514 IEEE80211_HW_SIGNAL_DBM | 1566 IEEE80211_HW_SIGNAL_DBM |
1515 IEEE80211_HW_NOISE_DBM; 1567 IEEE80211_HW_NOISE_DBM;
1516 1568