diff options
Diffstat (limited to 'drivers/net/wireless/b43/pio.c')
-rw-r--r-- | drivers/net/wireless/b43/pio.c | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index e96091b31499..9c1397996e0a 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -340,10 +340,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, | |||
340 | q->mmio_base + B43_PIO_TXDATA, | 340 | q->mmio_base + B43_PIO_TXDATA, |
341 | sizeof(u16)); | 341 | sizeof(u16)); |
342 | if (data_len & 1) { | 342 | if (data_len & 1) { |
343 | u8 tail[2] = { 0, }; | ||
344 | |||
343 | /* Write the last byte. */ | 345 | /* Write the last byte. */ |
344 | ctl &= ~B43_PIO_TXCTL_WRITEHI; | 346 | ctl &= ~B43_PIO_TXCTL_WRITEHI; |
345 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | 347 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
346 | b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]); | 348 | tail[0] = data[data_len - 1]; |
349 | ssb_block_write(dev->dev, tail, 2, | ||
350 | q->mmio_base + B43_PIO_TXDATA, | ||
351 | sizeof(u16)); | ||
347 | } | 352 | } |
348 | 353 | ||
349 | return ctl; | 354 | return ctl; |
@@ -386,26 +391,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, | |||
386 | q->mmio_base + B43_PIO8_TXDATA, | 391 | q->mmio_base + B43_PIO8_TXDATA, |
387 | sizeof(u32)); | 392 | sizeof(u32)); |
388 | if (data_len & 3) { | 393 | if (data_len & 3) { |
389 | u32 value = 0; | 394 | u8 tail[4] = { 0, }; |
390 | 395 | ||
391 | /* Write the last few bytes. */ | 396 | /* Write the last few bytes. */ |
392 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | | 397 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | |
393 | B43_PIO8_TXCTL_24_31); | 398 | B43_PIO8_TXCTL_24_31); |
394 | data = &(data[data_len - 1]); | ||
395 | switch (data_len & 3) { | 399 | switch (data_len & 3) { |
396 | case 3: | 400 | case 3: |
397 | ctl |= B43_PIO8_TXCTL_16_23; | 401 | ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; |
398 | value |= (u32)(*data) << 16; | 402 | tail[0] = data[data_len - 3]; |
399 | data--; | 403 | tail[1] = data[data_len - 2]; |
404 | tail[2] = data[data_len - 1]; | ||
405 | break; | ||
400 | case 2: | 406 | case 2: |
401 | ctl |= B43_PIO8_TXCTL_8_15; | 407 | ctl |= B43_PIO8_TXCTL_8_15; |
402 | value |= (u32)(*data) << 8; | 408 | tail[0] = data[data_len - 2]; |
403 | data--; | 409 | tail[1] = data[data_len - 1]; |
410 | break; | ||
404 | case 1: | 411 | case 1: |
405 | value |= (u32)(*data); | 412 | tail[0] = data[data_len - 1]; |
413 | break; | ||
406 | } | 414 | } |
407 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); | 415 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); |
408 | b43_piotx_write32(q, B43_PIO8_TXDATA, value); | 416 | ssb_block_write(dev->dev, tail, 4, |
417 | q->mmio_base + B43_PIO8_TXDATA, | ||
418 | sizeof(u32)); | ||
409 | } | 419 | } |
410 | 420 | ||
411 | return ctl; | 421 | return ctl; |
@@ -693,21 +703,25 @@ data_ready: | |||
693 | q->mmio_base + B43_PIO8_RXDATA, | 703 | q->mmio_base + B43_PIO8_RXDATA, |
694 | sizeof(u32)); | 704 | sizeof(u32)); |
695 | if (len & 3) { | 705 | if (len & 3) { |
696 | u32 value; | 706 | u8 tail[4] = { 0, }; |
697 | char *data; | ||
698 | 707 | ||
699 | /* Read the last few bytes. */ | 708 | /* Read the last few bytes. */ |
700 | value = b43_piorx_read32(q, B43_PIO8_RXDATA); | 709 | ssb_block_read(dev->dev, tail, 4, |
701 | data = &(skb->data[len + padding - 1]); | 710 | q->mmio_base + B43_PIO8_RXDATA, |
711 | sizeof(u32)); | ||
702 | switch (len & 3) { | 712 | switch (len & 3) { |
703 | case 3: | 713 | case 3: |
704 | *data = (value >> 16); | 714 | skb->data[len + padding - 3] = tail[0]; |
705 | data--; | 715 | skb->data[len + padding - 2] = tail[1]; |
716 | skb->data[len + padding - 1] = tail[2]; | ||
717 | break; | ||
706 | case 2: | 718 | case 2: |
707 | *data = (value >> 8); | 719 | skb->data[len + padding - 2] = tail[0]; |
708 | data--; | 720 | skb->data[len + padding - 1] = tail[1]; |
721 | break; | ||
709 | case 1: | 722 | case 1: |
710 | *data = value; | 723 | skb->data[len + padding - 1] = tail[0]; |
724 | break; | ||
711 | } | 725 | } |
712 | } | 726 | } |
713 | } else { | 727 | } else { |
@@ -715,11 +729,13 @@ data_ready: | |||
715 | q->mmio_base + B43_PIO_RXDATA, | 729 | q->mmio_base + B43_PIO_RXDATA, |
716 | sizeof(u16)); | 730 | sizeof(u16)); |
717 | if (len & 1) { | 731 | if (len & 1) { |
718 | u16 value; | 732 | u8 tail[2] = { 0, }; |
719 | 733 | ||
720 | /* Read the last byte. */ | 734 | /* Read the last byte. */ |
721 | value = b43_piorx_read16(q, B43_PIO_RXDATA); | 735 | ssb_block_read(dev->dev, tail, 2, |
722 | skb->data[len + padding - 1] = value; | 736 | q->mmio_base + B43_PIO_RXDATA, |
737 | sizeof(u16)); | ||
738 | skb->data[len + padding - 1] = tail[0]; | ||
723 | } | 739 | } |
724 | } | 740 | } |
725 | 741 | ||