diff options
| author | Jeff Garzik <jeff@garzik.org> | 2006-04-26 06:16:50 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-04-26 06:16:50 -0400 |
| commit | 3b908870b8332dfd40be0e919e187aa4991536fb (patch) | |
| tree | cb7cc30d04e647902b8c6cfac840626a4d09e770 | |
| parent | 3b85418bc998876ce46784fb49f243100b2dd909 (diff) | |
| parent | 7c241d37fe0e6442c5cf3b5d73f7f58f2dc66352 (diff) | |
Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream-fixes
| -rw-r--r-- | MAINTAINERS | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_pio.c | 92 | ||||
| -rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_pio.h | 16 | ||||
| -rw-r--r-- | drivers/net/wireless/hostap/hostap_ioctl.c | 4 | ||||
| -rw-r--r-- | include/net/ieee80211softmac.h | 5 | ||||
| -rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 20 | ||||
| -rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 2 | ||||
| -rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 27 |
9 files changed, 133 insertions, 49 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 4e1e8175eb6d..d6a8e5b434ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -421,6 +421,14 @@ L: linux-hams@vger.kernel.org | |||
| 421 | W: http://www.baycom.org/~tom/ham/ham.html | 421 | W: http://www.baycom.org/~tom/ham/ham.html |
| 422 | S: Maintained | 422 | S: Maintained |
| 423 | 423 | ||
| 424 | BCM43XX WIRELESS DRIVER | ||
| 425 | P: Michael Buesch | ||
| 426 | M: mb@bu3sch.de | ||
| 427 | P: Stefano Brivio | ||
| 428 | M: st3@riseup.net | ||
| 429 | W: http://bcm43xx.berlios.de/ | ||
| 430 | S: Maintained | ||
| 431 | |||
| 424 | BEFS FILE SYSTEM | 432 | BEFS FILE SYSTEM |
| 425 | P: Sergey S. Kostyliov | 433 | P: Sergey S. Kostyliov |
| 426 | M: rathamahata@php4.ru | 434 | M: rathamahata@php4.ru |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index 2d520e4b0276..b7d77638ba8c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h | |||
| @@ -213,6 +213,14 @@ static inline | |||
| 213 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) | 213 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) |
| 214 | { | 214 | { |
| 215 | } | 215 | } |
| 216 | static inline | ||
| 217 | void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring) | ||
| 218 | { | ||
| 219 | } | ||
| 220 | static inline | ||
| 221 | void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) | ||
| 222 | { | ||
| 223 | } | ||
| 216 | 224 | ||
| 217 | #endif /* CONFIG_BCM43XX_DMA */ | 225 | #endif /* CONFIG_BCM43XX_DMA */ |
| 218 | #endif /* BCM43xx_DMA_H_ */ | 226 | #endif /* BCM43xx_DMA_H_ */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index c59ddd40680d..0aa1bd269a25 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include "bcm43xx_pio.h" | 27 | #include "bcm43xx_pio.h" |
| 28 | #include "bcm43xx_main.h" | 28 | #include "bcm43xx_main.h" |
| 29 | #include "bcm43xx_xmit.h" | 29 | #include "bcm43xx_xmit.h" |
| 30 | #include "bcm43xx_power.h" | ||
| 30 | 31 | ||
| 31 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
| 32 | 33 | ||
| @@ -44,10 +45,10 @@ static void tx_octet(struct bcm43xx_pioqueue *queue, | |||
| 44 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 45 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
| 45 | octet); | 46 | octet); |
| 46 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 47 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
| 47 | BCM43xx_PIO_TXCTL_WRITEHI); | 48 | BCM43xx_PIO_TXCTL_WRITELO); |
| 48 | } else { | 49 | } else { |
| 49 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 50 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
| 50 | BCM43xx_PIO_TXCTL_WRITEHI); | 51 | BCM43xx_PIO_TXCTL_WRITELO); |
| 51 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 52 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
| 52 | octet); | 53 | octet); |
| 53 | } | 54 | } |
| @@ -103,7 +104,7 @@ static void tx_complete(struct bcm43xx_pioqueue *queue, | |||
| 103 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 104 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
| 104 | skb->data[skb->len - 1]); | 105 | skb->data[skb->len - 1]); |
| 105 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 106 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
| 106 | BCM43xx_PIO_TXCTL_WRITEHI | | 107 | BCM43xx_PIO_TXCTL_WRITELO | |
| 107 | BCM43xx_PIO_TXCTL_COMPLETE); | 108 | BCM43xx_PIO_TXCTL_COMPLETE); |
| 108 | } else { | 109 | } else { |
| 109 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 110 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
| @@ -112,9 +113,10 @@ static void tx_complete(struct bcm43xx_pioqueue *queue, | |||
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | static u16 generate_cookie(struct bcm43xx_pioqueue *queue, | 115 | static u16 generate_cookie(struct bcm43xx_pioqueue *queue, |
| 115 | int packetindex) | 116 | struct bcm43xx_pio_txpacket *packet) |
| 116 | { | 117 | { |
| 117 | u16 cookie = 0x0000; | 118 | u16 cookie = 0x0000; |
| 119 | int packetindex; | ||
| 118 | 120 | ||
| 119 | /* We use the upper 4 bits for the PIO | 121 | /* We use the upper 4 bits for the PIO |
| 120 | * controller ID and the lower 12 bits | 122 | * controller ID and the lower 12 bits |
| @@ -135,6 +137,7 @@ static u16 generate_cookie(struct bcm43xx_pioqueue *queue, | |||
| 135 | default: | 137 | default: |
| 136 | assert(0); | 138 | assert(0); |
| 137 | } | 139 | } |
| 140 | packetindex = pio_txpacket_getindex(packet); | ||
| 138 | assert(((u16)packetindex & 0xF000) == 0x0000); | 141 | assert(((u16)packetindex & 0xF000) == 0x0000); |
| 139 | cookie |= (u16)packetindex; | 142 | cookie |= (u16)packetindex; |
| 140 | 143 | ||
| @@ -184,7 +187,7 @@ static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue, | |||
| 184 | bcm43xx_generate_txhdr(queue->bcm, | 187 | bcm43xx_generate_txhdr(queue->bcm, |
| 185 | &txhdr, skb->data, skb->len, | 188 | &txhdr, skb->data, skb->len, |
| 186 | (packet->xmitted_frags == 0), | 189 | (packet->xmitted_frags == 0), |
| 187 | generate_cookie(queue, pio_txpacket_getindex(packet))); | 190 | generate_cookie(queue, packet)); |
| 188 | 191 | ||
| 189 | tx_start(queue); | 192 | tx_start(queue); |
| 190 | octets = skb->len + sizeof(txhdr); | 193 | octets = skb->len + sizeof(txhdr); |
| @@ -241,7 +244,7 @@ static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet) | |||
| 241 | queue->tx_devq_packets++; | 244 | queue->tx_devq_packets++; |
| 242 | queue->tx_devq_used += octets; | 245 | queue->tx_devq_used += octets; |
| 243 | 246 | ||
| 244 | assert(packet->xmitted_frags <= packet->txb->nr_frags); | 247 | assert(packet->xmitted_frags < packet->txb->nr_frags); |
| 245 | packet->xmitted_frags++; | 248 | packet->xmitted_frags++; |
| 246 | packet->xmitted_octets += octets; | 249 | packet->xmitted_octets += octets; |
| 247 | } | 250 | } |
| @@ -257,8 +260,14 @@ static void tx_tasklet(unsigned long d) | |||
| 257 | unsigned long flags; | 260 | unsigned long flags; |
| 258 | struct bcm43xx_pio_txpacket *packet, *tmp_packet; | 261 | struct bcm43xx_pio_txpacket *packet, *tmp_packet; |
| 259 | int err; | 262 | int err; |
| 263 | u16 txctl; | ||
| 260 | 264 | ||
| 261 | bcm43xx_lock_mmio(bcm, flags); | 265 | bcm43xx_lock_mmio(bcm, flags); |
| 266 | |||
| 267 | txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); | ||
| 268 | if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) | ||
| 269 | goto out_unlock; | ||
| 270 | |||
| 262 | list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { | 271 | list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { |
| 263 | assert(packet->xmitted_frags < packet->txb->nr_frags); | 272 | assert(packet->xmitted_frags < packet->txb->nr_frags); |
| 264 | if (packet->xmitted_frags == 0) { | 273 | if (packet->xmitted_frags == 0) { |
| @@ -288,6 +297,7 @@ static void tx_tasklet(unsigned long d) | |||
| 288 | next_packet: | 297 | next_packet: |
| 289 | continue; | 298 | continue; |
| 290 | } | 299 | } |
| 300 | out_unlock: | ||
| 291 | bcm43xx_unlock_mmio(bcm, flags); | 301 | bcm43xx_unlock_mmio(bcm, flags); |
| 292 | } | 302 | } |
| 293 | 303 | ||
| @@ -330,12 +340,19 @@ struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm, | |||
| 330 | (unsigned long)queue); | 340 | (unsigned long)queue); |
| 331 | 341 | ||
| 332 | value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); | 342 | value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); |
| 333 | value |= BCM43xx_SBF_XFER_REG_BYTESWAP; | 343 | value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP; |
| 334 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); | 344 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); |
| 335 | 345 | ||
| 336 | qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); | 346 | qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); |
| 347 | if (qsize == 0) { | ||
| 348 | printk(KERN_ERR PFX "ERROR: This card does not support PIO " | ||
| 349 | "operation mode. Please use DMA mode " | ||
| 350 | "(module parameter pio=0).\n"); | ||
| 351 | goto err_freequeue; | ||
| 352 | } | ||
| 337 | if (qsize <= BCM43xx_PIO_TXQADJUST) { | 353 | if (qsize <= BCM43xx_PIO_TXQADJUST) { |
| 338 | printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize); | 354 | printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", |
| 355 | qsize); | ||
| 339 | goto err_freequeue; | 356 | goto err_freequeue; |
| 340 | } | 357 | } |
| 341 | qsize -= BCM43xx_PIO_TXQADJUST; | 358 | qsize -= BCM43xx_PIO_TXQADJUST; |
| @@ -444,15 +461,10 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm, | |||
| 444 | { | 461 | { |
| 445 | struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; | 462 | struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; |
| 446 | struct bcm43xx_pio_txpacket *packet; | 463 | struct bcm43xx_pio_txpacket *packet; |
| 447 | u16 tmp; | ||
| 448 | 464 | ||
| 449 | assert(!queue->tx_suspended); | 465 | assert(!queue->tx_suspended); |
| 450 | assert(!list_empty(&queue->txfree)); | 466 | assert(!list_empty(&queue->txfree)); |
| 451 | 467 | ||
| 452 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); | ||
| 453 | if (tmp & BCM43xx_PIO_TXCTL_SUSPEND) | ||
| 454 | return -EBUSY; | ||
| 455 | |||
| 456 | packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); | 468 | packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); |
| 457 | packet->txb = txb; | 469 | packet->txb = txb; |
| 458 | packet->xmitted_frags = 0; | 470 | packet->xmitted_frags = 0; |
| @@ -462,7 +474,7 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm, | |||
| 462 | assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); | 474 | assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); |
| 463 | 475 | ||
| 464 | /* Suspend TX, if we are out of packets in the "free" queue. */ | 476 | /* Suspend TX, if we are out of packets in the "free" queue. */ |
| 465 | if (unlikely(list_empty(&queue->txfree))) { | 477 | if (list_empty(&queue->txfree)) { |
| 466 | netif_stop_queue(queue->bcm->net_dev); | 478 | netif_stop_queue(queue->bcm->net_dev); |
| 467 | queue->tx_suspended = 1; | 479 | queue->tx_suspended = 1; |
| 468 | } | 480 | } |
| @@ -480,15 +492,15 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, | |||
| 480 | 492 | ||
| 481 | queue = parse_cookie(bcm, status->cookie, &packet); | 493 | queue = parse_cookie(bcm, status->cookie, &packet); |
| 482 | assert(queue); | 494 | assert(queue); |
| 483 | //TODO | 495 | |
| 484 | if (!queue) | ||
| 485 | return; | ||
| 486 | free_txpacket(packet, 1); | 496 | free_txpacket(packet, 1); |
| 487 | if (unlikely(queue->tx_suspended)) { | 497 | if (queue->tx_suspended) { |
| 488 | queue->tx_suspended = 0; | 498 | queue->tx_suspended = 0; |
| 489 | netif_wake_queue(queue->bcm->net_dev); | 499 | netif_wake_queue(queue->bcm->net_dev); |
| 490 | } | 500 | } |
| 491 | /* If there are packets on the txqueue, poke the tasklet. */ | 501 | /* If there are packets on the txqueue, poke the tasklet |
| 502 | * to transmit them. | ||
| 503 | */ | ||
| 492 | if (!list_empty(&queue->txqueue)) | 504 | if (!list_empty(&queue->txqueue)) |
| 493 | tasklet_schedule(&queue->txtask); | 505 | tasklet_schedule(&queue->txtask); |
| 494 | } | 506 | } |
| @@ -519,12 +531,9 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) | |||
| 519 | int i, preamble_readwords; | 531 | int i, preamble_readwords; |
| 520 | struct sk_buff *skb; | 532 | struct sk_buff *skb; |
| 521 | 533 | ||
| 522 | return; | ||
| 523 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); | 534 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); |
| 524 | if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) { | 535 | if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) |
| 525 | dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk. | ||
| 526 | return; | 536 | return; |
| 527 | } | ||
| 528 | bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, | 537 | bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, |
| 529 | BCM43xx_PIO_RXCTL_DATAAVAILABLE); | 538 | BCM43xx_PIO_RXCTL_DATAAVAILABLE); |
| 530 | 539 | ||
| @@ -538,8 +547,7 @@ return; | |||
| 538 | return; | 547 | return; |
| 539 | data_ready: | 548 | data_ready: |
| 540 | 549 | ||
| 541 | //FIXME: endianess in this function. | 550 | len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
| 542 | len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); | ||
| 543 | if (unlikely(len > 0x700)) { | 551 | if (unlikely(len > 0x700)) { |
| 544 | pio_rx_error(queue, 0, "len > 0x700"); | 552 | pio_rx_error(queue, 0, "len > 0x700"); |
| 545 | return; | 553 | return; |
| @@ -555,7 +563,7 @@ data_ready: | |||
| 555 | preamble_readwords = 18 / sizeof(u16); | 563 | preamble_readwords = 18 / sizeof(u16); |
| 556 | for (i = 0; i < preamble_readwords; i++) { | 564 | for (i = 0; i < preamble_readwords; i++) { |
| 557 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); | 565 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
| 558 | preamble[i + 1] = cpu_to_be16(tmp);//FIXME? | 566 | preamble[i + 1] = cpu_to_le16(tmp); |
| 559 | } | 567 | } |
| 560 | rxhdr = (struct bcm43xx_rxhdr *)preamble; | 568 | rxhdr = (struct bcm43xx_rxhdr *)preamble; |
| 561 | rxflags2 = le16_to_cpu(rxhdr->flags2); | 569 | rxflags2 = le16_to_cpu(rxhdr->flags2); |
| @@ -591,16 +599,40 @@ data_ready: | |||
| 591 | } | 599 | } |
| 592 | skb_put(skb, len); | 600 | skb_put(skb, len); |
| 593 | for (i = 0; i < len - 1; i += 2) { | 601 | for (i = 0; i < len - 1; i += 2) { |
| 594 | tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); | 602 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
| 595 | *((u16 *)(skb->data + i)) = tmp; | 603 | *((u16 *)(skb->data + i)) = cpu_to_le16(tmp); |
| 596 | } | 604 | } |
| 597 | if (len % 2) { | 605 | if (len % 2) { |
| 598 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); | 606 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
| 599 | skb->data[len - 1] = (tmp & 0x00FF); | 607 | skb->data[len - 1] = (tmp & 0x00FF); |
| 608 | /* The specs say the following is required, but | ||
| 609 | * it is wrong and corrupts the PLCP. If we don't do | ||
| 610 | * this, the PLCP seems to be correct. So ifdef it out for now. | ||
| 611 | */ | ||
| 612 | #if 0 | ||
| 600 | if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) | 613 | if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) |
| 601 | skb->data[0x20] = (tmp & 0xFF00) >> 8; | 614 | skb->data[2] = (tmp & 0xFF00) >> 8; |
| 602 | else | 615 | else |
| 603 | skb->data[0x1E] = (tmp & 0xFF00) >> 8; | 616 | skb->data[0] = (tmp & 0xFF00) >> 8; |
| 617 | #endif | ||
| 604 | } | 618 | } |
| 619 | skb_trim(skb, len - IEEE80211_FCS_LEN); | ||
| 605 | bcm43xx_rx(queue->bcm, skb, rxhdr); | 620 | bcm43xx_rx(queue->bcm, skb, rxhdr); |
| 606 | } | 621 | } |
| 622 | |||
| 623 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) | ||
| 624 | { | ||
| 625 | bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1); | ||
| 626 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | ||
| 627 | bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) | ||
| 628 | | BCM43xx_PIO_TXCTL_SUSPEND); | ||
| 629 | } | ||
| 630 | |||
| 631 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) | ||
| 632 | { | ||
| 633 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | ||
| 634 | bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) | ||
| 635 | & ~BCM43xx_PIO_TXCTL_SUSPEND); | ||
| 636 | bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); | ||
| 637 | tasklet_schedule(&queue->txtask); | ||
| 638 | } | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h index 970627bc1769..dfc78209e3a3 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | #define BCM43xx_PIO_RXCTL 0x08 | 14 | #define BCM43xx_PIO_RXCTL 0x08 |
| 15 | #define BCM43xx_PIO_RXDATA 0x0A | 15 | #define BCM43xx_PIO_RXDATA 0x0A |
| 16 | 16 | ||
| 17 | #define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0) | 17 | #define BCM43xx_PIO_TXCTL_WRITELO (1 << 0) |
| 18 | #define BCM43xx_PIO_TXCTL_WRITELO (1 << 1) | 18 | #define BCM43xx_PIO_TXCTL_WRITEHI (1 << 1) |
| 19 | #define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) | 19 | #define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) |
| 20 | #define BCM43xx_PIO_TXCTL_INIT (1 << 3) | 20 | #define BCM43xx_PIO_TXCTL_INIT (1 << 3) |
| 21 | #define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) | 21 | #define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) |
| @@ -95,6 +95,7 @@ void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue, | |||
| 95 | u16 offset, u16 value) | 95 | u16 offset, u16 value) |
| 96 | { | 96 | { |
| 97 | bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); | 97 | bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); |
| 98 | mmiowb(); | ||
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | 101 | ||
| @@ -107,6 +108,9 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, | |||
| 107 | struct bcm43xx_xmitstatus *status); | 108 | struct bcm43xx_xmitstatus *status); |
| 108 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); | 109 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); |
| 109 | 110 | ||
| 111 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); | ||
| 112 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); | ||
| 113 | |||
| 110 | #else /* CONFIG_BCM43XX_PIO */ | 114 | #else /* CONFIG_BCM43XX_PIO */ |
| 111 | 115 | ||
| 112 | static inline | 116 | static inline |
| @@ -133,6 +137,14 @@ static inline | |||
| 133 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) | 137 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) |
| 134 | { | 138 | { |
| 135 | } | 139 | } |
| 140 | static inline | ||
| 141 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) | ||
| 142 | { | ||
| 143 | } | ||
| 144 | static inline | ||
| 145 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) | ||
| 146 | { | ||
| 147 | } | ||
| 136 | 148 | ||
| 137 | #endif /* CONFIG_BCM43XX_PIO */ | 149 | #endif /* CONFIG_BCM43XX_PIO */ |
| 138 | #endif /* BCM43xx_PIO_H_ */ | 150 | #endif /* BCM43xx_PIO_H_ */ |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 8b37e824dfcb..8399de581893 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
| @@ -1860,7 +1860,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
| 1860 | memset(&iwe, 0, sizeof(iwe)); | 1860 | memset(&iwe, 0, sizeof(iwe)); |
| 1861 | iwe.cmd = SIOCGIWFREQ; | 1861 | iwe.cmd = SIOCGIWFREQ; |
| 1862 | if (scan) { | 1862 | if (scan) { |
| 1863 | chan = scan->chid; | 1863 | chan = le16_to_cpu(scan->chid); |
| 1864 | } else if (bss) { | 1864 | } else if (bss) { |
| 1865 | chan = bss->chan; | 1865 | chan = bss->chan; |
| 1866 | } else { | 1866 | } else { |
| @@ -1868,7 +1868,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
| 1868 | } | 1868 | } |
| 1869 | 1869 | ||
| 1870 | if (chan > 0) { | 1870 | if (chan > 0) { |
| 1871 | iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000; | 1871 | iwe.u.freq.m = freq_list[chan - 1] * 100000; |
| 1872 | iwe.u.freq.e = 1; | 1872 | iwe.u.freq.e = 1; |
| 1873 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1873 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
| 1874 | IW_EV_FREQ_LEN); | 1874 | IW_EV_FREQ_LEN); |
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index 6b3693f05ca0..b1ebfbae397f 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h | |||
| @@ -96,10 +96,13 @@ struct ieee80211softmac_assoc_info { | |||
| 96 | * | 96 | * |
| 97 | * bssvalid is true if we found a matching network | 97 | * bssvalid is true if we found a matching network |
| 98 | * and saved it's BSSID into the bssid above. | 98 | * and saved it's BSSID into the bssid above. |
| 99 | * | ||
| 100 | * bssfixed is used for SIOCSIWAP. | ||
| 99 | */ | 101 | */ |
| 100 | u8 static_essid:1, | 102 | u8 static_essid:1, |
| 101 | associating:1, | 103 | associating:1, |
| 102 | bssvalid:1; | 104 | bssvalid:1, |
| 105 | bssfixed:1; | ||
| 103 | 106 | ||
| 104 | /* Scan retries remaining */ | 107 | /* Scan retries remaining */ |
| 105 | int scan_retry; | 108 | int scan_retry; |
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index 4498023841dc..fb79ce7d6439 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
| @@ -144,6 +144,12 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne | |||
| 144 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) | 144 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) |
| 145 | return 0; | 145 | return 0; |
| 146 | 146 | ||
| 147 | /* assume that users know what they're doing ... | ||
| 148 | * (note we don't let them select a net we're incompatible with) */ | ||
| 149 | if (mac->associnfo.bssfixed) { | ||
| 150 | return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN); | ||
| 151 | } | ||
| 152 | |||
| 147 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ | 153 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ |
| 148 | if (mac->associnfo.req_essid.len == 0 | 154 | if (mac->associnfo.req_essid.len == 0 |
| 149 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) | 155 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) |
| @@ -176,7 +182,7 @@ ieee80211softmac_assoc_work(void *d) | |||
| 176 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); | 182 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
| 177 | 183 | ||
| 178 | /* try to find the requested network in our list, if we found one already */ | 184 | /* try to find the requested network in our list, if we found one already */ |
| 179 | if (mac->associnfo.bssvalid) | 185 | if (mac->associnfo.bssvalid || mac->associnfo.bssfixed) |
| 180 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 186 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
| 181 | 187 | ||
| 182 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, | 188 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, |
| @@ -241,19 +247,25 @@ ieee80211softmac_assoc_work(void *d) | |||
| 241 | if (ieee80211softmac_start_scan(mac)) | 247 | if (ieee80211softmac_start_scan(mac)) |
| 242 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); | 248 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); |
| 243 | return; | 249 | return; |
| 244 | } | 250 | } else { |
| 245 | else { | ||
| 246 | spin_lock_irqsave(&mac->lock, flags); | 251 | spin_lock_irqsave(&mac->lock, flags); |
| 247 | mac->associnfo.associating = 0; | 252 | mac->associnfo.associating = 0; |
| 248 | mac->associated = 0; | 253 | mac->associated = 0; |
| 249 | spin_unlock_irqrestore(&mac->lock, flags); | 254 | spin_unlock_irqrestore(&mac->lock, flags); |
| 250 | 255 | ||
| 251 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); | 256 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); |
| 257 | /* reset the retry counter for the next user request since we | ||
| 258 | * break out and don't reschedule ourselves after this point. */ | ||
| 259 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
| 252 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); | 260 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); |
| 253 | return; | 261 | return; |
| 254 | } | 262 | } |
| 255 | } | 263 | } |
| 256 | 264 | ||
| 265 | /* reset the retry counter for the next user request since we | ||
| 266 | * now found a net and will try to associate to it, but not | ||
| 267 | * schedule this function again. */ | ||
| 268 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
| 257 | mac->associnfo.bssvalid = 1; | 269 | mac->associnfo.bssvalid = 1; |
| 258 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); | 270 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); |
| 259 | /* copy the ESSID for displaying it */ | 271 | /* copy the ESSID for displaying it */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 60f06a31f0d1..be83bdc1644a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
| @@ -45,6 +45,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
| 45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; | 45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; |
| 46 | softmac->scaninfo = NULL; | 46 | softmac->scaninfo = NULL; |
| 47 | 47 | ||
| 48 | softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
| 49 | |||
| 48 | /* TODO: initialise all the other callbacks in the ieee struct | 50 | /* TODO: initialise all the other callbacks in the ieee struct |
| 49 | * (once they're written) | 51 | * (once they're written) |
| 50 | */ | 52 | */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 00f0d4f71897..27edb2b5581a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
| @@ -27,7 +27,8 @@ | |||
| 27 | #include "ieee80211softmac_priv.h" | 27 | #include "ieee80211softmac_priv.h" |
| 28 | 28 | ||
| 29 | #include <net/iw_handler.h> | 29 | #include <net/iw_handler.h> |
| 30 | 30 | /* for is_broadcast_ether_addr and is_zero_ether_addr */ | |
| 31 | #include <linux/etherdevice.h> | ||
| 31 | 32 | ||
| 32 | int | 33 | int |
| 33 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, | 34 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, |
| @@ -83,7 +84,6 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
| 83 | sm->associnfo.static_essid = 1; | 84 | sm->associnfo.static_essid = 1; |
| 84 | } | 85 | } |
| 85 | } | 86 | } |
| 86 | sm->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
| 87 | 87 | ||
| 88 | /* set our requested ESSID length. | 88 | /* set our requested ESSID length. |
| 89 | * If applicable, we have already copied the data in */ | 89 | * If applicable, we have already copied the data in */ |
| @@ -310,8 +310,6 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
| 310 | char *extra) | 310 | char *extra) |
| 311 | { | 311 | { |
| 312 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 312 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
| 313 | static const unsigned char any[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
| 314 | static const unsigned char off[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
| 315 | unsigned long flags; | 313 | unsigned long flags; |
| 316 | 314 | ||
| 317 | /* sanity check */ | 315 | /* sanity check */ |
| @@ -320,10 +318,17 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
| 320 | } | 318 | } |
| 321 | 319 | ||
| 322 | spin_lock_irqsave(&mac->lock, flags); | 320 | spin_lock_irqsave(&mac->lock, flags); |
| 323 | if (!memcmp(any, data->ap_addr.sa_data, ETH_ALEN) || | 321 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { |
| 324 | !memcmp(off, data->ap_addr.sa_data, ETH_ALEN)) { | 322 | /* the bssid we have is not to be fixed any longer, |
| 325 | schedule_work(&mac->associnfo.work); | 323 | * and we should reassociate to the best AP. */ |
| 326 | goto out; | 324 | mac->associnfo.bssfixed = 0; |
| 325 | /* force reassociation */ | ||
| 326 | mac->associnfo.bssvalid = 0; | ||
| 327 | if (mac->associated) | ||
| 328 | schedule_work(&mac->associnfo.work); | ||
| 329 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | ||
| 330 | /* the bssid we have is no longer fixed */ | ||
| 331 | mac->associnfo.bssfixed = 0; | ||
| 327 | } else { | 332 | } else { |
| 328 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { | 333 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { |
| 329 | if (mac->associnfo.associating || mac->associated) { | 334 | if (mac->associnfo.associating || mac->associated) { |
| @@ -333,12 +338,14 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
| 333 | } else { | 338 | } else { |
| 334 | /* copy new value in data->ap_addr.sa_data to bssid */ | 339 | /* copy new value in data->ap_addr.sa_data to bssid */ |
| 335 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); | 340 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); |
| 336 | } | 341 | } |
| 342 | /* tell the other code that this bssid should be used no matter what */ | ||
| 343 | mac->associnfo.bssfixed = 1; | ||
| 337 | /* queue associate if new bssid or (old one again and not associated) */ | 344 | /* queue associate if new bssid or (old one again and not associated) */ |
| 338 | schedule_work(&mac->associnfo.work); | 345 | schedule_work(&mac->associnfo.work); |
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | out: | 348 | out: |
| 342 | spin_unlock_irqrestore(&mac->lock, flags); | 349 | spin_unlock_irqrestore(&mac->lock, flags); |
| 343 | return 0; | 350 | return 0; |
| 344 | } | 351 | } |
