aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r--drivers/net/wireless/b43/xmit.c206
1 files changed, 106 insertions, 100 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 7caa26eb4105..19aefbfb2c93 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -30,48 +30,51 @@
30#include "xmit.h" 30#include "xmit.h"
31#include "phy.h" 31#include "phy.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h"
33 34
34 35
35/* Extract the bitrate out of a CCK PLCP header. */ 36/* Extract the bitrate index out of a CCK PLCP header. */
36static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) 37static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
37{ 38{
38 switch (plcp->raw[0]) { 39 switch (plcp->raw[0]) {
39 case 0x0A: 40 case 0x0A:
40 return B43_CCK_RATE_1MB; 41 return 0;
41 case 0x14: 42 case 0x14:
42 return B43_CCK_RATE_2MB; 43 return 1;
43 case 0x37: 44 case 0x37:
44 return B43_CCK_RATE_5MB; 45 return 2;
45 case 0x6E: 46 case 0x6E:
46 return B43_CCK_RATE_11MB; 47 return 3;
47 } 48 }
48 B43_WARN_ON(1); 49 B43_WARN_ON(1);
49 return 0; 50 return -1;
50} 51}
51 52
52/* Extract the bitrate out of an OFDM PLCP header. */ 53/* Extract the bitrate index out of an OFDM PLCP header. */
53static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) 54static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
54{ 55{
56 int base = aphy ? 0 : 4;
57
55 switch (plcp->raw[0] & 0xF) { 58 switch (plcp->raw[0] & 0xF) {
56 case 0xB: 59 case 0xB:
57 return B43_OFDM_RATE_6MB; 60 return base + 0;
58 case 0xF: 61 case 0xF:
59 return B43_OFDM_RATE_9MB; 62 return base + 1;
60 case 0xA: 63 case 0xA:
61 return B43_OFDM_RATE_12MB; 64 return base + 2;
62 case 0xE: 65 case 0xE:
63 return B43_OFDM_RATE_18MB; 66 return base + 3;
64 case 0x9: 67 case 0x9:
65 return B43_OFDM_RATE_24MB; 68 return base + 4;
66 case 0xD: 69 case 0xD:
67 return B43_OFDM_RATE_36MB; 70 return base + 5;
68 case 0x8: 71 case 0x8:
69 return B43_OFDM_RATE_48MB; 72 return base + 6;
70 case 0xC: 73 case 0xC:
71 return B43_OFDM_RATE_54MB; 74 return base + 7;
72 } 75 }
73 B43_WARN_ON(1); 76 B43_WARN_ON(1);
74 return 0; 77 return -1;
75} 78}
76 79
77u8 b43_plcp_get_ratecode_cck(const u8 bitrate) 80u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
@@ -191,6 +194,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
191 (const struct ieee80211_hdr *)fragment_data; 194 (const struct ieee80211_hdr *)fragment_data;
192 int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); 195 int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
193 u16 fctl = le16_to_cpu(wlhdr->frame_control); 196 u16 fctl = le16_to_cpu(wlhdr->frame_control);
197 struct ieee80211_rate *fbrate;
194 u8 rate, rate_fb; 198 u8 rate, rate_fb;
195 int rate_ofdm, rate_fb_ofdm; 199 int rate_ofdm, rate_fb_ofdm;
196 unsigned int plcp_fragment_len; 200 unsigned int plcp_fragment_len;
@@ -200,9 +204,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
200 204
201 memset(txhdr, 0, sizeof(*txhdr)); 205 memset(txhdr, 0, sizeof(*txhdr));
202 206
203 rate = txctl->tx_rate; 207 WARN_ON(!txctl->tx_rate);
208 rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
204 rate_ofdm = b43_is_ofdm_rate(rate); 209 rate_ofdm = b43_is_ofdm_rate(rate);
205 rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; 210 fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
211 rate_fb = fbrate->hw_value;
206 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); 212 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
207 213
208 if (rate_ofdm) 214 if (rate_ofdm)
@@ -221,11 +227,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
221 * use the original dur_id field. */ 227 * use the original dur_id field. */
222 txhdr->dur_fb = wlhdr->duration_id; 228 txhdr->dur_fb = wlhdr->duration_id;
223 } else { 229 } else {
224 int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb);
225 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, 230 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
226 txctl->vif, 231 txctl->vif,
227 fragment_len, 232 fragment_len,
228 fbrate_base100kbps); 233 fbrate);
229 } 234 }
230 235
231 plcp_fragment_len = fragment_len + FCS_LEN; 236 plcp_fragment_len = fragment_len + FCS_LEN;
@@ -287,7 +292,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
287 phy_ctl |= B43_TXH_PHY_ENC_OFDM; 292 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
288 else 293 else
289 phy_ctl |= B43_TXH_PHY_ENC_CCK; 294 phy_ctl |= B43_TXH_PHY_ENC_CCK;
290 if (dev->short_preamble) 295 if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
291 phy_ctl |= B43_TXH_PHY_SHORTPRMBL; 296 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
292 297
293 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { 298 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
@@ -332,7 +337,8 @@ int b43_generate_txhdr(struct b43_wldev *dev,
332 int rts_rate_ofdm, rts_rate_fb_ofdm; 337 int rts_rate_ofdm, rts_rate_fb_ofdm;
333 struct b43_plcp_hdr6 *plcp; 338 struct b43_plcp_hdr6 *plcp;
334 339
335 rts_rate = txctl->rts_cts_rate; 340 WARN_ON(!txctl->rts_cts_rate);
341 rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
336 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); 342 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
337 rts_rate_fb = b43_calc_fallback_rate(rts_rate); 343 rts_rate_fb = b43_calc_fallback_rate(rts_rate);
338 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 344 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
@@ -506,7 +512,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
506 u16 phystat0, phystat3, chanstat, mactime; 512 u16 phystat0, phystat3, chanstat, mactime;
507 u32 macstat; 513 u32 macstat;
508 u16 chanid; 514 u16 chanid;
509 u8 jssi; 515 u16 phytype;
510 int padding; 516 int padding;
511 517
512 memset(&status, 0, sizeof(status)); 518 memset(&status, 0, sizeof(status));
@@ -514,10 +520,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
514 /* Get metadata about the frame from the header. */ 520 /* Get metadata about the frame from the header. */
515 phystat0 = le16_to_cpu(rxhdr->phy_status0); 521 phystat0 = le16_to_cpu(rxhdr->phy_status0);
516 phystat3 = le16_to_cpu(rxhdr->phy_status3); 522 phystat3 = le16_to_cpu(rxhdr->phy_status3);
517 jssi = rxhdr->jssi;
518 macstat = le32_to_cpu(rxhdr->mac_status); 523 macstat = le32_to_cpu(rxhdr->mac_status);
519 mactime = le16_to_cpu(rxhdr->mac_time); 524 mactime = le16_to_cpu(rxhdr->mac_time);
520 chanstat = le16_to_cpu(rxhdr->channel); 525 chanstat = le16_to_cpu(rxhdr->channel);
526 phytype = chanstat & B43_RX_CHAN_PHYTYPE;
521 527
522 if (macstat & B43_RX_MAC_FCSERR) 528 if (macstat & B43_RX_MAC_FCSERR)
523 dev->wl->ieee_stats.dot11FCSErrorCount++; 529 dev->wl->ieee_stats.dot11FCSErrorCount++;
@@ -567,26 +573,40 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
567 } 573 }
568 } 574 }
569 575
570 status.ssi = b43_rssi_postprocess(dev, jssi, 576 /* Link quality statistics */
571 (phystat0 & B43_RX_PHYST0_OFDM),
572 (phystat0 & B43_RX_PHYST0_GAINCTL),
573 (phystat3 & B43_RX_PHYST3_TRSTATE));
574 status.noise = dev->stats.link_noise; 577 status.noise = dev->stats.link_noise;
575 /* the next line looks wrong, but is what mac80211 wants */ 578 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
576 status.signal = (jssi * 100) / B43_RX_MAX_SSI; 579// s8 rssi = max(rxhdr->power0, rxhdr->power1);
580 //TODO: Find out what the rssi value is (dBm or percentage?)
581 // and also find out what the maximum possible value is.
582 // Fill status.ssi and status.signal fields.
583 } else {
584 status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi,
585 (phystat0 & B43_RX_PHYST0_OFDM),
586 (phystat0 & B43_RX_PHYST0_GAINCTL),
587 (phystat3 & B43_RX_PHYST3_TRSTATE));
588 /* the next line looks wrong, but is what mac80211 wants */
589 status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
590 }
591
577 if (phystat0 & B43_RX_PHYST0_OFDM) 592 if (phystat0 & B43_RX_PHYST0_OFDM)
578 status.rate = b43_plcp_get_bitrate_ofdm(plcp); 593 status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
594 phytype == B43_PHYTYPE_A);
579 else 595 else
580 status.rate = b43_plcp_get_bitrate_cck(plcp); 596 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
581 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); 597 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
582 598
583 /* 599 /*
584 * If monitors are present get full 64-bit timestamp. This 600 * All frames on monitor interfaces and beacons always need a full
585 * code assumes we get to process the packet within 16 bits 601 * 64-bit timestamp. Monitor interfaces need it for diagnostic
586 * of timestamp, i.e. about 65 milliseconds after the PHY 602 * purposes and beacons for IBSS merging.
587 * received the first symbol. 603 * This code assumes we get to process the packet within 16 bits
604 * of timestamp, i.e. about 65 milliseconds after the PHY received
605 * the first symbol.
588 */ 606 */
589 if (dev->wl->radiotap_enabled) { 607 if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
608 == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
609 dev->wl->radiotap_enabled) {
590 u16 low_mactime_now; 610 u16 low_mactime_now;
591 611
592 b43_tsf_read(dev, &status.mactime); 612 b43_tsf_read(dev, &status.mactime);
@@ -601,29 +621,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
601 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; 621 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
602 switch (chanstat & B43_RX_CHAN_PHYTYPE) { 622 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
603 case B43_PHYTYPE_A: 623 case B43_PHYTYPE_A:
604 status.phymode = MODE_IEEE80211A; 624 status.band = IEEE80211_BAND_5GHZ;
605 B43_WARN_ON(1); 625 B43_WARN_ON(1);
606 /* FIXME: We don't really know which value the "chanid" contains. 626 /* FIXME: We don't really know which value the "chanid" contains.
607 * So the following assignment might be wrong. */ 627 * So the following assignment might be wrong. */
608 status.channel = chanid; 628 status.freq = b43_channel_to_freq_5ghz(chanid);
609 status.freq = b43_channel_to_freq_5ghz(status.channel);
610 break; 629 break;
611 case B43_PHYTYPE_G: 630 case B43_PHYTYPE_G:
612 status.phymode = MODE_IEEE80211G; 631 status.band = IEEE80211_BAND_2GHZ;
613 /* chanid is the radio channel cookie value as used 632 /* chanid is the radio channel cookie value as used
614 * to tune the radio. */ 633 * to tune the radio. */
615 status.freq = chanid + 2400; 634 status.freq = chanid + 2400;
616 status.channel = b43_freq_to_channel_2ghz(status.freq);
617 break; 635 break;
618 case B43_PHYTYPE_N: 636 case B43_PHYTYPE_N:
619 status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/;
620 /* chanid is the SHM channel cookie. Which is the plain 637 /* chanid is the SHM channel cookie. Which is the plain
621 * channel number in b43. */ 638 * channel number in b43. */
622 status.channel = chanid; 639 if (chanstat & B43_RX_CHAN_5GHZ) {
623 if (chanstat & B43_RX_CHAN_5GHZ) 640 status.band = IEEE80211_BAND_5GHZ;
624 status.freq = b43_freq_to_channel_5ghz(status.freq); 641 status.freq = b43_freq_to_channel_5ghz(chanid);
625 else 642 } else {
626 status.freq = b43_freq_to_channel_2ghz(status.freq); 643 status.band = IEEE80211_BAND_2GHZ;
644 status.freq = b43_freq_to_channel_2ghz(chanid);
645 }
627 break; 646 break;
628 default: 647 default:
629 B43_WARN_ON(1); 648 B43_WARN_ON(1);
@@ -657,67 +676,54 @@ void b43_handle_txstatus(struct b43_wldev *dev,
657 dev->wl->ieee_stats.dot11RTSSuccessCount++; 676 dev->wl->ieee_stats.dot11RTSSuccessCount++;
658 } 677 }
659 678
660 b43_dma_handle_txstatus(dev, status); 679 if (b43_using_pio_transfers(dev))
680 b43_pio_handle_txstatus(dev, status);
681 else
682 b43_dma_handle_txstatus(dev, status);
661} 683}
662 684
663/* Handle TX status report as received through DMA/PIO queues */ 685/* Fill out the mac80211 TXstatus report based on the b43-specific
664void b43_handle_hwtxstatus(struct b43_wldev *dev, 686 * txstatus report data. This returns a boolean whether the frame was
665 const struct b43_hwtxstatus *hw) 687 * successfully transmitted. */
688bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
689 const struct b43_txstatus *status)
666{ 690{
667 struct b43_txstatus status; 691 bool frame_success = 1;
668 u8 tmp; 692
669 693 if (status->acked) {
670 status.cookie = le16_to_cpu(hw->cookie); 694 /* The frame was ACKed. */
671 status.seq = le16_to_cpu(hw->seq); 695 report->flags |= IEEE80211_TX_STATUS_ACK;
672 status.phy_stat = hw->phy_stat; 696 } else {
673 tmp = hw->count; 697 /* The frame was not ACKed... */
674 status.frame_count = (tmp >> 4); 698 if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
675 status.rts_count = (tmp & 0x0F); 699 /* ...but we expected an ACK. */
676 tmp = hw->flags; 700 frame_success = 0;
677 status.supp_reason = ((tmp & 0x1C) >> 2); 701 report->excessive_retries = 1;
678 status.pm_indicated = !!(tmp & 0x80); 702 }
679 status.intermediate = !!(tmp & 0x40); 703 }
680 status.for_ampdu = !!(tmp & 0x20); 704 if (status->frame_count == 0) {
681 status.acked = !!(tmp & 0x02); 705 /* The frame was not transmitted at all. */
682 706 report->retry_count = 0;
683 b43_handle_txstatus(dev, &status); 707 } else
708 report->retry_count = status->frame_count - 1;
709
710 return frame_success;
684} 711}
685 712
686/* Stop any TX operation on the device (suspend the hardware queues) */ 713/* Stop any TX operation on the device (suspend the hardware queues) */
687void b43_tx_suspend(struct b43_wldev *dev) 714void b43_tx_suspend(struct b43_wldev *dev)
688{ 715{
689 b43_dma_tx_suspend(dev); 716 if (b43_using_pio_transfers(dev))
717 b43_pio_tx_suspend(dev);
718 else
719 b43_dma_tx_suspend(dev);
690} 720}
691 721
692/* Resume any TX operation on the device (resume the hardware queues) */ 722/* Resume any TX operation on the device (resume the hardware queues) */
693void b43_tx_resume(struct b43_wldev *dev) 723void b43_tx_resume(struct b43_wldev *dev)
694{ 724{
695 b43_dma_tx_resume(dev); 725 if (b43_using_pio_transfers(dev))
696} 726 b43_pio_tx_resume(dev);
697 727 else
698#if 0 728 b43_dma_tx_resume(dev);
699static void upload_qos_parms(struct b43_wldev *dev,
700 const u16 * parms, u16 offset)
701{
702 int i;
703
704 for (i = 0; i < B43_NR_QOSPARMS; i++) {
705 b43_shm_write16(dev, B43_SHM_SHARED,
706 offset + (i * 2), parms[i]);
707 }
708}
709#endif
710
711/* Initialize the QoS parameters */
712void b43_qos_init(struct b43_wldev *dev)
713{
714 /* FIXME: This function must probably be called from the mac80211
715 * config callback. */
716 return;
717
718 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
719 //FIXME kill magic
720 b43_write16(dev, 0x688, b43_read16(dev, 0x688) | 0x4);
721
722 /*TODO: We might need some stack support here to get the values. */
723} 729}