* [PATCH net-next 2/2] ipip: capture inner headers during encapsulation
From: Pravin B Shelar @ 2013-03-09 1:12 UTC (permalink / raw)
To: davem, netdev; +Cc: jesse, Pravin B Shelar
Allow IPIP to make use of tx-checksum offloading.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
net/ipv4/ipip.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 18f5352..b50435b 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -483,11 +483,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
- skb_checksum_help(skb))
- goto tx_error;
-
old_iph = ip_hdr(skb);
if (tos & 1)
@@ -572,6 +567,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
old_iph = ip_hdr(skb);
}
+ if (!skb->encapsulation) {
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+ }
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ skb->ip_summed = CHECKSUM_NONE;
+
skb->transport_header = skb->network_header;
skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
@@ -599,7 +601,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->ttl = old_iph->ttl;
nf_reset(skb);
- skb->ip_summed = CHECKSUM_NONE;
pkt_len = skb->len - skb_transport_offset(skb);
err = ip_local_out(skb);
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 1/2] ipip: Use tunnel_ip_select_ident() for tunnel IP-Identification.
From: Pravin B Shelar @ 2013-03-09 1:12 UTC (permalink / raw)
To: davem, netdev; +Cc: jesse, Pravin B Shelar
tunnel_ip_select_ident() is more efficient when generating ip-header
id given inner packet is of ipv4 type.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
net/ipv4/ipip.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 8f024d4..18f5352 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -478,6 +478,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
__be32 dst = tiph->daddr;
struct flowi4 fl4;
int mtu;
+ int err;
+ int pkt_len;
if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
@@ -591,11 +593,28 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->tos = INET_ECN_encapsulate(tos, old_iph->tos);
iph->daddr = fl4.daddr;
iph->saddr = fl4.saddr;
+ tunnel_ip_select_ident(skb, old_iph, &rt->dst);
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = old_iph->ttl;
- iptunnel_xmit(skb, dev);
+ nf_reset(skb);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ pkt_len = skb->len - skb_transport_offset(skb);
+ err = ip_local_out(skb);
+ if (likely(net_xmit_eval(err) == 0)) {
+ struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats);
+
+ u64_stats_update_begin(&tstats->syncp);
+ tstats->tx_bytes += pkt_len;
+ tstats->tx_packets++;
+ u64_stats_update_end(&tstats->syncp);
+ } else {
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
+ }
+
return NETDEV_TX_OK;
tx_error_icmp:
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 0/2] ipip: Few ipip tunnel improvements.
From: Pravin B Shelar @ 2013-03-09 1:12 UTC (permalink / raw)
To: davem, netdev; +Cc: jesse, Pravin B Shelar
Few improvements which are already present in other tunneling
protocols implementations like gre and vxlan.
Pravin B Shelar (2):
ipip: Use tunnel_ip_select_ident() for tunnel IP-Identification.
ipip: capture inner headers during encapsulation
net/ipv4/ipip.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
^ permalink raw reply
* [PATCH net-next] drivers:net: Remove unnecessary OOM messages after netdev_alloc_skb
From: Joe Perches @ 2013-03-09 1:03 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Emitting netdev_alloc_skb and netdev_alloc_skb_ip_align OOM
messages is unnecessary as there is already a dump_stack
after allocation failures.
Other trivial changes around these removals:
Convert a few comparisons of pointer to 0 to !pointer.
Change flow to remove unnecessary label.
Remove now unused variable.
Hoist assignment from if.
Signed-off-by: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
---
drivers/net/caif/caif_shmcore.c | 5 +----
drivers/net/ethernet/adi/bfin_mac.c | 6 ++----
drivers/net/ethernet/amd/7990.c | 2 --
drivers/net/ethernet/amd/a2065.c | 1 -
drivers/net/ethernet/amd/am79c961a.c | 1 -
drivers/net/ethernet/amd/ariadne.c | 1 -
drivers/net/ethernet/amd/atarilance.c | 2 --
drivers/net/ethernet/amd/au1000_eth.c | 1 -
drivers/net/ethernet/amd/declance.c | 2 --
drivers/net/ethernet/amd/pcnet32.c | 1 -
drivers/net/ethernet/amd/sun3lance.c | 3 ---
drivers/net/ethernet/amd/sunlance.c | 4 ----
drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 6 ++----
drivers/net/ethernet/atheros/atlx/atl2.c | 3 ---
drivers/net/ethernet/broadcom/bgmac.c | 4 +---
drivers/net/ethernet/broadcom/sb1250-mac.c | 5 +----
drivers/net/ethernet/cadence/at91_ether.c | 1 -
drivers/net/ethernet/cirrus/cs89x0.c | 6 ------
drivers/net/ethernet/dlink/dl2k.c | 7 ++-----
drivers/net/ethernet/freescale/fec.c | 2 --
.../net/ethernet/freescale/fs_enet/fs_enet-main.c | 17 +++--------------
drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 2 --
drivers/net/ethernet/i825xx/82596.c | 8 +++-----
drivers/net/ethernet/i825xx/lib82596.c | 6 ++----
drivers/net/ethernet/ibm/ehea/ehea_main.c | 9 ++-------
drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 5 ++---
drivers/net/ethernet/natsemi/sonic.c | 1 -
drivers/net/ethernet/netx-eth.c | 2 --
drivers/net/ethernet/nuvoton/w90p910_ether.c | 1 -
drivers/net/ethernet/nvidia/forcedeth.c | 1 -
drivers/net/ethernet/qlogic/qla3xxx.c | 1 -
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 6 ------
drivers/net/ethernet/rdc/r6040.c | 1 -
drivers/net/ethernet/realtek/8139too.c | 2 --
drivers/net/ethernet/realtek/atp.c | 2 --
drivers/net/ethernet/seeq/ether3.c | 22 +++++-----------------
drivers/net/ethernet/seeq/sgiseeq.c | 2 --
drivers/net/ethernet/sis/sis900.c | 7 ++-----
drivers/net/ethernet/smsc/smc9194.c | 2 --
drivers/net/ethernet/smsc/smc91x.c | 2 --
drivers/net/ethernet/smsc/smsc9420.c | 4 +---
drivers/net/ethernet/sun/sunqe.c | 5 +----
drivers/net/ethernet/tehuti/tehuti.c | 5 ++---
drivers/net/ethernet/ti/tlan.c | 4 +---
drivers/net/ethernet/xilinx/ll_temac_main.c | 10 +++-------
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 9 +++------
drivers/net/ethernet/xircom/xirc2ps_cs.c | 1 -
47 files changed, 39 insertions(+), 161 deletions(-)
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c
index bce8bac..cca2afc 100644
--- a/drivers/net/caif/caif_shmcore.c
+++ b/drivers/net/caif/caif_shmcore.c
@@ -338,11 +338,8 @@ static void shm_rx_work_func(struct work_struct *rx_work)
/* Get a suitable CAIF packet and copy in data. */
skb = netdev_alloc_skb(pshm_drv->pshm_dev->pshm_netdev,
frm_pck_len + 1);
-
- if (skb == NULL) {
- pr_info("OOM: Try next frame in descriptor\n");
+ if (skb == NULL)
break;
- }
p = skb_put(skb, frm_pck_len);
memcpy(p, pbuf->desc_vptr + frm_pck_ofs, frm_pck_len);
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index a175d0b..ee70577 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -188,10 +188,9 @@ static int desc_list_init(struct net_device *dev)
/* allocate a new skb for next time receive */
new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
- if (!new_skb) {
- pr_notice("init: low on mem - packet dropped\n");
+ if (!new_skb)
goto init_error;
- }
+
skb_reserve(new_skb, NET_IP_ALIGN);
/* Invidate the data cache of skb->data range when it is write back
* cache. It will prevent overwritting the new data from DMA
@@ -1236,7 +1235,6 @@ static void bfin_mac_rx(struct net_device *dev)
new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
if (!new_skb) {
- netdev_notice(dev, "rx: low on mem - packet dropped\n");
dev->stats.rx_dropped++;
goto out;
}
diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c
index 6e722dc..65926a9 100644
--- a/drivers/net/ethernet/amd/7990.c
+++ b/drivers/net/ethernet/amd/7990.c
@@ -318,8 +318,6 @@ static int lance_rx (struct net_device *dev)
struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
if (!skb) {
- printk ("%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
rd->mblength = 0;
rd->rmd1_bits = LE_R1_OWN;
diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c
index 3789aff..0866e76 100644
--- a/drivers/net/ethernet/amd/a2065.c
+++ b/drivers/net/ethernet/amd/a2065.c
@@ -293,7 +293,6 @@ static int lance_rx(struct net_device *dev)
struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
if (!skb) {
- netdev_warn(dev, "Memory squeeze, deferring packet\n");
dev->stats.rx_dropped++;
rd->mblength = 0;
rd->rmd1_bits = LE_R1_OWN;
diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c
index 60e2b70..9793767 100644
--- a/drivers/net/ethernet/amd/am79c961a.c
+++ b/drivers/net/ethernet/amd/am79c961a.c
@@ -528,7 +528,6 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
dev->stats.rx_packets++;
} else {
am_writeword (dev, hdraddr + 2, RMD_OWN);
- printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
dev->stats.rx_dropped++;
break;
}
diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c
index 98f4522..c178eb4 100644
--- a/drivers/net/ethernet/amd/ariadne.c
+++ b/drivers/net/ethernet/amd/ariadne.c
@@ -193,7 +193,6 @@ static int ariadne_rx(struct net_device *dev)
skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- netdev_warn(dev, "Memory squeeze, deferring packet\n");
for (i = 0; i < RX_RING_SIZE; i++)
if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN)
break;
diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
index 84219df..ab9bedb 100644
--- a/drivers/net/ethernet/amd/atarilance.c
+++ b/drivers/net/ethernet/amd/atarilance.c
@@ -996,8 +996,6 @@ static int lance_rx( struct net_device *dev )
else {
skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
- dev->name ));
for( i = 0; i < RX_RING_SIZE; i++ )
if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
RMD1_OWN_CHIP)
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index de774d4..688aede 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -727,7 +727,6 @@ static int au1000_rx(struct net_device *dev)
frmlen -= 4; /* Remove FCS */
skb = netdev_alloc_skb(dev, frmlen + 2);
if (skb == NULL) {
- netdev_err(dev, "Memory squeeze, dropping packet.\n");
dev->stats.rx_dropped++;
continue;
}
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c
index baca0bd..3d86ffe 100644
--- a/drivers/net/ethernet/amd/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -607,8 +607,6 @@ static int lance_rx(struct net_device *dev)
skb = netdev_alloc_skb(dev, len + 2);
if (skb == 0) {
- printk("%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
*rds_ptr(rd, mblength, lp->type) = 0;
*rds_ptr(rd, rmd1, lp->type) =
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index 797f847..ed21307 100644
--- a/drivers/net/ethernet/amd/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -1166,7 +1166,6 @@ static void pcnet32_rx_entry(struct net_device *dev,
skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
if (skb == NULL) {
- netif_err(lp, drv, dev, "Memory squeeze, dropping packet\n");
dev->stats.rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c
index 74b3891..de412d3 100644
--- a/drivers/net/ethernet/amd/sun3lance.c
+++ b/drivers/net/ethernet/amd/sun3lance.c
@@ -812,9 +812,6 @@ static int lance_rx( struct net_device *dev )
else {
skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
- dev->name ));
-
dev->stats.rx_dropped++;
head->msg_length = 0;
head->flag |= RMD1_OWN_CHIP;
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index 6a40290..70d5430 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -536,8 +536,6 @@ static void lance_rx_dvma(struct net_device *dev)
skb = netdev_alloc_skb(dev, len + 2);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
rd->mblength = 0;
rd->rmd1_bits = LE_R1_OWN;
@@ -708,8 +706,6 @@ static void lance_rx_pio(struct net_device *dev)
skb = netdev_alloc_skb(dev, len + 2);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
sbus_writew(0, &rd->mblength);
sbus_writeb(LE_R1_OWN, &rd->rmd1_bits);
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 92f4734..e1f1b2a 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1420,11 +1420,9 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
RRS_PKT_SIZE_MASK) - 4; /* CRC */
skb = netdev_alloc_skb_ip_align(netdev, packet_size);
- if (skb == NULL) {
- netdev_warn(netdev,
- "Memory squeeze, deferring packet\n");
+ if (skb == NULL)
goto skip_pkt;
- }
+
memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
skb_put(skb, packet_size);
skb->protocol = eth_type_trans(skb, netdev);
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index 1278b47..a046b6f 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -437,9 +437,6 @@ static void atl2_intr_rx(struct atl2_adapter *adapter)
/* alloc new buffer */
skb = netdev_alloc_skb_ip_align(netdev, rx_size);
if (NULL == skb) {
- printk(KERN_WARNING
- "%s: Mem squeeze, deferring packet.\n",
- netdev->name);
/*
* Check that some rx space is free. If not,
* free one and mark stats->rx_dropped++.
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index d6cb376..eec0af4 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -245,10 +245,8 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
/* Alloc skb */
slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
- if (!slot->skb) {
- bgmac_err(bgmac, "Allocation of skb failed!\n");
+ if (!slot->skb)
return -ENOMEM;
- }
/* Poison - if everything goes fine, hardware will overwrite it */
rx = (struct bgmac_rx_header *)slot->skb->data;
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index e9b35da..e80bfb6 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -831,11 +831,8 @@ static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d,
sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE +
SMP_CACHE_BYTES * 2 +
NET_IP_ALIGN);
- if (sb_new == NULL) {
- pr_info("%s: sk_buff allocation failed\n",
- d->sbdma_eth->sbm_dev->name);
+ if (sb_new == NULL)
return -ENOBUFS;
- }
sbdma_align_skb(sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN);
}
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
index 1a57e16..5bd7786 100644
--- a/drivers/net/ethernet/cadence/at91_ether.c
+++ b/drivers/net/ethernet/cadence/at91_ether.c
@@ -209,7 +209,6 @@ static void at91ether_rx(struct net_device *dev)
netif_rx(skb);
} else {
lp->stats.rx_dropped++;
- netdev_notice(dev, "Memory squeeze, dropping packet.\n");
}
if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH))
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index 73c1c8c..aaa0499 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -478,9 +478,6 @@ dma_rx(struct net_device *dev)
/* Malloc up new buffer. */
skb = netdev_alloc_skb(dev, length + 2);
if (skb == NULL) {
- /* I don't think we want to do this to a stressed system */
- cs89_dbg(0, err, "%s: Memory squeeze, dropping packet\n",
- dev->name);
dev->stats.rx_dropped++;
/* AKPM: advance bp to the next frame */
@@ -731,9 +728,6 @@ net_rx(struct net_device *dev)
/* Malloc up new buffer. */
skb = netdev_alloc_skb(dev, length + 2);
if (skb == NULL) {
-#if 0 /* Again, this seems a cruel thing to do */
- pr_warn("%s: Memory squeeze, dropping packet\n", dev->name);
-#endif
dev->stats.rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index 110d26f..afa8e3a 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -580,12 +580,9 @@ alloc_list (struct net_device *dev)
skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
np->rx_skbuff[i] = skb;
- if (skb == NULL) {
- printk (KERN_ERR
- "%s: alloc_list: allocate Rx buffer error! ",
- dev->name);
+ if (skb == NULL)
break;
- }
+
/* Rubicon now supports 40 bits of addressing space. */
np->rx_ring[i].fraginfo =
cpu_to_le64 ( pci_map_single (
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 069a155..f97c60f 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -743,8 +743,6 @@ fec_enet_rx(struct net_device *ndev, int budget)
skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN);
if (unlikely(!skb)) {
- printk("%s: Memory squeeze, dropping packet.\n",
- ndev->name);
ndev->stats.rx_dropped++;
} else {
skb_reserve(skb, NET_IP_ALIGN);
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 46df288..edc1200 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -177,8 +177,6 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
received++;
netif_receive_skb(skb);
} else {
- dev_warn(fep->dev,
- "Memory squeeze, dropping packet.\n");
fep->stats.rx_dropped++;
skbn = skb;
}
@@ -309,8 +307,6 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
received++;
netif_rx(skb);
} else {
- dev_warn(fep->dev,
- "Memory squeeze, dropping packet.\n");
fep->stats.rx_dropped++;
skbn = skb;
}
@@ -505,11 +501,9 @@ void fs_init_bds(struct net_device *dev)
*/
for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
- if (skb == NULL) {
- dev_warn(fep->dev,
- "Memory squeeze, unable to allocate skb\n");
+ if (skb == NULL)
break;
- }
+
skb_align(skb, ENET_RX_ALIGN);
fep->rx_skbuff[i] = skb;
CBDW_BUFADDR(bdp,
@@ -593,13 +587,8 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
/* Alloc new skb */
new_skb = netdev_alloc_skb(dev, skb->len + 4);
- if (!new_skb) {
- if (net_ratelimit()) {
- dev_warn(fep->dev,
- "Memory squeeze, dropping tx packet.\n");
- }
+ if (!new_skb)
return NULL;
- }
/* Make sure new skb is properly aligned */
skb_align(new_skb, 4);
diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
index 2418faf..8412570 100644
--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
+++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
@@ -1003,8 +1003,6 @@ static void fjn_rx(struct net_device *dev)
}
skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n",
- pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
dev->stats.rx_dropped++;
break;
diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c
index 1c54e22..e388161 100644
--- a/drivers/net/ethernet/i825xx/82596.c
+++ b/drivers/net/ethernet/i825xx/82596.c
@@ -798,16 +798,14 @@ static inline int i596_rx(struct net_device *dev)
#ifdef __mc68000__
cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
#endif
- }
- else
+ } else {
skb = netdev_alloc_skb(dev, pkt_len + 2);
+ }
memory_squeeze:
if (skb == NULL) {
/* XXX tulip.c can defer packets here!! */
- printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
dev->stats.rx_dropped++;
- }
- else {
+ } else {
if (!rx_in_place) {
/* 16 byte align the data fields */
skb_reserve(skb, 2);
diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c
index f045ea4..d653bac 100644
--- a/drivers/net/ethernet/i825xx/lib82596.c
+++ b/drivers/net/ethernet/i825xx/lib82596.c
@@ -715,14 +715,12 @@ static inline int i596_rx(struct net_device *dev)
rbd->v_data = newskb->data;
rbd->b_data = SWAP32(dma_addr);
DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
- } else
+ } else {
skb = netdev_alloc_skb_ip_align(dev, pkt_len);
+ }
memory_squeeze:
if (skb == NULL) {
/* XXX tulip.c can defer packets here!! */
- printk(KERN_ERR
- "%s: i596_rx Memory squeeze, dropping packet.\n",
- dev->name);
dev->stats.rx_dropped++;
} else {
if (!rx_in_place) {
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index 328f47c..0296334 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -402,7 +402,6 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
skb_arr_rq1[index] = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[index]) {
- netdev_info(dev, "Unable to allocate enough skb in the array\n");
pr->rq1_skba.os_skbs = fill_wqes - i;
break;
}
@@ -432,10 +431,8 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
for (i = 0; i < nr_rq1a; i++) {
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
- if (!skb_arr_rq1[i]) {
- netdev_info(dev, "Not enough memory to allocate skb array\n");
+ if (!skb_arr_rq1[i])
break;
- }
}
/* Ring doorbell */
ehea_update_rq1a(pr->qp, i - 1);
@@ -695,10 +692,8 @@ static int ehea_proc_rwqes(struct net_device *dev,
skb = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
- if (!skb) {
- netdev_err(dev, "Not enough memory to allocate skb\n");
+ if (!skb)
break;
- }
}
skb_copy_to_linear_data(skb, ((char *)cqe) + 64,
cqe->num_bytes_transfered - 4);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
index 3488c6d..2448f0d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
@@ -58,10 +58,9 @@ static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv)
/* build the pkt before xmit */
skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN);
- if (!skb) {
- en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n");
+ if (!skb)
return -ENOMEM;
- }
+
skb_reserve(skb, NET_IP_ALIGN);
ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr));
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index 46795e4..1bd419d 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -424,7 +424,6 @@ static void sonic_rx(struct net_device *dev)
/* Malloc up new buffer. */
new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2);
if (new_skb == NULL) {
- printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
lp->stats.rx_dropped++;
break;
}
diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c
index 63e7af4..cb9e638 100644
--- a/drivers/net/ethernet/netx-eth.c
+++ b/drivers/net/ethernet/netx-eth.c
@@ -152,8 +152,6 @@ static void netx_eth_receive(struct net_device *ndev)
skb = netdev_alloc_skb(ndev, len);
if (unlikely(skb == NULL)) {
- printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
- ndev->name);
ndev->stats.rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
index 162da89..539d202 100644
--- a/drivers/net/ethernet/nuvoton/w90p910_ether.c
+++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c
@@ -737,7 +737,6 @@ static void netdev_rx(struct net_device *dev)
data = ether->rdesc->recv_buf[ether->cur_rx];
skb = netdev_alloc_skb(dev, length + 2);
if (!skb) {
- dev_err(&pdev->dev, "get skb buffer error\n");
ether->stats.rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 0b8de12..b62262c 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5025,7 +5025,6 @@ static int nv_loopback_test(struct net_device *dev)
pkt_len = ETH_DATA_LEN;
tx_skb = netdev_alloc_skb(dev, pkt_len);
if (!tx_skb) {
- netdev_err(dev, "netdev_alloc_skb() failed during loopback test\n");
ret = 0;
goto out;
}
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 8fd38cb6..91a8fcd 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -312,7 +312,6 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev,
lrg_buf_cb->skb = netdev_alloc_skb(qdev->ndev,
qdev->lrg_buffer_len);
if (unlikely(!lrg_buf_cb->skb)) {
- netdev_err(qdev->ndev, "failed netdev_alloc_skb()\n");
qdev->lrg_buf_skb_check++;
} else {
/*
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index b13ab54..1dd778a 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -1211,8 +1211,6 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
netdev_alloc_skb(qdev->ndev,
SMALL_BUFFER_SIZE);
if (sbq_desc->p.skb == NULL) {
- netif_err(qdev, probe, qdev->ndev,
- "Couldn't get an skb.\n");
rx_ring->sbq_clean_idx = clean_idx;
return;
}
@@ -1519,8 +1517,6 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
skb = netdev_alloc_skb(ndev, length);
if (!skb) {
- netif_err(qdev, drv, qdev->ndev,
- "Couldn't get an skb, need to unwind!.\n");
rx_ring->rx_dropped++;
put_page(lbq_desc->p.pg_chunk.page);
return;
@@ -1605,8 +1601,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
/* Allocate new_skb and copy */
new_skb = netdev_alloc_skb(qdev->ndev, length + NET_IP_ALIGN);
if (new_skb == NULL) {
- netif_err(qdev, probe, qdev->ndev,
- "No skb available, drop the packet.\n");
rx_ring->rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index d5622ab..e9dc849 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -350,7 +350,6 @@ static int r6040_alloc_rxbufs(struct net_device *dev)
do {
skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
if (!skb) {
- netdev_err(dev, "failed to alloc skb for rx\n");
rc = -ENOMEM;
goto err_exit;
}
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 1276ac7..3ccedeb 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -2041,8 +2041,6 @@ keep_pkt:
netif_receive_skb (skb);
} else {
- if (net_ratelimit())
- netdev_warn(dev, "Memory squeeze, dropping packet\n");
dev->stats.rx_dropped++;
}
received++;
diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c
index 9f2d416..d77d60e 100644
--- a/drivers/net/ethernet/realtek/atp.c
+++ b/drivers/net/ethernet/realtek/atp.c
@@ -782,8 +782,6 @@ static void net_rx(struct net_device *dev)
skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
- dev->name);
dev->stats.rx_dropped++;
goto done;
}
diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c
index 3aca578..bdac936 100644
--- a/drivers/net/ethernet/seeq/ether3.c
+++ b/drivers/net/ethernet/seeq/ether3.c
@@ -651,8 +651,11 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
received ++;
- } else
- goto dropping;
+ } else {
+ ether3_outw(next_ptr >> 8, REG_RECVEND);
+ dev->stats.rx_dropped++;
+ goto done;
+ }
} else {
struct net_device_stats *stats = &dev->stats;
ether3_outw(next_ptr >> 8, REG_RECVEND);
@@ -679,21 +682,6 @@ done:
}
return maxcnt;
-
-dropping:{
- static unsigned long last_warned;
-
- ether3_outw(next_ptr >> 8, REG_RECVEND);
- /*
- * Don't print this message too many times...
- */
- if (time_after(jiffies, last_warned + 10 * HZ)) {
- last_warned = jiffies;
- printk("%s: memory squeeze, dropping packet.\n", dev->name);
- }
- dev->stats.rx_dropped++;
- goto done;
- }
}
/*
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
index 0fde9ca..0ad5694 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -381,8 +381,6 @@ memory_squeeze:
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
} else {
- printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
}
} else {
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index efca14e..e458296 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -1841,15 +1841,12 @@ refill_rx_ring:
entry = sis_priv->dirty_rx % NUM_RX_DESC;
if (sis_priv->rx_skbuff[entry] == NULL) {
- if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) {
+ skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE);
+ if (skb == NULL) {
/* not enough memory for skbuff, this makes a
* "hole" on the buffer ring, it is not clear
* how the hardware will react to this kind
* of degenerated buffer */
- if (netif_msg_rx_err(sis_priv))
- printk(KERN_INFO "%s: Memory squeeze, "
- "deferring packet.\n",
- net_dev->name);
net_dev->stats.rx_dropped++;
break;
}
diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c
index 50823da..e85c2e7 100644
--- a/drivers/net/ethernet/smsc/smc9194.c
+++ b/drivers/net/ethernet/smsc/smc9194.c
@@ -1223,9 +1223,7 @@ static void smc_rcv(struct net_device *dev)
dev->stats.multicast++;
skb = netdev_alloc_skb(dev, packet_length + 5);
-
if ( skb == NULL ) {
- printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n");
dev->stats.rx_dropped++;
goto done;
}
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 591650a..dfbf978 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -465,8 +465,6 @@ static inline void smc_rcv(struct net_device *dev)
*/
skb = netdev_alloc_skb(dev, packet_len);
if (unlikely(skb == NULL)) {
- printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
- dev->name);
SMC_WAIT_MMU_BUSY(lp);
SMC_SET_MMU_CMD(lp, MC_RELEASE);
dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index d457fa2..ffa5c4a 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -848,10 +848,8 @@ static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index)
BUG_ON(pd->rx_buffers[index].skb);
BUG_ON(pd->rx_buffers[index].mapping);
- if (unlikely(!skb)) {
- smsc_warn(RX_ERR, "Failed to allocate new skb!");
+ if (unlikely(!skb))
return -ENOMEM;
- }
mapping = pci_map_single(pd->pdev, skb_tail_pointer(skb),
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
index 49bf3e2..8182591b 100644
--- a/drivers/net/ethernet/sun/sunqe.c
+++ b/drivers/net/ethernet/sun/sunqe.c
@@ -414,7 +414,7 @@ static void qe_rx(struct sunqe *qep)
struct qe_rxd *this;
struct sunqe_buffers *qbufs = qep->buffers;
__u32 qbufs_dvma = qep->buffers_dvma;
- int elem = qep->rx_new, drops = 0;
+ int elem = qep->rx_new;
u32 flags;
this = &rxbase[elem];
@@ -436,7 +436,6 @@ static void qe_rx(struct sunqe *qep)
} else {
skb = netdev_alloc_skb(dev, len + 2);
if (skb == NULL) {
- drops++;
dev->stats.rx_dropped++;
} else {
skb_reserve(skb, 2);
@@ -456,8 +455,6 @@ static void qe_rx(struct sunqe *qep)
this = &rxbase[elem];
}
qep->rx_new = elem;
- if (drops)
- printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", qep->dev->name);
}
static void qe_tx_reclaim(struct sunqe *qep);
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index e15cc71..e8824ce 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -1102,10 +1102,9 @@ static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f)
dno = bdx_rxdb_available(db) - 1;
while (dno > 0) {
skb = netdev_alloc_skb(priv->ndev, f->m.pktsz + NET_IP_ALIGN);
- if (!skb) {
- pr_err("NO MEM: netdev_alloc_skb failed\n");
+ if (!skb)
break;
- }
+
skb_reserve(skb, NET_IP_ALIGN);
idx = bdx_rxdb_alloc_elem(db);
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 2272538..bdda36f 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -1911,10 +1911,8 @@ static void tlan_reset_lists(struct net_device *dev)
list->frame_size = TLAN_MAX_FRAME_SIZE;
list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
- if (!skb) {
- netdev_err(dev, "Out of memory for received data\n");
+ if (!skb)
break;
- }
list->buffer[0].address = pci_map_single(priv->pci_dev,
skb->data,
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 9fc2ada..5ac43e4 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -273,11 +273,9 @@ static int temac_dma_bd_init(struct net_device *ndev)
skb = netdev_alloc_skb_ip_align(ndev,
XTE_MAX_JUMBO_FRAME_SIZE);
-
- if (skb == 0) {
- dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+ if (!skb)
goto out;
- }
+
lp->rx_skb[i] = skb;
/* returns physical address of skb->data */
lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
@@ -789,9 +787,7 @@ static void ll_temac_recv(struct net_device *ndev)
new_skb = netdev_alloc_skb_ip_align(ndev,
XTE_MAX_JUMBO_FRAME_SIZE);
-
- if (new_skb == 0) {
- dev_err(&ndev->dev, "no memory for new sk_buff\n");
+ if (!new_skb) {
spin_unlock_irqrestore(&lp->rx_lock, flags);
return;
}
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 278c9db..397d4a6 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -235,10 +235,8 @@ static int axienet_dma_bd_init(struct net_device *ndev)
((i + 1) % RX_BD_NUM);
skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size);
- if (!skb) {
- dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+ if (!skb)
goto out;
- }
lp->rx_bd_v[i].sw_id_offset = (u32) skb;
lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
@@ -777,10 +775,9 @@ static void axienet_recv(struct net_device *ndev)
packets++;
new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size);
- if (!new_skb) {
- dev_err(&ndev->dev, "no memory for new sk_buff\n");
+ if (!new_skb)
return;
- }
+
cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
lp->max_frm_size,
DMA_FROM_DEVICE);
diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c
index 98e09d0..76210ab 100644
--- a/drivers/net/ethernet/xircom/xirc2ps_cs.c
+++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c
@@ -1041,7 +1041,6 @@ xirc2ps_interrupt(int irq, void *dev_id)
/* 1 extra so we can use insw */
skb = netdev_alloc_skb(dev, pktlen + 3);
if (!skb) {
- pr_notice("low memory, packet dropped (size=%u)\n", pktlen);
dev->stats.rx_dropped++;
} else { /* okay get the packet */
skb_reserve(skb, 2);
--
1.8.1.2.459.gbcd45b4.dirty
^ permalink raw reply related
* [PATCH V1] ks8851_mll: basic ethernet statistics
From: Choi, David @ 2013-03-08 22:58 UTC (permalink / raw)
To: netdev@vger.kernel.org; +Cc: Li, Charles
>From f8a50c5e9d01aa633033bd622bd83706d86f85cc Mon Sep 17 00:00:00 2001
From: "David J. Choi" <david.choi@micrel.com>
Date: Fri, 8 Mar 2013 13:02:23 -0800
Subject: [PATCH V1] ks8851_mll: basic ethernet statistics
Implement to collect ethernet statistical information on ks8851_mll device.
Signed-off-by: David J. Choi <david.choi@micrel.com>
---
drivers/net/ethernet/micrel/ks8851_mll.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index a343066..db108e7 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -792,20 +792,35 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
frame_hdr = ks->frame_head_info;
while (ks->frame_cnt--) {
+ if (unlikely(!(frame_hdr->sts & RXFSHR_RXFV) ||
+ frame_hdr->len >= RX_BUF_SIZE ||
+ frame_hdr->len <= 0)) {
+
+ /* discard an invalid packet */
+ ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+ netdev->stats.rx_dropped++;
+ if (!(frame_hdr->sts & RXFSHR_RXFV))
+ netdev->stats.rx_frame_errors++;
+ else
+ netdev->stats.rx_length_errors++;
+ frame_hdr++;
+ continue;
+ }
+
skb = netdev_alloc_skb(netdev, frame_hdr->len + 16);
- if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
- (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
+ if (likely(skb)) {
skb_reserve(skb, 2);
/* read data block including CRC 4 bytes */
ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
- skb_put(skb, frame_hdr->len);
+ skb_put(skb, frame_hdr->len - 4);
skb->protocol = eth_type_trans(skb, netdev);
netif_rx(skb);
+ /* exclude CRC size */
+ netdev->stats.rx_bytes += frame_hdr->len - 4;
+ netdev->stats.rx_packets++;
} else {
- pr_err("%s: err:skb alloc\n", __func__);
ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
- if (skb)
- dev_kfree_skb_irq(skb);
+ netdev->stats.rx_dropped++;
}
frame_hdr++;
}
@@ -877,6 +892,8 @@ static irqreturn_t ks_irq(int irq, void *pw)
ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
}
+ if (unlikely(status & IRQ_RXOI))
+ ks->netdev->stats.rx_over_errors++;
/* this should be the last in IRQ handler*/
ks_restore_cmd_reg(ks);
return IRQ_HANDLED;
@@ -1015,6 +1032,9 @@ static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
ks_write_qmu(ks, skb->data, skb->len);
+ /* add tx statistics */
+ netdev->stats.tx_bytes += skb->len;
+ netdev->stats.tx_packets++;
dev_kfree_skb(skb);
} else
retv = NETDEV_TX_BUSY;
--
1.7.11.7
^ permalink raw reply related
* Re: RFC: [PATCH 1/3] usb: cdc_ncm: patch for VMware
From: Dan Williams @ 2013-03-08 22:28 UTC (permalink / raw)
To: Loic Domaigne; +Cc: netdev, linux-usb
In-Reply-To: <20130308210319.GA4794@feynman.loic.net>
On Fri, 2013-03-08 at 22:03 +0100, Loic Domaigne wrote:
> This patch limits the Rx URB size to 16kB if the driver is compiled for a
> VMware environment. As of workstation 9, there are some major performance
> problems if the Rx URB size exceeds that limit.
>
> This patch applies to longterm kernel version 3.4.35.
>
> Signed-Off-By: Loic Domaigne <loic.domaigne@jambit.com>
>
> --- linux-3.4.35/drivers/net/usb/cdc_ncm.c.orig 2013-03-05 09:36:02.858740489 +0100
> +++ linux-3.4.35/drivers/net/usb/cdc_ncm.c 2013-03-05 10:20:18.092588668 +0100
> @@ -80,6 +80,23 @@
> #define CDC_NCM_TIMER_PENDING_CNT 2
> #define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC)
>
> +/* maximum Rx URB size */
> +/*
> + * in the original Linux driver, the rx urb size can be up to
> + * CDC_NCM_NTB_MAX_SIZE_RX.
> + *
> + * Under VMware (as of wks9), URB size greater than 16kB is a problem,
> + * so simply adjust this define when the driver is compiled for a VMware
> + * environment.
> + *
> + */
> +#ifdef VMWARE_BUG
> +#warning "Compiling for VMware"
> +#define CDC_NCM_MAX_RX_URB_SIZE 16384
> +#else
> +#define CDC_NCM_MAX_RX_URB_SIZE CDC_NCM_NTB_MAX_SIZE_RX
> +#endif
I can't see how that is going to get past any sort of review. Either
there's some other way of detecting that the CPU is the VMWare emulated
one or you're stuck with the bug until VMWare fixes it.
Dan
> +
> /* The following macro defines the minimum header space */
> #define CDC_NCM_MIN_HDR_SIZE \
> (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
> @@ -589,6 +606,9 @@ advance:
> ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> dev->status = ctx->status_ep;
> dev->rx_urb_size = ctx->rx_max;
> + if (dev->rx_urb_size > CDC_NCM_MAX_RX_URB_SIZE)
> + dev->rx_urb_size = CDC_NCM_MAX_RX_URB_SIZE;
> + pr_debug("dev->rx_urb_size = %zu", dev->rx_urb_size);
>
> /*
> * We should get an event when network connection is "connected" or
> --
> 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
^ permalink raw reply
* [patch] ixgbe: in shutdown, do netif_running() under rtnl_lock
From: akepner @ 2013-03-08 22:05 UTC (permalink / raw)
To: netdev; +Cc: e1000-devel
During shutdown it's possible for __dev_close() (which holds
rtnl_lock) to clear the __LINK_STATE_START bit, and for ixgbe
to then read that bit (without holding rtnl_lock), and then
not fail to free irqs, etc. The result is a crash like this:
------------[ cut here ]------------
kernel BUG at drivers/pci/msi.c:313!
invalid opcode: 0000 [#1] SMP
last sysfs file: /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map
CPU 1
Pid: 5910, comm: reboot Tainted: P ---------------- 2.6.32 #1 empty
RIP: 0010:[<ffffffff81305c2b>] [<ffffffff81305c2b>] free_msi_irqs+0x11b/0x130
RSP: 0018:ffff880185c9bc88 EFLAGS: 00010282
RAX: ffff880219f58bc0 RBX: ffff88021ac53b00 RCX: 0000000000000000
RDX: 0000000000000001 RSI: 0000000000000246 RDI: 000000000000004a
RBP: ffff880185c9bcc8 R08: 0000000000000002 R09: 0000000000000106
R10: 0000000000000000 R11: 0000000000000006 R12: ffff88021e524778
R13: 0000000000000001 R14: ffff88021e524000 R15: 0000000000000000
FS: 00007f90821b7700(0000) GS:ffff880028220000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f90818bd010 CR3: 0000000132c64000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process reboot (pid: 5910, threadinfo ffff880185c9a000, task ffff88021bf04a80)
Stack:
ffff880185c9bc98 000000018130529d ffff880185c9bcc8 ffff88021e524000
<0> 0000000000000004 ffff88021948c700 0000000000000000 ffff880185c9bda7
<0> ffff880185c9bce8 ffffffff81305cbd ffff880185c9bce8 ffff88021948c700
Call Trace:
[<ffffffff81305cbd>] pci_disable_msix+0x3d/0x50
[<ffffffffa00501d5>] ixgbe_reset_interrupt_capability+0x65/0x90 [ixgbe]
[<ffffffffa00512f6>] ixgbe_clear_interrupt_scheme+0xb6/0xd0 [ixgbe]
[<ffffffffa005330b>] __ixgbe_shutdown+0x5b/0x200 [ixgbe]
[<ffffffffa00534ca>] ixgbe_shutdown+0x1a/0x60 [ixgbe]
[<ffffffff812f6c7c>] pci_device_shutdown+0x2c/0x50
[<ffffffff813727fb>] device_shutdown+0x4b/0x160
[<ffffffff8107d98c>] kernel_restart_prepare+0x2c/0x40
ehci timer_action, mod_timer io_watchdog
[<ffffffff8107d9e6>] kernel_restart+0x16/0x60
[<ffffffff8107dbfd>] sys_reboot+0x1ad/0x200
[<ffffffff811676cf>] ? __d_free+0x3f/0x60
[<ffffffff81167748>] ? d_free+0x58/0x60
[<ffffffff8116f7c0>] ? mntput_no_expire+0x30/0x100
[<ffffffff81152b11>] ? __fput+0x191/0x200
[<ffffffff816565fe>] ? do_page_fault+0x3e/0xa0
[<ffffffff8100b132>] system_call_fastpath+0x16/0x1b
Code: 4c 89 ef e8 98 8c e3 ff 4d 39 f4 48 8b 43 10 75 cf 48 83 c4 18 5b 41 5c
41 5d 41 5e 41 5f c9 c3 49 8b 7d 20 e8 07 5a d3 ff eb c9 <0f> 0b 0f 1f 00 eb fb
66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
ehci timer_action, mod_timer io_watchdog
RIP [<ffffffff81305c2b>] free_msi_irqs+0x11b/0x130
RSP <ffff880185c9bc88>
---[ end trace 27de882a0fe75593 ]---
(This was seen on a pretty old kernel/driver, but looks like
the same bug is still possible.)
Signed-off-by: <akepner@riverbed.com>
---
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index db5611a..bbf0f7b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5077,14 +5077,14 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
netif_device_detach(netdev);
+ rtnl_lock();
if (netif_running(netdev)) {
- rtnl_lock();
ixgbe_down(adapter);
ixgbe_free_irq(adapter);
ixgbe_free_all_tx_resources(adapter);
ixgbe_free_all_rx_resources(adapter);
- rtnl_unlock();
}
+ rtnl_unlock();
ixgbe_clear_interrupt_scheme(adapter);
^ permalink raw reply related
* Re: [RFC PATCH v2 net-next 0/3] Allow bridge to function in non-promisc mode
From: Stephen Hemminger @ 2013-03-08 21:43 UTC (permalink / raw)
To: vyasevic; +Cc: netdev, bridge
In-Reply-To: <513A56E9.2090708@redhat.com>
On Fri, 08 Mar 2013 16:23:53 -0500
Vlad Yasevich <vyasevic@redhat.com> wrote:
> On 03/08/2013 10:17 AM, Vlad Yasevich wrote:
> > On 03/08/2013 12:43 AM, Stephen Hemminger wrote:
> >> On Thu, 7 Mar 2013 16:28:45 -0500
> >> Vlad Yasevich <vyasevic@redhat.com> wrote:
> >>
> >>> The series adds an ability to configure the bridge into a
> >>> non-primiscuous
> >>> mode. Instead, it provides the ability to identitfy some set of bridge
> >>> ports as uplinks and allows for MAC addresses to be programmed onto
> >>> those ports. In case the port hardware does not support mac filter,
> >>> that port will be placed in promiscuous mode.
> >>>
> >>> Default bridge operation continues to remain as "promiscuous". The new
> >>> functionality has to be enabled via sysfs (similar to other bridge
> >>> extensions).
> >>>
> >>> The uplink mode is implemented as a flag on a bridge port. The api to
> >>> change that flag follows the existing api to enable/disable other
> >>> existing
> >>> flags.
> >>>
> >>> All comments are welcome.
> >>>
> >>
> >> Can we make this a one step process and less visible to the user.
> >> If user defines an uplink device, and the uplink device is capable of
> >> filtering
> >> (and what ever other pre-conditions people can think of), then the
> >> bridge will
> >> transparently switch to uplink/non-promisc mode. This can also be
> >> used to trigger
> >> edge only mode in RSTP in the future.
> >>
> >> Less knobs.
> >>
> >
> > Ok. Let me see what I can do.
>
> So I started working through this and realized that this complicates the
> code significantly.
>
> * I have to re-introduce the uplink-list since now I need to track
> "filter capable" uplinks in addition to non-capable ones.
> * The really nice and simple sysfs interface to set a flag turns into
> something that duplicates code.
> * The bridge port removal can effect the promiscuity setting of the
> bridge if the last uplink is removed.
> * We lose the ability to run a promisc edge bridge with uplinks.
>
> I am really starting wonder if this is any better? The changes
> are much bigger and more complex while the functional flexibility is
> reduced. Is it really worth removing a configuration knob?
>
> I've attached an in-progress patch to demonstrate the above.
>
> -vlad
>
> -vlad
> >
> > Thanks
> > -vlad
> >
>
A two step process is fine (uplink and promisc as seperate step),
as long as invalid combinations are prevented. More options may lead to
more combinations that are invalid.
^ permalink raw reply
* Re: [RFC PATCH v2 net-next 0/3] Allow bridge to function in non-promisc mode
From: Vlad Yasevich @ 2013-03-08 21:23 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, bridge
In-Reply-To: <513A0109.4040607@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2133 bytes --]
On 03/08/2013 10:17 AM, Vlad Yasevich wrote:
> On 03/08/2013 12:43 AM, Stephen Hemminger wrote:
>> On Thu, 7 Mar 2013 16:28:45 -0500
>> Vlad Yasevich <vyasevic@redhat.com> wrote:
>>
>>> The series adds an ability to configure the bridge into a
>>> non-primiscuous
>>> mode. Instead, it provides the ability to identitfy some set of bridge
>>> ports as uplinks and allows for MAC addresses to be programmed onto
>>> those ports. In case the port hardware does not support mac filter,
>>> that port will be placed in promiscuous mode.
>>>
>>> Default bridge operation continues to remain as "promiscuous". The new
>>> functionality has to be enabled via sysfs (similar to other bridge
>>> extensions).
>>>
>>> The uplink mode is implemented as a flag on a bridge port. The api to
>>> change that flag follows the existing api to enable/disable other
>>> existing
>>> flags.
>>>
>>> All comments are welcome.
>>>
>>
>> Can we make this a one step process and less visible to the user.
>> If user defines an uplink device, and the uplink device is capable of
>> filtering
>> (and what ever other pre-conditions people can think of), then the
>> bridge will
>> transparently switch to uplink/non-promisc mode. This can also be
>> used to trigger
>> edge only mode in RSTP in the future.
>>
>> Less knobs.
>>
>
> Ok. Let me see what I can do.
So I started working through this and realized that this complicates the
code significantly.
* I have to re-introduce the uplink-list since now I need to track
"filter capable" uplinks in addition to non-capable ones.
* The really nice and simple sysfs interface to set a flag turns into
something that duplicates code.
* The bridge port removal can effect the promiscuity setting of the
bridge if the last uplink is removed.
* We lose the ability to run a promisc edge bridge with uplinks.
I am really starting wonder if this is any better? The changes
are much bigger and more complex while the functional flexibility is
reduced. Is it really worth removing a configuration knob?
I've attached an in-progress patch to demonstrate the above.
-vlad
-vlad
>
> Thanks
> -vlad
>
[-- Attachment #2: test.patch --]
[-- Type: text/x-patch, Size: 8158 bytes --]
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index c4edfe1..b9444e9 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -220,6 +220,7 @@ enum {
IFLA_BRPORT_GUARD, /* bpdu guard */
IFLA_BRPORT_PROTECT, /* root port protection */
IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
+ IFLA_BRPORT_UPLINK, /* uplink port */
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index d5f1d3f..df0afb2 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -356,6 +356,7 @@ void br_dev_setup(struct net_device *dev)
br->dev = dev;
spin_lock_init(&br->lock);
INIT_LIST_HEAD(&br->port_list);
+ INIT_LIST_HEAD(&br->uplink_list);
spin_lock_init(&br->hash_lock);
br->bridge_id.prio[0] = 0x80;
@@ -371,6 +372,7 @@ void br_dev_setup(struct net_device *dev)
br->bridge_hello_time = br->hello_time = 2 * HZ;
br->bridge_forward_delay = br->forward_delay = 15 * HZ;
br->ageing_time = 300 * HZ;
+ br->promisc_enabled = 1;
br_netfilter_rtable_init(br);
br_stp_timer_init(br);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ef1b914..8a3a085 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -60,6 +60,29 @@ static int port_cost(struct net_device *dev)
return 100; /* assume old 10Mbps */
}
+static void br_set_promisc(struct net_bridge *br, int val)
+{
+ struct net_bridge_port *p;
+
+ if (val) {
+ br->promisc_enabled = 1;
+ /* For each port on the bridge, turn on promisc mode and
+ * turn off ALLMULTI to handle multicast traffic.
+ */
+ list_for_each_entry(p, &br->port_list, list) {
+ dev_set_promiscuity(p->dev, 1);
+ dev_set_allmulti(p->dev, -1);
+ }
+
+ } else {
+ br->promisc_enabled = 0;
+ /* For each port on the bridge, turn off promisc mode */
+ list_for_each_entry(p, &br->port_list, list) {
+ dev_set_allmulti(p->dev, 1);
+ dev_set_promiscuity(p->dev, -1);
+ }
+ }
+}
/* Check for port carrier transistions. */
void br_port_carrier_check(struct net_bridge_port *p)
@@ -132,7 +155,14 @@ static void del_nbp(struct net_bridge_port *p)
sysfs_remove_link(br->ifobj, p->dev->name);
- dev_set_promiscuity(dev, -1);
+ if (br->promisc_enabled)
+ dev_set_promiscuity(dev, -1);
+ else
+ dev_set_allmulti(dev, -1);
+
+ list_del_rcu(&p->uplink_list);
+ if (list_empty(&br->uplink_list))
+ br_set_promisc(br, 1);
spin_lock_bh(&br->lock);
br_stp_disable_port(p);
@@ -222,6 +252,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
p->priority = 0x8000 >> BR_PORT_BITS;
p->port_no = index;
p->flags = 0;
+ INIT_LIST_HEAD(&p->uplink_list);
br_init_port(p);
p->state = BR_STATE_DISABLED;
br_stp_port_timer_init(p);
@@ -350,9 +381,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
call_netdevice_notifiers(NETDEV_JOIN, dev);
- err = dev_set_promiscuity(dev, 1);
- if (err)
- goto put_back;
+ if (br->promisc_enabled) {
+ err = dev_set_promiscuity(dev, 1);
+ if (err)
+ goto put_back;
+ } else {
+ err = dev_set_allmulti(dev, 1);
+ if (err)
+ goto put_back;
+ }
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
SYSFS_BRIDGE_PORT_ATTR);
@@ -414,7 +451,10 @@ err2:
kobject_put(&p->kobj);
p = NULL; /* kobject_put frees */
err1:
- dev_set_promiscuity(dev, -1);
+ if (br->promisc_enabled)
+ dev_set_promiscuity(dev, -1);
+ else
+ dev_set_allmulti(dev, -1);
put_back:
dev_put(dev);
kfree(p);
@@ -449,6 +489,30 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
return 0;
}
+void br_set_uplink(struct net_bridge_port *p)
+{
+ if (p->flags & BR_UPLINK) {
+ if (p->dev->priv_flags & IFF_UNICAST_FLT) {
+ /* Turn off promisc mode if this is the first
+ * filter capable uplink
+ */
+ if (list_empty(&p->br->uplink_list))
+ br_set_promisc(p->br, 0);
+
+ list_add_rcu(&p->uplink_list, &p->br->uplink_list);
+ }
+ } else {
+ if (p->dev->priv_flags & IFF_UNICAST_FLT) {
+ list_del_rcu(&p->uplink_list);
+ /* Turn on promisc mode if this was the last
+ * filter capable uplink
+ */
+ if (list_empty(&p->br->uplink_list))
+ br_set_promisc(p->br, 1);
+ }
+ }
+}
+
void __net_exit br_net_exit(struct net *net)
{
struct net_device *dev;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 27aa3ee..e53eb0b 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -283,6 +283,7 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
[IFLA_BRPORT_MODE] = { .type = NLA_U8 },
[IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
[IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
+ [IFLA_BRPORT_UPLINK] = { .type = NLA_U8 },
};
/* Change the state of the port and notify spanning tree */
@@ -325,10 +326,12 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
{
int err;
+ unsigned long flags = p->flags;
br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
+ br_set_port_flag(p, tb, IFLA_BRPORT_UPLINK, BR_UPLINK);
if (tb[IFLA_BRPORT_COST]) {
err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
@@ -347,6 +350,11 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
if (err)
return err;
}
+
+ /* If the uplink flag has changed do additional processing */
+ if ((flags ^ p->flags) & BR_UPLINK)
+ br_set_uplink(p);
+
return 0;
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6d314c4..ab8cb1a9 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -130,6 +130,7 @@ struct net_bridge_port
struct net_bridge *br;
struct net_device *dev;
struct list_head list;
+ struct list_head uplink_list;
/* STP */
u8 priority;
@@ -156,6 +157,7 @@ struct net_bridge_port
#define BR_BPDU_GUARD 0x00000002
#define BR_ROOT_BLOCK 0x00000004
#define BR_MULTICAST_FAST_LEAVE 0x00000008
+#define BR_UPLINK 0x00000010
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
u32 multicast_startup_queries_sent;
@@ -277,6 +279,8 @@ struct net_bridge
struct timer_list topology_change_timer;
struct timer_list gc_timer;
struct kobject *ifobj;
+ struct list_head uplink_list;
+ u8 promisc_enabled;
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
u8 vlan_enabled;
struct net_port_vlans __rcu *vlan_info;
@@ -426,6 +430,7 @@ extern int br_del_if(struct net_bridge *br,
extern int br_min_mtu(const struct net_bridge *br);
extern netdev_features_t br_features_recompute(struct net_bridge *br,
netdev_features_t features);
+extern void br_set_uplink(struct net_bridge_port *port);
/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index a1ef1b6..454a0cf 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -159,6 +159,29 @@ BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE);
BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD);
BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK);
+static ssize_t show_uplink(struct net_bridge_port *p, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(p->flags & BR_UPLINK));
+}
+
+static int store_uplink(struct net_bridge_port *p, unsigned long v)
+{
+ unsigned long flags = p->flags;
+
+ if (v)
+ flags |= BR_UPLINK;
+ else
+ flags &= ~BR_UPLINK;
+
+ if (flags != p->flags) {
+ p->flags = flags;
+ br_set_uplink(p);
+ br_ifinfo_notify(RTM_NEWLINK, p);
+ }
+ return 0;
+}
+static BRPORT_ATTR(uplink, S_IRUGO | S_IWUSR, show_uplink, store_uplink);
+
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
{
@@ -195,6 +218,7 @@ static const struct brport_attribute *brport_attrs[] = {
&brport_attr_hairpin_mode,
&brport_attr_bpdu_guard,
&brport_attr_root_block,
+ &brport_attr_uplink,
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&brport_attr_multicast_router,
&brport_attr_multicast_fast_leave,
^ permalink raw reply related
* RFC: [PATCH 3/3] usb: cdc_ncm: MirrorLink booster for N60x,70x
From: Loic Domaigne @ 2013-03-08 21:03 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA; +Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA
This patch allows to boost the performance if used for MirrorLink(TM). It
is derived from a patch provided by Nokia-LC/Berlin. It optimizes the transfer
speed for the Nokia N60x,70x. which requires special settings (jumbo frame,
no batching)
This patch applies to longterm kernel version 3.4.35.
Signed-Off-By: Loic Domaigne <loic.domaigne-NEfzRHNIQpPQT0dZR+AlfA@public.gmane.org>
--- linux-3.4.35/drivers/net/usb/cdc_ncm.c.patch2 2013-03-05 10:34:56.639566116 +0100
+++ linux-3.4.35/drivers/net/usb/cdc_ncm.c 2013-03-05 10:54:33.941773425 +0100
@@ -38,6 +38,22 @@
* SUCH DAMAGE.
*/
+/* MirrorLink(TM) Booster patch
+ *
+ * Copyright (c) jambit GmbH
+ * Contact: Loic Domaigne <loic.domaigne-NEfzRHNIQpPQT0dZR+AlfA@public.gmane.org>
+ *
+ * Contribution:
+ * Part of this work is derived from a patch provided by Nokia-LC/Berlin
+ * (thanks Juan!), which was licensed under the terms of the GNU General
+ * Public License (GPL) Version 2
+ *
+ * Licensing:
+ * This patch is available to you under the terms of the GNU General Public
+ * License (GPL) Version 2
+ *
+ * Disclaimer: same as above.
+ */
#include <linux/version.h> /* LINUX_VERSION_CODE and KERNEL_VERSION macro */
#include <linux/module.h>
#include <linux/init.h>
@@ -52,7 +68,7 @@
#include <linux/usb/usbnet.h>
#include <linux/usb/cdc.h>
-#define DRIVER_VERSION "14-Mar-2012"
+#define DRIVER_VERSION "08-June-2012"
/* CDC NCM subclass 3.2.1 */
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
@@ -182,6 +198,38 @@ cdc_ncm_get_drvinfo(struct net_device *n
usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
}
+void mirrorlink_booster(struct cdc_ncm_ctx *ctx, struct usbnet *dev)
+{
+#define NOKIA 0x0421
+#define N6x7x 0x1419
+
+ if (ctx->udev->descriptor.idVendor == NOKIA) {
+
+ switch (ctx->udev->descriptor.idProduct) {
+ case N6x7x:
+ /* The Nokia N60x,70x (productId 0x1419) needs:
+ * - Jumbo Frame (MTU 8kB)
+ * - Disable TX batching to improve latency
+ */
+ if (dev != NULL)
+ /* called during NCM bind */
+ dev->hard_mtu = 8192+ETH_HLEN;
+ else {
+ /* called during NCM setup */
+ pr_info(KBUILD_MODNAME ": jambit MirrorLink booster for "
+ "Nokia 60x,70x family");
+ ctx->tx_max_datagrams = 1;
+ ctx->max_datagram_size = 8192+ETH_HLEN;
+ }
+ break;
+
+ default:
+ /* no other Nokia yet */
+ break;
+ }
+ }
+}
+
static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
{
u32 val;
@@ -414,9 +462,10 @@ size_err:
}
max_dgram_err:
+ mirrorlink_booster(ctx, NULL);
if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
^ permalink raw reply
* RFC: [PATCH 1/3] usb: cdc_ncm: patch for VMware
From: Loic Domaigne @ 2013-03-08 21:03 UTC (permalink / raw)
To: netdev; +Cc: linux-usb
This patch limits the Rx URB size to 16kB if the driver is compiled for a
VMware environment. As of workstation 9, there are some major performance
problems if the Rx URB size exceeds that limit.
This patch applies to longterm kernel version 3.4.35.
Signed-Off-By: Loic Domaigne <loic.domaigne@jambit.com>
--- linux-3.4.35/drivers/net/usb/cdc_ncm.c.orig 2013-03-05 09:36:02.858740489 +0100
+++ linux-3.4.35/drivers/net/usb/cdc_ncm.c 2013-03-05 10:20:18.092588668 +0100
@@ -80,6 +80,23 @@
#define CDC_NCM_TIMER_PENDING_CNT 2
#define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC)
+/* maximum Rx URB size */
+/*
+ * in the original Linux driver, the rx urb size can be up to
+ * CDC_NCM_NTB_MAX_SIZE_RX.
+ *
+ * Under VMware (as of wks9), URB size greater than 16kB is a problem,
+ * so simply adjust this define when the driver is compiled for a VMware
+ * environment.
+ *
+ */
+#ifdef VMWARE_BUG
+#warning "Compiling for VMware"
+#define CDC_NCM_MAX_RX_URB_SIZE 16384
+#else
+#define CDC_NCM_MAX_RX_URB_SIZE CDC_NCM_NTB_MAX_SIZE_RX
+#endif
+
/* The following macro defines the minimum header space */
#define CDC_NCM_MIN_HDR_SIZE \
(sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
@@ -589,6 +606,9 @@ advance:
ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
dev->status = ctx->status_ep;
dev->rx_urb_size = ctx->rx_max;
+ if (dev->rx_urb_size > CDC_NCM_MAX_RX_URB_SIZE)
+ dev->rx_urb_size = CDC_NCM_MAX_RX_URB_SIZE;
+ pr_debug("dev->rx_urb_size = %zu", dev->rx_urb_size);
/*
* We should get an event when network connection is "connected" or
^ permalink raw reply
* RFC: [PATCH 2/3] usb: cdc_ncm: patch for multi kernel versions
From: Loic Domaigne @ 2013-03-08 21:03 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA; +Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA
This patch allows to have a single source for many kernel versions. As the
NCM driver at jambit runs on a wide range of embedded linux (from
2.6.35 to 3.4.x) we devised this convenient patch.
This patch applies to longterm kernel version 3.4.35.
Signed-Off-By: Loic Domaigne <loic.domaigne-NEfzRHNIQpPQT0dZR+AlfA@public.gmane.org>
--- linux-3.4.35/drivers/net/usb/cdc_ncm.c.patch1 2013-03-05 10:22:14.361091251 +0100
+++ linux-3.4.35/drivers/net/usb/cdc_ncm.c 2013-03-05 10:33:33.169861281 +0100
@@ -38,6 +38,7 @@
* SUCH DAMAGE.
*/
+#include <linux/version.h> /* LINUX_VERSION_CODE and KERNEL_VERSION macro */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
@@ -48,7 +49,6 @@
#include <linux/crc32.h>
#include <linux/usb.h>
#include <linux/hrtimer.h>
-#include <linux/atomic.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/cdc.h>
@@ -1244,8 +1244,30 @@ static const struct ethtool_ops cdc_ncm_
.nway_reset = usbnet_nway_reset,
};
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
+
module_usb_driver(cdc_ncm_driver);
+#else
+
+static int __init cdc_ncm_init(void)
+{
+ pr_info(KBUILD_MODNAME ": " DRIVER_VERSION "\n");
+ pr_info(KBUILD_MODNAME ": MirrorLink booster by Jambit\n");
+ return usb_register(&cdc_ncm_driver);
+}
+
+module_init(cdc_ncm_init);
+
+static void __exit cdc_ncm_exit(void)
+{
+ usb_deregister(&cdc_ncm_driver);
+}
+
+module_exit(cdc_ncm_exit);
+
+#endif
+
MODULE_AUTHOR("Hans Petter Selasky");
MODULE_DESCRIPTION("USB CDC NCM host driver");
MODULE_LICENSE("Dual BSD/GPL");
--
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
* RFC: [PATCH 0/3] usb: cdc_ncm: patches for MirrorLink
From: Loic Domaigne @ 2013-03-08 21:03 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA; +Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA
The following serie of patches has been devised at jambit within the
MirrorLink(TM) context.
It contains:
- a patch for getting acceptable performance of the NCM driver under WMware
environment (tested so far up to Workstation 9.0)
- a patch to have a single driver source for many kernel versions. This becomes
handy if you need to support a wide range of kernel versions, as we do.
- a patch to boost transfer performance for the Nokia N60x, N70x.
patch3 depends on patch2, and patch 2 on patch1. The patches apply
to longterm kernel version 3.4.35.
We are aware that those patches may not be suited for the mainstream driver.
On the other hand, jambit likes to make those patches public for anyone
interested in those topics.
Thanks,
Loic
--
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: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Hannes Frederic Sowa @ 2013-03-08 20:53 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, yoshfuji
In-Reply-To: <1362756219.15793.240.camel@edumazet-glaptop>
On Fri, Mar 08, 2013 at 07:23:39AM -0800, Eric Dumazet wrote:
> On Fri, 2013-03-08 at 16:08 +0100, Hannes Frederic Sowa wrote:
> > On Fri, Mar 08, 2013 at 06:53:06AM -0800, Eric Dumazet wrote:
> > > No matter how you hash, a hacker can easily fill your defrag unit with
> > > not complete datagrams, so what's the point ?
> >
> > I want to harden reassembly logic against all fragments being put in
> > the same hash bucket because of malicious traffic and thus creating
> > long list traversals in the fragment queue hash table.
>
> Note that the long traversal was a real issue with TCP (thats why I
> introduced ipv6_addr_jhash()), as a single ehash slot could contains
> thousand of sockets.
>
> But with fragments, we should just limit the depth of any particular
> slot, and drop above a particular threshold.
>
> reassembly is a best effort mechanism, better make sure it doesnt use
> all our cpu cycles.
On my VM I counted 17500 iterations in one hash bucket and maxing out
one CPU until I got rcu stalls and NMIs. In comparison: If I use the
old hasing code I have max iterations of 370 and don't expirience any
rcu stalls or NMIs (seems to be around 17500/64+-epsilon).
I have not yet drawn my conclusion on this, yet, but I agree some list
length limiting code would be useful independent of the hash function.
^ permalink raw reply
* [PATCH net-next 5/5] qlcnic: Bump up the version to 5.1.36
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
In-Reply-To: <1362772433-12045-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index ba3c72f..c8b4895 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 1
-#define _QLCNIC_LINUX_SUBVERSION 35
-#define QLCNIC_LINUX_VERSIONID "5.1.35"
+#define _QLCNIC_LINUX_SUBVERSION 36
+#define QLCNIC_LINUX_VERSIONID "5.1.36"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 4/5] qlcnic: Fix ethtool statistics collection
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
In-Reply-To: <1362772433-12045-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
o Properly fill statistics data into buffer.
Update buffer pointer properly after filling statistics data into buffer.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index f687a63..f4f279d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1071,8 +1071,7 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
}
}
-static void
-qlcnic_fill_stats(u64 *data, void *stats, int type)
+static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
{
if (type == QLCNIC_MAC_STATS) {
struct qlcnic_mac_statistics *mac_stats =
@@ -1121,6 +1120,7 @@ qlcnic_fill_stats(u64 *data, void *stats, int type)
*data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
*data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
}
+ return data;
}
static void qlcnic_get_ethtool_stats(struct net_device *dev,
@@ -1148,7 +1148,7 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev,
/* Retrieve MAC statistics from firmware */
memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
qlcnic_get_mac_stats(adapter, &mac_stats);
- qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
+ data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
}
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
@@ -1160,7 +1160,7 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev,
if (ret)
return;
- qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
+ data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
if (ret)
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 3/5] qlcnic: Fix ethtool statistics for 82xx adapter
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
In-Reply-To: <1362772433-12045-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
o Fix miscalculation of statistics length
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index ba1502a..f687a63 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -149,7 +149,8 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
static inline int qlcnic_82xx_statistics(void)
{
- return QLCNIC_STATS_LEN + ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
+ return ARRAY_SIZE(qlcnic_device_gstrings_stats) +
+ ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
}
static inline int qlcnic_83xx_statistics(void)
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 2/5] qlcnic: Enable LED test support for 83xx adapter
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <1362772433-12045-1-git-send-email-shahed.shaikh@qlogic.com>
From: Himanshu Madhani <himanshu.madhani@qlogic.com>
o Add support for LED test on 83xx series adapters
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 45 ++++++++++++++++++++
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 1 +
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 3 +-
3 files changed, 48 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 41c02ba..c08fa20 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -1432,6 +1432,51 @@ mbx_err:
}
}
+int qlcnic_83xx_set_led(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ int err = -EIO, active = 1;
+
+ if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
+ netdev_warn(netdev,
+ "LED test is not supported in non-privileged mode\n");
+ return -EOPNOTSUPP;
+ }
+
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
+ return -EBUSY;
+
+ if (test_bit(__QLCNIC_RESETTING, &adapter->state))
+ break;
+
+ err = qlcnic_83xx_config_led(adapter, active, 0);
+ if (err)
+ netdev_err(netdev, "Failed to set LED blink state\n");
+ break;
+ case ETHTOOL_ID_INACTIVE:
+ active = 0;
+
+ if (test_bit(__QLCNIC_RESETTING, &adapter->state))
+ break;
+
+ err = qlcnic_83xx_config_led(adapter, active, 0);
+ if (err)
+ netdev_err(netdev, "Failed to reset LED blink state\n");
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (!active || err)
+ clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
+
+ return err;
+}
+
void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
int enable)
{
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 94e3ee0..648a73f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -449,5 +449,6 @@ int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *);
int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *);
int qlcnic_83xx_loopback_test(struct net_device *, u8);
int qlcnic_83xx_interrupt_test(struct net_device *);
+int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state);
int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 5641f8e..ba1502a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1176,7 +1176,8 @@ static int qlcnic_set_led(struct net_device *dev,
int err = -EIO, active = 1;
if (qlcnic_83xx_check(adapter))
- return -EOPNOTSUPP;
+ return qlcnic_83xx_set_led(dev, state);
+
if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
netdev_warn(dev, "LED test not supported for non "
"privilege function\n");
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 1/1] qlcnic: Fix endian issues in 83xx driver
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
In-Reply-To: <1362772433-12045-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
o Split mailbox structure elements on boundary of adapter
register size i.e. 32bit.
o Shuffle the position of structure elements based on CPU endianness.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 106 ++++++++++++++++----
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 17 +++-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 33 ++++++-
3 files changed, 130 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index cd5ae88..41c02ba 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -15,36 +15,57 @@
#define RSS_HASHTYPE_IP_TCP 0x3
/* status descriptor mailbox data
- * @phy_addr: physical address of buffer
+ * @phy_addr_{low|high}: physical address of buffer
* @sds_ring_size: buffer size
* @intrpt_id: interrupt id
* @intrpt_val: source of interrupt
*/
struct qlcnic_sds_mbx {
- u64 phy_addr;
- u8 rsvd1[16];
+ u32 phy_addr_low;
+ u32 phy_addr_high;
+ u32 rsvd1[4];
+#if defined(__LITTLE_ENDIAN)
u16 sds_ring_size;
- u16 rsvd2[3];
+ u16 rsvd2;
+ u16 rsvd3[2];
u16 intrpt_id;
u8 intrpt_val;
- u8 rsvd3[5];
+ u8 rsvd4;
+#elif defined(__BIG_ENDIAN)
+ u16 rsvd2;
+ u16 sds_ring_size;
+ u16 rsvd3[2];
+ u8 rsvd4;
+ u8 intrpt_val;
+ u16 intrpt_id;
+#endif
+ u32 rsvd5;
} __packed;
/* receive descriptor buffer data
- * phy_addr_reg: physical address of regular buffer
- * phy_addr_jmb: physical address of jumbo buffer
+ * phy_addr_reg_{low|high}: physical address of regular buffer
+ * phy_addr_jmb_{low|high}: physical address of jumbo buffer
* reg_ring_sz: size of regular buffer
* reg_ring_len: no. of entries in regular buffer
* jmb_ring_len: no. of entries in jumbo buffer
* jmb_ring_sz: size of jumbo buffer
*/
struct qlcnic_rds_mbx {
- u64 phy_addr_reg;
- u64 phy_addr_jmb;
+ u32 phy_addr_reg_low;
+ u32 phy_addr_reg_high;
+ u32 phy_addr_jmb_low;
+ u32 phy_addr_jmb_high;
+#if defined(__LITTLE_ENDIAN)
u16 reg_ring_sz;
u16 reg_ring_len;
u16 jmb_ring_sz;
u16 jmb_ring_len;
+#elif defined(__BIG_ENDIAN)
+ u16 reg_ring_len;
+ u16 reg_ring_sz;
+ u16 jmb_ring_len;
+ u16 jmb_ring_sz;
+#endif
} __packed;
/* host producers for regular and jumbo rings */
@@ -61,6 +82,7 @@ struct __host_producer_mbx {
* @phy_port: physical port id
*/
struct qlcnic_rcv_mbx_out {
+#if defined(__LITTLE_ENDIAN)
u8 rcv_num;
u8 sts_num;
u16 ctx_id;
@@ -68,32 +90,56 @@ struct qlcnic_rcv_mbx_out {
u8 num_pci_func;
u8 phy_port;
u8 vport_id;
+#elif defined(__BIG_ENDIAN)
+ u16 ctx_id;
+ u8 sts_num;
+ u8 rcv_num;
+ u8 vport_id;
+ u8 phy_port;
+ u8 num_pci_func;
+ u8 state;
+#endif
u32 host_csmr[QLCNIC_MAX_RING_SETS];
struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
} __packed;
struct qlcnic_add_rings_mbx_out {
+#if defined(__LITTLE_ENDIAN)
u8 rcv_num;
u8 sts_num;
- u16 ctx_id;
+ u16 ctx_id;
+#elif defined(__BIG_ENDIAN)
+ u16 ctx_id;
+ u8 sts_num;
+ u8 rcv_num;
+#endif
u32 host_csmr[QLCNIC_MAX_RING_SETS];
struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
} __packed;
/* Transmit context mailbox inbox registers
- * @phys_addr: DMA address of the transmit buffer
- * @cnsmr_index: host consumer index
+ * @phys_addr_{low|high}: DMA address of the transmit buffer
+ * @cnsmr_index_{low|high}: host consumer index
* @size: legth of transmit buffer ring
* @intr_id: interrput id
* @src: src of interrupt
*/
struct qlcnic_tx_mbx {
- u64 phys_addr;
- u64 cnsmr_index;
+ u32 phys_addr_low;
+ u32 phys_addr_high;
+ u32 cnsmr_index_low;
+ u32 cnsmr_index_high;
+#if defined(__LITTLE_ENDIAN)
u16 size;
u16 intr_id;
u8 src;
u8 rsvd[3];
+#elif defined(__BIG_ENDIAN)
+ u16 intr_id;
+ u16 size;
+ u8 rsvd[3];
+ u8 src;
+#endif
} __packed;
/* Transmit context mailbox outbox registers
@@ -101,11 +147,18 @@ struct qlcnic_tx_mbx {
* @ctx_id: transmit context id
* @state: state of the transmit context
*/
+
struct qlcnic_tx_mbx_out {
u32 host_prod;
+#if defined(__LITTLE_ENDIAN)
u16 ctx_id;
u8 state;
u8 rsvd;
+#elif defined(__BIG_ENDIAN)
+ u8 rsvd;
+ u8 state;
+ u16 ctx_id;
+#endif
} __packed;
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
@@ -1004,7 +1057,8 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
sds = &recv_ctx->sds_rings[i];
sds->consumer = 0;
memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
- sds_mbx.phy_addr = sds->phys_addr;
+ sds_mbx.phy_addr_low = LSD(sds->phys_addr);
+ sds_mbx.phy_addr_high = MSD(sds->phys_addr);
sds_mbx.sds_ring_size = sds->num_desc;
if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -1090,7 +1144,8 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
sds = &recv_ctx->sds_rings[i];
sds->consumer = 0;
memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
- sds_mbx.phy_addr = sds->phys_addr;
+ sds_mbx.phy_addr_low = LSD(sds->phys_addr);
+ sds_mbx.phy_addr_high = MSD(sds->phys_addr);
sds_mbx.sds_ring_size = sds->num_desc;
if (adapter->flags & QLCNIC_MSIX_ENABLED)
intrpt_id = ahw->intr_tbl[i].id;
@@ -1110,13 +1165,15 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
rds = &recv_ctx->rds_rings[0];
rds->producer = 0;
memset(&rds_mbx, 0, rds_mbx_size);
- rds_mbx.phy_addr_reg = rds->phys_addr;
+ rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
+ rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
rds_mbx.reg_ring_sz = rds->dma_size;
rds_mbx.reg_ring_len = rds->num_desc;
/* Jumbo ring */
rds = &recv_ctx->rds_rings[1];
rds->producer = 0;
- rds_mbx.phy_addr_jmb = rds->phys_addr;
+ rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
+ rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
rds_mbx.jmb_ring_sz = rds->dma_size;
rds_mbx.jmb_ring_len = rds->num_desc;
buf = &cmd.req.arg[index];
@@ -1182,8 +1239,10 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
/* setup mailbox inbox registerss */
- mbx.phys_addr = tx->phys_addr;
- mbx.cnsmr_index = tx->hw_cons_phys_addr;
+ mbx.phys_addr_low = LSD(tx->phys_addr);
+ mbx.phys_addr_high = MSD(tx->phys_addr);
+ mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
+ mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
mbx.size = tx->num_desc;
if (adapter->flags & QLCNIC_MSIX_ENABLED)
msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
@@ -1713,7 +1772,12 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
(adapter->recv_ctx->context_id << 16);
mv.vlan = le16_to_cpu(vlan_id);
- memcpy(&mv.mac, addr, ETH_ALEN);
+ mv.mac_addr0 = addr[0];
+ mv.mac_addr1 = addr[1];
+ mv.mac_addr2 = addr[2];
+ mv.mac_addr3 = addr[3];
+ mv.mac_addr4 = addr[4];
+ mv.mac_addr5 = addr[5];
buf = &cmd.req.arg[2];
memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
err = qlcnic_issue_cmd(adapter, &cmd);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 61f81f6..94e3ee0 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -94,8 +94,23 @@ struct qlcnic_intrpt_config {
};
struct qlcnic_macvlan_mbx {
- u8 mac[ETH_ALEN];
+#if defined(__LITTLE_ENDIAN)
+ u8 mac_addr0;
+ u8 mac_addr1;
+ u8 mac_addr2;
+ u8 mac_addr3;
+ u8 mac_addr4;
+ u8 mac_addr5;
u16 vlan;
+#elif defined(__BIG_ENDIAN)
+ u8 mac_addr3;
+ u8 mac_addr2;
+ u8 mac_addr1;
+ u8 mac_addr0;
+ u16 vlan;
+ u8 mac_addr5;
+ u8 mac_addr4;
+#endif
};
struct qlc_83xx_fw_info {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 5c033f2..ba5ac69 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -31,6 +31,7 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter);
/* Template header */
struct qlc_83xx_reset_hdr {
+#if defined(__LITTLE_ENDIAN)
u16 version;
u16 signature;
u16 size;
@@ -39,14 +40,31 @@ struct qlc_83xx_reset_hdr {
u16 checksum;
u16 init_offset;
u16 start_offset;
+#elif defined(__BIG_ENDIAN)
+ u16 signature;
+ u16 version;
+ u16 entries;
+ u16 size;
+ u16 checksum;
+ u16 hdr_size;
+ u16 start_offset;
+ u16 init_offset;
+#endif
} __packed;
/* Command entry header. */
struct qlc_83xx_entry_hdr {
- u16 cmd;
- u16 size;
- u16 count;
- u16 delay;
+#if defined(__LITTLE_ENDIAN)
+ u16 cmd;
+ u16 size;
+ u16 count;
+ u16 delay;
+#elif defined(__BIG_ENDIAN)
+ u16 size;
+ u16 cmd;
+ u16 delay;
+ u16 count;
+#endif
} __packed;
/* Generic poll command */
@@ -60,10 +78,17 @@ struct qlc_83xx_rmw {
u32 mask;
u32 xor_value;
u32 or_value;
+#if defined(__LITTLE_ENDIAN)
u8 shl;
u8 shr;
u8 index_a;
u8 rsvd;
+#elif defined(__BIG_ENDIAN)
+ u8 rsvd;
+ u8 index_a;
+ u8 shr;
+ u8 shl;
+#endif
} __packed;
/* Generic command with 2 DWORD */
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 0/5] qlcnic: bug fixes and feature updates
From: Shahed Shaikh @ 2013-03-08 19:53 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Please apply to net-next.
Thanks,
Shahed
Himanshu Madhani (1):
qlcnic: Enable LED test support for 83xx adapter
Shahed Shaikh (4):
qlcnic: Fix endianness issues in 83xx driver
qlcnic: Fix ethtool statistics for 82xx adapter
qlcnic: Fix ethtool statistics collection
qlcnic: Bump up the version to 5.1.36
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 +-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 151 +++++++++++++++++---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 18 +++-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 33 ++++-
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 14 +-
5 files changed, 186 insertions(+), 34 deletions(-)
^ permalink raw reply
* RE: [PATCH net-next 1/5] bna: fix declaration mismatch
From: Rasesh Mody @ 2013-03-08 19:30 UTC (permalink / raw)
To: Stephen Hemminger, David Miller; +Cc: netdev@vger.kernel.org, Stephen Hemminger
In-Reply-To: <20130308190808.861866355@vyatta.com>
>From: Stephen Hemminger [mailto:shemminger@vyatta.com]
>Sent: Friday, March 08, 2013 11:08 AM
>
>The function is declared to take u32 but definition uses enum.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
You are right, thanks Stephen!
Acked-by: Rasesh Mody <rmody@brocade.com>
^ permalink raw reply
* [PATCH net-next 5/5] dcb: fix sparse warnings
From: Stephen Hemminger @ 2013-03-08 19:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20130308190739.260966567@vyatta.com>
[-- Attachment #1: dcb-sparse.patch --]
[-- Type: text/plain, Size: 454 bytes --]
Add header with function definitions to quiet warnings and avoid future errors.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
--- a/net/dcb/dcbevent.c 2012-12-07 15:06:43.291665973 -0800
+++ b/net/dcb/dcbevent.c 2013-03-08 10:36:52.394147858 -0800
@@ -20,6 +20,7 @@
#include <linux/rtnetlink.h>
#include <linux/notifier.h>
#include <linux/export.h>
+#include <net/dcbevent.h>
static ATOMIC_NOTIFIER_HEAD(dcbevent_notif_chain);
^ permalink raw reply
* [PATCH net-next 2/5] Supject: phy: make local function static
From: Stephen Hemminger @ 2013-03-08 19:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20130308190739.260966567@vyatta.com>
[-- Attachment #1: phy-local.patch --]
[-- Type: text/plain, Size: 408 bytes --]
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
--- a/drivers/net/phy/lxt.c 2013-03-08 10:33:17.950142115 -0800
+++ b/drivers/net/phy/lxt.c 2013-03-08 10:33:22.210142229 -0800
@@ -159,7 +159,7 @@ static int lxt973a2_update_link(struct p
return 0;
}
-int lxt973a2_read_status(struct phy_device *phydev)
+static int lxt973a2_read_status(struct phy_device *phydev)
{
int adv;
int err;
^ permalink raw reply
* [PATCH net-next 3/5] phy: vitesse make vsc824x_add_skew static
From: Stephen Hemminger @ 2013-03-08 19:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20130308190739.260966567@vyatta.com>
[-- Attachment #1: vitesse-local.patch --]
[-- Type: text/plain, Size: 710 bytes --]
Function is only used in this file, should be static and not
an exported symbol.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
--- a/drivers/net/phy/vitesse.c 2013-03-08 10:33:16.126142066 -0800
+++ b/drivers/net/phy/vitesse.c 2013-03-08 10:33:22.818142246 -0800
@@ -61,7 +61,7 @@ MODULE_DESCRIPTION("Vitesse PHY driver")
MODULE_AUTHOR("Kriston Carson");
MODULE_LICENSE("GPL");
-int vsc824x_add_skew(struct phy_device *phydev)
+static int vsc824x_add_skew(struct phy_device *phydev)
{
int err;
int extcon;
@@ -81,7 +81,6 @@ int vsc824x_add_skew(struct phy_device *
return err;
}
-EXPORT_SYMBOL(vsc824x_add_skew);
static int vsc824x_config_init(struct phy_device *phydev)
{
^ permalink raw reply
* [PATCH net-next 1/5] bna: fix declaration mismatch
From: Stephen Hemminger @ 2013-03-08 19:07 UTC (permalink / raw)
To: David Miller, Rasesh Mody; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20130308190739.260966567@vyatta.com>
[-- Attachment #1: bna-mismatch.patch --]
[-- Type: text/plain, Size: 815 bytes --]
The function is declared to take u32 but definition uses enum.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c 2013-03-08 10:33:19.142142147 -0800
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c 2013-03-08 10:33:21.534142211 -0800
@@ -76,7 +76,7 @@ static void bfa_ioc_pf_disabled(struct b
static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc);
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
-static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
+static void bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
u32 boot_param);
static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
^ 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