* Re: [PATCH 3/4] myri10ge - Driver core
From: Brice Goglin @ 2006-05-19 15:48 UTC (permalink / raw)
To: Andi Kleen; +Cc: Arnd Bergmann, netdev, gallatin, linux-kernel
In-Reply-To: <200605191309.30992.ak@suse.de>
Andi Kleen wrote:
> On Friday 19 May 2006 12:00, Arnd Bergmann wrote:
>
>> On Friday 19 May 2006 04:25, Brice Goglin wrote:
>>
>>> dev_mc_upload() from net/core/dev_mcast.c does
>>>
>>> spin_lock_bh(&dev->xmit_lock);
>>> __dev_mc_upload(dev);
>>>
>>> which calls dev->set_multicast_list(), which is
>>> myri10ge_set_multicast_list()
>>>
>>> which calls myri10ge_change_promisc
>>>
>>> which calls myri10ge_send_cmd
>>>
>> Hmm, if that is the only path where you call it, it may be
>> helpful to change myri10ge_change_promisc to call a special
>> atomic version of myri10ge_send_cmd then, while all others
>> use the regular version, which you can then convert to
>> do msleep as well.
>>
>
> Or just drop the xmit lock while you do that. As long as you
> handle races with ->start_xmit yourself it's ok
>
Looks like we can do that.
Thanks,
Brice
^ permalink raw reply
* [patch 00/10] [RFT] bcm43xx: support for PCI-E devices
From: Stefano Brivio @ 2006-05-19 15:44 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II
Can somebody with a bcm4311 or bcm4312 board please test this. This
patchset adds support for PCI-E devices and includes as well some minor
fixes to powercontrol, wireless core management, PCI core management.
--
Ciao
Stefano
^ permalink raw reply
* [patch 01/10] [RFT] bcm43xx: add core ID for PCI-E core
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_core_id.diff --]
[-- Type: text/plain, Size: 614 bytes --]
Add core ID for PCI-E core.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -202,6 +202,7 @@
#define BCM43xx_COREID_USB20_HOST 0x819
#define BCM43xx_COREID_USB20_DEV 0x81a
#define BCM43xx_COREID_SDIO_HOST 0x81b
+#define BCM43xx_COREID_PCIE 0x820
/* Core Information Registers */
#define BCM43xx_CIR_BASE 0xf00
--
Ciao
Stefano
^ permalink raw reply
* [patch 02/10] [RFT] bcm43xx: functions for access to PCI-E registers and PCI-E MDIO
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_core_rw.diff --]
[-- Type: text/plain, Size: 2778 bytes --]
Add read and write functions for PCI-E registers
Add write function for MDIO slaves.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2973,6 +2973,45 @@ out:
return err;
}
+static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
+{
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
+ return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
+}
+
+static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
+ u32 data)
+{
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
+}
+
+static int bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
+ u16 data)
+{
+ int i;
+
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
+ BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
+ (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
+ data);
+ udelay(10);
+
+ for (i = 0; i < 10; i++) {
+ if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
+ BCM43xx_PCIE_MDIO_TC)
+ return 0;
+ udelay(1000);
+ }
+ if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
+ BCM43xx_PCIE_MDIO_TC)
+ return 0;
+
+ printk(KERN_ERR PFX "Error: MDIO transaction failed\n");
+ return -EIO;
+}
+
/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
* To enable core 0, pass a core_mask of 1<<0
*/
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -154,6 +154,24 @@
#define BCM43xx_SBTOPCI2_PREFETCH 0x4
#define BCM43xx_SBTOPCI2_BURST 0x8
+/* PCI-E core registers. */
+#define BCM43xx_PCIECORE_REG_ADDR 0x0130
+#define BCM43xx_PCIECORE_REG_DATA 0x0134
+#define BCM43xx_PCIECORE_MDIO_CTL 0x0128
+#define BCM43xx_PCIECORE_MDIO_DATA 0x012C
+
+/* PCI-E registers. */
+#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004
+#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100
+
+/* PCI-E MDIO bits. */
+#define BCM43xx_PCIE_MDIO_ST 0x40000000
+#define BCM43xx_PCIE_MDIO_WT 0x10000000
+#define BCM43xx_PCIE_MDIO_DEV 22
+#define BCM43xx_PCIE_MDIO_REG 18
+#define BCM43xx_PCIE_MDIO_TA 0x00020000
+#define BCM43xx_PCIE_MDIO_TC 0x0100
+
/* Chipcommon capabilities. */
#define BCM43xx_CAPABILITIES_PCTL 0x00040000
#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
--
Ciao
Stefano
^ permalink raw reply
* [patch 03/10] [RFT] bcm43xx: fix reading core ID and revision from sb_id_hi
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-find_core_id.diff --]
[-- Type: text/plain, Size: 846 bytes --]
Fix reading core ID and revision from sb_id_hi.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2565,8 +2565,8 @@ static int bcm43xx_probe_cores(struct bc
/* fetch sb_id_hi from core information registers */
sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
- core_id = (sb_id_hi & 0xFFF0) >> 4;
- core_rev = (sb_id_hi & 0xF);
+ core_id = (sb_id_hi & 0x8FF0) >> 4;
+ core_rev = (sb_id_hi & 0x7000) >> 8 | (sb_id_hi & 0xF);
core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
/* if present, chipcommon is always core 0; read the chipid from it */
--
Ciao
Stefano
^ permalink raw reply
* [patch 04/10] [RFT] bcm43xx: use PCI-E core as a PCI core, allow wireless core with rev 10
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_core_probe.diff --]
[-- Type: text/plain, Size: 905 bytes --]
Allow for PCI-E core to be considered as PCI core. Allow revision 10 of
wireless core.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2676,6 +2676,7 @@ static int bcm43xx_probe_cores(struct bc
core = NULL;
switch (core_id) {
case BCM43xx_COREID_PCI:
+ case BCM43xx_COREID_PCIE:
core = &bcm->core_pci;
if (core->available) {
printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
@@ -2714,6 +2715,7 @@ static int bcm43xx_probe_cores(struct bc
case 6:
case 7:
case 9:
+ case 10:
break;
default:
printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
--
Ciao
Stefano
^ permalink raw reply
* [patch 05/10] [RFT] bcm43xx: wireless core initialization for PCI-E devices
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-80211init.diff --]
[-- Type: text/plain, Size: 1068 bytes --]
Fix wireless core initialization in order to work with PCI-E devices.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2832,16 +2832,11 @@ static int bcm43xx_wireless_core_init(st
u32 sbimconfiglow;
u8 limit;
- if (bcm->chip_rev < 5) {
+ if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
- if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
- sbimconfiglow |= 0x32;
- else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
- sbimconfiglow |= 0x53;
- else
- assert(0);
+ sbimconfiglow |= 0x32;
bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
}
--
Ciao
Stefano
^ permalink raw reply
* [patch 06/10] [RFT] bcm43xx: fix bcm43xx_wireless_core_mark_inactive
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-80211core_inactive.diff --]
[-- Type: text/plain, Size: 734 bytes --]
Trivial change in specs related to bcm43xx_wireless_core_mark_inactive.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1431,7 +1431,6 @@ static int bcm43xx_wireless_core_mark_in
if (err)
goto out;
sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= ~0x20000000;
sbtmstatelow |= 0x20000000;
bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
err = bcm43xx_switch_core(bcm, old_core);
--
Ciao
Stefano
^ permalink raw reply
* [patch 07/10] [RFT] bcm43xx: allow PHY revision 8, dont give up on unknown phy_rev
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-gphy_allow_rev8.diff --]
[-- Type: text/plain, Size: 1143 bytes --]
Allow a GPHY to have revision 8. Issue a warning instead of giving up when
dealing with an unknown core revision.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2717,10 +2717,9 @@ static int bcm43xx_probe_cores(struct bc
case 10:
break;
default:
- printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
+ printk(KERN_WARNING PFX
+ "Unsupported 80211 core revision %u\n",
core_rev);
- err = -ENODEV;
- goto out;
}
bcm->nr_80211_available++;
bcm43xx_init_struct_phyinfo(&ext_80211->phy);
@@ -3377,7 +3376,7 @@ static int bcm43xx_read_phyinfo(struct b
bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
break;
case BCM43xx_PHYTYPE_G:
- if (phy_rev > 7)
+ if (phy_rev > 8)
phy_rev_ok = 0;
bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
IEEE80211_CCK_MODULATION;
--
Ciao
Stefano
^ permalink raw reply
* [patch 08/10] [RFT] bcm43xx: powercontrol support for PCI-E devices
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_powercontrol.diff --]
[-- Type: text/plain, Size: 1910 bytes --]
Add powercontrol support for PCI-E devices.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -140,6 +140,7 @@
/* Chipcommon registers. */
#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
+#define BCM43xx_CHIPCOMMON_CTL 0x28
#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_power.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.c
@@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_pri
int err, maxfreq;
struct bcm43xx_coreinfo *old_core;
- if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
- return 0;
old_core = bcm->current_core;
err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
if (err == -ENODEV)
@@ -162,6 +160,21 @@ int bcm43xx_pctl_init(struct bcm43xx_pri
if (err)
goto out;
+ if (bcm->chip_id == 0x4321) {
+ if (bcm->chip_rev == 1)
+ bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
+ if (bcm->chip_rev == 0)
+ bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
+ }
+
+ if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
+ return 0;
+
+ if (bcm->current_core->rev >= 10)
+ bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
+ (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
+ & 0x0000FFFF) | 0x40000);
+
maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
(maxfreq * 150 + 999999) / 1000000);
--
Ciao
Stefano
^ permalink raw reply
* [patch 09/10] [RFT] bcm43xx: backplane setup for PCI-E devices and devices with PCI core ID > 10
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_backplane.diff --]
[-- Type: text/plain, Size: 5168 bytes --]
Backplane setup for PCI-E devices and PCI devices with PCI Core ID > 10.
Use chipcommon if possible while broadcasting PCI settings.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -154,6 +154,7 @@
/* SBTOPCI2 values. */
#define BCM43xx_SBTOPCI2_PREFETCH 0x4
#define BCM43xx_SBTOPCI2_BURST 0x8
+#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20
/* PCI-E core registers. */
#define BCM43xx_PCIECORE_REG_ADDR 0x0130
@@ -173,6 +174,14 @@
#define BCM43xx_PCIE_MDIO_TA 0x00020000
#define BCM43xx_PCIE_MDIO_TC 0x0100
+/* MDIO devices. */
+#define BCM43xx_MDIO_SERDES_RX 0x1F
+
+/* SERDES RX registers. */
+#define BCM43xx_SERDES_RXTIMER 0x2
+#define BCM43xx_SERDES_CDR 0x6
+#define BCM43xx_SERDES_CDR_BW 0x7
+
/* Chipcommon capabilities. */
#define BCM43xx_CAPABILITIES_PCTL 0x00040000
#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2952,18 +2952,26 @@ static void bcm43xx_pcicore_broadcast_va
static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
{
- int err;
- struct bcm43xx_coreinfo *old_core;
+ int err = 0;
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_pci);
- if (err)
- goto out;
+ bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
+ if (bcm->core_chipcommon.available) {
+ err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
+ if (err)
+ goto out;
+
+ bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
+
+ /* this function is always called when a PCI core is mapped */
+ err = bcm43xx_switch_core(bcm, &bcm->core_pci);
+ if (err)
+ goto out;
+ } else
+ bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
+
+ bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
- bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
out:
return err;
}
@@ -3026,7 +3034,8 @@ static int bcm43xx_setup_backplane_pci_c
if (err)
goto out;
- if (bcm->core_pci.rev < 6) {
+ if (bcm->current_core->rev < 6 ||
+ bcm->current_core->id == BCM43xx_COREID_PCI) {
value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
value |= (1 << backplane_flag_nr);
bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
@@ -3044,21 +3053,46 @@ static int bcm43xx_setup_backplane_pci_c
}
}
- value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
- value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
- bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
-
- if (bcm->core_pci.rev < 5) {
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
- value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
- & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
- value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
- & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
- err = bcm43xx_pcicore_commit_settings(bcm);
- assert(err == 0);
+ if (bcm->current_core->id == BCM43xx_COREID_PCI) {
+ value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
+ value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
+ bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
+
+ if (bcm->current_core->rev < 5) {
+ value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
+ value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
+ & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
+ value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
+ & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
+ bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
+ err = bcm43xx_pcicore_commit_settings(bcm);
+ assert(err == 0);
+ } else if (bcm->current_core->rev >= 11) {
+ value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
+ value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
+ bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
+ }
+ } else {
+ if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
+ value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
+ value |= 0x8;
+ bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
+ value);
+ }
+ if (bcm->current_core->rev == 0) {
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
+ BCM43xx_SERDES_RXTIMER, 0x8128);
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
+ BCM43xx_SERDES_CDR, 0x0100);
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
+ BCM43xx_SERDES_CDR_BW, 0x1466);
+ } else if (bcm->current_core->rev == 1) {
+ value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
+ value |= 0x40;
+ bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
+ value);
+ }
}
-
out_switch_back:
err = bcm43xx_switch_core(bcm, old_core);
out:
--
Ciao
Stefano
^ permalink raw reply
* [patch 10/10] [RFT] bcm43xx: add PCI ID for bcm4311
From: Stefano Brivio @ 2006-05-18 22:00 UTC (permalink / raw)
To: netdev; +Cc: Edgar Hucek, Matthew Garrett, Louis E Garcia II, Stefano Brivio
In-Reply-To: <20060519154451.042749000@polimi.it>
[-- Attachment #1: bcm43xx-pcie_ids.diff --]
[-- Type: text/plain, Size: 849 bytes --]
Add PCI ID for bcm4311 PCI-E device.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -130,6 +130,8 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for
{ PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4307 802.11b */
{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ /* Broadcom 4311 802.11(a)/b/g */
+ { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4318 802.11b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4306 802.11b/g */
--
Ciao
Stefano
^ permalink raw reply
* sky2 large MTU problems...
From: Daniel J Blueman @ 2006-05-19 16:22 UTC (permalink / raw)
To: shemminger; +Cc: netdev, Linux Networking
I've found that when increasing the sky2 interface MTU beyond
somewhere around 6000-7500, packets can get truncated.
The interface is the internal interface on a NAT router - I've been
able to reproduce this with 2.6.16 and 2.6.17-rc4 when say sending an
email from gmail (via the web interface).
Hardware:
sky2 v1.3 addr 0xdfbfc000 irq 169 Yukon-EC (0xb6) rev 1
Symptoms:
# ifconfig lan0 mtu 7500
# tcpdump -ni lan0
08:38:13.595118 IP truncated-ip - 100 bytes missing! 192.168.0.3.1552
> 213.160.98.138.554: . 2700848741:2700850201(1460) ack 1729330122 win
64883
(then sending from gmail hangs)
Let me know if you need a more specific reproducer (eg a particular
URL); I can test changes too.
--
Daniel J Blueman
^ permalink raw reply
* Re: [PATCH] Gianfar SKB Recycling Support
From: Stephen Hemminger @ 2006-05-19 17:47 UTC (permalink / raw)
To: Haruki Dai-r35557
Cc: netdev, Fleming Andy-afleming, Kumar Gala, Haruki Dai-r35557
In-Reply-To: <18AEF66AFDF06F4CAAA1D419D000FD33524B79@az33exm24.fsl.freescale.net>
On Wed, 17 May 2006 15:45:14 -0700
"Haruki Dai-r35557" <Dai.Haruki@freescale.com> wrote:
> This patch improves the IP forwarding throughput of
> the Freescale TSEC/eTSEC Gianfar driver. By recycling
> the Socket buffer and Data buffer, reduce the unnecessary
> memory allocation and de-allocation in the forwarding
> processing chain.
>
> Signed-off-by: Dai Haruki <dai.haruki@freescale.com>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
>
In case the general impression wasn't clear from the earlier comments.
This patch is an interesting benchmark tweak, but unlikely to ever
make it into the mainline kernel. The kernel needs to be a general
purpose system and deal with multiple types of hardware and resource
control.
But don't give up looking at performance. If you can find ways to
speed up the overall socket buffer handling without breaking existing
semantics; then the patches would be positively received.
^ permalink raw reply
* Re: [PATCH] bcm43xx-d80211: measure the channel change time
From: John W. Linville @ 2006-05-19 18:02 UTC (permalink / raw)
To: Johannes Berg
Cc: Jiri Benc, Michael Buesch, netdev-u79uwXL29TY76Z2rM5mHXA,
bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
In-Reply-To: <1146746216.1137.33.camel@localhost>
On Thu, May 04, 2006 at 02:36:56PM +0200, Johannes Berg wrote:
> On Thu, 2006-05-04 at 14:33 +0200, Jiri Benc wrote:
>
> > TSF is set to a value sent by an AP. Is there anything that prevents
> > that AP to send you e.g. 0xfffffffffffff0?
>
> Ah, good point, I didn't think of stupid APs. Yeah, it should handle it
> I guess.
I'm going to apply this patch as it stands. Please follow-up with
a patch to handle the TSF overflow.
Thanks,
John
--
John W. Linville
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org
^ permalink raw reply
* Re: [PATCH wireless-dev] d80211: Don't discriminate against 802.11b drivers
From: John W. Linville @ 2006-05-19 18:06 UTC (permalink / raw)
To: Michael Wu; +Cc: Jiri Benc, Jouni Malinen, netdev, jkmaline
In-Reply-To: <200605151319.23246.flamingice@sourmilk.net>
On Mon, May 15, 2006 at 01:19:23PM -0400, Michael Wu wrote:
> On Monday 15 May 2006 07:37, Jiri Benc wrote:
> > This issue can be easily solved by not masking hw_modes by
> > valid_hw_modes in ieee80211_ioctl_prism2_param and
> > ieee80211_precalc_modes. Just check (hw_modes & valid_hw_modes) instead
> > of hw_modes in ieee80211_sta_scan_timer.
> >
> > And yes, hw_modes is a confusing name. It should be named
> > hw_modes_mask_disabled_by_user or so. Maybe at least some better comment
> > about this in ieee80211_i.h won't be a bad idea.
> >
> Okay, how about this? Instead of adding valid_hw_modes, I added enabled_modes,
> and replaced all instances of local->hw_modes with local->enabled_modes.
> local->hw_modes now really means what modes are supported by the hardware.
Are we satisfied w/ this patch? If so, please repost the patch after
cleaning-up the changelog according to the rules here:
http://linux.yyz.us/patch-format.html
Thanks,
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
* Re: [PATCH,RFT] bcm43xx: use softmac-suggested TX rate
From: John W. Linville @ 2006-05-19 18:08 UTC (permalink / raw)
To: Daniel Drake; +Cc: netdev
In-Reply-To: <20060506091651.26BCD88A2C3@zog.reactivated.net>
On Sat, May 06, 2006 at 10:16:51AM +0100, Daniel Drake wrote:
> Can a bcm43xx user please test this. It uses the new txrate stuff found in
> the wireless-dev tree.
Daniel,
Do you intend for this to be merged? Given recent miscommunication,
I figured I should ask... :-)
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
* Re: [PATCH,RFT] bcm43xx: use softmac-suggested TX rate
From: Daniel Drake @ 2006-05-19 18:44 UTC (permalink / raw)
To: linville; +Cc: netdev
In-Reply-To: <20060519180846.GE30177@tuxdriver.com>
John W. Linville wrote:
> Do you intend for this to be merged? Given recent miscommunication,
> I figured I should ask... :-)
Nobody has tested it yet, so no, but thanks for asking.
I figure it will be easier to find testers once the base patch (softmac
suggest txrate) has been pushed by you into 2.6.18-rc1 ;)
Daniel
^ permalink raw reply
* Re: [PATCH,RFT] bcm43xx: use softmac-suggested TX rate
From: Michael Buesch @ 2006-05-19 18:32 UTC (permalink / raw)
To: Daniel Drake; +Cc: netdev, linville
In-Reply-To: <446E11FF.2060006@gentoo.org>
On Friday 19 May 2006 20:44, you wrote:
> John W. Linville wrote:
> > Do you intend for this to be merged? Given recent miscommunication,
> > I figured I should ask... :-)
>
> Nobody has tested it yet, so no, but thanks for asking.
>
> I figure it will be easier to find testers once the base patch (softmac
> suggest txrate) has been pushed by you into 2.6.18-rc1 ;)
Next time, please CC the maintainers, so they don't accidentally delete
important mail. ;)
Can you resend that patch to me in private and I will see if it
is good.
^ permalink raw reply
* Re: [PATCH 02/11] ixgb: Fix the use of dprintk rather than printk
From: Auke Kok @ 2006-05-19 18:35 UTC (permalink / raw)
To: Francois Romieu
Cc: Jeff Kirsher, Jeff Garzik, netdev, David Miller, John Rociak,
Jesse Brandeburg
In-Reply-To: <20060422090301.GB26666@electric-eye.fr.zoreil.com>
Francois Romieu wrote:
> Jeff Kirsher <jeffrey.t.kirsher@intel.com> :
>> @@ -486,8 +495,7 @@ ixgb_probe(struct pci_dev *pdev,
>> netif_carrier_off(netdev);
>> netif_stop_queue(netdev);
>>
>> - printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",
>> - netdev->name);
>> + DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n");
>
> It could probably be factored out with ixgb_driver_string.
the driver name is different from the interface/device that it drives - Hence
the different name. The 'Connection' name as above is the branding name as
well, and that's why we print it here as such. e1000 does the same thing for
the same reason.
Auke
^ permalink raw reply
* wireless-dev updated
From: John W. Linville @ 2006-05-19 19:15 UTC (permalink / raw)
To: netdev
I have updated the wireless-dev tree w/ some patches posted over the
last couple of weeks. Please update your repositories!
John
---
The following changes since commit b3783fbd3cc23106a21995b1bebde396047b2759:
John W. Linville:
Merge branch 'from-linus'
are found in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-dev.git
Jiri Benc:
d80211: switching management interface on/off
d80211: use alloc_netdev
d80211: fix is_ieee80211_device
John W. Linville:
bcm43xx-d80211: remove out-dated docs and script
Michael Buesch:
bcm43xx-d80211: rewrite interface handling
bcm43xx-d80211: measure the channel change time
bcm43xx-d80211: Fix access to non-existent PHY registers
Stefano Brivio:
bcm43xx-d80211: check for valid MAC address in SPROM
bcm43xx-d80211: add PCI ID for bcm4319
Documentation/networking/bcm43xx-d80211-HOWTO.txt | 67 -----
Documentation/networking/bcm43xx-d80211.txt | 31 ---
drivers/net/wireless/d80211/bcm43xx/bcm43xx.h | 42 +++
drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c | 2
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c | 245 +++++++++++++-------
drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c | 6
net/d80211/hostapd_ioctl.h | 1
net/d80211/ieee80211.c | 149 ++++++------
net/d80211/ieee80211_i.h | 9 -
net/d80211/ieee80211_iface.c | 82 +++++--
net/d80211/ieee80211_ioctl.c | 16 +
scripts/bcm43xx-d80211-sta_up.sh | 80 -------
12 files changed, 355 insertions(+), 375 deletions(-)
delete mode 100644 Documentation/networking/bcm43xx-d80211-HOWTO.txt
delete mode 100644 Documentation/networking/bcm43xx-d80211.txt
delete mode 100755 scripts/bcm43xx-d80211-sta_up.sh
diff --git a/Documentation/networking/bcm43xx-d80211-HOWTO.txt b/Documentation/networking/bcm43xx-d80211-HOWTO.txt
deleted file mode 100644
index 90e4ddf..0000000
--- a/Documentation/networking/bcm43xx-d80211-HOWTO.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-**** ****
-**** HOWTO get bcm43xx-dscape running ****
-**** ****
-
-This is a port of the bcm43xx driver for the devicescape ieee802.11
-stack. The devicescape ieee802.11 stack is an advanced out-of-mainline
-802.11 protocol module.
-I will call the "devicescape ieee802.11 stack" simply "dscape" in the
-following text.
-
-
-*** Setting up the bcm43xx driver with dscape is currently non-trivial,
-*** as several modifications to the kernel and the userland
-*** wpa_supplicant tool are required. We are working on it...
-
-
-1) You need to patch the kernel with the ieee80211-devicescape stack
- and the bcm43xx-dscape port.
- Both are available in one cummulative at:
- ftp://ftp.bu3sch.de/bcm43xx-snapshots/all-in-one/bcm43xx-dscape/
- Read the instructions on http://bcm43xx.berlios.de/ for how to apply
- this patch.
-
- Patch the kernel, compile and install it.
- When configuring, enable
- "Networking/Generic IEEE 802.11 Networking Stack (dscape)"
- and
- "Device Drivers/Network device support/Wireless LAN (non-hamradio)/Broadcom BCM43xx wireless support (DeviceScape stack)"
- Reboot.
-
-2) Set up a wpa_supplicant config file in /etc/wpa_supplicant.conf
- Here is an example for an AES WPA encrypted network:
-
- # WPA AES encryption
- ctrl_interface=/var/run/wpa_supplicant
- network={
- ssid="ACCESSPOINT_SSID"
- key_mgmt=WPA-PSK
- proto=WPA
- pairwise=CCMP TKIP
- group=CCMP TKIP
- psk="MY PASSPHRASE"
- priority=3
- }
-
-3) Take a bottle of your favourite beer, open it and take a swallow.
-
-4) Now it's time to bring the driver up.
- Do modprobe bcm43xx-d80211 to load the driver.
- There is an ugly bash script to bring the driver up after insmod.
- It is found in the "scripts" subdirectory of the patched kernel
- tree and is called "bcm43xx-d80211-sta_up.sh".
- Call scripts/bcm43xx-d80211-sta_up.sh --help to get some usage information.
- It may suffice to call scripts/bcm43xx-d80211-sta_up.sh without any parameters. See
- the help. Default parameters, which are used when called without parameters,
- are explained there.
-
-5) If you want to access the internet, make sure your default route
- is correctly set up with your gateway's IP:
- route add default gw 192.168.xxx.xxx
-
-6) Take another swallow from your bottle of beer and test if it works:
- ping www.kernel.org
-
-7) If it works, drink the rest of your beer. Otherwise read this HOWTO again,
- and again and again. Complain to bcm43xx-dev@lists.berlios.de, if it still
- does not work.
diff --git a/Documentation/networking/bcm43xx-d80211.txt b/Documentation/networking/bcm43xx-d80211.txt
deleted file mode 100644
index 89b101d..0000000
--- a/Documentation/networking/bcm43xx-d80211.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-
- BCM43xx Linux Driver Project
- ============================
-
-About this software
--------------------
-
-The goal of this project is to develop a linux driver for Broadcom
-BCM43xx chips, based on the specification at
-http://bcm-specs.sipsolutions.net/
-
-The project page is http://bcm43xx.berlios.de/
-
-This is a port of the bcm43xx driver for the devicescape ieee802.11
-stack.
-
-Requirements
-------------
-
-1) Linux Kernel 2.6.16 or later
- http://www.kernel.org/
-
- See Documentation/networking/bcm43xx-d80211-HOWTO.txt for further
- instructions.
-
-2) Firmware Files
-
- Please try bcm43xx-fwcutter. It can extract the firmware from various
- binary driver files and supports driver files from Windows, MacOS and
- Linux. You can get bcm43xx-fwcutter from http://bcm43xx.berlios.de/.
- Also, bcm43xx-fwcutter comes with a README file for further instructions.
diff --git a/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h b/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
index 97bde56..a4a97c2 100644
--- a/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
@@ -626,10 +626,32 @@ struct bcm43xx_key {
u8 algorithm;
};
+struct bcm43xx_interface {
+ /* Opaque ID of the operating interface (!= monitor
+ * interface) from the ieee80211 subsystem.
+ * Do not modify.
+ */
+ int if_id;
+ /* MAC address. */
+ u8 *mac_addr;
+ /* Current BSSID (if any). */
+ u8 *bssid;
+
+ /* Interface type. (IEEE80211_IF_TYPE_XXX) */
+ int type;
+ /* Counter of active monitor interfaces. */
+ int monitor;
+ /* Is the card operating in AP, STA or IBSS mode? */
+ unsigned int operating:1;
+ /* Promisc mode active?
+ * Note that (monitor != 0) implies promisc.
+ */
+ unsigned int promisc:1;
+};
+
struct bcm43xx_private {
struct ieee80211_hw *ieee;
struct ieee80211_low_level_stats ieee_stats;
- int iw_mode;
struct net_device *net_dev;
struct pci_dev *pci_dev;
@@ -653,6 +675,13 @@ struct bcm43xx_private {
short_slot:1, /* TRUE, if short slot timing is enabled. */
firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
+ /* One physical device can have one operating interface
+ * and a virtually infinite amount of monitoring interfaces.
+ * This keeps track of the interfaces and the corresponding
+ * hardware modes.
+ */
+ struct bcm43xx_interface interface;
+ /* Various statistics about the physical device. */
struct bcm43xx_stats stats;
/* Bus type we are connected to.
@@ -716,8 +745,6 @@ #endif
/* Informational stuff. */
char nick[IW_ESSID_MAX_SIZE + 1];
- u8 bssid[ETH_ALEN];
- int interfaces;
/* encryption/decryption */
u16 security_offset;
@@ -854,6 +881,15 @@ struct bcm43xx_private * dev_to_bcm(stru
return bcm;
}
+/* Is the device operating in a specified mode (IEEE80211_IF_TYPE_XXX). */
+static inline
+int bcm43xx_is_mode(struct bcm43xx_private *bcm, int type)
+{
+ if (type == IEEE80211_IF_TYPE_MNTR)
+ return !!bcm->interface.monitor;
+ return (bcm->interface.operating &&
+ bcm->interface.type == type);
+}
static inline
u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
diff --git a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
index 02bb08d..439bae4 100644
--- a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
@@ -217,7 +217,7 @@ void bcm43xx_leds_update(struct bcm43xx_
bcm43xx_led_blink_stop(led, 0);
continue;
case BCM43xx_LED_APTRANSFER:
- if (bcm->iw_mode == IW_MODE_MASTER) {
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
if (transferring) {
interval = BCM43xx_LEDBLINK_FAST;
turn_on = 1;
diff --git a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
index 93fc6f4..88f7dfe 100644
--- a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
@@ -128,6 +128,8 @@ static struct pci_device_id bcm43xx_pci_
{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4318 802.11b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ /* Broadcom 4319 802.11b/g */
+ { PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4306 802.11b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4306 802.11a */
@@ -354,6 +356,33 @@ void bcm43xx_tsf_write(struct bcm43xx_pr
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
}
+static void bcm43xx_measure_channel_change_time(struct bcm43xx_private *bcm)
+{
+ struct bcm43xx_radioinfo *radio;
+ u64 start, stop;
+ unsigned long flags;
+ u8 oldchan, testchan;
+
+ /* We (ab)use the bcm43xx TSF timer to measure the time needed
+ * to switch channels. This information is handed over to
+ * the ieee80211 subsystem.
+ * Time is measured in microseconds.
+ */
+
+ bcm43xx_lock_mmio(bcm, flags);
+ radio = bcm43xx_current_radio(bcm);
+ oldchan = radio->channel;
+ testchan = (oldchan == 6) ? 7 : 6;
+ bcm43xx_tsf_read(bcm, &start);
+ bcm43xx_radio_selectchannel(bcm, testchan, 0);
+ bcm43xx_tsf_read(bcm, &stop);
+ bcm43xx_radio_selectchannel(bcm, oldchan, 0);
+ bcm43xx_unlock_mmio(bcm, flags);
+
+ assert(stop > start);
+ bcm->ieee->channel_change_time = stop - start;
+}
+
static
void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
u16 offset,
@@ -378,18 +407,26 @@ void bcm43xx_macfilter_set(struct bcm43x
static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
u16 offset)
{
- const u8 zero_addr[ETH_ALEN] = { 0 };
+ static const u8 zero_addr[ETH_ALEN] = { 0 };
bcm43xx_macfilter_set(bcm, offset, zero_addr);
}
static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
{
- const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
- const u8 *bssid = bcm->bssid;
+ static const u8 zero_addr[ETH_ALEN] = { 0 };
+ const u8 *mac = NULL;
+ const u8 *bssid = NULL;
u8 mac_bssid[ETH_ALEN * 2];
int i;
+ bssid = bcm->interface.bssid;
+ if (!bssid)
+ bssid = zero_addr;
+ mac = bcm->interface.mac_addr;
+ if (!mac)
+ mac = zero_addr;
+
memcpy(mac_bssid, mac, ETH_ALEN);
memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
@@ -1438,15 +1475,15 @@ generate_new:
static void handle_irq_ps(struct bcm43xx_private *bcm)
{
- if (bcm->iw_mode == IW_MODE_MASTER) {
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
///TODO: PS TBTT
} else {
if (1/*FIXME: the last PSpoll frame was sent successfully */)
bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
}
- if (bcm->iw_mode == IW_MODE_ADHOC)
+ bcm->reg124_set_0x4 = 0;
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_IBSS))
bcm->reg124_set_0x4 = 1;
- //FIXME else set to false?
}
static void handle_irq_reg124(struct bcm43xx_private *bcm)
@@ -1456,7 +1493,6 @@ static void handle_irq_reg124(struct bcm
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
| 0x4);
- //FIXME: reset reg124_set_0x4 to false?
}
static void handle_irq_pmq(struct bcm43xx_private *bcm)
@@ -1509,7 +1545,9 @@ static void handle_irq_beacon(struct bcm
* Request the 80211 subsystem to generate a new beacon
* frame and use it as template.
*/
- bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev, 0, &control);
+ bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
+ bcm->interface.if_id,
+ &control);
if (unlikely(!bcm->cached_beacon)) {
dprintkl(KERN_WARNING PFX "Could not generate beacon template.\n");
goto ack;
@@ -1603,7 +1641,7 @@ #endif /* CONFIG_BCM43XX_D80211_DEBUG*/
}
if (reason & BCM43xx_IRQ_BEACON) {
- if (bcm->iw_mode == IW_MODE_MASTER)
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
handle_irq_beacon(bcm);
bcmirq_handled(BCM43xx_IRQ_BEACON);
}
@@ -2147,55 +2185,49 @@ void bcm43xx_mac_suspend(struct bcm43xx_
printkl(KERN_ERR PFX "MAC suspend failed\n");
}
-void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
- int iw_mode)
+static void bcm43xx_select_opmode(struct bcm43xx_private *bcm)
{
- struct net_device *net_dev = bcm->net_dev;
u32 status;
u16 value;
- bcm->iw_mode = iw_mode;
- if (iw_mode == IW_MODE_MONITOR)
- net_dev->type = ARPHRD_IEEE80211;
- else
- net_dev->type = ARPHRD_ETHER;
-
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- /* Reset status to infrastructured mode */
- status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
+ /* Reset status to default STA mode */
+ status &= ~BCM43xx_SBF_MODE_AP;
+ status &= ~BCM43xx_SBF_MODE_MONITOR;
status &= ~BCM43xx_SBF_MODE_PROMISC;
status |= BCM43xx_SBF_MODE_NOTADHOC;
-/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
-status |= BCM43xx_SBF_MODE_PROMISC;
-
- switch (iw_mode) {
- case IW_MODE_MONITOR:
+ if (bcm->interface.operating) {
+ switch (bcm->interface.type) {
+ case IEEE80211_IF_TYPE_AP:
+ status |= BCM43xx_SBF_MODE_AP;
+ break;
+ case IEEE80211_IF_TYPE_IBSS:
+ status &= ~BCM43xx_SBF_MODE_NOTADHOC;
+ break;
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_MNTR:
+ case IEEE80211_IF_TYPE_WDS:
+ break;
+ default:
+ assert(0);
+ }
+ }
+ if (bcm->interface.monitor) {
status |= BCM43xx_SBF_MODE_MONITOR;
status |= BCM43xx_SBF_MODE_PROMISC;
- break;
- case IW_MODE_ADHOC:
- status &= ~BCM43xx_SBF_MODE_NOTADHOC;
- break;
- case IW_MODE_MASTER:
- status |= BCM43xx_SBF_MODE_AP;
- break;
- case IW_MODE_SECOND:
- case IW_MODE_REPEAT:
- TODO(); /* TODO */
- break;
- case IW_MODE_INFRA:
- /* nothing to be done here... */
- break;
- default:
- dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
}
- if (net_dev->flags & IFF_PROMISC)
+ if (bcm->interface.promisc)
status |= BCM43xx_SBF_MODE_PROMISC;
+
+/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
+status |= BCM43xx_SBF_MODE_PROMISC;
+
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
value = 0x0002;
- if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
+ if ((status & BCM43xx_SBF_MODE_NOTADHOC) &&
+ !(status & BCM43xx_SBF_MODE_AP)) {
if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
value = 0x0064;
else
@@ -2291,7 +2323,7 @@ static int bcm43xx_chip_init(struct bcm4
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
/* Initially set the wireless operation mode. */
- bcm43xx_set_iwmode(bcm, bcm->iw_mode);
+ bcm43xx_select_opmode(bcm);
if (bcm->current_core->rev < 3) {
bcm43xx_write16(bcm, 0x060E, 0x0000);
@@ -2599,27 +2631,6 @@ out:
return err;
}
-static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
-{
- const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
- u8 *bssid = bcm->bssid;
-
- switch (bcm->iw_mode) {
- case IW_MODE_ADHOC:
- random_ether_addr(bssid);
- break;
- case IW_MODE_MASTER:
- case IW_MODE_INFRA:
- case IW_MODE_REPEAT:
- case IW_MODE_SECOND:
- case IW_MODE_MONITOR:
- memcpy(bssid, mac, ETH_ALEN);
- break;
- default:
- assert(0);
- }
-}
-
static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
u16 rate,
int is_ofdm)
@@ -2746,7 +2757,6 @@ static int bcm43xx_wireless_core_init(st
/* Maximum Contention Window */
bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
- bcm43xx_gen_bssid(bcm);
bcm43xx_write_mac_bssid_templates(bcm);
if (bcm->current_core->rev >= 5)
@@ -3725,6 +3735,7 @@ static int bcm43xx_init_board(struct bcm
dprintk(KERN_INFO PFX "80211 cores initialized\n");
bcm43xx_setup_modes(bcm);
bcm43xx_security_init(bcm);
+ bcm43xx_measure_channel_change_time(bcm);
ieee80211_update_hw(bcm->net_dev, bcm->ieee);
ieee80211_netif_oper(bcm->net_dev, NETIF_ATTACH);
ieee80211_netif_oper(bcm->net_dev, NETIF_START);
@@ -3934,7 +3945,7 @@ static int bcm43xx_attach_board(struct b
bcm43xx_pctl_set_crystal(bcm, 0);
/* Set the MAC address in the networking subsystem */
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
+ if (is_valid_ether_addr(bcm->sprom.et1macaddr))
memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
else
memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
@@ -4169,13 +4180,8 @@ #endif /* CONFIG_NET_POLL_CONTROLLER */
static int bcm43xx_net_open(struct net_device *net_dev)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int res;
- res = bcm43xx_init_board(bcm);
- if (!res)
- return res;
- bcm43xx_set_iwmode(bcm, bcm->iw_mode);
- return 0;
+ return bcm43xx_init_board(bcm);
}
static int bcm43xx_net_stop(struct net_device *net_dev)
@@ -4194,33 +4200,91 @@ static int bcm43xx_add_interface(struct
struct ieee80211_if_init_conf *conf)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ unsigned long flags;
+ int err = -EOPNOTSUPP;
+
+ bcm43xx_lock_mmio(bcm, flags);
- if (bcm->interfaces > 0)
- return -ENOBUFS;
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
- bcm->iw_mode = IW_MODE_MONITOR;
+ bcm->interface.monitor++;
} else {
- if (memcmp(bcm->net_dev->dev_addr, conf->mac_addr, ETH_ALEN) != 0)
- return -EADDRNOTAVAIL;
- if (conf->type == IEEE80211_IF_TYPE_STA)
- bcm->iw_mode = IW_MODE_INFRA;
- else if (conf->type == IEEE80211_IF_TYPE_IBSS)
- bcm->iw_mode = IW_MODE_ADHOC;
- else if (conf->type == IEEE80211_IF_TYPE_AP)
- bcm->iw_mode = IW_MODE_MASTER;
- else
- return -EOPNOTSUPP;
+ if (bcm->interface.operating)
+ goto out_unlock;
+ bcm->interface.operating = 1;
+ bcm->interface.if_id = conf->if_id;
+ bcm->interface.mac_addr = conf->mac_addr;
+ bcm->interface.type = conf->type;
}
- bcm->interfaces++;
- return 0;
+ if (bcm->initialized)
+ bcm43xx_select_opmode(bcm);
+ err = 0;
+
+ dprintk(KERN_INFO PFX "Virtual interface added "
+ "(type: 0x%08X, ID: %d, MAC: "
+ BCM43xx_MACFMT ")\n",
+ conf->type, conf->if_id,
+ BCM43xx_MACARG(conf->mac_addr));
+
+out_unlock:
+ bcm43xx_unlock_mmio(bcm, flags);
+
+ return err;
}
static void bcm43xx_remove_interface(struct net_device *net_dev,
struct ieee80211_if_init_conf *conf)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ unsigned long flags;
- bcm->interfaces--;
+ bcm43xx_lock_mmio(bcm, flags);
+ if (conf->type == IEEE80211_IF_TYPE_MNTR) {
+ bcm->interface.monitor--;
+ assert(bcm->interface.monitor >= 0);
+ } else
+ bcm->interface.operating = 0;
+ if (bcm->initialized)
+ bcm43xx_select_opmode(bcm);
+ bcm43xx_unlock_mmio(bcm, flags);
+
+ dprintk(KERN_INFO PFX "Virtual interface removed "
+ "(type: 0x%08X, ID: %d, MAC: "
+ BCM43xx_MACFMT ")\n",
+ conf->type, conf->if_id,
+ BCM43xx_MACARG(conf->mac_addr));
+}
+
+static int bcm43xx_config_interface(struct net_device *net_dev,
+ int if_id,
+ struct ieee80211_if_conf *conf)
+{
+ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ unsigned long flags;
+
+ bcm43xx_lock(bcm, flags);
+ if (conf->type != IEEE80211_IF_TYPE_MNTR) {
+ assert(bcm->interface.if_id == if_id);
+ bcm->interface.bssid = conf->bssid;
+ }
+ bcm43xx_unlock(bcm, flags);
+
+ return 0;
+}
+
+static void bcm43xx_set_multicast_list(struct net_device *net_dev,
+ unsigned short netflags,
+ int mc_count)
+{
+ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ unsigned long flags;
+
+ bcm43xx_lock_mmio(bcm, flags);
+ if (bcm->interface.promisc != !!(netflags & IFF_PROMISC)) {
+ bcm->interface.promisc = !!(netflags & IFF_PROMISC);
+ if (bcm->initialized)
+ bcm43xx_select_opmode(bcm);
+ }
+ bcm43xx_unlock_mmio(bcm, flags);
}
/* Initialization of struct net_device, just after allocation. */
@@ -4294,6 +4358,7 @@ #endif
ieee->name = KBUILD_MODNAME;
ieee->host_gen_beacon = 1;
ieee->rx_includes_fcs = 1;
+ ieee->monitor_during_oper = 1;
ieee->tx = bcm43xx_net_hard_start_xmit;
ieee->open = bcm43xx_net_open;
ieee->stop = bcm43xx_net_stop;
@@ -4301,6 +4366,8 @@ #endif
ieee->remove_interface = bcm43xx_remove_interface;
ieee->reset = bcm43xx_net_reset;
ieee->config = bcm43xx_net_config;
+ ieee->config_interface = bcm43xx_config_interface;
+ ieee->set_multicast_list = bcm43xx_set_multicast_list;
//TODO ieee->set_key = bcm43xx_net_set_key;
ieee->get_stats = bcm43xx_net_get_stats;
ieee->queues = 1;
diff --git a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
index 45da79d..413b2ed 100644
--- a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
@@ -94,7 +94,7 @@ void bcm43xx_raw_phy_lock(struct bcm43xx
bcm43xx_mac_suspend(bcm);
spin_lock(&phy->lock);
} else {
- if (bcm->iw_mode != IW_MODE_MASTER)
+ if (!bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
}
phy->is_locked = 1;
@@ -111,7 +111,7 @@ void bcm43xx_raw_phy_unlock(struct bcm43
bcm43xx_mac_enable(bcm);
}
} else {
- if (bcm->iw_mode != IW_MODE_MASTER)
+ if (!bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
}
phy->is_locked = 0;
@@ -1287,7 +1287,7 @@ static void bcm43xx_phy_initg(struct bcm
if (radio->revision == 8)
bcm43xx_phy_write(bcm, 0x0805, 0x3230);
bcm43xx_phy_init_pctl(bcm);
- if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) {
+ if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) {
bcm43xx_phy_write(bcm, 0x0429,
bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
bcm43xx_phy_write(bcm, 0x04C3,
diff --git a/net/d80211/hostapd_ioctl.h b/net/d80211/hostapd_ioctl.h
index a462688..3adfa9a 100644
--- a/net/d80211/hostapd_ioctl.h
+++ b/net/d80211/hostapd_ioctl.h
@@ -91,6 +91,7 @@ enum {
PRISM2_PARAM_KEY_MGMT = 1040,
PRISM2_PARAM_RADAR_DETECT = 1043,
PRISM2_PARAM_SPECTRUM_MGMT = 1044,
+ PRISM2_PARAM_MGMT_IF = 1045,
/* NOTE: Please try to coordinate with other active development
* branches before allocating new param numbers so that each new param
* will be unique within all branches and the allocated number will not
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index ffb7985..0614fa2 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -59,6 +59,8 @@ static int rate_control_initialize(struc
static u8 * ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len);
+static int ieee80211_mgmt_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
struct ieee80211_key_conf *
ieee80211_key_data2conf(struct ieee80211_local *local,
@@ -1097,7 +1099,8 @@ __ieee80211_tx_prepare(struct ieee80211_
static int inline is_ieee80211_device(struct net_device *dev)
{
return (dev->wireless_handlers ==
- (struct iw_handler_def *) &ieee80211_iw_handler_def);
+ (struct iw_handler_def *) &ieee80211_iw_handler_def) ||
+ (dev->hard_start_xmit == ieee80211_mgmt_start_xmit);
}
/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
@@ -1954,8 +1957,6 @@ static inline int identical_mac_addr_all
{
return (type1 == IEEE80211_IF_TYPE_MNTR ||
type2 == IEEE80211_IF_TYPE_MNTR ||
- type1 == IEEE80211_IF_TYPE_MGMT ||
- type2 == IEEE80211_IF_TYPE_MGMT ||
(type1 == IEEE80211_IF_TYPE_AP &&
type2 == IEEE80211_IF_TYPE_WDS) ||
(type1 == IEEE80211_IF_TYPE_WDS &&
@@ -1990,6 +1991,20 @@ static int ieee80211_master_stop(struct
return 0;
}
+static int ieee80211_mgmt_open(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+
+ if (!netif_running(local->mdev))
+ return -EOPNOTSUPP;
+ return 0;
+}
+
+static int ieee80211_mgmt_stop(struct net_device *dev)
+{
+ return 0;
+}
+
/* Check if running monitor interfaces should go to a "soft monitor" mode
* and switch them if necessary. */
static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
@@ -2032,7 +2047,6 @@ static int ieee80211_open(struct net_dev
struct net_device *ndev = nsdata->dev;
if (ndev != dev && ndev != local->mdev &&
- ndev != local->apdev &&
netif_running(ndev) &&
memcmp(dev->dev_addr, ndev->dev_addr, ETH_ALEN) == 0 &&
!identical_mac_addr_allowed(sdata->type, nsdata->type)) {
@@ -2075,8 +2089,11 @@ static int ieee80211_open(struct net_dev
res = local->hw->open(sdata->master);
if (res == 0) {
res = dev_open(sdata->master);
- if (res && local->hw->stop)
- local->hw->stop(sdata->master);
+ if (res) {
+ if (local->hw->stop)
+ local->hw->stop(sdata->master);
+ } else if (local->apdev)
+ dev_open(local->apdev);
}
if (res) {
if (local->hw->remove_interface)
@@ -2119,6 +2136,8 @@ static int ieee80211_stop(struct net_dev
if (local->open_count == 0) {
ieee80211_stop_scan(sdata->master);
dev_close(sdata->master);
+ if (local->apdev)
+ dev_close(local->apdev);
if (local->hw->stop)
local->hw->stop(sdata->master);
}
@@ -2367,6 +2386,10 @@ ieee80211_rx_mgmt(struct net_device *dev
if (msg_type != ieee80211_msg_monitor)
dev = local->apdev;
+ if (!dev) {
+ dev_kfree_skb(skb);
+ return;
+ }
skb->dev = dev;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -3998,6 +4021,19 @@ void ieee80211_if_setup(struct net_devic
dev->destructor = ieee80211_if_free;
}
+void ieee80211_if_mgmt_setup(struct net_device *dev)
+{
+ ether_setup(dev);
+ dev->hard_start_xmit = ieee80211_mgmt_start_xmit;
+ dev->change_mtu = ieee80211_change_mtu_apdev;
+ dev->get_stats = ieee80211_get_stats;
+ dev->open = ieee80211_mgmt_open;
+ dev->stop = ieee80211_mgmt_stop;
+ dev->type = ARPHRD_IEEE80211_PRISM;
+ dev->hard_header_parse = header_parse_80211;
+ dev->tx_queue_len = 0;
+ dev->destructor = ieee80211_if_free;
+}
static void ieee80211_precalc_rates(struct ieee80211_hw *hw)
{
@@ -4018,57 +4054,43 @@ static void ieee80211_precalc_rates(stru
struct net_device *ieee80211_alloc_hw(size_t priv_data_len,
void (*setup)(struct net_device *))
{
- struct net_device *apdev, *mdev;
+ struct net_device *mdev;
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
- int alloc_size;
+ int priv_size;
- /* Ensure 32-bit alignment of our private data and hw private data.
- * Each net_device is followed by a sub_if_data which which is used
- * for wds/vlan information; it is aligned as well.
+ /* Ensure 32-byte alignment of our private data and hw private data.
+ * Each net_device is followed by a sub_if_data which is used for
+ * interface specific information.
*
* Sample memory map looks something like:
*
* 0000 *****************
* * net_dev *
- * 015c *****************
+ * 0160 *****************
* * sub_if *
- * 017c *****************
+ * 0180 *****************
* * local *
- * 0b84 *****************
+ * 0b80 *****************
* * hw_priv *
* 1664 *****************
- * * ap net_dev *
- * 17c0 *****************
- * * sub_if *
- * *****************
*/
- alloc_size = sizeof(struct net_device) +
- sizeof(struct ieee80211_sub_if_data) + 3 +
- sizeof(struct ieee80211_local) + 3 +
- priv_data_len + 3 +
- sizeof(struct net_device) + 3 +
- sizeof(struct ieee80211_sub_if_data) + 3 +
- 4096;
- mdev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
+ priv_size = ((sizeof(struct ieee80211_sub_if_data) +
+ NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
+ ((sizeof(struct ieee80211_local) +
+ NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
+ priv_data_len;
+ mdev = alloc_netdev(priv_size, "wmaster%d", ether_setup);
if (mdev == NULL)
return NULL;
- mdev->priv = (struct net_device *)
- ((char *) mdev +
- ((sizeof(struct net_device) + 3) & ~3) +
- ((sizeof(struct ieee80211_sub_if_data) + 3) & ~3));
+ mdev->priv = (char *)netdev_priv(mdev) +
+ ((sizeof(struct ieee80211_sub_if_data) +
+ NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
local = mdev->priv;
- local->hw_priv = (void *)
- ((char *) local + ((sizeof(struct ieee80211_local) + 3) & ~3));
- apdev = (struct net_device *)
- ((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
-
- ether_setup(mdev);
- memcpy(mdev->name, "wmaster%d", 10);
-
- if (strlen(mdev->name) + 2 >= sizeof(mdev->name))
- goto fail;
+ local->hw_priv = (char *)local +
+ ((sizeof(struct ieee80211_local) +
+ NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
local->dev_index = -1;
local->mdev = mdev;
@@ -4104,28 +4126,6 @@ struct net_device *ieee80211_alloc_hw(si
ieee80211_if_init(mdev);
- apdev = (struct net_device *)
- ((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
- local->apdev = apdev;
- ether_setup(apdev);
- apdev->priv = local;
- apdev->hard_start_xmit = ieee80211_mgmt_start_xmit;
- apdev->change_mtu = ieee80211_change_mtu_apdev;
- apdev->get_stats = ieee80211_get_stats;
- apdev->open = ieee80211_open;
- apdev->stop = ieee80211_stop;
- apdev->type = ARPHRD_IEEE80211_PRISM;
- apdev->hard_header_parse = header_parse_80211;
- apdev->tx_queue_len = 0;
- sprintf(apdev->name, "%sap", mdev->name);
-
- sdata = IEEE80211_DEV_TO_SUB_IF(apdev);
- sdata->type = IEEE80211_IF_TYPE_MGMT;
- sdata->dev = apdev;
- sdata->master = mdev;
- sdata->local = local;
- list_add_tail(&sdata->list, &local->sub_if_list);
-
mdev->hard_start_xmit = ieee80211_master_start_xmit;
mdev->wireless_handlers =
(struct iw_handler_def *) &ieee80211_iw_handler_def;
@@ -4155,10 +4155,6 @@ struct net_device *ieee80211_alloc_hw(si
setup(mdev);
return mdev;
-
- fail:
- ieee80211_free_hw(mdev);
- return NULL;
}
@@ -4193,15 +4189,11 @@ int ieee80211_register_hw(struct net_dev
sta_info_start(local);
- result = register_netdev(local->apdev);
- if (result < 0)
- goto fail_1st_dev;
-
if (hw->fraglist)
dev->features |= NETIF_F_FRAGLIST;
result = register_netdev(dev);
if (result < 0)
- goto fail_2nd_dev;
+ goto fail_dev;
if (rate_control_initialize(local) < 0) {
printk(KERN_DEBUG "%s: Failed to initialize rate control "
@@ -4226,9 +4218,7 @@ int ieee80211_register_hw(struct net_dev
fail_rate:
unregister_netdev(dev);
-fail_2nd_dev:
- unregister_netdev(local->apdev);
-fail_1st_dev:
+fail_dev:
sta_info_stop(local);
ieee80211_unregister_sysfs(local);
fail_sysfs:
@@ -4247,12 +4237,6 @@ int ieee80211_update_hw(struct net_devic
if (hw->queues == 0)
hw->queues = 1;
- memcpy(local->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
- local->apdev->base_addr = dev->base_addr;
- local->apdev->irq = dev->irq;
- local->apdev->mem_start = dev->mem_start;
- local->apdev->mem_end = dev->mem_end;
-
if (!hw->modes || !hw->modes->channels || !hw->modes->rates ||
!hw->modes->num_channels || !hw->modes->num_rates)
return -1;
@@ -4291,6 +4275,9 @@ void ieee80211_unregister_hw(struct net_
del_timer_sync(&local->scan_timer);
ieee80211_rx_bss_list_deinit(dev);
+ if (local->apdev)
+ ieee80211_if_del(local->apdev);
+
list_for_each_safe(ptr, n, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
@@ -4323,7 +4310,7 @@ void ieee80211_unregister_hw(struct net_
void ieee80211_free_hw(struct net_device *dev)
{
- kfree(dev);
+ free_netdev(dev);
}
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index ee0b399..48aa9d3 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -307,11 +307,7 @@ #define NUM_DEFAULT_KEYS 4
int channel_use_raw;
};
-#define IEEE80211_DEV_TO_SUB_IF(dev) ((struct ieee80211_sub_if_data *) \
- ((char *)(dev) + ((sizeof(struct net_device) + 3) & ~3)))
-#define IEEE80211_SUB_IF_TO_DEV(sub_if) ((struct net_device *) \
- ((char *)(sub_if) - ((sizeof(struct net_device) + 3) & ~3)))
-
+#define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev)
struct ieee80211_local {
struct ieee80211_hw *hw;
@@ -518,6 +514,7 @@ void ieee80211_prepare_rates(struct net_
void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
void ieee80211_if_setup(struct net_device *dev);
+void ieee80211_if_mgmt_setup(struct net_device *dev);
/* ieee80211_ioctl.c */
int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -595,6 +592,8 @@ int ieee80211_if_remove(struct net_devic
void ieee80211_if_free(struct net_device *dev);
void ieee80211_if_flush(struct net_device *dev);
void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
+int ieee80211_if_add_mgmt(struct net_device *dev);
+void ieee80211_if_del_mgmt(struct net_device *dev);
/* ieee80211_sysfs.c */
int ieee80211_register_sysfs(struct ieee80211_local *local);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index f3ce45f..8a2f7f5 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -31,16 +31,12 @@ int ieee80211_if_add(struct net_device *
struct net_device *ndev, *tmp_dev;
struct ieee80211_local *local = dev->priv;
struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent;
- int alloc_size;
int ret;
int i;
ASSERT_RTNL();
- /* ensure 32-bit alignment of our private data and hw private data */
- alloc_size = sizeof(struct net_device) + 3 +
- sizeof(struct ieee80211_sub_if_data) + 3;
-
- ndev = *new_dev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
+ ndev = *new_dev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
+ "", ieee80211_if_setup);
if (ndev == NULL)
return -ENOMEM;
@@ -68,7 +64,6 @@ int ieee80211_if_add(struct net_device *
ndev->mem_start = dev->mem_start;
ndev->mem_end = dev->mem_end;
ndev->flags = dev->flags & IFF_MULTICAST;
- ieee80211_if_setup(ndev);
sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
sdata->type = IEEE80211_IF_TYPE_AP;
@@ -88,11 +83,66 @@ int ieee80211_if_add(struct net_device *
return 0;
fail:
- kfree(ndev);
+ free_netdev(ndev);
*new_dev = NULL;
return ret;
}
+int ieee80211_if_add_mgmt(struct net_device *dev)
+{
+ struct net_device *ndev;
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata, *nsdata;
+ int ret;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ ASSERT_RTNL();
+
+ ndev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), "",
+ ieee80211_if_mgmt_setup);
+ if (ndev == NULL)
+ return -ENOMEM;
+ ret = dev_alloc_name(ndev, "wmgmt%d");
+ if (ret)
+ goto fail;
+
+ ndev->priv = local;
+ memcpy(ndev->dev_addr, dev->dev_addr, ETH_ALEN);
+ ndev->base_addr = dev->base_addr;
+ ndev->irq = dev->irq;
+ ndev->mem_start = dev->mem_start;
+ ndev->mem_end = dev->mem_end;
+
+ nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+ nsdata->type = IEEE80211_IF_TYPE_MGMT;
+ nsdata->master = local->mdev;
+ nsdata->dev = ndev;
+ nsdata->local = local;
+ ieee80211_if_sdata_init(nsdata);
+
+ ret = register_netdevice(ndev);
+ if (ret)
+ goto fail;
+ if (local->open_count > 0)
+ dev_open(ndev);
+ local->apdev = ndev;
+ return 0;
+fail:
+ free_netdev(ndev);
+ return ret;
+}
+
+void ieee80211_if_del_mgmt(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct net_device *apdev;
+
+ ASSERT_RTNL();
+ apdev = local->apdev;
+ local->apdev = NULL;
+ unregister_netdevice(apdev);
+}
+
void ieee80211_if_set_type(struct net_device *dev, int type)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -110,6 +160,7 @@ void ieee80211_if_set_type(struct net_de
sdata->u.ap.max_ratectrl_rateidx = -1;
skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
sdata->bss = &sdata->u.ap;
+ sdata->type = IEEE80211_IF_TYPE_STA;
break;
case IEEE80211_IF_TYPE_STA:
case IEEE80211_IF_TYPE_IBSS: {
@@ -244,9 +295,8 @@ void __ieee80211_if_del(struct ieee80211
list_del(&sdata->list);
ieee80211_proc_deinit_virtual(dev);
unregister_netdevice(dev);
- /* Default data device and management device are allocated with the
- * master device. All other devices are separately allocated and will
- * be freed by net_device->destructor (i. e. ieee80211_if_free). */
+ /* Except master interface, the net_device will be freed by
+ * net_device->destructor (i. e. ieee80211_if_free). */
}
/* Must be called with rtnl lock held. */
@@ -263,8 +313,7 @@ int ieee80211_if_remove(struct net_devic
list_for_each_entry_safe(sdata, n, &local->sub_if_list, list) {
if ((sdata->type == id || id == -1) &&
strcmp(name, sdata->dev->name) == 0 &&
- sdata->dev != local->mdev &&
- sdata->dev != local->apdev) {
+ sdata->dev != local->mdev) {
__ieee80211_if_del(local, sdata);
return 0;
}
@@ -277,7 +326,7 @@ void ieee80211_if_free(struct net_device
struct ieee80211_local *local = dev->priv;
BUG_ON(dev == local->mdev || dev == local->apdev);
- kfree(dev);
+ free_netdev(dev);
}
/* Must be called with rtnl lock held. */
@@ -298,6 +347,9 @@ void ieee80211_if_del(struct net_device
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
rtnl_lock();
- __ieee80211_if_del(local, sdata);
+ if (sdata->type == IEEE80211_IF_TYPE_MGMT)
+ ieee80211_if_del_mgmt(local->mdev);
+ else
+ __ieee80211_if_del(local, sdata);
rtnl_unlock();
}
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 5d31a8f..0bfa361 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -2469,6 +2469,16 @@ static int ieee80211_ioctl_prism2_param(
case PRISM2_PARAM_SPECTRUM_MGMT:
local->conf.spect_mgmt = value;
break;
+ case PRISM2_PARAM_MGMT_IF:
+ if (value == 1) {
+ if (local->apdev == NULL)
+ ret = ieee80211_if_add_mgmt(local->mdev);
+ } else if (value == 0) {
+ if (local->apdev)
+ ieee80211_if_del_mgmt(local->mdev);
+ } else
+ ret = -EINVAL;
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -2651,6 +2661,12 @@ static int ieee80211_ioctl_get_prism2_pa
else
*param = !!sdata->u.sta.wmm_enabled;
break;
+ case PRISM2_PARAM_MGMT_IF:
+ if (local->apdev)
+ *param = local->apdev->ifindex;
+ else
+ ret = -ENOENT;
+ break;
default:
ret = -EOPNOTSUPP;
diff --git a/scripts/bcm43xx-d80211-sta_up.sh b/scripts/bcm43xx-d80211-sta_up.sh
deleted file mode 100755
index a21ddff..0000000
--- a/scripts/bcm43xx-d80211-sta_up.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/bash
-
-if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
- echo "$0, an ugly script to configure and bring up a STA (802.11 station)"
- echo "device for the linux devicescape 802.11 stack."
- echo
- echo "Usage:"
- echo "$0 [ wlan_device local_ip wpasupplicant_config ]"
- echo
- echo "Examples:"
- echo "Run with default parameters: $0"
- echo "Manually define parameters: $0 wlan0 192.168.1.1 ./wpasupp.conf"
- echo
- echo "Default parameters are: $0 wlan0 192.168.1.101 /etc/wpa_supplicant.conf"
- exit 1
-fi
-
-wlan_dev="$1"
-ip_addr="$2"
-wpasupp_conf="$3"
-
-if [ -z "$wlan_dev" ]; then
- wlan_dev="wlan0"
-fi
-if [ -z "$sta_dev" ]; then
- sta_dev="sta0"
-fi
-if [ -z "$ip_addr" ]; then
- ip_addr="192.168.1.101"
-fi
-if [ -z "$wpasupp_conf" ]; then
- wpasupp_conf="/etc/wpa_supplicant.conf"
-fi
-
-idx=$(echo $wlan_dev | awk '{ gsub("[^0-9]", "", $0); printf($0); }')
-if [ -z "$idx" ]; then
- echo "Invalid wlan_device parameter \"$wlan_dev\". Example: wlan0"
- exit 1
-fi
-sta_dev="sta$idx"
-phy_dev="phy$idx"
-
-function run()
-{
- echo "$@"
- $@
- res=$?
- if [ $res -ne 0 ]; then
- echo "FAILED ($res)"
- exit 1
- fi
-}
-
-if [ -z "$(grep -e bcm43xx /proc/modules)" ]; then
- echo "ERROR: bcm43xx module not loaded."
- exit 1
-fi
-
-killall wpa_supplicant 2>/dev/null
-echo -n "$sta_dev" > /sys/class/ieee80211/${phy_dev}/add_iface
-if [ $? -ne 0 ]; then
- echo "ERROR: Could not add STA device."
- exit 1
-fi
-run iwconfig $wlan_dev.11 mode managed
-run ifconfig $wlan_dev.11 up
-
-hwaddr="$(ifconfig | grep $wlan_dev.11 | awk '{print $NF}')"
-run ifconfig $sta_dev hw ether $hwaddr
-run ifconfig $sta_dev $ip_addr
-run ifconfig $sta_dev up
-run iwconfig $sta_dev mode managed
-
-run wpa_supplicant -B -Dwext -i$sta_dev -c$wpasupp_conf
-
-echo
-echo "You may want to set the default route, now:"
-echo " route add default gw GATEWAY_IP_ADDRESS"
-
-exit 0
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply related
* Re: [PATCH wireless-dev] d80211: Don't discriminate against 802.11b drivers
From: Michael Wu @ 2006-05-19 19:03 UTC (permalink / raw)
To: John W. Linville; +Cc: Jiri Benc, Jouni Malinen, netdev, jkmaline
In-Reply-To: <20060519180649.GD30177@tuxdriver.com>
On Friday 19 May 2006 14:06, John W. Linville wrote:
> Are we satisfied w/ this patch? If so, please repost the patch after
> cleaning-up the changelog according to the rules here:
>
> http://linux.yyz.us/patch-format.html
>
I was going to after getting a response, but Jiri Benc already pulled it into
his dscape tree and cleaned up the changelog, so I assumed that was enough.
I'll repost if needed.
-Michael Wu
^ permalink raw reply
* Re: [PATCH wireless-dev] d80211: Don't discriminate against 802.11b drivers
From: John W. Linville @ 2006-05-19 19:22 UTC (permalink / raw)
To: Michael Wu; +Cc: Jiri Benc, Jouni Malinen, netdev, jkmaline
In-Reply-To: <200605191503.12369.flamingice@sourmilk.net>
On Fri, May 19, 2006 at 03:03:11PM -0400, Michael Wu wrote:
> On Friday 19 May 2006 14:06, John W. Linville wrote:
> > Are we satisfied w/ this patch? If so, please repost the patch after
> > cleaning-up the changelog according to the rules here:
> >
> > http://linux.yyz.us/patch-format.html
> >
> I was going to after getting a response, but Jiri Benc already pulled it into
> his dscape tree and cleaned up the changelog, so I assumed that was enough.
> I'll repost if needed.
I'm happy to take patches from Jiri (or pull from Jiri's tree).
Jiri, I'll count on you to pass this on when you are ready.
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
* [GIT PATCH] SCTP updates
From: Sridhar Samudrala @ 2006-05-19 22:24 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
Dave,
Please pull the following SCTP updates from
master.kernel.org:/pub/scm/linux/kernel/git/sridhar/lksctp-2.6.git
Thanks
Sridhar
include/net/sctp/command.h | 1
include/net/sctp/sctp.h | 6 +-
net/sctp/input.c | 144 +++++++++++++++++++++++++-------------------
net/sctp/sm_sideeffect.c | 16 ++++-
net/sctp/sm_statefuns.c | 81 +++++++++++++++++--------
net/sctp/socket.c | 29 +++++----
6 files changed, 168 insertions(+), 109 deletions(-)
commit b89498a1c2941c00889dd025f52dcb653a5083bc
Author: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Fri May 19 14:32:06 2006 -0700
[SCTP]: Allow linger to abort 1-N style sockets.
Enable SO_LINGER functionality for 1-N style sockets. The socket API
draft will be clarfied to allow for this functionality. The linger
settings will apply to all associations on a given socket.
Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
commit a601266e4f3c479790f373c2e3122a766d123652
Author: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Fri May 19 14:25:53 2006 -0700
[SCTP]: Validate the parameter length in HB-ACK chunk.
If SCTP receives a badly formatted HB-ACK chunk, it is possible
that we may access invalid memory and potentially have a buffer
overflow. We should really make sure that the chunk format is
what we expect, before attempting to touch the data.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
commit dd2d1c6f2958d027e4591ca5d2a04dfe36ca6512
Author: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Fri May 19 11:52:20 2006 -0700
[SCTP]: Respect the real chunk length when walking parameters.
When performing bound checks during the parameter processing, we
want to use the real chunk and paramter lengths for bounds instead
of the rounded ones. This prevents us from potentially walking of
the end if the chunk length was miscalculated. We still use rounded
lengths when advancing the pointer. This was found during a
conformance test that changed the chunk length without modifying
parameters.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
commit 61c9fed41638249f8b6ca5345064eb1beb50179f
Author: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Fri May 19 11:01:18 2006 -0700
[SCTP]: A better solution to fix the race between sctp_peeloff() and
sctp_rcv().
The goal is to hold the ref on the association/endpoint throughout the
state-machine process. We accomplish like this:
/* ref on the assoc/ep is taken during lookup */
if owned_by_user(sk)
sctp_add_backlog(skb, sk);
else
inqueue_push(skb, sk);
/* drop the ref on the assoc/ep */
However, in sctp_add_backlog() we take the ref on assoc/ep and hold it
while the skb is on the backlog queue. This allows us to get rid of the
sock_hold/sock_put in the lookup routines.
Now sctp_backlog_rcv() needs to account for potential association move.
In the unlikely event that association moved, we need to retest if the
new socket is locked by user. If we don't this, we may have two packets
racing up the stack toward the same socket and we can't deal with it.
If the new socket is still locked, we'll just add the skb to its backlog
continuing to hold the ref on the association. This get's rid of the
need to move packets from one backlog to another and it also safe in
case new packets arrive on the same backlog queue.
The last step, is to lock the new socket when we are moving the
association to it. This is needed in case any new packets arrive on
the association when it moved. We want these to go to the backlog since
we would like to avoid the race between this new packet and a packet
that may be sitting on the backlog queue of the old socket toward the
same association.
Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
commit 8de8c8738086501bbe3057ed6f4b70dded657488
Author: Sridhar Samudrala <sri@us.ibm.com>
Date: Fri May 19 10:58:12 2006 -0700
[SCTP]: Set sk_err so that poll wakes up after a non-blocking connect failure.
Also fix some other cases where sk_err is not set for 1-1 style sockets.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
^ permalink raw reply
* Re: [GIT PATCH] SCTP updates
From: David S. Miller @ 2006-05-19 23:02 UTC (permalink / raw)
To: sri; +Cc: netdev, lksctp-developers
In-Reply-To: <1148077498.9764.3.camel@w-sridhar2.beaverton.ibm.com>
From: Sridhar Samudrala <sri@us.ibm.com>
Date: Fri, 19 May 2006 15:24:58 -0700
> Please pull the following SCTP updates from
> master.kernel.org:/pub/scm/linux/kernel/git/sridhar/lksctp-2.6.git
Pulled, thanks a lot Sridhar.
^ 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