diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/pio.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.h | 2 |
5 files changed, 59 insertions, 11 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 83161d9af813..6e08405e8026 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -1164,7 +1164,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1164 | { | 1164 | { |
1165 | const struct b43legacy_dma_ops *ops = ring->ops; | 1165 | const struct b43legacy_dma_ops *ops = ring->ops; |
1166 | u8 *header; | 1166 | u8 *header; |
1167 | int slot; | 1167 | int slot, old_top_slot, old_used_slots; |
1168 | int err; | 1168 | int err; |
1169 | struct b43legacy_dmadesc_generic *desc; | 1169 | struct b43legacy_dmadesc_generic *desc; |
1170 | struct b43legacy_dmadesc_meta *meta; | 1170 | struct b43legacy_dmadesc_meta *meta; |
@@ -1174,6 +1174,9 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1174 | #define SLOTS_PER_PACKET 2 | 1174 | #define SLOTS_PER_PACKET 2 |
1175 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); | 1175 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); |
1176 | 1176 | ||
1177 | old_top_slot = ring->current_slot; | ||
1178 | old_used_slots = ring->used_slots; | ||
1179 | |||
1177 | /* Get a slot for the header. */ | 1180 | /* Get a slot for the header. */ |
1178 | slot = request_slot(ring); | 1181 | slot = request_slot(ring); |
1179 | desc = ops->idx2desc(ring, slot, &meta_hdr); | 1182 | desc = ops->idx2desc(ring, slot, &meta_hdr); |
@@ -1181,9 +1184,14 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1181 | 1184 | ||
1182 | header = &(ring->txhdr_cache[slot * sizeof( | 1185 | header = &(ring->txhdr_cache[slot * sizeof( |
1183 | struct b43legacy_txhdr_fw3)]); | 1186 | struct b43legacy_txhdr_fw3)]); |
1184 | b43legacy_generate_txhdr(ring->dev, header, | 1187 | err = b43legacy_generate_txhdr(ring->dev, header, |
1185 | skb->data, skb->len, ctl, | 1188 | skb->data, skb->len, ctl, |
1186 | generate_cookie(ring, slot)); | 1189 | generate_cookie(ring, slot)); |
1190 | if (unlikely(err)) { | ||
1191 | ring->current_slot = old_top_slot; | ||
1192 | ring->used_slots = old_used_slots; | ||
1193 | return err; | ||
1194 | } | ||
1187 | 1195 | ||
1188 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, | 1196 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, |
1189 | sizeof(struct b43legacy_txhdr_fw3), 1); | 1197 | sizeof(struct b43legacy_txhdr_fw3), 1); |
@@ -1206,6 +1214,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1206 | if (dma_mapping_error(meta->dmaaddr)) { | 1214 | if (dma_mapping_error(meta->dmaaddr)) { |
1207 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1215 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
1208 | if (!bounce_skb) { | 1216 | if (!bounce_skb) { |
1217 | ring->current_slot = old_top_slot; | ||
1218 | ring->used_slots = old_used_slots; | ||
1209 | err = -ENOMEM; | 1219 | err = -ENOMEM; |
1210 | goto out_unmap_hdr; | 1220 | goto out_unmap_hdr; |
1211 | } | 1221 | } |
@@ -1216,6 +1226,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1216 | meta->skb = skb; | 1226 | meta->skb = skb; |
1217 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1227 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1218 | if (dma_mapping_error(meta->dmaaddr)) { | 1228 | if (dma_mapping_error(meta->dmaaddr)) { |
1229 | ring->current_slot = old_top_slot; | ||
1230 | ring->used_slots = old_used_slots; | ||
1219 | err = -EIO; | 1231 | err = -EIO; |
1220 | goto out_free_bounce; | 1232 | goto out_free_bounce; |
1221 | } | 1233 | } |
@@ -1282,6 +1294,13 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, | |||
1282 | B43legacy_BUG_ON(ring->stopped); | 1294 | B43legacy_BUG_ON(ring->stopped); |
1283 | 1295 | ||
1284 | err = dma_tx_fragment(ring, skb, ctl); | 1296 | err = dma_tx_fragment(ring, skb, ctl); |
1297 | if (unlikely(err == -ENOKEY)) { | ||
1298 | /* Drop this packet, as we don't have the encryption key | ||
1299 | * anymore and must not transmit it unencrypted. */ | ||
1300 | dev_kfree_skb_any(skb); | ||
1301 | err = 0; | ||
1302 | goto out_unlock; | ||
1303 | } | ||
1285 | if (unlikely(err)) { | 1304 | if (unlikely(err)) { |
1286 | b43legacyerr(dev->wl, "DMA tx mapping failure\n"); | 1305 | b43legacyerr(dev->wl, "DMA tx mapping failure\n"); |
1287 | goto out_unlock; | 1306 | goto out_unlock; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index aa20d5d56e2f..53f7f2e97615 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3160,8 +3160,6 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) | |||
3160 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4); | 3160 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4); |
3161 | 3161 | ||
3162 | ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ | 3162 | ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ |
3163 | memset(wl->bssid, 0, ETH_ALEN); | ||
3164 | memset(wl->mac_addr, 0, ETH_ALEN); | ||
3165 | b43legacy_upload_card_macaddress(dev); | 3163 | b43legacy_upload_card_macaddress(dev); |
3166 | b43legacy_security_init(dev); | 3164 | b43legacy_security_init(dev); |
3167 | b43legacy_rng_init(wl); | 3165 | b43legacy_rng_init(wl); |
@@ -3263,6 +3261,13 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3263 | * LEDs that are registered later depend on it. */ | 3261 | * LEDs that are registered later depend on it. */ |
3264 | b43legacy_rfkill_init(dev); | 3262 | b43legacy_rfkill_init(dev); |
3265 | 3263 | ||
3264 | /* Kill all old instance specific information to make sure | ||
3265 | * the card won't use it in the short timeframe between start | ||
3266 | * and mac80211 reconfiguring it. */ | ||
3267 | memset(wl->bssid, 0, ETH_ALEN); | ||
3268 | memset(wl->mac_addr, 0, ETH_ALEN); | ||
3269 | wl->filter_flags = 0; | ||
3270 | |||
3266 | mutex_lock(&wl->mutex); | 3271 | mutex_lock(&wl->mutex); |
3267 | 3272 | ||
3268 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { | 3273 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { |
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index e4f4c5c39e33..bcdd54eb2edb 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c | |||
@@ -181,7 +181,7 @@ union txhdr_union { | |||
181 | struct b43legacy_txhdr_fw3 txhdr_fw3; | 181 | struct b43legacy_txhdr_fw3 txhdr_fw3; |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue, | 184 | static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue, |
185 | struct sk_buff *skb, | 185 | struct sk_buff *skb, |
186 | struct b43legacy_pio_txpacket *packet, | 186 | struct b43legacy_pio_txpacket *packet, |
187 | size_t txhdr_size) | 187 | size_t txhdr_size) |
@@ -189,14 +189,17 @@ static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue, | |||
189 | union txhdr_union txhdr_data; | 189 | union txhdr_union txhdr_data; |
190 | u8 *txhdr = NULL; | 190 | u8 *txhdr = NULL; |
191 | unsigned int octets; | 191 | unsigned int octets; |
192 | int err; | ||
192 | 193 | ||
193 | txhdr = (u8 *)(&txhdr_data.txhdr_fw3); | 194 | txhdr = (u8 *)(&txhdr_data.txhdr_fw3); |
194 | 195 | ||
195 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); | 196 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); |
196 | b43legacy_generate_txhdr(queue->dev, | 197 | err = b43legacy_generate_txhdr(queue->dev, |
197 | txhdr, skb->data, skb->len, | 198 | txhdr, skb->data, skb->len, |
198 | &packet->txstat.control, | 199 | &packet->txstat.control, |
199 | generate_cookie(queue, packet)); | 200 | generate_cookie(queue, packet)); |
201 | if (err) | ||
202 | return err; | ||
200 | 203 | ||
201 | tx_start(queue); | 204 | tx_start(queue); |
202 | octets = skb->len + txhdr_size; | 205 | octets = skb->len + txhdr_size; |
@@ -204,6 +207,8 @@ static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue, | |||
204 | octets--; | 207 | octets--; |
205 | tx_data(queue, txhdr, (u8 *)skb->data, octets); | 208 | tx_data(queue, txhdr, (u8 *)skb->data, octets); |
206 | tx_complete(queue, skb); | 209 | tx_complete(queue, skb); |
210 | |||
211 | return 0; | ||
207 | } | 212 | } |
208 | 213 | ||
209 | static void free_txpacket(struct b43legacy_pio_txpacket *packet, | 214 | static void free_txpacket(struct b43legacy_pio_txpacket *packet, |
@@ -226,6 +231,7 @@ static int pio_tx_packet(struct b43legacy_pio_txpacket *packet) | |||
226 | struct b43legacy_pioqueue *queue = packet->queue; | 231 | struct b43legacy_pioqueue *queue = packet->queue; |
227 | struct sk_buff *skb = packet->skb; | 232 | struct sk_buff *skb = packet->skb; |
228 | u16 octets; | 233 | u16 octets; |
234 | int err; | ||
229 | 235 | ||
230 | octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3); | 236 | octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3); |
231 | if (queue->tx_devq_size < octets) { | 237 | if (queue->tx_devq_size < octets) { |
@@ -247,8 +253,14 @@ static int pio_tx_packet(struct b43legacy_pio_txpacket *packet) | |||
247 | if (queue->tx_devq_used + octets > queue->tx_devq_size) | 253 | if (queue->tx_devq_used + octets > queue->tx_devq_size) |
248 | return -EBUSY; | 254 | return -EBUSY; |
249 | /* Now poke the device. */ | 255 | /* Now poke the device. */ |
250 | pio_tx_write_fragment(queue, skb, packet, | 256 | err = pio_tx_write_fragment(queue, skb, packet, |
251 | sizeof(struct b43legacy_txhdr_fw3)); | 257 | sizeof(struct b43legacy_txhdr_fw3)); |
258 | if (unlikely(err == -ENOKEY)) { | ||
259 | /* Drop this packet, as we don't have the encryption key | ||
260 | * anymore and must not transmit it unencrypted. */ | ||
261 | free_txpacket(packet, 1); | ||
262 | return 0; | ||
263 | } | ||
252 | 264 | ||
253 | /* Account for the packet size. | 265 | /* Account for the packet size. |
254 | * (We must not overflow the device TX queue) | 266 | * (We must not overflow the device TX queue) |
@@ -486,6 +498,9 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, | |||
486 | queue = parse_cookie(dev, status->cookie, &packet); | 498 | queue = parse_cookie(dev, status->cookie, &packet); |
487 | B43legacy_WARN_ON(!queue); | 499 | B43legacy_WARN_ON(!queue); |
488 | 500 | ||
501 | if (!packet->skb) | ||
502 | return; | ||
503 | |||
489 | queue->tx_devq_packets--; | 504 | queue->tx_devq_packets--; |
490 | queue->tx_devq_used -= (packet->skb->len + | 505 | queue->tx_devq_used -= (packet->skb->len + |
491 | sizeof(struct b43legacy_txhdr_fw3)); | 506 | sizeof(struct b43legacy_txhdr_fw3)); |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index e20c552442d5..d84408a82db9 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -181,7 +181,7 @@ static u8 b43legacy_calc_fallback_rate(u8 bitrate) | |||
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
183 | 183 | ||
184 | static void generate_txhdr_fw3(struct b43legacy_wldev *dev, | 184 | static int generate_txhdr_fw3(struct b43legacy_wldev *dev, |
185 | struct b43legacy_txhdr_fw3 *txhdr, | 185 | struct b43legacy_txhdr_fw3 *txhdr, |
186 | const unsigned char *fragment_data, | 186 | const unsigned char *fragment_data, |
187 | unsigned int fragment_len, | 187 | unsigned int fragment_len, |
@@ -252,6 +252,13 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
252 | iv_len = min((size_t)txctl->iv_len, | 252 | iv_len = min((size_t)txctl->iv_len, |
253 | ARRAY_SIZE(txhdr->iv)); | 253 | ARRAY_SIZE(txhdr->iv)); |
254 | memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); | 254 | memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); |
255 | } else { | ||
256 | /* This key is invalid. This might only happen | ||
257 | * in a short timeframe after machine resume before | ||
258 | * we were able to reconfigure keys. | ||
259 | * Drop this packet completely. Do not transmit it | ||
260 | * unencrypted to avoid leaking information. */ | ||
261 | return -ENOKEY; | ||
255 | } | 262 | } |
256 | } | 263 | } |
257 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 264 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) |
@@ -345,16 +352,18 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
345 | /* Apply the bitfields */ | 352 | /* Apply the bitfields */ |
346 | txhdr->mac_ctl = cpu_to_le32(mac_ctl); | 353 | txhdr->mac_ctl = cpu_to_le32(mac_ctl); |
347 | txhdr->phy_ctl = cpu_to_le16(phy_ctl); | 354 | txhdr->phy_ctl = cpu_to_le16(phy_ctl); |
355 | |||
356 | return 0; | ||
348 | } | 357 | } |
349 | 358 | ||
350 | void b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | 359 | int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, |
351 | u8 *txhdr, | 360 | u8 *txhdr, |
352 | const unsigned char *fragment_data, | 361 | const unsigned char *fragment_data, |
353 | unsigned int fragment_len, | 362 | unsigned int fragment_len, |
354 | const struct ieee80211_tx_control *txctl, | 363 | const struct ieee80211_tx_control *txctl, |
355 | u16 cookie) | 364 | u16 cookie) |
356 | { | 365 | { |
357 | generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, | 366 | return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, |
358 | fragment_data, fragment_len, | 367 | fragment_data, fragment_len, |
359 | txctl, cookie); | 368 | txctl, cookie); |
360 | } | 369 | } |
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index 8a155d0a5d1f..bab47928a0c9 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h | |||
@@ -76,7 +76,7 @@ struct b43legacy_txhdr_fw3 { | |||
76 | 76 | ||
77 | 77 | ||
78 | 78 | ||
79 | void b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | 79 | int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, |
80 | u8 *txhdr, | 80 | u8 *txhdr, |
81 | const unsigned char *fragment_data, | 81 | const unsigned char *fragment_data, |
82 | unsigned int fragment_len, | 82 | unsigned int fragment_len, |