2009-12-06 17:20:21

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH 0/4] Setting coverage class (and ACK timeout and slot time)

These patches implement a feature essential for long distance wireless links:
setting ACK timeout and slot time. The API is based on a parameter called
Coverage Class specified by the 802.11 standard.

The first two patches add support to the kernel 802.11 stack via a new nl80211
parameter and a mac80211 callback.

Following two patches implement the callback in ath5k driver. Implementation
in ath9k driver is planned.

One additional patch outside the series adds the necessary userspace support
to iw.

Lukas Turek


2009-12-06 17:24:52

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH 3/4] ath5k: Fix functions for getting/setting slot time

Functions ath5k_hw_get_slot_time and ath5k_hw_set_slot_time were
converting microseconds to clocks only for AR5210, although it's needed
for all supported devices. The conversion was moved outside the
hardware-specific branches.

These functions are not called from anywhere yet, but they are needed
for an implementation of mac80211 callback set_coverage.

Signed-off-by: Lukas Turek <[email protected]>
---
drivers/net/wireless/ath/ath5k/qcu.c | 21 ++++++++++++++-------
1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/qcu.c
b/drivers/net/wireless/ath/ath5k/qcu.c
index eeebb9a..248878a 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -520,12 +520,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah,
unsigned int queue)
*/
unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
{
+ unsigned int slot_time_clock;
+
ATH5K_TRACE(ah->ah_sc);
+
if (ah->ah_version == AR5K_AR5210)
- return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
- AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
+ slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
else
- return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
+ slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
+
+ return ath5k_hw_clocktoh(slot_time_clock & 0xffff, ah->ah_turbo);
}

/*
@@ -533,15 +537,18 @@ unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
*/
int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
{
+ u32 slot_time_clock = ath5k_hw_htoclock(slot_time, ah->ah_turbo);
+
ATH5K_TRACE(ah->ah_sc);
- if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
+
+ if (slot_time_clock < AR5K_SLOT_TIME_9 ||
+ slot_time_clock > AR5K_SLOT_TIME_MAX)
return -EINVAL;

if (ah->ah_version == AR5K_AR5210)
- ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
- ah->ah_turbo), AR5K_SLOT_TIME);
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
else
- ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);

return 0;
}
--
1.6.4.4

2009-12-07 09:47:57

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

Lukáš Turek wrote:
> On 6.12.2009 20:20 Felix Fietkau wrote:
>> In 2.4 GHz, regular slot time is 20 usec, unless short slot is enabled.
>> 2.4 GHz with short slot and 5 GHz both use 9 usec.
> Yes, but where the short slot time gets enabled? According to the standard
> (don't have the reference now) all stations in 802.11g network should switch
> to 20 usec slot time when 802.11b-only station connects. But I can't find
> this anywhere in the driver, the only write to AR5K_DCU_GBL_IFS_SLOT is in
> initvals.c - it seems it's not implemented yet.
>
> After some more digging I found that the function ath5k_hw_clocktoh is wrong,
> there are more possible clock rates than 40 and 80, this is in FreeBSD
> driver:
> /* 11a Turbo 11b 11g 108g */
> static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };
>
> Now the values in initvals.c finally make sense:
>
> a/XR aTurbo b g (DYN) gTurbo
> hex 0x168 0x1e0 0x1b8 0x18c 0x1e0
> clocks 360 480 440 396 480
> usec 9 6 20 9 6
>
> Unfortunately I still don't know how to calculate the ACK timeout for
> different slot time than 9. The formula in athctrl is
> 2 * slot_time + 3
> and I don't know where the '3' comes from. Any ideas?
I went through 802.11-2007 again to figure out how this is supposed to
be calculated. The document states:

aSIFSTime is: aRxRFDelay + aRxPLCPDelay + aMACProcessingDelay +
aRxTxTurnaroundTime.
aSlotTime is: aCCATime + aRxTxTurnaroundTime + aAirPropagationTime +
aMACProcessingDelay.
ACKTimeout is: aSIFSTime + aSlotTime + aPHY-RX-START-Delay

SIFS is usually 10 usec and aAirPropagationTime is the propagation for
the round trip, not just one way. It defaults to 1 usec.

Also, Coverage Class = aAirPropagationTime * 3 usec
So a more correct formula might be:
int slot_time = slot_time_base + coverage_class * 3;
int ack_timeout = slot_time + 10 + 3;

I'm still not sure about the offset of 3 for ack_timeout, but since it's
a small constant, it probably won't matter too much.

Of course, the distance settting code in iw probably also needs
changing, as it needs to accomodate for aAirPropagationTime being the
round trip time, not one-way.

- Felix

2009-12-06 19:32:13

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On 6.12.2009 20:28 Lukáš Turek wrote:
> I looked at the rndis driver, but it seems it could be configured via
> wireless extensions only, it does not define cfg80211_ops at all, so I
> think it cannot be managed via nl80211 and I don't see your point there...
Sorry, I looked at some older version of the driver...

Lukas Turek


Attachments:
(No filename) (330.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-06 18:49:24

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On Sun, 2009-12-06 at 19:45 +0100, Lukáš Turek wrote:
> On 6.12.2009 19:01 Johannes Berg wrote:
> > This patch assumes that all hardware supports this, which is not really
> > what you want. You'll want to know if it can't be set. Yes, we assume
> > rts/cts can be set always, but that's a _much_ safer bet.
> If the hardware does not support it, the operation will fail with EOPNOTSUPP:
>
> # iw phy0 set coverage 1
> command failed: Operation not supported (-95)

Umm, no it won't, that's only with your specific mac80211
implementation. Try on rndis for instance.

johannes


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

2009-12-09 13:30:41

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 2009-12-09 2:12 PM, Luk?? Turek wrote:
>> Some hardware internally calculates the ACK timeout based on the
>> configured slot time. Broadcom does it this way.
>> Maybe adjusting the ACK timeout without adjusting the slot time works,
>> but it'll probably interfere with CSMA.
> Ahteros is not Broadcom, it does not have a firmware, I'm writing the ACK
> timeout directly into a register of the MAC chip. But you're suggesting what
> I said in previus mail: we have to understand what the hardware does. And as
> there is no documentation, the only way is experiment. Most of ath5k was
> developed this way.
>
>> > 802.11a: 21 ?s
>> > 802.11b: 27 ?s
>> > 802.11g: 19 ?s
>>
>> How did you measure it?
> Just by gradually lowering the value in ACK timeout register (it's accessible
> via sysctl in FreeBSD) and testing the link using ordinary ping. When the ACK
> timeout was too low, packetloss grew from 0% to 50% or so.
That's definitely completely inaccurate. Even before you get packet
loss, as you lower the ACK timeout value, you will first start to get an
increase in the number of retransmissions.

>> I'm guessing that most hardware does have some degree of tolerance for
>> timing variation. IMHO, if the standard recommends slightly higher but
>> working values for the same distance, we should use that rather than
>> experimentally determined limits.
> The problem is, it's not slightly higher, it's twice or more higher:
> aSIFSTime + aSlotTime + aPHY-RX-START-Delay is 50 in 802.11a mode, while the
> default ACK timeout for 802.11a used in ath5k initialisation is 25. And in
> 802.11b the aPHY-RX-START-Delay alone is defined as 192 ?s, while the default
> used by ath5k is 48.
>
> I looked into the current Madwifi sources again, and found they use only
> aSIFSTime + aSlotTime as ACK timeout. That's 25 for 11a, 30 for 11b and 19 for
> 11g, so it's in line with my experimental observations and also the 11a ath5k
> default. Probably the hardware accounts for aPHY-RX-START-Delay itself (it's
> PHY value, while ACK timeout is MAC chip register).
Yes, the current formula in Madwifi looks correct. We should use that.

- Felix

2009-12-06 17:29:26

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH] iw: Add support for NL80211_ATTR_WIPHY_COVERAGE_CLASS

New nl80211 attribute NL80211_ATTR_WIPHY_COVERAGE_CLASS allows setting
IEEE 802.11 coverage class, which is then used by drivers to calculate
slot time and ACK timeout for long distance links.

Two iw parameters are added: 'coverage' sets the coverage class
directly, while 'distance' is more user-friendly, as it allows to set
just the link distance and let iw do the necessary calculation itself.

Signed-off-by: Lukas Turek <[email protected]>
---
info.c | 7 +++++++
nl80211.h | 15 +++++++++++++++
phy.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/info.c b/info.c
index ddff78b..3c69afc 100644
--- a/info.c
+++ b/info.c
@@ -264,6 +264,13 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
printf("\tRTS threshold: %d\n", rts);
}

+ if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
+ unsigned int coverage;
+
+ coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
+ printf("\tCoverage class: %d (up to %dm)\n", coverage, 900 * coverage);
+ }
+
if (!tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES])
goto commands;

diff --git a/nl80211.h b/nl80211.h
index 45db17f..e241ed1 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -349,6 +349,10 @@ enum nl80211_commands {
NL80211_CMD_GET_SURVEY,
NL80211_CMD_NEW_SURVEY_RESULTS,

+ NL80211_CMD_SET_PMKSA,
+ NL80211_CMD_DEL_PMKSA,
+ NL80211_CMD_FLUSH_PMKSA,
+
/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
@@ -398,6 +402,8 @@ enum nl80211_commands {
* @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
* larger than or equal to this use RTS/CTS handshake); allowed range:
* 0..65536, disable with (u32)-1; dot11RTSThreshold; u32
+ * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11
+ * section 7.3.2.9; dot11CoverageClass; u8
*
* @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
* @NL80211_ATTR_IFNAME: network interface name
@@ -598,6 +604,10 @@ enum nl80211_commands {
* the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
* containing info as possible, see &enum survey_info.
*
+ * @NL80211_ATTR_PMKID: PMK material for PMKSA caching.
+ * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can
+ * cache, a wiphy attribute.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -732,6 +742,11 @@ enum nl80211_attrs {

NL80211_ATTR_SURVEY_INFO,

+ NL80211_ATTR_PMKID,
+ NL80211_ATTR_MAX_NUM_PMKIDS,
+
+ NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
diff --git a/phy.c b/phy.c
index 8dd01aa..eb95bd5 100644
--- a/phy.c
+++ b/phy.c
@@ -164,3 +164,61 @@ static int handle_netns(struct nl80211_state *state,
COMMAND(set, netns, "<pid>",
NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns,
"Put this wireless device into a different network namespace");
+
+static int handle_coverage(struct nl80211_state *state,
+ struct nl_cb *cb,
+ struct nl_msg *msg,
+ int argc, char **argv)
+{
+ unsigned int coverage;
+
+ if (argc != 1)
+ return 1;
+
+ coverage = strtoul(argv[0], NULL, 10);
+ if (coverage > 255)
+ return 1;
+
+ NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage);
+
+ return 0;
+ nla_put_failure:
+ return -ENOBUFS;
+}
+COMMAND(set, coverage, "<coverage class>",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_coverage,
+ "Set coverage class (1 for every 3 usec of air propagation time).\n"
+ "Valid values: 0 - 255.");
+
+static int handle_distance(struct nl80211_state *state,
+ struct nl_cb *cb,
+ struct nl_msg *msg,
+ int argc, char **argv)
+{
+ unsigned int distance, coverage;
+
+ if (argc != 1)
+ return 1;
+
+ distance = strtoul(argv[0], NULL, 10);
+
+ /*
+ * Divide distance by speed of light in m/usec (300) to get air
+ * propagation time and then by three to get coverage class as
+ * specified in IEEE 802.11-2007 table 7-27 and round the result
+ * upwards.
+ */
+ coverage = (distance + 899) / 900;
+ if (coverage > 255)
+ return 1;
+
+ NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage);
+
+ return 0;
+ nla_put_failure:
+ return -ENOBUFS;
+}
+COMMAND(set, distance, "<distance>",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_distance,
+ "Set appropriate coverage class for given link distance in meters.\n"
+ "Valid values: 0 - 229500");
--
1.6.4.4

2009-12-06 21:53:11

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH] iw: Add support for NL80211_ATTR_WIPHY_COVERAGE_CLASS

On Sun, Dec 6, 2009 at 1:49 PM, Luis R. Rodriguez <[email protected]> wrote:
> On Sun, Dec 6, 2009 at 9:29 AM, Lukáš Turek <[email protected]> wrote:
>> New nl80211 attribute NL80211_ATTR_WIPHY_COVERAGE_CLASS allows setting
>> IEEE 802.11 coverage class, which is then used by drivers to calculate
>> slot time and ACK timeout for long distance links.
>>
>> Two iw parameters are added: 'coverage' sets the coverage class
>> directly, while 'distance' is more user-friendly, as it allows to set
>> just the link distance and let iw do the necessary calculation itself.
>>
>> Signed-off-by: Lukas Turek <[email protected]>
>> ---
>>  info.c    |    7 +++++++
>>  nl80211.h |   15 +++++++++++++++
>>  phy.c     |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 80 insertions(+), 0 deletions(-)
>>
>> diff --git a/info.c b/info.c
>> index ddff78b..3c69afc 100644
>> --- a/info.c
>> +++ b/info.c
>> @@ -264,6 +264,13 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
>>                        printf("\tRTS threshold: %d\n", rts);
>>        }
>>
>> +       if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
>> +               unsigned int coverage;
>
> Just some quick comments.
>
> u8 seems more appropriate, given that you define this a u8 anyway.
>
>> +
>> +               coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
>> +               printf("\tCoverage class: %d (up to %dm)\n", coverage, 900 * coverage);
>
> printf ?

Neverind, forgot this was userspace :)

Luis

2009-12-06 17:26:46

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

The callback sets slot time as specified in IEEE 802.11-2007 section
17.3.8.6 (for 20MHz channels only for now) and ACK and CTS timeouts
using calculations taken from Madwifi's athctrl. The values are
persistent, they are restored after device reset.

Signed-off-by: Lukas Turek <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++
drivers/net/wireless/ath/ath5k/base.c | 22 ++++++++++++++++++++++
drivers/net/wireless/ath/ath5k/pcu.c | 19 +++++++++++++++++++
drivers/net/wireless/ath/ath5k/reset.c | 4 ++++
4 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6a2a967..1b906e6 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1063,6 +1063,7 @@ struct ath5k_hw {
u32 ah_cw_min;
u32 ah_cw_max;
u32 ah_limit_tx_retries;
+ u8 ah_coverage_class;

/* Antenna Control */
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1231,6 +1232,7 @@ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
+extern void ath5k_hw_set_coverage(struct ath5k_hw *ah, u8 coverage_class);
/* Key table (WEP) functions */
extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a4c086f..27c65b9 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -254,6 +254,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
u32 changes);
static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
+static void ath5k_set_coverage(struct ieee80211_hw *hw, u8 coverage_class);

static const struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
@@ -274,6 +275,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
.bss_info_changed = ath5k_bss_info_changed,
.sw_scan_start = ath5k_sw_scan_start,
.sw_scan_complete = ath5k_sw_scan_complete,
+ .set_coverage = ath5k_set_coverage,
};

/*
@@ -3274,3 +3276,23 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
AR5K_LED_ASSOC : AR5K_LED_INIT);
}
+
+/**
+ * ath5k_set_coverage - Set coverage class
+ *
+ * @hw: struct ieee80211_hw pointer
+ * @coverage_class: IEEE 802.11 coverage class
+ *
+ * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
+ * coverage class. The values are persistent, they are set again after device
+ * reset.
+ */
+static void ath5k_set_coverage(struct ieee80211_hw *hw, u8 coverage_class)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ mutex_lock(&sc->lock);
+ ath5k_hw_set_coverage(sc->ah, coverage_class);
+ sc->ah->ah_coverage_class = coverage_class; /* Restored on reset */
+ mutex_unlock(&sc->lock);
+}
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 64fc1eb..2383e22 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -1050,3 +1050,22 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
return 0;
}

+/**
+ * ath5k_hw_set_coverage - Set coverage class
+ *
+ * @ah: The &struct ath5k_hw
+ * @coverage_class: IEEE 802.11 coverage class
+ *
+ * Sets slot time, ACK timeout and CTS timeout for given coverage class.
+ */
+void ath5k_hw_set_coverage(struct ath5k_hw *ah, u8 coverage_class)
+{
+ /* Calculations taken from Madwifi's athctrl */
+ int slot_time = 9 + 3 * coverage_class;
+ int ack_timeout = slot_time * 2 + 3;
+ int cts_timeout = ack_timeout;
+
+ ath5k_hw_set_slot_time(ah, slot_time);
+ ath5k_hw_set_ack_timeout(ah, ack_timeout);
+ ath5k_hw_set_cts_timeout(ah, cts_timeout);
+}
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 62954fc..85aeecf 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1317,6 +1317,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Restore antenna mode */
ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);

+ /* Restore slot time and ACK timeouts */
+ if (ah->ah_coverage_class > 0)
+ ath5k_hw_set_coverage(ah, ah->ah_coverage_class);
+
/*
* Configure QCUs/DCUs
*/
--
1.6.4.4

2009-12-06 17:22:48

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

The new attribute NL80211_ATTR_WIPHY_COVERAGE_CLASS sets IEEE 802.11
Coverage Class, which depends on maximum distance of nodes in a
wireless network. It's required for long distance links (more than a few
hundred meters).

Signed-off-by: Lukas Turek <[email protected]>
---
include/linux/nl80211.h | 4 ++++
include/net/cfg80211.h | 2 ++
net/wireless/core.c | 1 +
net/wireless/nl80211.c | 15 +++++++++++++++
4 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index da8ea2e..e241ed1 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -402,6 +402,8 @@ enum nl80211_commands {
* @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
* larger than or equal to this use RTS/CTS handshake); allowed range:
* 0..65536, disable with (u32)-1; dot11RTSThreshold; u32
+ * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11
+ * section 7.3.2.9; dot11CoverageClass; u8
*
* @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
* @NL80211_ATTR_IFNAME: network interface name
@@ -743,6 +745,8 @@ enum nl80211_attrs {
NL80211_ATTR_PMKID,
NL80211_ATTR_MAX_NUM_PMKIDS,

+ NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0884b9a..fe50c71 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -837,6 +837,7 @@ enum wiphy_params_flags {
WIPHY_PARAM_RETRY_LONG = 1 << 1,
WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2,
WIPHY_PARAM_RTS_THRESHOLD = 1 << 3,
+ WIPHY_PARAM_COVERAGE_CLASS = 1 << 4,
};

/**
@@ -1217,6 +1218,7 @@ struct wiphy {
u8 retry_long;
u32 frag_threshold;
u32 rts_threshold;
+ u8 coverage_class;

char fw_version[ETHTOOL_BUSINFO_LEN];
u32 hw_version;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index c674567..14e14ce 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -402,6 +402,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
rdev->wiphy.retry_long = 4;
rdev->wiphy.frag_threshold = (u32) -1;
rdev->wiphy.rts_threshold = (u32) -1;
+ rdev->wiphy.coverage_class = 0;

return &rdev->wiphy;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a602843..7835846 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -69,6 +69,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
[NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
[NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
[NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },

[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -442,6 +443,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
dev->wiphy.frag_threshold);
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
dev->wiphy.rts_threshold);
+ NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+ dev->wiphy.coverage_class);

NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
dev->wiphy.max_scan_ssids);
@@ -681,6 +684,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
u32 changed;
u8 retry_short = 0, retry_long = 0;
u32 frag_threshold = 0, rts_threshold = 0;
+ u8 coverage_class = 0;

rtnl_lock();

@@ -803,9 +807,16 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
changed |= WIPHY_PARAM_RTS_THRESHOLD;
}

+ if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
+ coverage_class = nla_get_u8(
+ info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
+ changed |= WIPHY_PARAM_COVERAGE_CLASS;
+ }
+
if (changed) {
u8 old_retry_short, old_retry_long;
u32 old_frag_threshold, old_rts_threshold;
+ u8 old_coverage_class;

if (!rdev->ops->set_wiphy_params) {
result = -EOPNOTSUPP;
@@ -816,6 +827,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
old_retry_long = rdev->wiphy.retry_long;
old_frag_threshold = rdev->wiphy.frag_threshold;
old_rts_threshold = rdev->wiphy.rts_threshold;
+ old_coverage_class = rdev->wiphy.coverage_class;

if (changed & WIPHY_PARAM_RETRY_SHORT)
rdev->wiphy.retry_short = retry_short;
@@ -825,6 +837,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
rdev->wiphy.frag_threshold = frag_threshold;
if (changed & WIPHY_PARAM_RTS_THRESHOLD)
rdev->wiphy.rts_threshold = rts_threshold;
+ if (changed & WIPHY_PARAM_COVERAGE_CLASS)
+ rdev->wiphy.coverage_class = coverage_class;

result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
if (result) {
@@ -832,6 +846,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
rdev->wiphy.retry_long = old_retry_long;
rdev->wiphy.frag_threshold = old_frag_threshold;
rdev->wiphy.rts_threshold = old_rts_threshold;
+ rdev->wiphy.coverage_class = old_coverage_class;
}
}

--
1.6.4.4

2009-12-06 19:20:56

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

Lukáš Turek wrote:
> On 6.12.2009 19:34 Felix Fietkau wrote:
>> This part is wrong. The slot time can be either short or long, based on
>> configuration and PHY type.
> I did some test, and the value returned by ath5k_hw_get_slot_time was always
> 9, even when connected to 802.11b-only AP. I didn't try the turbo mode,
> though. Unfortunately I don't know how to calculate ACK timeouts for
> a different slot time - the formula I used is the only one in both Madwifi's
> and FreeBSD's athctrl.
In 2.4 GHz, regular slot time is 20 usec, unless short slot is enabled.
2.4 GHz with short slot and 5 GHz both use 9 usec.

- Felix

2009-12-06 21:59:34

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On 6.12.2009 19:49 Johannes Berg wrote:
> Umm, no it won't, that's only with your specific mac80211
> implementation. Try on rndis for instance.
So I looked at both drivers that define set_wiphy_params: rndis and
iwmc3200wifi. Both ignore WIPHY_PARAM_RETRY_SHORT and WIPHY_PARAM_RETRY_LONG,
so WIPHY_PARAM_COVERAGE_CLASS is just another parameter they would ignore.

Anyway, I don't mind adding set_coverage_class to cfg80211_ops if you think
it's the best solution. It won't change the netlink API.

Lukas Turek


Attachments:
(No filename) (516.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-06 18:35:05

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

Lukáš Turek wrote:
> The callback sets slot time as specified in IEEE 802.11-2007 section
> 17.3.8.6 (for 20MHz channels only for now) and ACK and CTS timeouts
> using calculations taken from Madwifi's athctrl. The values are
> persistent, they are restored after device reset.
>
> Signed-off-by: Lukas Turek <[email protected]>
> ---
> diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
> index 64fc1eb..2383e22 100644
> --- a/drivers/net/wireless/ath/ath5k/pcu.c
> +++ b/drivers/net/wireless/ath/ath5k/pcu.c
> @@ -1050,3 +1050,22 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
> return 0;
> }
>
> +/**
> + * ath5k_hw_set_coverage - Set coverage class
> + *
> + * @ah: The &struct ath5k_hw
> + * @coverage_class: IEEE 802.11 coverage class
> + *
> + * Sets slot time, ACK timeout and CTS timeout for given coverage class.
> + */
> +void ath5k_hw_set_coverage(struct ath5k_hw *ah, u8 coverage_class)
> +{
> + /* Calculations taken from Madwifi's athctrl */
> + int slot_time = 9 + 3 * coverage_class;
> + int ack_timeout = slot_time * 2 + 3;
> + int cts_timeout = ack_timeout;
This part is wrong. The slot time can be either short or long, based on
configuration and PHY type.

- Felix

2009-12-06 18:01:15

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On Sun, 2009-12-06 at 18:22 +0100, Lukáš Turek wrote:
> The new attribute NL80211_ATTR_WIPHY_COVERAGE_CLASS sets IEEE 802.11
> Coverage Class,

This patch assumes that all hardware supports this, which is not really
what you want. You'll want to know if it can't be set. Yes, we assume
rts/cts can be set always, but that's a _much_ safer bet.

johannes


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

2009-12-06 17:23:41

by Lukáš Turek

[permalink] [raw]
Subject: [PATCH 2/4] mac80211: Add new callback set_coverage

Mac80211 callback to driver set_coverage() sets slot time and ACK timeout
for given coverage class. The callback is optional, but it's essential for
long distance links.

Signed-off-by: Lukas Turek <[email protected]>
---
include/net/mac80211.h | 5 +++++
net/mac80211/cfg.c | 6 ++++++
2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 1d75b96..2865bc6 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1477,6 +1477,10 @@ enum ieee80211_ampdu_mlme_action {
* need to set wiphy->rfkill_poll to %true before registration,
* and need to call wiphy_rfkill_set_hw_state() in the callback.
*
+ * @set_coverage: Set slot time for given coverage class as specified
+ * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout
+ * accordingly. Optional function, could be NULL.
+ *
* @testmode_cmd: Implement a cfg80211 test mode command.
*/
struct ieee80211_ops {
@@ -1531,6 +1535,7 @@ struct ieee80211_ops {
struct ieee80211_sta *sta, u16 tid, u16 *ssn);

void (*rfkill_poll)(struct ieee80211_hw *hw);
+ void (*set_coverage)(struct ieee80211_hw *hw, u8 coverage_class);
#ifdef CONFIG_NL80211_TESTMODE
int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
#endif
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 93ee1fd..f0ab669 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1236,6 +1236,12 @@ static int ieee80211_set_wiphy_params(struct wiphy
*wiphy, u32 changed)
struct ieee80211_local *local = wiphy_priv(wiphy);
int err;

+ if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
+ if (!local->ops->set_coverage)
+ return -EOPNOTSUPP;
+ local->ops->set_coverage(&local->hw, wiphy->coverage_class);
+ }
+
if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
err = drv_set_rts_threshold(local, wiphy->rts_threshold);

--
1.6.4.4

2009-12-06 20:23:08

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 6.12.2009 20:20 Felix Fietkau wrote:
> In 2.4 GHz, regular slot time is 20 usec, unless short slot is enabled.
> 2.4 GHz with short slot and 5 GHz both use 9 usec.
Yes, but where the short slot time gets enabled? According to the standard
(don't have the reference now) all stations in 802.11g network should switch
to 20 usec slot time when 802.11b-only station connects. But I can't find
this anywhere in the driver, the only write to AR5K_DCU_GBL_IFS_SLOT is in
initvals.c - it seems it's not implemented yet.

After some more digging I found that the function ath5k_hw_clocktoh is wrong,
there are more possible clock rates than 40 and 80, this is in FreeBSD
driver:
/* 11a Turbo 11b 11g 108g */
static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };

Now the values in initvals.c finally make sense:

a/XR aTurbo b g (DYN) gTurbo
hex 0x168 0x1e0 0x1b8 0x18c 0x1e0
clocks 360 480 440 396 480
usec 9 6 20 9 6

Unfortunately I still don't know how to calculate the ACK timeout for
different slot time than 9. The formula in athctrl is
2 * slot_time + 3
and I don't know where the '3' comes from. Any ideas?

Lukas Turek


Attachments:
(No filename) (1.16 kB)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-06 18:45:47

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On 6.12.2009 19:01 Johannes Berg wrote:
> This patch assumes that all hardware supports this, which is not really
> what you want. You'll want to know if it can't be set. Yes, we assume
> rts/cts can be set always, but that's a _much_ safer bet.
If the hardware does not support it, the operation will fail with EOPNOTSUPP:

# iw phy0 set coverage 1
command failed: Operation not supported (-95)

Or is there a better solution?

Lukas Turek


Attachments:
(No filename) (441.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-06 19:00:21

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 6.12.2009 19:34 Felix Fietkau wrote:
> This part is wrong. The slot time can be either short or long, based on
> configuration and PHY type.
I did some test, and the value returned by ath5k_hw_get_slot_time was always
9, even when connected to 802.11b-only AP. I didn't try the turbo mode,
though. Unfortunately I don't know how to calculate ACK timeouts for
a different slot time - the formula I used is the only one in both Madwifi's
and FreeBSD's athctrl.

Also the calculation of initial slot time is not expained anywhere, there are
only some magic values in initvals.c.

Lukas Turek


Attachments:
(No filename) (596.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-09 01:16:06

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 7.12.2009 10:48 you wrote:
> ACKTimeout is: aSIFSTime + aSlotTime + aPHY-RX-START-Delay
802.11a uses SIFS of 16 µs and 9 µs slot time, that's 25 µs in total. However,
the athctrl calculation uses 21 µs ACK timeout for zero distance. And I know
the result is correct, as we are using it on 70 links with distances varying
between 100m and 8km.

I don't say the standard is wrong, just that the hardware might start counting
at a different moment than the standard assumes.

> Of course, the distance settting code in iw probably also needs
> changing, as it needs to accomodate for aAirPropagationTime being the
> round trip time, not one-way.
Well, according to my interpretation the aAirPropagationTime is the one-way
delay. I think it makes sense when we consider the reason the slots are used
in CSMA/CA:

Station waits a random number of slots. If no other station was transmitting
at the beginning of a previous slot, the station starts its own transmit. So
the slot time has to be at least the time needed to switch the radio from RX
to TX plus the one-way propagation delay, so that every other station can
hear the medium is busy on time.


Anyway, I think there's only one sure way to determine the correct base ACK
timeout for different modes: experiment. It's easy to detect that the ACK
timeout is too low - packetloss grows dramatically.

The main observation is this: ACK timeout does not depend on slot time!
In retrospect it makes sense: station waits only SIFS before sending ACK, not
a single slot.

The measured values of minimum slot times (with AR5212 and AR5414) are these:

802.11a: 21 µs
802.11b: 27 µs
802.11g: 19 µs

I can't give much explanation, the difference of 6 µs between 11a and 11b
might be the difference of SIFS (16µs vs. 10µs). 11g uses 10 µs SIFS too, but
with additional 6 µs "signal extension", maybe that's why the value is closer
to 11a than 11b. It's all just guessing, though.

So I propose to use 21 µs in 802.11a mode and 27 µs in 802.11b/g mode (as
there might be some 802.11b clients and 6µs won't make much difference).
What do you think?

Lukas Turek


Attachments:
(No filename) (2.09 kB)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-07 11:04:53

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/4] mac80211: Add new callback set_coverage

On Mon, 2009-12-07 at 12:59 +0200, Kalle Valo wrote:
> Lukáš Turek <[email protected]> writes:
>
> > Mac80211 callback to driver set_coverage() sets slot time and ACK timeout
> > for given coverage class. The callback is optional, but it's essential for
> > long distance links.
>
> [...]
>
> > + * @set_coverage: Set slot time for given coverage class as specified
> > + * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout
> > + * accordingly. Optional function, could be NULL.
> > + *

Also, should be %NULL for kernel-doc :)

johannes


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

2009-12-07 06:57:05

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On Sun, 2009-12-06 at 22:59 +0100, Lukáš Turek wrote:
> On 6.12.2009 19:49 Johannes Berg wrote:
> > Umm, no it won't, that's only with your specific mac80211
> > implementation. Try on rndis for instance.
> So I looked at both drivers that define set_wiphy_params: rndis and
> iwmc3200wifi. Both ignore WIPHY_PARAM_RETRY_SHORT and WIPHY_PARAM_RETRY_LONG,
> so WIPHY_PARAM_COVERAGE_CLASS is just another parameter they would ignore.
>
> Anyway, I don't mind adding set_coverage_class to cfg80211_ops if you think
> it's the best solution. It won't change the netlink API.

Maybe we can just keep it the way you did it, and add capability flags
for all of it (retry too) eventually.

johannes


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

2009-12-07 10:59:19

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/4] mac80211: Add new callback set_coverage

Luk?? Turek <[email protected]> writes:

> Mac80211 callback to driver set_coverage() sets slot time and ACK timeout
> for given coverage class. The callback is optional, but it's essential for
> long distance links.

[...]

> + * @set_coverage: Set slot time for given coverage class as specified
> + * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout
> + * accordingly. Optional function, could be NULL.
> + *

Please document if the callback can sleep or not. Preferably the
former.

--
Kalle Valo

2009-12-09 23:51:19

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 9.12.2009 14:30 you wrote:
> That's definitely completely inaccurate. Even before you get packet
> loss, as you lower the ACK timeout value, you will first start to get an
> increase in the number of retransmissions.
In fact the ping was "ping -s 1472 -c 1000 -i 0.002", that's more than
12Mbit/s pushed into the link. Sorry, I shouldn't call it "ordinary ping".
I didn't say it was perfect, but it couldn't have been completely inaccurate,
because I found the athctrl value for 11a mode and Madwifi value for 11g mode
that way.

> Yes, the current formula in Madwifi looks correct. We should use that.
OK, I will prepare a revised patch series. However I need to fix the usec to
clock conversion in Ath5k before (currently it's correct for 802.11a only).

Lukas Turek


Attachments:
(No filename) (776.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-09 01:48:13

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 2009-12-09 2:15 AM, Luk?? Turek wrote:
> On 7.12.2009 10:48 you wrote:
>> ACKTimeout is: aSIFSTime + aSlotTime + aPHY-RX-START-Delay
> 802.11a uses SIFS of 16 ?s and 9 ?s slot time, that's 25 ?s in total. However,
> the athctrl calculation uses 21 ?s ACK timeout for zero distance. And I know
> the result is correct, as we are using it on 70 links with distances varying
> between 100m and 8km.
>
> I don't say the standard is wrong, just that the hardware might start counting
> at a different moment than the standard assumes.
>
>> Of course, the distance settting code in iw probably also needs
>> changing, as it needs to accomodate for aAirPropagationTime being the
>> round trip time, not one-way.
> Well, according to my interpretation the aAirPropagationTime is the one-way
> delay. I think it makes sense when we consider the reason the slots are used
> in CSMA/CA:
>
> Station waits a random number of slots. If no other station was transmitting
> at the beginning of a previous slot, the station starts its own transmit. So
> the slot time has to be at least the time needed to switch the radio from RX
> to TX plus the one-way propagation delay, so that every other station can
> hear the medium is busy on time.
The document also mentions this about the definition of aAirPropagationTime:

Twice the propagation time (in microseconds) for a signal to cross the
maximum distance between the most distant allowable STAs that are slot
synchronized.
If it was only one-way instead of round trip, the ACKTimeout formula
would not make sense, as it would only take one way into account,
however both the data frame and the ack frame need time to reach their
destination.

> Anyway, I think there's only one sure way to determine the correct base ACK
> timeout for different modes: experiment. It's easy to detect that the ACK
> timeout is too low - packetloss grows dramatically.
>
> The main observation is this: ACK timeout does not depend on slot time!
> In retrospect it makes sense: station waits only SIFS before sending ACK, not
> a single slot.
Some hardware internally calculates the ACK timeout based on the
configured slot time. Broadcom does it this way.
Maybe adjusting the ACK timeout without adjusting the slot time works,
but it'll probably interfere with CSMA.

> The measured values of minimum slot times (with AR5212 and AR5414) are these:
>
> 802.11a: 21 ?s
> 802.11b: 27 ?s
> 802.11g: 19 ?s
How did you measure it?

> I can't give much explanation, the difference of 6 ?s between 11a and 11b
> might be the difference of SIFS (16?s vs. 10?s). 11g uses 10 ?s SIFS too, but
> with additional 6 ?s "signal extension", maybe that's why the value is closer
> to 11a than 11b. It's all just guessing, though.
>
> So I propose to use 21 ?s in 802.11a mode and 27 ?s in 802.11b/g mode (as
> there might be some 802.11b clients and 6?s won't make much difference).
> What do you think?
I'm guessing that most hardware does have some degree of tolerance for
timing variation. IMHO, if the standard recommends slightly higher but
working values for the same distance, we should use that rather than
experimentally determined limits.

- Felix

2009-12-06 21:49:35

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH] iw: Add support for NL80211_ATTR_WIPHY_COVERAGE_CLASS

On Sun, Dec 6, 2009 at 9:29 AM, Lukáš Turek <[email protected]> wrote:
> New nl80211 attribute NL80211_ATTR_WIPHY_COVERAGE_CLASS allows setting
> IEEE 802.11 coverage class, which is then used by drivers to calculate
> slot time and ACK timeout for long distance links.
>
> Two iw parameters are added: 'coverage' sets the coverage class
> directly, while 'distance' is more user-friendly, as it allows to set
> just the link distance and let iw do the necessary calculation itself.
>
> Signed-off-by: Lukas Turek <[email protected]>
> ---
>  info.c    |    7 +++++++
>  nl80211.h |   15 +++++++++++++++
>  phy.c     |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 80 insertions(+), 0 deletions(-)
>
> diff --git a/info.c b/info.c
> index ddff78b..3c69afc 100644
> --- a/info.c
> +++ b/info.c
> @@ -264,6 +264,13 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
>                        printf("\tRTS threshold: %d\n", rts);
>        }
>
> +       if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
> +               unsigned int coverage;

Just some quick comments.

u8 seems more appropriate, given that you define this a u8 anyway.

> +
> +               coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
> +               printf("\tCoverage class: %d (up to %dm)\n", coverage, 900 * coverage);

printf ?

Luis

2009-12-09 13:12:45

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath5k: Implement mac80211 callback set_coverage

On 9.12.2009 02:48 Felix Fietkau wrote:
> Twice the propagation time (in microseconds) for a signal to cross the
> maximum distance between the most distant allowable STAs that are slot
> synchronized.
Oh, I missed that... And maybe I'm starting to understand it: the slots are in
fact some kind of clock synchronization, recipient gets synchronized with a
one-way delay, and then when there's a transmit in the other direction,
another one-way delay is added to the "clock".

Unfortunately using this calculation makes us incompatible with FreeBSD and
madwifi-ng, however it seems current Madwifi uses the standard calculation:
http://madwifi-project.org/changeset/3977/madwifi/branches/madwifi-hal-0.10.5.6/ath/if_ath.c?format=diff&new=3977

And now I'm quite sure the athctrl calculation is completely wrong.
Even if it produces correct results :o)

> Some hardware internally calculates the ACK timeout based on the
> configured slot time. Broadcom does it this way.
> Maybe adjusting the ACK timeout without adjusting the slot time works,
> but it'll probably interfere with CSMA.
Ahteros is not Broadcom, it does not have a firmware, I'm writing the ACK
timeout directly into a register of the MAC chip. But you're suggesting what
I said in previus mail: we have to understand what the hardware does. And as
there is no documentation, the only way is experiment. Most of ath5k was
developed this way.

> > 802.11a: 21 ?s
> > 802.11b: 27 ?s
> > 802.11g: 19 ?s
>
> How did you measure it?
Just by gradually lowering the value in ACK timeout register (it's accessible
via sysctl in FreeBSD) and testing the link using ordinary ping. When the ACK
timeout was too low, packetloss grew from 0% to 50% or so.

> I'm guessing that most hardware does have some degree of tolerance for
> timing variation. IMHO, if the standard recommends slightly higher but
> working values for the same distance, we should use that rather than
> experimentally determined limits.
The problem is, it's not slightly higher, it's twice or more higher:
aSIFSTime + aSlotTime + aPHY-RX-START-Delay is 50 in 802.11a mode, while the
default ACK timeout for 802.11a used in ath5k initialisation is 25. And in
802.11b the aPHY-RX-START-Delay alone is defined as 192 ?s, while the default
used by ath5k is 48.

I looked into the current Madwifi sources again, and found they use only
aSIFSTime + aSlotTime as ACK timeout. That's 25 for 11a, 30 for 11b and 19 for
11g, so it's in line with my experimental observations and also the 11a ath5k
default. Probably the hardware accounts for aPHY-RX-START-Delay itself (it's
PHY value, while ACK timeout is MAC chip register).

So, what do you think about using the formula from Madwifi?

Lukas Turek


Attachments:
(No filename) (2.67 kB)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments

2009-12-06 19:28:46

by Lukáš Turek

[permalink] [raw]
Subject: Re: [PATCH 1/4] nl80211: Add new WIPHY attribute COVERAGE_CLASS

On 6.12.2009 19:49 Johannes Berg wrote:
> Umm, no it won't, that's only with your specific mac80211
> implementation. Try on rndis for instance.
I looked at the rndis driver, but it seems it could be configured via wireless
extensions only, it does not define cfg80211_ops at all, so I think it cannot
be managed via nl80211 and I don't see your point there...

Lukas Turek


Attachments:
(No filename) (376.00 B)
signature.asc (836.00 B)
This is a digitally signed message part.
Download all attachments