* [PATCH] airo: Reorder tests, check bounds before element
From: Roel Kluin @ 2009-10-26 14:28 UTC (permalink / raw)
To: John W. Linville, linux-wireless, Andrew Morton, LKML
Test whether index is within bounds before reading the element
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
drivers/net/wireless/airo.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 7116a1a..abf896a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4790,9 +4790,8 @@ static int proc_stats_rid_open( struct inode *inode,
static int get_dec_u16( char *buffer, int *start, int limit ) {
u16 value;
int valid = 0;
- for( value = 0; buffer[*start] >= '0' &&
- buffer[*start] <= '9' &&
- *start < limit; (*start)++ ) {
+ for (value = 0; *start < limit && buffer[*start] >= '0' &&
+ buffer[*start] <= '9'; (*start)++) {
valid = 1;
value *= 10;
value += buffer[*start] - '0';
^ permalink raw reply related
* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
From: Luis R. Rodriguez @ 2009-10-26 14:19 UTC (permalink / raw)
To: linux-wireless, Sujith; +Cc: ath9k-devel, Luis R. Rodriguez
In-Reply-To: <43e72e890910212042i6a6a1bc3h1cd2a742f462353f@mail.gmail.com>
On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> This series started off to extend support for ar9271 on ath9k_hw
>> but after review of the phy related code I noticed a fix for
>> AR5416 was only partially being implemented and used for all
>> chipsets. This series then adds the changes I've noticed so far
>> required for ar9271 but also fixes and completes the orientation
>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
>> documentation for it.
>>
>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
>> card -- I'd appreciate it if someone can give this a test on AR9285
Alright well I made it back to California and tested an AR9285 and
things are peachy so I will submit this now.
Luis
^ permalink raw reply
* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
From: Luis R. Rodriguez @ 2009-10-26 14:23 UTC (permalink / raw)
To: linux-wireless, Sujith, John W. Linville; +Cc: ath9k-devel, Luis R. Rodriguez
In-Reply-To: <43e72e890910260719j508670a8p87bb7a5cf31d843d@mail.gmail.com>
On Mon, Oct 26, 2009 at 7:19 AM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
>> <lrodriguez@atheros.com> wrote:
>>> This series started off to extend support for ar9271 on ath9k_hw
>>> but after review of the phy related code I noticed a fix for
>>> AR5416 was only partially being implemented and used for all
>>> chipsets. This series then adds the changes I've noticed so far
>>> required for ar9271 but also fixes and completes the orientation
>>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
>>> documentation for it.
>>>
>>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
>>> card -- I'd appreciate it if someone can give this a test on AR9285
>
> Alright well I made it back to California and tested an AR9285 and
> things are peachy so I will submit this now.
Johh, actually instead of resubmitting can you take these in as-is?
They should apply on top of the latest tree. Please let me know.
Luis
^ permalink raw reply
* Re: RECAP: indication of channel noise
From: Holger Schurig @ 2009-10-26 14:30 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Felix Fietkau
In-Reply-To: <1256565132.12462.9.camel@johannes.local>
> > NL80211_BSS_NOISE_MBM
Hmm, this could better be NL80211_CHANNEL_NOISE_MBM, to make
clear that this is not heat-related internal noise of the chip.
For the rest of your remarks: ok
--
M&N Solutions GmbH Ein Unternehmen der Datagroup AG
Holger Schurig
Raiffeisenstr. 10
61191 Rosbach
Tel: 06003/9141-15 Fax 06003/9141-49
http://www.mn-solutions.de/
Handelsregister Friedberg, HRB 5903
Geschäftsführer: P.Schrittenlocher
^ permalink raw reply
* [PATCH 4/4] ath9k_hw: add some debug print for hw initialization
From: Luis R. Rodriguez @ 2009-10-26 14:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1256567941-26859-1-git-send-email-lrodriguez@atheros.com>
This helps debugging hw bring up.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/calib.c | 3 +++
drivers/net/wireless/ath/ath9k/hw.c | 8 ++++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 551f880..07b7618 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -1084,6 +1084,9 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
+ ath_print(common, ATH_DBG_CALIBRATE, "Running carrier leakage "
+ "calibration fix\n");
+
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
if (IS_CHAN_HT20(chan)) {
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 50be381..04b6afc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1005,8 +1005,11 @@ int ath9k_hw_init(struct ath_hw *ah)
static void ath9k_hw_init_bb(struct ath_hw *ah,
struct ath9k_channel *chan)
{
+ struct ath_common *common = ath9k_hw_common(ah);
u32 synthDelay;
+ ath_print(common, ATH_DBG_RESET, "initializing baseband\n");
+
synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(chan))
synthDelay = (4 * synthDelay) / 22;
@@ -1591,6 +1594,8 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
{
u32 regval;
+ ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "Configuring DMA read/write settings\n");
/*
* set AHB_MODE not to do cacheline prefetches
*/
@@ -2145,6 +2150,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
/*
* For big endian systems turn on swapping for descriptors
*/
+ ath_print(common, ATH_DBG_RESET,
+ "Configuring byte swap settings\n");
+
if (AR_SREV_9100(ah)) {
u32 mask;
mask = REG_READ(ah, AR_CFG);
--
1.6.0.4
^ permalink raw reply related
* [PATCH 0/4] ath9k_hw: modify hw identification message
From: Luis R. Rodriguez @ 2009-10-26 14:38 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
While reviewing ar9271 radio revisions I determined the radio revision
does not apply although it can be populated in the EEPROM. This changes
the hw probe print to reflect this for single chips and throws the code
into hw code to be shared with ath9k_htc.
Luis R. Rodriguez (4):
ath9k_hw: move mac name and rf name helpers to hw code
ath9k_hw: distinguish single-chip solutions on initial probe print
ath9k_hw: add AR9271 single chip name mapping
ath9k_hw: add some debug print for hw initialization
drivers/net/wireless/ath/ath9k/ahb.c | 10 ++--
drivers/net/wireless/ath/ath9k/calib.c | 3 +
drivers/net/wireless/ath/ath9k/hw.c | 90 ++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 2 +
drivers/net/wireless/ath/ath9k/main.c | 58 --------------------
drivers/net/wireless/ath/ath9k/pci.c | 10 ++--
6 files changed, 103 insertions(+), 70 deletions(-)
^ permalink raw reply
* [PATCH 2/4] ath9k_hw: distinguish single-chip solutions on initial probe print
From: Luis R. Rodriguez @ 2009-10-26 14:38 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1256567941-26859-1-git-send-email-lrodriguez@atheros.com>
Devices with external radios have revisions which we can count on.
On single chip solutions these EEPROM values for these radio revision
also exist but are not meaningful as the radios are embedded onto the
same chip. Each single-chip device evolves together as one device.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/ahb.c | 11 ++++-------
drivers/net/wireless/ath/ath9k/hw.c | 27 +++++++++++++++++++++++----
drivers/net/wireless/ath/ath9k/hw.h | 3 +--
drivers/net/wireless/ath/ath9k/pci.c | 11 ++++-------
4 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 41422c4..925818c 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -69,6 +69,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
int irq;
int ret = 0;
struct ath_hw *ah;
+ char hw_name[1024];
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "no platform data specified\n");
@@ -133,15 +134,11 @@ static int ath_ahb_probe(struct platform_device *pdev)
}
ah = sc->sc_ah;
+ ath9k_hw_name(ah, hw_name);
printk(KERN_INFO
- "%s: Atheros AR%s MAC/BB Rev:%x, "
- "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+ "%s: %s mem=0x%lx, irq=%d\n",
wiphy_name(hw->wiphy),
- ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
- ah->hw_version.macRev,
- ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
- AR_RADIO_SREV_MAJOR)),
- ah->hw_version.phyRev,
+ hw_name,
(unsigned long)mem, irq);
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cf543e3..f65b591 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3959,7 +3959,7 @@ static struct {
/*
* Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
*/
-const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
+static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
{
int i;
@@ -3971,13 +3971,12 @@ const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
return "????";
}
-EXPORT_SYMBOL(ath9k_hw_mac_bb_name);
/*
* Return the RF name. "????" is returned if the RF is unknown.
* Used for devices with external radios.
*/
-const char *ath9k_hw_rf_name(u16 rf_version)
+static const char *ath9k_hw_rf_name(u16 rf_version)
{
int i;
@@ -3989,4 +3988,24 @@ const char *ath9k_hw_rf_name(u16 rf_version)
return "????";
}
-EXPORT_SYMBOL(ath9k_hw_rf_name);
+
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name)
+{
+ /* chipsets >= AR9280 are single-chip */
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ sprintf(hw_name,
+ "Atheros single-chip AR%s Rev:%x",
+ ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev);
+ }
+ else {
+ sprintf(hw_name,
+ "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x: ",
+ ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev,
+ ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
+ AR_RADIO_SREV_MAJOR)),
+ ah->hw_version.phyRev);
+ }
+}
+EXPORT_SYMBOL(ath9k_hw_name);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 100fcba..3ceb4c6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -720,8 +720,7 @@ void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_isr(struct ath_hw *hw);
u32 ath9k_hw_gettsf32(struct ath_hw *ah);
-const char *ath9k_hw_mac_bb_name(u32 mac_bb_version);
-const char *ath9k_hw_rf_name(u16 rf_version);
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name);
#define ATH_PCIE_CAP_LINK_CTRL 0x70
#define ATH_PCIE_CAP_LINK_L0S 1
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 76f3890..963d6fe 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -114,6 +114,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
u32 val;
int ret = 0;
struct ath_hw *ah;
+ char hw_name[1024];
if (pci_enable_device(pdev))
return -EIO;
@@ -218,15 +219,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sc->irq = pdev->irq;
ah = sc->sc_ah;
+ ath9k_hw_name(ah, hw_name);
printk(KERN_INFO
- "%s: Atheros AR%s MAC/BB Rev:%x "
- "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+ "%s: %s mem=0x%lx, irq=%d\n",
wiphy_name(hw->wiphy),
- ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
- ah->hw_version.macRev,
- ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
- AR_RADIO_SREV_MAJOR)),
- ah->hw_version.phyRev,
+ hw_name,
(unsigned long)mem, pdev->irq);
return 0;
--
1.6.0.4
^ permalink raw reply related
* [PATCH 3/4] ath9k_hw: add AR9271 single chip name mapping
From: Luis R. Rodriguez @ 2009-10-26 14:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1256567941-26859-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/hw.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f65b591..50be381 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3941,7 +3941,8 @@ static struct {
/* Single-chip solutions */
{ AR_SREV_VERSION_9280, "9280" },
{ AR_SREV_VERSION_9285, "9285" },
- { AR_SREV_VERSION_9287, "9287" }
+ { AR_SREV_VERSION_9287, "9287" },
+ { AR_SREV_VERSION_9271, "9271" },
};
/* For devices with external radios */
--
1.6.0.4
^ permalink raw reply related
* [PATCH 1/4] ath9k_hw: move mac name and rf name helpers to hw code
From: Luis R. Rodriguez @ 2009-10-26 14:38 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1256567941-26859-1-git-send-email-lrodriguez@atheros.com>
These are shared between ath9k and the future ath9k_htc driver.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/ahb.c | 5 ++-
drivers/net/wireless/ath/ath9k/hw.c | 62 +++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 3 ++
drivers/net/wireless/ath/ath9k/main.c | 58 ------------------------------
drivers/net/wireless/ath/ath9k/pci.c | 5 ++-
5 files changed, 71 insertions(+), 62 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 25531f2..41422c4 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -137,9 +137,10 @@ static int ath_ahb_probe(struct platform_device *pdev)
"%s: Atheros AR%s MAC/BB Rev:%x, "
"AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
wiphy_name(hw->wiphy),
- ath_mac_bb_name(ah->hw_version.macVersion),
+ ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
ah->hw_version.macRev,
- ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
+ AR_RADIO_SREV_MAJOR)),
ah->hw_version.phyRev,
(unsigned long)mem, irq);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index db95876..cf543e3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3928,3 +3928,65 @@ void ath_gen_timer_isr(struct ath_hw *ah)
}
}
EXPORT_SYMBOL(ath_gen_timer_isr);
+
+static struct {
+ u32 version;
+ const char * name;
+} ath_mac_bb_names[] = {
+ /* Devices with external radios */
+ { AR_SREV_VERSION_5416_PCI, "5416" },
+ { AR_SREV_VERSION_5416_PCIE, "5418" },
+ { AR_SREV_VERSION_9100, "9100" },
+ { AR_SREV_VERSION_9160, "9160" },
+ /* Single-chip solutions */
+ { AR_SREV_VERSION_9280, "9280" },
+ { AR_SREV_VERSION_9285, "9285" },
+ { AR_SREV_VERSION_9287, "9287" }
+};
+
+/* For devices with external radios */
+static struct {
+ u16 version;
+ const char * name;
+} ath_rf_names[] = {
+ { 0, "5133" },
+ { AR_RAD5133_SREV_MAJOR, "5133" },
+ { AR_RAD5122_SREV_MAJOR, "5122" },
+ { AR_RAD2133_SREV_MAJOR, "2133" },
+ { AR_RAD2122_SREV_MAJOR, "2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
+{
+ int i;
+
+ for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
+ if (ath_mac_bb_names[i].version == mac_bb_version) {
+ return ath_mac_bb_names[i].name;
+ }
+ }
+
+ return "????";
+}
+EXPORT_SYMBOL(ath9k_hw_mac_bb_name);
+
+/*
+ * Return the RF name. "????" is returned if the RF is unknown.
+ * Used for devices with external radios.
+ */
+const char *ath9k_hw_rf_name(u16 rf_version)
+{
+ int i;
+
+ for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
+ if (ath_rf_names[i].version == rf_version) {
+ return ath_rf_names[i].name;
+ }
+ }
+
+ return "????";
+}
+EXPORT_SYMBOL(ath9k_hw_rf_name);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 936ef5b..100fcba 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -720,6 +720,9 @@ void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_isr(struct ath_hw *hw);
u32 ath9k_hw_gettsf32(struct ath_hw *ah);
+const char *ath9k_hw_mac_bb_name(u32 mac_bb_version);
+const char *ath9k_hw_rf_name(u16 rf_version);
+
#define ATH_PCIE_CAP_LINK_CTRL 0x70
#define ATH_PCIE_CAP_LINK_L0S 1
#define ATH_PCIE_CAP_LINK_L1 2
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 69cf702..9fefc51 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -3191,64 +3191,6 @@ struct ieee80211_ops ath9k_ops = {
.rfkill_poll = ath9k_rfkill_poll_state,
};
-static struct {
- u32 version;
- const char * name;
-} ath_mac_bb_names[] = {
- { AR_SREV_VERSION_5416_PCI, "5416" },
- { AR_SREV_VERSION_5416_PCIE, "5418" },
- { AR_SREV_VERSION_9100, "9100" },
- { AR_SREV_VERSION_9160, "9160" },
- { AR_SREV_VERSION_9280, "9280" },
- { AR_SREV_VERSION_9285, "9285" },
- { AR_SREV_VERSION_9287, "9287" }
-};
-
-static struct {
- u16 version;
- const char * name;
-} ath_rf_names[] = {
- { 0, "5133" },
- { AR_RAD5133_SREV_MAJOR, "5133" },
- { AR_RAD5122_SREV_MAJOR, "5122" },
- { AR_RAD2133_SREV_MAJOR, "2133" },
- { AR_RAD2122_SREV_MAJOR, "2122" }
-};
-
-/*
- * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
- */
-const char *
-ath_mac_bb_name(u32 mac_bb_version)
-{
- int i;
-
- for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
- if (ath_mac_bb_names[i].version == mac_bb_version) {
- return ath_mac_bb_names[i].name;
- }
- }
-
- return "????";
-}
-
-/*
- * Return the RF name. "????" is returned if the RF is unknown.
- */
-const char *
-ath_rf_name(u16 rf_version)
-{
- int i;
-
- for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
- if (ath_rf_names[i].version == rf_version) {
- return ath_rf_names[i].name;
- }
- }
-
- return "????";
-}
-
static int __init ath9k_init(void)
{
int error;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 63059b6..76f3890 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -222,9 +222,10 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
"%s: Atheros AR%s MAC/BB Rev:%x "
"AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
wiphy_name(hw->wiphy),
- ath_mac_bb_name(ah->hw_version.macVersion),
+ ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
ah->hw_version.macRev,
- ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
+ AR_RADIO_SREV_MAJOR)),
ah->hw_version.phyRev,
(unsigned long)mem, pdev->irq);
--
1.6.0.4
^ permalink raw reply related
* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
From: John W. Linville @ 2009-10-26 14:41 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, Sujith, ath9k-devel
In-Reply-To: <43e72e890910260723o58ad4635g4f6bebfa28f673bb@mail.gmail.com>
On Mon, Oct 26, 2009 at 07:23:44AM -0700, Luis R. Rodriguez wrote:
> On Mon, Oct 26, 2009 at 7:19 AM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
> > On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
> > <lrodriguez@atheros.com> wrote:
> >> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
> >> <lrodriguez@atheros.com> wrote:
> >>> This series started off to extend support for ar9271 on ath9k_hw
> >>> but after review of the phy related code I noticed a fix for
> >>> AR5416 was only partially being implemented and used for all
> >>> chipsets. This series then adds the changes I've noticed so far
> >>> required for ar9271 but also fixes and completes the orientation
> >>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
> >>> documentation for it.
> >>>
> >>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
> >>> card -- I'd appreciate it if someone can give this a test on AR9285
> >
> > Alright well I made it back to California and tested an AR9285 and
> > things are peachy so I will submit this now.
>
> Johh, actually instead of resubmitting can you take these in as-is?
> They should apply on top of the latest tree. Please let me know.
I'm a little buried ATM, but sure -- that'll be fine...
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: Only device wlan1 but no connection Fritz!WLAN USB stick N2.4
From: Luis R. Rodriguez @ 2009-10-26 14:57 UTC (permalink / raw)
To: Ed Vaessen; +Cc: linux-wireless
In-Reply-To: <e14196febc59d9ca25868fec63816139.squirrel@webmail.xs4all.nl>
On Mon, Oct 26, 2009 at 6:17 AM, Ed Vaessen <evaessen@xs4all.nl> wrote:
> I have a Fritz!Box Fon WLAN 7170 as router and try to connect wireless to
> it with the Fritz!WLAN USB N2.4 stick using the compat-wireless software.
> Without succes so far.
> Oct 25 15:38:38 vaessen-laptop kernel: [ 399.349605] usb 1-1: USB
> disconnect, address 5
> Oct 25 15:38:39 vaessen-laptop kernel: [ 400.608057] usb 1-1: new high
> speed USB device using ehci_hcd and address 6
> Oct 25 15:38:39 vaessen-laptop kernel: [ 400.771795] usb 1-1:
> configuration #1 chosen from 1 choice
> Oct 25 15:38:39 vaessen-laptop kernel: [ 400.888063] usb 1-1: reset high
> speed USB device using ehci_hcd and address 6
> Oct 25 15:38:40 vaessen-laptop kernel: [ 402.044043] usb 1-1: firmware:
> requesting ar9170.fw
> Oct 25 15:38:41 vaessen-laptop kernel: [ 402.465806] Registered led
> device: ar9170-phy1::tx
> Oct 25 15:38:41 vaessen-laptop kernel: [ 402.465846] Registered led
> device: ar9170-phy1::assoc
> Oct 25 15:38:41 vaessen-laptop kernel: [ 402.465851] usb 1-1: Atheros
> AR9170 is registered as 'phy1'
> Oct 25 15:38:41 vaessen-laptop kernel: [ 402.471136] udev: renamed network
> interface wlan0 to wlan1
>
> It seems the firmware is installed.
> Command iwconfig:
>
> lo no wireless extensions.
>
> eth0 no wireless extensions.
>
> pan0 no wireless extensions.
>
> wlan1 IEEE 802.11bg Mode:Managed Access Point: Not-Associated
> Tx-Power=0 dBm
> Retry long limit:7 RTS thrff Fragment thrff
> Power Managementff
>
> Command sudo lshw -C network gives for the wireless this information:
>
> *-network:1 DISABLED
> description: Wireless interface
> physical id: 2
> bus info: usb@1:1
> logical name: wlan1
> serial: 00:1f:3f:09:2d:40
> capabilities: ethernet physical wireless
> configuration: broadcast=yes driver=ar9170usb
> driverversion=2.6.28-16-generic firmware=N/A link=yes multicast=yes
> wireless=IEEE 802.11bg
>
> This 'firmware=N/A' puzzles me.
That's probably from ethtool, and since John added ethtool support all
we would need to do I think is tag the firmware name on the wiphy
struct (wiphy->fw_version). But we haven't added that yet to ar9170.
> I used System->Administration->Network Tools but cannot ping the Fritz!Box
> router
> The interface information says that wireless interface wlan1 is inactive.
>
> How do I make it active?
Bring the interface up first:
ip link set dev wlan1 up
Then use iw to scan for example
Luis
^ permalink raw reply
* rtl8187: kernel oops when leds enabled
From: Richard Farina @ 2009-10-26 15:17 UTC (permalink / raw)
To: linux-wireless
Using kernel 2.6.31 and compat-wireless stable 2.6.32_rc5 I get this
kernel oops nearly 100% of the time when I unplug the device. I have
tried with the device down, up, and while transmitting, here are the
three oopses. Sorry it took me so long for this report, it is an odd
bug. When I was running older kernel/compat-wireless this oops was
about 4-5 screens longs so I couldn't take a picture. Additionally I
took the advice of a few of the list members to try the crashkernel
feature (which is AWESOME btw) but it doesn't work for this oops. Let
me be more specific, I can trigger an oops and the crash kernel kicks
in, but with this oops the crash kernel never kicks in so I am guessing
this is bad news.
I'm honestly a little surprised that no one has bothered to reproduce
this in the month since I reported it but maybe it is more unique to my
setup than it seems.
Hope these pictures are readable enough to be useful.
http://picpaste.com/pics/cimg1470.1256404028.jpg
http://picpaste.com/pics/cimg1474.1256404126.jpg
http://picpaste.com/pics/cimg1477.1256404170.jpg
I can fairly well generate this error at will and I'm available to test
reproducing the bug in any possible situation which is suggested and/or
test patches to fix.
Thanks,
Rick
^ permalink raw reply
* [PATCH] libertas: introduce mesh.h
From: Holger Schurig @ 2009-10-26 15:21 UTC (permalink / raw)
To: linux-wireless, Dan Williams, John Linville
Concentrating mesh related code into one file will allow a less
intrusive CONFIG_LIBERTAS_MESH.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
---
Dan, John: this is on top of the patch series with the 19 patches
that isolate the WEXT stuff. So please review and ACK/NACK that
first.
Some day later we'll do "git mv persistcfg.c mesh.c"
This will give us the possiblity to easier make a Kconfig entry
for MESH ...
or to rip it out, should there be no user for it.
--- linux-wl.orig/drivers/net/wireless/libertas/dev.h
+++ linux-wl/drivers/net/wireless/libertas/dev.h
@@ -6,6 +6,7 @@
#ifndef _LBS_DEV_H_
#define _LBS_DEV_H_
+#include "mesh.h"
#include "scan.h"
#include "assoc.h"
@@ -21,17 +22,6 @@
uint16_t sp_reserved;
};
-/* Mesh statistics */
-struct lbs_mesh_stats {
- u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
- u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
- u32 fwd_drop_ttl; /* Fwd: TTL zero */
- u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
- u32 fwd_drop_noroute; /* Fwd: No route to Destination */
- u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
- u32 drop_blind; /* Rx: Dropped by blinding table */
- u32 tx_failed_cnt; /* Tx: Failed transmissions */
-};
/** Private structure for the MV device */
struct lbs_private {
--- /dev/null
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -0,0 +1,32 @@
+/**
+ * Contains all definitions needed for the Libertas' MESH
implementation.
+ */
+#ifndef _LBS_MESH_H_
+#define _LBS_MESH_H_
+
+
+#include <net/iw_handler.h>
+
+
+/* Mesh statistics */
+struct lbs_mesh_stats {
+ u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
+ u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
+ u32 fwd_drop_ttl; /* Fwd: TTL zero */
+ u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
+ u32 fwd_drop_noroute; /* Fwd: No route to Destination */
+ u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
+ u32 drop_blind; /* Rx: Dropped by blinding table */
+ u32 tx_failed_cnt; /* Tx: Failed transmissions */
+};
+
+
+struct net_device;
+
+void lbs_persist_config_init(struct net_device *net);
+void lbs_persist_config_remove(struct net_device *net);
+
+extern struct iw_handler_def mesh_handler_def;
+
+
+#endif
--- linux-wl.orig/drivers/net/wireless/libertas/decl.h
+++ linux-wl/drivers/net/wireless/libertas/decl.h
@@ -27,11 +27,6 @@
int lbs_process_rxed_packet(struct lbs_private *priv, struct
sk_buff *);
-/* persistcfg.c */
-void lbs_persist_config_init(struct net_device *net);
-void lbs_persist_config_remove(struct net_device *net);
-
-
/* main.c */
struct lbs_private *lbs_add_card(void *card, struct device
*dmdev);
void lbs_remove_card(struct lbs_private *priv);
--- linux-wl.orig/drivers/net/wireless/libertas/wext.h
+++ linux-wl/drivers/net/wireless/libertas/wext.h
@@ -7,12 +7,11 @@
void lbs_send_disconnect_notification(struct lbs_private *priv);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32
event);
-extern struct iw_handler_def lbs_handler_def;
-extern struct iw_handler_def mesh_handler_def;
-
struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
struct lbs_private *priv,
u8 band,
u16 channel);
+extern struct iw_handler_def lbs_handler_def;
+
#endif
--
http://www.holgerschurig.de
^ permalink raw reply
* [PATCH] libertas: initial move of mesh related functions into persistcfg.c
From: Holger Schurig @ 2009-10-26 15:22 UTC (permalink / raw)
To: linux-wireless, Dan Williams, John Linville
This moves mesh initialization, start/stop and rx/tx handling from
the respective *.c files into persistcfg.c.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
--- linux-wl.orig/drivers/net/wireless/libertas/main.c
+++ linux-wl/drivers/net/wireless/libertas/main.c
@@ -94,107 +94,9 @@
return 0;
}
-/**
- * Attributes exported through sysfs
- */
-
-/**
- * @brief Get function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
-}
-
-/**
- * @brief Set function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- uint32_t datum;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- sscanf(buf, "%x", &datum);
- mesh_access.data[0] = cpu_to_le32(datum);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- u32 retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- retry_limit = le32_to_cpu(mesh_access.data[1]);
- return snprintf(buf, 10, "%d\n", retry_limit);
-}
-
-/**
- * @brief Set function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- unsigned long retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
-
- if (!strict_strtoul(buf, 10, &retry_limit))
- return -ENOTSUPP;
- if (retry_limit > 15)
- return -ENOTSUPP;
-
- mesh_access.data[1] = cpu_to_le32(retry_limit);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
-static int lbs_add_mesh(struct lbs_private *priv);
-static void lbs_remove_mesh(struct lbs_private *priv);
/**
@@ -260,74 +162,7 @@
static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
/**
- * Get function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
-}
-
-/**
- * Set function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- int enable;
- int ret, action = CMD_ACT_MESH_CONFIG_STOP;
-
- sscanf(buf, "%x", &enable);
- enable = !!enable;
- if (enable == !!priv->mesh_dev)
- return count;
- if (enable)
- action = CMD_ACT_MESH_CONFIG_START;
- ret = lbs_mesh_config(priv, action, priv->channel);
- if (ret)
- return ret;
-
- if (enable)
- lbs_add_mesh(priv);
- else
- lbs_remove_mesh(priv);
-
- return count;
-}
-
-/**
- * lbs_mesh attribute to be exported per ethX interface
- * through sysfs (/sys/class/net/ethX/lbs_mesh)
- */
-static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
-
-/**
- * anycast_mask attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/anycast_mask)
- */
-static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
-
-/**
- * prb_rsp_limit attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
- */
-static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
- lbs_prb_rsp_limit_set);
-
-static struct attribute *lbs_mesh_sysfs_entries[] = {
- &dev_attr_anycast_mask.attr,
- &dev_attr_prb_rsp_limit.attr,
- NULL,
-};
-
-static struct attribute_group lbs_mesh_attr_group = {
- .attrs = lbs_mesh_sysfs_entries,
-};
-
-/**
- * @brief This function opens the ethX or mshX interface
+ * @brief This function opens the ethX interface
*
* @param dev A pointer to net_device structure
* @return 0 or -EBUSY if monitor mode active
@@ -346,18 +181,12 @@
goto out;
}
- if (dev == priv->mesh_dev) {
- priv->mesh_open = 1;
- priv->mesh_connect_status = LBS_CONNECTED;
- netif_carrier_on(dev);
- } else {
- priv->infra_open = 1;
+ priv->infra_open = 1;
- if (priv->connect_status == LBS_CONNECTED)
- netif_carrier_on(dev);
- else
- netif_carrier_off(dev);
- }
+ if (priv->connect_status == LBS_CONNECTED)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
if (!priv->tx_pending_len)
netif_wake_queue(dev);
@@ -369,33 +198,6 @@
}
/**
- * @brief This function closes the mshX interface
- *
- * @param dev A pointer to net_device structure
- * @return 0
- */
-static int lbs_mesh_stop(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_MESH);
- spin_lock_irq(&priv->driver_lock);
-
- priv->mesh_open = 0;
- priv->mesh_connect_status = LBS_DISCONNECTED;
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- spin_unlock_irq(&priv->driver_lock);
-
- schedule_work(&priv->mcast_work);
-
- lbs_deb_leave(LBS_DEB_MESH);
- return 0;
-}
-
-/**
* @brief This function closes the ethX interface
*
* @param dev A pointer to net_device structure
@@ -466,7 +268,7 @@
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
-static int lbs_set_mac_address(struct net_device *dev, void *addr)
+int lbs_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
struct lbs_private *priv = dev->ml_priv;
@@ -600,7 +402,7 @@
lbs_deb_leave(LBS_DEB_NET);
}
-static void lbs_set_multicast_list(struct net_device *dev)
+void lbs_set_multicast_list(struct net_device *dev)
{
struct lbs_private *priv = dev->ml_priv;
@@ -1177,7 +979,6 @@
priv->card = card;
- priv->mesh_open = 0;
priv->infra_open = 0;
@@ -1198,6 +999,7 @@
INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
+ priv->mesh_open = 0;
sprintf(priv->mesh_ssid, "mesh");
priv->mesh_ssid_len = 4;
@@ -1292,50 +1094,12 @@
lbs_update_channel(priv);
- /* Check mesh FW version and appropriately send the mesh start
- * command
+ /*
+ * While rtap isn't related to mesh, only mesh-enabled
+ * firmware implements the rtap functionality via
+ * CMD_802_11_MONITOR_MODE.
*/
- if (priv->mesh_fw_ver == MESH_FW_OLD) {
- /* Enable mesh, if supported, and work out which TLV it uses.
- 0x100 + 291 is an unofficial value used in 5.110.20.pXX
- 0x100 + 37 is the official value used in 5.110.21.pXX
- but we check them in that order because 20.pXX doesn't
- give an error -- it just silently fails. */
-
- /* 5.110.20.pXX firmware will fail the command if the channel
- doesn't match the existing channel. But only if the TLV
- is correct. If the channel is wrong, _BOTH_ versions will
- give an error to 0x100+291, and allow 0x100+37 to succeed.
- It's just that 5.110.20.pXX will not have done anything
- useful */
-
- priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel)) {
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
- priv->mesh_tlv = 0;
- }
- } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
- /* 10.0.0.pXX new firmwares should succeed with TLV
- * 0x100+37; Do not invoke command with old TLV.
- */
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
- priv->mesh_tlv = 0;
- }
- if (priv->mesh_tlv) {
- lbs_add_mesh(priv);
-
- if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
- lbs_pr_err("cannot register lbs_mesh attribute\n");
-
- /* While rtap isn't related to mesh, only mesh-enabled
- * firmware implements the rtap functionality via
- * CMD_802_11_MONITOR_MODE.
- */
+ if (lbs_init_mesh(priv)) {
if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
lbs_pr_err("cannot register lbs_rtap attribute\n");
}
@@ -1369,10 +1133,8 @@
netif_carrier_off(dev);
lbs_debugfs_remove_one(priv);
- if (priv->mesh_tlv) {
- device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+ if (lbs_deinit_mesh(priv))
device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
- }
/* Delete the timeout of the currently processing command */
del_timer_sync(&priv->command_timer);
@@ -1405,95 +1167,6 @@
EXPORT_SYMBOL_GPL(lbs_stop_card);
-static const struct net_device_ops mesh_netdev_ops = {
- .ndo_open = lbs_dev_open,
- .ndo_stop = lbs_mesh_stop,
- .ndo_start_xmit = lbs_hard_start_xmit,
- .ndo_set_mac_address = lbs_set_mac_address,
- .ndo_set_multicast_list = lbs_set_multicast_list,
-};
-
-/**
- * @brief This function adds mshX interface
- *
- * @param priv A pointer to the struct lbs_private structure
- * @return 0 if successful, -X otherwise
- */
-static int lbs_add_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev = NULL;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MESH);
-
- /* Allocate a virtual mesh device */
- if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
- lbs_deb_mesh("init mshX device failed\n");
- ret = -ENOMEM;
- goto done;
- }
- mesh_dev->ml_priv = priv;
- priv->mesh_dev = mesh_dev;
-
- mesh_dev->netdev_ops = &mesh_netdev_ops;
- mesh_dev->ethtool_ops = &lbs_ethtool_ops;
- memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
- sizeof(priv->dev->dev_addr));
-
- SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
-
-#ifdef WIRELESS_EXT
- mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
-#endif
- mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- /* Register virtual mesh interface */
- ret = register_netdev(mesh_dev);
- if (ret) {
- lbs_pr_err("cannot register mshX virtual interface\n");
- goto err_free;
- }
-
- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- if (ret)
- goto err_unregister;
-
- lbs_persist_config_init(mesh_dev);
-
- /* Everything successful */
- ret = 0;
- goto done;
-
-err_unregister:
- unregister_netdev(mesh_dev);
-
-err_free:
- free_netdev(mesh_dev);
-
-done:
- lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
- return ret;
-}
-
-static void lbs_remove_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev;
-
-
- mesh_dev = priv->mesh_dev;
- if (!mesh_dev)
- return;
-
- lbs_deb_enter(LBS_DEB_MESH);
- netif_stop_queue(mesh_dev);
- netif_carrier_off(mesh_dev);
- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- lbs_persist_config_remove(mesh_dev);
- unregister_netdev(mesh_dev);
- priv->mesh_dev = NULL;
- free_netdev(mesh_dev);
- lbs_deb_leave(LBS_DEB_MESH);
-}
-
void lbs_queue_event(struct lbs_private *priv, u32 event)
{
unsigned long flags;
--- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c
+++ linux-wl/drivers/net/wireless/libertas/persistcfg.c
@@ -6,15 +6,444 @@
#include <linux/kthread.h>
#include <linux/kfifo.h>
-#include "host.h"
+#include "mesh.h"
#include "decl.h"
-#include "dev.h"
-#include "wext.h"
-#include "debugfs.h"
-#include "scan.h"
-#include "assoc.h"
#include "cmd.h"
+
+/***************************************************************************
+ * Mesh sysfs support
+ */
+
+/**
+ * Attributes exported through sysfs
+ */
+
+/**
+ * @brief Get function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_get(struct device *dev,
+ struct device_attribute *attr, char * buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
+}
+
+/**
+ * @brief Set function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_set(struct device *dev,
+ struct device_attribute *attr, const char * buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ uint32_t datum;
+ int ret;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ sscanf(buf, "%x", &datum);
+ mesh_access.data[0] = cpu_to_le32(datum);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ u32 retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ retry_limit = le32_to_cpu(mesh_access.data[1]);
+ return snprintf(buf, 10, "%d\n", retry_limit);
+}
+
+/**
+ * @brief Set function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ unsigned long retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
+
+ if (!strict_strtoul(buf, 10, &retry_limit))
+ return -ENOTSUPP;
+ if (retry_limit > 15)
+ return -ENOTSUPP;
+
+ mesh_access.data[1] = cpu_to_le32(retry_limit);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * Get function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_get(struct device *dev,
+ struct device_attribute *attr, char * buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
+}
+
+/**
+ * Set function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_set(struct device *dev,
+ struct device_attribute *attr, const char * buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ int enable;
+ int ret, action = CMD_ACT_MESH_CONFIG_STOP;
+
+ sscanf(buf, "%x", &enable);
+ enable = !!enable;
+ if (enable == !!priv->mesh_dev)
+ return count;
+ if (enable)
+ action = CMD_ACT_MESH_CONFIG_START;
+ ret = lbs_mesh_config(priv, action, priv->channel);
+ if (ret)
+ return ret;
+
+ if (enable)
+ lbs_add_mesh(priv);
+ else
+ lbs_remove_mesh(priv);
+
+ return count;
+}
+
+/**
+ * lbs_mesh attribute to be exported per ethX interface
+ * through sysfs (/sys/class/net/ethX/lbs_mesh)
+ */
+static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
+
+/**
+ * anycast_mask attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/anycast_mask)
+ */
+static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
+
+/**
+ * prb_rsp_limit attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
+ */
+static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
+ lbs_prb_rsp_limit_set);
+
+static struct attribute *lbs_mesh_sysfs_entries[] = {
+ &dev_attr_anycast_mask.attr,
+ &dev_attr_prb_rsp_limit.attr,
+ NULL,
+};
+
+static struct attribute_group lbs_mesh_attr_group = {
+ .attrs = lbs_mesh_sysfs_entries,
+};
+
+
+
+/***************************************************************************
+ * Initializing and starting, stopping mesh
+ */
+
+/*
+ * Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+int lbs_init_mesh(struct lbs_private *priv)
+{
+ struct net_device *dev = priv->dev;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ /* Enable mesh, if supported, and work out which TLV it uses.
+ 0x100 + 291 is an unofficial value used in 5.110.20.pXX
+ 0x100 + 37 is the official value used in 5.110.21.pXX
+ but we check them in that order because 20.pXX doesn't
+ give an error -- it just silently fails. */
+
+ /* 5.110.20.pXX firmware will fail the command if the channel
+ doesn't match the existing channel. But only if the TLV
+ is correct. If the channel is wrong, _BOTH_ versions will
+ give an error to 0x100+291, and allow 0x100+37 to succeed.
+ It's just that 5.110.20.pXX will not have done anything
+ useful */
+
+ priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel)) {
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel))
+ priv->mesh_tlv = 0;
+ }
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ /* 10.0.0.pXX new firmwares should succeed with TLV
+ * 0x100+37; Do not invoke command with old TLV.
+ */
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel))
+ priv->mesh_tlv = 0;
+ }
+ if (priv->mesh_tlv) {
+ lbs_add_mesh(priv);
+
+ if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+ lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+ ret = 1;
+ }
+
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+
+int lbs_deinit_mesh(struct lbs_private *priv)
+{
+ struct net_device *dev = priv->dev;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ if (priv->mesh_tlv) {
+ device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+ ret = 1;
+ }
+
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+
+/**
+ * @brief This function closes the mshX interface
+ *
+ * @param dev A pointer to net_device structure
+ * @return 0
+ */
+static int lbs_mesh_stop(struct net_device *dev)
+{
+ struct lbs_private *priv = dev->ml_priv;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+ spin_lock_irq(&priv->driver_lock);
+
+ priv->mesh_open = 0;
+ priv->mesh_connect_status = LBS_DISCONNECTED;
+
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+
+ spin_unlock_irq(&priv->driver_lock);
+
+ schedule_work(&priv->mcast_work);
+
+ lbs_deb_leave(LBS_DEB_MESH);
+ return 0;
+}
+
+/**
+ * @brief This function opens the mshX interface
+ *
+ * @param dev A pointer to net_device structure
+ * @return 0 or -EBUSY if monitor mode active
+ */
+static int lbs_mesh_dev_open(struct net_device *dev)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_NET);
+
+ spin_lock_irq(&priv->driver_lock);
+
+ if (priv->monitormode) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ priv->mesh_open = 1;
+ priv->mesh_connect_status = LBS_CONNECTED;
+ netif_carrier_on(dev);
+
+ if (!priv->tx_pending_len)
+ netif_wake_queue(dev);
+ out:
+
+ spin_unlock_irq(&priv->driver_lock);
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+ return ret;
+}
+
+static const struct net_device_ops mesh_netdev_ops = {
+ .ndo_open = lbs_mesh_dev_open,
+ .ndo_stop = lbs_mesh_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
+/**
+ * @brief This function adds mshX interface
+ *
+ * @param priv A pointer to the struct lbs_private structure
+ * @return 0 if successful, -X otherwise
+ */
+int lbs_add_mesh(struct lbs_private *priv)
+{
+ struct net_device *mesh_dev = NULL;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ /* Allocate a virtual mesh device */
+ mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
+ if (!mesh_dev) {
+ lbs_deb_mesh("init mshX device failed\n");
+ ret = -ENOMEM;
+ goto done;
+ }
+ mesh_dev->ml_priv = priv;
+ priv->mesh_dev = mesh_dev;
+
+ mesh_dev->netdev_ops = &mesh_netdev_ops;
+ mesh_dev->ethtool_ops = &lbs_ethtool_ops;
+ memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
+ sizeof(priv->dev->dev_addr));
+
+ SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
+
+#ifdef WIRELESS_EXT
+ mesh_dev->wireless_handlers = &mesh_handler_def;
+#endif
+ mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ /* Register virtual mesh interface */
+ ret = register_netdev(mesh_dev);
+ if (ret) {
+ lbs_pr_err("cannot register mshX virtual interface\n");
+ goto err_free;
+ }
+
+ ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+ if (ret)
+ goto err_unregister;
+
+ lbs_persist_config_init(mesh_dev);
+
+ /* Everything successful */
+ ret = 0;
+ goto done;
+
+err_unregister:
+ unregister_netdev(mesh_dev);
+
+err_free:
+ free_netdev(mesh_dev);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+void lbs_remove_mesh(struct lbs_private *priv)
+{
+ struct net_device *mesh_dev;
+
+ mesh_dev = priv->mesh_dev;
+ if (!mesh_dev)
+ return;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+ netif_stop_queue(mesh_dev);
+ netif_carrier_off(mesh_dev);
+ sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+ lbs_persist_config_remove(mesh_dev);
+ unregister_netdev(mesh_dev);
+ priv->mesh_dev = NULL;
+ free_netdev(mesh_dev);
+ lbs_deb_leave(LBS_DEB_MESH);
+}
+
+
+
+/***************************************************************************
+ * Sending and receiving
+ */
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+ struct net_device *dev, struct rxpd *rxpd)
+{
+ if (priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ if (rxpd->rx_control & RxPD_MESH_FRAME)
+ dev = priv->mesh_dev;
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
+ dev = priv->mesh_dev;
+ }
+ }
+ return dev;
+}
+
+
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+ struct net_device *dev, struct txpd *txpd)
+{
+ if (dev == priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD)
+ txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ else if (priv->mesh_fw_ver == MESH_FW_NEW)
+ txpd->u.bss.bss_num = MESH_IFACE_ID;
+ }
+}
+
+
+/***************************************************************************
+ * Persistent configuration support
+ */
+
static int mesh_get_default_parameters(struct device *dev,
struct mrvl_mesh_defaults *defs)
{
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.h
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -22,10 +22,34 @@
struct net_device;
+struct lbs_private;
+
+int lbs_init_mesh(struct lbs_private *priv);
+int lbs_deinit_mesh(struct lbs_private *priv);
+
+int lbs_add_mesh(struct lbs_private *priv);
+void lbs_remove_mesh(struct lbs_private *priv);
+
+
+/* Sending / Receiving */
+
+struct rxpd;
+struct txpd;
+
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+ struct net_device *dev, struct rxpd *rxpd);
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+ struct net_device *dev, struct txpd *txpd);
+
+
+/* Persistent configuration */
void lbs_persist_config_init(struct net_device *net);
void lbs_persist_config_remove(struct net_device *net);
+
+/* WEXT handler */
+
extern struct iw_handler_def mesh_handler_def;
--- linux-wl.orig/drivers/net/wireless/libertas/Makefile
+++ linux-wl/drivers/net/wireless/libertas/Makefile
@@ -1,14 +1,14 @@
+libertas-y += tx.o
+libertas-y += persistcfg.o
+libertas-y += main.o
+libertas-y += rx.o
libertas-y += assoc.o
libertas-y += cfg.o
libertas-y += cmd.o
libertas-y += cmdresp.o
libertas-y += debugfs.o
libertas-y += ethtool.o
-libertas-y += main.o
-libertas-y += persistcfg.o
-libertas-y += rx.o
libertas-y += scan.o
-libertas-y += tx.o
libertas-y += wext.o
usb8xxx-objs += if_usb.o
--- linux-wl.orig/drivers/net/wireless/libertas/decl.h
+++ linux-wl/drivers/net/wireless/libertas/decl.h
@@ -34,6 +34,9 @@
void lbs_stop_card(struct lbs_private *priv);
void lbs_host_to_card_done(struct lbs_private *priv);
+int lbs_set_mac_address(struct net_device *dev, void *addr);
+void lbs_set_multicast_list(struct net_device *dev);
+
int lbs_suspend(struct lbs_private *priv);
void lbs_resume(struct lbs_private *priv);
--- linux-wl.orig/drivers/net/wireless/libertas/rx.c
+++ linux-wl/drivers/net/wireless/libertas/rx.c
@@ -160,15 +160,8 @@
p_rx_pd = (struct rxpd *) skb->data;
p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
le32_to_cpu(p_rx_pd->pkt_ptr));
- if (priv->mesh_dev) {
- if (priv->mesh_fw_ver == MESH_FW_OLD) {
- if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
- dev = priv->mesh_dev;
- } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
- if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
- dev = priv->mesh_dev;
- }
- }
+
+ dev = lbs_mesh_set_dev(priv, dev, p_rx_pd);
lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
min_t(unsigned int, skb->len, 100));
--- linux-wl.orig/drivers/net/wireless/libertas/tx.c
+++ linux-wl/drivers/net/wireless/libertas/tx.c
@@ -131,12 +131,7 @@
txpd->tx_packet_length = cpu_to_le16(pkt_len);
txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
- if (dev == priv->mesh_dev) {
- if (priv->mesh_fw_ver == MESH_FW_OLD)
- txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
- else if (priv->mesh_fw_ver == MESH_FW_NEW)
- txpd->u.bss.bss_num = MESH_IFACE_ID;
- }
+ lbs_mesh_set_txpd(priv, dev, txpd);
lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
--
http://www.holgerschurig.de
^ permalink raw reply
* [PATCH, v2] libertas: initial move of mesh related functions into persistcfg.c
From: Holger Schurig @ 2009-10-26 15:41 UTC (permalink / raw)
To: linux-wireless; +Cc: Dan Williams, John Linville
In-Reply-To: <200910261622.22140.hs4233@mail.mn-solutions.de>
This moves mesh initialization, start/stop and rx/tx handling from
the respective *.c files into persistcfg.c.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
---
v2: don't modify Makefile
--- linux-wl.orig/drivers/net/wireless/libertas/main.c
+++ linux-wl/drivers/net/wireless/libertas/main.c
@@ -94,107 +94,9 @@
return 0;
}
-/**
- * Attributes exported through sysfs
- */
-
-/**
- * @brief Get function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
-}
-
-/**
- * @brief Set function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- uint32_t datum;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- sscanf(buf, "%x", &datum);
- mesh_access.data[0] = cpu_to_le32(datum);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- u32 retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- retry_limit = le32_to_cpu(mesh_access.data[1]);
- return snprintf(buf, 10, "%d\n", retry_limit);
-}
-
-/**
- * @brief Set function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- unsigned long retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
-
- if (!strict_strtoul(buf, 10, &retry_limit))
- return -ENOTSUPP;
- if (retry_limit > 15)
- return -ENOTSUPP;
-
- mesh_access.data[1] = cpu_to_le32(retry_limit);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
-static int lbs_add_mesh(struct lbs_private *priv);
-static void lbs_remove_mesh(struct lbs_private *priv);
/**
@@ -260,74 +162,7 @@
static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
/**
- * Get function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
-}
-
-/**
- * Set function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- int enable;
- int ret, action = CMD_ACT_MESH_CONFIG_STOP;
-
- sscanf(buf, "%x", &enable);
- enable = !!enable;
- if (enable == !!priv->mesh_dev)
- return count;
- if (enable)
- action = CMD_ACT_MESH_CONFIG_START;
- ret = lbs_mesh_config(priv, action, priv->channel);
- if (ret)
- return ret;
-
- if (enable)
- lbs_add_mesh(priv);
- else
- lbs_remove_mesh(priv);
-
- return count;
-}
-
-/**
- * lbs_mesh attribute to be exported per ethX interface
- * through sysfs (/sys/class/net/ethX/lbs_mesh)
- */
-static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
-
-/**
- * anycast_mask attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/anycast_mask)
- */
-static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
-
-/**
- * prb_rsp_limit attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
- */
-static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
- lbs_prb_rsp_limit_set);
-
-static struct attribute *lbs_mesh_sysfs_entries[] = {
- &dev_attr_anycast_mask.attr,
- &dev_attr_prb_rsp_limit.attr,
- NULL,
-};
-
-static struct attribute_group lbs_mesh_attr_group = {
- .attrs = lbs_mesh_sysfs_entries,
-};
-
-/**
- * @brief This function opens the ethX or mshX interface
+ * @brief This function opens the ethX interface
*
* @param dev A pointer to net_device structure
* @return 0 or -EBUSY if monitor mode active
@@ -346,18 +181,12 @@
goto out;
}
- if (dev == priv->mesh_dev) {
- priv->mesh_open = 1;
- priv->mesh_connect_status = LBS_CONNECTED;
- netif_carrier_on(dev);
- } else {
- priv->infra_open = 1;
+ priv->infra_open = 1;
- if (priv->connect_status == LBS_CONNECTED)
- netif_carrier_on(dev);
- else
- netif_carrier_off(dev);
- }
+ if (priv->connect_status == LBS_CONNECTED)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
if (!priv->tx_pending_len)
netif_wake_queue(dev);
@@ -369,33 +198,6 @@
}
/**
- * @brief This function closes the mshX interface
- *
- * @param dev A pointer to net_device structure
- * @return 0
- */
-static int lbs_mesh_stop(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_MESH);
- spin_lock_irq(&priv->driver_lock);
-
- priv->mesh_open = 0;
- priv->mesh_connect_status = LBS_DISCONNECTED;
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- spin_unlock_irq(&priv->driver_lock);
-
- schedule_work(&priv->mcast_work);
-
- lbs_deb_leave(LBS_DEB_MESH);
- return 0;
-}
-
-/**
* @brief This function closes the ethX interface
*
* @param dev A pointer to net_device structure
@@ -466,7 +268,7 @@
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
-static int lbs_set_mac_address(struct net_device *dev, void *addr)
+int lbs_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
struct lbs_private *priv = dev->ml_priv;
@@ -600,7 +402,7 @@
lbs_deb_leave(LBS_DEB_NET);
}
-static void lbs_set_multicast_list(struct net_device *dev)
+void lbs_set_multicast_list(struct net_device *dev)
{
struct lbs_private *priv = dev->ml_priv;
@@ -1177,7 +980,6 @@
priv->card = card;
- priv->mesh_open = 0;
priv->infra_open = 0;
@@ -1198,6 +1000,7 @@
INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
+ priv->mesh_open = 0;
sprintf(priv->mesh_ssid, "mesh");
priv->mesh_ssid_len = 4;
@@ -1292,50 +1095,12 @@
lbs_update_channel(priv);
- /* Check mesh FW version and appropriately send the mesh start
- * command
+ /*
+ * While rtap isn't related to mesh, only mesh-enabled
+ * firmware implements the rtap functionality via
+ * CMD_802_11_MONITOR_MODE.
*/
- if (priv->mesh_fw_ver == MESH_FW_OLD) {
- /* Enable mesh, if supported, and work out which TLV it uses.
- 0x100 + 291 is an unofficial value used in 5.110.20.pXX
- 0x100 + 37 is the official value used in 5.110.21.pXX
- but we check them in that order because 20.pXX doesn't
- give an error -- it just silently fails. */
-
- /* 5.110.20.pXX firmware will fail the command if the channel
- doesn't match the existing channel. But only if the TLV
- is correct. If the channel is wrong, _BOTH_ versions will
- give an error to 0x100+291, and allow 0x100+37 to succeed.
- It's just that 5.110.20.pXX will not have done anything
- useful */
-
- priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel)) {
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
- priv->mesh_tlv = 0;
- }
- } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
- /* 10.0.0.pXX new firmwares should succeed with TLV
- * 0x100+37; Do not invoke command with old TLV.
- */
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
- priv->mesh_tlv = 0;
- }
- if (priv->mesh_tlv) {
- lbs_add_mesh(priv);
-
- if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
- lbs_pr_err("cannot register lbs_mesh attribute\n");
-
- /* While rtap isn't related to mesh, only mesh-enabled
- * firmware implements the rtap functionality via
- * CMD_802_11_MONITOR_MODE.
- */
+ if (lbs_init_mesh(priv)) {
if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
lbs_pr_err("cannot register lbs_rtap attribute\n");
}
@@ -1369,10 +1134,8 @@
netif_carrier_off(dev);
lbs_debugfs_remove_one(priv);
- if (priv->mesh_tlv) {
- device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+ if (lbs_deinit_mesh(priv))
device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
- }
/* Delete the timeout of the currently processing command */
del_timer_sync(&priv->command_timer);
@@ -1405,95 +1168,6 @@
EXPORT_SYMBOL_GPL(lbs_stop_card);
-static const struct net_device_ops mesh_netdev_ops = {
- .ndo_open = lbs_dev_open,
- .ndo_stop = lbs_mesh_stop,
- .ndo_start_xmit = lbs_hard_start_xmit,
- .ndo_set_mac_address = lbs_set_mac_address,
- .ndo_set_multicast_list = lbs_set_multicast_list,
-};
-
-/**
- * @brief This function adds mshX interface
- *
- * @param priv A pointer to the struct lbs_private structure
- * @return 0 if successful, -X otherwise
- */
-static int lbs_add_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev = NULL;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MESH);
-
- /* Allocate a virtual mesh device */
- if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
- lbs_deb_mesh("init mshX device failed\n");
- ret = -ENOMEM;
- goto done;
- }
- mesh_dev->ml_priv = priv;
- priv->mesh_dev = mesh_dev;
-
- mesh_dev->netdev_ops = &mesh_netdev_ops;
- mesh_dev->ethtool_ops = &lbs_ethtool_ops;
- memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
- sizeof(priv->dev->dev_addr));
-
- SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
-
-#ifdef WIRELESS_EXT
- mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
-#endif
- mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- /* Register virtual mesh interface */
- ret = register_netdev(mesh_dev);
- if (ret) {
- lbs_pr_err("cannot register mshX virtual interface\n");
- goto err_free;
- }
-
- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- if (ret)
- goto err_unregister;
-
- lbs_persist_config_init(mesh_dev);
-
- /* Everything successful */
- ret = 0;
- goto done;
-
-err_unregister:
- unregister_netdev(mesh_dev);
-
-err_free:
- free_netdev(mesh_dev);
-
-done:
- lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
- return ret;
-}
-
-static void lbs_remove_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev;
-
-
- mesh_dev = priv->mesh_dev;
- if (!mesh_dev)
- return;
-
- lbs_deb_enter(LBS_DEB_MESH);
- netif_stop_queue(mesh_dev);
- netif_carrier_off(mesh_dev);
- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- lbs_persist_config_remove(mesh_dev);
- unregister_netdev(mesh_dev);
- priv->mesh_dev = NULL;
- free_netdev(mesh_dev);
- lbs_deb_leave(LBS_DEB_MESH);
-}
-
void lbs_queue_event(struct lbs_private *priv, u32 event)
{
unsigned long flags;
--- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c
+++ linux-wl/drivers/net/wireless/libertas/persistcfg.c
@@ -6,15 +6,444 @@
#include <linux/kthread.h>
#include <linux/kfifo.h>
-#include "host.h"
+#include "mesh.h"
#include "decl.h"
-#include "dev.h"
-#include "wext.h"
-#include "debugfs.h"
-#include "scan.h"
-#include "assoc.h"
#include "cmd.h"
+
+/***************************************************************************
+ * Mesh sysfs support
+ */
+
+/**
+ * Attributes exported through sysfs
+ */
+
+/**
+ * @brief Get function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_get(struct device *dev,
+ struct device_attribute *attr, char * buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
+}
+
+/**
+ * @brief Set function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_set(struct device *dev,
+ struct device_attribute *attr, const char * buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ uint32_t datum;
+ int ret;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ sscanf(buf, "%x", &datum);
+ mesh_access.data[0] = cpu_to_le32(datum);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ u32 retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ retry_limit = le32_to_cpu(mesh_access.data[1]);
+ return snprintf(buf, 10, "%d\n", retry_limit);
+}
+
+/**
+ * @brief Set function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ unsigned long retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
+
+ if (!strict_strtoul(buf, 10, &retry_limit))
+ return -ENOTSUPP;
+ if (retry_limit > 15)
+ return -ENOTSUPP;
+
+ mesh_access.data[1] = cpu_to_le32(retry_limit);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * Get function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_get(struct device *dev,
+ struct device_attribute *attr, char * buf)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
+}
+
+/**
+ * Set function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_set(struct device *dev,
+ struct device_attribute *attr, const char * buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+ int enable;
+ int ret, action = CMD_ACT_MESH_CONFIG_STOP;
+
+ sscanf(buf, "%x", &enable);
+ enable = !!enable;
+ if (enable == !!priv->mesh_dev)
+ return count;
+ if (enable)
+ action = CMD_ACT_MESH_CONFIG_START;
+ ret = lbs_mesh_config(priv, action, priv->channel);
+ if (ret)
+ return ret;
+
+ if (enable)
+ lbs_add_mesh(priv);
+ else
+ lbs_remove_mesh(priv);
+
+ return count;
+}
+
+/**
+ * lbs_mesh attribute to be exported per ethX interface
+ * through sysfs (/sys/class/net/ethX/lbs_mesh)
+ */
+static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
+
+/**
+ * anycast_mask attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/anycast_mask)
+ */
+static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
+
+/**
+ * prb_rsp_limit attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
+ */
+static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
+ lbs_prb_rsp_limit_set);
+
+static struct attribute *lbs_mesh_sysfs_entries[] = {
+ &dev_attr_anycast_mask.attr,
+ &dev_attr_prb_rsp_limit.attr,
+ NULL,
+};
+
+static struct attribute_group lbs_mesh_attr_group = {
+ .attrs = lbs_mesh_sysfs_entries,
+};
+
+
+
+/***************************************************************************
+ * Initializing and starting, stopping mesh
+ */
+
+/*
+ * Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+int lbs_init_mesh(struct lbs_private *priv)
+{
+ struct net_device *dev = priv->dev;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ /* Enable mesh, if supported, and work out which TLV it uses.
+ 0x100 + 291 is an unofficial value used in 5.110.20.pXX
+ 0x100 + 37 is the official value used in 5.110.21.pXX
+ but we check them in that order because 20.pXX doesn't
+ give an error -- it just silently fails. */
+
+ /* 5.110.20.pXX firmware will fail the command if the channel
+ doesn't match the existing channel. But only if the TLV
+ is correct. If the channel is wrong, _BOTH_ versions will
+ give an error to 0x100+291, and allow 0x100+37 to succeed.
+ It's just that 5.110.20.pXX will not have done anything
+ useful */
+
+ priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel)) {
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel))
+ priv->mesh_tlv = 0;
+ }
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ /* 10.0.0.pXX new firmwares should succeed with TLV
+ * 0x100+37; Do not invoke command with old TLV.
+ */
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel))
+ priv->mesh_tlv = 0;
+ }
+ if (priv->mesh_tlv) {
+ lbs_add_mesh(priv);
+
+ if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+ lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+ ret = 1;
+ }
+
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+
+int lbs_deinit_mesh(struct lbs_private *priv)
+{
+ struct net_device *dev = priv->dev;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ if (priv->mesh_tlv) {
+ device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+ ret = 1;
+ }
+
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+
+/**
+ * @brief This function closes the mshX interface
+ *
+ * @param dev A pointer to net_device structure
+ * @return 0
+ */
+static int lbs_mesh_stop(struct net_device *dev)
+{
+ struct lbs_private *priv = dev->ml_priv;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+ spin_lock_irq(&priv->driver_lock);
+
+ priv->mesh_open = 0;
+ priv->mesh_connect_status = LBS_DISCONNECTED;
+
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+
+ spin_unlock_irq(&priv->driver_lock);
+
+ schedule_work(&priv->mcast_work);
+
+ lbs_deb_leave(LBS_DEB_MESH);
+ return 0;
+}
+
+/**
+ * @brief This function opens the mshX interface
+ *
+ * @param dev A pointer to net_device structure
+ * @return 0 or -EBUSY if monitor mode active
+ */
+static int lbs_mesh_dev_open(struct net_device *dev)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_NET);
+
+ spin_lock_irq(&priv->driver_lock);
+
+ if (priv->monitormode) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ priv->mesh_open = 1;
+ priv->mesh_connect_status = LBS_CONNECTED;
+ netif_carrier_on(dev);
+
+ if (!priv->tx_pending_len)
+ netif_wake_queue(dev);
+ out:
+
+ spin_unlock_irq(&priv->driver_lock);
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+ return ret;
+}
+
+static const struct net_device_ops mesh_netdev_ops = {
+ .ndo_open = lbs_mesh_dev_open,
+ .ndo_stop = lbs_mesh_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
+/**
+ * @brief This function adds mshX interface
+ *
+ * @param priv A pointer to the struct lbs_private structure
+ * @return 0 if successful, -X otherwise
+ */
+int lbs_add_mesh(struct lbs_private *priv)
+{
+ struct net_device *mesh_dev = NULL;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ /* Allocate a virtual mesh device */
+ mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
+ if (!mesh_dev) {
+ lbs_deb_mesh("init mshX device failed\n");
+ ret = -ENOMEM;
+ goto done;
+ }
+ mesh_dev->ml_priv = priv;
+ priv->mesh_dev = mesh_dev;
+
+ mesh_dev->netdev_ops = &mesh_netdev_ops;
+ mesh_dev->ethtool_ops = &lbs_ethtool_ops;
+ memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
+ sizeof(priv->dev->dev_addr));
+
+ SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
+
+#ifdef WIRELESS_EXT
+ mesh_dev->wireless_handlers = &mesh_handler_def;
+#endif
+ mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ /* Register virtual mesh interface */
+ ret = register_netdev(mesh_dev);
+ if (ret) {
+ lbs_pr_err("cannot register mshX virtual interface\n");
+ goto err_free;
+ }
+
+ ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+ if (ret)
+ goto err_unregister;
+
+ lbs_persist_config_init(mesh_dev);
+
+ /* Everything successful */
+ ret = 0;
+ goto done;
+
+err_unregister:
+ unregister_netdev(mesh_dev);
+
+err_free:
+ free_netdev(mesh_dev);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
+}
+
+void lbs_remove_mesh(struct lbs_private *priv)
+{
+ struct net_device *mesh_dev;
+
+ mesh_dev = priv->mesh_dev;
+ if (!mesh_dev)
+ return;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+ netif_stop_queue(mesh_dev);
+ netif_carrier_off(mesh_dev);
+ sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+ lbs_persist_config_remove(mesh_dev);
+ unregister_netdev(mesh_dev);
+ priv->mesh_dev = NULL;
+ free_netdev(mesh_dev);
+ lbs_deb_leave(LBS_DEB_MESH);
+}
+
+
+
+/***************************************************************************
+ * Sending and receiving
+ */
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+ struct net_device *dev, struct rxpd *rxpd)
+{
+ if (priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ if (rxpd->rx_control & RxPD_MESH_FRAME)
+ dev = priv->mesh_dev;
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
+ dev = priv->mesh_dev;
+ }
+ }
+ return dev;
+}
+
+
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+ struct net_device *dev, struct txpd *txpd)
+{
+ if (dev == priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD)
+ txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ else if (priv->mesh_fw_ver == MESH_FW_NEW)
+ txpd->u.bss.bss_num = MESH_IFACE_ID;
+ }
+}
+
+
+/***************************************************************************
+ * Persistent configuration support
+ */
+
static int mesh_get_default_parameters(struct device *dev,
struct mrvl_mesh_defaults *defs)
{
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.h
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -22,10 +22,34 @@
struct net_device;
+struct lbs_private;
+
+int lbs_init_mesh(struct lbs_private *priv);
+int lbs_deinit_mesh(struct lbs_private *priv);
+
+int lbs_add_mesh(struct lbs_private *priv);
+void lbs_remove_mesh(struct lbs_private *priv);
+
+
+/* Sending / Receiving */
+
+struct rxpd;
+struct txpd;
+
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+ struct net_device *dev, struct rxpd *rxpd);
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+ struct net_device *dev, struct txpd *txpd);
+
+
+/* Persistent configuration */
void lbs_persist_config_init(struct net_device *net);
void lbs_persist_config_remove(struct net_device *net);
+
+/* WEXT handler */
+
extern struct iw_handler_def mesh_handler_def;
--- linux-wl.orig/drivers/net/wireless/libertas/decl.h
+++ linux-wl/drivers/net/wireless/libertas/decl.h
@@ -34,6 +34,9 @@
void lbs_stop_card(struct lbs_private *priv);
void lbs_host_to_card_done(struct lbs_private *priv);
+int lbs_set_mac_address(struct net_device *dev, void *addr);
+void lbs_set_multicast_list(struct net_device *dev);
+
int lbs_suspend(struct lbs_private *priv);
void lbs_resume(struct lbs_private *priv);
--- linux-wl.orig/drivers/net/wireless/libertas/rx.c
+++ linux-wl/drivers/net/wireless/libertas/rx.c
@@ -160,15 +160,8 @@
p_rx_pd = (struct rxpd *) skb->data;
p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
le32_to_cpu(p_rx_pd->pkt_ptr));
- if (priv->mesh_dev) {
- if (priv->mesh_fw_ver == MESH_FW_OLD) {
- if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
- dev = priv->mesh_dev;
- } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
- if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
- dev = priv->mesh_dev;
- }
- }
+
+ dev = lbs_mesh_set_dev(priv, dev, p_rx_pd);
lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
min_t(unsigned int, skb->len, 100));
--- linux-wl.orig/drivers/net/wireless/libertas/tx.c
+++ linux-wl/drivers/net/wireless/libertas/tx.c
@@ -131,12 +131,7 @@
txpd->tx_packet_length = cpu_to_le16(pkt_len);
txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
- if (dev == priv->mesh_dev) {
- if (priv->mesh_fw_ver == MESH_FW_OLD)
- txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
- else if (priv->mesh_fw_ver == MESH_FW_NEW)
- txpd->u.bss.bss_num = MESH_IFACE_ID;
- }
+ lbs_mesh_set_txpd(priv, dev, txpd);
lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
^ permalink raw reply
* [PATCH] libertas: move mesh-only ethtool operations away
From: Holger Schurig @ 2009-10-26 15:44 UTC (permalink / raw)
To: linux-wireless, Dan Williams, John Linville
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
--- linux-wl.orig/drivers/net/wireless/libertas/ethtool.c
+++ linux-wl/drivers/net/wireless/libertas/ethtool.c
@@ -8,17 +8,8 @@
#include "dev.h"
#include "wext.h"
#include "cmd.h"
+#include "mesh.h"
-static const char * mesh_stat_strings[]= {
- "drop_duplicate_bcast",
- "drop_ttl_zero",
- "drop_no_fwd_route",
- "drop_no_buffers",
- "fwded_unicast_cnt",
- "fwded_bcast_cnt",
- "drop_blind_table",
- "tx_failed_cnt"
-};
static void lbs_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
@@ -73,73 +64,6 @@
return ret;
}
-static void lbs_ethtool_get_stats(struct net_device *dev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct lbs_private *priv = dev->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-
- /* Get Mesh Statistics */
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
-
- if (ret) {
- memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
- return;
- }
-
- priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
- priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
- priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
- priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
- priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
- priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
- priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
- priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
-
- data[0] = priv->mstats.fwd_drop_rbt;
- data[1] = priv->mstats.fwd_drop_ttl;
- data[2] = priv->mstats.fwd_drop_noroute;
- data[3] = priv->mstats.fwd_drop_nobuf;
- data[4] = priv->mstats.fwd_unicast_cnt;
- data[5] = priv->mstats.fwd_bcast_cnt;
- data[6] = priv->mstats.drop_blind;
- data[7] = priv->mstats.tx_failed_cnt;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
-
-static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
- return MESH_STATS_NUM;
-
- return -EOPNOTSUPP;
-}
-
-static void lbs_ethtool_get_strings(struct net_device *dev,
- uint32_t stringset, uint8_t *s)
-{
- int i;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-
- switch (stringset) {
- case ETH_SS_STATS:
- for (i=0; i < MESH_STATS_NUM; i++) {
- memcpy(s + i * ETH_GSTRING_LEN,
- mesh_stat_strings[i],
- ETH_GSTRING_LEN);
- }
- break;
- }
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
-
static void lbs_ethtool_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
@@ -187,9 +111,9 @@
.get_drvinfo = lbs_ethtool_get_drvinfo,
.get_eeprom = lbs_ethtool_get_eeprom,
.get_eeprom_len = lbs_ethtool_get_eeprom_len,
- .get_sset_count = lbs_ethtool_get_sset_count,
- .get_ethtool_stats = lbs_ethtool_get_stats,
- .get_strings = lbs_ethtool_get_strings,
+ .get_sset_count = lbs_mesh_ethtool_get_sset_count,
+ .get_ethtool_stats = lbs_mesh_ethtool_get_stats,
+ .get_strings = lbs_mesh_ethtool_get_strings,
.get_wol = lbs_ethtool_get_wol,
.set_wol = lbs_ethtool_set_wol,
};
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.h
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -53,4 +53,15 @@
extern struct iw_handler_def mesh_handler_def;
+/* Ethtool statistics */
+
+struct ethtool_stats;
+
+void lbs_mesh_ethtool_get_stats(struct net_device *dev,
+ struct ethtool_stats *stats, uint64_t *data);
+int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset);
+void lbs_mesh_ethtool_get_strings(struct net_device *dev,
+ uint32_t stringset, uint8_t *s);
+
+
#endif
--- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c
+++ linux-wl/drivers/net/wireless/libertas/persistcfg.c
@@ -880,3 +880,87 @@
sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
}
+
+
+
+/***************************************************************************
+ * Ethtool related
+ */
+
+static const char *mesh_stat_strings[] = {
+ "drop_duplicate_bcast",
+ "drop_ttl_zero",
+ "drop_no_fwd_route",
+ "drop_no_buffers",
+ "fwded_unicast_cnt",
+ "fwded_bcast_cnt",
+ "drop_blind_table",
+ "tx_failed_cnt"
+};
+
+void lbs_mesh_ethtool_get_stats(struct net_device *dev,
+ struct ethtool_stats *stats, uint64_t *data)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+
+ /* Get Mesh Statistics */
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
+
+ if (ret) {
+ memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
+ return;
+ }
+
+ priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
+ priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
+ priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
+ priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
+ priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
+ priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
+ priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
+ priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
+
+ data[0] = priv->mstats.fwd_drop_rbt;
+ data[1] = priv->mstats.fwd_drop_ttl;
+ data[2] = priv->mstats.fwd_drop_noroute;
+ data[3] = priv->mstats.fwd_drop_nobuf;
+ data[4] = priv->mstats.fwd_unicast_cnt;
+ data[5] = priv->mstats.fwd_bcast_cnt;
+ data[6] = priv->mstats.drop_blind;
+ data[7] = priv->mstats.tx_failed_cnt;
+
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+}
+
+int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+ struct lbs_private *priv = dev->ml_priv;
+
+ if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
+ return MESH_STATS_NUM;
+
+ return -EOPNOTSUPP;
+}
+
+void lbs_mesh_ethtool_get_strings(struct net_device *dev,
+ uint32_t stringset, uint8_t *s)
+{
+ int i;
+
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < MESH_STATS_NUM; i++) {
+ memcpy(s + i * ETH_GSTRING_LEN,
+ mesh_stat_strings[i],
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+}
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: rtl8187: kernel oops when leds enabled
From: Larry Finger @ 2009-10-26 15:50 UTC (permalink / raw)
To: Richard Farina; +Cc: linux-wireless
In-Reply-To: <4AE5BD6C.2050303@gmail.com>
On 10/26/2009 10:17 AM, Richard Farina wrote:
> I'm honestly a little surprised that no one has bothered to reproduce
> this in the month since I reported it but maybe it is more unique to my
> setup than it seems.
Your machine seems to be unique in that it happens most of the time.
It took more than 10 tries, but I finally got my copy of the
wireless-testing kernel to oops.
I will be working on a patch.
Larry
^ permalink raw reply
* [PATCH] libertas: move mesh command handling away
From: Holger Schurig @ 2009-10-26 15:53 UTC (permalink / raw)
To: linux-wireless, Dan Williams, John Linville
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
--- linux-wl.orig/drivers/net/wireless/libertas/cmd.c
+++ linux-wl/drivers/net/wireless/libertas/cmd.c
@@ -3,7 +3,6 @@
* It prepares command and sends it to firmware when it is ready.
*/
-#include <net/lib80211.h>
#include <linux/kfifo.h>
#include <linux/sched.h>
@@ -697,173 +696,6 @@
return 0;
}
-static int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
- u16 cmd_action, void *pdata_buf)
-{
- struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
- lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
- cmd->command = cpu_to_le16(CMD_BT_ACCESS);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) +
- sizeof(struct cmd_header));
- cmd->result = 0;
- bt_access->action = cpu_to_le16(cmd_action);
-
- switch (cmd_action) {
- case CMD_ACT_BT_ACCESS_ADD:
- memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
- lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", bt_access->addr1, 6);
- break;
- case CMD_ACT_BT_ACCESS_DEL:
- memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
- lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", bt_access->addr1, 6);
- break;
- case CMD_ACT_BT_ACCESS_LIST:
- bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
- break;
- case CMD_ACT_BT_ACCESS_RESET:
- break;
- case CMD_ACT_BT_ACCESS_SET_INVERT:
- bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
- break;
- case CMD_ACT_BT_ACCESS_GET_INVERT:
- break;
- default:
- break;
- }
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
-static int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
- u16 cmd_action, void *pdata_buf)
-{
- struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
- lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
- cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) +
- sizeof(struct cmd_header));
- cmd->result = 0;
-
- if (pdata_buf)
- memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
- else
- memset(fwt_access, 0, sizeof(*fwt_access));
-
- fwt_access->action = cpu_to_le16(cmd_action);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
- struct cmd_ds_mesh_access *cmd)
-{
- int ret;
-
- lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
- cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
- cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
- cmd->hdr.result = 0;
-
- cmd->action = cpu_to_le16(cmd_action);
-
- ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-static int __lbs_mesh_config_send(struct lbs_private *priv,
- struct cmd_ds_mesh_config *cmd,
- uint16_t action, uint16_t type)
-{
- int ret;
- u16 command = CMD_MESH_CONFIG_OLD;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- /*
- * Command id is 0xac for v10 FW along with mesh interface
- * id in bits 14-13-12.
- */
- if (priv->mesh_fw_ver == MESH_FW_NEW)
- command = CMD_MESH_CONFIG |
- (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
-
- cmd->hdr.command = cpu_to_le16(command);
- cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
- cmd->hdr.result = 0;
-
- cmd->type = cpu_to_le16(type);
- cmd->action = cpu_to_le16(action);
-
- ret = lbs_cmd_with_response(priv, command, cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-int lbs_mesh_config_send(struct lbs_private *priv,
- struct cmd_ds_mesh_config *cmd,
- uint16_t action, uint16_t type)
-{
- int ret;
-
- if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
- return -EOPNOTSUPP;
-
- ret = __lbs_mesh_config_send(priv, cmd, action, type);
- return ret;
-}
-
-/* This function is the CMD_MESH_CONFIG legacy function. It only handles the
- * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG
- * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
- * lbs_mesh_config_send.
- */
-int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_meshie *ie;
- DECLARE_SSID_BUF(ssid);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.channel = cpu_to_le16(chan);
- ie = (struct mrvl_meshie *)cmd.data;
-
- switch (action) {
- case CMD_ACT_MESH_CONFIG_START:
- ie->id = WLAN_EID_GENERIC;
- ie->val.oui[0] = 0x00;
- ie->val.oui[1] = 0x50;
- ie->val.oui[2] = 0x43;
- ie->val.type = MARVELL_MESH_IE_TYPE;
- ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
- ie->val.version = MARVELL_MESH_IE_VERSION;
- ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
- ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
- ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
- ie->val.mesh_id_len = priv->mesh_ssid_len;
- memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
- ie->len = sizeof(struct mrvl_meshie_val) -
- IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
- break;
- case CMD_ACT_MESH_CONFIG_STOP:
- break;
- default:
- return -1;
- }
- lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
- action, priv->mesh_tlv, chan,
- print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
-
- return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
-}
-
static void lbs_queue_cmd(struct lbs_private *priv,
struct cmd_ctrl_node *cmdnode)
{
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.h
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -6,6 +6,7 @@
#include <net/iw_handler.h>
+#include <net/lib80211.h>
/* Mesh statistics */
@@ -42,6 +43,16 @@
struct net_device *dev, struct txpd *txpd);
+/* Command handling */
+
+struct cmd_ds_command;
+
+int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
+ u16 cmd_action, void *pdata_buf);
+int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
+ u16 cmd_action, void *pdata_buf);
+
+
/* Persistent configuration */
void lbs_persist_config_init(struct net_device *net);
--- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c
+++ linux-wl/drivers/net/wireless/libertas/persistcfg.c
@@ -441,6 +441,181 @@
/***************************************************************************
+ * Mesh command handling
+ */
+
+int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
+ u16 cmd_action, void *pdata_buf)
+{
+ struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
+ lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+ cmd->command = cpu_to_le16(CMD_BT_ACCESS);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) +
+ sizeof(struct cmd_header));
+ cmd->result = 0;
+ bt_access->action = cpu_to_le16(cmd_action);
+
+ switch (cmd_action) {
+ case CMD_ACT_BT_ACCESS_ADD:
+ memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
+ lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
+ bt_access->addr1, 6);
+ break;
+ case CMD_ACT_BT_ACCESS_DEL:
+ memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
+ lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
+ bt_access->addr1, 6);
+ break;
+ case CMD_ACT_BT_ACCESS_LIST:
+ bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
+ break;
+ case CMD_ACT_BT_ACCESS_RESET:
+ break;
+ case CMD_ACT_BT_ACCESS_SET_INVERT:
+ bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
+ break;
+ case CMD_ACT_BT_ACCESS_GET_INVERT:
+ break;
+ default:
+ break;
+ }
+ lbs_deb_leave(LBS_DEB_CMD);
+ return 0;
+}
+
+int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
+ u16 cmd_action, void *pdata_buf)
+{
+ struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
+ lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+ cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) +
+ sizeof(struct cmd_header));
+ cmd->result = 0;
+
+ if (pdata_buf)
+ memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
+ else
+ memset(fwt_access, 0, sizeof(*fwt_access));
+
+ fwt_access->action = cpu_to_le16(cmd_action);
+
+ lbs_deb_leave(LBS_DEB_CMD);
+ return 0;
+}
+
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+ struct cmd_ds_mesh_access *cmd)
+{
+ int ret;
+
+ lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+ cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
+ cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
+ cmd->hdr.result = 0;
+
+ cmd->action = cpu_to_le16(cmd_action);
+
+ ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
+
+ lbs_deb_leave(LBS_DEB_CMD);
+ return ret;
+}
+
+static int __lbs_mesh_config_send(struct lbs_private *priv,
+ struct cmd_ds_mesh_config *cmd,
+ uint16_t action, uint16_t type)
+{
+ int ret;
+ u16 command = CMD_MESH_CONFIG_OLD;
+
+ lbs_deb_enter(LBS_DEB_CMD);
+
+ /*
+ * Command id is 0xac for v10 FW along with mesh interface
+ * id in bits 14-13-12.
+ */
+ if (priv->mesh_fw_ver == MESH_FW_NEW)
+ command = CMD_MESH_CONFIG |
+ (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+ cmd->hdr.command = cpu_to_le16(command);
+ cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
+ cmd->hdr.result = 0;
+
+ cmd->type = cpu_to_le16(type);
+ cmd->action = cpu_to_le16(action);
+
+ ret = lbs_cmd_with_response(priv, command, cmd);
+
+ lbs_deb_leave(LBS_DEB_CMD);
+ return ret;
+}
+
+int lbs_mesh_config_send(struct lbs_private *priv,
+ struct cmd_ds_mesh_config *cmd,
+ uint16_t action, uint16_t type)
+{
+ int ret;
+
+ if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
+ return -EOPNOTSUPP;
+
+ ret = __lbs_mesh_config_send(priv, cmd, action, type);
+ return ret;
+}
+
+/* This function is the CMD_MESH_CONFIG legacy function. It only handles the
+ * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG
+ * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
+ * lbs_mesh_config_send.
+ */
+int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
+{
+ struct cmd_ds_mesh_config cmd;
+ struct mrvl_meshie *ie;
+ DECLARE_SSID_BUF(ssid);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.channel = cpu_to_le16(chan);
+ ie = (struct mrvl_meshie *)cmd.data;
+
+ switch (action) {
+ case CMD_ACT_MESH_CONFIG_START:
+ ie->id = WLAN_EID_GENERIC;
+ ie->val.oui[0] = 0x00;
+ ie->val.oui[1] = 0x50;
+ ie->val.oui[2] = 0x43;
+ ie->val.type = MARVELL_MESH_IE_TYPE;
+ ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
+ ie->val.version = MARVELL_MESH_IE_VERSION;
+ ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
+ ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
+ ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
+ ie->val.mesh_id_len = priv->mesh_ssid_len;
+ memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
+ ie->len = sizeof(struct mrvl_meshie_val) -
+ IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
+ break;
+ case CMD_ACT_MESH_CONFIG_STOP:
+ break;
+ default:
+ return -1;
+ }
+ lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
+ action, priv->mesh_tlv, chan,
+ print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
+
+ return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
+}
+
+
+
+/***************************************************************************
* Persistent configuration support
*/
--
http://www.holgerschurig.de
^ permalink raw reply
* [RFC] firmware_class: make request_firmware_nowait more useful
From: Johannes Berg @ 2009-10-26 16:12 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-wireless
Unfortunately, one cannot hold on to the struct firmware
that request_firmware_nowait() hands off, which is needed
in some cases. Allow this by requiring the callback to
free it (via release_firmware).
Additionally, give it a gfp_t parameter -- all the current
users call it from a GFP_KERNEL context so the GFP_ATOMIC
isn't necessary. This also marks an API break which is
useful in a sense, although that is obviously not the
primary purpose of this change.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
This is a prerequisite for many drivers' conversion to the firmware
loading scheme we talked about at the wireless summit. Due to
suspend/hibernate we need to keep a copy of the firmware loaded, but
because we cannot request_firmware() during probe() we want to use
_nowait() and then proceed registration (or unbind) on the callback.
drivers/base/firmware_class.c | 14 ++++++--------
drivers/firmware/dell_rbu.c | 9 +++++++--
drivers/serial/ucc_uart.c | 8 +++++---
drivers/staging/comedi/drivers/usbdux.c | 5 ++++-
drivers/staging/comedi/drivers/usbduxfast.c | 5 ++++-
drivers/usb/atm/ueagle-atm.c | 7 ++++---
include/linux/firmware.h | 5 +++--
7 files changed, 33 insertions(+), 20 deletions(-)
--- wireless-testing.orig/drivers/base/firmware_class.c 2009-10-26 16:45:18.000000000 +0100
+++ wireless-testing/drivers/base/firmware_class.c 2009-10-26 17:08:10.000000000 +0100
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg)
}
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->uevent);
- if (ret < 0)
- fw_work->cont(NULL, fw_work->context);
- else {
- fw_work->cont(fw, fw_work->context);
- release_firmware(fw);
- }
+
+ fw_work->cont(fw, fw_work->context);
+
module_put(fw_work->module);
kfree(fw_work);
return ret;
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg)
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
+ * @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg)
int
request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
struct task_struct *task;
struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
- GFP_ATOMIC);
+ gfp);
if (!fw_work)
return -ENOMEM;
--- wireless-testing.orig/include/linux/firmware.h 2009-10-26 16:45:53.000000000 +0100
+++ wireless-testing/include/linux/firmware.h 2009-10-26 17:03:56.000000000 +0100
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/compiler.h>
+#include <linux/gfp.h>
#define FW_ACTION_NOHOTPLUG 0
#define FW_ACTION_HOTPLUG 1
@@ -38,7 +39,7 @@ int request_firmware(const struct firmwa
struct device *device);
int request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context));
void release_firmware(const struct firmware *fw);
@@ -51,7 +52,7 @@ static inline int request_firmware(const
}
static inline int request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
return -EINVAL;
--- wireless-testing.orig/drivers/firmware/dell_rbu.c 2009-10-26 16:49:06.000000000 +0100
+++ wireless-testing/drivers/firmware/dell_rbu.c 2009-10-26 16:49:52.000000000 +0100
@@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct
{
rbu_data.entry_created = 0;
- if (!fw || !fw->size)
+ if (!fw)
return;
+ if (!fw->size)
+ goto out;
+
spin_lock(&rbu_data.lock);
if (!strcmp(image_type, "mono")) {
if (!img_update_realloc(fw->size))
@@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct
} else
pr_debug("invalid image type specified.\n");
spin_unlock(&rbu_data.lock);
+ out:
+ release_firmware(fw);
}
static ssize_t read_rbu_image_type(struct kobject *kobj,
@@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(stru
spin_unlock(&rbu_data.lock);
req_firm_rc = request_firmware_nowait(THIS_MODULE,
FW_ACTION_NOHOTPLUG, "dell_rbu",
- &rbu_device->dev, &context,
+ &rbu_device->dev, GFP_KERNEL, &context,
callbackfn_rbu);
if (req_firm_rc) {
printk(KERN_ERR
--- wireless-testing.orig/drivers/serial/ucc_uart.c 2009-10-26 16:50:04.000000000 +0100
+++ wireless-testing/drivers/serial/ucc_uart.c 2009-10-26 16:51:10.000000000 +0100
@@ -1179,16 +1179,18 @@ static void uart_firmware_cont(const str
if (firmware->header.length != fw->size) {
dev_err(dev, "invalid firmware\n");
- return;
+ goto out;
}
ret = qe_upload_firmware(firmware);
if (ret) {
dev_err(dev, "could not load firmware\n");
- return;
+ goto out;
}
firmware_loaded = 1;
+ out:
+ release_firmware(fw);
}
static int ucc_uart_probe(struct of_device *ofdev,
@@ -1247,7 +1249,7 @@ static int ucc_uart_probe(struct of_devi
*/
ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG, filename, &ofdev->dev,
- &ofdev->dev, uart_firmware_cont);
+ GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
if (ret) {
dev_err(&ofdev->dev,
"could not load firmware %s\n",
--- wireless-testing.orig/drivers/staging/comedi/drivers/usbdux.c 2009-10-26 16:51:16.000000000 +0100
+++ wireless-testing/drivers/staging/comedi/drivers/usbdux.c 2009-10-26 16:51:52.000000000 +0100
@@ -2327,9 +2327,11 @@ static void usbdux_firmware_request_comp
if (ret) {
dev_err(&usbdev->dev,
"Could not upload firmware (err=%d)\n", ret);
- return;
+ goto out;
}
comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+ release_firmware(fw);
}
/* allocate memory for the urbs and initialise them */
@@ -2580,6 +2582,7 @@ static int usbduxsub_probe(struct usb_in
FW_ACTION_HOTPLUG,
"usbdux_firmware.bin",
&udev->dev,
+ GFP_KERNEL,
usbduxsub + index,
usbdux_firmware_request_complete_handler);
--- wireless-testing.orig/drivers/staging/comedi/drivers/usbduxfast.c 2009-10-26 17:01:20.000000000 +0100
+++ wireless-testing/drivers/staging/comedi/drivers/usbduxfast.c 2009-10-26 17:01:47.000000000 +0100
@@ -1451,10 +1451,12 @@ static void usbduxfast_firmware_request_
if (ret) {
dev_err(&usbdev->dev,
"Could not upload firmware (err=%d)\n", ret);
- return;
+ goto out;
}
comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+ release_firmware(fw);
}
/*
@@ -1569,6 +1571,7 @@ static int usbduxfastsub_probe(struct us
FW_ACTION_HOTPLUG,
"usbduxfast_firmware.bin",
&udev->dev,
+ GFP_KERNEL,
usbduxfastsub + index,
usbduxfast_firmware_request_complete_handler);
--- wireless-testing.orig/drivers/usb/atm/ueagle-atm.c 2009-10-26 17:01:48.000000000 +0100
+++ wireless-testing/drivers/usb/atm/ueagle-atm.c 2009-10-26 17:03:29.000000000 +0100
@@ -667,12 +667,12 @@ static void uea_upload_pre_firmware(cons
else
uea_info(usb, "firmware uploaded\n");
- uea_leaves(usb);
- return;
+ goto err;
err_fw_corrupted:
uea_err(usb, "firmware is corrupted\n");
err:
+ release_firmware(fw_entry);
uea_leaves(usb);
}
@@ -705,7 +705,8 @@ static int uea_load_firmware(struct usb_
break;
}
- ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+ GFP_KERNEL, usb, uea_upload_pre_firmware);
if (ret)
uea_err(usb, "firmware %s is not available\n", fw_name);
else
^ permalink raw reply
* Re: [PATCH 2/4] ath9k_hw: distinguish single-chip solutions on initial probe print
From: Kalle Valo @ 2009-10-26 16:14 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linville, linux-wireless, ath9k-devel
In-Reply-To: <1256567941-26859-3-git-send-email-lrodriguez@atheros.com>
"Luis R. Rodriguez" <lrodriguez@atheros.com> writes:
> Devices with external radios have revisions which we can count on.
> On single chip solutions these EEPROM values for these radio revision
> also exist but are not meaningful as the radios are embedded onto the
> same chip. Each single-chip device evolves together as one device.
>
> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> ---
> drivers/net/wireless/ath/ath9k/ahb.c | 11 ++++-------
> drivers/net/wireless/ath/ath9k/hw.c | 27 +++++++++++++++++++++++----
> drivers/net/wireless/ath/ath9k/hw.h | 3 +--
> drivers/net/wireless/ath/ath9k/pci.c | 11 ++++-------
> 4 files changed, 32 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
> index 41422c4..925818c 100644
> --- a/drivers/net/wireless/ath/ath9k/ahb.c
> +++ b/drivers/net/wireless/ath/ath9k/ahb.c
> @@ -69,6 +69,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
> int irq;
> int ret = 0;
> struct ath_hw *ah;
> + char hw_name[1024];
This is a bit too large to allocate from stack IMHO.
[...]
> --- a/drivers/net/wireless/ath/ath9k/pci.c
> +++ b/drivers/net/wireless/ath/ath9k/pci.c
> @@ -114,6 +114,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> u32 val;
> int ret = 0;
> struct ath_hw *ah;
> + char hw_name[1024];
Ditto.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH 2/4] ath9k_hw: distinguish single-chip solutions on initial probe print
From: Luis R. Rodriguez @ 2009-10-26 16:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: linville, linux-wireless, ath9k-devel
In-Reply-To: <87hbtmgmj6.fsf@purkki.valot.fi>
On Mon, Oct 26, 2009 at 9:14 AM, Kalle Valo <kalle.valo@iki.fi> wrote:
> "Luis R. Rodriguez" <lrodriguez@atheros.com> writes:
>
>> Devices with external radios have revisions which we can count on.
>> On single chip solutions these EEPROM values for these radio revision
>> also exist but are not meaningful as the radios are embedded onto the
>> same chip. Each single-chip device evolves together as one device.
>>
>> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
>> ---
>> drivers/net/wireless/ath/ath9k/ahb.c | 11 ++++-------
>> drivers/net/wireless/ath/ath9k/hw.c | 27 +++++++++++++++++++++++----
>> drivers/net/wireless/ath/ath9k/hw.h | 3 +--
>> drivers/net/wireless/ath/ath9k/pci.c | 11 ++++-------
>> 4 files changed, 32 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
>> index 41422c4..925818c 100644
>> --- a/drivers/net/wireless/ath/ath9k/ahb.c
>> +++ b/drivers/net/wireless/ath/ath9k/ahb.c
>> @@ -69,6 +69,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
>> int irq;
>> int ret = 0;
>> struct ath_hw *ah;
>> + char hw_name[1024];
>
> This is a bit too large to allocate from stack IMHO.
>
>
> [...]
>
>> --- a/drivers/net/wireless/ath/ath9k/pci.c
>> +++ b/drivers/net/wireless/ath/ath9k/pci.c
>> @@ -114,6 +114,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> u32 val;
>> int ret = 0;
>> struct ath_hw *ah;
>> + char hw_name[1024];
>
> Ditto.
We use this for debugfs, so I went with that as an upper limit, given
that we just use it a probe it seemed sane.
Luis
^ permalink raw reply
* Re: iwl3945, after a while stops working with "No space for Tx"
From: reinette chatre @ 2009-10-26 16:25 UTC (permalink / raw)
To: Frederik Nosi
Cc: Zhu, Yi, Intel Linux Wireless, John W. Linville, Winkler, Tomas,
Kolekar, Abhijeet, linux-wireless@vger.kernel.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <177253.23325.qm@web53903.mail.re2.yahoo.com>
On Sat, 2009-10-24 at 06:44 -0700, Frederik Nosi wrote:
> Hi,
> first sorry if somebody is not the right contact, got the adressess from ./scripts/get_maintainer.pl -f drivers/net/wireless/iwlwifi.
> From some kernel versions now, after some time that im using this card it stops working and on messages i get this errors:
>
> Oct 24 14:38:24 kotys NetworkManager: <info> Activation (wlan0) Stage 5 of 5 (IP Configure Commit) complete.
> [snip pulseaudio's stuppid log spam warning]
> Oct 24 14:40:07 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:09 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
> Oct 24 14:40:10 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
> Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending POWER_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: set power fail, ret = -110
> Oct 24 14:40:14 kotys kernel: No probe response from AP 00:1c:df:82:63:c9 after 500ms, disconnecting.
> Oct 24 14:40:14 kotys NetworkManager: <info> (wlan0): supplicant connection state: completed -> disconnected
> Oct 24 14:40:14 kotys NetworkManager: <info> (wlan0): supplicant connection state: disconnected -> scanning
> Oct 24 14:40:14 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 1)
> Oct 24 14:40:15 kotys NetworkManager: <info> (wlan0): supplicant connection state: scanning -> associating
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 2)
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 3)
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 timed out
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
>
>
> When this happens i am able to use the card only after reloading the related modules, iwl3945 ecc. But the problem happens again after some minutes that im connected.
>
> Kernel is 2.6.32-rc5 but his started happening around 2.6.31, not sure exactly what version as i update kernel often. Firmware is iwl3945-ucode-15.32.2.9.
>
> Every other info that you need just ask. I hope i dont have to bisect as this is the laptop i use for work too, but if it's needed i'll do.
>
> I'm not subscribed on any ML, so in case please cc me.
>
We currently have a bug open for this issue. Could you please add this
information to
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1944 ?
Thank you
Reinette
^ permalink raw reply
* Re: [PATCH 2/4] ath9k_hw: distinguish single-chip solutions on initial probe print
From: Michael Buesch @ 2009-10-26 16:29 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Kalle Valo, linville, linux-wireless, ath9k-devel
In-Reply-To: <43e72e890910260921h91c4cb5u5a2fc81e73377055@mail.gmail.com>
On Monday 26 October 2009 17:21:40 Luis R. Rodriguez wrote:
> >> --- a/drivers/net/wireless/ath/ath9k/pci.c
> >> +++ b/drivers/net/wireless/ath/ath9k/pci.c
> >> @@ -114,6 +114,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> >> u32 val;
> >> int ret = 0;
> >> struct ath_hw *ah;
> >> + char hw_name[1024];
> >
> > Ditto.
>
> We use this for debugfs, so I went with that as an upper limit, given
> that we just use it a probe it seemed sane.
I think it's completely insane, because you effectively use 25% of the available stack.
Why is a hardware name 1024 chars (max) long anyway?
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I would be pissed off after reading the first line already ;)
--
Greetings, Michael.
^ permalink raw reply
* [RFC] libertas: minimal WEXT handler for MESH
From: Holger Schurig @ 2009-10-26 16:29 UTC (permalink / raw)
To: linux-wireless, Dan Williams, Johannes Berg
Here I moved some WEXT related for the mesh interface from wext.c
into the upcoming "mesh.c". Near the very end of this patch you
see the new iw_handler definition.
For many handlers, I simply put NULL there, but I guess
that I should do this:
a) register mesh_dev with cfg80211 as well
b) use the handlers from compat-wext.c instead
Is this right? And I guess that I connot do b) without a)
Or is it ok to do b) without a). Would then cfg80211 than always
calls into the priv->dev (for the station's struct net_device *).
I'm puzzled.
I guess that this patch --- as it is --- will leave you with a broken
mesh implementation. Or with a partially broken one, e.g. where you
can define mesh-SSID, but you cannot reduce the TX power. Not sure if
that is what we want ---- or in other words, not sure if the mesh-WEXT
handler really only needs 4 or so handler functions.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
--- linux-wl.orig/drivers/net/wireless/libertas/wext.c
+++ linux-wl/drivers/net/wireless/libertas/wext.c
@@ -104,45 +104,6 @@
}
/**
- * @brief Find the channel frequency power info with specific channel
- *
- * @param priv A pointer to struct lbs_private structure
- * @param band it can be BAND_A, BAND_G or BAND_B
- * @param channel the channel for looking
- * @return A pointer to struct chan_freq_power structure or NULL if not find.
- */
-struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
- struct lbs_private *priv,
- u8 band,
- u16 channel)
-{
- struct chan_freq_power *cfp = NULL;
- struct region_channel *rc;
- int i, j;
-
- for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
- rc = &priv->region_channel[j];
-
- if (!rc->valid || !rc->CFP)
- continue;
- if (rc->band != band)
- continue;
- for (i = 0; i < rc->nrcfp; i++) {
- if (rc->CFP[i].channel == channel) {
- cfp = &rc->CFP[i];
- break;
- }
- }
- }
-
- if (!cfp && channel)
- lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find "
- "cfp by band %d / channel %d\n", band, channel);
-
- return cfp;
-}
-
-/**
* @brief Find the channel frequency power info with specific frequency
*
* @param priv A pointer to struct lbs_private structure
@@ -213,7 +174,7 @@
return 0;
}
-static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
+int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
struct lbs_private *priv = dev->ml_priv;
@@ -422,18 +383,6 @@
return 0;
}
-static int mesh_wlan_get_mode(struct net_device *dev,
- struct iw_request_info *info, u32 * uwrq,
- char *extra)
-{
- lbs_deb_enter(LBS_DEB_WEXT);
-
- *uwrq = IW_MODE_REPEAT;
-
- lbs_deb_leave(LBS_DEB_WEXT);
- return 0;
-}
-
static int lbs_get_txpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
@@ -838,7 +787,7 @@
return 0;
}
-static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
+struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
{
enum {
POOR = 30,
@@ -1010,58 +959,6 @@
return ret;
}
-static int lbs_mesh_set_freq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *fwrq, char *extra)
-{
- struct lbs_private *priv = dev->ml_priv;
- struct chan_freq_power *cfp;
- int ret = -EINVAL;
-
- lbs_deb_enter(LBS_DEB_WEXT);
-
- /* If setting by frequency, convert to a channel */
- if (fwrq->e == 1) {
- long f = fwrq->m / 100000;
-
- cfp = find_cfp_by_band_and_freq(priv, 0, f);
- if (!cfp) {
- lbs_deb_wext("invalid freq %ld\n", f);
- goto out;
- }
-
- fwrq->e = 0;
- fwrq->m = (int) cfp->channel;
- }
-
- /* Setting by channel number */
- if (fwrq->m > 1000 || fwrq->e > 0) {
- goto out;
- }
-
- cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
- if (!cfp) {
- goto out;
- }
-
- if (fwrq->m != priv->channel) {
- lbs_deb_wext("mesh channel change forces eth disconnect\n");
- if (priv->mode == IW_MODE_INFRA)
- lbs_cmd_80211_deauthenticate(priv,
- priv->curbssparams.bssid,
- WLAN_REASON_DEAUTH_LEAVING);
- else if (priv->mode == IW_MODE_ADHOC)
- lbs_adhoc_stop(priv);
- }
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
- lbs_update_channel(priv);
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
- return ret;
-}
-
static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
@@ -2110,60 +2007,6 @@
return ret;
}
-static int lbs_mesh_get_essid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq, char *extra)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_WEXT);
-
- memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
-
- dwrq->length = priv->mesh_ssid_len;
-
- dwrq->flags = 1; /* active */
-
- lbs_deb_leave(LBS_DEB_WEXT);
- return 0;
-}
-
-static int lbs_mesh_set_essid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq, char *extra)
-{
- struct lbs_private *priv = dev->ml_priv;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_WEXT);
-
- if (!priv->radio_on) {
- ret = -EINVAL;
- goto out;
- }
-
- /* Check the size of the string */
- if (dwrq->length > IEEE80211_MAX_SSID_LEN) {
- ret = -E2BIG;
- goto out;
- }
-
- if (!dwrq->flags || !dwrq->length) {
- ret = -EINVAL;
- goto out;
- } else {
- /* Specific SSID requested */
- memcpy(priv->mesh_ssid, extra, dwrq->length);
- priv->mesh_ssid_len = dwrq->length;
- }
-
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel);
- out:
- lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
- return ret;
-}
-
/**
* @brief Connect to the AP or Ad-hoc Network with specific bssid
*
@@ -2270,71 +2113,8 @@
(iw_handler) NULL, /* SIOCSIWPMKSA */
};
-static const iw_handler mesh_wlan_handler[] = {
- (iw_handler) NULL, /* SIOCSIWCOMMIT */
- (iw_handler) lbs_get_name, /* SIOCGIWNAME */
- (iw_handler) NULL, /* SIOCSIWNWID */
- (iw_handler) NULL, /* SIOCGIWNWID */
- (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
- (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */
- (iw_handler) NULL, /* SIOCSIWMODE */
- (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */
- (iw_handler) NULL, /* SIOCSIWSENS */
- (iw_handler) NULL, /* SIOCGIWSENS */
- (iw_handler) NULL, /* SIOCSIWRANGE */
- (iw_handler) lbs_get_range, /* SIOCGIWRANGE */
- (iw_handler) NULL, /* SIOCSIWPRIV */
- (iw_handler) NULL, /* SIOCGIWPRIV */
- (iw_handler) NULL, /* SIOCSIWSTATS */
- (iw_handler) NULL, /* SIOCGIWSTATS */
- iw_handler_set_spy, /* SIOCSIWSPY */
- iw_handler_get_spy, /* SIOCGIWSPY */
- iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
- iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
- (iw_handler) NULL, /* SIOCSIWAP */
- (iw_handler) NULL, /* SIOCGIWAP */
- (iw_handler) NULL, /* SIOCSIWMLME */
- (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
- (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */
- (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */
- (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
- (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
- (iw_handler) NULL, /* SIOCSIWNICKN */
- (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) lbs_set_rate, /* SIOCSIWRATE */
- (iw_handler) lbs_get_rate, /* SIOCGIWRATE */
- (iw_handler) lbs_set_rts, /* SIOCSIWRTS */
- (iw_handler) lbs_get_rts, /* SIOCGIWRTS */
- (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */
- (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */
- (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */
- (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */
- (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */
- (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */
- (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */
- (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */
- (iw_handler) lbs_set_power, /* SIOCSIWPOWER */
- (iw_handler) lbs_get_power, /* SIOCGIWPOWER */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */
- (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */
- (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */
- (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */
- (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
- (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
- (iw_handler) NULL, /* SIOCSIWPMKSA */
-};
struct iw_handler_def lbs_handler_def = {
.num_standard = ARRAY_SIZE(lbs_handler),
.standard = (iw_handler *) lbs_handler,
.get_wireless_stats = lbs_get_wireless_stats,
};
-
-struct iw_handler_def mesh_handler_def = {
- .num_standard = ARRAY_SIZE(mesh_wlan_handler),
- .standard = (iw_handler *) mesh_wlan_handler,
- .get_wireless_stats = lbs_get_wireless_stats,
-};
--- linux-wl.orig/drivers/net/wireless/libertas/wext.h
+++ linux-wl/drivers/net/wireless/libertas/wext.h
@@ -4,6 +4,14 @@
#ifndef _LBS_WEXT_H_
#define _LBS_WEXT_H_
+
+struct lbs_private;
+struct net_device;
+struct iw_request_info;
+struct iw_freq;
+struct iw_statistics;
+
+
void lbs_send_disconnect_notification(struct lbs_private *priv);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
@@ -14,4 +22,9 @@
extern struct iw_handler_def lbs_handler_def;
+int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
+ struct iw_freq *fwrq, char *extra);
+struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev);
+
+
#endif
--- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c
+++ linux-wl/drivers/net/wireless/libertas/persistcfg.c
@@ -9,6 +9,7 @@
#include "mesh.h"
#include "decl.h"
#include "cmd.h"
+#include "wext.h"
/***************************************************************************
@@ -1059,6 +1060,294 @@
/***************************************************************************
+ * WEXT related
+ */
+
+/**
+ * @brief Find the channel frequency power info with specific frequency
+ *
+ * @param priv A pointer to struct lbs_private structure
+ * @param band it can be BAND_A, BAND_G or BAND_B
+ * @param freq the frequency for looking
+ * @return A pointer to struct chan_freq_power structure or NULL if not find.
+ */
+static struct chan_freq_power *find_cfp_by_band_and_freq(
+ struct lbs_private *priv,
+ u8 band,
+ u32 freq)
+{
+ struct chan_freq_power *cfp = NULL;
+ struct region_channel *rc;
+ int i, j;
+
+ for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+ rc = &priv->region_channel[j];
+
+ if (!rc->valid || !rc->CFP)
+ continue;
+ if (rc->band != band)
+ continue;
+ for (i = 0; i < rc->nrcfp; i++) {
+ if (rc->CFP[i].freq == freq) {
+ cfp = &rc->CFP[i];
+ break;
+ }
+ }
+ }
+
+ if (!cfp && freq)
+ lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by "
+ "band %d / freq %d\n", band, freq);
+
+ return cfp;
+}
+
+/**
+ * @brief Find the channel frequency power info with specific channel
+ *
+ * @param priv A pointer to struct lbs_private structure
+ * @param band it can be BAND_A, BAND_G or BAND_B
+ * @param channel the channel for looking
+ * @return A pointer to struct chan_freq_power structure or NULL if not find.
+ */
+struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
+ struct lbs_private *priv,
+ u8 band,
+ u16 channel)
+{
+ struct chan_freq_power *cfp = NULL;
+ struct region_channel *rc;
+ int i, j;
+
+ for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+ rc = &priv->region_channel[j];
+
+ if (!rc->valid || !rc->CFP)
+ continue;
+ if (rc->band != band)
+ continue;
+ for (i = 0; i < rc->nrcfp; i++) {
+ if (rc->CFP[i].channel == channel) {
+ cfp = &rc->CFP[i];
+ break;
+ }
+ }
+ }
+
+ if (!cfp && channel)
+ lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find "
+ "cfp by band %d / channel %d\n", band, channel);
+
+ return cfp;
+}
+
+static int lbs_mesh_set_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *fwrq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ struct chan_freq_power *cfp;
+ int ret = -EINVAL;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ /* If setting by frequency, convert to a channel */
+ if (fwrq->e == 1) {
+ long f = fwrq->m / 100000;
+
+ cfp = find_cfp_by_band_and_freq(priv, 0, f);
+ if (!cfp) {
+ lbs_deb_wext("invalid freq %ld\n", f);
+ goto out;
+ }
+
+ fwrq->e = 0;
+ fwrq->m = (int) cfp->channel;
+ }
+
+ /* Setting by channel number */
+ if (fwrq->m > 1000 || fwrq->e > 0)
+ goto out;
+
+ cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
+ if (!cfp)
+ goto out;
+
+ if (fwrq->m != priv->channel) {
+ lbs_deb_wext("mesh channel change forces eth disconnect\n");
+ if (priv->mode == IW_MODE_INFRA)
+ lbs_cmd_80211_deauthenticate(priv,
+ priv->curbssparams.bssid,
+ WLAN_REASON_DEAUTH_LEAVING);
+ else if (priv->mode == IW_MODE_ADHOC)
+ lbs_adhoc_stop(priv);
+ }
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
+ lbs_update_channel(priv);
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+}
+
+static int mesh_wlan_get_mode(struct net_device *dev,
+ struct iw_request_info *info, u32 * uwrq,
+ char *extra)
+{
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ *uwrq = IW_MODE_REPEAT;
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return 0;
+}
+
+static int lbs_mesh_set_essid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ if (!priv->radio_on) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Check the size of the string */
+ if (dwrq->length > IEEE80211_MAX_SSID_LEN) {
+ ret = -E2BIG;
+ goto out;
+ }
+
+ if (!dwrq->flags || !dwrq->length) {
+ ret = -EINVAL;
+ goto out;
+ } else {
+ /* Specific SSID requested */
+ memcpy(priv->mesh_ssid, extra, dwrq->length);
+ priv->mesh_ssid_len = dwrq->length;
+ }
+
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->channel);
+ out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+}
+
+static int lbs_mesh_get_essid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
+
+ dwrq->length = priv->mesh_ssid_len;
+
+ dwrq->flags = 1; /* active */
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return 0;
+}
+
+
+static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ /* Use nickname to indicate that mesh is on */
+
+ if (priv->mesh_connect_status == LBS_CONNECTED) {
+ strncpy(extra, "Mesh", 12);
+ extra[12] = '\0';
+ dwrq->length = strlen(extra);
+ }
+
+ else {
+ extra[0] = '\0';
+ dwrq->length = 0;
+ }
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return 0;
+}
+
+
+static const iw_handler mesh_wlan_handler[] = {
+ (iw_handler) NULL, /* SIOCSIWCOMMIT */
+ (iw_handler) NULL, /* SIOCGIWNAME, was lbs_get_name */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
+ (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */
+ (iw_handler) NULL, /* SIOCSIWMODE */
+ (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* SIOCSIWRANGE */
+ (iw_handler) NULL, /* SIOCGIWRANGE, was lbs_get_range */
+ (iw_handler) NULL, /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* SIOCGIWSTATS */
+ iw_handler_set_spy, /* SIOCSIWSPY */
+ iw_handler_get_spy, /* SIOCGIWSPY */
+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
+ (iw_handler) NULL, /* SIOCSIWAP */
+ (iw_handler) NULL, /* SIOCGIWAP */
+ (iw_handler) NULL, /* SIOCSIWMLME */
+ (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
+ (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */
+ (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */
+ (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
+ (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWRATE, was lbs_set_rate */
+ (iw_handler) NULL, /* SIOCGIWRATE, was lbs_get_rate */
+ (iw_handler) NULL, /* SIOCSIWRTS, was lbs_set_rts */
+ (iw_handler) NULL, /* SIOCGIWRTS, was lbs_get_rts */
+ (iw_handler) NULL, /* SIOCSIWFRAG, was lbs_set_frag */
+ (iw_handler) NULL, /* SIOCGIWFRAG, was lbs_get_frag */
+ (iw_handler) NULL, /* SIOCSIWTXPOW, was lbs_set_txpow */
+ (iw_handler) NULL, /* SIOCGIWTXPOW, was lbs_get_txpow */
+ (iw_handler) NULL, /* SIOCSIWRETRY, was lbs_set_retry */
+ (iw_handler) NULL, /* SIOCGIWRETRY, was lbs_get_retry */
+ (iw_handler) NULL, /* SIOCSIWENCODE, was lbs_set_encode */
+ (iw_handler) NULL, /* SIOCGIWENCODE, was lbs_get_encode */
+ (iw_handler) NULL, /* SIOCSIWPOWER, was lbs_set_power */
+ (iw_handler) NULL, /* SIOCGIWPOWER, was lbs_get_power */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWGENIE, was lbs_set_genie */
+ (iw_handler) NULL, /* SIOCGIWGENIE, lbs_get_genie */
+ (iw_handler) NULL, /* SIOCSIWAUTH, lbs_set_auth */
+ (iw_handler) NULL, /* SIOCGIWAUTH, lbs_get_auth */
+ (iw_handler) NULL, /* SIOCSIWENCODEEXT, was lbs_set_encodeext */
+ (iw_handler) NULL, /* SIOCGIWENCODEEXT, was lbs_get_encodeext */
+ (iw_handler) NULL, /* SIOCSIWPMKSA */
+};
+struct iw_handler_def mesh_handler_def = {
+ .num_standard = ARRAY_SIZE(mesh_wlan_handler),
+ .standard = (iw_handler *) mesh_wlan_handler,
+ .get_wireless_stats = lbs_get_wireless_stats,
+};
+
+
+/***************************************************************************
* Ethtool related
*/
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: [RFC] libertas: minimal WEXT handler for MESH
From: Johannes Berg @ 2009-10-26 16:35 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-wireless, Dan Williams
In-Reply-To: <200910261729.36583.hs4233@mail.mn-solutions.de>
[-- Attachment #1: Type: text/plain, Size: 411 bytes --]
On Mon, 2009-10-26 at 17:29 +0100, Holger Schurig wrote:
> For many handlers, I simply put NULL there, but I guess
> that I should do this:
>
> a) register mesh_dev with cfg80211 as well
> b) use the handlers from compat-wext.c instead
>
> Is this right? And I guess that I connot do b) without a)
>
> Or is it ok to do b) without a).
No, it's not, it'll most certainly segfault.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox