From: "Luis R. Rodriguez" <mcgrof@gmail.com>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org, Jiri Slaby <jirislaby@gmail.com>,
Nick Kossifidis <mickflemm@gmail.com>
Subject: [PATCH 2/6] ath5k: Enable radar detection
Date: Fri, 5 Oct 2007 21:18:37 -0400 [thread overview]
Message-ID: <20071006011837.GB25022@pogo> (raw)
In-Reply-To: <20071006011657.GA24862@pogo>
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 <mcgrof@gmail.com>
---
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
next prev parent reply other threads:[~2007-10-06 1:17 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-06 1:04 [PATCH 0/6] ath5k: initvals, radar, promiscuous bug and multicast Luis R. Rodriguez
2007-10-06 1:16 ` [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k Luis R. Rodriguez
2007-10-06 1:18 ` Luis R. Rodriguez [this message]
2007-10-06 1:19 ` [PATCH 3/6] ath5k: Fix a bug which pushed us to enable the promiscuous filter Luis R. Rodriguez
2007-10-06 1:19 ` [PATCH 4/6] ath5k: Add proper support for multicast Luis R. Rodriguez
2007-10-06 1:20 ` [PATCH 5/6] ath5k: Add documenation for atheros bssid_mask Luis R. Rodriguez
2007-10-06 1:20 ` [PATCH 6/6] ath5k: Do not let the driver through for not yet supported radios Luis R. Rodriguez
2007-10-07 10:13 ` Nick Kossifidis
2007-10-08 20:48 ` Luis R. Rodriguez
2007-10-09 2:37 ` Nick Kossifidis
2007-10-09 7:02 ` Holger Schurig
2007-10-09 8:17 ` Nick Kossifidis
2007-10-09 20:05 ` [PATCH 5/6] ath5k: Add documenation for atheros bssid_mask Johannes Berg
2007-10-09 20:01 ` [PATCH 4/6] ath5k: Add proper support for multicast Johannes Berg
2007-10-10 18:11 ` Luis R. Rodriguez
2007-10-07 9:56 ` [PATCH 2/6] ath5k: Enable radar detection Nick Kossifidis
2007-10-07 10:28 ` Nick Kossifidis
2007-10-08 20:34 ` Luis R. Rodriguez
2007-10-08 21:18 ` Michael Taylor
2007-10-09 7:05 ` Holger Schurig
2007-10-09 9:34 ` Johannes Berg
2007-10-09 15:59 ` Luis R. Rodriguez
2007-10-07 9:49 ` [PATCH 1/6] ath5k: Ported new initval changes from OpenBSD to ath5k Nick Kossifidis
2007-10-08 20:38 ` Luis R. Rodriguez
2007-10-09 2:31 ` Nick Kossifidis
2007-10-09 7:17 ` Jiri Slaby
2007-10-09 8:15 ` Nick Kossifidis
2007-10-06 1:23 ` [PATCH 0/6] ath5k: initvals, radar, promiscuous bug and multicast Luis R. Rodriguez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071006011837.GB25022@pogo \
--to=mcgrof@gmail.com \
--cc=jirislaby@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=mickflemm@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.