Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 246908
b: refs/heads/master
c: 44c866a
h: refs/heads/master
v: v3
  • Loading branch information
John W. Linville committed Apr 19, 2011
1 parent 916a455 commit 7ad4660
Show file tree
Hide file tree
Showing 111 changed files with 3,830 additions and 2,963 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f212b43c4e4a8f6378c50ce18f3d271983b575a7
refs/heads/master: 44c866a0a57b08b7090be24ccb33679ed1d4f476
9 changes: 1 addition & 8 deletions trunk/drivers/net/wireless/ath/ath.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,7 @@ struct ath_ops {
};

struct ath_common;

struct ath_bus_ops {
enum ath_bus_type ath_bus_type;
void (*read_cachesize)(struct ath_common *common, int *csz);
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
void (*bt_coex_prep)(struct ath_common *common);
void (*extn_synch_en)(struct ath_common *common);
};
struct ath_bus_ops;

struct ath_common {
void *ah;
Expand Down
28 changes: 28 additions & 0 deletions trunk/drivers/net/wireless/ath/ath5k/ahb.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <linux/nl80211.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h>
#include <ar231x_platform.h>
#include "ath5k.h"
#include "debug.h"
Expand Down Expand Up @@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
return 0;
}

static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
struct ath5k_softc *sc = ah->ah_sc;
struct platform_device *pdev = to_platform_device(sc->dev);
struct ar231x_board_config *bcfg = pdev->dev.platform_data;
u8 *cfg_mac;

if (to_platform_device(sc->dev)->id == 0)
cfg_mac = bcfg->config->wlan0_mac;
else
cfg_mac = bcfg->config->wlan1_mac;

memcpy(mac, cfg_mac, ETH_ALEN);
return 0;
}

static const struct ath_bus_ops ath_ahb_bus_ops = {
.ath_bus_type = ATH_AHB,
.read_cachesize = ath5k_ahb_read_cachesize,
.eeprom_read = ath5k_ahb_eeprom_read,
.eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
};

/*Initialization*/
Expand Down Expand Up @@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev)
else
reg |= AR5K_AR5312_ENABLE_WLAN1;
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);

/*
* On a dual-band AR5312, the multiband radio is only
* used as pass-through. Disable 2 GHz support in the
* driver for it
*/
if (to_platform_device(sc->dev)->id == 0 &&
(bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
(BD_WLAN1|BD_WLAN0))
__set_bit(ATH_STAT_2G_DISABLED, sc->status);
}

ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
Expand Down
31 changes: 24 additions & 7 deletions trunk/drivers/net/wireless/ath/ath5k/ath5k.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@

/* SIFS */
#define AR5K_INIT_SIFS_TURBO 6
/* XXX: 8 from initvals 10 from standard */
#define AR5K_INIT_SIFS_DEFAULT_BG 8
#define AR5K_INIT_SIFS_DEFAULT_BG 10
#define AR5K_INIT_SIFS_DEFAULT_A 16
#define AR5K_INIT_SIFS_HALF_RATE 32
#define AR5K_INIT_SIFS_QUARTER_RATE 64
Expand Down Expand Up @@ -453,12 +452,10 @@ struct ath5k_tx_status {
u16 ts_seqnum;
u16 ts_tstamp;
u8 ts_status;
u8 ts_rate[4];
u8 ts_retry[4];
u8 ts_final_idx;
u8 ts_final_retry;
s8 ts_rssi;
u8 ts_shortretry;
u8 ts_longretry;
u8 ts_virtcol;
u8 ts_antenna;
};
Expand Down Expand Up @@ -875,6 +872,19 @@ enum ath5k_int {
AR5K_INT_QTRIG = 0x40000000, /* Non common */
AR5K_INT_GLOBAL = 0x80000000,

AR5K_INT_TX_ALL = AR5K_INT_TXOK
| AR5K_INT_TXDESC
| AR5K_INT_TXERR
| AR5K_INT_TXEOL
| AR5K_INT_TXURN,

AR5K_INT_RX_ALL = AR5K_INT_RXOK
| AR5K_INT_RXDESC
| AR5K_INT_RXERR
| AR5K_INT_RXNOFRM
| AR5K_INT_RXEOL
| AR5K_INT_RXORN,

AR5K_INT_COMMON = AR5K_INT_RXOK
| AR5K_INT_RXDESC
| AR5K_INT_RXERR
Expand Down Expand Up @@ -1058,6 +1068,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;
bool ah_short_slot;

/* Antenna Control */
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
Expand Down Expand Up @@ -1144,6 +1155,13 @@ struct ath5k_hw {
struct ath5k_rx_status *);
};

struct ath_bus_ops {
enum ath_bus_type ath_bus_type;
void (*read_cachesize)(struct ath_common *common, int *csz);
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac);
};

/*
* Prototypes
*/
Expand Down Expand Up @@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah);
/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
void ath5k_eeprom_detach(struct ath5k_hw *ah);
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);


/* Protocol Control Unit Functions */
/* Helpers */
int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
int len, struct ieee80211_rate *rate);
int len, struct ieee80211_rate *rate, bool shortpre);
unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
Expand Down
7 changes: 6 additions & 1 deletion trunk/drivers/net/wireless/ath/ath5k/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc)
goto err;
}

if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
__clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
__clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
}

/* Crypto settings */
common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);

if (srev >= AR5K_SREV_AR5212_V4 &&
(ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
(ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
!AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;

Expand Down
71 changes: 56 additions & 15 deletions trunk/drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
return true;
}

static void
ath5k_set_current_imask(struct ath5k_softc *sc)
{
enum ath5k_int imask = sc->imask;
unsigned long flags;

spin_lock_irqsave(&sc->irqlock, flags);
if (sc->rx_pending)
imask &= ~AR5K_INT_RX_ALL;
if (sc->tx_pending)
imask &= ~AR5K_INT_TX_ALL;
ath5k_hw_set_imr(sc->ah, imask);
spin_unlock_irqrestore(&sc->irqlock, flags);
}

static void
ath5k_tasklet_rx(unsigned long data)
{
Expand Down Expand Up @@ -1506,6 +1521,8 @@ ath5k_tasklet_rx(unsigned long data)
} while (ath5k_rxbuf_setup(sc, bf) == 0);
unlock:
spin_unlock(&sc->rxbuflock);
sc->rx_pending = false;
ath5k_set_current_imask(sc);
}


Expand Down Expand Up @@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
struct ath5k_txq *txq, struct ath5k_tx_status *ts)
{
struct ieee80211_tx_info *info;
u8 tries[3];
int i;

sc->stats.tx_all_count++;
sc->stats.tx_bytes_count += skb->len;
info = IEEE80211_SKB_CB(skb);

tries[0] = info->status.rates[0].count;
tries[1] = info->status.rates[1].count;
tries[2] = info->status.rates[2].count;

ieee80211_tx_info_clear_status(info);
for (i = 0; i < 4; i++) {

for (i = 0; i < ts->ts_final_idx; i++) {
struct ieee80211_tx_rate *r =
&info->status.rates[i];

if (ts->ts_rate[i]) {
r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
r->count = ts->ts_retry[i];
} else {
r->idx = -1;
r->count = 0;
}
r->count = tries[i];
}

/* count the successful attempt as well */
info->status.rates[ts->ts_final_idx].count++;
info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
info->status.rates[ts->ts_final_idx + 1].idx = -1;

if (unlikely(ts->ts_status)) {
sc->stats.ack_fail++;
Expand All @@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
} else {
info->flags |= IEEE80211_TX_STAT_ACK;
info->status.ack_signal = ts->ts_rssi;

/* count the successful attempt as well */
info->status.rates[ts->ts_final_idx].count++;
}

/*
Expand Down Expand Up @@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data)
for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
ath5k_tx_processq(sc, &sc->txqs[i]);

sc->tx_pending = false;
ath5k_set_current_imask(sc);
}


Expand Down Expand Up @@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
* AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
}

static void
ath5k_schedule_rx(struct ath5k_softc *sc)
{
sc->rx_pending = true;
tasklet_schedule(&sc->rxtq);
}

static void
ath5k_schedule_tx(struct ath5k_softc *sc)
{
sc->tx_pending = true;
tasklet_schedule(&sc->txtq);
}

irqreturn_t
ath5k_intr(int irq, void *dev_id)
{
Expand Down Expand Up @@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id)
ieee80211_queue_work(sc->hw, &sc->reset_work);
}
else
tasklet_schedule(&sc->rxtq);
ath5k_schedule_rx(sc);
} else {
if (status & AR5K_INT_SWBA) {
tasklet_hi_schedule(&sc->beacontq);
Expand All @@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id)
ath5k_hw_update_tx_triglevel(ah, true);
}
if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
tasklet_schedule(&sc->rxtq);
ath5k_schedule_rx(sc);
if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
| AR5K_INT_TXERR | AR5K_INT_TXEOL))
tasklet_schedule(&sc->txtq);
ath5k_schedule_tx(sc);
if (status & AR5K_INT_BMISS) {
/* TODO */
}
Expand All @@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id)

} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);

if (sc->rx_pending || sc->tx_pending)
ath5k_set_current_imask(sc);

if (unlikely(!counter))
ATH5K_WARN(sc, "too many interrupts, giving up for now\n");

Expand Down Expand Up @@ -2572,6 +2612,8 @@ ath5k_init_hw(struct ath5k_softc *sc)

static void stop_tasklets(struct ath5k_softc *sc)
{
sc->rx_pending = false;
sc->tx_pending = false;
tasklet_kill(&sc->rxtq);
tasklet_kill(&sc->txtq);
tasklet_kill(&sc->calib);
Expand Down Expand Up @@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw)
INIT_WORK(&sc->reset_work, ath5k_reset_work);
INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);

ret = ath5k_eeprom_read_mac(ah, mac);
ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
if (ret) {
ATH5K_ERR(sc, "unable to read address from EEPROM\n");
goto err_queues;
Expand Down Expand Up @@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc)
* XXX: ??? detach ath5k_hw ???
* Other than that, it's straightforward...
*/
ath5k_debug_finish_device(sc);
ieee80211_unregister_hw(hw);
ath5k_desc_free(sc);
ath5k_txq_release(sc);
Expand Down
7 changes: 6 additions & 1 deletion trunk/drivers/net/wireless/ath/ath5k/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,13 @@ struct ath5k_softc {
dma_addr_t desc_daddr; /* DMA (physical) address */
size_t desc_len; /* size of TX/RX descriptors */

DECLARE_BITMAP(status, 5);
DECLARE_BITMAP(status, 6);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
#define ATH_STAT_PROMISC 2
#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */

unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
struct ieee80211_channel *curchan; /* current h/w channel */
Expand All @@ -207,6 +208,10 @@ struct ath5k_softc {

enum ath5k_int imask; /* interrupt mask copy */

spinlock_t irqlock;
bool rx_pending; /* rx tasklet pending */
bool tx_pending; /* tx tasklet pending */

u8 lladdr[ETH_ALEN];
u8 bssidmask[ETH_ALEN];

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/ath/ath5k/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
}
}

if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112)
__clear_bit(AR5K_MODE_11A, caps->cap_mode);

/* Set number of supported TX queues */
if (ah->ah_version == AR5K_AR5210)
caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU;
Expand Down
Loading

0 comments on commit 7ad4660

Please sign in to comment.