aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c30
1 files changed, 9 insertions, 21 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b02dbc8a666e..c90992f613fe 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -34,7 +34,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
34 struct sk_buff *frag_skb) 34 struct sk_buff *frag_skb)
35{ 35{
36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); 36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
37 struct skb_frame_desc *skbdesc;
38 struct ieee80211_tx_info *rts_info; 37 struct ieee80211_tx_info *rts_info;
39 struct sk_buff *skb; 38 struct sk_buff *skb;
40 int size; 39 int size;
@@ -65,6 +64,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
65 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); 64 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
66 rts_info = IEEE80211_SKB_CB(skb); 65 rts_info = IEEE80211_SKB_CB(skb);
67 rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; 66 rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
67 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; 68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; 69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
70 70
@@ -82,14 +82,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
82 frag_skb->data, size, tx_info, 82 frag_skb->data, size, tx_info,
83 (struct ieee80211_rts *)(skb->data)); 83 (struct ieee80211_rts *)(skb->data));
84 84
85 /* 85 if (rt2x00queue_write_tx_frame(queue, skb)) {
86 * Initialize skb descriptor
87 */
88 skbdesc = get_skb_frame_desc(skb);
89 memset(skbdesc, 0, sizeof(*skbdesc));
90 skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
91
92 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
93 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); 86 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
94 return NETDEV_TX_BUSY; 87 return NETDEV_TX_BUSY;
95 } 88 }
@@ -135,18 +128,16 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
135 } 128 }
136 129
137 /* 130 /*
138 * If CTS/RTS is required. and this frame is not CTS or RTS, 131 * If CTS/RTS is required. create and queue that frame first.
139 * create and queue that frame first. But make sure we have 132 * Make sure we have at least enough entries available to send
140 * at least enough entries available to send this CTS/RTS 133 * this CTS/RTS frame as well as the data frame.
141 * frame as well as the data frame.
142 * Note that when the driver has set the set_rts_threshold() 134 * Note that when the driver has set the set_rts_threshold()
143 * callback function it doesn't need software generation of 135 * callback function it doesn't need software generation of
144 * neither RTS or CTS-to-self frames and handles everything 136 * either RTS or CTS-to-self frame and handles everything
145 * inside the hardware. 137 * inside the hardware.
146 */ 138 */
147 frame_control = le16_to_cpu(ieee80211hdr->frame_control); 139 frame_control = le16_to_cpu(ieee80211hdr->frame_control);
148 if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && 140 if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
149 (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
150 IEEE80211_TX_CTL_USE_CTS_PROTECT)) && 141 IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
151 !rt2x00dev->ops->hw->set_rts_threshold) { 142 !rt2x00dev->ops->hw->set_rts_threshold) {
152 if (rt2x00queue_available(queue) <= 1) { 143 if (rt2x00queue_available(queue) <= 1) {
@@ -160,17 +151,14 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
160 } 151 }
161 } 152 }
162 153
163 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { 154 if (rt2x00queue_write_tx_frame(queue, skb)) {
164 ieee80211_stop_queue(rt2x00dev->hw, qid); 155 ieee80211_stop_queue(rt2x00dev->hw, qid);
165 return NETDEV_TX_BUSY; 156 return NETDEV_TX_BUSY;
166 } 157 }
167 158
168 if (rt2x00queue_full(queue)) 159 if (rt2x00queue_threshold(queue))
169 ieee80211_stop_queue(rt2x00dev->hw, qid); 160 ieee80211_stop_queue(rt2x00dev->hw, qid);
170 161
171 if (rt2x00dev->ops->lib->kick_tx_queue)
172 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
173
174 return NETDEV_TX_OK; 162 return NETDEV_TX_OK;
175} 163}
176EXPORT_SYMBOL_GPL(rt2x00mac_tx); 164EXPORT_SYMBOL_GPL(rt2x00mac_tx);