summaryrefslogtreecommitdiffstats
path: root/package/b43/src/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/b43/src/xmit.c')
-rw-r--r--package/b43/src/xmit.c177
1 files changed, 88 insertions, 89 deletions
diff --git a/package/b43/src/xmit.c b/package/b43/src/xmit.c
index 4014b6c82..f9e1cff2a 100644
--- a/package/b43/src/xmit.c
+++ b/package/b43/src/xmit.c
@@ -30,6 +30,7 @@
#include "xmit.h"
#include "phy.h"
#include "dma.h"
+#include "pio.h"
/* Extract the bitrate index out of a CCK PLCP header. */
@@ -184,14 +185,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u8 *_txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
+ const struct ieee80211_tx_info *info,
u16 cookie)
{
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
const struct b43_phy *phy = &dev->phy;
const struct ieee80211_hdr *wlhdr =
(const struct ieee80211_hdr *)fragment_data;
- int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
+ int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
u16 fctl = le16_to_cpu(wlhdr->frame_control);
struct ieee80211_rate *fbrate;
u8 rate, rate_fb;
@@ -200,13 +201,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u32 mac_ctl = 0;
u16 phy_ctl = 0;
u8 extra_ft = 0;
+ struct ieee80211_rate *txrate;
memset(txhdr, 0, sizeof(*txhdr));
- WARN_ON(!txctl->tx_rate);
- rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
+ txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
+ rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
rate_ofdm = b43_is_ofdm_rate(rate);
- fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
+ fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : txrate;
rate_fb = fbrate->hw_value;
rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
@@ -226,15 +228,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
* use the original dur_id field. */
txhdr->dur_fb = wlhdr->duration_id;
} else {
- txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
- txctl->vif,
- fragment_len,
- fbrate);
+ txhdr->dur_fb = ieee80211_generic_frame_duration(
+ dev->wl->hw, info->control.vif, fragment_len, fbrate);
}
plcp_fragment_len = fragment_len + FCS_LEN;
if (use_encryption) {
- u8 key_idx = (u16) (txctl->key_idx);
+ u8 key_idx = info->control.hw_key->hw_key_idx;
struct b43_key *key;
int wlhdr_len;
size_t iv_len;
@@ -252,7 +252,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
}
/* Hardware appends ICV. */
- plcp_fragment_len += txctl->icv_len;
+ plcp_fragment_len += info->control.icv_len;
key_idx = b43_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
@@ -260,7 +260,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG;
wlhdr_len = ieee80211_get_hdrlen(fctl);
- iv_len = min((size_t) txctl->iv_len,
+ iv_len = min((size_t) info->control.iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
}
@@ -291,10 +291,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
phy_ctl |= B43_TXH_PHY_ENC_OFDM;
else
phy_ctl |= B43_TXH_PHY_ENC_CCK;
- if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+ if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
- switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
+ switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
case 0: /* Default */
phy_ctl |= B43_TXH_PHY_ANT01AUTO;
break;
@@ -315,34 +315,36 @@ int b43_generate_txhdr(struct b43_wldev *dev,
}
/* MAC control */
- if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK;
if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
mac_ctl |= B43_TXH_MAC_HWSEQ;
- if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43_TXH_MAC_STMSDU;
if (phy->type == B43_PHYTYPE_A)
mac_ctl |= B43_TXH_MAC_5GHZ;
- if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+ if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
mac_ctl |= B43_TXH_MAC_LONGFRAME;
/* Generate the RTS or CTS-to-self frame */
- if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
- (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+ if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+ (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
unsigned int len;
struct ieee80211_hdr *hdr;
int rts_rate, rts_rate_fb;
int rts_rate_ofdm, rts_rate_fb_ofdm;
struct b43_plcp_hdr6 *plcp;
+ struct ieee80211_rate *rts_cts_rate;
- WARN_ON(!txctl->rts_cts_rate);
- rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
+ rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
+
+ rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
rts_rate_fb = b43_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
- if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+ if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
struct ieee80211_cts *cts;
if (b43_is_old_txhdr_format(dev)) {
@@ -352,9 +354,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
cts = (struct ieee80211_cts *)
(txhdr->new_format.rts_frame);
}
- ieee80211_ctstoself_get(dev->wl->hw, txctl->vif,
+ ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
fragment_data, fragment_len,
- txctl, cts);
+ info, cts);
mac_ctl |= B43_TXH_MAC_SENDCTS;
len = sizeof(struct ieee80211_cts);
} else {
@@ -367,9 +369,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
rts = (struct ieee80211_rts *)
(txhdr->new_format.rts_frame);
}
- ieee80211_rts_get(dev->wl->hw, txctl->vif,
+ ieee80211_rts_get(dev->wl->hw, info->control.vif,
fragment_data, fragment_len,
- txctl, rts);
+ info, rts);
mac_ctl |= B43_TXH_MAC_SENDRTS;
len = sizeof(struct ieee80211_rts);
}
@@ -512,7 +514,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
u32 macstat;
u16 chanid;
u16 phytype;
- u8 jssi;
int padding;
memset(&status, 0, sizeof(status));
@@ -520,7 +521,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
/* Get metadata about the frame from the header. */
phystat0 = le16_to_cpu(rxhdr->phy_status0);
phystat3 = le16_to_cpu(rxhdr->phy_status3);
- jssi = rxhdr->jssi;
macstat = le32_to_cpu(rxhdr->mac_status);
mactime = le16_to_cpu(rxhdr->mac_time);
chanstat = le16_to_cpu(rxhdr->channel);
@@ -574,13 +574,21 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
}
}
- status.ssi = b43_rssi_postprocess(dev, jssi,
- (phystat0 & B43_RX_PHYST0_OFDM),
- (phystat0 & B43_RX_PHYST0_GAINCTL),
- (phystat3 & B43_RX_PHYST3_TRSTATE));
+ /* Link quality statistics */
status.noise = dev->stats.link_noise;
- /* the next line looks wrong, but is what mac80211 wants */
- status.signal = (jssi * 100) / B43_RX_MAX_SSI;
+ if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
+// s8 rssi = max(rxhdr->power0, rxhdr->power1);
+ //TODO: Find out what the rssi value is (dBm or percentage?)
+ // and also find out what the maximum possible value is.
+ // Fill status.ssi and status.signal fields.
+ } else {
+ status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
+ (phystat0 & B43_RX_PHYST0_OFDM),
+ (phystat0 & B43_RX_PHYST0_GAINCTL),
+ (phystat3 & B43_RX_PHYST3_TRSTATE));
+ status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
+ }
+
if (phystat0 & B43_RX_PHYST0_OFDM)
status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
phytype == B43_PHYTYPE_A);
@@ -589,12 +597,16 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
/*
- * If monitors are present get full 64-bit timestamp. This
- * code assumes we get to process the packet within 16 bits
- * of timestamp, i.e. about 65 milliseconds after the PHY
- * received the first symbol.
+ * All frames on monitor interfaces and beacons always need a full
+ * 64-bit timestamp. Monitor interfaces need it for diagnostic
+ * purposes and beacons for IBSS merging.
+ * This code assumes we get to process the packet within 16 bits
+ * of timestamp, i.e. about 65 milliseconds after the PHY received
+ * the first symbol.
*/
- if (dev->wl->radiotap_enabled) {
+ if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
+ == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
+ dev->wl->radiotap_enabled) {
u16 low_mactime_now;
b43_tsf_read(dev, &status.mactime);
@@ -664,67 +676,54 @@ void b43_handle_txstatus(struct b43_wldev *dev,
dev->wl->ieee_stats.dot11RTSSuccessCount++;
}
- b43_dma_handle_txstatus(dev, status);
+ if (b43_using_pio_transfers(dev))
+ b43_pio_handle_txstatus(dev, status);
+ else
+ b43_dma_handle_txstatus(dev, status);
}
-/* Handle TX status report as received through DMA/PIO queues */
-void b43_handle_hwtxstatus(struct b43_wldev *dev,
- const struct b43_hwtxstatus *hw)
+/* Fill out the mac80211 TXstatus report based on the b43-specific
+ * txstatus report data. This returns a boolean whether the frame was
+ * successfully transmitted. */
+bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+ const struct b43_txstatus *status)
{
- struct b43_txstatus status;
- u8 tmp;
-
- status.cookie = le16_to_cpu(hw->cookie);
- status.seq = le16_to_cpu(hw->seq);
- status.phy_stat = hw->phy_stat;
- tmp = hw->count;
- status.frame_count = (tmp >> 4);
- status.rts_count = (tmp & 0x0F);
- tmp = hw->flags;
- status.supp_reason = ((tmp & 0x1C) >> 2);
- status.pm_indicated = !!(tmp & 0x80);
- status.intermediate = !!(tmp & 0x40);
- status.for_ampdu = !!(tmp & 0x20);
- status.acked = !!(tmp & 0x02);
-
- b43_handle_txstatus(dev, &status);
+ bool frame_success = 1;
+
+ if (status->acked) {
+ /* The frame was ACKed. */
+ report->flags |= IEEE80211_TX_STAT_ACK;
+ } else {
+ /* The frame was not ACKed... */
+ if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ /* ...but we expected an ACK. */
+ frame_success = 0;
+ report->status.excessive_retries = 1;
+ }
+ }
+ if (status->frame_count == 0) {
+ /* The frame was not transmitted at all. */
+ report->status.retry_count = 0;
+ } else
+ report->status.retry_count = status->frame_count - 1;
+
+ return frame_success;
}
/* Stop any TX operation on the device (suspend the hardware queues) */
void b43_tx_suspend(struct b43_wldev *dev)
{
- b43_dma_tx_suspend(dev);
+ if (b43_using_pio_transfers(dev))
+ b43_pio_tx_suspend(dev);
+ else
+ b43_dma_tx_suspend(dev);
}
/* Resume any TX operation on the device (resume the hardware queues) */
void b43_tx_resume(struct b43_wldev *dev)
{
- b43_dma_tx_resume(dev);
-}
-
-#if 0
-static void upload_qos_parms(struct b43_wldev *dev,
- const u16 * parms, u16 offset)
-{
- int i;
-
- for (i = 0; i < B43_NR_QOSPARMS; i++) {
- b43_shm_write16(dev, B43_SHM_SHARED,
- offset + (i * 2), parms[i]);
- }
-}
-#endif
-
-/* Initialize the QoS parameters */
-void b43_qos_init(struct b43_wldev *dev)
-{
- /* FIXME: This function must probably be called from the mac80211
- * config callback. */
- return;
-
- b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
- //FIXME kill magic
- b43_write16(dev, 0x688, b43_read16(dev, 0x688) | 0x4);
-
- /*TODO: We might need some stack support here to get the values. */
+ if (b43_using_pio_transfers(dev))
+ b43_pio_tx_resume(dev);
+ else
+ b43_dma_tx_resume(dev);
}