aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/p54/p54common.c73
-rw-r--r--drivers/net/wireless/p54/p54common.h2
2 files changed, 49 insertions, 26 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 602392628e4e..de92b58d4508 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -652,6 +652,10 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
652 __skb_unlink(entry, &priv->tx_queue); 652 __skb_unlink(entry, &priv->tx_queue);
653 spin_unlock_irqrestore(&priv->tx_queue.lock, flags); 653 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
654 654
655 entry_hdr = (struct p54_hdr *) entry->data;
656 entry_data = (struct p54_tx_data *) entry_hdr->data;
657 priv->tx_stats[entry_data->hw_queue].len--;
658
655 if (unlikely(entry == priv->cached_beacon)) { 659 if (unlikely(entry == priv->cached_beacon)) {
656 kfree_skb(entry); 660 kfree_skb(entry);
657 priv->cached_beacon = NULL; 661 priv->cached_beacon = NULL;
@@ -668,8 +672,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
668 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, 672 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
669 status.ampdu_ack_len) != 23); 673 status.ampdu_ack_len) != 23);
670 674
671 entry_hdr = (struct p54_hdr *) entry->data;
672 entry_data = (struct p54_tx_data *) entry_hdr->data;
673 if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) 675 if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
674 pad = entry_data->align[0]; 676 pad = entry_data->align[0];
675 677
@@ -687,7 +689,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
687 } 689 }
688 } 690 }
689 691
690 priv->tx_stats[entry_data->hw_queue].len--;
691 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && 692 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
692 (!payload->status)) 693 (!payload->status))
693 info->flags |= IEEE80211_TX_STAT_ACK; 694 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1004,6 +1005,38 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
1004 return 0; 1005 return 0;
1005} 1006}
1006 1007
1008static void p54_sta_notify_ps(struct ieee80211_hw *dev,
1009 enum sta_notify_ps_cmd notify_cmd,
1010 struct ieee80211_sta *sta)
1011{
1012 switch (notify_cmd) {
1013 case STA_NOTIFY_AWAKE:
1014 p54_sta_unlock(dev, sta->addr);
1015 break;
1016 default:
1017 break;
1018 }
1019}
1020
1021static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
1022 enum sta_notify_cmd notify_cmd,
1023 struct ieee80211_sta *sta)
1024{
1025 switch (notify_cmd) {
1026 case STA_NOTIFY_ADD:
1027 case STA_NOTIFY_REMOVE:
1028 /*
1029 * Notify the firmware that we don't want or we don't
1030 * need to buffer frames for this station anymore.
1031 */
1032
1033 p54_sta_unlock(dev, sta->addr);
1034 break;
1035 default:
1036 break;
1037 }
1038}
1039
1007static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry) 1040static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
1008{ 1041{
1009 struct p54_common *priv = dev->priv; 1042 struct p54_common *priv = dev->priv;
@@ -1069,7 +1102,7 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
1069 if (info->control.sta) 1102 if (info->control.sta)
1070 *aid = info->control.sta->aid; 1103 *aid = info->control.sta->aid;
1071 else 1104 else
1072 *flags = P54_HDR_FLAG_DATA_OUT_NOCANCEL; 1105 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
1073 } 1106 }
1074 return ret; 1107 return ret;
1075} 1108}
@@ -1082,7 +1115,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
1082 struct p54_hdr *hdr; 1115 struct p54_hdr *hdr;
1083 struct p54_tx_data *txhdr; 1116 struct p54_tx_data *txhdr;
1084 size_t padding, len, tim_len = 0; 1117 size_t padding, len, tim_len = 0;
1085 int i, j, ridx; 1118 int i, j, ridx, ret;
1086 u16 hdr_flags = 0, aid = 0; 1119 u16 hdr_flags = 0, aid = 0;
1087 u8 rate, queue; 1120 u8 rate, queue;
1088 u8 cts_rate = 0x20; 1121 u8 cts_rate = 0x20;
@@ -1092,30 +1125,18 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
1092 1125
1093 queue = skb_get_queue_mapping(skb); 1126 queue = skb_get_queue_mapping(skb);
1094 1127
1095 if (p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { 1128 ret = p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid);
1096 current_queue = &priv->tx_stats[queue]; 1129 current_queue = &priv->tx_stats[queue];
1097 if (unlikely(current_queue->len > current_queue->limit)) 1130 if (unlikely((current_queue->len > current_queue->limit) && ret))
1098 return NETDEV_TX_BUSY; 1131 return NETDEV_TX_BUSY;
1099 current_queue->len++; 1132 current_queue->len++;
1100 current_queue->count++; 1133 current_queue->count++;
1101 if (current_queue->len == current_queue->limit) 1134 if ((current_queue->len == current_queue->limit) && ret)
1102 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); 1135 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
1103 }
1104 1136
1105 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; 1137 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
1106 len = skb->len; 1138 len = skb->len;
1107 1139
1108 if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) {
1109 if (info->control.sta)
1110 if (p54_sta_unlock(dev, info->control.sta->addr)) {
1111 if (current_queue) {
1112 current_queue->len--;
1113 current_queue->count--;
1114 }
1115 return NETDEV_TX_BUSY;
1116 }
1117 }
1118
1119 txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding); 1140 txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding);
1120 hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr)); 1141 hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr));
1121 1142
@@ -1834,6 +1855,8 @@ static const struct ieee80211_ops p54_ops = {
1834 .add_interface = p54_add_interface, 1855 .add_interface = p54_add_interface,
1835 .remove_interface = p54_remove_interface, 1856 .remove_interface = p54_remove_interface,
1836 .set_tim = p54_set_tim, 1857 .set_tim = p54_set_tim,
1858 .sta_notify_ps = p54_sta_notify_ps,
1859 .sta_notify = p54_sta_notify,
1837 .config = p54_config, 1860 .config = p54_config,
1838 .config_interface = p54_config_interface, 1861 .config_interface = p54_config_interface,
1839 .bss_info_changed = p54_bss_info_changed, 1862 .bss_info_changed = p54_bss_info_changed,
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 3419f16be938..d292ffbec08c 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -302,7 +302,7 @@ enum p54_frame_sent_status {
302 P54_TX_OK = 0, 302 P54_TX_OK = 0,
303 P54_TX_FAILED, 303 P54_TX_FAILED,
304 P54_TX_PSM, 304 P54_TX_PSM,
305 P54_TX_PSM_CANCELLED 305 P54_TX_PSM_CANCELLED = 4
306}; 306};
307 307
308struct p54_frame_sent { 308struct p54_frame_sent {