2008-07-30 06:16:17

by YanBo

[permalink] [raw]
Subject: [RFC PATCH] ath5k:mesh support (enable send beacon)

This patch enable Ath5k send mesh beacon and found each other, I tested it
between two Atheros cards AR5414/AR5413 and AR2413, it seemed they can send
beacon correctly and ping each other. The kernel I used is pulled from
wireless-testing tree. The HEAD is
a520bdbe7d344296482f9355e29b0018ea58760f (iwl-scan.c: fixup merge
damage in wireless-testing#master)

But in order to make the mesh works, below three patches need to be apply first
1. [ath5k-devel] [PATCH] ath5k: add Mesh Point support
http://marc.info/?l=linux-wireless&m=121632572409109&w=2
2. [ath5k-devel] [PATCH 1/3] Ath5k: fix beacon-update deadlock
http://marc.info/?l=linux-wireless&m=121681221413848&w=2
3. [PATCH] mac80211: fix mesh beaconing
http://marc.info/?l=linux-wireless&m=121735468220792&w=2

Something need to be notice:
1: In ath5k ADHOC mode the TSF will be dynamic adjusted, but in Mesh
mode, it is not be
done. In my opinion the mesh node need adjust TSF too (CMIIW).
2: The default beacon intval is 1000ms, we can change it in base.c
ath5k_config_interface() . ( or there is any command or tools can be
used to do this, I don't know :) )
3: After input "iw dev mesh station dump" it will trigger a lock
problem(attach is the warning info).
4: In my test after send 7 ping packets, the kernel will crash for
some reason. (After I get a serial console line, will report more
detail of it or send a patch if I can figure them out)


Signed-off-by: Li YanBo <[email protected]>

drivers/net/wireless/ath5k/base.c | 31 +++++++++++++++++++++----------
1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c
b/drivers/net/wireless/ath5k/base.c
index 16c19ce..a56a4d5 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1810,7 +1810,8 @@ accept:
ath5k_debug_dump_skb(sc, skb, "RX ", 0);

/* check beacons in IBSS mode */
- if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
+ if (sc->opmode == IEEE80211_IF_TYPE_IBSS ||
+ sc->opmode == IEEE80211_IF_TYPE_MESH_POINT)
ath5k_check_ibss_tsf(sc, skb, &rxs);

__ieee80211_rx(sc->hw, skb, &rxs);
@@ -1927,7 +1928,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc,
struct ath5k_buf *bf)
ds = bf->desc;

flags = AR5K_TXDESC_NOACK;
- if (sc->opmode == IEEE80211_IF_TYPE_IBSS && ath5k_hw_hasveol(ah)) {
+ if ((sc->opmode == IEEE80211_IF_TYPE_IBSS ||
+ sc->opmode == IEEE80211_IF_TYPE_MESH_POINT) &&
+ ath5k_hw_hasveol(ah)) {
ds->ds_link = bf->daddr; /* self-linked */
flags |= AR5K_TXDESC_VEOL;
/*
@@ -2154,7 +2157,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)

if (sc->opmode == IEEE80211_IF_TYPE_STA) {
sc->imask |= AR5K_INT_BMISS;
- } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
+ } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS ||
+ sc->opmode == IEEE80211_IF_TYPE_MESH_POINT) {
/*
* In IBSS mode we use a self-linked tx descriptor and let the
* hardware send the beacons automatically. We have to load it
@@ -2163,11 +2167,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)
* timers in order to detect automatic TSF updates.
*/
ath5k_beaconq_config(sc);
-
- sc->imask |= AR5K_INT_SWBA;
+ if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
+ sc->imask |= AR5K_INT_SWBA;

if (ath5k_hw_hasveol(ah))
ath5k_beacon_send(sc);
+
+ /* set the beacon timer */
+ if (sc->opmode == IEEE80211_IF_TYPE_MESH_POINT)
+ ath5k_beacon_update_timers(sc, 0);
}
/* TODO else AP */

@@ -2720,6 +2728,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
case IEEE80211_IF_TYPE_STA:
case IEEE80211_IF_TYPE_IBSS:
case IEEE80211_IF_TYPE_MNTR:
+ case IEEE80211_IF_TYPE_MESH_POINT:
sc->opmode = conf->type;
break;
default:
@@ -2787,7 +2796,7 @@ ath5k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
}

if (conf->changed & IEEE80211_IFCC_BEACON &&
- vif->type == IEEE80211_IF_TYPE_IBSS) {
+ (vif->type == IEEE80211_IF_TYPE_IBSS || ieee80211_vif_is_mesh(vif))) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
if (!beacon) {
ret = -ENOMEM;
@@ -2916,7 +2925,8 @@ static void ath5k_configure_filter(struct
ieee80211_hw *hw,
test_bit(ATH_STAT_PROMISC, sc->status))
rfilt |= AR5K_RX_FILTER_PROM;
if (sc->opmode == IEEE80211_IF_TYPE_STA ||
- sc->opmode == IEEE80211_IF_TYPE_IBSS) {
+ sc->opmode == IEEE80211_IF_TYPE_IBSS ||
+ sc->opmode == IEEE80211_IF_TYPE_MESH_POINT) {
rfilt |= AR5K_RX_FILTER_BEACON;
}

@@ -3020,7 +3030,8 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
* in IBSS mode we need to update the beacon timers too.
* this will also reset the TSF if we call it with 0
*/
- if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
+ if (sc->opmode == IEEE80211_IF_TYPE_IBSS ||
+ sc->opmode == IEEE80211_IF_TYPE_MESH_POINT)
ath5k_beacon_update_timers(sc, 0);
else
ath5k_hw_reset_tsf(sc->ah);
@@ -3034,8 +3045,8 @@ ath5k_beacon_update(struct ieee80211_hw *hw,
struct sk_buff *skb)

ath5k_debug_dump_skb(sc, skb, "BC ", 1);

-
- if (sc->opmode != IEEE80211_IF_TYPE_IBSS) {
+ if (sc->opmode != IEEE80211_IF_TYPE_IBSS &&
+ sc->opmode != IEEE80211_IF_TYPE_MESH_POINT) {
ret = -EIO;
goto end;
}


Attachments:
(No filename) (5.05 kB)
iw-trigger-lock-info.txt (8.18 kB)
Download all attachments