diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-04-02 13:58:20 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-08 16:44:41 -0400 |
commit | d8c17e159758c2a4f8c3319fe8a6cf313f7a6733 (patch) | |
tree | 7246a95b8ed3872e1772563715c4264976008dad /drivers/net/wireless/b43 | |
parent | 36316126e90b058ad7bd5b9e3d6079814e0a17e2 (diff) |
b43: Use SSB block-I/O to do PIO
This changes the b43-PIO code to use the new SSB block-I/O.
This reduces the overhead by removing lots of function calls, pointer
dereferencing, if-conditionals any byteswapping for each packet data word.
This also fixes a harmless sparse endianness warning.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pio.c | 173 |
2 files changed, 91 insertions, 83 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 94f04559028b..f51b2d9b085b 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -67,6 +67,7 @@ config B43_PCMCIA | |||
67 | config B43_PIO | 67 | config B43_PIO |
68 | bool | 68 | bool |
69 | depends on B43 && (B43_PCMCIA || B43_FORCE_PIO) | 69 | depends on B43 && (B43_PCMCIA || B43_FORCE_PIO) |
70 | select SSB_BLOCKIO | ||
70 | default y | 71 | default y |
71 | 72 | ||
72 | config B43_NPHY | 73 | config B43_NPHY |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index e73769ac027f..fcacafb04346 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -338,27 +338,28 @@ static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev, | |||
338 | return q; | 338 | return q; |
339 | } | 339 | } |
340 | 340 | ||
341 | static inline void tx_write_2byte_queue(struct b43_pio_txqueue *q, | 341 | static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, |
342 | u16 *ctl, | 342 | u16 ctl, |
343 | const void *_data, | 343 | const void *_data, |
344 | unsigned int data_len) | 344 | unsigned int data_len) |
345 | { | 345 | { |
346 | struct b43_wldev *dev = q->dev; | ||
346 | const u8 *data = _data; | 347 | const u8 *data = _data; |
347 | unsigned int i; | 348 | |
348 | u16 value; | 349 | ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; |
349 | 350 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | |
350 | *ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; | 351 | |
351 | b43_piotx_write16(q, B43_PIO_TXCTL, *ctl); | 352 | ssb_block_write(dev->dev, data, (data_len & ~1), |
352 | for (i = 0; i < data_len; i += 2) { | 353 | q->mmio_base + B43_PIO_TXDATA, |
353 | value = data[i]; | 354 | sizeof(u16)); |
354 | if (i + 1 < data_len) { | 355 | if (data_len & 1) { |
355 | value |= (u16)(data[i + 1]) << 8; | 356 | /* Write the last byte. */ |
356 | } else { | 357 | ctl &= ~B43_PIO_TXCTL_WRITEHI; |
357 | *ctl &= ~B43_PIO_TXCTL_WRITEHI; | 358 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
358 | b43_piotx_write16(q, B43_PIO_TXCTL, *ctl); | 359 | b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]); |
359 | } | ||
360 | b43_piotx_write16(q, B43_PIO_TXDATA, value); | ||
361 | } | 360 | } |
361 | |||
362 | return ctl; | ||
362 | } | 363 | } |
363 | 364 | ||
364 | static void pio_tx_frame_2byte_queue(struct b43_pio_txpacket *pack, | 365 | static void pio_tx_frame_2byte_queue(struct b43_pio_txpacket *pack, |
@@ -374,51 +375,53 @@ static void pio_tx_frame_2byte_queue(struct b43_pio_txpacket *pack, | |||
374 | ctl &= ~B43_PIO_TXCTL_EOF; | 375 | ctl &= ~B43_PIO_TXCTL_EOF; |
375 | 376 | ||
376 | /* Transfer the header data. */ | 377 | /* Transfer the header data. */ |
377 | tx_write_2byte_queue(q, &ctl, hdr, hdrlen); | 378 | ctl = tx_write_2byte_queue(q, ctl, hdr, hdrlen); |
378 | /* Transfer the frame data. */ | 379 | /* Transfer the frame data. */ |
379 | tx_write_2byte_queue(q, &ctl, frame, frame_len); | 380 | ctl = tx_write_2byte_queue(q, ctl, frame, frame_len); |
380 | 381 | ||
381 | ctl |= B43_PIO_TXCTL_EOF; | 382 | ctl |= B43_PIO_TXCTL_EOF; |
382 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | 383 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
383 | } | 384 | } |
384 | 385 | ||
385 | static inline void tx_write_4byte_queue(struct b43_pio_txqueue *q, | 386 | static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, |
386 | u32 *ctl, | 387 | u32 ctl, |
387 | const void *_data, | 388 | const void *_data, |
388 | unsigned int data_len) | 389 | unsigned int data_len) |
389 | { | 390 | { |
391 | struct b43_wldev *dev = q->dev; | ||
390 | const u8 *data = _data; | 392 | const u8 *data = _data; |
391 | unsigned int i; | 393 | |
392 | u32 value; | 394 | ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 | |
393 | bool ctl_changed = 0; | 395 | B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; |
394 | 396 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); | |
395 | *ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 | | 397 | |
396 | B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; | 398 | ssb_block_write(dev->dev, data, (data_len & ~3), |
397 | b43_piotx_write32(q, B43_PIO8_TXCTL, *ctl); | 399 | q->mmio_base + B43_PIO8_TXDATA, |
398 | for (i = 0; i < data_len; i += 4) { | 400 | sizeof(u32)); |
399 | value = data[i]; | 401 | if (data_len & 3) { |
400 | if (i + 1 < data_len) { | 402 | u32 value = 0; |
401 | value |= (u32)(data[i + 1]) << 8; | 403 | |
402 | } else { | 404 | /* Write the last few bytes. */ |
403 | *ctl &= ~B43_PIO8_TXCTL_8_15; | 405 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | |
404 | ctl_changed = 1; | 406 | B43_PIO8_TXCTL_24_31); |
405 | } | 407 | data = &(data[data_len - 1]); |
406 | if (i + 2 < data_len) { | 408 | switch (data_len & 3) { |
407 | value |= (u32)(data[i + 2]) << 16; | 409 | case 3: |
408 | } else { | 410 | ctl |= B43_PIO8_TXCTL_16_23; |
409 | *ctl &= ~B43_PIO8_TXCTL_16_23; | 411 | value |= (u32)(*data) << 16; |
410 | ctl_changed = 1; | 412 | data--; |
411 | } | 413 | case 2: |
412 | if (i + 3 < data_len) { | 414 | ctl |= B43_PIO8_TXCTL_8_15; |
413 | value |= (u32)(data[i + 3]) << 24; | 415 | value |= (u32)(*data) << 8; |
414 | } else { | 416 | data--; |
415 | *ctl &= ~B43_PIO8_TXCTL_24_31; | 417 | case 1: |
416 | ctl_changed = 1; | 418 | value |= (u32)(*data); |
417 | } | 419 | } |
418 | if (ctl_changed) | 420 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); |
419 | b43_piotx_write32(q, B43_PIO8_TXCTL, *ctl); | ||
420 | b43_piotx_write32(q, B43_PIO8_TXDATA, value); | 421 | b43_piotx_write32(q, B43_PIO8_TXDATA, value); |
421 | } | 422 | } |
423 | |||
424 | return ctl; | ||
422 | } | 425 | } |
423 | 426 | ||
424 | static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack, | 427 | static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack, |
@@ -434,9 +437,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack, | |||
434 | ctl &= ~B43_PIO8_TXCTL_EOF; | 437 | ctl &= ~B43_PIO8_TXCTL_EOF; |
435 | 438 | ||
436 | /* Transfer the header data. */ | 439 | /* Transfer the header data. */ |
437 | tx_write_4byte_queue(q, &ctl, hdr, hdrlen); | 440 | ctl = tx_write_4byte_queue(q, ctl, hdr, hdrlen); |
438 | /* Transfer the frame data. */ | 441 | /* Transfer the frame data. */ |
439 | tx_write_4byte_queue(q, &ctl, frame, frame_len); | 442 | ctl = tx_write_4byte_queue(q, ctl, frame, frame_len); |
440 | 443 | ||
441 | ctl |= B43_PIO8_TXCTL_EOF; | 444 | ctl |= B43_PIO8_TXCTL_EOF; |
442 | b43_piotx_write32(q, B43_PIO_TXCTL, ctl); | 445 | b43_piotx_write32(q, B43_PIO_TXCTL, ctl); |
@@ -627,6 +630,7 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev, | |||
627 | /* Returns whether we should fetch another frame. */ | 630 | /* Returns whether we should fetch another frame. */ |
628 | static bool pio_rx_frame(struct b43_pio_rxqueue *q) | 631 | static bool pio_rx_frame(struct b43_pio_rxqueue *q) |
629 | { | 632 | { |
633 | struct b43_wldev *dev = q->dev; | ||
630 | struct b43_rxhdr_fw4 rxhdr; | 634 | struct b43_rxhdr_fw4 rxhdr; |
631 | u16 len; | 635 | u16 len; |
632 | u32 macstat; | 636 | u32 macstat; |
@@ -672,21 +676,13 @@ data_ready: | |||
672 | 676 | ||
673 | /* Get the preamble (RX header) */ | 677 | /* Get the preamble (RX header) */ |
674 | if (q->rev >= 8) { | 678 | if (q->rev >= 8) { |
675 | u32 *preamble = (u32 *)&rxhdr; | 679 | ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), |
676 | u32 value; | 680 | q->mmio_base + B43_PIO8_RXDATA, |
677 | 681 | sizeof(u32)); | |
678 | for (i = 0; i < sizeof(rxhdr); i += 4) { | ||
679 | value = b43_piorx_read32(q, B43_PIO8_RXDATA); | ||
680 | preamble[i / 4] = cpu_to_le32(value); | ||
681 | } | ||
682 | } else { | 682 | } else { |
683 | u16 *preamble = (u16 *)&rxhdr; | 683 | ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), |
684 | u16 value; | 684 | q->mmio_base + B43_PIO_RXDATA, |
685 | 685 | sizeof(u16)); | |
686 | for (i = 0; i < sizeof(rxhdr); i += 2) { | ||
687 | value = b43_piorx_read16(q, B43_PIO_RXDATA); | ||
688 | preamble[i / 2] = cpu_to_le16(value); | ||
689 | } | ||
690 | } | 686 | } |
691 | /* Sanity checks. */ | 687 | /* Sanity checks. */ |
692 | len = le16_to_cpu(rxhdr.frame_len); | 688 | len = le16_to_cpu(rxhdr.frame_len); |
@@ -720,26 +716,37 @@ data_ready: | |||
720 | skb_reserve(skb, 2); | 716 | skb_reserve(skb, 2); |
721 | skb_put(skb, len + padding); | 717 | skb_put(skb, len + padding); |
722 | if (q->rev >= 8) { | 718 | if (q->rev >= 8) { |
723 | u32 value; | 719 | ssb_block_read(dev->dev, skb->data + padding, (len & ~3), |
724 | 720 | q->mmio_base + B43_PIO8_RXDATA, | |
725 | for (i = padding; i < len + padding; i += 4) { | 721 | sizeof(u32)); |
722 | if (len & 3) { | ||
723 | u32 value; | ||
724 | char *data; | ||
725 | |||
726 | /* Read the last few bytes. */ | ||
726 | value = b43_piorx_read32(q, B43_PIO8_RXDATA); | 727 | value = b43_piorx_read32(q, B43_PIO8_RXDATA); |
727 | skb->data[i] = value; | 728 | data = &(skb->data[len + padding - 1]); |
728 | if ((i + 1) < (len + padding)) | 729 | switch (len & 3) { |
729 | skb->data[i + 1] = value >> 8; | 730 | case 3: |
730 | if ((i + 2) < (len + padding)) | 731 | *data = (value >> 16); |
731 | skb->data[i + 2] = value >> 16; | 732 | data--; |
732 | if ((i + 3) < (len + padding)) | 733 | case 2: |
733 | skb->data[i + 3] = value >> 24; | 734 | *data = (value >> 8); |
735 | data--; | ||
736 | case 1: | ||
737 | *data = value; | ||
738 | } | ||
734 | } | 739 | } |
735 | } else { | 740 | } else { |
736 | u16 value; | 741 | ssb_block_read(dev->dev, skb->data + padding, (len & ~1), |
742 | q->mmio_base + B43_PIO_RXDATA, | ||
743 | sizeof(u16)); | ||
744 | if (len & 1) { | ||
745 | u16 value; | ||
737 | 746 | ||
738 | for (i = padding; i < len + padding; i += 2) { | 747 | /* Read the last byte. */ |
739 | value = b43_piorx_read16(q, B43_PIO_RXDATA); | 748 | value = b43_piorx_read16(q, B43_PIO_RXDATA); |
740 | skb->data[i] = value; | 749 | skb->data[len + padding - 1] = value; |
741 | if ((i + 1) < (len + padding)) | ||
742 | skb->data[i + 1] = value >> 8; | ||
743 | } | 750 | } |
744 | } | 751 | } |
745 | 752 | ||