diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 30 |
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 | } |
176 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); | 164 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); |