* Re: [PATCH net-next] mlx4: use dev_kfree_skb() instead of dev_kfree_skb_any()
From: Or Gerlitz @ 2012-09-18 19:58 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, Yevgeny Petrilin, Or Gerlitz, Ying Cai
In-Reply-To: <1347866974.26523.53.camel@edumazet-glaptop>
On Mon, Sep 17, 2012 at 10:29 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Since commit e22979d96a5 (mlx4_en: Moving to Interrupts for TX
> completions), we no longer can free TX skb from hard IRQ, but only from
> normal softirq or process context.
>
> Therefore, we can directly call dev_kfree_skb() from
> mlx4_en_free_tx_desc() like other conventional NAPI drivers.
Hi Eric,
The team is all off till tomorrow, we will look and get back to you
Or.
^ permalink raw reply
* Re: [V4 PATCH 0/8] csiostor: Chelsio FCoE offload driver submission
From: Naresh Kumar Inna @ 2012-09-18 17:50 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-scsi@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <1347957374.2388.15.camel@dabdike.int.hansenpartnership.com>
On 9/18/2012 2:06 PM, James Bottomley wrote:
> On Tue, 2012-09-18 at 09:54, Naresh Kumar Inna wrote:
>> Hi James,
>>
>> Could you please consider merging version V4 of the driver patches, if
>> you think they are in good shape now?
>
> Well, definitely not yet; you seem to have missed the memo on readq:
>
> CC [M] drivers/scsi/cxgbi/cxgb4i/cxgb4i.o
> drivers/scsi/csiostor/csio_hw.c: In function csio_hw_mc_read:
> drivers/scsi/csiostor/csio_hw.c:194:3: error: implicit declaration of
> function readq [-Werror=implicit-function-declaration]
>
> It's only defined on platforms which can support an atomic 64 bit
> operation (which is mostly not any 32 bit platforms) ... so this could
> do with compile testing on those.
>
> To see how to handle readq/writeq in the 32 bit case, see the uses in
> fnic or qla2xxx
>
Thanks for reviewing. I will fix up readq/writeq, as well as other
32-bit compilation issues, if any.
> You also have a couple of unnecessary version.h includes.
>
I will get rid of them.
> Since you're a new driver, could you not do a correctly unlocked
> queuecommand routine? You'll find the way you've currently got it coded
> (holding the host lock for the entire queuecommand routine) is very
> performance detrimental.
>
Yes, I am aware of that. However, some of this code was written and
tested before the lock-less queuecommand came into existence. Going the
lock-less route would require me to test the driver thoroughly again. It
definitely is in my to-do list, but I would like to take that up after
the initial submission goes through. Would that be OK?
> You have a lot of locking statements which aren't easy to audit by hand
> because there are multiple unlocks. Things like this:
>
> csio_scan_finished(struct Scsi_Host *shost, unsigned long time)
> {
> struct csio_lnode *ln = shost_priv(shost);
> int rv = 0;
>
> spin_lock_irq(shost->host_lock);
> if (!ln->hwp || csio_list_deleted(&ln->sm.sm_list)) {
> spin_unlock_irq(shost->host_lock);
> return 1;
> }
>
> rv = csio_scan_done(ln, jiffies, time, csio_max_scan_tmo * HZ,
> csio_delta_scan_tmo * HZ);
>
> spin_unlock_irq(shost->host_lock);
>
> return rv;
> }
>
> Are better coded as
>
> csio_scan_finished(struct Scsi_Host *shost, unsigned long time)
> {
> struct csio_lnode *ln = shost_priv(shost);
> int rv = 1;
>
> spin_lock_irq(shost->host_lock);
> if (!ln->hwp || csio_list_deleted(&ln->sm.sm_list))
> goto out;
>
> rv = csio_scan_done(ln, jiffies, time, csio_max_scan_tmo * HZ,
> csio_delta_scan_tmo * HZ);
>
> out:
> spin_unlock_irq(shost->host_lock);
>
> return rv;
> }
>
> It's shorter and the unlock clearly matches the lock. You could even
> invert the if logic and just make the csio_scan_done() conditional on it
> avoiding the goto.
>
I will try to minimize the lock/unlock mismatch instances per your
suggestions, if not eliminate them altogether.
> I'd also really like the people who understand FC to take a look over
> this as well.
>
Sure.
Thanks,
Naresh.
^ permalink raw reply
* Re: [PATCH 0/6] llc2: Simplify llc_station
From: Ben Hutchings @ 2012-09-18 17:49 UTC (permalink / raw)
To: David Miller; +Cc: acme, netdev
In-Reply-To: <20120917.131237.518528991078697534.davem@davemloft.net>
On Mon, Sep 17, 2012 at 01:12:37PM -0400, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Mon, 17 Sep 2012 13:10:17 -0400 (EDT)
>
> > From: David Miller <davem@davemloft.net>
> > Date: Mon, 17 Sep 2012 13:05:31 -0400 (EDT)
> >
> >> From: Ben Hutchings <ben@decadent.org.uk>
> >> Date: Sun, 16 Sep 2012 04:09:42 +0100
> >>
> >>> There seem to have been some grand plans for llc_station, but as they
> >>> haven't been fulfilled it's just unnecessarily complicated.
> >>
> >> I went over these a few times, they look correct, so I am going
> >> to apply them to net-next.
> >>
> >> If there are any problems let's hope that exposure in the tree
> >> helps shake those out.
> >
> > It doesn't even build properly, please fix this and resubmit:
> >
> > ERROR: "sysctl_llc_station_ack_timeout" [net/llc/llc2.ko] undefined!
>
> Actually, since I trusted you when you said you build tested this,
> I pushed it out to net-next pre-maturely.
>
> I'm going to fix this meanwhile by simply removing the sysctl that
> references this symbol.
>
> But you need to check for me whether that's ok or not.
The sysctl had no effect so I think it's fairly safe to assume nothing
depends on it. Thanks.
Ben.
--
Ben Hutchings
We get into the habit of living before acquiring the habit of thinking.
- Albert Camus
^ permalink raw reply
* Re: [PATCH 0/6] llc2: Simplify llc_station
From: Ben Hutchings @ 2012-09-18 17:29 UTC (permalink / raw)
To: David Miller; +Cc: acme, netdev
In-Reply-To: <20120917.131017.1646567691887140571.davem@davemloft.net>
On Mon, Sep 17, 2012 at 01:10:17PM -0400, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Mon, 17 Sep 2012 13:05:31 -0400 (EDT)
>
> > From: Ben Hutchings <ben@decadent.org.uk>
> > Date: Sun, 16 Sep 2012 04:09:42 +0100
> >
> >> There seem to have been some grand plans for llc_station, but as they
> >> haven't been fulfilled it's just unnecessarily complicated.
> >
> > I went over these a few times, they look correct, so I am going
> > to apply them to net-next.
> >
> > If there are any problems let's hope that exposure in the tree
> > helps shake those out.
>
> It doesn't even build properly, please fix this and resubmit:
>
> ERROR: "sysctl_llc_station_ack_timeout" [net/llc/llc2.ko] undefined!
Sorry, I was able to build net/llc/ successfully but didn't do a full
build which would have caught this.
Ben.
--
Ben Hutchings
We get into the habit of living before acquiring the habit of thinking.
- Albert Camus
^ permalink raw reply
* [PATCH 3/3] net/tipc/name_table.c: Remove unecessary semicolon
From: Peter Senna Tschudin @ 2012-09-18 17:10 UTC (permalink / raw)
To: jon.maloy
Cc: allan.stephens, davem, netdev, tipc-discussion, linux-kernel,
kernel-janitors, trivial, Peter Senna Tschudin
In-Reply-To: <1347988245-31413-1-git-send-email-peter.senna@gmail.com>
Found by http://coccinelle.lip6.fr/
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
net/tipc/name_table.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 98975e8..4675477 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -783,7 +783,7 @@ static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth,
if (!list_is_last(&publ->zone_list, &info->zone_list))
ret += tipc_snprintf(buf + ret, len - ret,
"\n%33s", " ");
- };
+ }
ret += tipc_snprintf(buf + ret, len - ret, "\n");
return ret;
--
1.7.11.4
^ permalink raw reply related
* [PATCH 2/3] net/openvswitch/vport.c: Remove unecessary semicolon
From: Peter Senna Tschudin @ 2012-09-18 17:10 UTC (permalink / raw)
To: jesse-l0M0P4e3n4LQT0dZR+AlfA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, trivial-DgEjT+Ai2ygdnm+yROfE0A,
netdev-u79uwXL29TY76Z2rM5mHXA, Peter Senna Tschudin,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1347988245-31413-1-git-send-email-peter.senna-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Found by http://coccinelle.lip6.fr/
Signed-off-by: Peter Senna Tschudin <peter.senna-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/openvswitch/vport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 9055dd6..03779e8 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -398,7 +398,7 @@ void ovs_vport_record_error(struct vport *vport, enum vport_err_type err_type)
case VPORT_E_TX_ERROR:
vport->err_stats.tx_errors++;
break;
- };
+ }
spin_unlock(&vport->stats_lock);
}
--
1.7.11.4
^ permalink raw reply related
* [PATCH 1/3] net/ieee802154/6lowpan.c: Remove unecessary semicolon
From: Peter Senna Tschudin @ 2012-09-18 17:10 UTC (permalink / raw)
To: alex.bluesman.smirnov
Cc: dbaryshkov, davem, linux-zigbee-devel, netdev, linux-kernel,
kernel-janitors, trivial, Peter Senna Tschudin
Found by http://coccinelle.lip6.fr/
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
net/ieee802154/6lowpan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index d529111..6d42c17 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -1256,7 +1256,7 @@ static int lowpan_device_event(struct notifier_block *unused,
}
unregister_netdevice_many(&del_list);
- };
+ }
out:
return NOTIFY_DONE;
--
1.7.11.4
^ permalink raw reply related
* [PATCH 5/5] ucc_geth: Add IRQ coalescing
From: Joakim Tjernlund @ 2012-09-18 16:56 UTC (permalink / raw)
To: netdev; +Cc: Joakim Tjernlund
In-Reply-To: <1347987385-19071-1-git-send-email-Joakim.Tjernlund@transmode.se>
Enable modest IRQ coalescing(4 pks) to reduce IRQ load.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
arch/powerpc/include/asm/qe.h | 1 +
drivers/net/ethernet/freescale/ucc_geth.c | 18 +++++++++++++++---
drivers/net/ethernet/freescale/ucc_geth.h | 20 ++++++++++++++++++++
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index 5e0b6d5..12a8ac8 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -373,6 +373,7 @@ enum comm_dir {
#define QE_MCC_STOP_RX 0x00000009
#define QE_ATM_TRANSMIT 0x0000000a
#define QE_HPAC_CLEAR_ALL 0x0000000b
+#define QE_SET_LAST_RX_THLD 0x00000013
#define QE_GRACEFUL_STOP_RX 0x0000001a
#define QE_RESTART_RX 0x0000001b
#define QE_HPAC_SET_PRIORITY 0x0000010b
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 7d60b95..772f796 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -124,7 +124,7 @@ static struct ucc_geth_info ugeth_primary_info = {
.ecamptr = ((uint32_t) NULL),
.eventRegMask = UCCE_OTHER,
.pausePeriod = 0xf000,
- .interruptcoalescingmaxvalue = {1, 1, 1, 1, 1, 1, 1, 1},
+ .interruptcoalescingmaxvalue = {4, 4, 4, 4, 4, 4, 4, 4},
.bdRingLenTx = {
TX_BD_RING_LEN,
TX_BD_RING_LEN,
@@ -237,7 +237,7 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
DMA_FROM_DEVICE));
skb_reserve(skb, UCC_GETH_RX_IP_ALIGNMENT);
out_be32((u32 __iomem *)bd,
- (R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W)));
+ (R_E | (in_be32((u32 __iomem*)bd) & R_W)));
return skb;
}
@@ -1606,6 +1606,7 @@ static void adjust_link(struct net_device *dev)
struct ucc_fast __iomem *uf_regs;
struct phy_device *phydev = ugeth->phydev;
int new_state = 0;
+ u32 cecr_subblock;
ug_regs = ugeth->ug_regs;
uf_regs = ugeth->uccf->uf_regs;
@@ -1657,6 +1658,17 @@ static void adjust_link(struct net_device *dev)
dev->name, phydev->speed);
break;
}
+ cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+ if (phydev->speed == SPEED_10)
+ qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock,
+ QE_CR_PROTOCOL_ETHERNET, UCC_10_TIME);
+ else if (phydev->speed == SPEED_100)
+ qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock,
+ QE_CR_PROTOCOL_ETHERNET, UCC_100_TIME);
+ else if (phydev->speed == SPEED_1000)
+ qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock,
+ QE_CR_PROTOCOL_ETHERNET, UCC_GBIT_TIME);
+
ugeth->oldspeed = phydev->speed;
}
@@ -2390,7 +2402,7 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
/* set bd status and length */
- out_be32((u32 __iomem *)bd, R_I);
+ out_be32((u32 __iomem *)bd, 0);
/* clear bd buffer */
out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
bd += sizeof(struct qe_bd);
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index b68637e..49165ce 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -923,6 +923,26 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_MACCFG1_INIT 0
#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1)
+/*
+ * From QUICC Engine Block Reference Manual, Chap 8.9:
+ * This command is used to set a timeout value for the Ethernet receiver
+ * interrupt coalescing mechanism.
+ * The timeout period is measured from the time that the last Ethernet frame
+ * was received. When the timeout expires, an interrupt is issued to the CPU
+ * even if the interrupt coalescing counter did not reach its maximum value. The
+ * timeout value should be written in the two least significant bytes of CECDR,
+ * and it should be specified in terms of serial clocks.
+ * For example, a value of 1000 in CECDR sets the timeout period to 1000 serial
+ * clocks.
+ * -------------------------------------------------------------------
+ * GBIT = 125MHz => 8ns/tick, 8 bits / tick
+ * 100 = 25 MHz => 40ns/tick, 4 bits / tick
+ * 10 = 2.5 MHz => 400ns/tick, 4 bits / tick
+ */
+#define UCC_GBIT_TIME 64
+#define UCC_100_TIME 64
+#define UCC_10_TIME 8
+
/* Ethernet Address Type. */
enum enet_addr_type {
ENET_ADDR_TYPE_INDIVIDUAL,
--
1.7.8.6
^ permalink raw reply related
* [PATCH 4/5] ucc_geth: Increase RX ring buffer from 32 to 64
From: Joakim Tjernlund @ 2012-09-18 16:56 UTC (permalink / raw)
To: netdev; +Cc: Joakim Tjernlund
In-Reply-To: <1347987385-19071-1-git-send-email-Joakim.Tjernlund@transmode.se>
We still see dropped pkgs in a busy network, this makes it better.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
drivers/net/ethernet/freescale/ucc_geth.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index aeb743c..b68637e 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -878,7 +878,7 @@ struct ucc_geth_hardware_statistics {
/* Driver definitions */
#define TX_BD_RING_LEN 0x10
-#define RX_BD_RING_LEN 0x20
+#define RX_BD_RING_LEN 0x40
#define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1)
--
1.7.8.6
^ permalink raw reply related
* [PATCH 3/5] ucc_geth: Fix two gcc warnings
From: Joakim Tjernlund @ 2012-09-18 16:56 UTC (permalink / raw)
To: netdev; +Cc: Joakim Tjernlund
In-Reply-To: <1347987385-19071-1-git-send-email-Joakim.Tjernlund@transmode.se>
ucc_geth.c: In function 'ucc_geth_startup':
ucc_geth.c:3092:45: warning: comparison between 'enum qe_fltr_largest_external_tbl_lookup_key_size' and 'enum qe_fltr_tbl_lookup_key_size'
ucc_geth.c:3096:45: warning: comparison between 'enum qe_fltr_largest_external_tbl_lookup_key_size' and 'enum qe_fltr_tbl_lookup_key_size'
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
drivers/net/ethernet/freescale/ucc_geth.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 5f1460a..7d60b95 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3074,11 +3074,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ug_info->rxExtendedFiltering) {
size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
if (ug_info->largestexternallookupkeysize ==
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
+ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
size +=
THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8;
if (ug_info->largestexternallookupkeysize ==
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
+ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
size +=
THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16;
}
--
1.7.8.6
^ permalink raw reply related
* [PATCH 2/5] ucc_geth: Word align Ethernet RX data
From: Joakim Tjernlund @ 2012-09-18 16:56 UTC (permalink / raw)
To: netdev; +Cc: Joakim Tjernlund
In-Reply-To: <1347987385-19071-1-git-send-email-Joakim.Tjernlund@transmode.se>
UCC controller can shift received Ethernet frames 2 bytes into the buffer,
making IP data word aligned, this patch enables that feature.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
drivers/net/ethernet/freescale/ucc_geth.c | 19 +++++++++++--------
drivers/net/ethernet/freescale/ucc_geth.h | 1 +
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index e609c93..5f1460a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -160,6 +160,7 @@ static struct ucc_geth_info ugeth_primary_info = {
.numThreadsRx = UCC_GETH_NUM_OF_THREADS_1,
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+ .ipAddressAlignment = 1,
};
static struct ucc_geth_info ugeth_info[8];
@@ -211,12 +212,13 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
u8 __iomem *bd)
{
struct sk_buff *skb = NULL;
+ u16 buf_len = ugeth->ug_info->uf_info.max_rx_buf_length +
+ UCC_GETH_RX_DATA_BUF_ALIGNMENT +
+ UCC_GETH_RX_IP_ALIGNMENT;
skb = __skb_dequeue(&ugeth->rx_recycle);
if (!skb)
- skb = netdev_alloc_skb(ugeth->ndev,
- ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT);
+ skb = netdev_alloc_skb(ugeth->ndev, buf_len);
if (skb == NULL)
return NULL;
@@ -231,10 +233,9 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
out_be32(&((struct qe_bd __iomem *)bd)->buf,
dma_map_single(ugeth->dev,
skb->data,
- ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+ buf_len,
DMA_FROM_DEVICE));
-
+ skb_reserve(skb, UCC_GETH_RX_IP_ALIGNMENT);
out_be32((u32 __iomem *)bd,
(R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W)));
@@ -1877,7 +1878,8 @@ static void ucc_geth_free_rx(struct ucc_geth_private *ugeth)
in_be32(&((struct qe_bd __iomem *)bd)->buf),
ugeth->ug_info->
uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+ UCC_GETH_RX_DATA_BUF_ALIGNMENT +
+ UCC_GETH_RX_IP_ALIGNMENT,
DMA_FROM_DEVICE);
dev_kfree_skb_any(
ugeth->rx_skbuff[i][j]);
@@ -3352,7 +3354,8 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
skb_recycle_check(skb,
ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT))
+ UCC_GETH_RX_DATA_BUF_ALIGNMENT +
+ UCC_GETH_RX_IP_ALIGNMENT))
__skb_queue_head(&ugeth->rx_recycle, skb);
else
dev_kfree_skb(skb);
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index f71b3e7..aeb743c 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -855,6 +855,7 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT 4
#define UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT 32
#define UCC_GETH_RX_DATA_BUF_ALIGNMENT 64
+#define UCC_GETH_RX_IP_ALIGNMENT 2 /* IP word alignment */
#define UCC_GETH_TAD_EF 0x80
#define UCC_GETH_TAD_V 0x40
--
1.7.8.6
^ permalink raw reply related
* [PATCH 1/5] ucc_geth: Reduce IRQ off in xmit path
From: Joakim Tjernlund @ 2012-09-18 16:56 UTC (permalink / raw)
To: netdev; +Cc: Joakim Tjernlund
Currently ucc_geth_start_xmit wraps IRQ off for the
whole body just to be safe.
Reduce the IRQ off period to a minimum.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
drivers/net/ethernet/freescale/ucc_geth.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 9ac14f8..e609c93 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3181,8 +3181,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
ugeth_vdbg("%s: IN", __func__);
- spin_lock_irqsave(&ugeth->lock, flags);
-
dev->stats.tx_bytes += skb->len;
/* Start from the next BD that should be filled */
@@ -3196,6 +3194,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
(ugeth->skb_curtx[txQ] +
1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
+ spin_lock_irqsave(&ugeth->lock, flags);
/* set up the buffer descriptor */
out_be32(&((struct qe_bd __iomem *)bd)->buf,
dma_map_single(ugeth->dev, skb->data,
@@ -3207,6 +3206,8 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* set bd status and length */
out_be32((u32 __iomem *)bd, bd_status);
+ spin_unlock_irqrestore(&ugeth->lock, flags);
+
/* Move to next BD in the ring */
if (!(bd_status & T_W))
@@ -3238,8 +3239,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
uccf = ugeth->uccf;
out_be16(uccf->p_utodr, UCC_FAST_TOD);
#endif
- spin_unlock_irqrestore(&ugeth->lock, flags);
-
return NETDEV_TX_OK;
}
--
1.7.8.6
^ permalink raw reply related
* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-09-18 15:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1347979239.26523.267.camel@edumazet-glaptop>
Thanks for the reply, Eric.
>>> -rc1 turned out to have the problem so I've bisected between 3.5 and
>>> 3.6-rc1. I arrived at:
>>>
>>> $ git bisect bad
>>> d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5 is the first bad commit
>>> commit d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
>>> Author: David S. Miller <davem@davemloft.net>
>>> Date: Tue Jul 17 12:58:50 2012 -0700
>>>
>>> ipv4: Cache input routes in fib_info nexthops.
>>>
>>> Caching input routes is slightly simpler than output routes, since we
>>> don't need to be concerned with nexthop exceptions. (locally
>>> destined, and routed packets, never trigger PMTU events or redirects
>>> that will be processed by us).
>>>
>>> However, we have to elide caching for the DIRECTSRC and non-zero itag
>>> cases.
>>>
>>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>>
>>> :040000 040000 6bbc75c1cbe62bf84ea412d3b98adf2b614779cd
>>> 3ad7256b4a71e63ca4530977c0550121ea803d35 M include
>>> :040000 040000 18c2a950a53c4eec9bfa12185d1e382dfed74af8
>>> a2ab6157d6cd54930da395758c6ded3a225d1f04 M net
>>>
>>> The bisect log:
>>> git bisect start
>>> # bad: [0d7614f09c1ebdbaa1599a5aba7593f147bf96ee] Linux 3.6-rc1
>>> git bisect bad 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee
>>> # good: [28a33cbc24e4256c143dce96c7d93bf423229f92] Linux 3.5
>>> git bisect good 28a33cbc24e4256c143dce96c7d93bf423229f92
>>> # bad: [614a6d4341b3760ca98a1c2c09141b71db5d1e90] Merge branch 'for-3.6'
>>> of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
>>> git bisect bad 614a6d4341b3760ca98a1c2c09141b71db5d1e90
>>> # bad: [320f5ea0cedc08ef65d67e056bcb9d181386ef2c] genetlink: define
>>> lockdep_genl_is_held() when CONFIG_LOCKDEP
>>> git bisect bad 320f5ea0cedc08ef65d67e056bcb9d181386ef2c
>>> # good: [0cd06647b7c24f6633e32a505930a9aa70138c22] Merge branch 'master'
>>> of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
>>> git bisect good 0cd06647b7c24f6633e32a505930a9aa70138c22
>>> # good: [dbfa600148a25903976910863c75dae185f8d187] cxgb3: set maximal
>>> number of default RSS queues
>>> git bisect good dbfa600148a25903976910863c75dae185f8d187
>>> # good: [efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3] bnx2: Try to recover
>>> from PCI block reset
>>> git bisect good efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3
>>> # good: [1bf91cdc1bba94ea062a9147d924815c13f029f2] ixgbe: Drop
>>> references to deprecated pci_ DMA api and instead use dma_ API
>>> git bisect good 1bf91cdc1bba94ea062a9147d924815c13f029f2
>>> # good: [b6dfd939fdc249fcf8cd7b8006f76239b33eb581] ixgbe: add support
>>> for new 82599 device
>>> git bisect good b6dfd939fdc249fcf8cd7b8006f76239b33eb581
>>> # good: [3ba97381343b271296487bf073eb670d5465a8b8] net: ethernet:
>>> davinci_emac: add pm_runtime support
>>> git bisect good 3ba97381343b271296487bf073eb670d5465a8b8
>>> # bad: [5e9965c15ba88319500284e590733f4a4629a288] Merge branch
>>> 'kill_rtcache'
>>> git bisect bad 5e9965c15ba88319500284e590733f4a4629a288
>>> # good: [f5b0a8743601a4477419171f5046bd07d1c080a0] net: Document
>>> dst->obsolete better.
>>> git bisect good f5b0a8743601a4477419171f5046bd07d1c080a0
>>> # bad: [ba3f7f04ef2b19aace38f855aedd17fe43035d50] ipv4: Kill
>>> FLOWI_FLAG_RT_NOCACHE and associated code.
>>> git bisect bad ba3f7f04ef2b19aace38f855aedd17fe43035d50
>>> # good: [f2bb4bedf35d5167a073dcdddf16543f351ef3ae] ipv4: Cache output
>>> routes in fib_info nexthops.
>>> git bisect good f2bb4bedf35d5167a073dcdddf16543f351ef3ae
>>> # bad: [d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5] ipv4: Cache input
>>> routes in fib_info nexthops.
>>> git bisect bad d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
>>>
>>> Checking out the parent commit
>>> (f2bb4bedf35d5167a073dcdddf16543f351ef3ae) and building and installing
>>> the kernel gives a working configuration, so I'm pretty confident in the
>>> outcome of the bisect. Reversing the patch gives errors, so I've not
>>> tested master with the patch reversed.
>>>
>>> Let me know if I can help in any way to identify a fix.
>>>
>> Sorry, I forgot to say that I also have tried running TinyCore Linux as
>> a KVM guest on a 3.6.0-rc6 kernel, and I can ping the router fine, so
>> the problem seems to be something specifically related to ruuning
>> Windows XP as the guest. I don't have any other guests installed so
>> that's as much as I can say, although I could maybe install a Win7 guest
>> tomorrow if that would help.
>
I hope you've seen my later email in which I reported my error in my
testing that led me to believe that all was OK with a linux client. In
fact, The router is inaccessible from both the Windows XP and the Linux
clients.
> It would help to have some traffic sample, maybe.
>
I'll need help here. How would I go about collecting that traffic. I
have wireshark installed, but haven't used it for years. Would a trace
from that be helpful? It might take me a while to figure out how to
capture it?
> Especially if the problem is not easily reproductible for us.
>
> (I dont have Windows XP nor Win7)
>
> Also the bisect might point to a commit with an already fixed bug :
This fix is already in 3.6.0-rc6. BTW, I've pulled the latest changes
from kernel.org this afternoon, but that hasn't helped.
>
> commit 4331debc51ee1ce319f4a389484e0e8e05de2aca
> Author: Eric Dumazet <edumazet@google.com>
> Date: Wed Jul 25 05:11:23 2012 +0000
>
> ipv4: rt_cache_valid must check expired routes
>
> commit d2d68ba9fe8 (ipv4: Cache input routes in fib_info nexthops.)
> introduced rt_cache_valid() helper. It unfortunately doesn't check if
> route is expired before caching it.
>
> I noticed sk_setup_caps() was constantly called on a tcp workload.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
>
^ permalink raw reply
* Re: [PATCH 1/4] ipv6: add a new namespace for nf_conntrack_reasm
From: Pablo Neira Ayuso @ 2012-09-18 15:45 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, netfilter-devel, Herbert Xu, Michal Kubeček,
David Miller, Patrick McHardy
In-Reply-To: <1347975911-5655-2-git-send-email-amwang@redhat.com>
On Tue, Sep 18, 2012 at 09:45:08PM +0800, Cong Wang wrote:
> As pointed by Michal, it is necessary to add a new
> namespace for nf_conntrack_reasm code, this prepares
> for the second patch.
>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: Michal Kubeček <mkubecek@suse.cz>
> Cc: David Miller <davem@davemloft.net>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Pablo Neira Ayuso <pablo@netfilter.org>
> Cc: netfilter-devel@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
> include/net/net_namespace.h | 3 +
> include/net/netns/ipv6.h | 8 ++
> net/ipv6/netfilter/nf_conntrack_reasm.c | 135 +++++++++++++++++++++----------
> 3 files changed, 104 insertions(+), 42 deletions(-)
>
> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> index 5ae57f1..d61e2b3 100644
> --- a/include/net/net_namespace.h
> +++ b/include/net/net_namespace.h
> @@ -93,6 +93,9 @@ struct net {
> #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
> struct netns_ct ct;
> #endif
> +#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
> + struct netns_nf_frag nf_frag;
> +#endif
> struct sock *nfnl;
> struct sock *nfnl_stash;
> #endif
> diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
> index 0318104..214cb0a 100644
> --- a/include/net/netns/ipv6.h
> +++ b/include/net/netns/ipv6.h
> @@ -71,4 +71,12 @@ struct netns_ipv6 {
> #endif
> #endif
> };
> +
> +#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
> +struct netns_nf_frag {
> + struct netns_sysctl_ipv6 sysctl;
> + struct netns_frags frags;
> +};
> +#endif
> +
> #endif
> diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
> index f94fb3a..d28c067 100644
> --- a/net/ipv6/netfilter/nf_conntrack_reasm.c
> +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
> @@ -71,27 +71,26 @@ struct nf_ct_frag6_queue
> };
>
> static struct inet_frags nf_frags;
> -static struct netns_frags nf_init_frags;
>
> #ifdef CONFIG_SYSCTL
> static struct ctl_table nf_ct_frag6_sysctl_table[] = {
> {
> .procname = "nf_conntrack_frag6_timeout",
> - .data = &nf_init_frags.timeout,
> + .data = &init_net.nf_frag.frags.timeout,
> .maxlen = sizeof(unsigned int),
> .mode = 0644,
> .proc_handler = proc_dointvec_jiffies,
> },
> {
> .procname = "nf_conntrack_frag6_low_thresh",
> - .data = &nf_init_frags.low_thresh,
> + .data = &init_net.nf_frag.frags.low_thresh,
> .maxlen = sizeof(unsigned int),
> .mode = 0644,
> .proc_handler = proc_dointvec,
> },
> {
> .procname = "nf_conntrack_frag6_high_thresh",
> - .data = &nf_init_frags.high_thresh,
> + .data = &init_net.nf_frag.frags.high_thresh,
> .maxlen = sizeof(unsigned int),
> .mode = 0644,
> .proc_handler = proc_dointvec,
> @@ -99,7 +98,54 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = {
> { }
> };
>
> -static struct ctl_table_header *nf_ct_frag6_sysctl_header;
> +static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
> +{
> + struct ctl_table *table;
> + struct ctl_table_header *hdr;
> +
> + table = nf_ct_frag6_sysctl_table;
> + if (!net_eq(net, &init_net)) {
> + table = kmemdup(table, sizeof(nf_ct_frag6_sysctl_table), GFP_KERNEL);
Sorry, you have to break lines at 80 chars.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH NEXT V3] rtlwifi: rtl8192c: rtl8192ce: Add support for B-CUT version of RTL8188CE
From: Larry Finger @ 2012-09-18 15:29 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, Larry Finger,
netdev-u79uwXL29TY76Z2rM5mHXA, Anisse Astier, Li Chaoming
Realtek devices with designation RTL8188CE-VL have the so-called B-cut
of the wireless chip. This patch adds the special programming needed by
these devices. In addition, a variable that was static has been moved into
the private data area as it is now needed in two different routines. This
change also fixes a minor bug that would be present if a system had more
than one RTL81{88,92}CE devices. Other drivers in the rtlwifi family had
already made this change, thus the variable already exists in the private
data structure.
Signed-off-by: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
Cc: Anisse Astier <anisse-fwwRqrJYcP2HXe+LvDLADg@public.gmane.org>
Cc: Li Chaoming <chaoming_li-kXabqFNEczNtrwSWzY7KCg@public.gmane.org>
---
rtl8192c/phy_common.c | 21 +++++++++++++++++
rtl8192ce/def.h | 3 ++
rtl8192ce/hw.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-----
rtl8192ce/phy.c | 2 +
rtl8192ce/sw.c | 6 +----
rtl8192ce/trx.c | 4 +--
6 files changed, 85 insertions(+), 11 deletions(-)
---
V1 => V2 Remove extraneous white space.
V2 => V3 A change that is not part of the B-cut change and was introduced
in V2 is moved to a separate patch.
John,
This patch is too invasive to backport to the stable kernels, thus it should
be applied to 3.7.
Thanks,
Larry
---
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -724,6 +724,26 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_h
}
EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
+static void _rtl92c_phy_sw_rf_setting(struct ieee80211_hw *hw, u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
+ if (channel == 6 && rtlphy->current_chan_bw ==
+ HT_CHANNEL_WIDTH_20)
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
+ 0x00255);
+ else{
+ u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
+ RF_RX_G1, RFREG_OFFSET_MASK);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
+ backupRF0x1A);
+ }
+ }
+}
+
static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
u32 cmdtableidx, u32 cmdtablesz,
enum swchnlcmd_id cmdid,
@@ -837,6 +857,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(st
currentcmd->para1,
RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[rfpath]);
+ _rtl92c_phy_sw_rf_setting(hw, channel);
}
break;
default:
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -116,6 +116,9 @@
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define CHIP_VER_B BIT(4)
+#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
+#define CHIP_BONDING_92C_1T2R 0x1
+#define RF_TYPE_1T2R BIT(1)
#define CHIP_92C_BITMASK BIT(0)
#define CHIP_UNKNOWN BIT(7)
#define CHIP_92C_1T2R 0x03
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
- static bool iqk_initialized; /* initialized to false */
bool rtstatus = true;
bool is92c;
int err;
@@ -921,9 +920,28 @@ int rtl92ce_hw_init(struct ieee80211_hw
rtlhal->last_hmeboxnum = 0;
rtl92c_phy_mac_config(hw);
+ /* because last function modify RCR, so we update
+ * rcr var here, or TP will unstable for receive_config
+ * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
+ * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/
+ rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
+ rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
+ rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
rtl92c_phy_bb_config(hw);
rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
rtl92c_phy_rf_config(hw);
+ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
+ !IS_92C_SERIAL(rtlhal->version)) {
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00);
+ } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201);
+ }
rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
RF_CHNLBW, RFREG_OFFSET_MASK);
rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
@@ -945,11 +963,11 @@ int rtl92ce_hw_init(struct ieee80211_hw
if (ppsc->rfpwr_state == ERFON) {
rtl92c_phy_set_rfpath_switch(hw, 1);
- if (iqk_initialized) {
+ if (rtlphy->iqk_initialized) {
rtl92c_phy_iq_calibrate(hw, true);
} else {
rtl92c_phy_iq_calibrate(hw, false);
- iqk_initialized = true;
+ rtlphy->iqk_initialized = true;
}
rtl92c_dm_check_txpower_tracking(hw);
@@ -1004,6 +1022,13 @@ static enum version_8192c _rtl92ce_read_
? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) |
CHIP_VENDOR_UMC));
}
+ if (IS_92C_SERIAL(version)) {
+ value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
+ version = (enum version_8192c)(version |
+ ((CHIP_BONDING_IDENTIFIER(value32)
+ == CHIP_BONDING_92C_1T2R) ?
+ RF_TYPE_1T2R : 0));
+ }
}
switch (version) {
@@ -1019,12 +1044,30 @@ static enum version_8192c _rtl92ce_read_
case VERSION_A_CHIP_88C:
versionid = "A_CHIP_88C";
break;
+ case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
+ versionid = "A_CUT_92C_1T2R";
+ break;
+ case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
+ versionid = "A_CUT_92C";
+ break;
+ case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
+ versionid = "A_CUT_88C";
+ break;
+ case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
+ versionid = "B_CUT_92C_1T2R";
+ break;
+ case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
+ versionid = "B_CUT_92C";
+ break;
+ case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
+ versionid = "B_CUT_88C";
+ break;
default:
versionid = "Unknown. Bug?";
break;
}
- RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
"Chip Version ID: %s\n", versionid);
switch (version & 0x3) {
@@ -1197,6 +1240,7 @@ static void _rtl92ce_poweroff_adapter(st
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 u1b_tmp;
u32 u4b_tmp;
@@ -1225,7 +1269,8 @@ static void _rtl92ce_poweroff_adapter(st
rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
- rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
+ if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
if (rtlpcipriv->bt_coexist.bt_coexistence) {
u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
u4b_tmp |= 0x03824800;
@@ -1254,6 +1299,9 @@ void rtl92ce_card_disable(struct ieee802
rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
_rtl92ce_poweroff_adapter(hw);
+
+ /* after power off we should do iqk again */
+ rtlpriv->phy.iqk_initialized = false;
}
void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
@@ -1912,6 +1960,8 @@ static void rtl92ce_update_hal_rate_mask
ratr_bitmap &= 0x0f0ff0ff;
break;
}
+ sta_entry->ratr_index = ratr_index;
+
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
"ratr_bitmap :%x\n", ratr_bitmap);
*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -82,6 +82,8 @@ bool rtl92c_phy_mac_config(struct ieee80
if (is92c)
rtl_write_byte(rtlpriv, 0x14, 0x71);
+ else
+ rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
return rtstatus;
}
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -162,12 +162,10 @@ int rtl92c_init_sw_vars(struct ieee80211
/* request fw */
if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
- !IS_92C_SERIAL(rtlhal->version)) {
+ !IS_92C_SERIAL(rtlhal->version))
rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
- } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
+ else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
- pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n");
- }
rtlpriv->max_fw_size = 0x4000;
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -127,11 +127,11 @@ static void _rtl92ce_query_rxphystatus(s
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct phy_sts_cck_8192s_t *cck_buf;
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
s8 rx_pwr_all = 0, rx_pwr[4];
u8 evm, pwdb_all, rf_rx_num = 0;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
- bool in_powersavemode = false;
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
@@ -147,7 +147,7 @@ static void _rtl92ce_query_rxphystatus(s
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
- if (!in_powersavemode)
+ if (ppsc->rfpwr_state == ERFON)
cck_highpwr = (u8) rtl_get_bbreg(hw,
RFPGA0_XA_HSSIPARAMETER2,
BIT(9));
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH NEXT V2] rtlwifi: rtl8192c: rtl8192ce: Add support for B-CUT version of RTL8188CE
From: Larry Finger @ 2012-09-18 14:50 UTC (permalink / raw)
To: Anisse Astier
Cc: linville-2XuSBdqkA4R54TAoqtyWWQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Li Chaoming
In-Reply-To: <20120918160901.22cf2261-nMKIGJZKI6fIeUwiHPfBe2GXanvQGlWp@public.gmane.org>
On 09/18/2012 09:09 AM, Anisse Astier wrote:
> On Mon, 17 Sep 2012 15:35:43 -0500, Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org> wrote :
>
>> Realtek devices with designation RTL8188CE-VL have the so-called B-cut
>> of the wireless chip. This patch adds the special programming needed by
>> these devices.
>>
>> Signed-off-by: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
>> Cc: Anisse Astier <anisse-fwwRqrJYcP2HXe+LvDLADg@public.gmane.org>
>> Cc: Li Chaoming <chaoming_li-kXabqFNEczNtrwSWzY7KCg@public.gmane.org>
>> ---
>> drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 21 +++++++
>> drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 3 +
>> drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 61 ++++++++++++++++++--
>> drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 4 +-
>> drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 6 +-
>> drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 4 +-
>> 6 files changed, 87 insertions(+), 12 deletions(-)
>> ---
>> V1 => V2 Remove extraneous white space.
>>
>>
>> John,
>>
>> This patch is too invasive to backport to the stable kernels, thus it should
>> be applied to 3.7.
>>
>> Thanks,
>>
>> Larry
>> ---
>>
>
> [snip]
>
>> Index: wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
>> ===================================================================
>> --- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
>> +++ wireless-testing-new/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
>> @@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw
>> struct rtl_phy *rtlphy = &(rtlpriv->phy);
>> struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
>> struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
>> - static bool iqk_initialized; /* initialized to false */
>> bool rtstatus = true;
>> bool is92c;
>> int err;
>> @@ -921,9 +920,28 @@ int rtl92ce_hw_init(struct ieee80211_hw
>>
>> rtlhal->last_hmeboxnum = 0;
>> rtl92c_phy_mac_config(hw);
>> + /* because last function modify RCR, so we update
>> + * rcr var here, or TP will unstable for receive_config
>> + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
>> + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/
>> + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
>> + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
>> + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
>> rtl92c_phy_bb_config(hw);
>> rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
>> rtl92c_phy_rf_config(hw);
>> + if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
>> + !IS_92C_SERIAL(rtlhal->version)) {
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255);
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00);
>> + } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
>> + rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE);
>> + rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31);
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425);
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200);
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053);
>> + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201);
>> + }
>> rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
>> RF_CHNLBW, RFREG_OFFSET_MASK);
>> rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
>> @@ -945,11 +963,11 @@ int rtl92ce_hw_init(struct ieee80211_hw
>>
>> if (ppsc->rfpwr_state == ERFON) {
>> rtl92c_phy_set_rfpath_switch(hw, 1);
>> - if (iqk_initialized) {
>> + if (rtlphy->iqk_initialized) {
>> rtl92c_phy_iq_calibrate(hw, true);
>> } else {
>> rtl92c_phy_iq_calibrate(hw, false);
>> - iqk_initialized = true;
>> + rtlphy->iqk_initialized = true;
>> }
>>
>> rtl92c_dm_check_txpower_tracking(hw);
>> @@ -1004,6 +1022,13 @@ static enum version_8192c _rtl92ce_read_
>> ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) |
>> CHIP_VENDOR_UMC));
>> }
>> + if (IS_92C_SERIAL(version)) {
>> + value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
>> + version = (enum version_8192c)(version |
>> + ((CHIP_BONDING_IDENTIFIER(value32)
>> + == CHIP_BONDING_92C_1T2R) ?
>> + RF_TYPE_1T2R : 0));
>> + }
>> }
>>
>> switch (version) {
>> @@ -1019,12 +1044,30 @@ static enum version_8192c _rtl92ce_read_
>> case VERSION_A_CHIP_88C:
>> versionid = "A_CHIP_88C";
>> break;
>> + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
>> + versionid = "A_CUT_92C_1T2R";
>> + break;
>> + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
>> + versionid = "A_CUT_92C";
>> + break;
>> + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
>> + versionid = "A_CUT_88C";
>> + break;
>> + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
>> + versionid = "B_CUT_92C_1T2R";
>> + break;
>> + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
>> + versionid = "B_CUT_92C";
>> + break;
>> + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
>> + versionid = "B_CUT_88C";
>> + break;
>> default:
>> versionid = "Unknown. Bug?";
>> break;
>> }
>>
>> - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
>> + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
>> "Chip Version ID: %s\n", versionid);
>>
>> switch (version & 0x3) {
>> @@ -1197,6 +1240,7 @@ static void _rtl92ce_poweroff_adapter(st
>> {
>> struct rtl_priv *rtlpriv = rtl_priv(hw);
>> struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
>> + struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
>> u8 u1b_tmp;
>> u32 u4b_tmp;
>>
>> @@ -1225,7 +1269,8 @@ static void _rtl92ce_poweroff_adapter(st
>> rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
>> rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
>> rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
>> - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
>> + if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
>> + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
>> if (rtlpcipriv->bt_coexist.bt_coexistence) {
>> u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
>> u4b_tmp |= 0x03824800;
>> @@ -1254,6 +1299,9 @@ void rtl92ce_card_disable(struct ieee802
>> rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
>> RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
>> _rtl92ce_poweroff_adapter(hw);
>> +
>> + /* after power off we should do iqk again */
>> + rtlpriv->phy.iqk_initialized = false;
>> }
>>
>> void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
>
> This part:
>> @@ -1355,9 +1403,9 @@ static void _rtl92ce_read_txpower_info_f
>> tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
>> else
>> tempval = EEPROM_DEFAULT_HT40_2SDIFF;
>> - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] =
>> + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] =
>> (tempval & 0xf);
>> - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] =
>> + rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] =
>> ((tempval & 0xf0) >> 4);
>> }
>>
>> @@ -1381,7 +1429,7 @@ static void _rtl92ce_read_txpower_info_f
>> "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
>> rf_path, i,
>> rtlefuse->
>> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]);
>> + eprom_chnl_txpwr_ht40_2sdf[rf_path][i]);
>>
>> for (rf_path = 0; rf_path < 2; rf_path++) {
>> for (i = 0; i < 14; i++) {
>> @@ -1396,14 +1444,14 @@ static void _rtl92ce_read_txpower_info_f
>> if ((rtlefuse->
>> eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
>> rtlefuse->
>> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index])
>> + eprom_chnl_txpwr_ht40_2sdf[rf_path][index])
>> > 0) {
>> rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
>> rtlefuse->
>> eeprom_chnlarea_txpwr_ht40_1s[rf_path]
>> [index] -
>> rtlefuse->
>> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
>> + eprom_chnl_txpwr_ht40_2sdf[rf_path]
>> [index];
>> } else {
>> rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
>
> wasn't in V1 of the patch. Is the rename normal?
The original length of the variable name was causing extreme difficulty in
keeping all lines to 80 characters in the code for the new driver for the
RTL8723AE device. The renaming helped. You are correct that the change should be
documented.
Larry
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-09-18 14:44 UTC (permalink / raw)
To: netdev
In-Reply-To: <505885DC.1060006@googlemail.com>
>>
> Sorry, I forgot to say that I also have tried running TinyCore Linux as
> a KVM guest on a 3.6.0-rc6 kernel, and I can ping the router fine, so
> the problem seems to be something specifically related to ruuning
> Windows XP as the guest. I don't have any other guests installed so
> that's as much as I can say, although I could maybe install a Win7 guest
> tomorrow if that would help.
>
Sorry again, but ignore the message above, please. Wrong kernel used in
test. In fact, I get the same failure to ping the router running on a
6.6.0-rc6 kernel.
Apologies for the noise.
Chris
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-09-18 14:40 UTC (permalink / raw)
To: Chris Clayton; +Cc: netdev
In-Reply-To: <505885DC.1060006@googlemail.com>
On Tue, 2012-09-18 at 15:31 +0100, Chris Clayton wrote:
> >> ...
> >> r8169 47159 0
> >>
> >> From the host I can successfully ping the guest, tap0 and the router as
> >> you would expect, but from the guest, although I can ping the host and
> >> tap0, I cannot ping the router. In practice, this means I have no
> >> internet access from the guest. As I say, this configuration works
> >> perfectly under 3.5.x and 3.4.x kernels.
> >>
> >> I'll do a coarse-grained "bisect" of Linus' 3.6 release candidates and
> >> report back, but does anyone have any prime-suspect patches that may be
> >> at the cause of this problem?
> >>
> >
> > -rc1 turned out to have the problem so I've bisected between 3.5 and
> > 3.6-rc1. I arrived at:
> >
> > $ git bisect bad
> > d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5 is the first bad commit
> > commit d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
> > Author: David S. Miller <davem@davemloft.net>
> > Date: Tue Jul 17 12:58:50 2012 -0700
> >
> > ipv4: Cache input routes in fib_info nexthops.
> >
> > Caching input routes is slightly simpler than output routes, since we
> > don't need to be concerned with nexthop exceptions. (locally
> > destined, and routed packets, never trigger PMTU events or redirects
> > that will be processed by us).
> >
> > However, we have to elide caching for the DIRECTSRC and non-zero itag
> > cases.
> >
> > Signed-off-by: David S. Miller <davem@davemloft.net>
> >
> > :040000 040000 6bbc75c1cbe62bf84ea412d3b98adf2b614779cd
> > 3ad7256b4a71e63ca4530977c0550121ea803d35 M include
> > :040000 040000 18c2a950a53c4eec9bfa12185d1e382dfed74af8
> > a2ab6157d6cd54930da395758c6ded3a225d1f04 M net
> >
> > The bisect log:
> > git bisect start
> > # bad: [0d7614f09c1ebdbaa1599a5aba7593f147bf96ee] Linux 3.6-rc1
> > git bisect bad 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee
> > # good: [28a33cbc24e4256c143dce96c7d93bf423229f92] Linux 3.5
> > git bisect good 28a33cbc24e4256c143dce96c7d93bf423229f92
> > # bad: [614a6d4341b3760ca98a1c2c09141b71db5d1e90] Merge branch 'for-3.6'
> > of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
> > git bisect bad 614a6d4341b3760ca98a1c2c09141b71db5d1e90
> > # bad: [320f5ea0cedc08ef65d67e056bcb9d181386ef2c] genetlink: define
> > lockdep_genl_is_held() when CONFIG_LOCKDEP
> > git bisect bad 320f5ea0cedc08ef65d67e056bcb9d181386ef2c
> > # good: [0cd06647b7c24f6633e32a505930a9aa70138c22] Merge branch 'master'
> > of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
> > git bisect good 0cd06647b7c24f6633e32a505930a9aa70138c22
> > # good: [dbfa600148a25903976910863c75dae185f8d187] cxgb3: set maximal
> > number of default RSS queues
> > git bisect good dbfa600148a25903976910863c75dae185f8d187
> > # good: [efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3] bnx2: Try to recover
> > from PCI block reset
> > git bisect good efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3
> > # good: [1bf91cdc1bba94ea062a9147d924815c13f029f2] ixgbe: Drop
> > references to deprecated pci_ DMA api and instead use dma_ API
> > git bisect good 1bf91cdc1bba94ea062a9147d924815c13f029f2
> > # good: [b6dfd939fdc249fcf8cd7b8006f76239b33eb581] ixgbe: add support
> > for new 82599 device
> > git bisect good b6dfd939fdc249fcf8cd7b8006f76239b33eb581
> > # good: [3ba97381343b271296487bf073eb670d5465a8b8] net: ethernet:
> > davinci_emac: add pm_runtime support
> > git bisect good 3ba97381343b271296487bf073eb670d5465a8b8
> > # bad: [5e9965c15ba88319500284e590733f4a4629a288] Merge branch
> > 'kill_rtcache'
> > git bisect bad 5e9965c15ba88319500284e590733f4a4629a288
> > # good: [f5b0a8743601a4477419171f5046bd07d1c080a0] net: Document
> > dst->obsolete better.
> > git bisect good f5b0a8743601a4477419171f5046bd07d1c080a0
> > # bad: [ba3f7f04ef2b19aace38f855aedd17fe43035d50] ipv4: Kill
> > FLOWI_FLAG_RT_NOCACHE and associated code.
> > git bisect bad ba3f7f04ef2b19aace38f855aedd17fe43035d50
> > # good: [f2bb4bedf35d5167a073dcdddf16543f351ef3ae] ipv4: Cache output
> > routes in fib_info nexthops.
> > git bisect good f2bb4bedf35d5167a073dcdddf16543f351ef3ae
> > # bad: [d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5] ipv4: Cache input
> > routes in fib_info nexthops.
> > git bisect bad d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
> >
> > Checking out the parent commit
> > (f2bb4bedf35d5167a073dcdddf16543f351ef3ae) and building and installing
> > the kernel gives a working configuration, so I'm pretty confident in the
> > outcome of the bisect. Reversing the patch gives errors, so I've not
> > tested master with the patch reversed.
> >
> > Let me know if I can help in any way to identify a fix.
> >
> Sorry, I forgot to say that I also have tried running TinyCore Linux as
> a KVM guest on a 3.6.0-rc6 kernel, and I can ping the router fine, so
> the problem seems to be something specifically related to ruuning
> Windows XP as the guest. I don't have any other guests installed so
> that's as much as I can say, although I could maybe install a Win7 guest
> tomorrow if that would help.
It would help to have some traffic sample, maybe.
Especially if the problem is not easily reproductible for us.
(I dont have Windows XP nor Win7)
Also the bisect might point to a commit with an already fixed bug :
commit 4331debc51ee1ce319f4a389484e0e8e05de2aca
Author: Eric Dumazet <edumazet@google.com>
Date: Wed Jul 25 05:11:23 2012 +0000
ipv4: rt_cache_valid must check expired routes
commit d2d68ba9fe8 (ipv4: Cache input routes in fib_info nexthops.)
introduced rt_cache_valid() helper. It unfortunately doesn't check if
route is expired before caching it.
I noticed sk_setup_caps() was constantly called on a tcp workload.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [RFC PATCH v1 0/3] usbnet: runtime suspend when link becomes down
From: Ming Lei @ 2012-09-18 14:36 UTC (permalink / raw)
To: Oliver Neukum
Cc: David S. Miller, Greg Kroah-Hartman, Fink Dmitry, Rafael Wysocki,
Alan Stern, netdev, linux-usb
In-Reply-To: <29958246.BU7m2dD7VT@linux-lqwf.site>
On Tue, Sep 18, 2012 at 10:28 PM, Oliver Neukum <oneukum@suse.de> wrote:
> On Tuesday 18 September 2012 22:23:18 Ming Lei wrote:
>> Hi,
>>
>> Currently only very few usbnet devices support the traffic based
>> runtime PM, eg. wake up devices if there are packets to be transmitted.
>
> Hi,
>
> independent of the rest it seems to me that the first two patches in your
> series are a useful cleanup by themselves. Could you submit them separately?
IMO, if the first two are OK now, David may commit the first two only.
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-09-18 14:31 UTC (permalink / raw)
To: netdev
In-Reply-To: <50588371.40103@googlemail.com>
>> ...
>> r8169 47159 0
>>
>> From the host I can successfully ping the guest, tap0 and the router as
>> you would expect, but from the guest, although I can ping the host and
>> tap0, I cannot ping the router. In practice, this means I have no
>> internet access from the guest. As I say, this configuration works
>> perfectly under 3.5.x and 3.4.x kernels.
>>
>> I'll do a coarse-grained "bisect" of Linus' 3.6 release candidates and
>> report back, but does anyone have any prime-suspect patches that may be
>> at the cause of this problem?
>>
>
> -rc1 turned out to have the problem so I've bisected between 3.5 and
> 3.6-rc1. I arrived at:
>
> $ git bisect bad
> d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5 is the first bad commit
> commit d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
> Author: David S. Miller <davem@davemloft.net>
> Date: Tue Jul 17 12:58:50 2012 -0700
>
> ipv4: Cache input routes in fib_info nexthops.
>
> Caching input routes is slightly simpler than output routes, since we
> don't need to be concerned with nexthop exceptions. (locally
> destined, and routed packets, never trigger PMTU events or redirects
> that will be processed by us).
>
> However, we have to elide caching for the DIRECTSRC and non-zero itag
> cases.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> :040000 040000 6bbc75c1cbe62bf84ea412d3b98adf2b614779cd
> 3ad7256b4a71e63ca4530977c0550121ea803d35 M include
> :040000 040000 18c2a950a53c4eec9bfa12185d1e382dfed74af8
> a2ab6157d6cd54930da395758c6ded3a225d1f04 M net
>
> The bisect log:
> git bisect start
> # bad: [0d7614f09c1ebdbaa1599a5aba7593f147bf96ee] Linux 3.6-rc1
> git bisect bad 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee
> # good: [28a33cbc24e4256c143dce96c7d93bf423229f92] Linux 3.5
> git bisect good 28a33cbc24e4256c143dce96c7d93bf423229f92
> # bad: [614a6d4341b3760ca98a1c2c09141b71db5d1e90] Merge branch 'for-3.6'
> of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
> git bisect bad 614a6d4341b3760ca98a1c2c09141b71db5d1e90
> # bad: [320f5ea0cedc08ef65d67e056bcb9d181386ef2c] genetlink: define
> lockdep_genl_is_held() when CONFIG_LOCKDEP
> git bisect bad 320f5ea0cedc08ef65d67e056bcb9d181386ef2c
> # good: [0cd06647b7c24f6633e32a505930a9aa70138c22] Merge branch 'master'
> of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
> git bisect good 0cd06647b7c24f6633e32a505930a9aa70138c22
> # good: [dbfa600148a25903976910863c75dae185f8d187] cxgb3: set maximal
> number of default RSS queues
> git bisect good dbfa600148a25903976910863c75dae185f8d187
> # good: [efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3] bnx2: Try to recover
> from PCI block reset
> git bisect good efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3
> # good: [1bf91cdc1bba94ea062a9147d924815c13f029f2] ixgbe: Drop
> references to deprecated pci_ DMA api and instead use dma_ API
> git bisect good 1bf91cdc1bba94ea062a9147d924815c13f029f2
> # good: [b6dfd939fdc249fcf8cd7b8006f76239b33eb581] ixgbe: add support
> for new 82599 device
> git bisect good b6dfd939fdc249fcf8cd7b8006f76239b33eb581
> # good: [3ba97381343b271296487bf073eb670d5465a8b8] net: ethernet:
> davinci_emac: add pm_runtime support
> git bisect good 3ba97381343b271296487bf073eb670d5465a8b8
> # bad: [5e9965c15ba88319500284e590733f4a4629a288] Merge branch
> 'kill_rtcache'
> git bisect bad 5e9965c15ba88319500284e590733f4a4629a288
> # good: [f5b0a8743601a4477419171f5046bd07d1c080a0] net: Document
> dst->obsolete better.
> git bisect good f5b0a8743601a4477419171f5046bd07d1c080a0
> # bad: [ba3f7f04ef2b19aace38f855aedd17fe43035d50] ipv4: Kill
> FLOWI_FLAG_RT_NOCACHE and associated code.
> git bisect bad ba3f7f04ef2b19aace38f855aedd17fe43035d50
> # good: [f2bb4bedf35d5167a073dcdddf16543f351ef3ae] ipv4: Cache output
> routes in fib_info nexthops.
> git bisect good f2bb4bedf35d5167a073dcdddf16543f351ef3ae
> # bad: [d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5] ipv4: Cache input
> routes in fib_info nexthops.
> git bisect bad d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
>
> Checking out the parent commit
> (f2bb4bedf35d5167a073dcdddf16543f351ef3ae) and building and installing
> the kernel gives a working configuration, so I'm pretty confident in the
> outcome of the bisect. Reversing the patch gives errors, so I've not
> tested master with the patch reversed.
>
> Let me know if I can help in any way to identify a fix.
>
Sorry, I forgot to say that I also have tried running TinyCore Linux as
a KVM guest on a 3.6.0-rc6 kernel, and I can ping the router fine, so
the problem seems to be something specifically related to ruuning
Windows XP as the guest. I don't have any other guests installed so
that's as much as I can say, although I could maybe install a Win7 guest
tomorrow if that would help.
> Chris
>
>> Let me know if there are any other diagnostics I can provide. Also, as
>> I'm not subscribed to netdev, please cc me to any reply.
>>
>> Thanks,
>>
>> Chris
^ permalink raw reply
* Re: [RFC PATCH v1 0/3] usbnet: runtime suspend when link becomes down
From: Oliver Neukum @ 2012-09-18 14:28 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman, Fink Dmitry, Rafael Wysocki,
Alan Stern, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1347978201-6219-1-git-send-email-ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
On Tuesday 18 September 2012 22:23:18 Ming Lei wrote:
> Hi,
>
> Currently only very few usbnet devices support the traffic based
> runtime PM, eg. wake up devices if there are packets to be transmitted.
Hi,
independent of the rest it seems to me that the first two patches in your
series are a useful cleanup by themselves. Could you submit them separately?
Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: xt_hashlimit.c race?
From: Eric Dumazet @ 2012-09-18 14:26 UTC (permalink / raw)
To: "Oleg A. Arkhangelsky"; +Cc: netdev
In-Reply-To: <20201347974535@web11g.yandex.ru>
On Tue, 2012-09-18 at 17:22 +0400, "Oleg A. Arkhangelsky" wrote:
> Hello,
>
> Looking at the net/netfilter/xt_hashlimit.c revealed one question. As far as
> I can understand hashlimit_mt() code under rcu_read_lock_bh() can be
> executed simultaneously by more than one CPU. So what if we have two
> packets with the same new dst value that processed in parallel by different
> CPUs? In both cases dh is NULL and both CPUs tries to create new
> entry in hash table. This is not what we want and can lead to undefined
> behavior in the future.
>
> Or maybe I'm wrong? Could anyone tell me is this situation possible?
>
Its absolutely possible, but should not have big impact.
One of the newly inserted entry will never be reached again and will
expire.
Following (untested) patch should remove the race.
net/netfilter/xt_hashlimit.c | 125 ++++++++++++++++-----------------
1 file changed, 62 insertions(+), 63 deletions(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 26a668a..246bc92 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -136,56 +136,6 @@ hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
return ((u64)hash * ht->cfg.size) >> 32;
}
-static struct dsthash_ent *
-dsthash_find(const struct xt_hashlimit_htable *ht,
- const struct dsthash_dst *dst)
-{
- struct dsthash_ent *ent;
- struct hlist_node *pos;
- u_int32_t hash = hash_dst(ht, dst);
-
- if (!hlist_empty(&ht->hash[hash])) {
- hlist_for_each_entry_rcu(ent, pos, &ht->hash[hash], node)
- if (dst_cmp(ent, dst)) {
- spin_lock(&ent->lock);
- return ent;
- }
- }
- return NULL;
-}
-
-/* allocate dsthash_ent, initialize dst, put in htable and lock it */
-static struct dsthash_ent *
-dsthash_alloc_init(struct xt_hashlimit_htable *ht,
- const struct dsthash_dst *dst)
-{
- struct dsthash_ent *ent;
-
- spin_lock(&ht->lock);
- /* initialize hash with random val at the time we allocate
- * the first hashtable entry */
- if (unlikely(!ht->rnd_initialized)) {
- get_random_bytes(&ht->rnd, sizeof(ht->rnd));
- ht->rnd_initialized = true;
- }
-
- if (ht->cfg.max && ht->count >= ht->cfg.max) {
- /* FIXME: do something. question is what.. */
- net_err_ratelimited("max count of %u reached\n", ht->cfg.max);
- ent = NULL;
- } else
- ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC);
- if (ent) {
- memcpy(&ent->dst, dst, sizeof(ent->dst));
- spin_lock_init(&ent->lock);
-
- spin_lock(&ent->lock);
- hlist_add_head_rcu(&ent->node, &ht->hash[hash_dst(ht, dst)]);
- ht->count++;
- }
- spin_unlock(&ht->lock);
- return ent;
-}
static void dsthash_free_rcu(struct rcu_head *head)
{
@@ -577,12 +527,70 @@ static u32 hashlimit_byte_cost(unsigned int len, struct dsthash_ent *dh)
return (u32) tmp;
}
+static struct dsthash_ent *
+dsthash_find(struct xt_hashlimit_htable *ht,
+ const struct dsthash_dst *dst)
+{
+ struct dsthash_ent *dh;
+ struct hlist_node *pos;
+ u_int32_t hash = hash_dst(ht, dst);
+ unsigned long now = jiffies;
+
+ hlist_for_each_entry_rcu(dh, pos, &ht->hash[hash], node) {
+ if (dst_cmp(dh, dst)) {
+found:
+ spin_lock(&dh->lock);
+ /* update expiration timeout */
+ dh->expires = now + msecs_to_jiffies(ht->cfg.expire);
+ rateinfo_recalc(dh, now, ht->cfg.mode);
+ return dh;
+ }
+ }
+
+ /* slow path */
+ spin_lock(&ht->lock);
+
+ /* initialize hash with random val at the time we allocate
+ * the first hashtable entry
+ */
+ if (unlikely(!ht->rnd_initialized)) {
+ get_random_bytes(&ht->rnd, sizeof(ht->rnd));
+ ht->rnd_initialized = true;
+ }
+ hash = hash_dst(ht, dst);
+ hlist_for_each_entry_rcu(dh, pos, &ht->hash[hash], node) {
+ if (dst_cmp(dh, dst)) {
+ spin_unlock(&ht->lock);
+ goto found;
+ }
+ }
+
+ if (ht->cfg.max && ht->count >= ht->cfg.max) {
+ /* FIXME: do something. question is what.. */
+ net_err_ratelimited("max count of %u reached\n", ht->cfg.max);
+ dh = NULL;
+ } else {
+ dh = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC);
+ }
+ if (dh) {
+ memcpy(&dh->dst, dst, sizeof(dh->dst));
+ spin_lock_init(&dh->lock);
+
+ spin_lock(&dh->lock);
+ hlist_add_head_rcu(&dh->node, &ht->hash[hash_dst(ht, dst)]);
+ ht->count++;
+ dh->expires = now + msecs_to_jiffies(ht->cfg.expire);
+ rateinfo_init(dh, ht);
+ }
+ spin_unlock(&ht->lock);
+ return dh;
+}
+
static bool
hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
struct xt_hashlimit_htable *hinfo = info->hinfo;
- unsigned long now = jiffies;
struct dsthash_ent *dh;
struct dsthash_dst dst;
u32 cost;
@@ -593,17 +601,8 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
rcu_read_lock_bh();
dh = dsthash_find(hinfo, &dst);
if (dh == NULL) {
- dh = dsthash_alloc_init(hinfo, &dst);
- if (dh == NULL) {
- rcu_read_unlock_bh();
- goto hotdrop;
- }
- dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
- rateinfo_init(dh, hinfo);
- } else {
- /* update expiration timeout */
- dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
- rateinfo_recalc(dh, now, hinfo->cfg.mode);
+ rcu_read_unlock_bh();
+ goto hotdrop;
}
if (info->cfg.mode & XT_HASHLIMIT_BYTES)
@@ -624,7 +623,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
/* default match is underlimit - so over the limit, we need to invert */
return info->cfg.mode & XT_HASHLIMIT_INVERT;
- hotdrop:
+hotdrop:
par->hotdrop = true;
return false;
}
^ permalink raw reply related
* [RFC PATCH v1 1/3] usbnet: introduce usbnet_link_change API
From: Ming Lei @ 2012-09-18 14:23 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, Fink Dmitry, Rafael Wysocki, Alan Stern, netdev,
linux-usb, Ming Lei
In-Reply-To: <1347978201-6219-1-git-send-email-ming.lei@canonical.com>
This patch introduces the API of usbnet_link_change, so that
usbnet can trace the link change, which may help to implement
the later runtime PM triggered by usb ethernet link change.
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
drivers/net/usb/usbnet.c | 13 ++++++++++++-
include/linux/usb/usbnet.h | 2 +-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index e944109..e986e4b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -677,6 +677,18 @@ static void usbnet_terminate_urbs(struct usbnet *dev)
remove_wait_queue(&unlink_wakeup, &wait);
}
+void usbnet_link_change(struct usbnet *dev, int link, int need_reset)
+{
+ if (link)
+ netif_carrier_on(dev->net);
+ else
+ netif_carrier_off(dev->net);
+
+ if (need_reset && link)
+ usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+}
+EXPORT_SYMBOL(usbnet_link_change);
+
int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
@@ -1591,7 +1603,6 @@ int usbnet_resume (struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_resume);
-
/*-------------------------------------------------------------------------*/
static int __init usbnet_init(void)
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index f87cf62..1937b74 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -160,7 +160,7 @@ extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
extern int usbnet_suspend(struct usb_interface *, pm_message_t);
extern int usbnet_resume(struct usb_interface *);
extern void usbnet_disconnect(struct usb_interface *);
-
+extern void usbnet_link_change(struct usbnet *dev, int link, int need_reset);
/* Drivers that reuse some of the standard USB CDC infrastructure
* (notably, using multiple interfaces according to the CDC
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH v1 3/3] usbnet: support runtime PM triggered by link change
From: Ming Lei @ 2012-09-18 14:23 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, Fink Dmitry, Rafael Wysocki, Alan Stern,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
Ming Lei
In-Reply-To: <1347978201-6219-1-git-send-email-ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
This patch implements runtime PM triggered by link change event
for devices which haven't defined manage_power() callback, based
on the below consideration:
- this kind of runtime PM has been supported by some PCI network
interfaces already, and it does make sense to suspend the usb
device to save power if no link is detected
- link down triggered runtime needn't to be implemented for devices
which have already supported traffic based runtime PM by .manage_power,
because runtime suspend can be triggered when no tx frames are to be
transmitted after link becoms down.
Unfortunately, some usbnet devices don't support remote wakeup,
or some devices may support it but the remote wakup can't be enabled
for link change event for some reason(no documents are public, not
supported ...).
This patch takes a periodic timer to wake up devices for detecting
the link change event if remote wakeup by link change can't be
supported. If the link is found to be down, put the device into
suspend immediately.
For the devices which support remote wakeup by link change and
don't support remote wakeup by incoming packets(not implement
manage_power callback), the patch can still make link change
triggered runtime PM working on these devices.
Signed-off-by: Ming Lei <ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
drivers/net/usb/sierra_net.c | 3 +-
drivers/net/usb/usbnet.c | 269 +++++++++++++++++++++++++++++++++++++++++-
include/linux/usb/usbnet.h | 20 ++++
3 files changed, 286 insertions(+), 6 deletions(-)
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 08ed9e5..0993f2d 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -418,6 +418,7 @@ static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
priv->link_up = 0;
}
usbnet_link_change(dev, link_up, 0);
+ usbnet_link_updated(dev);
}
static void sierra_net_dosync(struct usbnet *dev)
@@ -915,7 +916,7 @@ static struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev,
static const struct driver_info sierra_net_info_direct_ip = {
.description = "Sierra Wireless USB-to-WWAN Modem",
- .flags = FLAG_WWAN | FLAG_SEND_ZLP,
+ .flags = FLAG_WWAN | FLAG_SEND_ZLP | FLAG_LINK_UPDATE_BY_DRIVER,
.bind = sierra_net_bind,
.unbind = sierra_net_unbind,
.status = sierra_net_status,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index dc4ff47..14aa39e 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -91,6 +91,12 @@ static int msg_level = -1;
module_param (msg_level, int, 0);
MODULE_PARM_DESC (msg_level, "Override default message level");
+/* link runtime PM: auto check time */
+static int link_autocheck_time = 3;
+module_param_named(autocheck, link_autocheck_time, int, 0644);
+MODULE_PARM_DESC(autocheck, "default link auto check time in second");
+
+
/*-------------------------------------------------------------------------*/
/* handles CDC Ethernet and many other network "bulk data" interfaces */
@@ -677,8 +683,228 @@ static void usbnet_terminate_urbs(struct usbnet *dev)
remove_wait_queue(&unlink_wakeup, &wait);
}
-void usbnet_link_change(struct usbnet *dev, int link, int need_reset)
+void usbnet_link_updated(struct usbnet *dev)
+{
+ complete(&dev->link_update_completion);
+}
+EXPORT_SYMBOL(usbnet_link_updated);
+
+#define usbnet_link_suspend(dev) do { \
+ dev_dbg(&dev->intf->dev, "%s:link suspend", __func__); \
+ usb_autopm_put_interface_async(dev->intf); \
+} while(0)
+
+#define usbnet_link_resume(dev) do { \
+ dev_dbg(&dev->intf->dev, "%s:link resume", __func__); \
+ usb_autopm_get_interface_async(dev->intf); \
+} while(0)
+
+static int need_link_runtime_pm(struct usbnet *dev)
+{
+ if (dev->driver_info->manage_power)
+ return 0;
+
+ if (!dev->driver_info->status)
+ return 0;
+
+ return 1;
+}
+
+/* called by usbnet_suspend */
+static void start_link_detect(struct usbnet *dev)
{
+ if (!dev->link_rpm_enabled)
+ return;
+
+ if (dev->link_remote_wakeup)
+ return;
+
+ if (dev->link_check_started)
+ return;
+
+ dev->link_check_started = 1;
+ queue_delayed_work(system_freezable_wq, &dev->link_detect_work,
+ link_autocheck_time * HZ);
+}
+
+/* called by usbnet_resume */
+static void end_link_detect(struct usbnet *dev, int force_cancel)
+{
+ if (!dev->link_rpm_enabled)
+ return;
+
+ if (!dev->link_check_started)
+ return;
+
+ /*
+ * cancel the link detect work if usbnet is resumed
+ * not by link detect work
+ */
+ if (!dev->link_checking || force_cancel)
+ cancel_delayed_work_sync(&dev->link_detect_work);
+
+ dev->link_check_started = 0;
+}
+
+/* called by usbnet_open */
+static void enable_link_runtime_pm(struct usbnet *dev)
+{
+ dev->link_rpm_enabled = 1;
+
+ if (!dev->link_remote_wakeup) {
+ spin_lock_irq(&dev->udev->dev.power.lock);
+ dev->old_autosuspend_delay =
+ dev->udev->dev.power.autosuspend_delay;
+ spin_unlock_irq(&dev->udev->dev.power.lock);
+ pm_runtime_set_autosuspend_delay(&dev->udev->dev, 1);
+ } else {
+ dev->intf->needs_remote_wakeup = 1;
+ }
+
+ if (!netif_carrier_ok(dev->net) && dev->link_rpm_supported) {
+ dev->link_open_suspend = 1;
+ usbnet_link_suspend(dev);
+ }
+}
+
+/* called by usbnet_stop */
+static void disable_link_runtime_pm(struct usbnet *dev)
+{
+ int delay;
+
+ if (!dev->link_rpm_enabled)
+ return;
+
+ dev->link_rpm_enabled = 0;
+ end_link_detect(dev, 1);
+
+ if (dev->link_open_suspend) {
+ usbnet_link_resume(dev);
+ dev->link_open_suspend = 0;
+ }
+
+ if (dev->link_remote_wakeup) {
+ dev->intf->needs_remote_wakeup = 0;
+ return;
+ }
+
+ spin_lock_irq(&dev->udev->dev.power.lock);
+ delay = dev->udev->dev.power.autosuspend_delay;
+ spin_unlock_irq(&dev->udev->dev.power.lock);
+
+ /*
+ * If autosuspend delay has been changed after
+ * enable_link_runtime_pm(), just keep the latest delay.
+ *
+ * FIXME: the delay might be changed after the above
+ * lock is released and before the lock is held in
+ * pm_runtime_set_autosuspend_delay(), looks no
+ * big effect.
+ */
+ if (delay == 1) {
+ delay = dev->old_autosuspend_delay;
+ pm_runtime_set_autosuspend_delay(&dev->udev->dev,
+ delay);
+ }
+}
+
+static void update_link_state(struct usbnet *dev)
+{
+ char *buf = NULL;
+ unsigned pipe = 0;
+ unsigned maxp;
+ int ret, act_len, timeout;
+ struct urb urb;
+
+ pipe = usb_rcvintpipe(dev->udev,
+ dev->status->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+ maxp = usb_maxpacket(dev->udev, pipe, 0);
+
+ /*
+ * Take default timeout as 2 times of period.
+ * It is observed that asix device can update its link
+ * state duing one period(128ms). Low level driver can set
+ * its default update link time in bind() callback.
+ */
+ if (!dev->link_update_timeout) {
+ timeout = max((int) dev->status->desc.bInterval,
+ (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
+ timeout = 1 << timeout;
+ if (dev->udev->speed == USB_SPEED_HIGH)
+ timeout /= 8;
+ if (timeout < 128)
+ timeout = 128;
+ } else
+ timeout = dev->link_update_timeout;
+
+ buf = kmalloc(maxp, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ dev_dbg(&dev->intf->dev, "%s: timeout %dms\n", __func__, timeout);
+ ret = usb_interrupt_msg(dev->udev, pipe, buf, maxp,
+ &act_len, timeout);
+ if (!ret) {
+ urb.status = 0;
+ urb.actual_length = act_len;
+ urb.transfer_buffer = buf;
+ urb.transfer_buffer_length = maxp;
+ dev->driver_info->status(dev, &urb);
+ if (dev->driver_info->flags &
+ FLAG_LINK_UPDATE_BY_DRIVER)
+ wait_for_completion(&dev->link_update_completion);
+ dev_dbg(&dev->intf->dev, "%s: link updated\n", __func__);
+ } else
+ dev_dbg(&dev->intf->dev, "%s: link update failed %d\n",
+ __func__, ret);
+ kfree(buf);
+}
+
+static void link_detect_work(struct work_struct *work)
+{
+ struct usbnet *dev = container_of(work, struct usbnet,
+ link_detect_work.work);
+
+ dev_dbg(&dev->intf->dev, "%s: link resume\n", __func__);
+
+ dev->link_checking = 1;
+ usb_autopm_get_interface(dev->intf);
+ update_link_state(dev);
+ dev->link_checking = 0;
+
+ dev_dbg(&dev->intf->dev, "%s: link state %d\n",
+ __func__, netif_carrier_ok(dev->net));
+
+ if (!netif_carrier_ok(dev->net))
+ usb_autopm_put_interface(dev->intf);
+ else
+ usb_submit_urb(dev->interrupt, GFP_NOIO);
+}
+
+static void init_link_rpm(struct usbnet *dev)
+{
+ INIT_DELAYED_WORK(&dev->link_detect_work, link_detect_work);
+ init_completion(&dev->link_update_completion);
+
+ dev->link_remote_wakeup = !!(dev->driver_info->flags &
+ FLAG_LINK_SUPPORT_REMOTE_WAKEUP);
+ if (dev->link_remote_wakeup &&
+ !device_can_wakeup(&dev->udev->dev)) {
+ dev_err(&dev->udev->dev,
+ "I don't support remote wakeup\n");
+ dev->link_remote_wakeup = 0;
+ }
+
+ dev->link_state = 1;
+}
+
+static void __usbnet_link_change(struct usbnet *dev, int link,
+ int need_reset)
+{
+ dev_dbg(&dev->intf->dev, "%s: old_link=%d link=%d\n", __func__,
+ dev->link_state, link);
+
if (link)
netif_carrier_on(dev->net);
else
@@ -686,6 +912,25 @@ void usbnet_link_change(struct usbnet *dev, int link, int need_reset)
if (need_reset && link)
usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+
+ if (dev->link_rpm_enabled) {
+ if (!link && dev->link_state)
+ usbnet_link_suspend(dev);
+ else if (link && !dev->link_state && dev->link_remote_wakeup)
+ usbnet_link_resume(dev);
+ }
+ dev->link_state = link;
+}
+
+void usbnet_link_change(struct usbnet *dev, int link, int need_reset)
+{
+ /*
+ * Suppose the low level driver may support link runtime PM
+ * if it can detect the link change via usbnet_link_change.
+ */
+ dev->link_rpm_supported = 1;
+
+ __usbnet_link_change(dev, link, need_reset);
}
EXPORT_SYMBOL(usbnet_link_change);
@@ -731,8 +976,10 @@ int usbnet_stop (struct net_device *net)
tasklet_kill (&dev->bh);
if (info->manage_power)
info->manage_power(dev, 0);
- else
+ else {
+ disable_link_runtime_pm(dev);
usb_autopm_put_interface(dev->intf);
+ }
return 0;
}
@@ -807,6 +1054,9 @@ int usbnet_open (struct net_device *net)
if (retval < 0)
goto done_manage_power_error;
usb_autopm_put_interface(dev->intf);
+ } else {
+ if (need_link_runtime_pm(dev))
+ enable_link_runtime_pm(dev);
}
return retval;
@@ -1499,7 +1749,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
netif_device_attach (net);
if (dev->driver_info->flags & FLAG_LINK_INTR)
- usbnet_link_change(dev, 0, 0);
+ __usbnet_link_change(dev, 0, 0);
+
+ init_link_rpm(dev);
return 0;
@@ -1550,6 +1802,9 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
* wake the device
*/
netif_device_attach (dev->net);
+
+ if (PMSG_IS_AUTO(message))
+ start_link_detect(dev);
}
return 0;
}
@@ -1564,8 +1819,10 @@ int usbnet_resume (struct usb_interface *intf)
if (!--dev->suspend_count) {
/* resume interrupt URBs */
- if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags))
- usb_submit_urb(dev->interrupt, GFP_NOIO);
+ if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) {
+ if (!dev->link_checking)
+ usb_submit_urb(dev->interrupt, GFP_NOIO);
+ }
spin_lock_irq(&dev->txq.lock);
while ((res = usb_get_from_anchor(&dev->deferred))) {
@@ -1598,6 +1855,8 @@ int usbnet_resume (struct usb_interface *intf)
netif_tx_wake_all_queues(dev->net);
tasklet_schedule (&dev->bh);
}
+
+ end_link_detect(dev, 0);
}
return 0;
}
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 1937b74..d23dae5 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -68,6 +68,19 @@ struct usbnet {
# define EVENT_RX_PAUSED 5
# define EVENT_DEV_ASLEEP 6
# define EVENT_DEV_OPEN 7
+
+ /* link down triggered runtime PM */
+ struct delayed_work link_detect_work;
+ struct completion link_update_completion;
+ int link_update_timeout;
+ int old_autosuspend_delay;
+ unsigned int link_rpm_supported:1;
+ unsigned int link_rpm_enabled:1;
+ unsigned int link_check_started:1;
+ unsigned int link_checking:1;
+ unsigned int link_open_suspend:1;
+ unsigned int link_state:1;
+ unsigned int link_remote_wakeup:1;
};
static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -106,6 +119,12 @@ struct driver_info {
#define FLAG_MULTI_PACKET 0x2000
#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
+/* some drivers may not update link state in .status */
+#define FLAG_LINK_UPDATE_BY_DRIVER 0x8000
+
+/* device support remote wakeup by link change */
+#define FLAG_LINK_SUPPORT_REMOTE_WAKEUP 0x10000
+
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
@@ -161,6 +180,7 @@ extern int usbnet_suspend(struct usb_interface *, pm_message_t);
extern int usbnet_resume(struct usb_interface *);
extern void usbnet_disconnect(struct usb_interface *);
extern void usbnet_link_change(struct usbnet *dev, int link, int need_reset);
+extern void usbnet_link_updated(struct usbnet *dev);
/* Drivers that reuse some of the standard USB CDC infrastructure
* (notably, using multiple interfaces according to the CDC
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [RFC PATCH v1 2/3] usbnet: apply usbnet_link_change
From: Ming Lei @ 2012-09-18 14:23 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, Fink Dmitry, Rafael Wysocki, Alan Stern,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
Ming Lei
In-Reply-To: <1347978201-6219-1-git-send-email-ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
This patch applies the introduce usbnet_link_change API.
Signed-off-by: Ming Lei <ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
drivers/net/usb/asix_devices.c | 6 +-----
drivers/net/usb/cdc_ether.c | 5 +----
drivers/net/usb/cdc_ncm.c | 9 +++------
drivers/net/usb/dm9601.c | 7 +------
drivers/net/usb/mcs7830.c | 6 +-----
drivers/net/usb/sierra_net.c | 3 +--
drivers/net/usb/usbnet.c | 2 +-
7 files changed, 9 insertions(+), 29 deletions(-)
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 4fd48df..c354bb1 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -55,11 +55,7 @@ static void asix_status(struct usbnet *dev, struct urb *urb)
event = urb->transfer_buffer;
link = event->link & 0x01;
if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent (dev, EVENT_LINK_RESET );
- } else
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, link, 1);
netdev_dbg(dev->net, "Link Status is: %d\n", link);
}
}
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a03de71..c6e4be5 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -406,10 +406,7 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
case USB_CDC_NOTIFY_NETWORK_CONNECTION:
netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
event->wValue ? "on" : "off");
- if (event->wValue)
- netif_carrier_on(dev->net);
- else
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, event->wValue, 0);
break;
case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a..f425c2c 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -593,7 +593,7 @@ advance:
* (carrier is OFF) during attach, so the IP network stack does not
* start IPv6 negotiation and more.
*/
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, 0, 0);
ctx->tx_speed = ctx->rx_speed = 0;
return 0;
@@ -1131,12 +1131,9 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
" %sconnected\n",
ctx->netdev->name, ctx->connected ? "" : "dis");
- if (ctx->connected)
- netif_carrier_on(dev->net);
- else {
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, ctx->connected, 0);
+ if (!ctx->connected)
ctx->tx_speed = ctx->rx_speed = 0;
- }
break;
case USB_CDC_NOTIFY_SPEED_CHANGE:
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index e0433ce..7422d5a 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -587,12 +587,7 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb)
link = !!(buf[0] & 0x40);
if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent (dev, EVENT_LINK_RESET);
- }
- else
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, link, 1);
netdev_dbg(dev->net, "Link Status is: %d\n", link);
}
}
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 03c2d8d..49a98b7 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -639,11 +639,7 @@ static void mcs7830_status(struct usbnet *dev, struct urb *urb)
link = !(buf[1] & 0x20);
if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- } else
- netif_carrier_off(dev->net);
+ usbnet_link_change(dev, link, 1);
netdev_dbg(dev->net, "Link Status is: %d\n", link);
}
}
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 7ae70e9..08ed9e5 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -414,11 +414,10 @@ static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
if (link_up) {
sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
priv->link_up = 1;
- netif_carrier_on(dev->net);
} else {
priv->link_up = 0;
- netif_carrier_off(dev->net);
}
+ usbnet_link_change(dev, link_up, 0);
}
static void sierra_net_dosync(struct usbnet *dev)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index e986e4b..dc4ff47 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1499,7 +1499,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
netif_device_attach (net);
if (dev->driver_info->flags & FLAG_LINK_INTR)
- netif_carrier_off(net);
+ usbnet_link_change(dev, 0, 0);
return 0;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
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