2007-11-01 04:35:26

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 2/7] ath5k: Remove opaque pointers from ath5k_hw_attach()

Since we don't have a HAL anymore there is no point to use opaque pointers
in ath5k_hw_attach(). This will also give hw.c access to ath5k_softc
structure now when needed. While we're at it, lets also give some ah_sh
a reasonable name, ah_sh --> ah_iobase.

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 | 10 +++++-----
drivers/net/wireless/ath5k/base.c | 2 +-
drivers/net/wireless/ath5k/hw.c | 11 +++++------
3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 4122466..20567b1 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -943,8 +943,8 @@ struct ath5k_capabilities {
struct ath5k_hw {
u32 ah_magic;

- void *ah_sc;
- void __iomem *ah_sh;
+ struct ath5k_softc *ah_sc;
+ void __iomem *ah_iobase;

enum ath5k_int ah_imr;

@@ -1042,7 +1042,7 @@ struct ath5k_hw {
/* General Functions */
extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set);
/* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc, void __iomem *sh);
+extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode);
extern void ath5k_hw_detach(struct ath5k_hw *ah);
/* Reset Functions */
@@ -1151,12 +1151,12 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);

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

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

#endif
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 4b4ddf4..15ae868 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -559,7 +559,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
}

/* Initialize device */
- sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc, sc->iobase);
+ sc->ah = ath5k_hw_attach(sc, id->driver_data);
if (IS_ERR(sc->ah)) {
ret = PTR_ERR(sc->ah);
goto err_irq;
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 8ac88e7..320e32e 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -27,8 +27,8 @@
#include <linux/pci.h>
#include <linux/delay.h>

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

/*Rate tables*/
static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
@@ -187,8 +187,7 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
/*
* Check if the device is supported and initialize the needed structs
*/
-struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
- void __iomem *sh)
+struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
u8 mac[ETH_ALEN];
@@ -204,7 +203,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
}

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

/*
* HW information
@@ -323,7 +322,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
ret = ath5k_hw_get_capabilities(ah);
if (ret) {
AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
- device);
+ sc->pdev->device);
goto err_free;
}

@@ -331,7 +330,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
- device);
+ sc->pdev->device);
goto err_free;
}

--
1.5.2.5



2007-11-01 21:56:05

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 6/7] ath5k: Clear up settings of AR5K_RSSI_THR register settings

** Resending after checkpatch.pl

Clear up settings of AR5K_RSSI_THR register settings. These are split between
AR5K_TUNE_BMISS_THRES and AR5K_TUNE_RSSI_THRES.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 10 +++++++++-
drivers/net/wireless/ath5k/hw.c | 11 ++++-------
2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 3354b37..c8ab09a 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -86,8 +86,16 @@
#define AR5K_TUNE_RADAR_ALERT false
#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
-#define AR5K_TUNE_RSSI_THRES 1792
#define AR5K_TUNE_REGISTER_TIMEOUT 20000
+/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
+ * be the max value. */
+#define AR5K_TUNE_RSSI_THRES 129
+/* This must be set when setting the RSSI threshold otherwise it can
+ * prevent a reset. If AR5K_RSSI_THR is read after writing to it
+ * the BMISS_THRES will be seen as 0, seems harware doesn't keep
+ * track of it. Max value depends on harware. For AR5210 this is just 7.
+ * For AR5211+ this seems to be up to 255. */
+#define AR5K_TUNE_BMISS_THRES 7
#define AR5K_TUNE_REGISTER_DWELL_TIME 20000
#define AR5K_TUNE_BEACON_INTERVAL 100
#define AR5K_TUNE_AIFS 2
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 1b9c4f0..f1ba863 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -849,13 +849,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
/*PISR/SISR Not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
- /* XXX: AR5K_RSSI_THR has masks and shifts defined for it, so
- * direct write using ath5k_hw_reg_write seems wrong. Test with:
- * AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR,
- * AR5K_RSSI_THR_BMISS, AR5K_TUNE_RSSI_THRES);
- * with different variables and check results compared
- * to ath5k_hw_reg_write(ah, ) */
- ath5k_hw_reg_write(ah, AR5K_TUNE_RSSI_THRES, AR5K_RSSI_THR);
+ /* If we later allow tuning for this, store into sc structure */
+ data = AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
+ ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
}

/*
--
1.5.2.5


2007-11-01 16:47:23

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

On 11/1/07, Nick Kossifidis <[email protected]> wrote:

> Acked-by: Nick Kossifidis <[email protected]>
>
> Also checkout setcurmode function, i believe we can live without all
> this led-timing stuff and clean up both rate tables and related
> functions.

Yeap -- that is where I am sweeping next. The documentation of the
rates was added in a specific column arrangement for a good reason :)

Luis

2007-11-01 13:16:34

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

2007/11/1, Luis R. Rodriguez <[email protected]>:
> This adds documentation for struct ath5k_rate. This also removes
> some unused variables, lp_ack_duration and sp_ack_duration which
> are simply unnecessary. We obviously have information about the rest
> of the rate values, we can add more as we go, this just starts this up.
> I'll next target cleaning up the RATE macros, think that may be there
> the other G mode issues are in.
>
> Changes to ath5k.h
> Changes-licensed-under: ISC
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
> 1 files changed, 51 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> index c8ab09a..7147fb4 100644
> --- a/drivers/net/wireless/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath5k/ath5k.h
> @@ -549,17 +549,61 @@ struct ath5k_athchan_2ghz {
> * used by the rate control algorytm on MadWiFi.
> */
>
> -#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
> +/* Max number of rates on the rate table and what it seems
> + * Atheros hardware supports */
> +#define AR5K_MAX_RATES 32
>
> +/**
> + * struct ath5k_rate - rate structure
> + *
> + * This structure is used to get the RX rate or set the TX rate on the
> + * hardware descriptors. It is also used for internal modulation control
> + * and settings.
> + *
> + * @valid: is this a valid rate for the current mode
> + * @modulation: respective mac80211 modulation
> + * @rate_kbps: rate in kbit/s
> + * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
> + * &struct ath5k_rx_status.rs_rate and on TX on
> + * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
> + * up to 32 rates, indexed by 1-32. This means we really only need
> + * 6 bits for the rate_code.
> + * @dot11_rate: respective IEEE-802.11 rate value
> + * @control_rate: index of rate assumed to be used to send control frames.
> + * This can be used to set override the value on the rate duration
> + * registers. This is only useful if we can override in the harware at
> + * what rate we want to send control frames at. Note that IEEE-802.11
> + * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
> + * should send ACK/CTS, if we change this value we can be breaking
> + * the spec.
> + *
> + * On RX after the &struct ath5k_desc is parsed by the appropriate
> + * ah_proc_rx_desc() the respective hardware rate value is set in
> + * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
> + * &struct ath5k_tx_status.ts_rate which is later used to setup the
> + * &struct ath5k_desc correctly. This is the hardware rate map we are
> + * aware of:
> + *
> + * rate_code 1 2 3 4 5 6 7 8
> + * rate_kbps 3000 ? ? ? ? ? ? ?
> + *
> + * rate_code 9 10 11 12 13 14 15 16
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + * rate_code 17 18 19 20 21 22 23 24
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + * rate_code 25 26 27 28 29 30 31 32
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + */
> struct ath5k_rate {
> - u8 valid; /* Valid for rate control */
> + u8 valid;
> u32 modulation;
> - u16 rate_kbps; /* Rate in kbps used in computetxtime */
> - u8 rate_code; /* Rate mapping for h/w descriptors */
> + u16 rate_kbps;
> + u8 rate_code;
> u8 dot11_rate;
> - u8 control_rate; /* Rate for management frames -not used */
> - u16 lp_ack_duration;/* long preamble ACK duration -not used */
> - u16 sp_ack_duration;/* short preamble ACK duration -not used */
> + u8 control_rate;
> };
>
> /* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
> --
> 1.5.2.5
>
>

Acked-by: Nick Kossifidis <[email protected]>

Also checkout setcurmode function, i believe we can live without all
this led-timing stuff and clean up both rate tables and related
functions.

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

2007-11-01 21:56:48

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

** Resending after checkpatch.pl

This adds documentation for struct ath5k_rate. This also removes
some unused variables, lp_ack_duration and sp_ack_duration which
are simply unnecessary. We obviously have information about the rest
of the rate values, we can add more as we go, this just starts this up.
I'll next target cleaning up the RATE macros, think that may be there
the other G mode issues are in.

Changes to ath5k.h
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
1 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index c8ab09a..7147fb4 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -549,17 +549,61 @@ struct ath5k_athchan_2ghz {
* used by the rate control algorytm on MadWiFi.
*/

-#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
+/* Max number of rates on the rate table and what it seems
+ * Atheros hardware supports */
+#define AR5K_MAX_RATES 32

+/**
+ * struct ath5k_rate - rate structure
+ *
+ * This structure is used to get the RX rate or set the TX rate on the
+ * hardware descriptors. It is also used for internal modulation control
+ * and settings.
+ *
+ * @valid: is this a valid rate for the current mode
+ * @modulation: respective mac80211 modulation
+ * @rate_kbps: rate in kbit/s
+ * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
+ * &struct ath5k_rx_status.rs_rate and on TX on
+ * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
+ * up to 32 rates, indexed by 1-32. This means we really only need
+ * 6 bits for the rate_code.
+ * @dot11_rate: respective IEEE-802.11 rate value
+ * @control_rate: index of rate assumed to be used to send control frames.
+ * This can be used to set override the value on the rate duration
+ * registers. This is only useful if we can override in the harware at
+ * what rate we want to send control frames at. Note that IEEE-802.11
+ * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
+ * should send ACK/CTS, if we change this value we can be breaking
+ * the spec.
+ *
+ * On RX after the &struct ath5k_desc is parsed by the appropriate
+ * ah_proc_rx_desc() the respective hardware rate value is set in
+ * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
+ * &struct ath5k_tx_status.ts_rate which is later used to setup the
+ * &struct ath5k_desc correctly. This is the hardware rate map we are
+ * aware of:
+ *
+ * rate_code 1 2 3 4 5 6 7 8
+ * rate_kbps 3000 ? ? ? ? ? ? ?
+ *
+ * rate_code 9 10 11 12 13 14 15 16
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ * rate_code 17 18 19 20 21 22 23 24
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ * rate_code 25 26 27 28 29 30 31 32
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ */
struct ath5k_rate {
- u8 valid; /* Valid for rate control */
+ u8 valid;
u32 modulation;
- u16 rate_kbps; /* Rate in kbps used in computetxtime */
- u8 rate_code; /* Rate mapping for h/w descriptors */
+ u16 rate_kbps;
+ u8 rate_code;
u8 dot11_rate;
- u8 control_rate; /* Rate for management frames -not used */
- u16 lp_ack_duration;/* long preamble ACK duration -not used */
- u16 sp_ack_duration;/* short preamble ACK duration -not used */
+ u8 control_rate;
};

/* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
--
1.5.2.5


2007-11-01 21:57:24

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

On 11/01/2007 10:53 PM, Luis R. Rodriguez wrote:
> ** Resending after checkpatch.pl..
>
> This move the OFDM timings on ath5k_hw_reset() onto a helper,
> ath5k_hw_write_ofdm_timings() to make code cleaner.
>
> Changes to ath5k.h, hw.c
> Changes-licensed-under: ISC
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/ath5k/hw.c | 83 ++++++++++++++++++++++++++-------------
> 1 files changed, 55 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
> index 3f78d20..1b9c4f0 100644
> --- a/drivers/net/wireless/ath5k/hw.c
> +++ b/drivers/net/wireless/ath5k/hw.c
> @@ -458,6 +458,56 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
> */
>
> /**
> + * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
> + *
> + * @ah: the &struct ath5k_hw
> + * @channel: the currently set channel upon reset
> + *
> + * Write the OFDM timings for the AR5212 upon reset. This is a helper for
> + * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
> + * depending on the bandwidth of the channel.
> + *
> + */
> +static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
> + struct ieee80211_channel *channel)
> +{
> + /* Get exponent and mantissa and set it */
> + u32 coef_scaled, coef_exp, coef_man,
> + ds_coef_exp, ds_coef_man, clock;
> +
> + if (!(ah->ah_version == AR5K_AR5212) ||
> + !(channel->val & CHANNEL_OFDM))
> + BUG();

Note, that BUG can return (on configurations where !CONFIG_BUG). It is my fault
writing you it won't, sorry! Could you post a patch which will add return from
here and also from places where the BUG() is used in other places?

> +
> + /* Seems there are two PLLs, one for baseband sampling and one
> + * for tuning. Tuning basebands are 40 MHz or 80MHz when in
> + * turbo. */
> + clock = channel->val & CHANNEL_TURBO ? 80 : 40;
> + coef_scaled = ((5 * (clock << 24)) / 2) /
> + channel->freq;

thanks,
--
Jiri Slaby ([email protected])
Faculty of Informatics, Masaryk University

2007-11-01 22:01:16

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

On 11/1/07, Jiri Slaby <[email protected]> wrote:
> On 11/01/2007 10:53 PM, Luis R. Rodriguez wrote:
> > ** Resending after checkpatch.pl..
> >
> > This move the OFDM timings on ath5k_hw_reset() onto a helper,
> > ath5k_hw_write_ofdm_timings() to make code cleaner.
> >
> > Changes to ath5k.h, hw.c
> > Changes-licensed-under: ISC
> >
> > Signed-off-by: Luis R. Rodriguez <[email protected]>
> > ---
> > drivers/net/wireless/ath5k/hw.c | 83 ++++++++++++++++++++++++++-------------
> > 1 files changed, 55 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
> > index 3f78d20..1b9c4f0 100644
> > --- a/drivers/net/wireless/ath5k/hw.c
> > +++ b/drivers/net/wireless/ath5k/hw.c
> > @@ -458,6 +458,56 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
> > */
> >
> > /**
> > + * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
> > + *
> > + * @ah: the &struct ath5k_hw
> > + * @channel: the currently set channel upon reset
> > + *
> > + * Write the OFDM timings for the AR5212 upon reset. This is a helper for
> > + * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
> > + * depending on the bandwidth of the channel.
> > + *
> > + */
> > +static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
> > + struct ieee80211_channel *channel)
> > +{
> > + /* Get exponent and mantissa and set it */
> > + u32 coef_scaled, coef_exp, coef_man,
> > + ds_coef_exp, ds_coef_man, clock;
> > +
> > + if (!(ah->ah_version == AR5K_AR5212) ||
> > + !(channel->val & CHANNEL_OFDM))
> > + BUG();
>
> Note, that BUG can return (on configurations where !CONFIG_BUG). It is my fault
> writing you it won't, sorry! Could you post a patch which will add return from
> here and also from places where the BUG() is used in other places?

The only case where this will trigger is if someone in the driver
called this on hardware not supported so it is intended.

Do you want to BUG() and also return?

> > +
> > + /* Seems there are two PLLs, one for baseband sampling and one
> > + * for tuning. Tuning basebands are 40 MHz or 80MHz when in
> > + * turbo. */
> > + clock = channel->val & CHANNEL_TURBO ? 80 : 40;
> > + coef_scaled = ((5 * (clock << 24)) / 2) /
> > + channel->freq;

Luis

2007-11-01 21:53:26

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

** Resending after checkpatch.pl..

This move the OFDM timings on ath5k_hw_reset() onto a helper,
ath5k_hw_write_ofdm_timings() to make code cleaner.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/hw.c | 83 ++++++++++++++++++++++++++-------------
1 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 3f78d20..1b9c4f0 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -458,6 +458,56 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
*/

/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the OFDM timings for the AR5212 upon reset. This is a helper for
+ * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
+ * depending on the bandwidth of the channel.
+ *
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ /* Get exponent and mantissa and set it */
+ u32 coef_scaled, coef_exp, coef_man,
+ ds_coef_exp, ds_coef_man, clock;
+
+ if (!(ah->ah_version == AR5K_AR5212) ||
+ !(channel->val & CHANNEL_OFDM))
+ BUG();
+
+ /* Seems there are two PLLs, one for baseband sampling and one
+ * for tuning. Tuning basebands are 40 MHz or 80MHz when in
+ * turbo. */
+ clock = channel->val & CHANNEL_TURBO ? 80 : 40;
+ coef_scaled = ((5 * (clock << 24)) / 2) /
+ channel->freq;
+
+ for (coef_exp = 31; coef_exp > 0; coef_exp--)
+ if ((coef_scaled >> coef_exp) & 0x1)
+ break;
+
+ if (!coef_exp)
+ return -EINVAL;
+
+ coef_exp = 14 - (coef_exp - 24);
+ coef_man = coef_scaled +
+ (1 << (24 - coef_exp - 1));
+ ds_coef_man = coef_man >> (24 - coef_exp);
+ ds_coef_exp = coef_exp - 16;
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+ return 0;
+}
+
+/**
* ath5k_hw_write_rate_duration - set rate duration during hw resets
*
* @ah: the &struct ath5k_hw
@@ -696,34 +746,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
*/

/* Write OFDM timings on 5212*/
- if (ah->ah_version == AR5K_AR5212) {
- if (channel->val & CHANNEL_OFDM) {
- /* Get exponent and mantissa and set it */
- u32 coef_scaled, coef_exp, coef_man,
- ds_coef_exp, ds_coef_man, clock;
-
- clock = channel->val & CHANNEL_TURBO ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) /
- channel->freq;
-
- for (coef_exp = 31; coef_exp > 0; coef_exp--)
- if ((coef_scaled >> coef_exp) & 0x1)
- break;
-
- if (!coef_exp)
- return -EINVAL;
-
- coef_exp = 14 - (coef_exp - 24);
- coef_man = coef_scaled +
- (1 << (24 - coef_exp - 1));
- ds_coef_man = coef_man >> (24 - coef_exp);
- ds_coef_exp = coef_exp - 16;
-
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
- }
+ if (ah->ah_version == AR5K_AR5212 &&
+ channel->val & CHANNEL_OFDM) {
+ ret = ath5k_hw_write_ofdm_timings(ah, channel);
+ if (ret)
+ return ret;
}

/*Enable/disable 802.11b mode on 5111
--
1.5.2.5


2007-11-01 04:39:39

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 6/7] ath5k: Clear up settings of AR5K_RSSI_THR register settings

Clear up settings of AR5K_RSSI_THR register settings. These are split between
AR5K_TUNE_BMISS_THRES and AR5K_TUNE_RSSI_THRES.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 10 +++++++++-
drivers/net/wireless/ath5k/hw.c | 11 ++++-------
2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 3354b37..c8ab09a 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -86,8 +86,16 @@
#define AR5K_TUNE_RADAR_ALERT false
#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
-#define AR5K_TUNE_RSSI_THRES 1792
#define AR5K_TUNE_REGISTER_TIMEOUT 20000
+/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
+ * be the max value. */
+#define AR5K_TUNE_RSSI_THRES 129
+/* This must be set when setting the RSSI threshold otherwise it can
+ * prevent a reset. If AR5K_RSSI_THR is read after writing to it
+ * the BMISS_THRES will be seen as 0, seems harware doesn't keep
+ * track of it. Max value depends on harware. For AR5210 this is just 7.
+ * For AR5211+ this seems to be up to 255. */
+#define AR5K_TUNE_BMISS_THRES 7
#define AR5K_TUNE_REGISTER_DWELL_TIME 20000
#define AR5K_TUNE_BEACON_INTERVAL 100
#define AR5K_TUNE_AIFS 2
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 1b9c4f0..f1ba863 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -849,13 +849,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
/*PISR/SISR Not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
- /* XXX: AR5K_RSSI_THR has masks and shifts defined for it, so
- * direct write using ath5k_hw_reg_write seems wrong. Test with:
- * AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR,
- * AR5K_RSSI_THR_BMISS, AR5K_TUNE_RSSI_THRES);
- * with different variables and check results compared
- * to ath5k_hw_reg_write(ah, ) */
- ath5k_hw_reg_write(ah, AR5K_TUNE_RSSI_THRES, AR5K_RSSI_THR);
+ /* If we later allow tuning for this, store into sc structure */
+ data = AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
+ ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
}

/*
--
1.5.2.5


2007-11-01 21:50:39

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/7] ath5k: Clean up ath5k rate duration settings

Replace ath5k's rate duration computations for one using
mac80211's internals. Another consideration here is to simply
remove these and put them into initval values. They seem to be
static values based only on mode. We can do this later though once
we can physically confirm by trial and error these are indeed just
used for ACK timeout. The next puzzle is figuring out which registers
are actually setting the control rates.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>

From: Luis R. Rodriguez <[email protected]>
To: John Linville <[email protected]>
Cc: [email protected], "Jiri Slaby" <[email protected]>,
"Nick Kossifidis" <[email protected]>
Subject: [PATCH 3/7] ath5k: Clean up ath5k rate duration settings

** Resending after running through checkpatch.pl, removes
** some trailing whitespaces.

Replace ath5k's rate duration computations for one using
mac80211's internals. Another consideration here is to simply
remove these and put them into initval values. They seem to be
static values based only on mode.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 80 --------------
drivers/net/wireless/ath5k/hw.c | 201 ++++++++++++++----------------------
2 files changed, 76 insertions(+), 205 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 20567b1..3354b37 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -374,86 +374,6 @@ enum ath5k_pkt_type {
)

/*
- * Used to compute TX times
- */
-#define AR5K_CCK_SIFS_TIME 10
-#define AR5K_CCK_PREAMBLE_BITS 144
-#define AR5K_CCK_PLCP_BITS 48
-
-#define AR5K_OFDM_SIFS_TIME 16
-#define AR5K_OFDM_PREAMBLE_TIME 20
-#define AR5K_OFDM_PLCP_BITS 22
-#define AR5K_OFDM_SYMBOL_TIME 4
-
-#define AR5K_TURBO_SIFS_TIME 8
-#define AR5K_TURBO_PREAMBLE_TIME 14
-#define AR5K_TURBO_PLCP_BITS 22
-#define AR5K_TURBO_SYMBOL_TIME 4
-
-#define AR5K_XR_SIFS_TIME 16
-#define AR5K_XR_PLCP_BITS 22
-#define AR5K_XR_SYMBOL_TIME 4
-
-/* CCK */
-#define AR5K_CCK_NUM_BITS(_frmlen) (_frmlen << 3)
-
-#define AR5K_CCK_PHY_TIME(_sp) (_sp ? \
- ((AR5K_CCK_PREAMBLE_BITS + AR5K_CCK_PLCP_BITS) >> 1) : \
- (AR5K_CCK_PREAMBLE_BITS + AR5K_CCK_PLCP_BITS))
-
-#define AR5K_CCK_TX_TIME(_kbps, _frmlen, _sp) \
- (AR5K_CCK_PHY_TIME(_sp) + \
- ((AR5K_CCK_NUM_BITS(_frmlen) * 1000) / _kbps) + \
- AR5K_CCK_SIFS_TIME)
-
-/* OFDM */
-#define AR5K_OFDM_NUM_BITS(_frmlen) (AR5K_OFDM_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_OFDM_NUM_BITS_PER_SYM(_kbps) ((_kbps * \
- AR5K_OFDM_SYMBOL_TIME) / 1000)
-
-#define AR5K_OFDM_NUM_BITS(_frmlen) (AR5K_OFDM_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_OFDM_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_OFDM_NUM_BITS(_frmlen), \
- AR5K_OFDM_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_OFDM_TX_TIME(_kbps, _frmlen) \
- (AR5K_OFDM_PREAMBLE_TIME + AR5K_OFDM_SIFS_TIME + \
- (AR5K_OFDM_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_OFDM_SYMBOL_TIME))
-
-/* TURBO */
-#define AR5K_TURBO_NUM_BITS(_frmlen) (AR5K_TURBO_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_TURBO_NUM_BITS_PER_SYM(_kbps) (((_kbps << 1) * \
- AR5K_TURBO_SYMBOL_TIME) / 1000)
-
-#define AR5K_TURBO_NUM_BITS(_frmlen) (AR5K_TURBO_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_TURBO_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_TURBO_NUM_BITS(_frmlen), \
- AR5K_TURBO_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_TURBO_TX_TIME(_kbps, _frmlen) \
- (AR5K_TURBO_PREAMBLE_TIME + AR5K_TURBO_SIFS_TIME + \
- (AR5K_TURBO_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_TURBO_SYMBOL_TIME))
-
-/* eXtendent Range (?)*/
-#define AR5K_XR_PREAMBLE_TIME(_kbps) (((_kbps) < 1000) ? 173 : 76)
-
-#define AR5K_XR_NUM_BITS_PER_SYM(_kbps) ((_kbps * \
- AR5K_XR_SYMBOL_TIME) / 1000)
-
-#define AR5K_XR_NUM_BITS(_frmlen) (AR5K_XR_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_XR_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_XR_NUM_BITS(_frmlen), AR5K_XR_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_XR_TX_TIME(_kbps, _frmlen) \
- (AR5K_XR_PREAMBLE_TIME(_kbps) + AR5K_XR_SIFS_TIME + \
- (AR5K_XR_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_XR_SYMBOL_TIME))
-
-/*
* DMA size definitions (2^n+2)
*/
enum ath5k_dmasize {
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 320e32e..17c46e1 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -74,76 +74,6 @@ static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
General Functions
\*******************/

-
-/*
- * Calculate transmition time of a frame
- * TODO: Left here for combatibility, change it in ath5k
- */
-static u16 /*TODO: Is this really hardware dependent ?*/
-ath5k_computetxtime(struct ath5k_hw *ah, const struct ath5k_rate_table *rates,
- u32 frame_length, u16 rate_index, bool short_preamble)
-{
- const struct ath5k_rate *rate;
- u32 value;
-
- AR5K_ASSERT_ENTRY(rate_index, rates->rate_count);
-
- /*
- * Get rate by index
- */
- rate = &rates->rates[rate_index];
-
- /*
- * Calculate the transmission time by operation (PHY) mode
- */
- switch (rate->modulation) {
- /* Standard rates */
- case IEEE80211_RATE_CCK:
- /*
- * CCK / DS mode (802.11b)
- */
- value = AR5K_CCK_TX_TIME(rate->rate_kbps, frame_length,
- short_preamble &&
- rate->modulation == IEEE80211_RATE_CCK_2);
- break;
-
- case IEEE80211_RATE_OFDM:
- /*
- * Orthogonal Frequency Division Multiplexing
- */
- if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_OFDM_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- /* Vendor-specific rates */
- case MODULATION_TURBO:
- /*
- * Orthogonal Frequency Division Multiplexing
- * Atheros "Turbo Mode" (doubled rates)
- */
- if (AR5K_TURBO_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_TURBO_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- case MODULATION_XR:
- /*
- * Orthogonal Frequency Division Multiplexing
- * Atheros "eXtended Range" (XR)
- */
- if (AR5K_XR_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_XR_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- default:
- return 0;
- }
-
- return value;
-}
-
/*
* Functions used internaly
*/
@@ -523,9 +453,80 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
kfree(ah);
}

-/*******************************\
- Reset Functions
-\*******************************/
+/*
+ * Reset function and helpers
+ */
+
+/**
+ * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ *
+ * @ah: the &struct ath5k_hw
+ * @driver_mode: one of enum ieee80211_phymode or our one of our own
+ * vendor modes
+ *
+ * Write the rate duration table for the current mode upon hw reset. This
+ * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
+ * an ACK timeout for the hardware for the current mode for each rate. The
+ * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
+ * and 11Mbps) have another register for the short preamble ACK timeout
+ * calculation.
+ *
+ */
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
+ unsigned int driver_mode)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+ const struct ath5k_rate_table *rt;
+ unsigned int i;
+
+ /* Get rate table for the current operating mode */
+ rt = ath5k_hw_get_rate_table(ah,
+ driver_mode);
+
+ /* Write rate duration table */
+ for (i = 0; i < rt->rate_count; i++) {
+ const struct ath5k_rate *rate, *control_rate;
+ u32 reg;
+ u16 tx_time;
+
+ rate = &rt->rates[i];
+ control_rate = &rt->rates[rate->control_rate];
+
+ /* Set ACK timeout */
+ reg = AR5K_RATE_DUR(rate->rate_code);
+
+ /* An ACK frame consists of 10 bytes. If you add the FCS,
+ * which ieee80211_generic_frame_duration() adds,
+ * its 14 bytes. Note we use the control rate and not the
+ * actual rate for this rate. See mac80211 tx.c
+ * ieee80211_duration() for a brief description of
+ * what rate we should choose to TX ACKs. */
+ tx_time = ieee80211_generic_frame_duration(sc->hw,
+ sc->iface_id, 10, control_rate->rate_kbps/100);
+
+ ath5k_hw_reg_write(ah, tx_time, reg);
+
+ if (!HAS_SHPREAMBLE(i))
+ continue;
+
+ /*
+ * We're not distinguishing short preamble here,
+ * This is true, all we'll get is a longer value here
+ * which is not necessarilly bad. We could use
+ * export ieee80211_frame_duration() but that needs to be
+ * fixed first to be properly used by mac802111 drivers:
+ *
+ * - remove erp stuff and let the routine figure ofdm
+ * erp rates
+ * - remove passing argument ieee80211_local as
+ * drivers don't have access to it
+ * - move drivers using ieee80211_generic_frame_duration()
+ * to this
+ */
+ ath5k_hw_reg_write(ah, tx_time,
+ reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+ }
+}

/*
* Main reset function
@@ -533,7 +534,6 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
struct ieee80211_channel *channel, bool change_channel)
{
- const struct ath5k_rate_table *rt;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u32 data, s_seq, s_ant, s_led[3];
s32 noise_floor;
@@ -660,57 +660,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,

mdelay(1);

- /*
- * Set rate duration table on 5212
- */
- if (ah->ah_version == AR5K_AR5212) {
-
- /*For 802.11b*/
- if (driver_mode == MODE_IEEE80211B) {
-
- /*Get rate table for this operation mode*/
- rt = ath5k_hw_get_rate_table(ah,
- MODE_IEEE80211B);
- if (!rt)
- return -EINVAL;
-
- /*Write rate duration table*/
- for (i = 0; i < rt->rate_count; i++) {
- data = AR5K_RATE_DUR(rt->rates[i].rate_code);
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah, rt,
- 14, rt->rates[i].control_rate,
- false), data);
- if (HAS_SHPREAMBLE(i))
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah,
- rt, 14,
- rt->rates[i].control_rate,
- false), data +
- (AR5K_SET_SHORT_PREAMBLE << 2));
- }
-
- } else {
- /* For 802.11a/g Turbo/XR mode (AR5K_MODE_XR here is
- * O.K. for both a/g - OFDM) */
-
- /* Get rate table for this operation mode */
- rt = ath5k_hw_get_rate_table(ah,
- channel->val & CHANNEL_TURBO ?
- MODE_ATHEROS_TURBO : MODE_ATHEROS_TURBOG);
- if (!rt)
- return -EINVAL;
-
- /* Write rate duration table */
- for (i = 0; i < rt->rate_count; i++)
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah, rt,
- 14, rt->rates[i].control_rate,
- false),
- AR5K_RATE_DUR(rt->rates[i].rate_code));
-
- }
- }
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_write_rate_duration(ah, driver_mode);

/* Fix for first revision of the RF5112 RF chipset */
if (ah->ah_radio >= AR5K_RF5112 &&
--
1.5.2.5


2007-11-01 04:37:25

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 3/7] ath5k: Clean up ath5k rate duration settings

Replace ath5k's rate duration computations for one using
mac80211's internals. Another consideration here is to simply
remove these and put them into initval values. They seem to be
static values based only on mode. We can do this later though once
we can physically confirm by trial and error these are indeed just
used for ACK timeout. The next puzzle is figuring out which registers
are actually setting the control rates.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 80 --------------
drivers/net/wireless/ath5k/hw.c | 201 ++++++++++++++----------------------
2 files changed, 76 insertions(+), 205 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 20567b1..3354b37 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -374,86 +374,6 @@ enum ath5k_pkt_type {
)

/*
- * Used to compute TX times
- */
-#define AR5K_CCK_SIFS_TIME 10
-#define AR5K_CCK_PREAMBLE_BITS 144
-#define AR5K_CCK_PLCP_BITS 48
-
-#define AR5K_OFDM_SIFS_TIME 16
-#define AR5K_OFDM_PREAMBLE_TIME 20
-#define AR5K_OFDM_PLCP_BITS 22
-#define AR5K_OFDM_SYMBOL_TIME 4
-
-#define AR5K_TURBO_SIFS_TIME 8
-#define AR5K_TURBO_PREAMBLE_TIME 14
-#define AR5K_TURBO_PLCP_BITS 22
-#define AR5K_TURBO_SYMBOL_TIME 4
-
-#define AR5K_XR_SIFS_TIME 16
-#define AR5K_XR_PLCP_BITS 22
-#define AR5K_XR_SYMBOL_TIME 4
-
-/* CCK */
-#define AR5K_CCK_NUM_BITS(_frmlen) (_frmlen << 3)
-
-#define AR5K_CCK_PHY_TIME(_sp) (_sp ? \
- ((AR5K_CCK_PREAMBLE_BITS + AR5K_CCK_PLCP_BITS) >> 1) : \
- (AR5K_CCK_PREAMBLE_BITS + AR5K_CCK_PLCP_BITS))
-
-#define AR5K_CCK_TX_TIME(_kbps, _frmlen, _sp) \
- (AR5K_CCK_PHY_TIME(_sp) + \
- ((AR5K_CCK_NUM_BITS(_frmlen) * 1000) / _kbps) + \
- AR5K_CCK_SIFS_TIME)
-
-/* OFDM */
-#define AR5K_OFDM_NUM_BITS(_frmlen) (AR5K_OFDM_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_OFDM_NUM_BITS_PER_SYM(_kbps) ((_kbps * \
- AR5K_OFDM_SYMBOL_TIME) / 1000)
-
-#define AR5K_OFDM_NUM_BITS(_frmlen) (AR5K_OFDM_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_OFDM_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_OFDM_NUM_BITS(_frmlen), \
- AR5K_OFDM_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_OFDM_TX_TIME(_kbps, _frmlen) \
- (AR5K_OFDM_PREAMBLE_TIME + AR5K_OFDM_SIFS_TIME + \
- (AR5K_OFDM_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_OFDM_SYMBOL_TIME))
-
-/* TURBO */
-#define AR5K_TURBO_NUM_BITS(_frmlen) (AR5K_TURBO_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_TURBO_NUM_BITS_PER_SYM(_kbps) (((_kbps << 1) * \
- AR5K_TURBO_SYMBOL_TIME) / 1000)
-
-#define AR5K_TURBO_NUM_BITS(_frmlen) (AR5K_TURBO_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_TURBO_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_TURBO_NUM_BITS(_frmlen), \
- AR5K_TURBO_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_TURBO_TX_TIME(_kbps, _frmlen) \
- (AR5K_TURBO_PREAMBLE_TIME + AR5K_TURBO_SIFS_TIME + \
- (AR5K_TURBO_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_TURBO_SYMBOL_TIME))
-
-/* eXtendent Range (?)*/
-#define AR5K_XR_PREAMBLE_TIME(_kbps) (((_kbps) < 1000) ? 173 : 76)
-
-#define AR5K_XR_NUM_BITS_PER_SYM(_kbps) ((_kbps * \
- AR5K_XR_SYMBOL_TIME) / 1000)
-
-#define AR5K_XR_NUM_BITS(_frmlen) (AR5K_XR_PLCP_BITS + (_frmlen << 3))
-
-#define AR5K_XR_NUM_SYMBOLS(_kbps, _frmlen) \
- DIV_ROUND_UP(AR5K_XR_NUM_BITS(_frmlen), AR5K_XR_NUM_BITS_PER_SYM(_kbps))
-
-#define AR5K_XR_TX_TIME(_kbps, _frmlen) \
- (AR5K_XR_PREAMBLE_TIME(_kbps) + AR5K_XR_SIFS_TIME + \
- (AR5K_XR_NUM_SYMBOLS(_kbps, _frmlen) * AR5K_XR_SYMBOL_TIME))
-
-/*
* DMA size definitions (2^n+2)
*/
enum ath5k_dmasize {
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 320e32e..17c46e1 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -74,76 +74,6 @@ static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
General Functions
\*******************/

-
-/*
- * Calculate transmition time of a frame
- * TODO: Left here for combatibility, change it in ath5k
- */
-static u16 /*TODO: Is this really hardware dependent ?*/
-ath5k_computetxtime(struct ath5k_hw *ah, const struct ath5k_rate_table *rates,
- u32 frame_length, u16 rate_index, bool short_preamble)
-{
- const struct ath5k_rate *rate;
- u32 value;
-
- AR5K_ASSERT_ENTRY(rate_index, rates->rate_count);
-
- /*
- * Get rate by index
- */
- rate = &rates->rates[rate_index];
-
- /*
- * Calculate the transmission time by operation (PHY) mode
- */
- switch (rate->modulation) {
- /* Standard rates */
- case IEEE80211_RATE_CCK:
- /*
- * CCK / DS mode (802.11b)
- */
- value = AR5K_CCK_TX_TIME(rate->rate_kbps, frame_length,
- short_preamble &&
- rate->modulation == IEEE80211_RATE_CCK_2);
- break;
-
- case IEEE80211_RATE_OFDM:
- /*
- * Orthogonal Frequency Division Multiplexing
- */
- if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_OFDM_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- /* Vendor-specific rates */
- case MODULATION_TURBO:
- /*
- * Orthogonal Frequency Division Multiplexing
- * Atheros "Turbo Mode" (doubled rates)
- */
- if (AR5K_TURBO_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_TURBO_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- case MODULATION_XR:
- /*
- * Orthogonal Frequency Division Multiplexing
- * Atheros "eXtended Range" (XR)
- */
- if (AR5K_XR_NUM_BITS_PER_SYM(rate->rate_kbps) == 0)
- return 0;
- value = AR5K_XR_TX_TIME(rate->rate_kbps, frame_length);
- break;
-
- default:
- return 0;
- }
-
- return value;
-}
-
/*
* Functions used internaly
*/
@@ -523,9 +453,80 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
kfree(ah);
}

-/*******************************\
- Reset Functions
-\*******************************/
+/*
+ * Reset function and helpers
+ */
+
+/**
+ * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ *
+ * @ah: the &struct ath5k_hw
+ * @driver_mode: one of enum ieee80211_phymode or our one of our own
+ * vendor modes
+ *
+ * Write the rate duration table for the current mode upon hw reset. This
+ * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
+ * an ACK timeout for the hardware for the current mode for each rate. The
+ * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
+ * and 11Mbps) have another register for the short preamble ACK timeout
+ * calculation.
+ *
+ */
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
+ unsigned int driver_mode)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+ const struct ath5k_rate_table *rt;
+ unsigned int i;
+
+ /* Get rate table for the current operating mode */
+ rt = ath5k_hw_get_rate_table(ah,
+ driver_mode);
+
+ /* Write rate duration table */
+ for (i = 0; i < rt->rate_count; i++) {
+ const struct ath5k_rate *rate, *control_rate;
+ u32 reg;
+ u16 tx_time;
+
+ rate = &rt->rates[i];
+ control_rate = &rt->rates[rate->control_rate];
+
+ /* Set ACK timeout */
+ reg = AR5K_RATE_DUR(rate->rate_code);
+
+ /* An ACK frame consists of 10 bytes. If you add the FCS,
+ * which ieee80211_generic_frame_duration() adds,
+ * its 14 bytes. Note we use the control rate and not the
+ * actual rate for this rate. See mac80211 tx.c
+ * ieee80211_duration() for a brief description of
+ * what rate we should choose to TX ACKs. */
+ tx_time = ieee80211_generic_frame_duration(sc->hw,
+ sc->iface_id, 10, control_rate->rate_kbps/100);
+
+ ath5k_hw_reg_write(ah, tx_time, reg);
+
+ if (!HAS_SHPREAMBLE(i))
+ continue;
+
+ /*
+ * We're not distinguishing short preamble here,
+ * This is true, all we'll get is a longer value here
+ * which is not necessarilly bad. We could use
+ * export ieee80211_frame_duration() but that needs to be
+ * fixed first to be properly used by mac802111 drivers:
+ *
+ * - remove erp stuff and let the routine figure ofdm
+ * erp rates
+ * - remove passing argument ieee80211_local as
+ * drivers don't have access to it
+ * - move drivers using ieee80211_generic_frame_duration()
+ * to this
+ */
+ ath5k_hw_reg_write(ah, tx_time,
+ reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+ }
+}

/*
* Main reset function
@@ -533,7 +534,6 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
struct ieee80211_channel *channel, bool change_channel)
{
- const struct ath5k_rate_table *rt;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u32 data, s_seq, s_ant, s_led[3];
s32 noise_floor;
@@ -660,57 +660,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,

mdelay(1);

- /*
- * Set rate duration table on 5212
- */
- if (ah->ah_version == AR5K_AR5212) {
-
- /*For 802.11b*/
- if (driver_mode == MODE_IEEE80211B) {
-
- /*Get rate table for this operation mode*/
- rt = ath5k_hw_get_rate_table(ah,
- MODE_IEEE80211B);
- if (!rt)
- return -EINVAL;
-
- /*Write rate duration table*/
- for (i = 0; i < rt->rate_count; i++) {
- data = AR5K_RATE_DUR(rt->rates[i].rate_code);
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah, rt,
- 14, rt->rates[i].control_rate,
- false), data);
- if (HAS_SHPREAMBLE(i))
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah,
- rt, 14,
- rt->rates[i].control_rate,
- false), data +
- (AR5K_SET_SHORT_PREAMBLE << 2));
- }
-
- } else {
- /* For 802.11a/g Turbo/XR mode (AR5K_MODE_XR here is
- * O.K. for both a/g - OFDM) */
-
- /* Get rate table for this operation mode */
- rt = ath5k_hw_get_rate_table(ah,
- channel->val & CHANNEL_TURBO ?
- MODE_ATHEROS_TURBO : MODE_ATHEROS_TURBOG);
- if (!rt)
- return -EINVAL;
-
- /* Write rate duration table */
- for (i = 0; i < rt->rate_count; i++)
- ath5k_hw_reg_write(ah,
- ath5k_computetxtime(ah, rt,
- 14, rt->rates[i].control_rate,
- false),
- AR5K_RATE_DUR(rt->rates[i].rate_code));
-
- }
- }
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_write_rate_duration(ah, driver_mode);

/* Fix for first revision of the RF5112 RF chipset */
if (ah->ah_radio >= AR5K_RF5112 &&
--
1.5.2.5


2007-11-01 04:38:21

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 4/7] ath5k: Fix clock on OFDM timing computation

We were setting the clock to the turbo sampling rate always, lets fix this
for plain OFDM sampling rate at 40 MHz. I believe this tunes the PLL to
the desired frequency, by setting the mantissa and the exponent.

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

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

diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 17c46e1..3f78d20 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -698,10 +698,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212) {
if (channel->val & CHANNEL_OFDM) {
+ /* Get exponent and mantissa and set it */
u32 coef_scaled, coef_exp, coef_man,
ds_coef_exp, ds_coef_man, clock;

- clock = channel->val & CHANNEL_T ? 80 : 40;
+ clock = channel->val & CHANNEL_TURBO ? 80 : 40;
coef_scaled = ((5 * (clock << 24)) / 2) /
channel->freq;

--
1.5.2.5


2007-11-01 22:02:13

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

On 11/01/2007 11:01 PM, Luis R. Rodriguez wrote:
> On 11/1/07, Jiri Slaby <[email protected]> wrote:
>> On 11/01/2007 10:53 PM, Luis R. Rodriguez wrote:
>>> + if (!(ah->ah_version == AR5K_AR5212) ||
>>> + !(channel->val & CHANNEL_OFDM))
>>> + BUG();
>> Note, that BUG can return (on configurations where !CONFIG_BUG). It is my fault
>> writing you it won't, sorry! Could you post a patch which will add return from
>> here and also from places where the BUG() is used in other places?
>
> The only case where this will trigger is if someone in the driver
> called this on hardware not supported so it is intended.
>
> Do you want to BUG() and also return?

Yes, exactly.

2007-11-01 04:41:05

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

This adds documentation for struct ath5k_rate. This also removes
some unused variables, lp_ack_duration and sp_ack_duration which
are simply unnecessary. We obviously have information about the rest
of the rate values, we can add more as we go, this just starts this up.
I'll next target cleaning up the RATE macros, think that may be there
the other G mode issues are in.

Changes to ath5k.h
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
1 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index c8ab09a..7147fb4 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -549,17 +549,61 @@ struct ath5k_athchan_2ghz {
* used by the rate control algorytm on MadWiFi.
*/

-#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
+/* Max number of rates on the rate table and what it seems
+ * Atheros hardware supports */
+#define AR5K_MAX_RATES 32

+/**
+ * struct ath5k_rate - rate structure
+ *
+ * This structure is used to get the RX rate or set the TX rate on the
+ * hardware descriptors. It is also used for internal modulation control
+ * and settings.
+ *
+ * @valid: is this a valid rate for the current mode
+ * @modulation: respective mac80211 modulation
+ * @rate_kbps: rate in kbit/s
+ * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
+ * &struct ath5k_rx_status.rs_rate and on TX on
+ * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
+ * up to 32 rates, indexed by 1-32. This means we really only need
+ * 6 bits for the rate_code.
+ * @dot11_rate: respective IEEE-802.11 rate value
+ * @control_rate: index of rate assumed to be used to send control frames.
+ * This can be used to set override the value on the rate duration
+ * registers. This is only useful if we can override in the harware at
+ * what rate we want to send control frames at. Note that IEEE-802.11
+ * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
+ * should send ACK/CTS, if we change this value we can be breaking
+ * the spec.
+ *
+ * On RX after the &struct ath5k_desc is parsed by the appropriate
+ * ah_proc_rx_desc() the respective hardware rate value is set in
+ * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
+ * &struct ath5k_tx_status.ts_rate which is later used to setup the
+ * &struct ath5k_desc correctly. This is the hardware rate map we are
+ * aware of:
+ *
+ * rate_code 1 2 3 4 5 6 7 8
+ * rate_kbps 3000 ? ? ? ? ? ? ?
+ *
+ * rate_code 9 10 11 12 13 14 15 16
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ * rate_code 17 18 19 20 21 22 23 24
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ * rate_code 25 26 27 28 29 30 31 32
+ * rate_kbps ? ? ? ? ? ? ? ?
+ *
+ */
struct ath5k_rate {
- u8 valid; /* Valid for rate control */
+ u8 valid;
u32 modulation;
- u16 rate_kbps; /* Rate in kbps used in computetxtime */
- u8 rate_code; /* Rate mapping for h/w descriptors */
+ u16 rate_kbps;
+ u8 rate_code;
u8 dot11_rate;
- u8 control_rate; /* Rate for management frames -not used */
- u16 lp_ack_duration;/* long preamble ACK duration -not used */
- u16 sp_ack_duration;/* short preamble ACK duration -not used */
+ u8 control_rate;
};

/* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
--
1.5.2.5


2007-11-02 03:11:40

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

On Thu, Nov 01, 2007 at 03:06:51PM -0700, Randy Dunlap wrote:
> On Thu, 1 Nov 2007 17:56:40 -0400 Luis R. Rodriguez wrote:
>
> > ** Resending after checkpatch.pl
> >
> > This adds documentation for struct ath5k_rate. This also removes
> > some unused variables, lp_ack_duration and sp_ack_duration which
> > are simply unnecessary. We obviously have information about the rest
> > of the rate values, we can add more as we go, this just starts this up.
> > I'll next target cleaning up the RATE macros, think that may be there
> > the other G mode issues are in.
>
> Thanks for doing this... but one more change, please:
> (just move lines around, see below)
>
> > Changes to ath5k.h
> > Changes-licensed-under: ISC
> >
> > Signed-off-by: Luis R. Rodriguez <[email protected]>
> > ---
> > drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
> > 1 files changed, 51 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> > index c8ab09a..7147fb4 100644
> > --- a/drivers/net/wireless/ath5k/ath5k.h
> > +++ b/drivers/net/wireless/ath5k/ath5k.h
> > @@ -549,17 +549,61 @@ struct ath5k_athchan_2ghz {
> > * used by the rate control algorytm on MadWiFi.
> > */
> >
> > -#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
> > +/* Max number of rates on the rate table and what it seems
> > + * Atheros hardware supports */
> > +#define AR5K_MAX_RATES 32
>
> As described in Documentation/kernel-doc-nano-HOWTO.txt, the
> structure fields/members should immediately follow the first line.
> After all of the fields/members, you can add general info, like
> the first paragraph that is here.
>
> Example from that doc file:
>
>
> /**
> * struct my_struct - short description
> * @a: first member
> * @b: second member
> *
> * Longer description
> */

New patch, completes the docs and addresses Randy's points.

This adds documentation for struct ath5k_rate. This also removes
some unused variables, lp_ack_duration and sp_ack_duration which
are simply unnecessary.

We're now just missing information about rate hw values:

3-5
16
17-23
28-32

If anyone knows what those are, please let us know.

Changes to ath5k.h
Changes-licensed-under: ISC

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
1 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index c8ab09a..72c24bc 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -549,17 +549,60 @@ struct ath5k_athchan_2ghz {
* used by the rate control algorytm on MadWiFi.
*/

-#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
+/* Max number of rates on the rate table and what it seems
+ * Atheros hardware supports */
+#define AR5K_MAX_RATES 32

+/**
+ * struct ath5k_rate - rate structure
+ * @valid: is this a valid rate for the current mode
+ * @modulation: respective mac80211 modulation
+ * @rate_kbps: rate in kbit/s
+ * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
+ * &struct ath5k_rx_status.rs_rate and on TX on
+ * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
+ * up to 32 rates, indexed by 1-32. This means we really only need
+ * 6 bits for the rate_code.
+ * @dot11_rate: respective IEEE-802.11 rate value
+ * @control_rate: index of rate assumed to be used to send control frames.
+ * This can be used to set override the value on the rate duration
+ * registers. This is only useful if we can override in the harware at
+ * what rate we want to send control frames at. Note that IEEE-802.11
+ * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
+ * should send ACK/CTS, if we change this value we can be breaking
+ * the spec.
+ *
+ * This structure is used to get the RX rate or set the TX rate on the
+ * hardware descriptors. It is also used for internal modulation control
+ * and settings.
+ *
+ * On RX after the &struct ath5k_desc is parsed by the appropriate
+ * ah_proc_rx_desc() the respective hardware rate value is set in
+ * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
+ * &struct ath5k_tx_status.ts_rate which is later used to setup the
+ * &struct ath5k_desc correctly. This is the hardware rate map we are
+ * aware of:
+ *
+ * rate_code 1 2 3 4 5 6 7 8
+ * rate_kbps 3000 1000 ? ? ? 2000 500 48000
+ *
+ * rate_code 9 10 11 12 13 14 15 16
+ * rate_kbps 24000 12000 6000 54000 36000 18000 9000 ?
+ *
+ * rate_code 17 18 19 20 21 22 23 24
+ * rate_kbps ? ? ? ? ? ? ? 11000
+ *
+ * rate_code 25 26 27 28 29 30 31 32
+ * rate_kbps 5500 2000 1000 ? ? ? ? ?
+ *
+ */
struct ath5k_rate {
- u8 valid; /* Valid for rate control */
+ u8 valid;
u32 modulation;
- u16 rate_kbps; /* Rate in kbps used in computetxtime */
- u8 rate_code; /* Rate mapping for h/w descriptors */
+ u16 rate_kbps;
+ u8 rate_code;
u8 dot11_rate;
- u8 control_rate; /* Rate for management frames -not used */
- u16 lp_ack_duration;/* long preamble ACK duration -not used */
- u16 sp_ack_duration;/* short preamble ACK duration -not used */
+ u8 control_rate;
};

/* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */

2007-11-01 18:44:29

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/7] ath5k: Remove opaque pointers from ath5k_hw_attach()

On 11/1/07, Christoph Hellwig <[email protected]> wrote:
> > struct ath5k_hw {
> > u32 ah_magic;
> >
> > - void *ah_sc;
> > - void __iomem *ah_sh;
> > + struct ath5k_softc *ah_sc;
> > + void __iomem *ah_iobase;
> >
> > enum ath5k_int ah_imr;
>
> Why do you need separate ath5k_hw and ath5k_softc structures anyway?

CC'ing Michael Taylor.

I hope we don't need both. This will take a bit to remove though.
Because of the old HAL, things that were MadWIfi driver related could
be written to ath5k_softc and the HAL itself was in charge of only
using ath5k_hw (their respective counterparts in MadWifi).

The only thing that might be useful here is perhaps for locking access
to HW parts, so it is nice to have those parts separate. Recently
there was some effort put into MadWifi by Michael Taylor to ensure A
LOT of HAL access routines were spinlocked before being run. You can
see this in if_ath_hal.h. Essentially a macro which does the
spin_lock_irqsave() was being run before many HAL access routines...
whether we need such extensive locking merits some review. Perhaps
this is where some of our current problems lies in.

Luis

2007-11-01 13:06:44

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2/7] ath5k: Remove opaque pointers from ath5k_hw_attach()

2007/11/1, Luis R. Rodriguez <[email protected]>:
> Since we don't have a HAL anymore there is no point to use opaque pointers
> in ath5k_hw_attach(). This will also give hw.c access to ath5k_softc
> structure now when needed. While we're at it, lets also give some ah_sh
> a reasonable name, ah_sh --> ah_iobase.
>
> 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 | 10 +++++-----
> drivers/net/wireless/ath5k/base.c | 2 +-
> drivers/net/wireless/ath5k/hw.c | 11 +++++------
> 3 files changed, 11 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> index 4122466..20567b1 100644
> --- a/drivers/net/wireless/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath5k/ath5k.h
> @@ -943,8 +943,8 @@ struct ath5k_capabilities {
> struct ath5k_hw {
> u32 ah_magic;
>
> - void *ah_sc;
> - void __iomem *ah_sh;
> + struct ath5k_softc *ah_sc;
> + void __iomem *ah_iobase;
>
> enum ath5k_int ah_imr;
>
> @@ -1042,7 +1042,7 @@ struct ath5k_hw {
> /* General Functions */
> extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set);
> /* Attach/Detach Functions */
> -extern struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc, void __iomem *sh);
> +extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
> extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode);
> extern void ath5k_hw_detach(struct ath5k_hw *ah);
> /* Reset Functions */
> @@ -1151,12 +1151,12 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
>
> static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
> {
> - return ioread32(ah->ah_sh + reg);
> + return ioread32(ah->ah_iobase + reg);
> }
>
> static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
> {
> - iowrite32(val, ah->ah_sh + reg);
> + iowrite32(val, ah->ah_iobase + reg);
> }
>
> #endif
> diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
> index 4b4ddf4..15ae868 100644
> --- a/drivers/net/wireless/ath5k/base.c
> +++ b/drivers/net/wireless/ath5k/base.c
> @@ -559,7 +559,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
> }
>
> /* Initialize device */
> - sc->ah = ath5k_hw_attach(pdev->device, id->driver_data, sc, sc->iobase);
> + sc->ah = ath5k_hw_attach(sc, id->driver_data);
> if (IS_ERR(sc->ah)) {
> ret = PTR_ERR(sc->ah);
> goto err_irq;
> diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
> index 8ac88e7..320e32e 100644
> --- a/drivers/net/wireless/ath5k/hw.c
> +++ b/drivers/net/wireless/ath5k/hw.c
> @@ -27,8 +27,8 @@
> #include <linux/pci.h>
> #include <linux/delay.h>
>
> -#include "ath5k.h"
> #include "reg.h"
> +#include "base.h"
>
> /*Rate tables*/
> static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
> @@ -187,8 +187,7 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
> /*
> * Check if the device is supported and initialize the needed structs
> */
> -struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> - void __iomem *sh)
> +struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
> {
> struct ath5k_hw *ah;
> u8 mac[ETH_ALEN];
> @@ -204,7 +203,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> }
>
> ah->ah_sc = sc;
> - ah->ah_sh = sh;
> + ah->ah_iobase = sc->iobase;
>
> /*
> * HW information
> @@ -323,7 +322,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> ret = ath5k_hw_get_capabilities(ah);
> if (ret) {
> AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
> - device);
> + sc->pdev->device);
> goto err_free;
> }
>
> @@ -331,7 +330,7 @@ struct ath5k_hw *ath5k_hw_attach(u16 device, u8 mac_version, void *sc,
> ret = ath5k_eeprom_read_mac(ah, mac);
> if (ret) {
> AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
> - device);
> + sc->pdev->device);
> goto err_free;
> }
>
> --
> 1.5.2.5
>

Acked-by: Nick Kossifidis <[email protected]>

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

2007-11-01 22:22:01

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

On 11/01/2007 10:57 PM, Jiri Slaby wrote:
> Note, that BUG can return (on configurations where !CONFIG_BUG). It is my fault
> writing you it won't, sorry! Could you post a patch which will add return from
> here and also from places where the BUG() is used in other places?

Ok, after a talk we agreed, that making the BUG() a void is non-recommended
option on embedded and we can let the patch as it is. Hence it is
Acked-by: Jiri Slaby <[email protected]>

2007-11-01 13:27:57

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 6/7] ath5k: Clear up settings of AR5K_RSSI_THR register settings

2007/11/1, Luis R. Rodriguez <[email protected]>:
> Clear up settings of AR5K_RSSI_THR register settings. These are split between
> AR5K_TUNE_BMISS_THRES and AR5K_TUNE_RSSI_THRES.
>
> Changes to ath5k.h, hw.c
> Changes-licensed-under: ISC
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/ath5k/ath5k.h | 10 +++++++++-
> drivers/net/wireless/ath5k/hw.c | 11 ++++-------
> 2 files changed, 13 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> index 3354b37..c8ab09a 100644
> --- a/drivers/net/wireless/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath5k/ath5k.h
> @@ -86,8 +86,16 @@
> #define AR5K_TUNE_RADAR_ALERT false
> #define AR5K_TUNE_MIN_TX_FIFO_THRES 1
> #define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
> -#define AR5K_TUNE_RSSI_THRES 1792
> #define AR5K_TUNE_REGISTER_TIMEOUT 20000
> +/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
> + * be the max value. */
> +#define AR5K_TUNE_RSSI_THRES 129
> +/* This must be set when setting the RSSI threshold otherwise it can
> + * prevent a reset. If AR5K_RSSI_THR is read after writing to it
> + * the BMISS_THRES will be seen as 0, seems harware doesn't keep
> + * track of it. Max value depends on harware. For AR5210 this is just 7.
> + * For AR5211+ this seems to be up to 255. */
> +#define AR5K_TUNE_BMISS_THRES 7
> #define AR5K_TUNE_REGISTER_DWELL_TIME 20000
> #define AR5K_TUNE_BEACON_INTERVAL 100
> #define AR5K_TUNE_AIFS 2
> diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
> index 1b9c4f0..f1ba863 100644
> --- a/drivers/net/wireless/ath5k/hw.c
> +++ b/drivers/net/wireless/ath5k/hw.c
> @@ -849,13 +849,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
> /*PISR/SISR Not available on 5210*/
> if (ah->ah_version != AR5K_AR5210) {
> ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
> - /* XXX: AR5K_RSSI_THR has masks and shifts defined for it, so
> - * direct write using ath5k_hw_reg_write seems wrong. Test with:
> - * AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR,
> - * AR5K_RSSI_THR_BMISS, AR5K_TUNE_RSSI_THRES);
> - * with different variables and check results compared
> - * to ath5k_hw_reg_write(ah, ) */
> - ath5k_hw_reg_write(ah, AR5K_TUNE_RSSI_THRES, AR5K_RSSI_THR);
> + /* If we later allow tuning for this, store into sc structure */
> + data = AR5K_TUNE_RSSI_THRES |
> + AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
> + ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
> }
>
> /*
> --
> 1.5.2.5
>
>

Acked-by: Nick Kossifidis <[email protected]>

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

2007-11-01 04:39:01

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

This move the OFDM timings on ath5k_hw_reset() onto a helper,
ath5k_hw_write_ofdm_timings() to make code cleaner.

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

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath5k/hw.c | 83 ++++++++++++++++++++++++++-------------
1 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 3f78d20..1b9c4f0 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -458,6 +458,56 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
*/

/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the OFDM timings for the AR5212 upon reset. This is a helper for
+ * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
+ * depending on the bandwidth of the channel.
+ *
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ /* Get exponent and mantissa and set it */
+ u32 coef_scaled, coef_exp, coef_man,
+ ds_coef_exp, ds_coef_man, clock;
+
+ if (! (ah->ah_version == AR5K_AR5212) ||
+ ! (channel->val & CHANNEL_OFDM))
+ BUG();
+
+ /* Seems there are two PLLs, one for baseband sampling and one
+ * for tuning. Tuning basebands are 40 MHz or 80MHz when in
+ * turbo. */
+ clock = channel->val & CHANNEL_TURBO ? 80 : 40;
+ coef_scaled = ((5 * (clock << 24)) / 2) /
+ channel->freq;
+
+ for (coef_exp = 31; coef_exp > 0; coef_exp--)
+ if ((coef_scaled >> coef_exp) & 0x1)
+ break;
+
+ if (!coef_exp)
+ return -EINVAL;
+
+ coef_exp = 14 - (coef_exp - 24);
+ coef_man = coef_scaled +
+ (1 << (24 - coef_exp - 1));
+ ds_coef_man = coef_man >> (24 - coef_exp);
+ ds_coef_exp = coef_exp - 16;
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+ return 0;
+}
+
+/**
* ath5k_hw_write_rate_duration - set rate duration during hw resets
*
* @ah: the &struct ath5k_hw
@@ -696,34 +746,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
*/

/* Write OFDM timings on 5212*/
- if (ah->ah_version == AR5K_AR5212) {
- if (channel->val & CHANNEL_OFDM) {
- /* Get exponent and mantissa and set it */
- u32 coef_scaled, coef_exp, coef_man,
- ds_coef_exp, ds_coef_man, clock;
-
- clock = channel->val & CHANNEL_TURBO ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) /
- channel->freq;
-
- for (coef_exp = 31; coef_exp > 0; coef_exp--)
- if ((coef_scaled >> coef_exp) & 0x1)
- break;
-
- if (!coef_exp)
- return -EINVAL;
-
- coef_exp = 14 - (coef_exp - 24);
- coef_man = coef_scaled +
- (1 << (24 - coef_exp - 1));
- ds_coef_man = coef_man >> (24 - coef_exp);
- ds_coef_exp = coef_exp - 16;
-
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
- }
+ if (ah->ah_version == AR5K_AR5212 &&
+ channel->val & CHANNEL_OFDM) {
+ ret = ath5k_hw_write_ofdm_timings(ah, channel);
+ if (ret)
+ return ret;
}

/*Enable/disable 802.11b mode on 5111
--
1.5.2.5


2007-11-01 17:27:54

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 2/7] ath5k: Remove opaque pointers from ath5k_hw_attach()

> struct ath5k_hw {
> u32 ah_magic;
>
> - void *ah_sc;
> - void __iomem *ah_sh;
> + struct ath5k_softc *ah_sc;
> + void __iomem *ah_iobase;
>
> enum ath5k_int ah_imr;

Why do you need separate ath5k_hw and ath5k_softc structures anyway?


2007-11-01 22:27:43

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 5/7] ath5k: Move OFDM timings into a helper routine

2007/11/2, Jiri Slaby <[email protected]>:
> On 11/01/2007 10:57 PM, Jiri Slaby wrote:
> > Note, that BUG can return (on configurations where !CONFIG_BUG). It is my fault
> > writing you it won't, sorry! Could you post a patch which will add return from
> > here and also from places where the BUG() is used in other places?
>
> Ok, after a talk we agreed, that making the BUG() a void is non-recommended
> option on embedded and we can let the patch as it is. Hence it is
> Acked-by: Jiri Slaby <[email protected]>
>

Acked-by: Nick Kossifidis <[email protected]>

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

2007-11-01 22:07:04

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH 7/7] ath5k: Add documentation for struct ath5k_rate

On Thu, 1 Nov 2007 17:56:40 -0400 Luis R. Rodriguez wrote:

> ** Resending after checkpatch.pl
>
> This adds documentation for struct ath5k_rate. This also removes
> some unused variables, lp_ack_duration and sp_ack_duration which
> are simply unnecessary. We obviously have information about the rest
> of the rate values, we can add more as we go, this just starts this up.
> I'll next target cleaning up the RATE macros, think that may be there
> the other G mode issues are in.

Thanks for doing this... but one more change, please:
(just move lines around, see below)

> Changes to ath5k.h
> Changes-licensed-under: ISC
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/ath5k/ath5k.h | 58 +++++++++++++++++++++++++++++++----
> 1 files changed, 51 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
> index c8ab09a..7147fb4 100644
> --- a/drivers/net/wireless/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath5k/ath5k.h
> @@ -549,17 +549,61 @@ struct ath5k_athchan_2ghz {
> * used by the rate control algorytm on MadWiFi.
> */
>
> -#define AR5K_MAX_RATES 32 /*max number of rates on the rate table*/
> +/* Max number of rates on the rate table and what it seems
> + * Atheros hardware supports */
> +#define AR5K_MAX_RATES 32

As described in Documentation/kernel-doc-nano-HOWTO.txt, the
structure fields/members should immediately follow the first line.
After all of the fields/members, you can add general info, like
the first paragraph that is here.

Example from that doc file:


/**
* struct my_struct - short description
* @a: first member
* @b: second member
*
* Longer description
*/


> +/**
> + * struct ath5k_rate - rate structure
> + *
> + * This structure is used to get the RX rate or set the TX rate on the
> + * hardware descriptors. It is also used for internal modulation control
> + * and settings.
> + *
> + * @valid: is this a valid rate for the current mode
> + * @modulation: respective mac80211 modulation
> + * @rate_kbps: rate in kbit/s
> + * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
> + * &struct ath5k_rx_status.rs_rate and on TX on
> + * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
> + * up to 32 rates, indexed by 1-32. This means we really only need
> + * 6 bits for the rate_code.
> + * @dot11_rate: respective IEEE-802.11 rate value
> + * @control_rate: index of rate assumed to be used to send control frames.
> + * This can be used to set override the value on the rate duration
> + * registers. This is only useful if we can override in the harware at
> + * what rate we want to send control frames at. Note that IEEE-802.11
> + * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
> + * should send ACK/CTS, if we change this value we can be breaking
> + * the spec.
> + *
> + * On RX after the &struct ath5k_desc is parsed by the appropriate
> + * ah_proc_rx_desc() the respective hardware rate value is set in
> + * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
> + * &struct ath5k_tx_status.ts_rate which is later used to setup the
> + * &struct ath5k_desc correctly. This is the hardware rate map we are
> + * aware of:
> + *
> + * rate_code 1 2 3 4 5 6 7 8
> + * rate_kbps 3000 ? ? ? ? ? ? ?
> + *
> + * rate_code 9 10 11 12 13 14 15 16
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + * rate_code 17 18 19 20 21 22 23 24
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + * rate_code 25 26 27 28 29 30 31 32
> + * rate_kbps ? ? ? ? ? ? ? ?
> + *
> + */
> struct ath5k_rate {
> - u8 valid; /* Valid for rate control */
> + u8 valid;
> u32 modulation;
> - u16 rate_kbps; /* Rate in kbps used in computetxtime */
> - u8 rate_code; /* Rate mapping for h/w descriptors */
> + u16 rate_kbps;
> + u8 rate_code;
> u8 dot11_rate;
> - u8 control_rate; /* Rate for management frames -not used */
> - u16 lp_ack_duration;/* long preamble ACK duration -not used */
> - u16 sp_ack_duration;/* short preamble ACK duration -not used */
> + u8 control_rate;
> };
>
> /* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
> --

---
~Randy