* Re: sky2 1.3-rc1
From: Stephen Hemminger @ 2006-05-05 19:43 UTC (permalink / raw)
To: Daniel Drake
Cc: Thomas Glanzmann, Bill Hoover, Bertrand Jacquin, micheleschi,
netdev, teppic74
In-Reply-To: <445B9C93.4070406@gentoo.org>
On Fri, 05 May 2006 19:42:27 +0100
Daniel Drake <dsd@gentoo.org> wrote:
> Stephen Hemminger wrote:
> > What is happening is that if there is a misconfiguration and irq routing
> > is messed up (ie edge trigged). The driver will degenerate to polling every 100ms.
> > If your system is this misconfigured, then ACPI or the BIOS needs to be fixed
> > and the driver really only needs to work well enough to get the bug report out ;-)
>
> Ok, thanks for the explanation.
>
> Can you give any hints as to how we can classify this misconfiguration?
> Barry's system has a level triggered IRQ assigned to sky2, and that IRQ
> is not shared:
>
> http://bugs.gentoo.org/show_bug.cgi?id=132056#c3
>
> I'm just looking for something I can take to the ACPI developers, other
> than "its broken because Stephen said so" ;)
Try running idle_timeout=0 module parameter. In that case there will be no
polling timer. If it just hangs, then the problem is missed interrupt.
You could use this to see if you are getting irq's
--- sky2.orig/drivers/net/sky2.c
+++ sky2/drivers/net/sky2.c
@@ -2125,6 +2125,9 @@ static int sky2_poll(struct net_device *
int work_done = 0;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
+ if (netif_msg_intr((struct sky2_port *) netdev_priv(dev0)))
+ printk(KERN_DEBUG PFX "poll status %#x\n", status);
+
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
@@ -2183,6 +2186,9 @@ static irqreturn_t sky2_intr(int irq, vo
if (status == 0 || status == ~0)
return IRQ_NONE;
+ if (netif_msg_intr((struct sky2_port *) netdev_priv(dev0)))
+ printk(KERN_DEBUG PFX "irq status %#x\n", status);
+
prefetch(&hw->st_le[hw->st_idx]);
if (likely(__netif_rx_schedule_prep(dev0)))
__netif_rx_schedule(dev0);
^ permalink raw reply
* A custom Logo that expresses your company! (ID3712810)
From: Haley Rose @ 2006-05-05 22:41 UTC (permalink / raw)
To: ner
vay
Our art team creates a custom logo for you, based on your needs. Years of experience have taught us how to create a logo that makes a statement that is unique to you.
In a professional manner we learn about your image and how you would like the world to perceive you and your company. With this information we then create a logo that is not only unique but reflects the purpose of you and your company.
For value and a logo that reflects your image, take a few minutes and visit Logo Maker!
http://commend.info.logotip-marke.com
Sincerely,
Logo Design Team
alb bark crewmen
^ permalink raw reply
* [PATCH 4/4] [SCTP]: Fix state table entries for chunks received in CLOSED state.
From: Sridhar Samudrala @ 2006-05-05 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
[SCTP]: Fix state table entries for chunks received in CLOSED state.
Discard an unexpected chunk in CLOSED state rather can calling BUG().
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
net/sctp/sm_statetable.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 75ef104..8bcca56 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -366,9 +366,9 @@ #define TYPE_SCTP_ECN_ECNE { \
/* SCTP_STATE_EMPTY */ \
{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \
- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */ \
- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \
{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_ESTABLISHED */ \
@@ -380,7 +380,7 @@ #define TYPE_SCTP_ECN_ECNE { \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_ECN_ECNE */
#define TYPE_SCTP_ECN_CWR { \
@@ -401,7 +401,7 @@ #define TYPE_SCTP_ECN_CWR { \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_ECN_CWR */
#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
@@ -647,7 +647,7 @@ #define TYPE_SCTP_PRIMITIVE_REQUESTHEART
/* SCTP_STATE_EMPTY */ \
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \
- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */ \
{.fn = sctp_sf_do_prm_requestheartbeat, \
.name = "sctp_sf_do_prm_requestheartbeat"}, \
^ permalink raw reply related
* [PATCH 3/4] [SCTP]: Fix panic's when receiving fragmented SCTP control chunks.
From: Sridhar Samudrala @ 2006-05-05 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
[SCTP]: Fix panic's when receiving fragmented SCTP control chunks.
Use pskb_pull() to handle incoming COOKIE_ECHO and HEARTBEAT chunks that
are received as skb's with fragment list.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
net/sctp/sm_statefuns.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 6834032..27514f3 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(co
*/
chunk->subh.cookie_hdr =
(struct sctp_signed_cookie *)chunk->skb->data;
- skb_pull(chunk->skb,
- ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
+ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t)))
+ goto nomem;
/* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
* "Z" will reply with a COOKIE ACK chunk after building a TCB
@@ -965,7 +966,8 @@ sctp_disposition_t sctp_sf_beat_8_3(cons
*/
chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
- skb_pull(chunk->skb, paylen);
+ if (!pskb_pull(chunk->skb, paylen))
+ goto nomem;
reply = sctp_make_heartbeat_ack(asoc, chunk,
chunk->subh.hb_hdr, paylen);
@@ -1860,8 +1862,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupc
* are in good shape.
*/
chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
- skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
- sizeof(sctp_chunkhdr_t));
+ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t)))
+ goto nomem;
/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
* of a duplicate COOKIE ECHO match the Verification Tags of the
^ permalink raw reply related
* [PATCH 2/4] [SCTP]: Prevent possible infinite recursion with multiple bundled DATA.
From: Sridhar Samudrala @ 2006-05-05 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
[SCTP]: Prevent possible infinite recursion with multiple bundled DATA.
There is a rare situation that causes lksctp to go into infinite recursion
and crash the system. The trigger is a packet that contains at least the
first two DATA fragments of a message bundled together. The recursion is
triggered when the user data buffer is smaller that the full data message.
The problem is that we clone the skb for every fragment in the message.
When reassembling the full message, we try to link skbs from the "first
fragment" clone using the frag_list. However, since the frag_list is shared
between two clones in this rare situation, we end up setting the frag_list
pointer of the second fragment to point to itself. This causes
sctp_skb_pull() to potentially recurse indefinitely.
Proposed solution is to make a copy of the skb when attempting to link
things using frag_list.
Signed-off-by: Vladislav Yasevich <vladsilav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
net/sctp/ulpqueue.c | 27 +++++++++++++++++++++++++--
1 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 2080b2d..9505c88 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm
static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
{
struct sk_buff *pos;
+ struct sk_buff *new = NULL;
struct sctp_ulpevent *event;
struct sk_buff *pnext, *last;
struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
@@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_r
*/
if (last)
last->next = pos;
- else
- skb_shinfo(f_frag)->frag_list = pos;
+ else {
+ if (skb_cloned(f_frag)) {
+ /* This is a cloned skb, we can't just modify
+ * the frag_list. We need a new skb to do that.
+ * Instead of calling skb_unshare(), we'll do it
+ * ourselves since we need to delay the free.
+ */
+ new = skb_copy(f_frag, GFP_ATOMIC);
+ if (!new)
+ return NULL; /* try again later */
+
+ new->sk = f_frag->sk;
+
+ skb_shinfo(new)->frag_list = pos;
+ } else
+ skb_shinfo(f_frag)->frag_list = pos;
+ }
/* Remove the first fragment from the reassembly queue. */
__skb_unlink(f_frag, queue);
+
+ /* if we did unshare, then free the old skb and re-assign */
+ if (new) {
+ kfree_skb(f_frag);
+ f_frag = new;
+ }
+
while (pos) {
pnext = pos->next;
^ permalink raw reply related
* [PATCH 1/4] [SCTP]: Allow spillover of receiver buffer to avoid deadlock
From: Sridhar Samudrala @ 2006-05-05 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
Dave,
Please apply the following 4 SCTP patches to 2.6 tree.
Thanks
Sridhar
[SCTP]: Allow spillover of receive buffer to avoid deadlock.
This patch fixes a deadlock situation in the receive path by allowing
temporary spillover of the receive buffer.
- If the chunk we receive has a tsn that immediately follows the ctsn,
accept it even if we run out of receive buffer space and renege data with
higher TSNs.
- Once we accept one chunk in a packet, accept all the remaining chunks
even if we run out of receive buffer space.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Mark Butler <butlerm@middle.net>
Acked-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
include/net/sctp/structs.h | 1 +
net/sctp/inqueue.c | 1 +
net/sctp/sm_statefuns.c | 46 ++++++++++++++++++++++++++++++++++----------
3 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index eba99f3..7f4fea1 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -712,6 +712,7 @@ struct sctp_chunk {
__u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */
__s8 fast_retransmit; /* Is this chunk fast retransmitted? */
__u8 tsn_missing_report; /* Data chunk missing counter. */
+ __u8 data_accepted; /* At least 1 chunk in this packet accepted */
};
void sctp_chunk_hold(struct sctp_chunk *);
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 297b895..cf0c767 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct s
/* This is the first chunk in the packet. */
chunk->singleton = 1;
ch = (sctp_chunkhdr_t *) chunk->skb->data;
+ chunk->data_accepted = 0;
}
chunk->chunk_hdr = ch;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 2b9a832..6834032 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -5151,7 +5151,9 @@ static int sctp_eat_data(const struct sc
int tmp;
__u32 tsn;
int account_value;
+ struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
struct sock *sk = asoc->base.sk;
+ int rcvbuf_over = 0;
data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
@@ -5162,10 +5164,16 @@ static int sctp_eat_data(const struct sc
/* ASSERT: Now skb->data is really the user data. */
/*
- * if we are established, and we have used up our receive
- * buffer memory, drop the frame
- */
- if (asoc->state == SCTP_STATE_ESTABLISHED) {
+ * If we are established, and we have used up our receive buffer
+ * memory, think about droping the frame.
+ * Note that we have an opportunity to improve performance here.
+ * If we accept one chunk from an skbuff, we have to keep all the
+ * memory of that skbuff around until the chunk is read into user
+ * space. Therefore, once we accept 1 chunk we may as well accept all
+ * remaining chunks in the skbuff. The data_accepted flag helps us do
+ * that.
+ */
+ if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) {
/*
* If the receive buffer policy is 1, then each
* association can allocate up to sk_rcvbuf bytes
@@ -5176,9 +5184,25 @@ static int sctp_eat_data(const struct sc
account_value = atomic_read(&asoc->rmem_alloc);
else
account_value = atomic_read(&sk->sk_rmem_alloc);
-
- if (account_value > sk->sk_rcvbuf)
- return SCTP_IERROR_IGNORE_TSN;
+ if (account_value > sk->sk_rcvbuf) {
+ /*
+ * We need to make forward progress, even when we are
+ * under memory pressure, so we always allow the
+ * next tsn after the ctsn ack point to be accepted.
+ * This lets us avoid deadlocks in which we have to
+ * drop frames that would otherwise let us drain the
+ * receive queue.
+ */
+ if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn)
+ return SCTP_IERROR_IGNORE_TSN;
+
+ /*
+ * We're going to accept the frame but we should renege
+ * to make space for it. This will send us down that
+ * path later in this function.
+ */
+ rcvbuf_over = 1;
+ }
}
/* Process ECN based congestion.
@@ -5226,6 +5250,7 @@ static int sctp_eat_data(const struct sc
datalen -= sizeof(sctp_data_chunk_t);
deliver = SCTP_CMD_CHUNK_ULP;
+ chunk->data_accepted = 1;
/* Think about partial delivery. */
if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
@@ -5242,7 +5267,8 @@ static int sctp_eat_data(const struct sc
* large spill over.
*/
if (!asoc->rwnd || asoc->rwnd_over ||
- (datalen > asoc->rwnd + asoc->frag_point)) {
+ (datalen > asoc->rwnd + asoc->frag_point) ||
+ rcvbuf_over) {
/* If this is the next TSN, consider reneging to make
* room. Note: Playing nice with a confused sender. A
@@ -5250,8 +5276,8 @@ static int sctp_eat_data(const struct sc
* space and in the future we may want to detect and
* do more drastic reneging.
*/
- if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
- (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
+ if (sctp_tsnmap_has_gap(map) &&
+ (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
deliver = SCTP_CMD_RENEGE;
} else {
^ permalink raw reply related
* Re: [rfc][patch] ipvs: use proper timeout instead of fixed value
From: Andy Gospodarek @ 2006-05-05 18:57 UTC (permalink / raw)
To: Horms; +Cc: Andy Gospodarek, netdev, wensong, ja
In-Reply-To: <20060505032052.GY32328@verge.net.au>
On Fri, May 05, 2006 at 12:20:54PM +0900, Horms wrote:
>
> Sorry, I missunderstood your patch completely the first time around.
> Yes I think this is an excellent idea. Assuming its tested and works
> I'm happy to sign off on it and prod DaveM.
Horms,
I'll get a setup together and post results when I have them.
-andy
^ permalink raw reply
* Re: sky2 1.3-rc1
From: Daniel Drake @ 2006-05-05 18:42 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Thomas Glanzmann, Bill Hoover, Bertrand Jacquin, micheleschi,
netdev, teppic74
In-Reply-To: <20060505104536.2baefa5e@localhost.localdomain>
Stephen Hemminger wrote:
> What is happening is that if there is a misconfiguration and irq routing
> is messed up (ie edge trigged). The driver will degenerate to polling every 100ms.
> If your system is this misconfigured, then ACPI or the BIOS needs to be fixed
> and the driver really only needs to work well enough to get the bug report out ;-)
Ok, thanks for the explanation.
Can you give any hints as to how we can classify this misconfiguration?
Barry's system has a level triggered IRQ assigned to sky2, and that IRQ
is not shared:
http://bugs.gentoo.org/show_bug.cgi?id=132056#c3
I'm just looking for something I can take to the ACPI developers, other
than "its broken because Stephen said so" ;)
Thanks.
Daniel
^ permalink raw reply
* Re: Machine check in bcm43xx_phy_initg
From: Michael Buesch @ 2006-05-05 18:27 UTC (permalink / raw)
To: David Woodhouse; +Cc: linville, bcm43xx-dev, Andrew Morton, netdev
In-Reply-To: <1146853122.2766.42.camel@pmac.infradead.org>
On Friday 05 May 2006 20:18, you wrote:
> On Fri, 2006-05-05 at 19:42 +0200, Michael Buesch wrote:
> > > Signed-off-by: David Woodhouse <dwmw2@infradead.org>
> > Signed-off-by: Michael Buesch <mb@bu3sch.de>
> >
> > John, please apply. I will also send a patch for d80211.
>
> Would be good to get this into 2.6.17 too.
Absolutely, as it crashes machines.
That was my intention. ;)
--
Greetings Michael.
^ permalink raw reply
* Re: Machine check in bcm43xx_phy_initg
From: David Woodhouse @ 2006-05-05 18:18 UTC (permalink / raw)
To: Michael Buesch; +Cc: linville, bcm43xx-dev, Andrew Morton, netdev
In-Reply-To: <200605051942.39552.mb@bu3sch.de>
On Fri, 2006-05-05 at 19:42 +0200, Michael Buesch wrote:
> > Signed-off-by: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Michael Buesch <mb@bu3sch.de>
>
> John, please apply. I will also send a patch for d80211.
Would be good to get this into 2.6.17 too.
--
dwmw2
^ permalink raw reply
* Re: sky2 1.3-rc1
From: Stephen Hemminger @ 2006-05-05 17:45 UTC (permalink / raw)
To: Thomas Glanzmann
Cc: Daniel Drake, Bill Hoover, Bertrand Jacquin, micheleschi, netdev,
teppic74
In-Reply-To: <20060505173509.GK2757@cip.informatik.uni-erlangen.de>
On Fri, 5 May 2006 19:35:09 +0200
Thomas Glanzmann <sithglan@stud.uni-erlangen.de> wrote:
> Hello,
>
> > > http://developer.osdl.org/shemminger/prototypes/sky2-1.3-rc1.tar.bz2
>
> > v0.15:
> > 64 bytes from 10.0.0.138: icmp_seq=2 ttl=64 time=0.467 ms
>
> > v1.3-rc1:
> > 64 bytes from 10.0.0.138: icmp_seq=4 ttl=64 time=32.9 ms
>
> I can't confirm this. For me it is just perfect:
>
> 64 bytes from 89.106.66.1: icmp_seq=1 ttl=64 time=0.278 ms
>
> 0000:04:00.0 Ethernet controller: Marvell Technology Group Ltd.: Unknown device 4361 (rev 17)
>
> Thomas
What is happening is that if there is a misconfiguration and irq routing
is messed up (ie edge trigged). The driver will degenerate to polling every 100ms.
If your system is this misconfigured, then ACPI or the BIOS needs to be fixed
and the driver really only needs to work well enough to get the bug report out ;-)
The older driver was doing rewhacking the Transmit IRQ status timer,
so it would give a bogus transmit status interrupt and that was masking
issues.
^ permalink raw reply
* [PATCH] bcm43xx-d80211: Fix access to non-existent PHY registers
From: Michael Buesch @ 2006-05-05 17:50 UTC (permalink / raw)
To: John W. Linville; +Cc: bcm43xx-dev, netdev, David Woodhouse
John, this is the same patch as before, but for d80211.
Please apply to wireless-dev.
--
Fix the conditions under which we poke at the APHY registers in
bcm43xx_phy_initg() to avoid a machine check on chips where they don't
exist.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
diff --git a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
index 45da79d..1816f66 100644
--- a/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
@@ -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,
--
Greetings Michael.
^ permalink raw reply related
* Re: Machine check in bcm43xx_phy_initg
From: Michael Buesch @ 2006-05-05 17:42 UTC (permalink / raw)
To: linville; +Cc: bcm43xx-dev, Andrew Morton, netdev, David Woodhouse
In-Reply-To: <1146849577.2766.18.camel@pmac.infradead.org>
On Friday 05 May 2006 19:19, David Woodhouse wrote:
> On Fri, 2006-05-05 at 12:59 -0400, Joseph Jezak wrote:
> > I fixed the specs, it should be bcm->chip_package == 2, sorry for the
> > mistake.
>
> Thanks. The correct patch should look like this then...
>
> [BCM43xx] Fix access to non-existent PHY registers
>
> Fix the conditions under which we poke at the APHY registers in
> bcm43xx_phy_initg() to avoid a machine check on chips where they don't
> exist.
>
> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
John, please apply. I will also send a patch for d80211.
> --- linux-2.6.16.ppc64/drivers/net/wireless/bcm43xx/bcm43xx_phy.c~ 2006-05-04 19:16:09.000000000 +0100
> +++ linux-2.6.16.ppc64/drivers/net/wireless/bcm43xx/bcm43xx_phy.c 2006-05-05 17:22:57.000000000 +0100
> @@ -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,
>
--
Greetings Michael.
^ permalink raw reply
* Re: sky2 1.3-rc1
From: Thomas Glanzmann @ 2006-05-05 17:35 UTC (permalink / raw)
To: Daniel Drake
Cc: Stephen Hemminger, Bill Hoover, Bertrand Jacquin, micheleschi,
netdev, teppic74
In-Reply-To: <445B626B.1070407@gentoo.org>
Hello,
> > http://developer.osdl.org/shemminger/prototypes/sky2-1.3-rc1.tar.bz2
> v0.15:
> 64 bytes from 10.0.0.138: icmp_seq=2 ttl=64 time=0.467 ms
> v1.3-rc1:
> 64 bytes from 10.0.0.138: icmp_seq=4 ttl=64 time=32.9 ms
I can't confirm this. For me it is just perfect:
64 bytes from 89.106.66.1: icmp_seq=1 ttl=64 time=0.278 ms
0000:04:00.0 Ethernet controller: Marvell Technology Group Ltd.: Unknown device 4361 (rev 17)
Thomas
^ permalink raw reply
* Re: [x86_64, NET] smp_rmb() in dst_destroy() seems very expensive, ditto in kfree_skb()
From: Andi Kleen @ 2006-05-05 17:05 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, netdev
In-Reply-To: <445B11A3.1020407@cosmosbay.com>
On Friday 05 May 2006 10:49, Eric Dumazet wrote:
> On a dual opteron box, I noticed high oprofile numbers in net/core/dst.c
> , function dst_destroy(struct dst_entry * dst)
>
> It appears the smb_rmb() done at the begining of dst_destroy() is the
> killer (this is a lfence machine instruction, that apparently is doing
> a *lot* of things... may be IO related...) that is responsible for 80%
> of the cpu time used by the whole function.
>
> I dont understand very much all variety of available barriers, and why
> this smb_rmb() is used in dst_destroy().
> I missed the corresponding wmb that should be done somewhere in the dst
> code.
>
> Do we have an alternative to smp_rmb() in the dst_destroy()/ kfree_skb()
> context ?
Eliminating it probably wouldn't help very much - it just flushes the
loads already in flight. If it didn't do that the next smp_rmb() would.
I'm surprised there are that many though. Normally kernel code is spagetti
enough that the CPU cannot speculate too many loads ahead.
But are you 100% sure the cost is not in the lock decl ? That would make
more sense. Perhaps profile for cache misses too and double check?
-Andi
^ permalink raw reply
* Re: dBm cutoff at -1dBm is too low
From: Jean Tourrilhes @ 2006-05-05 17:28 UTC (permalink / raw)
To: Pavel Roskin; +Cc: NetDev
In-Reply-To: <1146760665.5294.65.camel@dv>
On Thu, May 04, 2006 at 12:37:45PM -0400, Pavel Roskin wrote:
> Hello, Jean!
>
> I'm converting Orinoco to the dBm reporting, and it turns out that the
> best signal iwconfig will report is -1dBm (0.8mW). This would happen if
> qual->level has its highest value of 255. Please see this code from
> wireless_tools.29.pre10:
>
> len = snprintf(buffer, buflen, "Signal level%c%d dBm ",
> qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':',
> qual->level - 0x100);
Yes, that's correct.
Note that the main limitation is that before I introduced the
explicit IW_QUAL_DBM in WE-19, the way to know if the value was
relative or dBm was to use the 'sign' of it, i.e. value above 0 were
non-dBm. The test is a few line before this snipset :
---------------------------------------------------------
/* Check if the statistics are in dBm or relative */
if((qual->updated & IW_QUAL_DBM)
|| (qual->level > range->max_qual.level))
{
---------------------------------------------------------
There are still quite a few drivers which have not been
converted to use IW_QUAL_DBM, so I don't want to drop the backward
compatibility yet.
> With most cards transmitting at 100mW and some going as high as 500mW,
> it's not unreasonable to expect that the received signal may exceed 1mW
> for closely located receivers with good antennas. I have seen HostAP
> reporting as much as 3mW through the proc filesystem!
My rationale was two fold.
First, such high values are quite unlikely, because cards need
to be very close, which does not happen that often. Power is limited
by spec and power consumption, so unlikely to go higher than
this. Also, I'm surprised that the card receiver does not saturate
with such high receive power, but I would question the accuracy of the
measurement.
Second, the measurement is useful mostly in marginal
conditions. When signal is great, you don't really care, when signal
is low, you want to tweak your system to improve reception.
> Wouldn't it be better to put the cutoff at a higher value? The simplest
> approach would be to treat qual->level and qual->noise as signed char,
> which would put the cutoff and 127dBm. 500 gigawatts should be enough
> for everyone :-)
FCC says Tx 1W @ 2.4 GHz, ETSI says Tx 100mW @ 2.4 Gz. Yeah,
you could use directional antennas. So, realistically, we only need to
extend to +30dBm.
On the other hand, I expect that with MIMO and UWB we would
start to receive signal weaker than what we currently do, and you
don't want to cutoff the bottom of the range (is -128dBm enough ?).
I tried to use 'signed' in the struct a long while ago, and
for some reason it broke left and right, I don't remember the
details. So, whatever we do, it would not be straightforward.
> Regards,
> Pavel Roskin
Have fun...
Jean
^ permalink raw reply
* Re: [Netem] where i can find this netem patch?
From: Stephen Hemminger @ 2006-05-05 17:15 UTC (permalink / raw)
To: George Nychis; +Cc: netdev, lartc, netem
In-Reply-To: <445B6A67.7020809@cmu.edu>
On Fri, 05 May 2006 11:08:23 -0400
George Nychis <gnychis@cmu.edu> wrote:
> Hi,
>
> I need help finding this patch that Stephen made.
>
> He sent me a patch, but i do not think its related to the patch that
> solved this problem. I will include the patch he did forward to me at
> the bottom.
> However here is the problem, i even rtied his misspelling of change :)
>
> thorium-ini 15849-tests # tc qdisc add dev ath0 root handle 1:0 netem
> drop 0%
> thorium-ini 15849-tests # tc qdisc add dev ath0 parent 1:1 handle 10:
> xcp capacity 54Mbit limit 500
> thorium-ini 15849-tests # tc qdisc change dev ath0 root handle 1:0 netem
> drop 1%
> RTNETLINK answers: Invalid argument
>
The problem was you are giving handle 1:0 so the change request was
going to xcp. And xcp doesn't understand netem rtnetlink message.
You want to do:
# tc qdisc change dev ath0 root netem drop 1%
^ permalink raw reply
* Very long list of struct dst_entry in dst_garbage_list
From: Eric Dumazet @ 2006-05-05 16:13 UTC (permalink / raw)
To: netdev
In-Reply-To: <445B11A3.1020407@cosmosbay.com>
I noticed that after a 'ip route flush cache' (manual or timer
triggered) on a busy server, XXXXX entries are added to dst_garbage_list.
(XXXXX depends on the number of established sockets)
Every 1/10th second (DST_GC_MIN) , net/core/dst.c::dst_run_gc() is
fired, and try to free some entries from the list, but many entries have
a non null refcnt and stay in the list for the next run.
Linux version is 2.6.17-rc3.
Do you think a rework of dst_run_gc() function is necessary, (using a
batch mode to limit the number of entries examined at each run), or is
it a "should not happen, something is broken" situation ?
Eric
^ permalink raw reply
* Re: Fw: [Bugme-new] [Bug 6495] New: Vlan MTU Fragmentation
From: Ben Greear @ 2006-05-05 15:57 UTC (permalink / raw)
To: Andrew Morton; +Cc: netdev, bugme-daemon@kernel-bugs.osdl.org
In-Reply-To: <20060504235628.33041b55.akpm@osdl.org>
Andrew Morton wrote:
>
> Begin forwarded message:
>
> Date: Thu, 4 May 2006 23:15:56 -0700
> From: bugme-daemon@bugzilla.kernel.org
> To: bugme-new@lists.osdl.org
> Subject: [Bugme-new] [Bug 6495] New: Vlan MTU Fragmentation
>
>
> http://bugzilla.kernel.org/show_bug.cgi?id=6495
>
> Summary: Vlan MTU Fragmentation
> Kernel Version: 2.6.16.12
> Status: NEW
> Severity: normal
> Owner: shemminger@osdl.org
> Submitter: slavon@bigtelecom.ru
>
>
> Steps to reproduce:
>
> ifconfing eth0 mtu 1500
> ifconfing eth0.100 mtu 1500
>
> ping www.ru -s 2000
> -- BAD --
>
> ----------------
>
> ifconfing eth0 mtu 1500
> ifconfing eth0.100 mtu 1496
>
> ping www.ru -s 2000
> --NORMAL--
This is almost definately a bug in the ethernet driver. The driver needs
to be modified so that it can send/receive pkts that are MTU + 4 bytes for the
VLAN header.
We need to know what NIC/driver this user is using...
Ben
>
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* [PATCH] bcm43xx: Fix array overrun in bcm43xx_geo_init
From: Michael Buesch @ 2006-05-05 15:23 UTC (permalink / raw)
To: John W. Linville; +Cc: Andrew Morton, Stefano Brivio, bcm43xx-dev, netdev
The problem here is that the bcm34xx driver and the ieee80211
stack do not agree on what channels are possible for 802.11a.
The ieee80211 stack only wants channels between 34 and 165, while
the bcm43xx driver accepts anything from 0 to 200. I made the
bcm43xx driver comply with the ieee80211 stack expectations, by
using the proper constants.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
[mb]: Reduce stack usage by kzalloc-ing ieee80211_geo
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c 2006-05-05 17:01:08.000000000 +0200
+++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.c 2006-05-05 17:19:59.000000000 +0200
@@ -939,9 +939,9 @@
return 0;
}
-static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
+static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
{
- struct ieee80211_geo geo;
+ struct ieee80211_geo *geo;
struct ieee80211_channel *chan;
int have_a = 0, have_bg = 0;
int i;
@@ -949,7 +949,10 @@
struct bcm43xx_phyinfo *phy;
const char *iso_country;
- memset(&geo, 0, sizeof(geo));
+ geo = kzalloc(sizeof(*geo), GFP_KERNEL);
+ if (!geo)
+ return -ENOMEM;
+
for (i = 0; i < bcm->nr_80211_available; i++) {
phy = &(bcm->core_80211_ext[i].phy);
switch (phy->type) {
@@ -967,31 +970,36 @@
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
if (have_a) {
- for (i = 0, channel = 0; channel < 201; channel++) {
- chan = &geo.a[i++];
+ for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
+ channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
+ chan = &geo->a[i++];
chan->freq = bcm43xx_channel_to_freq_a(channel);
chan->channel = channel;
}
- geo.a_channels = i;
+ geo->a_channels = i;
}
if (have_bg) {
- for (i = 0, channel = 1; channel < 15; channel++) {
- chan = &geo.bg[i++];
+ for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
+ channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+ chan = &geo->bg[i++];
chan->freq = bcm43xx_channel_to_freq_bg(channel);
chan->channel = channel;
}
- geo.bg_channels = i;
+ geo->bg_channels = i;
}
- memcpy(geo.name, iso_country, 2);
+ memcpy(geo->name, iso_country, 2);
if (0 /*TODO: Outdoor use only */)
- geo.name[2] = 'O';
+ geo->name[2] = 'O';
else if (0 /*TODO: Indoor use only */)
- geo.name[2] = 'I';
+ geo->name[2] = 'I';
else
- geo.name[2] = ' ';
- geo.name[3] = '\0';
+ geo->name[2] = ' ';
+ geo->name[3] = '\0';
+
+ ieee80211_set_geo(bcm->ieee, geo);
+ kfree(geo);
- ieee80211_set_geo(bcm->ieee, &geo);
+ return 0;
}
/* DummyTransmission function, as documented on
@@ -3464,6 +3472,9 @@
goto err_80211_unwind;
bcm43xx_wireless_core_disable(bcm);
}
+ err = bcm43xx_geo_init(bcm);
+ if (err)
+ goto err_80211_unwind;
bcm43xx_pctl_set_crystal(bcm, 0);
/* Set the MAC address in the networking subsystem */
@@ -3472,8 +3483,6 @@
else
memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
- bcm43xx_geo_init(bcm);
-
snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
"Broadcom %04X", bcm->chip_id);
Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.h
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.h 2006-05-01 17:42:02.000000000 +0200
+++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.h 2006-05-05 17:01:33.000000000 +0200
@@ -118,12 +118,14 @@
static inline
int bcm43xx_is_valid_channel_a(u8 channel)
{
- return (channel <= 200);
+ return (channel >= IEEE80211_52GHZ_MIN_CHANNEL
+ && channel <= IEEE80211_52GHZ_MAX_CHANNEL);
}
static inline
int bcm43xx_is_valid_channel_bg(u8 channel)
{
- return (channel >= 1 && channel <= 14);
+ return (channel >= IEEE80211_24GHZ_MIN_CHANNEL
+ && channel <= IEEE80211_24GHZ_MAX_CHANNEL);
}
static inline
int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
--
Greetings Michael.
^ permalink raw reply
* where i can find this netem patch?
From: George Nychis @ 2006-05-05 15:08 UTC (permalink / raw)
To: netdev; +Cc: lartc, netem
In-Reply-To: <20060428102421.7d304ca6@localhost.localdomain>
Hi,
I need help finding this patch that Stephen made.
He sent me a patch, but i do not think its related to the patch that
solved this problem. I will include the patch he did forward to me at
the bottom.
However here is the problem, i even rtied his misspelling of change :)
thorium-ini 15849-tests # tc qdisc add dev ath0 root handle 1:0 netem
drop 0%
thorium-ini 15849-tests # tc qdisc add dev ath0 parent 1:1 handle 10:
xcp capacity 54Mbit limit 500
thorium-ini 15849-tests # tc qdisc change dev ath0 root handle 1:0 netem
drop 1%
RTNETLINK answers: Invalid argument
thorium-ini 15849-tests # tc qdisc chang dev ath0 root handle 1:0 netem
drop 1%
RTNETLINK answers: Invalid argument
thorium-ini 15849-tests # tc qdisc change dev ath0 root handle 1: netem
drop 1%
RTNETLINK answers: Invalid argument
here is the patch i was forwarded, but did not solve this problem:
--- linux-2.6.orig/net/sched/sch_netem.c
+++ linux-2.6/net/sched/sch_netem.c
@@ -167,7 +167,7 @@ static int netem_enqueue(struct sk_buff
if (count == 0) {
sch->qstats.drops++;
kfree_skb(skb);
- return NET_XMIT_DROP;
+ return NET_XMIT_BYPASS;
}
/*
I'd greatly appreciate any help solving the change problem.
Thanks!
George
Stephen Hemminger wrote:
> Loss was broken, patch sent.
>
> The following works now:
>
> # tc qdisc add dev eth1 root handle 1:0 netem loss 20%
>
> # tc qdisc add dev eth1 parent 1:1 handle 10: tbf \
> rate 256kbit buffer 1600 limit 3000
> # ping -f -c 1000 shell
>
> 1000 packets transmitted, 781 received, 21% packet loss, time 3214ms
> rtt min/avg/max/mdev = 0.187/0.398/3.763/0.730 ms, ipg/ewma 3.217/0.538 ms
>
> # tc qdisc chang dev eth1 handle 1: netem loss 1%
> # ping -f -c 1000 shell
>
> 1000 packets transmitted, 990 received, 1% packet loss, time 2922ms
> rtt min/avg/max/mdev = 0.187/2.739/3.298/0.789 ms, ipg/ewma 2.924/2.084 ms
>
>
>
^ permalink raw reply
* Re: sky2 1.3-rc1
From: Daniel Drake @ 2006-05-05 14:34 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Bill Hoover, Thomas Glanzmann, Bertrand Jacquin, micheleschi,
netdev, teppic74
In-Reply-To: <20060503120507.4558c675@localhost.localdomain>
Stephen Hemminger wrote:
> Here is a new version that addresses some of the outstanding bugs.
> * There was a race in receive processing that would cause hang
> * Some more support for Yukon Ultra found in dual-core Centrino
> laptops (I want one of these).
>
> It does not fix the problems with dual port cards corrupting receive
> data (and possibly memory).
>
> http://developer.osdl.org/shemminger/prototypes/sky2-1.3-rc1.tar.bz2
>
> If this works for most people, I'll post as separate patches for 2.6.17
> tomorrow.
>
Barry Shilliday at http://bugs.gentoo.org/132056 reports that 1.3-rc1
solves his earlier problems introduced in v1.1 are solved. However, it's
not perfect, as latencies are much higher than they used to be.
v0.15:
64 bytes from 10.0.0.138: icmp_seq=2 ttl=64 time=0.467 ms
v1.3-rc1:
64 bytes from 10.0.0.138: icmp_seq=4 ttl=64 time=32.9 ms
Daniel
^ permalink raw reply
* [PATCH] d80211: switching management interface on/off
From: Jiri Benc @ 2006-05-05 13:17 UTC (permalink / raw)
To: Jouni Malinen; +Cc: John W. Linville, netdev, jkmaline
In-Reply-To: <20060504164423.GA12204@instant802.com>
Default management interface (wmasterXap) confuses users. This patch removes
it and gives userspace tools (such as hostapd or wpa_supplicant) possibility
to switch it on/off as needed.
To do this, a new PRISM2_PARAM_MGMT_IF iwpriv ioctl is introduced. When set,
it accepts one parameter: 1 for enabling the interface, 0 for disabling it.
When read, it returns ifindex of the management interface or -ENOENT when
the management interface is switched off.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/hostapd_ioctl.h | 1
net/d80211/ieee80211.c | 101 ++++++++++++++++++-------------------------
net/d80211/ieee80211_i.h | 3 +
net/d80211/ieee80211_iface.c | 66 ++++++++++++++++++++++++++--
net/d80211/ieee80211_ioctl.c | 16 ++++++
5 files changed, 127 insertions(+), 60 deletions(-)
--- dscape.orig/net/d80211/hostapd_ioctl.h
+++ dscape/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
--- dscape.orig/net/d80211/ieee80211.c
+++ dscape/net/d80211/ieee80211.c
@@ -1954,8 +1954,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 +1988,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 +2044,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 +2086,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 +2133,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 +2383,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 +4018,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,7 +4051,7 @@ 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;
@@ -4038,17 +4071,11 @@ struct net_device *ieee80211_alloc_hw(si
* 0b84 *****************
* * 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);
if (mdev == NULL)
@@ -4061,15 +4088,10 @@ struct net_device *ieee80211_alloc_hw(si
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->dev_index = -1;
local->mdev = mdev;
local->rx_handlers = ieee80211_rx_handlers;
@@ -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);
--- dscape.orig/net/d80211/ieee80211_i.h
+++ dscape/net/d80211/ieee80211_i.h
@@ -518,6 +518,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 +596,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);
--- dscape.orig/net/d80211/ieee80211_iface.c
+++ dscape/net/d80211/ieee80211_iface.c
@@ -93,6 +93,63 @@ fail:
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 alloc_size, ret;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ ASSERT_RTNL();
+ alloc_size = sizeof(struct net_device) + 3 +
+ sizeof(struct ieee80211_sub_if_data) + 3;
+
+ ndev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
+ 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;
+ ieee80211_if_mgmt_setup(ndev);
+
+ 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:
+ kfree(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 +167,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: {
@@ -263,8 +321,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;
}
@@ -298,6 +355,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();
}
--- dscape.orig/net/d80211/ieee80211_ioctl.c
+++ dscape/net/d80211/ieee80211_ioctl.c
@@ -2471,6 +2471,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;
@@ -2653,6 +2663,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;
^ permalink raw reply
* Re: [PATCH] bcm43xx-d80211: proper implementation of virtual interface support
From: Jiri Benc @ 2006-05-05 10:34 UTC (permalink / raw)
To: Johannes Berg; +Cc: Ulrich Kunitz, Ivo van Doorn, Marcus Better, netdev
In-Reply-To: <1146824140.1137.67.camel@localhost>
On Fri, 05 May 2006 12:15:40 +0200, Johannes Berg wrote:
> On Fri, 2006-05-05 at 07:45 +0200, Ulrich Kunitz wrote:
> > But there could be also
> > support for one interface in AP and the other in STA mode.
>
> That's actually a much more interesting use case for WDS.
You don't need different MAC address for WDS.
Jiri
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* Re: [PATCH] bcm43xx-d80211: proper implementation of virtual interface support
From: Johannes Berg @ 2006-05-05 10:15 UTC (permalink / raw)
To: Ulrich Kunitz; +Cc: Jiri Benc, Ivo van Doorn, Marcus Better, netdev
In-Reply-To: <Pine.LNX.4.58.0605050738240.21178@p15091797.pureserver.info>
[-- Attachment #1: Type: text/plain, Size: 220 bytes --]
On Fri, 2006-05-05 at 07:45 +0200, Ulrich Kunitz wrote:
> But there could be also
> support for one interface in AP and the other in STA mode.
That's actually a much more interesting use case for WDS.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 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