2007-10-06 01:03:26

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 0/6] ath5k: initvals, radar, promiscuous bug and multicast

This patch series adds a few things which have been sitting in my
queue. The most important change is the proper fix for the promiscuous
bug.

Luis


2007-10-06 01:17:14

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 2/6] ath5k: Enable radar detection

Enable radar detection, and clean up ath5k_hw_attach() definition.

Specifically this patch:

o On struct ath_hw:
* renames ah_sh to ah_iobase to make its use clear
* move ah_sc to non-opaque struct, as we only currently use
it as struct ath_softc. We we add SoC support we can figure
an alternative.
* Move out radar struct definition into new struct ath_radar

o On ath5k_hw_attach() we currenlty pass the ath_sofct struct and
sc->iobase. No point in passing both since we're already passing sc.

o Remove any comments referring to a "HAL". We don't have one anymore.
Another patch later will replace 'hal' -> 'ahw'.

o On ath5k_hw_get_isr() only read AR5K_RAC_PISR on non-AR5210s

o Capture AR5K_IMR_RXPHY and pass it as AR5K_INT_RXPHY to our
interrupt handler. Upon detection call ath5k_radar_alert(). Upper
layers need radar detection handling support. Right now just
announce detection. We enable radar detection through new
ath5k_hw_enable_radar_alert().

Changes to ath5k_base.[ch]
Changes-licensed-under: 3-clause-BSD

Changes to ath5k.h, hw.c
Changes-licensed-under: ISC
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 65 +++++++++++++++++--------------
drivers/net/wireless/ath5k/base.c | 44 ++++++++++++++++-----
drivers/net/wireless/ath5k/base.h | 2 +-
drivers/net/wireless/ath5k/hw.c | 74 +++++++++++++++++++++++++++++-------
4 files changed, 130 insertions(+), 55 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 9308916..445fde8 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -274,10 +274,10 @@ enum ath5k_tx_queue_subtype {
};

/*
- * Queue ID numbers as returned by the HAL, each number
- * represents a hw queue. If hw does not support hw queues
- * (eg 5210) all data goes in one queue. These match
- * d80211 definitions (net80211/MadWiFi don't use them).
+ * Queue ID numbers as used by ath5k_hw_setup_tx_queue() and
+ * ath5k_hw_wait_for_beacon(). Each number represents a hw queue.
+ * If hw does not support hw queues (eg 5210) all data goes in one
+ * queue. These match mac0211 definitions.
*/
enum ath5k_tx_queue_id {
AR5K_TX_QUEUE_ID_NOQCU_DATA = 0,
@@ -323,7 +323,8 @@ struct ath5k_txq_info {

/*
* Transmit packet types.
- * These are not fully used inside OpenHAL yet
+ * These are currently only used in ath5k_hw_setup_2word_tx_desc() to
+ * distinguish frame types on AR5210.
*/
enum ath5k_pkt_type {
AR5K_PKT_TYPE_NORMAL = 0,
@@ -573,8 +574,7 @@ struct ath_desc {
#define CHANNEL_MODES CHANNEL_ALL

/*
- * Used internaly in OpenHAL (ar5211.c/ar5212.c
- * for reset_tx_queue). Also see struct struct ieee80211_channel.
+ * Used internaly in ath5k_hw_reset_tx_queue()
*/
#define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0)
#define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0)
@@ -717,13 +717,14 @@ enum ath5k_ant_setting {
};

/*
- * HAL interrupt abstraction
+ * Hardware interrupt masks helpers
*/

/*
* These are mapped to take advantage of some common bits
* between the MAC chips, to be able to set intr properties
- * easier. Some of them are not used yet inside OpenHAL.
+ * easier. Some of them are not used yet inside hw.c. Most map
+ * to the respective hw interrupt value.
*/
enum ath5k_int {
AR5K_INT_RX = 0x00000001,
@@ -773,8 +774,8 @@ enum ath5k_power_mode {
};

/*
- * These match net80211 definitions (not used in
- * d80211).
+ * These match net80211 definitions
+ * XXX: move to mac80211 led work
*/
#define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/
#define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/
@@ -788,9 +789,8 @@ enum ath5k_power_mode {
#define AR5K_SOFTLED_OFF 1

/*
- * Chipset capabilities -see ath_hal_getcapability-
- * get_capability function is not yet fully implemented
- * in OpenHAL so most of these don't work yet...
+ * Chipset capabilities. See ath5k_hw_get_capability(),
+ * we do what we can as we make progress
*/
enum ath5k_capability_type {
AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */
@@ -862,14 +862,20 @@ struct ath5k_capabilities {
* Misc defines
*/

+struct ath_radar {
+ bool r_enabled;
+ int r_last_alert;
+ struct ieee80211_channel r_last_channel;
+};
+
#define AR5K_MAX_GPIO 10
#define AR5K_MAX_RF_BANKS 8

struct ath_hw {
u32 ah_magic;

- void *ah_sc;
- void __iomem *ah_sh;
+ struct ath_softc *ah_sc;
+ void __iomem *ah_iobase;
enum ath5k_countrycode ah_country_code;

enum ath5k_int ah_imr;
@@ -937,11 +943,7 @@ struct ath_hw {
s16 txp_ofdm;
} ah_txpower;

- struct {
- bool r_enabled;
- int r_last_alert;
- struct ieee80211_channel r_last_channel;
- } ah_radar;
+ struct ath_radar ah_radar;

/*
* Function pointers
@@ -966,7 +968,8 @@ struct ath_hw {
/* General Functions */
extern int ath5k_hw_register_timeout(struct ath_hw *hal, u32 reg, u32 flag, u32 val, bool is_set);
/* Attach/Detach Functions */
-extern struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc, void __iomem *sh);
+extern struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version,
+ struct ath_softc *sc);
extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath_hw *hal, unsigned int mode);
extern void ath5k_hw_detach(struct ath_hw *hal);
/* Reset Functions */
@@ -981,12 +984,15 @@ extern void ath5k_hw_put_rx_buf(struct ath_hw *hal, u32 phys_addr);
extern int ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue);
extern int ath5k_hw_stop_tx_dma(struct ath_hw *hal, unsigned int queue);
extern u32 ath5k_hw_get_tx_buf(struct ath_hw *hal, unsigned int queue);
-extern int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr);
+extern int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue,
+ u32 phys_addr);
extern int ath5k_hw_update_tx_triglevel(struct ath_hw *hal, bool increase);
/* Interrupt handling */
extern bool ath5k_hw_is_intr_pending(struct ath_hw *hal);
extern int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask);
-extern enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal, enum ath5k_int new_mask);
+extern enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal,
+ enum ath5k_int new_mask);
+extern void ath5k_hw_enable_radar_alert(struct ath_hw *hal, bool enable);
/* EEPROM access functions */
extern int ath5k_hw_set_regdomain(struct ath_hw *hal, u16 regdomain);
/* Protocol Control Unit Functions */
@@ -994,7 +1000,8 @@ extern int ath5k_hw_set_opmode(struct ath_hw *hal);
/* BSSID Functions */
extern void ath5k_hw_get_lladdr(struct ath_hw *hal, u8 *mac);
extern int ath5k_hw_set_lladdr(struct ath_hw *hal, const u8 *mac);
-extern void ath5k_hw_set_associd(struct ath_hw *hal, const u8 *bssid, u16 assoc_id);
+extern void ath5k_hw_set_associd(struct ath_hw *hal,
+ const u8 *bssid, u16 assoc_id);
extern int ath5k_hw_set_bssid_mask(struct ath_hw *hal, const u8 *mask);
/* Receive start/stop functions */
extern void ath5k_hw_start_rx_pcu(struct ath_hw *hal);
@@ -1073,14 +1080,14 @@ extern int ath5k_hw_txpower(struct ath_hw *hal, struct ieee80211_channel *channe
extern int ath5k_hw_set_txpower_limit(struct ath_hw *hal, unsigned int power);


-static inline u32 ath5k_hw_reg_read(struct ath_hw *hal, u16 reg)
+static inline u32 ath5k_hw_reg_read(struct ath_hw *ahw, u16 reg)
{
- return ioread32(hal->ah_sh + reg);
+ return ioread32(ahw->ah_iobase + reg);
}

-static inline void ath5k_hw_reg_write(struct ath_hw *hal, u32 val, u16 reg)
+static inline void ath5k_hw_reg_write(struct ath_hw *ahw, u32 val, u16 reg)
{
- iowrite32(val, hal->ah_sh + reg);
+ iowrite32(val, ahw->ah_iobase + reg);
}

#endif
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index afcc7e1..fa591eb 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -114,9 +114,8 @@ module_param_named(debug, ath_debug, uint, 0);
#endif

/*
- * User a static table of PCI id's for now. While this is the
- * "new way" to do things, we may want to switch back to having
- * the HAL check them by defining a probe method.
+ * ath5k_hw_attach() may also do further checking. Some devices keep the same
+ * PCI vendor:device ID but may differ. ath5k_hw_attach() will check there.
*/
static struct pci_device_id ath_pci_id_table[] __devinitdata = {
{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
@@ -596,7 +595,7 @@ static void ath_beacon_send(struct ath_softc *sc)
if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
printk(KERN_WARNING "ath: beacon queue %u didn't stop?\n",
sc->bhalq);
- /* NB: the HAL still stops DMA, so proceed */
+ /* ath5k_hw_stop_tx_dma() still stops DMA, so proceed */
}
pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len,
PCI_DMA_TODEVICE);
@@ -717,6 +716,8 @@ static void ath_beacon_config(struct ath_softc *sc)
ath5k_hw_hasveol(ah))
ath_beacon_send(sc);
}
+ /* Enable radar alerts */
+ ath5k_hw_enable_radar_alert(ah, true);
#undef TSF_TO_TU
}

@@ -1135,7 +1136,7 @@ static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
*
* XXX needed?
*/
-/* ath_chan_change(sc, chan); */
+ //ath_chan_set(sc, sc->curchan);

/*
* Re-enable interrupts.
@@ -1260,10 +1261,6 @@ static int ath_reset(struct ieee80211_hw *hw)
int ret;

DPRINTF(sc, ATH_DEBUG_RESET, "resetting\n");
- /*
- * Convert to a HAL channel description with the flags
- * constrained to reflect the current operating mode.
- */
sc->curchan = hw->conf.chan;

ath5k_hw_set_intr(ah, 0);
@@ -1289,7 +1286,7 @@ static int ath_reset(struct ieee80211_hw *hw)
*
* XXX needed?
*/
-/* ath_chan_change(sc, c); */
+ //ath_chan_set(sc, sc->curchan);
ath_beacon_config(sc);
/* intrs are started by ath_beacon_config */

@@ -1669,6 +1666,28 @@ static void ath_led_event(struct ath_softc *sc, int event)
}
}

+static void ath5k_radar_alert(struct ath_hw *ahw)
+{
+ struct ath_radar *radar = &ahw->ah_radar;
+ struct ieee80211_channel *radar_chan = &radar->r_last_channel;
+ struct ieee80211_channel *curr_chan = &ahw->ah_current_channel;
+
+ /* Limit ~1/s */
+ if (radar_chan->chan == curr_chan->chan &&
+ jiffies < (radar->r_last_alert + 1 * HZ))
+ return;
+
+ memcpy(radar_chan, curr_chan, sizeof(struct ieee80211_channel));
+ radar->r_last_alert = jiffies;
+
+ dev_info(&ahw->ah_sc->pdev->dev,
+ "Possible radar activity detected at "
+ "%u MHz (jiffies %u)\n", radar->r_last_alert,
+ curr_chan->chan);
+
+ /* Higher layer should probably do something here... TBC */
+}
+
static irqreturn_t ath_intr(int irq, void *dev_id)
{
struct ath_softc *sc = dev_id;
@@ -1701,6 +1720,9 @@ static irqreturn_t ath_intr(int irq, void *dev_id)
tasklet_schedule(&sc->restq);
} else if (unlikely(status & AR5K_INT_RXORN)) {
tasklet_schedule(&sc->restq);
+ } else if ((unlikely(status & AR5K_INT_RXPHY)) &&
+ ah->ah_radar.r_enabled) {
+ ath5k_radar_alert(ah);
} else {
if (status & AR5K_INT_SWBA) {
/*
@@ -2373,7 +2395,7 @@ static int __devinit ath_pci_probe(struct pci_dev *pdev,
goto err_free;
}

- sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc, sc->iobase);
+ sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc);
if (IS_ERR(sc->ah)) {
ret = PTR_ERR(sc->ah);
goto err_irq;
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index 4a624cc..1bd1d1f 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -191,7 +191,7 @@ struct ath_softc {
struct tasklet_struct txtq; /* tx intr tasklet */

struct ath_buf *bbuf; /* beacon buffer */
- unsigned int bhalq, /* HAL q for outgoing beacons */
+ unsigned int bhalq, /* Hw q for outgoing beacons */
bmisscount, /* missed beacon transmits */
bintval, /* beacon interval */
bsent;
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index ae4c5b5..6ef492c 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -21,7 +21,7 @@
*/

/*
- * HAL interface for Atheros Wireless LAN devices.
+ * Hardware interface for Atheros Wireless LAN devices.
*/

#include <linux/pci.h>
@@ -29,6 +29,7 @@

#include "ath5k.h"
#include "reg.h"
+#include "base.h"

/*Rate tables*/
static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
@@ -191,8 +192,8 @@ int ath5k_hw_register_timeout(struct ath_hw *hal, u32 reg, u32 flag, u32 val,
/*
* Check if the device is supported and initialize the needed structs
*/
-struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
- void __iomem *sh)
+struct ath_hw *ath5k_hw_attach(u16 device,
+ u8 mac_version, struct ath_softc *sc)
{
struct ath_hw *hal;
u8 mac[ETH_ALEN];
@@ -208,10 +209,10 @@ struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
}

hal->ah_sc = sc;
- hal->ah_sh = sh;
+ hal->ah_iobase = sc->iobase;

/*
- * HAL information
+ * Hardware cached data
*/

/* Regulation Stuff */
@@ -1474,14 +1475,15 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
return -ENODEV;
}
}
+ else {
+ /*
+ * Read interrupt status from the Read-And-Clear shadow register
+ */
+ data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
+ }

/*
- * Read interrupt status from the Read-And-Clear shadow register
- */
- data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
-
- /*
- * Get abstract interrupt mask (HAL-compatible)
+ * Get abstract interrupt mask
*/
*interrupt_mask = (data & AR5K_INT_COMMON) & hal->ah_imr;

@@ -1494,6 +1496,9 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR))
*interrupt_mask |= AR5K_INT_TX;

+ if (data & AR5K_IMR_RXPHY)
+ *interrupt_mask |= AR5K_INT_RXPHY;
+
if (hal->ah_version != AR5K_AR5210) {
/*HIU = Host Interface Unit (PCI etc)*/
if (unlikely(data & (AR5K_ISR_HIUERR)))
@@ -1504,12 +1509,14 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
*interrupt_mask |= AR5K_INT_BNR;
}

+#if 0
/*
* XXX: BMISS interrupts may occur after association.
- * I found this on 5210 code but it needs testing
+ * Needs testing.
*/
-#if 0
- interrupt_mask &= ~AR5K_INT_BMISS;
+ if (hal->ah_version != AR5K_AR5210) {
+ interrupt_mask &= ~AR5K_INT_BMISS;
+ }
#endif

/*
@@ -1570,6 +1577,45 @@ enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal, enum ath5k_int new_mask)
return old_mask;
}

+/*
+ * Enable HW radar detection
+ */
+void ath5k_hw_enable_radar_alert(struct ath_hw *ahw, bool enable)
+{
+
+ AR5K_TRACE;
+ /*
+ * Enable radar detection
+ */
+
+ /* Disable interupts */
+ ath5k_hw_reg_write(ahw, AR5K_IER_DISABLE, AR5K_IER);
+
+ /*
+ * Set the RXPHY interrupt to be able to detect
+ * possible radar activity.
+ */
+ if (ahw->ah_version == AR5K_AR5210) {
+ if (enable)
+ AR5K_REG_ENABLE_BITS(ahw, AR5K_IMR, AR5K_IMR_RXPHY);
+ else
+ AR5K_REG_DISABLE_BITS(ahw, AR5K_IMR, AR5K_IMR_RXPHY);
+ } else {
+ /* Also set AR5K_PHY_RADAR register on 5111/5112 */
+ if (enable) {
+ ath5k_hw_reg_write(ahw, AR5K_PHY_RADAR_ENABLE,
+ AR5K_PHY_RADAR);
+ AR5K_REG_ENABLE_BITS(ahw, AR5K_PIMR, AR5K_IMR_RXPHY);
+ } else {
+ ath5k_hw_reg_write(ahw, AR5K_PHY_RADAR_DISABLE,
+ AR5K_PHY_RADAR);
+ AR5K_REG_DISABLE_BITS(ahw, AR5K_PIMR, AR5K_IMR_RXPHY);
+ }
+ }
+
+ /* Re-enable interrupts */
+ ath5k_hw_reg_write(ahw, AR5K_IER_ENABLE, AR5K_IER);
+}

/*************************\
EEPROM access functions
--
1.5.2.5



2007-10-09 07:02:10

by Holger Schurig

[permalink] [raw]
Subject: Re: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

> You are right but i was on a trip
...
> I'll try again wireless-dev and I'll send a
> patch series here.

If you were away you might not have heard that wireless-dev is
dead. Use wireless-2.6 instead.

The chance that this boots is higher :-)


2007-10-10 08:44:12

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 4/6] ath5k: Add proper support for multicast

On Fri, 2007-10-05 at 21:19 -0400, Luis R. Rodriguez wrote:

> + /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
> + * set we should only pass on control frames for this
> + * station. This needs testing. I believe right now this
> + * enables *all* control frames */

Which is fine too, but not most efficient. Remember that the docs also
say you can pass up more frames, so an implementation that passes up
*all* frames at all times is correct in that it supports all filter
flags; it is, however, rather inefficient.

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-06 01:15:34

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

Ported new initval changes from OpenBSD to ath5k to ar5212_ini[] and
ar5212_ini_mode[]. This also adds an O(log(N)) bitswap for one byte
on ath5k_hw_bitswap(), thanks to Tom from OpenBSD. These changes
have been tested.

Changes-licensed-under: ISC
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/hw.h | 14 +++++++++---
drivers/net/wireless/ath5k/initvals.c | 34 +++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/hw.h
index d48754c..24da1c8 100644
--- a/drivers/net/wireless/ath5k/hw.h
+++ b/drivers/net/wireless/ath5k/hw.h
@@ -427,13 +427,11 @@ struct ath5k_hw_tx_status {
#define AR5K_INIT_CFG 0x00000000
#endif

-/*#define AR5K_REG_READ(_reg) ath5k_hw_reg_read(hal, _reg)
-
-#define AR5K_REG_WRITE(_reg, _val) ath5k_hw_reg_write(hal, _val, _reg)*/
-
+/* Shift and then mask */
#define AR5K_REG_SM(_val, _flags) \
(((_val) << _flags##_S) & (_flags))

+/* Mask and then shift */
#define AR5K_REG_MS(_val, _flags) \
(((_val) & (_flags)) >> _flags##_S)

@@ -579,6 +577,14 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
{
u32 retval = 0, bit, i;

+ /* O(log(N)) bitswap for one byte */
+ if (bits == 8) {
+ val = ((val & 0xF0) >> 4) | ((val & 0x0F) << 4);
+ val = ((val & 0xCC) >> 2) | ((val & 0x33) << 2);
+ val = ((val & 0xAA) >> 1) | ((val & 0x55) << 1);
+ return val;
+ }
+
for (i = 0; i < bits; i++) {
bit = (val >> i) & 1;
retval = (retval << 1) | bit;
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 11aeacc..1f96a86 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -710,6 +710,12 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_PHY(657), 0x00007bb6 },
{ AR5K_PHY(658), 0x0fff3ffc },
{ AR5K_PHY_CCKTXCTL, 0x00000000 },
+ { AR5K_BB_GAIN(0), 0x00000000 }, /* 0x9b00 */
+ { AR5K_BB_GAIN(10), 0x0000000c }, /* 0x9b28 */
+ { AR5K_BB_GAIN(14), 0x00000012 }, /* 0x9b38 */
+ { AR5K_BB_GAIN(25), 0x00000021 }, /* 0x9b64 */
+ { AR5K_BB_GAIN(35), 0x0000002d }, /* 0x9b8c */
+ { AR5K_BB_GAIN(39), 0x00000033 }, /* 0x9b9c */
};

/* Initial mode-specific settings for AR5212 */
@@ -747,6 +753,34 @@ static const struct ath5k_ini_mode ar5212_ini_mode[] = {
{ 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
{ AR5K_TIME_OUT,
{ 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+ { 0x9804,
+ { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+ { 0x9820,
+ { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+ { 0x9834,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x9838,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x9844,
+ { 0x1372161c, 0x13721c25, 0x13721728, 0x137216a2, 0x13721c25 } },
+ { 0x9850,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x9858,
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+ { 0x9860,
+ { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d10, 0x00009d10 } },
+ { 0x9864,
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x9868,
+ { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+ { 0x9918,
+ { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+ { 0x9924,
+ { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+ { 0xa180,
+ { 0x10ff14ff, 0x10ff14ff, 0x10ff10ff, 0x10ff19ff, 0x10ff19ff } },
+ { 0xa230,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
};

/* Initial mode-specific settings for AR5212 + RF5111 */
--
1.5.2.5


2007-10-06 01:21:41

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 0/6] ath5k: initvals, radar, promiscuous bug and multicast

On Fri, Oct 05, 2007 at 09:04:49PM -0400, Luis R. Rodriguez wrote:
> This patch series adds a few things which have been sitting in my
> queue. The most important change is the proper fix for the promiscuous
> bug.

And and forgot to add that I've tested the driver now on big endian.
I'm able to auth and assoc but the big-endian box is in an area where
the DHCP server sends the ACK to the IP and not broadcast so haven't
tested further. I can also tcpdump and scan well.

I'll keep testing as we go. This box will eventually be available of
anyone wanting to test on big endian.

Luis

2007-10-10 08:44:15

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 5/6] ath5k: Add documenation for atheros bssid_mask

On Fri, 2007-10-05 at 21:20 -0400, Luis R. Rodriguez wrote:

> + * Note that this is a simple filter and *does* not filter out all
> + * relevant frames. Some non-relevant frames will get through, probability
> + * jocks are welcomed to compute.

> + * IFRAME-05: 1101 --> allowed but its not for us!!!

This is why hostapd will always use a mask that ends with the bits you
want and basically requires that you reserve the full MAC address space
for all matching BSSIDs to that station. I.E. hostapd will set the mask
to 0x3 (or is it ~0x3? you know what I mean) if you have three or four
BSSIDs and if you only have three it is assumed that the fourth is
unused.

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-08 20:38:47

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

On Sun, Oct 07, 2007 at 02:49:23AM -0700, Nick Kossifidis wrote:
> 2007/10/5, Luis R. Rodriguez <[email protected]>:
> > Ported new initval changes from OpenBSD to ath5k to ar5212_ini[] and
> > ar5212_ini_mode[].
>
> NACK
>
> Nothing new was introduced in OpenBSD cvs that i haven't already
> included!, what have you ported ???

Actually, you are right, an oversight by my part. Thanks for catching
this. However after verying this I did find the one type. Please
review.

> > This also adds an O(log(N)) bitswap for one byte
> > on ath5k_hw_bitswap(), thanks to Tom from OpenBSD.
>
> ACK it's used for modifying rf buffer settings...

I think its easier to just new patches. I'll do so but please first
review the small change below.

Luis


diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 1537517..f826422 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1980,4 +1980,4 @@ after DFS is enabled */
#define AR5K_PHY_GAIN_2GHZ 0xa20c
#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000
#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18
-#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c
+#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6448416a

2007-10-08 20:48:54

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

On Sun, Oct 07, 2007 at 03:13:28AM -0700, Nick Kossifidis wrote:
> NACK i have a better fix wich uses chip srev, i had commited it on
> ath5k branch on madwifi svn...
>
> what's going on ? noone read my chagnes n ath5k branch on madwifi svn
> ? i did this change some time ago (over a month) and it seems you
> didn't even saw it...
>
> http://madwifi.org/changeset/2703
> http://madwifi.org/changeset/2704
>
> what happened to my changes ? you told me you would commit them here...

I had said I would but Jiri sent some patches based on your work which
I thought included your latest changes. Instead of bitching about
things you should start sending patches, that would be more helpful.

Anyway I actually like that approach more, thanks. John -- I'll send in a new
patch series.

Luis

2007-10-09 08:15:09

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

2007/10/9, Jiri Slaby <[email protected]>:
> On 10/09/2007 04:31 AM, Nick Kossifidis wrote:
> > I'll post a pach series asap here with my fixes against current
> > wireless-dev including your fixes on base.c/h and any other fixes
>
> Just a note, wireless-2.6 is current wireless tree.
>
>

ACK ;-)

Just booted it, i'll start making patches asap...

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-09 09:33:53

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

On Tue, 2007-10-09 at 09:05 +0200, Holger Schurig wrote:
> > There's an airport less
> > than 1 mile away and I've never detected true radar.
>
> Maybe you need to go to some russian military camp. Some russian
> surface-to-air missile systems used (20 years ago) frequency
> ranges in the 5 GHz area.

Indeed, I'm told most radars use 10GHz these days.

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-10 18:11:37

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 4/6] ath5k: Add proper support for multicast

On 10/9/07, Johannes Berg <[email protected]> wrote:
> On Fri, 2007-10-05 at 21:19 -0400, Luis R. Rodriguez wrote:
>
> > + /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
> > + * set we should only pass on control frames for this
> > + * station. This needs testing. I believe right now this
> > + * enables *all* control frames */
>
> Which is fine too, but not most efficient. Remember that the docs also
> say you can pass up more frames, so an implementation that passes up
> *all* frames at all times is correct in that it supports all filter
> flags; it is, however, rather inefficient.

Right, well I think we might be able to figure out way to do by th
BSSID, if it doesn't do so already. But I'll clean up the comments to
reflect this is OK then.

Luis

2007-10-09 15:59:18

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

On 10/9/07, Johannes Berg <[email protected]> wrote:
> On Tue, 2007-10-09 at 09:05 +0200, Holger Schurig wrote:
> > > There's an airport less
> > > than 1 mile away and I've never detected true radar.
> >
> > Maybe you need to go to some russian military camp. Some russian
> > surface-to-air missile systems used (20 years ago) frequency
> > ranges in the 5 GHz area.
>
> Indeed, I'm told most radars use 10GHz these days.

We'll just disable the filter for radar for now then and leave this
for later when someone wants DFS. We have other things we can work on
instead.

Luis

2007-10-06 01:28:27

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 4/6] ath5k: Add proper support for multicast

Add proper support for multicast and keep any HW imposed error filters.
There seems to be several ways to enable multicast. We choose right now
MadWifi's old implementation. We can later try ath5k_hw_set_mcast_filterindex()
as well.

ath5k_hw_get_rx_filter() may enable AR5K_RX_FILTER_RADARERR or
AR5K_RX_FILTER_PHYERR. We respect those calls in our configure_filter()

Changes to base.c
Changes-licensed-under: 3-clause-BSD

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/base.c | 64 ++++++++++++++++++++++++++++++------
1 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index b11a14b..325965a 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1397,8 +1397,15 @@ unlock:
FIF_BCN_PRBRESP_PROMISC
/*
* o always accept unicast, broadcast, and multicast traffic
- * o maintain current state of phy error reception (the hal
- * may enable phy error frames for noise immunity work)
+ * o multicast traffic for all BSSIDs will be enabled if mac80211
+ * says it should be
+ * o multicast traffic for all BSSIDs will be enabled if mac80211
+ * says it should be
+ * o maintain current state of radar error, phy ofdm or phy cck error reception.
+ * If the hardware detects any of these type of errors then
+ * ath5k_hw_get_rx_filter() will pass to us the respective
+ * hardware filters to be able to receive these type of frames.
+ * We do this to be safe, for noise immunity work.
* o probe request frames are accepted only when operating in
* hostap, adhoc, or monitor modes
* o enable promiscuous mode according to the interface state
@@ -1416,15 +1423,23 @@ static void ath_configure_filter(struct ieee80211_hw *hw,
{
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->ah;
- u32 rfilt;
+ u32 mfilt[2], val, rfilt;
+ u8 pos;
+ int i;
+
+ mfilt[0] = mfilt[1] = 0;

/* Only deal with supported flags */
changed_flags &= SUPPORTED_FIF_FLAGS;
*new_flags &= SUPPORTED_FIF_FLAGS;

- /* XXX: Start by enabling broadcasts and Unicast, move this later
- * to mac802111 and add a flag for these */
- rfilt = AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST;
+ /* If HW detects any phy or radar errors, leave those filters on.
+ * Also, always enable Unicast, Broadcasts and Multicast
+ * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
+ rfilt = (ath5k_hw_get_rx_filter(ah) &
+ (AR5K_RX_FILTER_RADARERR | AR5K_RX_FILTER_PHYERR)) |
+ ( AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
+ AR5K_RX_FILTER_MCAST);

if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
if (*new_flags & FIF_PROMISC_IN_BSS) {
@@ -1435,18 +1450,43 @@ static void ath_configure_filter(struct ieee80211_hw *hw,
__clear_bit(ATH_STAT_PROMISC, sc->status);
}

- if (*new_flags & FIF_ALLMULTI)
- rfilt |= AR5K_RX_FILTER_MCAST;
+ /* Note, AR5K_RX_FILTER_MCAST is already enabled */
+ if (*new_flags & FIF_ALLMULTI) {
+ mfilt[0] = mfilt[1] = ~0;
+ } else {
+ for (i = 0; i < mc_count; i++) {
+ if (!mclist)
+ break;
+ /* calculate XOR of eight 6-bit values */
+ val = LE_READ_4(mclist->dmi_addr + 0);
+ pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ val = LE_READ_4(mclist->dmi_addr + 3);
+ pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ pos &= 0x3f;
+ mfilt[pos / 32] |= (1 << (pos % 32));
+ /* XXX: we might be able to just do this instead,
+ * but not sure, needs testing, if we do use this we'd
+ * neet to inform below to not reset the mcast */
+ //ath5k_hw_set_mcast_filterindex(ah,
+ // mclist->dmi_addr[5]);
+ mclist = mclist->next;
+ }
+ }
+
+
/* This is the best we can do */
if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
rfilt |= AR5K_RX_FILTER_PHYERR;
+
/* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
* and probes for any BSSID, this needs testing */
if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
- /* FIF_CONTROL doc says that FIF_PROMISC_IN_BSS is not set we should
- * only pass on control frames for this station. This needs testing.
- * I believe right now this enables *all* control frames */
+
+ /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
+ * set we should only pass on control frames for this
+ * station. This needs testing. I believe right now this
+ * enables *all* control frames */
if (*new_flags & FIF_CONTROL)
rfilt |= AR5K_RX_FILTER_CONTROL;

@@ -1467,6 +1507,8 @@ static void ath_configure_filter(struct ieee80211_hw *hw,
rfilt |= AR5K_RX_FILTER_BEACON;
}

+ /* Set multicast bits */
+ ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
/* Set the cached hw filter flags, this will alter actually
* be set in HW */
sc->filter_flags = rfilt;
--
1.5.2.5


2007-10-09 02:37:57

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

2007/10/8, Luis R. Rodriguez <[email protected]>:
> On Sun, Oct 07, 2007 at 03:13:28AM -0700, Nick Kossifidis wrote:
> > NACK i have a better fix wich uses chip srev, i had commited it on
> > ath5k branch on madwifi svn...
> >
> > what's going on ? noone read my chagnes n ath5k branch on madwifi svn
> > ? i did this change some time ago (over a month) and it seems you
> > didn't even saw it...
> >
> > http://madwifi.org/changeset/2703
> > http://madwifi.org/changeset/2704
> >
> > what happened to my changes ? you told me you would commit them here...
>
> I had said I would but Jiri sent some patches based on your work which
> I thought included your latest changes. Instead of bitching about
> things you should start sending patches, that would be more helpful.
>
> Anyway I actually like that approach more, thanks. John -- I'll send in a new
> patch series.
>
> Luis
>

You are right but i was on a trip and i couldn't work on it, before i
left wireless-dev wouldn't boot for me so i couldn't test any patch.
I'll try again wireless-dev and I'll send a patch series here.

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-06 01:18:57

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 5/6] ath5k: Add documenation for atheros bssid_mask

This patch adds extensive documenation for the atheros bssid_mask. Credit
to David Kimdon for figuring this out. I am just documenting it.

No need to check for ath5k_hw_hasbssidmask() as
ath5k_hw_set_bssid_mask() will do the check itself.

Also add link to Atheros patent 6677779 B1 about buffer registers and
control registers. Hope this helps.

Changes to base.c
Changes-licensed-under: 3-clause-BSD

Changes to hw.c, reg.h
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/base.c | 7 +--
drivers/net/wireless/ath5k/hw.c | 96 +++++++++++++++++++++++++++++++++++-
drivers/net/wireless/ath5k/reg.h | 17 ++++--
3 files changed, 107 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 325965a..caf9562 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2268,10 +2268,9 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)

ath5k_hw_get_lladdr(ah, mac);
SET_IEEE80211_PERM_ADDR(hw, mac);
- if (ath5k_hw_hasbssidmask(ah)) {
- memset(sc->bssidmask, 0xff, ETH_ALEN);
- ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
- }
+ /* All MAC address bits matter for ACKs */
+ memset(sc->bssidmask, 0xff, ETH_ALEN);
+ ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);

ret = ieee80211_register_hw(hw);
if (ret) {
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 6a8a278..445fa96 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -2366,9 +2366,99 @@ void ath5k_hw_set_associd(struct ath_hw *hal, const u8 *bssid, u16 assoc_id)

ath5k_hw_enable_pspoll(hal, NULL, 0);
}
-
-/*
- * Set BSSID mask on 5212
+/**
+ * ath5k_hw_set_bssid_mask - set common bits we should listen to
+ *
+ * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode every bit matters. In AP
+ * mode with a single BSS every bit matters as well. In AP mode with
+ * multiple BSSes not every bit matters.
+ *
+ * @hal: the &struct ath_hw
+ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
+ *
+ * Note that this is a simple filter and *does* not filter out all
+ * relevant frames. Some non-relevant frames will get through, probability
+ * jocks are welcomed to compute.
+ *
+ * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
+ * computing the set of:
+ *
+ * ~ ( MAC XOR BSSID )
+ *
+ * When you do this you are essentially computing the common bits. Later it
+ * is assumed the harware will "and" (&) the BSSID mask with the MAC address
+ * to obtain the relevant bits which should match on the destination frame.
+ *
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ * \
+ * MAC: 0001 |
+ * BSSID-01: 0100 | --> Belongs to us
+ * BSSID-02: 1001 |
+ * /
+ * -------------------
+ * BSSID-03: 0110 | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ * On loop iteration for BSSID-01:
+ * ~(0001 ^ 0100) -> ~(0101)
+ * -> 1010
+ * bssid_mask = 1010
+ *
+ * On loop iteration for BSSID-02:
+ * bssid_mask &= ~(0001 ^ 1001)
+ * bssid_mask = (1010) & ~(0001 ^ 1001)
+ * bssid_mask = (1010) & ~(1001)
+ * bssid_mask = (1010) & (0110)
+ * bssid_mask = 0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01: 0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is beacuse the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ * --> allow = (0010) == 0000 ? 1 : 0;
+ * --> allow = 0
+ *
+ * Lets now test a frame that should work:
+ *
+ * IFRAME-02: 0001 (we should allow)
+ *
+ * allow = (0001 & 1010) == 1010
+ *
+ * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
+ * --> allow = (0010) == (0010)
+ * --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03: 0100 --> allowed
+ * IFRAME-04: 1001 --> allowed
+ * IFRAME-05: 1101 --> allowed but its not for us!!!
+ *
*/
int ath5k_hw_set_bssid_mask(struct ath_hw *hal, const u8 *mask)
{
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 0a7b312..1537517 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1252,10 +1252,13 @@
#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */
#define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */
#define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */
-#define AR5K_RX_FILTER_PHYERR (ah->ah_version == AR5K_AR5211 ? \
- AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)
-#define AR5K_RX_FILTER_RADARERR (ah->ah_version == AR5K_AR5211 ? \
- AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)
+#define AR5K_RX_FILTER_PHYERR \
+ ((ah->ah_version == AR5K_AR5211 ? \
+ AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
+#define AR5K_RX_FILTER_RADARERR \
+ ((ah->ah_version == AR5K_AR5211 ? \
+ AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
+
/*
* Multicast filter register (lower 32 bits)
*/
@@ -1755,8 +1758,10 @@
* packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
* for now. It's interesting that they are also used for some other operations.
*
- * Also check out ath5k_hw.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers)
+ * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
*/

#define AR5K_RF_BUFFER 0x989c
--
1.5.2.5


2007-10-08 21:34:56

by Michael Taylor

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection


> So far I haven't received one AR5K_INT_RXPHY interrupt yet. Mind you we
> are already setting radar to 1 too -- we do this at the end of
> ath_reset() with ath5k_hw_enable_radar_alert() -- so not sure what's
> going on. I do live in front of a cemetery...
>
You may be using an AR5210 chip?

Look at madwifi-dfs branch in madwifi.org for an example of how to
configure the pulse detector. To get radar pulse detection to work you
have to update the pulse detection configuration, disable the filtering
of PHY radar errors, and enable the radar detection. Then you should be
able to get the errors just by playing a video (such as the one provided
by the FCC) between a client and the AP. You should get enough false
positives from the pulse detector to notice. You won't get them from an
idle AP, and you are very unlikely to detect real radar (in my
experience). I work at NASA Research Park at what was formerly Moffett
Air Base. There's an airport less than 1 mile away and I've never
detected true radar.

IMPORTANT: The Atheros hardware 5212 and higher provides only pulse
detection, NOT radar detection. The 5210 stuff doesn't even provide
radar errors or pulse detection... it's supposed to be possible to use
zero-byte packets with PHYERR or something if you disable filtering of
zero byte packets, but I haven't tried it.

The driver has to match the pulses to known patterns and filter out the
noise. It has to be able to filter out excess pulses and handle missed
pulses (you can't detect radar while transmitting). That's why the
madwifi-dfs branch has been brewing for longer than you might think. The
Atheros proprietary drivers provide one implementation of matching and
the madwifi-dfs branch currently works for all short-pulse type radars,
and isn't quite ready for prime time for long pulse type radars.

BTW, there are a lot more details to DFS than getting a pulse error from
the hardware... but I'll assume you know what has to happen at the
higher levels.

For the lower level stuff, feel free to send me any questions you have
for Atheros radar detection.

- M
> Anyway IMO we shouldn't handle radar detection but simply pass it down
> to the upper layers, in this case mac80211. It seems for DFS this
> would mean to force to change channels and blacklist the channel for
> 30 minutes. If this interrupt *does* prove to be very noisy we can
> simply disable the AR5K_RX_FILTER_RADARERR and even AR5K_RX_FILTER_PHYERR
> later. Perhaps AR5K_RX_FILTER_RADARERR should be enabled during
> configure_filter() through mac80211 to indicate when we do *need* DFS.
> Right now AR5K_RX_FILTER_PHYERR is enabled when mac80211 tells us
> about FIF_FCSFAIL | FIF_PLCPFAIL, we also keep the current
> hw settings on AR5K_PHY_ERR_FIL (AR5K_PHY_ERR_FIL_RADAR,
> AR5K_PHY_ERR_FIL_OFDM or AR5K_PHY_ERR_FIL_CCK).
>
> Comments?
>
> Luis
>

2007-10-07 09:56:15

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

This is very sensitive, have you tested it ? Michael Taylor has
reported AFAIK that just enabling radar interrupt results alerts even
if no radar is present (noisy environment), plz take a look at
madwifi-dfs code we need to set things up before enabling the
interrupt...

2007/10/5, Luis R. Rodriguez <[email protected]>:
> Enable radar detection, and clean up ath5k_hw_attach() definition.
>
> Specifically this patch:
>
> o On struct ath_hw:
> * renames ah_sh to ah_iobase to make its use clear
> * move ah_sc to non-opaque struct, as we only currently use
> it as struct ath_softc. We we add SoC support we can figure
> an alternative.
> * Move out radar struct definition into new struct ath_radar
>
> o On ath5k_hw_attach() we currenlty pass the ath_sofct struct and
> sc->iobase. No point in passing both since we're already passing sc.
>
> o Remove any comments referring to a "HAL". We don't have one anymore.
> Another patch later will replace 'hal' -> 'ahw'.
>
> o On ath5k_hw_get_isr() only read AR5K_RAC_PISR on non-AR5210s
>
> o Capture AR5K_IMR_RXPHY and pass it as AR5K_INT_RXPHY to our
> interrupt handler. Upon detection call ath5k_radar_alert(). Upper
> layers need radar detection handling support. Right now just
> announce detection. We enable radar detection through new
> ath5k_hw_enable_radar_alert().
>
> Changes to ath5k_base.[ch]
> Changes-licensed-under: 3-clause-BSD
>
> Changes to ath5k.h, hw.c
> Changes-licensed-under: ISC
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/ath5k/ath5k.h | 65 +++++++++++++++++--------------
> drivers/net/wireless/ath5k/base.c | 44 ++++++++++++++++-----
> drivers/net/wireless/ath5k/base.h | 2 +-
> drivers/net/wireless/ath5k/hw.c | 74 +++++++++++++++++++++++++++++-------
> 4 files changed, 130 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> index 9308916..445fde8 100644
> --- a/drivers/net/wireless/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath5k/ath5k.h
> @@ -274,10 +274,10 @@ enum ath5k_tx_queue_subtype {
> };
>
> /*
> - * Queue ID numbers as returned by the HAL, each number
> - * represents a hw queue. If hw does not support hw queues
> - * (eg 5210) all data goes in one queue. These match
> - * d80211 definitions (net80211/MadWiFi don't use them).
> + * Queue ID numbers as used by ath5k_hw_setup_tx_queue() and
> + * ath5k_hw_wait_for_beacon(). Each number represents a hw queue.
> + * If hw does not support hw queues (eg 5210) all data goes in one
> + * queue. These match mac0211 definitions.
> */
> enum ath5k_tx_queue_id {
> AR5K_TX_QUEUE_ID_NOQCU_DATA = 0,
> @@ -323,7 +323,8 @@ struct ath5k_txq_info {
>
> /*
> * Transmit packet types.
> - * These are not fully used inside OpenHAL yet
> + * These are currently only used in ath5k_hw_setup_2word_tx_desc() to
> + * distinguish frame types on AR5210.
> */
> enum ath5k_pkt_type {
> AR5K_PKT_TYPE_NORMAL = 0,
> @@ -573,8 +574,7 @@ struct ath_desc {
> #define CHANNEL_MODES CHANNEL_ALL
>
> /*
> - * Used internaly in OpenHAL (ar5211.c/ar5212.c
> - * for reset_tx_queue). Also see struct struct ieee80211_channel.
> + * Used internaly in ath5k_hw_reset_tx_queue()
> */
> #define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0)
> #define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0)
> @@ -717,13 +717,14 @@ enum ath5k_ant_setting {
> };
>
> /*
> - * HAL interrupt abstraction
> + * Hardware interrupt masks helpers
> */
>
> /*
> * These are mapped to take advantage of some common bits
> * between the MAC chips, to be able to set intr properties
> - * easier. Some of them are not used yet inside OpenHAL.
> + * easier. Some of them are not used yet inside hw.c. Most map
> + * to the respective hw interrupt value.
> */
> enum ath5k_int {
> AR5K_INT_RX = 0x00000001,
> @@ -773,8 +774,8 @@ enum ath5k_power_mode {
> };
>
> /*
> - * These match net80211 definitions (not used in
> - * d80211).
> + * These match net80211 definitions
> + * XXX: move to mac80211 led work
> */
> #define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/
> #define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/
> @@ -788,9 +789,8 @@ enum ath5k_power_mode {
> #define AR5K_SOFTLED_OFF 1
>
> /*
> - * Chipset capabilities -see ath_hal_getcapability-
> - * get_capability function is not yet fully implemented
> - * in OpenHAL so most of these don't work yet...
> + * Chipset capabilities. See ath5k_hw_get_capability(),
> + * we do what we can as we make progress
> */
> enum ath5k_capability_type {
> AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */
> @@ -862,14 +862,20 @@ struct ath5k_capabilities {
> * Misc defines
> */
>
> +struct ath_radar {
> + bool r_enabled;
> + int r_last_alert;
> + struct ieee80211_channel r_last_channel;
> +};
> +
> #define AR5K_MAX_GPIO 10
> #define AR5K_MAX_RF_BANKS 8
>
> struct ath_hw {
> u32 ah_magic;
>
> - void *ah_sc;
> - void __iomem *ah_sh;
> + struct ath_softc *ah_sc;
> + void __iomem *ah_iobase;
> enum ath5k_countrycode ah_country_code;
>
> enum ath5k_int ah_imr;
> @@ -937,11 +943,7 @@ struct ath_hw {
> s16 txp_ofdm;
> } ah_txpower;
>
> - struct {
> - bool r_enabled;
> - int r_last_alert;
> - struct ieee80211_channel r_last_channel;
> - } ah_radar;
> + struct ath_radar ah_radar;
>
> /*
> * Function pointers
> @@ -966,7 +968,8 @@ struct ath_hw {
> /* General Functions */
> extern int ath5k_hw_register_timeout(struct ath_hw *hal, u32 reg, u32 flag, u32 val, bool is_set);
> /* Attach/Detach Functions */
> -extern struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc, void __iomem *sh);
> +extern struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version,
> + struct ath_softc *sc);
> extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath_hw *hal, unsigned int mode);
> extern void ath5k_hw_detach(struct ath_hw *hal);
> /* Reset Functions */
> @@ -981,12 +984,15 @@ extern void ath5k_hw_put_rx_buf(struct ath_hw *hal, u32 phys_addr);
> extern int ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue);
> extern int ath5k_hw_stop_tx_dma(struct ath_hw *hal, unsigned int queue);
> extern u32 ath5k_hw_get_tx_buf(struct ath_hw *hal, unsigned int queue);
> -extern int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr);
> +extern int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue,
> + u32 phys_addr);
> extern int ath5k_hw_update_tx_triglevel(struct ath_hw *hal, bool increase);
> /* Interrupt handling */
> extern bool ath5k_hw_is_intr_pending(struct ath_hw *hal);
> extern int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask);
> -extern enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal, enum ath5k_int new_mask);
> +extern enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal,
> + enum ath5k_int new_mask);
> +extern void ath5k_hw_enable_radar_alert(struct ath_hw *hal, bool enable);
> /* EEPROM access functions */
> extern int ath5k_hw_set_regdomain(struct ath_hw *hal, u16 regdomain);
> /* Protocol Control Unit Functions */
> @@ -994,7 +1000,8 @@ extern int ath5k_hw_set_opmode(struct ath_hw *hal);
> /* BSSID Functions */
> extern void ath5k_hw_get_lladdr(struct ath_hw *hal, u8 *mac);
> extern int ath5k_hw_set_lladdr(struct ath_hw *hal, const u8 *mac);
> -extern void ath5k_hw_set_associd(struct ath_hw *hal, const u8 *bssid, u16 assoc_id);
> +extern void ath5k_hw_set_associd(struct ath_hw *hal,
> + const u8 *bssid, u16 assoc_id);
> extern int ath5k_hw_set_bssid_mask(struct ath_hw *hal, const u8 *mask);
> /* Receive start/stop functions */
> extern void ath5k_hw_start_rx_pcu(struct ath_hw *hal);
> @@ -1073,14 +1080,14 @@ extern int ath5k_hw_txpower(struct ath_hw *hal, struct ieee80211_channel *channe
> extern int ath5k_hw_set_txpower_limit(struct ath_hw *hal, unsigned int power);
>
>
> -static inline u32 ath5k_hw_reg_read(struct ath_hw *hal, u16 reg)
> +static inline u32 ath5k_hw_reg_read(struct ath_hw *ahw, u16 reg)
> {
> - return ioread32(hal->ah_sh + reg);
> + return ioread32(ahw->ah_iobase + reg);
> }
>
> -static inline void ath5k_hw_reg_write(struct ath_hw *hal, u32 val, u16 reg)
> +static inline void ath5k_hw_reg_write(struct ath_hw *ahw, u32 val, u16 reg)
> {
> - iowrite32(val, hal->ah_sh + reg);
> + iowrite32(val, ahw->ah_iobase + reg);
> }
>
> #endif
> diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
> index afcc7e1..fa591eb 100644
> --- a/drivers/net/wireless/ath5k/base.c
> +++ b/drivers/net/wireless/ath5k/base.c
> @@ -114,9 +114,8 @@ module_param_named(debug, ath_debug, uint, 0);
> #endif
>
> /*
> - * User a static table of PCI id's for now. While this is the
> - * "new way" to do things, we may want to switch back to having
> - * the HAL check them by defining a probe method.
> + * ath5k_hw_attach() may also do further checking. Some devices keep the same
> + * PCI vendor:device ID but may differ. ath5k_hw_attach() will check there.
> */
> static struct pci_device_id ath_pci_id_table[] __devinitdata = {
> { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
> @@ -596,7 +595,7 @@ static void ath_beacon_send(struct ath_softc *sc)
> if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
> printk(KERN_WARNING "ath: beacon queue %u didn't stop?\n",
> sc->bhalq);
> - /* NB: the HAL still stops DMA, so proceed */
> + /* ath5k_hw_stop_tx_dma() still stops DMA, so proceed */
> }
> pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len,
> PCI_DMA_TODEVICE);
> @@ -717,6 +716,8 @@ static void ath_beacon_config(struct ath_softc *sc)
> ath5k_hw_hasveol(ah))
> ath_beacon_send(sc);
> }
> + /* Enable radar alerts */
> + ath5k_hw_enable_radar_alert(ah, true);
> #undef TSF_TO_TU
> }
>
> @@ -1135,7 +1136,7 @@ static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
> *
> * XXX needed?
> */
> -/* ath_chan_change(sc, chan); */
> + //ath_chan_set(sc, sc->curchan);
>
> /*
> * Re-enable interrupts.
> @@ -1260,10 +1261,6 @@ static int ath_reset(struct ieee80211_hw *hw)
> int ret;
>
> DPRINTF(sc, ATH_DEBUG_RESET, "resetting\n");
> - /*
> - * Convert to a HAL channel description with the flags
> - * constrained to reflect the current operating mode.
> - */
> sc->curchan = hw->conf.chan;
>
> ath5k_hw_set_intr(ah, 0);
> @@ -1289,7 +1286,7 @@ static int ath_reset(struct ieee80211_hw *hw)
> *
> * XXX needed?
> */
> -/* ath_chan_change(sc, c); */
> + //ath_chan_set(sc, sc->curchan);
> ath_beacon_config(sc);
> /* intrs are started by ath_beacon_config */
>
> @@ -1669,6 +1666,28 @@ static void ath_led_event(struct ath_softc *sc, int event)
> }
> }
>
> +static void ath5k_radar_alert(struct ath_hw *ahw)
> +{
> + struct ath_radar *radar = &ahw->ah_radar;
> + struct ieee80211_channel *radar_chan = &radar->r_last_channel;
> + struct ieee80211_channel *curr_chan = &ahw->ah_current_channel;
> +
> + /* Limit ~1/s */
> + if (radar_chan->chan == curr_chan->chan &&
> + jiffies < (radar->r_last_alert + 1 * HZ))
> + return;
> +
> + memcpy(radar_chan, curr_chan, sizeof(struct ieee80211_channel));
> + radar->r_last_alert = jiffies;
> +
> + dev_info(&ahw->ah_sc->pdev->dev,
> + "Possible radar activity detected at "
> + "%u MHz (jiffies %u)\n", radar->r_last_alert,
> + curr_chan->chan);
> +
> + /* Higher layer should probably do something here... TBC */
> +}
> +
> static irqreturn_t ath_intr(int irq, void *dev_id)
> {
> struct ath_softc *sc = dev_id;
> @@ -1701,6 +1720,9 @@ static irqreturn_t ath_intr(int irq, void *dev_id)
> tasklet_schedule(&sc->restq);
> } else if (unlikely(status & AR5K_INT_RXORN)) {
> tasklet_schedule(&sc->restq);
> + } else if ((unlikely(status & AR5K_INT_RXPHY)) &&
> + ah->ah_radar.r_enabled) {
> + ath5k_radar_alert(ah);
> } else {
> if (status & AR5K_INT_SWBA) {
> /*
> @@ -2373,7 +2395,7 @@ static int __devinit ath_pci_probe(struct pci_dev *pdev,
> goto err_free;
> }
>
> - sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc, sc->iobase);
> + sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc);
> if (IS_ERR(sc->ah)) {
> ret = PTR_ERR(sc->ah);
> goto err_irq;
> diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
> index 4a624cc..1bd1d1f 100644
> --- a/drivers/net/wireless/ath5k/base.h
> +++ b/drivers/net/wireless/ath5k/base.h
> @@ -191,7 +191,7 @@ struct ath_softc {
> struct tasklet_struct txtq; /* tx intr tasklet */
>
> struct ath_buf *bbuf; /* beacon buffer */
> - unsigned int bhalq, /* HAL q for outgoing beacons */
> + unsigned int bhalq, /* Hw q for outgoing beacons */
> bmisscount, /* missed beacon transmits */
> bintval, /* beacon interval */
> bsent;
> diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
> index ae4c5b5..6ef492c 100644
> --- a/drivers/net/wireless/ath5k/hw.c
> +++ b/drivers/net/wireless/ath5k/hw.c
> @@ -21,7 +21,7 @@
> */
>
> /*
> - * HAL interface for Atheros Wireless LAN devices.
> + * Hardware interface for Atheros Wireless LAN devices.
> */
>
> #include <linux/pci.h>
> @@ -29,6 +29,7 @@
>
> #include "ath5k.h"
> #include "reg.h"
> +#include "base.h"
>
> /*Rate tables*/
> static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
> @@ -191,8 +192,8 @@ int ath5k_hw_register_timeout(struct ath_hw *hal, u32 reg, u32 flag, u32 val,
> /*
> * Check if the device is supported and initialize the needed structs
> */
> -struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> - void __iomem *sh)
> +struct ath_hw *ath5k_hw_attach(u16 device,
> + u8 mac_version, struct ath_softc *sc)
> {
> struct ath_hw *hal;
> u8 mac[ETH_ALEN];
> @@ -208,10 +209,10 @@ struct ath_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> }
>
> hal->ah_sc = sc;
> - hal->ah_sh = sh;
> + hal->ah_iobase = sc->iobase;
>
> /*
> - * HAL information
> + * Hardware cached data
> */
>
> /* Regulation Stuff */
> @@ -1474,14 +1475,15 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
> return -ENODEV;
> }
> }
> + else {
> + /*
> + * Read interrupt status from the Read-And-Clear shadow register
> + */
> + data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
> + }
>
> /*
> - * Read interrupt status from the Read-And-Clear shadow register
> - */
> - data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
> -
> - /*
> - * Get abstract interrupt mask (HAL-compatible)
> + * Get abstract interrupt mask
> */
> *interrupt_mask = (data & AR5K_INT_COMMON) & hal->ah_imr;
>
> @@ -1494,6 +1496,9 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
> if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR))
> *interrupt_mask |= AR5K_INT_TX;
>
> + if (data & AR5K_IMR_RXPHY)
> + *interrupt_mask |= AR5K_INT_RXPHY;
> +
> if (hal->ah_version != AR5K_AR5210) {
> /*HIU = Host Interface Unit (PCI etc)*/
> if (unlikely(data & (AR5K_ISR_HIUERR)))
> @@ -1504,12 +1509,14 @@ int ath5k_hw_get_isr(struct ath_hw *hal, enum ath5k_int *interrupt_mask)
> *interrupt_mask |= AR5K_INT_BNR;
> }
>
> +#if 0
> /*
> * XXX: BMISS interrupts may occur after association.
> - * I found this on 5210 code but it needs testing
> + * Needs testing.
> */
> -#if 0
> - interrupt_mask &= ~AR5K_INT_BMISS;
> + if (hal->ah_version != AR5K_AR5210) {
> + interrupt_mask &= ~AR5K_INT_BMISS;
> + }
> #endif
>
> /*
> @@ -1570,6 +1577,45 @@ enum ath5k_int ath5k_hw_set_intr(struct ath_hw *hal, enum ath5k_int new_mask)
> return old_mask;
> }
>
> +/*
> + * Enable HW radar detection
> + */
> +void ath5k_hw_enable_radar_alert(struct ath_hw *ahw, bool enable)
> +{
> +
> + AR5K_TRACE;
> + /*
> + * Enable radar detection
> + */
> +
> + /* Disable interupts */
> + ath5k_hw_reg_write(ahw, AR5K_IER_DISABLE, AR5K_IER);
> +
> + /*
> + * Set the RXPHY interrupt to be able to detect
> + * possible radar activity.
> + */
> + if (ahw->ah_version == AR5K_AR5210) {
> + if (enable)
> + AR5K_REG_ENABLE_BITS(ahw, AR5K_IMR, AR5K_IMR_RXPHY);
> + else
> + AR5K_REG_DISABLE_BITS(ahw, AR5K_IMR, AR5K_IMR_RXPHY);
> + } else {
> + /* Also set AR5K_PHY_RADAR register on 5111/5112 */
> + if (enable) {
> + ath5k_hw_reg_write(ahw, AR5K_PHY_RADAR_ENABLE,
> + AR5K_PHY_RADAR);
> + AR5K_REG_ENABLE_BITS(ahw, AR5K_PIMR, AR5K_IMR_RXPHY);
> + } else {
> + ath5k_hw_reg_write(ahw, AR5K_PHY_RADAR_DISABLE,
> + AR5K_PHY_RADAR);
> + AR5K_REG_DISABLE_BITS(ahw, AR5K_PIMR, AR5K_IMR_RXPHY);
> + }
> + }
> +
> + /* Re-enable interrupts */
> + ath5k_hw_reg_write(ahw, AR5K_IER_ENABLE, AR5K_IER);
> +}
>
> /*************************\
> EEPROM access functions
> --
> 1.5.2.5
>
>
>


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-08 20:34:11

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

On Sun, Oct 07, 2007 at 03:28:12AM -0700, Nick Kossifidis wrote:
> Take a look here..
> http://thread.gmane.org/gmane.linux.drivers.madwifi.devel/4386/focus=4391

Of course I have tested this...

So far I haven't received one AR5K_INT_RXPHY interrupt yet. Mind you we
are already setting radar to 1 too -- we do this at the end of
ath_reset() with ath5k_hw_enable_radar_alert() -- so not sure what's
going on. I do live in front of a cemetery...

Anyway IMO we shouldn't handle radar detection but simply pass it down
to the upper layers, in this case mac80211. It seems for DFS this
would mean to force to change channels and blacklist the channel for
30 minutes. If this interrupt *does* prove to be very noisy we can
simply disable the AR5K_RX_FILTER_RADARERR and even AR5K_RX_FILTER_PHYERR
later. Perhaps AR5K_RX_FILTER_RADARERR should be enabled during
configure_filter() through mac80211 to indicate when we do *need* DFS.
Right now AR5K_RX_FILTER_PHYERR is enabled when mac80211 tells us
about FIF_FCSFAIL | FIF_PLCPFAIL, we also keep the current
hw settings on AR5K_PHY_ERR_FIL (AR5K_PHY_ERR_FIL_RADAR,
AR5K_PHY_ERR_FIL_OFDM or AR5K_PHY_ERR_FIL_CCK).

Comments?

Luis

2007-10-09 02:31:33

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

2007/10/8, Luis R. Rodriguez <[email protected]>:
> On Sun, Oct 07, 2007 at 02:49:23AM -0700, Nick Kossifidis wrote:
> > 2007/10/5, Luis R. Rodriguez <[email protected]>:
> > > Ported new initval changes from OpenBSD to ath5k to ar5212_ini[] and
> > > ar5212_ini_mode[].
> >
> > NACK
> >
> > Nothing new was introduced in OpenBSD cvs that i haven't already
> > included!, what have you ported ???
>
> Actually, you are right, an oversight by my part. Thanks for catching
> this. However after verying this I did find the one type. Please
> review.
>
> > > This also adds an O(log(N)) bitswap for one byte
> > > on ath5k_hw_bitswap(), thanks to Tom from OpenBSD.
> >
> > ACK it's used for modifying rf buffer settings...
>
> I think its easier to just new patches. I'll do so but please first
> review the small change below.
>
> Luis
>
>
> diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
> index 1537517..f826422 100644
> --- a/drivers/net/wireless/ath5k/reg.h
> +++ b/drivers/net/wireless/ath5k/reg.h
> @@ -1980,4 +1980,4 @@ after DFS is enabled */
> #define AR5K_PHY_GAIN_2GHZ 0xa20c
> #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000
> #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18
> -#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c
> +#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6448416a
>

I'll post a pach series asap here with my fixes against current
wireless-dev including your fixes on base.c/h and any other fixes
posted so far that are not included yet i hope now wireless-dev will
boot for me so i can also test them. About PHY_GAIN i did some tests
before ending up with this value, it comes from initialization of 5211
and after testing 5211+5111 and 5212+5111 combinations it seems it
performs better. The ideal solution would be to read antenna gain from
eeprom and somehow calculate this value dynamicaly instead of putting
a static one.

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-09 07:05:34

by Holger Schurig

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

> There's an airport less
> than 1 mile away and I've never detected true radar.

Maybe you need to go to some russian military camp. Some russian
surface-to-air missile systems used (20 years ago) frequency
ranges in the 5 GHz area.

2007-10-07 09:49:24

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

2007/10/5, Luis R. Rodriguez <[email protected]>:
> Ported new initval changes from OpenBSD to ath5k to ar5212_ini[] and
> ar5212_ini_mode[].

NACK

Nothing new was introduced in OpenBSD cvs that i haven't already
included!, what have you ported ???

Settings inside inivals.c are O.K. there is no need to change them and
if you do plz maintain the style, e.g. all BB TABLE settings go
together seperately per chipset (not as part of mac initialization)
etc. I've spent a lot time cleaning ini register settings up, plz
check out that these values you are adding are not already written in
a previous step.

> This also adds an O(log(N)) bitswap for one byte
> on ath5k_hw_bitswap(), thanks to Tom from OpenBSD.

ACK it's used for modifying rf buffer settings...

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-07 10:13:30

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

NACK i have a better fix wich uses chip srev, i had commited it on
ath5k branch on madwifi svn...

what's going on ? noone read my chagnes n ath5k branch on madwifi svn
? i did this change some time ago (over a month) and it seems you
didn't even saw it...

http://madwifi.org/changeset/2703
http://madwifi.org/changeset/2704

what happened to my changes ? you told me you would commit them here...

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-06 01:19:34

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

The IBM AR5424 card uses the same vendor:device ID as an old AR5212. AR5424
is not yet supported though. We detect this and report it.

OpenBSD has similar checks but they check for 64-bit.

Changes to ath5k_base.[ch]
Changes-licensed-under: 3-clause-BSD

Changes to hw.c
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/base.c | 1 +
drivers/net/wireless/ath5k/base.h | 1 +
drivers/net/wireless/ath5k/hw.c | 22 ++++++++++++++++++++++
3 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index caf9562..97a7613 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2423,6 +2423,7 @@ static int __devinit ath_pci_probe(struct pci_dev *pdev,
sc->iobase = mem;
sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
sc->opmode = IEEE80211_IF_TYPE_STA;
+ sc->pci_express = !!pci_find_capability(pdev, PCI_CAP_ID_EXP);
mutex_init(&sc->lock);
spin_lock_init(&sc->rxbuflock);
spin_lock_init(&sc->txbuflock);
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index 1bd1d1f..fde51f1 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -131,6 +131,7 @@ struct ath_softc {
struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_IEEE80211_MODES];
enum ieee80211_if_types opmode;
struct ath_hw *ah; /* Atheros HW */
+ unsigned int pci_express : 1;/* indicates PCI Express */

int debug;

diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 445fa96..5f2edce 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -240,6 +240,28 @@ struct ath_hw *ath5k_hw_attach(u16 device,
*/
hal->ah_single_chip = true;
break;
+ case PCI_DEVICE_ID_ATHEROS_AR5212_IBM:
+ /*
+ * IBM ThinkPads use the same device ID for different
+ * chipset versions... we differentiate by pci_express
+ */
+ if (sc->pci_express) {
+ /*
+ * PCI Express "Mini Card" interface based on the
+ * AR5424 chipset.
+ */
+ hal->ah_single_chip = true;
+ /* not yet supported */
+ dev_info(&sc->pdev->dev,
+ "PCI-Express AR5424 not yet supported\n");
+ ret = -EINVAL;
+ goto err_free;
+ } else {
+ /* Classic Mini PCI interface based on AR5212 */
+ hal->ah_single_chip = false;
+ }
+ break;
+
default:
/*
* Multi chip solutions
--
1.5.2.5


2007-10-06 01:18:00

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 3/6] ath5k: Fix a bug which pushed us to enable the promiscuous filter

Fix a bug which pushed us to enable the promiscuous filter
all the time during normal operation. The real problem was caused
becuase we were reseting the bssid to the broadcast during
ath5k_hw_reset(). We now cache the bssid value and set the
bssid again during resets. This gives the driver considerably
more stability.

Known issue: if your DHCP server doesn't ACK your IP via the broadcast but
instead sends it to the IP it gives you (Cisco seems to do this) you
may not get the reply. Work is in progress to figure this issue out.
This issue was present before this patch.

Changes to base.c
Changes-licensed-under: 3-clause-BSD

Changes to ath5k.h, hw.c
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 4 ++++
drivers/net/wireless/ath5k/base.c | 15 ++++++++-------
drivers/net/wireless/ath5k/hw.c | 23 ++++++++++-------------
3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 445fde8..e3f12b9 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -883,6 +883,10 @@ struct ath_hw {
enum ieee80211_if_types ah_op_mode;
enum ath5k_power_mode ah_power_mode;
struct ieee80211_channel ah_current_channel;
+ /* Current BSSID we are trying to assoc to / creating, this
+ * comes from ieee80211_if_conf. This is passed by mac80211 on
+ * config_interface() */
+ u8 bssid[ETH_ALEN];
bool ah_turbo;
bool ah_calibration;
bool ah_running;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index fa591eb..b11a14b 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1365,6 +1365,7 @@ static int ath_config_interface(struct ieee80211_hw *hw, int if_id,
struct ieee80211_if_conf *conf)
{
struct ath_softc *sc = hw->priv;
+ struct ath_hw *ah = sc->ah;
int ret;

/* Set to a reasonable value. Note that this will
@@ -1375,8 +1376,13 @@ static int ath_config_interface(struct ieee80211_hw *hw, int if_id,
ret = -EIO;
goto unlock;
}
- if (conf->bssid)
- ath5k_hw_set_associd(sc->ah, conf->bssid, 0 /* FIXME: aid */);
+ if (conf->bssid) {
+ /* Cache for later use during resets */
+ memcpy(ah->bssid, conf->bssid, ETH_ALEN);
+ /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
+ * a clean way of letting us retrieve this yet. */
+ ath5k_hw_set_associd(ah, ah->bssid, 0);
+ }
mutex_unlock(&sc->lock);

return ath_reset(hw);
@@ -1459,11 +1465,6 @@ static void ath_configure_filter(struct ieee80211_hw *hw,
if (sc->opmode == IEEE80211_IF_TYPE_STA ||
sc->opmode == IEEE80211_IF_TYPE_IBSS) {
rfilt |= AR5K_RX_FILTER_BEACON;
- /* Note: AR5212 requires AR5K_RX_FILTER_PROM to receive broadcasts,
- * perhaps the flags are off, for now to be safe we'll enable it for
- * STA and ADHOC until we have this properly mapped */
- if (ah->ah_version == AR5K_AR5212)
- rfilt |= AR5K_RX_FILTER_PROM;
}

/* Set the cached hw filter flags, this will alter actually
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 6ef492c..6a8a278 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -310,15 +310,6 @@ struct ath_hw *ath5k_hw_attach(u16 device,

hal->ah_phy = AR5K_PHY(0);

- /* Set MAC to bcast: ff:ff:ff:ff:ff:ff, this is using 'mac' as a
- * temporary variable for setting our BSSID. Right bellow we update
- * it with ath5k_hw_get_lladdr() */
- memset(mac, 0xff, ETH_ALEN);
- ath5k_hw_set_associd(hal, mac, 0);
-
- ath5k_hw_get_lladdr(hal, mac);
- ath5k_hw_set_opmode(hal);
-
#ifdef AR5K_DEBUG
ath5k_hw_dump_state(hal);
#endif
@@ -350,6 +341,10 @@ struct ath_hw *ath5k_hw_attach(u16 device,
}

ath5k_hw_set_lladdr(hal, mac);
+ /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
+ memset(hal->bssid, 0xff, ETH_ALEN);
+ ath5k_hw_set_associd(hal, hal->bssid, 0);
+ ath5k_hw_set_opmode(hal);

ath5k_hw_set_rfgain_opt(hal);

@@ -547,7 +542,6 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode,
const struct ath5k_rate_table *rt;
struct ath5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
u32 data, noise_floor, s_seq, s_ant, s_led[3];
- u8 mac[ETH_ALEN];
unsigned int i, mode, freq, ee_mode, ant[2];
int ret;

@@ -865,8 +859,9 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode,
/*
* Misc
*/
- memset(mac, 0xff, ETH_ALEN);
- ath5k_hw_set_associd(hal, mac, 0);
+ /* XXX: add hal->aid once mac80211 gives this to us */
+ ath5k_hw_set_associd(hal, hal->bssid, 0);
+
ath5k_hw_set_opmode(hal);
/*PISR/SISR Not available on 5210*/
if (hal->ah_version != AR5K_AR5210) {
@@ -1062,7 +1057,9 @@ static int ath5k_hw_nic_reset(struct ath_hw *hal, u32 val)
ret = ath5k_hw_register_timeout(hal, AR5K_RESET_CTL, mask, val, false);

/*
- * Reset configuration register (for hw byte-swap)
+ * Reset configuration register (for hw byte-swap). Note that this
+ * is only set for big endian. We do the necessary magic in
+ * AR5K_INIT_CFG.
*/
if ((val & AR5K_RESET_CTL_PCU) == 0)
ath5k_hw_reg_write(hal, AR5K_INIT_CFG, AR5K_CFG);
--
1.5.2.5


2007-10-07 10:28:14

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath5k: Enable radar detection

Take a look here..
http://thread.gmane.org/gmane.linux.drivers.madwifi.devel/4386/focus=4391

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-09 08:17:03

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios

2007/10/9, Holger Schurig <[email protected]>:
> > You are right but i was on a trip
> ...
> > I'll try again wireless-dev and I'll send a
> > patch series here.
>
> If you were away you might not have heard that wireless-dev is
> dead. Use wireless-2.6 instead.
>
> The chance that this boots is higher :-)
>

Thanx, it booted ok, last non-working was 2.6.23-rc3...


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2007-10-09 07:17:28

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k

On 10/09/2007 04:31 AM, Nick Kossifidis wrote:
> I'll post a pach series asap here with my fixes against current
> wireless-dev including your fixes on base.c/h and any other fixes

Just a note, wireless-2.6 is current wireless tree.