* [PATCH 00/17] tg3: 5717 support part 1
From: Matt Carlson @ 2009-08-28 22:27 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patchset adds two patches for the 5785 and starts support for the
5717 ASIC rev. The 5717 ASIC rev is a new dual-port NetXtreme I server
controller family that supports MSIX, jumbo frames, TSS and RSS. The
devices can operate with copper and / or serdes phys. This patchset
gets the ball rolling by taking care of a few housekeeping items and
then preparing the napi and interrupt routines for multiple interrupt
vector support.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
^ permalink raw reply
* [PATCH 08/17] tg3: Create a new prodring_set structure
From: Matt Carlson @ 2009-08-29 0:00 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch migrates most of the rx producer ring variables to a new
tg3_rx_prodring_set structure and modifies the code accordingly.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 163 +++++++++++++++++++++++++++-------------------------
drivers/net/tg3.h | 27 +++++----
2 files changed, 100 insertions(+), 90 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5d0a1e6..053d4e8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4352,24 +4352,25 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
struct sk_buff *skb;
dma_addr_t mapping;
int skb_size, dest_idx;
+ struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
src_map = NULL;
switch (opaque_key) {
case RXD_OPAQUE_RING_STD:
dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
- desc = &tp->rx_std[dest_idx];
- map = &tp->rx_std_buffers[dest_idx];
+ desc = &tpr->rx_std[dest_idx];
+ map = &tpr->rx_std_buffers[dest_idx];
if (src_idx >= 0)
- src_map = &tp->rx_std_buffers[src_idx];
+ src_map = &tpr->rx_std_buffers[src_idx];
skb_size = tp->rx_pkt_map_sz;
break;
case RXD_OPAQUE_RING_JUMBO:
dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
- desc = &tp->rx_jumbo[dest_idx];
- map = &tp->rx_jumbo_buffers[dest_idx];
+ desc = &tpr->rx_jmb[dest_idx];
+ map = &tpr->rx_jmb_buffers[dest_idx];
if (src_idx >= 0)
- src_map = &tp->rx_jumbo_buffers[src_idx];
+ src_map = &tpr->rx_jmb_buffers[src_idx];
skb_size = TG3_RX_JMB_MAP_SZ;
break;
@@ -4414,22 +4415,23 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
struct tg3_rx_buffer_desc *src_desc, *dest_desc;
struct ring_info *src_map, *dest_map;
int dest_idx;
+ struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
switch (opaque_key) {
case RXD_OPAQUE_RING_STD:
dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
- dest_desc = &tp->rx_std[dest_idx];
- dest_map = &tp->rx_std_buffers[dest_idx];
- src_desc = &tp->rx_std[src_idx];
- src_map = &tp->rx_std_buffers[src_idx];
+ dest_desc = &tpr->rx_std[dest_idx];
+ dest_map = &tpr->rx_std_buffers[dest_idx];
+ src_desc = &tpr->rx_std[src_idx];
+ src_map = &tpr->rx_std_buffers[src_idx];
break;
case RXD_OPAQUE_RING_JUMBO:
dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
- dest_desc = &tp->rx_jumbo[dest_idx];
- dest_map = &tp->rx_jumbo_buffers[dest_idx];
- src_desc = &tp->rx_jumbo[src_idx];
- src_map = &tp->rx_jumbo_buffers[src_idx];
+ dest_desc = &tpr->rx_jmb[dest_idx];
+ dest_map = &tpr->rx_jmb_buffers[dest_idx];
+ src_desc = &tpr->rx_jmb[src_idx];
+ src_map = &tpr->rx_jmb_buffers[src_idx];
break;
default:
@@ -4482,6 +4484,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
u32 sw_idx = tp->rx_rcb_ptr;
u16 hw_idx;
int received;
+ struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
hw_idx = tp->hw_status->idx[0].rx_producer;
/*
@@ -4501,20 +4504,18 @@ static int tg3_rx(struct tg3 *tp, int budget)
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
if (opaque_key == RXD_OPAQUE_RING_STD) {
- dma_addr = pci_unmap_addr(&tp->rx_std_buffers[desc_idx],
- mapping);
- skb = tp->rx_std_buffers[desc_idx].skb;
- post_ptr = &tp->rx_std_ptr;
+ struct ring_info *ri = &tpr->rx_std_buffers[desc_idx];
+ dma_addr = pci_unmap_addr(ri, mapping);
+ skb = ri->skb;
+ post_ptr = &tpr->rx_std_ptr;
rx_std_posted++;
} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
- dma_addr = pci_unmap_addr(&tp->rx_jumbo_buffers[desc_idx],
- mapping);
- skb = tp->rx_jumbo_buffers[desc_idx].skb;
- post_ptr = &tp->rx_jumbo_ptr;
- }
- else {
+ struct ring_info *ri = &tpr->rx_jmb_buffers[desc_idx];
+ dma_addr = pci_unmap_addr(ri, mapping);
+ skb = ri->skb;
+ post_ptr = &tpr->rx_jmb_ptr;
+ } else
goto next_pkt_nopost;
- }
work_mask |= opaque_key;
@@ -4627,12 +4628,12 @@ next_pkt_nopost:
/* Refill RX ring(s). */
if (work_mask & RXD_OPAQUE_RING_STD) {
- sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE;
+ sw_idx = tpr->rx_std_ptr % TG3_RX_RING_SIZE;
tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
sw_idx);
}
if (work_mask & RXD_OPAQUE_RING_JUMBO) {
- sw_idx = tp->rx_jumbo_ptr % TG3_RX_JUMBO_RING_SIZE;
+ sw_idx = tpr->rx_jmb_ptr % TG3_RX_JUMBO_RING_SIZE;
tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
sw_idx);
}
@@ -5517,13 +5518,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
-static void tg3_rx_prodring_free(struct tg3 *tp)
+static void tg3_rx_prodring_free(struct tg3 *tp,
+ struct tg3_rx_prodring_set *tpr)
{
struct ring_info *rxp;
int i;
for (i = 0; i < TG3_RX_RING_SIZE; i++) {
- rxp = &tp->rx_std_buffers[i];
+ rxp = &tpr->rx_std_buffers[i];
if (rxp->skb == NULL)
continue;
@@ -5538,7 +5540,7 @@ static void tg3_rx_prodring_free(struct tg3 *tp)
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
- rxp = &tp->rx_jumbo_buffers[i];
+ rxp = &tpr->rx_jmb_buffers[i];
if (rxp->skb == NULL)
continue;
@@ -5560,12 +5562,13 @@ static void tg3_rx_prodring_free(struct tg3 *tp)
* end up in the driver. tp->{tx,}lock are held and thus
* we may not sleep.
*/
-static int tg3_rx_prodring_alloc(struct tg3 *tp)
+static int tg3_rx_prodring_alloc(struct tg3 *tp,
+ struct tg3_rx_prodring_set *tpr)
{
u32 i, rx_pkt_dma_sz;
/* Zero out all descriptors. */
- memset(tp->rx_std, 0, TG3_RX_RING_BYTES);
+ memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
@@ -5580,7 +5583,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp)
for (i = 0; i < TG3_RX_RING_SIZE; i++) {
struct tg3_rx_buffer_desc *rxd;
- rxd = &tp->rx_std[i];
+ rxd = &tpr->rx_std[i];
rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT;
rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
rxd->opaque = (RXD_OPAQUE_RING_STD |
@@ -5605,13 +5608,13 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp)
if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE))
goto done;
- memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES);
+ memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES);
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
struct tg3_rx_buffer_desc *rxd;
- rxd = &tp->rx_jumbo[i];
+ rxd = &tpr->rx_jmb[i];
rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
RXD_FLAG_JUMBO;
@@ -5639,58 +5642,60 @@ done:
return 0;
initfail:
- tg3_rx_prodring_free(tp);
+ tg3_rx_prodring_free(tp, tpr);
return -ENOMEM;
}
-static void tg3_rx_prodring_fini(struct tg3 *tp)
+static void tg3_rx_prodring_fini(struct tg3 *tp,
+ struct tg3_rx_prodring_set *tpr)
{
- kfree(tp->rx_std_buffers);
- tp->rx_std_buffers = NULL;
- kfree(tp->rx_jumbo_buffers);
- tp->rx_jumbo_buffers = NULL;
- if (tp->rx_std) {
+ kfree(tpr->rx_std_buffers);
+ tpr->rx_std_buffers = NULL;
+ kfree(tpr->rx_jmb_buffers);
+ tpr->rx_jmb_buffers = NULL;
+ if (tpr->rx_std) {
pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
- tp->rx_std, tp->rx_std_mapping);
- tp->rx_std = NULL;
+ tpr->rx_std, tpr->rx_std_mapping);
+ tpr->rx_std = NULL;
}
- if (tp->rx_jumbo) {
+ if (tpr->rx_jmb) {
pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
- tp->rx_jumbo, tp->rx_jumbo_mapping);
- tp->rx_jumbo = NULL;
+ tpr->rx_jmb, tpr->rx_jmb_mapping);
+ tpr->rx_jmb = NULL;
}
}
-static int tg3_rx_prodring_init(struct tg3 *tp)
+static int tg3_rx_prodring_init(struct tg3 *tp,
+ struct tg3_rx_prodring_set *tpr)
{
- tp->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
- TG3_RX_RING_SIZE, GFP_KERNEL);
- if (!tp->rx_std_buffers)
+ tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
+ TG3_RX_RING_SIZE, GFP_KERNEL);
+ if (!tpr->rx_std_buffers)
return -ENOMEM;
- tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
- &tp->rx_std_mapping);
- if (!tp->rx_std)
+ tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
+ &tpr->rx_std_mapping);
+ if (!tpr->rx_std)
goto err_out;
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- tp->rx_jumbo_buffers = kzalloc(sizeof(struct ring_info) *
- TG3_RX_JUMBO_RING_SIZE,
- GFP_KERNEL);
- if (!tp->rx_jumbo_buffers)
+ tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
+ TG3_RX_JUMBO_RING_SIZE,
+ GFP_KERNEL);
+ if (!tpr->rx_jmb_buffers)
goto err_out;
- tp->rx_jumbo = pci_alloc_consistent(tp->pdev,
- TG3_RX_JUMBO_RING_BYTES,
- &tp->rx_jumbo_mapping);
- if (!tp->rx_jumbo)
+ tpr->rx_jmb = pci_alloc_consistent(tp->pdev,
+ TG3_RX_JUMBO_RING_BYTES,
+ &tpr->rx_jmb_mapping);
+ if (!tpr->rx_jmb)
goto err_out;
}
return 0;
err_out:
- tg3_rx_prodring_fini(tp);
+ tg3_rx_prodring_fini(tp, tpr);
return -ENOMEM;
}
@@ -5726,7 +5731,7 @@ static void tg3_free_rings(struct tg3 *tp)
dev_kfree_skb_any(skb);
}
- tg3_rx_prodring_free(tp);
+ tg3_rx_prodring_free(tp, &tp->prodring[0]);
}
/* Initialize tx/rx rings for packet processing.
@@ -5745,7 +5750,7 @@ static int tg3_init_rings(struct tg3 *tp)
memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
- return tg3_rx_prodring_alloc(tp);
+ return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
}
/*
@@ -5776,7 +5781,7 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
- tg3_rx_prodring_fini(tp);
+ tg3_rx_prodring_fini(tp, &tp->prodring[0]);
}
/*
@@ -5785,7 +5790,7 @@ static void tg3_free_consistent(struct tg3 *tp)
*/
static int tg3_alloc_consistent(struct tg3 *tp)
{
- if (tg3_rx_prodring_init(tp))
+ if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
return -ENOMEM;
tp->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
@@ -6794,6 +6799,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
{
u32 val, rdmac_mode;
int i, err, limit;
+ struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
tg3_disable_ints(tp);
@@ -7022,9 +7028,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
* configurable.
*/
tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
- ((u64) tp->rx_std_mapping >> 32));
+ ((u64) tpr->rx_std_mapping >> 32));
tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
- ((u64) tp->rx_std_mapping & 0xffffffff));
+ ((u64) tpr->rx_std_mapping & 0xffffffff));
tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_BUFFER_DESC);
@@ -7043,9 +7049,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
- ((u64) tp->rx_jumbo_mapping >> 32));
+ ((u64) tpr->rx_jmb_mapping >> 32));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
- ((u64) tp->rx_jumbo_mapping & 0xffffffff));
+ ((u64) tpr->rx_jmb_mapping & 0xffffffff));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
@@ -7102,14 +7108,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
BDINFO_FLAGS_MAXLEN_SHIFT),
0);
- tp->rx_std_ptr = tp->rx_pending;
+ tpr->rx_std_ptr = tp->rx_pending;
tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
- tp->rx_std_ptr);
+ tpr->rx_std_ptr);
- tp->rx_jumbo_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
- tp->rx_jumbo_pending : 0;
+ tpr->rx_jmb_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
+ tp->rx_jumbo_pending : 0;
tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
- tp->rx_jumbo_ptr);
+ tpr->rx_jmb_ptr);
/* Initialize MAC address and backoff seed. */
__tg3_set_mac_addr(tp, 0);
@@ -9815,6 +9821,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
dma_addr_t map;
int num_pkts, tx_len, rx_len, i, err;
struct tg3_rx_buffer_desc *desc;
+ struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
if (loopback_mode == TG3_MAC_LOOPBACK) {
/* HW errata - mac loopback fails in some cases on 5780.
@@ -9949,9 +9956,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
if (rx_len != tx_len)
goto out;
- rx_skb = tp->rx_std_buffers[desc_idx].skb;
+ rx_skb = tpr->rx_std_buffers[desc_idx].skb;
- map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping);
+ map = pci_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping);
pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
for (i = 14; i < tx_len; i++) {
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index d029b4b..7a27cff 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2476,6 +2476,17 @@ struct tg3_ethtool_stats {
u64 nic_tx_threshold_hit;
};
+struct tg3_rx_prodring_set {
+ u32 rx_std_ptr;
+ u32 rx_jmb_ptr;
+ struct tg3_rx_buffer_desc *rx_std;
+ struct tg3_rx_buffer_desc *rx_jmb;
+ struct ring_info *rx_std_buffers;
+ struct ring_info *rx_jmb_buffers;
+ dma_addr_t rx_std_mapping;
+ dma_addr_t rx_jmb_mapping;
+};
+
struct tg3 {
/* begin "general, frequently-used members" cacheline section */
@@ -2551,27 +2562,19 @@ struct tg3 {
void (*write32_rx_mbox) (struct tg3 *, u32,
u32);
u32 rx_rcb_ptr;
- u32 rx_std_ptr;
- u32 rx_jumbo_ptr;
u32 rx_pending;
u32 rx_jumbo_pending;
+ u32 rx_std_max_post;
+ u32 rx_pkt_map_sz;
#if TG3_VLAN_TAG_USED
struct vlan_group *vlgrp;
#endif
- struct tg3_rx_buffer_desc *rx_std;
- struct ring_info *rx_std_buffers;
- dma_addr_t rx_std_mapping;
- u32 rx_std_max_post;
-
- struct tg3_rx_buffer_desc *rx_jumbo;
- struct ring_info *rx_jumbo_buffers;
- dma_addr_t rx_jumbo_mapping;
-
struct tg3_rx_buffer_desc *rx_rcb;
dma_addr_t rx_rcb_mapping;
- u32 rx_pkt_map_sz;
+ struct tg3_rx_prodring_set prodring[1];
+
/* begin "everything else" cacheline(s) section */
struct net_device_stats net_stats;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 05/17] tg3: Move the JUMBO_CAPABLE and SUPPORT_MSI flags
From: Matt Carlson @ 2009-08-28 23:58 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch moves where the jumbo capable and msi support flags are
located. This is prep work for the addition of msix support flags.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 10 +++++-----
drivers/net/tg3.h | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 606703c..5e74a19 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -92,7 +92,7 @@
/* hardware minimum and maximum for a single frame's data payload */
#define TG3_MIN_MTU 60
#define TG3_MAX_MTU(tp) \
- ((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) ? 9000 : 1500)
+ ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ? 9000 : 1500)
/* These numbers seem to be hard coded in the NIC firmware somehow.
* You can't change the ring sizes, but you can change where you place
@@ -1921,7 +1921,7 @@ out:
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
/* Cannot do read-modify-write on 5401 */
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
- } else if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
+ } else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
u32 phy_reg;
/* Set bit 14 with read-modify-write to preserve other bits */
@@ -1933,7 +1933,7 @@ out:
/* Set phy register 0x10 bit 0 to high fifo elasticity to support
* jumbo frames transmission.
*/
- if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
u32 phy_reg;
if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
@@ -6975,7 +6975,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* Program the jumbo buffer descriptor ring control
* blocks on those devices that have them.
*/
- if ((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) &&
+ if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
/* Setup replenish threshold. */
tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
@@ -12034,7 +12034,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
- tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
+ tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
&pci_state_reg);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 1c9495d..5efae2c 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2601,6 +2601,7 @@ struct tg3 {
#define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000
#define TG3_FLAG_NVRAM 0x00002000
#define TG3_FLAG_NVRAM_BUFFERED 0x00004000
+#define TG3_FLAG_SUPPORT_MSI 0x00008000
#define TG3_FLAG_PCIX_MODE 0x00020000
#define TG3_FLAG_PCI_HIGH_SPEED 0x00040000
#define TG3_FLAG_PCI_32BIT 0x00080000
@@ -2613,7 +2614,7 @@ struct tg3 {
#define TG3_FLAG_CPMU_PRESENT 0x04000000
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
-#define TG3_FLAG_SUPPORT_MSI 0x20000000
+#define TG3_FLAG_JUMBO_CAPABLE 0x20000000
#define TG3_FLAG_CHIP_RESETTING 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 tg3_flags2;
@@ -2639,7 +2640,6 @@ struct tg3 {
#define TG3_FLG2_5750_PLUS 0x00080000
#define TG3_FLG2_PROTECTED_NVRAM 0x00100000
#define TG3_FLG2_USING_MSI 0x00200000
-#define TG3_FLG2_JUMBO_CAPABLE 0x00400000
#define TG3_FLG2_MII_SERDES 0x00800000
#define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \
TG3_FLG2_MII_SERDES)
--
1.6.3.3
^ permalink raw reply related
* [PATCH 06/17] tg3: Clarify rx buffer relationships
From: Matt Carlson @ 2009-08-28 23:58 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch attempts to document the various rx buffer sizes used by the
driver and how they relate to each other.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 42 +++++++++++++++++++++++-------------------
drivers/net/tg3.h | 2 +-
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5e74a19..a2a5f31 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -125,8 +125,15 @@
TG3_TX_RING_SIZE)
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
-#define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64)
-#define RX_JUMBO_PKT_BUF_SZ (9046 + tp->rx_offset + 64)
+#define TG3_DMA_BYTE_ENAB 64
+
+#define TG3_RX_STD_DMA_SZ 1536
+#define TG3_RX_JMB_DMA_SZ 9046
+
+#define TG3_RX_DMA_TO_MAP_SZ(x) ((x) + TG3_DMA_BYTE_ENAB)
+
+#define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
+#define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tp) ((tp)->tx_pending / 4)
@@ -4354,7 +4361,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
map = &tp->rx_std_buffers[dest_idx];
if (src_idx >= 0)
src_map = &tp->rx_std_buffers[src_idx];
- skb_size = tp->rx_pkt_buf_sz;
+ skb_size = tp->rx_pkt_map_sz;
break;
case RXD_OPAQUE_RING_JUMBO:
@@ -4363,7 +4370,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
map = &tp->rx_jumbo_buffers[dest_idx];
if (src_idx >= 0)
src_map = &tp->rx_jumbo_buffers[src_idx];
- skb_size = RX_JUMBO_PKT_BUF_SZ;
+ skb_size = TG3_RX_JMB_MAP_SZ;
break;
default:
@@ -4376,14 +4383,13 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
* Callers depend upon this behavior and assume that
* we leave everything unchanged if we fail.
*/
- skb = netdev_alloc_skb(tp->dev, skb_size);
+ skb = netdev_alloc_skb(tp->dev, skb_size + tp->rx_offset);
if (skb == NULL)
return -ENOMEM;
skb_reserve(skb, tp->rx_offset);
- mapping = pci_map_single(tp->pdev, skb->data,
- skb_size - tp->rx_offset,
+ mapping = pci_map_single(tp->pdev, skb->data, skb_size,
PCI_DMA_FROMDEVICE);
map->skb = skb;
@@ -4540,8 +4546,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
if (skb_size < 0)
goto drop_it;
- pci_unmap_single(tp->pdev, dma_addr,
- skb_size - tp->rx_offset,
+ pci_unmap_single(tp->pdev, dma_addr, skb_size,
PCI_DMA_FROMDEVICE);
skb_put(skb, len);
@@ -5531,7 +5536,7 @@ static void tg3_free_rings(struct tg3 *tp)
continue;
pci_unmap_single(tp->pdev,
pci_unmap_addr(rxp, mapping),
- tp->rx_pkt_buf_sz - tp->rx_offset,
+ tp->rx_pkt_map_sz,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(rxp->skb);
rxp->skb = NULL;
@@ -5544,7 +5549,7 @@ static void tg3_free_rings(struct tg3 *tp)
continue;
pci_unmap_single(tp->pdev,
pci_unmap_addr(rxp, mapping),
- RX_JUMBO_PKT_BUF_SZ - tp->rx_offset,
+ TG3_RX_JMB_MAP_SZ,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(rxp->skb);
rxp->skb = NULL;
@@ -5581,7 +5586,7 @@ static void tg3_free_rings(struct tg3 *tp)
*/
static int tg3_init_rings(struct tg3 *tp)
{
- u32 i;
+ u32 i, rx_pkt_dma_sz;
/* Free up all the SKBs. */
tg3_free_rings(tp);
@@ -5592,10 +5597,11 @@ static int tg3_init_rings(struct tg3 *tp)
memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
- tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
+ rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
- (tp->dev->mtu > ETH_DATA_LEN))
- tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
+ tp->dev->mtu > ETH_DATA_LEN)
+ rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
+ tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
/* Initialize invariants of the rings, we only set this
* stuff once. This works because the card does not
@@ -5605,8 +5611,7 @@ static int tg3_init_rings(struct tg3 *tp)
struct tg3_rx_buffer_desc *rxd;
rxd = &tp->rx_std[i];
- rxd->idx_len = (tp->rx_pkt_buf_sz - tp->rx_offset - 64)
- << RXD_LEN_SHIFT;
+ rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT;
rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
rxd->opaque = (RXD_OPAQUE_RING_STD |
(i << RXD_OPAQUE_INDEX_SHIFT));
@@ -5617,8 +5622,7 @@ static int tg3_init_rings(struct tg3 *tp)
struct tg3_rx_buffer_desc *rxd;
rxd = &tp->rx_jumbo[i];
- rxd->idx_len = (RX_JUMBO_PKT_BUF_SZ - tp->rx_offset - 64)
- << RXD_LEN_SHIFT;
+ rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
RXD_FLAG_JUMBO;
rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 5efae2c..d029b4b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2571,7 +2571,7 @@ struct tg3 {
struct tg3_rx_buffer_desc *rx_rcb;
dma_addr_t rx_rcb_mapping;
- u32 rx_pkt_buf_sz;
+ u32 rx_pkt_map_sz;
/* begin "everything else" cacheline(s) section */
struct net_device_stats net_stats;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 01/17] tg3: Delay mdio bus init until fw finishes
From: Matt Carlson @ 2009-08-28 22:27 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
The device firmware uses the MDIO bus during early setup. If the driver
modifies the MDIO bus configuration while it is in use by the firmware,
any number of bad things can happen. This patch delays MDIO setup until
after the firmware posts its magic signature, signifying initialization
is complete.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8af2cdf..ab3159e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6348,14 +6348,14 @@ static int tg3_chip_reset(struct tg3 *tp)
tw32_f(MAC_MODE, 0);
udelay(40);
- tg3_mdio_start(tp);
-
tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
err = tg3_poll_fw(tp);
if (err)
return err;
+ tg3_mdio_start(tp);
+
if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
val = tr32(0x7c00);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 10/17] tg3: Cleanup interrupt setup / teardown
From: Matt Carlson @ 2009-08-29 0:01 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
Later patches will be adding MSIX support, which will complicate
interrupt initialization. This patch prepares for the integration by
breaking out the interrupt setup and teardown code into separate
functions and cleaning up the error return paths.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 94 ++++++++++++++++++++++++++---------------------------
1 files changed, 46 insertions(+), 48 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 3725ac8..37a4629 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7865,6 +7865,33 @@ static int tg3_request_firmware(struct tg3 *tp)
return 0;
}
+static void tg3_ints_init(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) {
+ /* All MSI supporting chips should support tagged
+ * status. Assert that this is the case.
+ */
+ if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+ printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
+ "Not using MSI.\n", tp->dev->name);
+ } else if (pci_enable_msi(tp->pdev) == 0) {
+ u32 msi_mode;
+
+ msi_mode = tr32(MSGINT_MODE);
+ tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
+ tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+ }
+ }
+}
+
+static void tg3_ints_fini(struct tg3 *tp)
+{
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ pci_disable_msi(tp->pdev);
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ }
+}
+
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
@@ -7906,33 +7933,14 @@ static int tg3_open(struct net_device *dev)
if (err)
return err;
- if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) {
- /* All MSI supporting chips should support tagged
- * status. Assert that this is the case.
- */
- if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
- printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
- "Not using MSI.\n", tp->dev->name);
- } else if (pci_enable_msi(tp->pdev) == 0) {
- u32 msi_mode;
+ tg3_ints_init(tp);
- msi_mode = tr32(MSGINT_MODE);
- tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
- tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
- }
- }
- err = tg3_request_irq(tp);
+ napi_enable(&tp->napi);
- if (err) {
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
- pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
- }
- tg3_free_consistent(tp);
- return err;
- }
+ err = tg3_request_irq(tp);
- napi_enable(&tp->napi);
+ if (err)
+ goto err_out1;
tg3_full_lock(tp, 0);
@@ -7960,36 +7968,19 @@ static int tg3_open(struct net_device *dev)
tg3_full_unlock(tp);
- if (err) {
- napi_disable(&tp->napi);
- free_irq(tp->pdev->irq, dev);
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
- pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
- }
- tg3_free_consistent(tp);
- return err;
- }
+ if (err)
+ goto err_out2;
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
err = tg3_test_msi(tp);
if (err) {
tg3_full_lock(tp, 0);
-
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
- pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
- }
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_free_rings(tp);
- tg3_free_consistent(tp);
-
tg3_full_unlock(tp);
- napi_disable(&tp->napi);
-
- return err;
+ goto err_out1;
}
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -8015,6 +8006,15 @@ static int tg3_open(struct net_device *dev)
netif_start_queue(dev);
return 0;
+
+err_out2:
+ free_irq(tp->pdev->irq, dev);
+
+err_out1:
+ napi_disable(&tp->napi);
+ tg3_ints_fini(tp);
+ tg3_free_consistent(tp);
+ return err;
}
#if 0
@@ -8273,10 +8273,8 @@ static int tg3_close(struct net_device *dev)
tg3_full_unlock(tp);
free_irq(tp->pdev->irq, dev);
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
- pci_disable_msi(tp->pdev);
- tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
- }
+
+ tg3_ints_fini(tp);
memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
sizeof(tp->net_stats_prev));
--
1.6.3.3
^ permalink raw reply related
* [PATCH 11/17] tg3: Move napi to per-int struct
From: Matt Carlson @ 2009-08-29 0:01 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch creates a per-interrupt data structure, moves the napi
member over, and creates a tg3 pointer back to the device structure.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 39 +++++++++++++++++----------------------
drivers/net/tg3.h | 9 ++++++++-
2 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 37a4629..b308c40 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -687,7 +687,7 @@ static void tg3_restart_ints(struct tg3 *tp)
static inline void tg3_netif_stop(struct tg3 *tp)
{
tp->dev->trans_start = jiffies; /* prevent tx timeout */
- napi_disable(&tp->napi);
+ napi_disable(&tp->napi[0].napi);
netif_tx_disable(tp->dev);
}
@@ -698,7 +698,7 @@ static inline void tg3_netif_start(struct tg3 *tp)
* so long as all callers are assured to have free tx slots
* (such as after tg3_init_hw)
*/
- napi_enable(&tp->napi);
+ napi_enable(&tp->napi[0].napi);
tp->hw_status->status |= SD_STATUS_UPDATED;
tg3_enable_ints(tp);
}
@@ -4447,13 +4447,6 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
src_map->skb = NULL;
}
-#if TG3_VLAN_TAG_USED
-static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
-{
- return vlan_gro_receive(&tp->napi, tp->vlgrp, vlan_tag, skb);
-}
-#endif
-
/* The RX ring scheme is composed of multiple rings which post fresh
* buffers to the chip, and one special ring the chip uses to report
* status back to the host.
@@ -4591,11 +4584,11 @@ static int tg3_rx(struct tg3 *tp, int budget)
#if TG3_VLAN_TAG_USED
if (tp->vlgrp != NULL &&
desc->type_flags & RXD_FLAG_VLAN) {
- tg3_vlan_rx(tp, skb,
- desc->err_vlan & RXD_VLAN_MASK);
+ vlan_gro_receive(&tp->napi[0].napi, tp->vlgrp,
+ desc->err_vlan & RXD_VLAN_MASK, skb);
} else
#endif
- napi_gro_receive(&tp->napi, skb);
+ napi_gro_receive(&tp->napi[0].napi, skb);
received++;
budget--;
@@ -4686,7 +4679,8 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
static int tg3_poll(struct napi_struct *napi, int budget)
{
- struct tg3 *tp = container_of(napi, struct tg3, napi);
+ struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
+ struct tg3 *tp = tnapi->tp;
int work_done = 0;
struct tg3_hw_status *sblk = tp->hw_status;
@@ -4770,7 +4764,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
- napi_schedule(&tp->napi);
+ napi_schedule(&tp->napi[0].napi);
return IRQ_HANDLED;
}
@@ -4795,7 +4789,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (likely(!tg3_irq_sync(tp)))
- napi_schedule(&tp->napi);
+ napi_schedule(&tp->napi[0].napi);
return IRQ_RETVAL(1);
}
@@ -4837,7 +4831,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- napi_schedule(&tp->napi);
+ napi_schedule(&tp->napi[0].napi);
} else {
/* No work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
@@ -4895,7 +4889,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- napi_schedule(&tp->napi);
+ napi_schedule(&tp->napi[0].napi);
out:
return IRQ_RETVAL(handled);
@@ -4936,7 +4930,7 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
tg3_full_unlock(tp);
del_timer_sync(&tp->timer);
tp->irq_sync = 0;
- napi_enable(&tp->napi);
+ napi_enable(&tp->napi[0].napi);
dev_close(tp->dev);
tg3_full_lock(tp, 0);
}
@@ -7935,7 +7929,7 @@ static int tg3_open(struct net_device *dev)
tg3_ints_init(tp);
- napi_enable(&tp->napi);
+ napi_enable(&tp->napi[0].napi);
err = tg3_request_irq(tp);
@@ -8011,7 +8005,7 @@ err_out2:
free_irq(tp->pdev->irq, dev);
err_out1:
- napi_disable(&tp->napi);
+ napi_disable(&tp->napi[0].napi);
tg3_ints_fini(tp);
tg3_free_consistent(tp);
return err;
@@ -8252,7 +8246,7 @@ static int tg3_close(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
- napi_disable(&tp->napi);
+ napi_disable(&tp->napi[0].napi);
cancel_work_sync(&tp->reset_task);
netif_stop_queue(dev);
@@ -13396,7 +13390,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
tp->tx_pending = TG3_DEF_TX_RING_PENDING;
- netif_napi_add(dev, &tp->napi, tg3_poll, 64);
+ tp->napi[0].tp = tp;
+ netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
dev->irq = pdev->irq;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 982171f..aff3f04 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2487,6 +2487,13 @@ struct tg3_rx_prodring_set {
dma_addr_t rx_jmb_mapping;
};
+#define TG3_IRQ_MAX_VECS 1
+
+struct tg3_napi {
+ struct napi_struct napi ____cacheline_aligned;
+ struct tg3 *tp;
+};
+
struct tg3 {
/* begin "general, frequently-used members" cacheline section */
@@ -2558,7 +2565,7 @@ struct tg3 {
dma_addr_t tx_desc_mapping;
/* begin "rx thread" cacheline section */
- struct napi_struct napi;
+ struct tg3_napi napi[TG3_IRQ_MAX_VECS];
void (*write32_rx_mbox) (struct tg3 *, u32,
u32);
u32 rx_rcb_ptr;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 07/17] tg3: Create rx producer ring setup routines
From: Matt Carlson @ 2009-08-28 23:59 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
Later patches are going to complicate the ring initialization routines.
This patch breaks out the setup and teardown of the rx producer rings
into separate functions to make the code more readable.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 231 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 144 insertions(+), 87 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index a2a5f31..5d0a1e6 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5517,14 +5517,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
-/* Free up pending packets in all rx/tx rings.
- *
- * The chip has been shut down and the driver detached from
- * the networking, so no interrupts or new tx packets will
- * end up in the driver. tp->{tx,}lock is not held and we are not
- * in an interrupt context and thus may sleep.
- */
-static void tg3_free_rings(struct tg3 *tp)
+static void tg3_rx_prodring_free(struct tg3 *tp)
{
struct ring_info *rxp;
int i;
@@ -5534,46 +5527,29 @@ static void tg3_free_rings(struct tg3 *tp)
if (rxp->skb == NULL)
continue;
- pci_unmap_single(tp->pdev,
- pci_unmap_addr(rxp, mapping),
- tp->rx_pkt_map_sz,
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb_any(rxp->skb);
- rxp->skb = NULL;
- }
-
- for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
- rxp = &tp->rx_jumbo_buffers[i];
- if (rxp->skb == NULL)
- continue;
pci_unmap_single(tp->pdev,
pci_unmap_addr(rxp, mapping),
- TG3_RX_JMB_MAP_SZ,
+ tp->rx_pkt_map_sz,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(rxp->skb);
rxp->skb = NULL;
}
- for (i = 0; i < TG3_TX_RING_SIZE; ) {
- struct tx_ring_info *txp;
- struct sk_buff *skb;
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+ for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+ rxp = &tp->rx_jumbo_buffers[i];
- txp = &tp->tx_buffers[i];
- skb = txp->skb;
+ if (rxp->skb == NULL)
+ continue;
- if (skb == NULL) {
- i++;
- continue;
+ pci_unmap_single(tp->pdev,
+ pci_unmap_addr(rxp, mapping),
+ TG3_RX_JMB_MAP_SZ,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb_any(rxp->skb);
+ rxp->skb = NULL;
}
-
- skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
-
- txp->skb = NULL;
-
- i += skb_shinfo(skb)->nr_frags + 1;
-
- dev_kfree_skb_any(skb);
}
}
@@ -5584,18 +5560,12 @@ static void tg3_free_rings(struct tg3 *tp)
* end up in the driver. tp->{tx,}lock are held and thus
* we may not sleep.
*/
-static int tg3_init_rings(struct tg3 *tp)
+static int tg3_rx_prodring_alloc(struct tg3 *tp)
{
u32 i, rx_pkt_dma_sz;
- /* Free up all the SKBs. */
- tg3_free_rings(tp);
-
/* Zero out all descriptors. */
memset(tp->rx_std, 0, TG3_RX_RING_BYTES);
- memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES);
- memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
- memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
@@ -5617,19 +5587,6 @@ static int tg3_init_rings(struct tg3 *tp)
(i << RXD_OPAQUE_INDEX_SHIFT));
}
- if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
- for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
- struct tg3_rx_buffer_desc *rxd;
-
- rxd = &tp->rx_jumbo[i];
- rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
- rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
- RXD_FLAG_JUMBO;
- rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
- (i << RXD_OPAQUE_INDEX_SHIFT));
- }
- }
-
/* Now allocate fresh SKBs for each rx ring. */
for (i = 0; i < tp->rx_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) {
@@ -5639,13 +5596,29 @@ static int tg3_init_rings(struct tg3 *tp)
"successfully.\n",
tp->dev->name, i, tp->rx_pending);
if (i == 0)
- return -ENOMEM;
+ goto initfail;
tp->rx_pending = i;
break;
}
}
+ if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE))
+ goto done;
+
+ memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES);
+
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
+ for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+ struct tg3_rx_buffer_desc *rxd;
+
+ rxd = &tp->rx_jumbo[i];
+ rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
+ rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
+ RXD_FLAG_JUMBO;
+ rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
+ (i << RXD_OPAQUE_INDEX_SHIFT));
+ }
+
for (i = 0; i < tp->rx_jumbo_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
-1, i) < 0) {
@@ -5654,26 +5627,28 @@ static int tg3_init_rings(struct tg3 *tp)
"only %d out of %d buffers were "
"allocated successfully.\n",
tp->dev->name, i, tp->rx_jumbo_pending);
- if (i == 0) {
- tg3_free_rings(tp);
- return -ENOMEM;
- }
+ if (i == 0)
+ goto initfail;
tp->rx_jumbo_pending = i;
break;
}
}
}
+
+done:
return 0;
+
+initfail:
+ tg3_rx_prodring_free(tp);
+ return -ENOMEM;
}
-/*
- * Must not be invoked with interrupt sources disabled and
- * the hardware shutdown down.
- */
-static void tg3_free_consistent(struct tg3 *tp)
+static void tg3_rx_prodring_fini(struct tg3 *tp)
{
kfree(tp->rx_std_buffers);
tp->rx_std_buffers = NULL;
+ kfree(tp->rx_jumbo_buffers);
+ tp->rx_jumbo_buffers = NULL;
if (tp->rx_std) {
pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
tp->rx_std, tp->rx_std_mapping);
@@ -5684,6 +5659,103 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->rx_jumbo, tp->rx_jumbo_mapping);
tp->rx_jumbo = NULL;
}
+}
+
+static int tg3_rx_prodring_init(struct tg3 *tp)
+{
+ tp->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
+ TG3_RX_RING_SIZE, GFP_KERNEL);
+ if (!tp->rx_std_buffers)
+ return -ENOMEM;
+
+ tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
+ &tp->rx_std_mapping);
+ if (!tp->rx_std)
+ goto err_out;
+
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+ tp->rx_jumbo_buffers = kzalloc(sizeof(struct ring_info) *
+ TG3_RX_JUMBO_RING_SIZE,
+ GFP_KERNEL);
+ if (!tp->rx_jumbo_buffers)
+ goto err_out;
+
+ tp->rx_jumbo = pci_alloc_consistent(tp->pdev,
+ TG3_RX_JUMBO_RING_BYTES,
+ &tp->rx_jumbo_mapping);
+ if (!tp->rx_jumbo)
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ tg3_rx_prodring_fini(tp);
+ return -ENOMEM;
+}
+
+/* Free up pending packets in all rx/tx rings.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver. tp->{tx,}lock is not held and we are not
+ * in an interrupt context and thus may sleep.
+ */
+static void tg3_free_rings(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < TG3_TX_RING_SIZE; ) {
+ struct tx_ring_info *txp;
+ struct sk_buff *skb;
+
+ txp = &tp->tx_buffers[i];
+ skb = txp->skb;
+
+ if (skb == NULL) {
+ i++;
+ continue;
+ }
+
+ skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+
+ txp->skb = NULL;
+
+ i += skb_shinfo(skb)->nr_frags + 1;
+
+ dev_kfree_skb_any(skb);
+ }
+
+ tg3_rx_prodring_free(tp);
+}
+
+/* Initialize tx/rx rings for packet processing.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver. tp->{tx,}lock are held and thus
+ * we may not sleep.
+ */
+static int tg3_init_rings(struct tg3 *tp)
+{
+ /* Free up all the SKBs. */
+ tg3_free_rings(tp);
+
+ /* Zero out all descriptors. */
+ memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+ memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+
+ return tg3_rx_prodring_alloc(tp);
+}
+
+/*
+ * Must not be invoked with interrupt sources disabled and
+ * the hardware shutdown down.
+ */
+static void tg3_free_consistent(struct tg3 *tp)
+{
+ kfree(tp->tx_buffers);
+ tp->tx_buffers = NULL;
if (tp->rx_rcb) {
pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
tp->rx_rcb, tp->rx_rcb_mapping);
@@ -5704,6 +5776,7 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
+ tg3_rx_prodring_fini(tp);
}
/*
@@ -5712,28 +5785,12 @@ static void tg3_free_consistent(struct tg3 *tp)
*/
static int tg3_alloc_consistent(struct tg3 *tp)
{
- tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) *
- (TG3_RX_RING_SIZE +
- TG3_RX_JUMBO_RING_SIZE)) +
- (sizeof(struct tx_ring_info) *
- TG3_TX_RING_SIZE),
- GFP_KERNEL);
- if (!tp->rx_std_buffers)
+ if (tg3_rx_prodring_init(tp))
return -ENOMEM;
- tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
- tp->tx_buffers = (struct tx_ring_info *)
- &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
-
- tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
- &tp->rx_std_mapping);
- if (!tp->rx_std)
- goto err_out;
-
- tp->rx_jumbo = pci_alloc_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
- &tp->rx_jumbo_mapping);
-
- if (!tp->rx_jumbo)
+ tp->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
+ TG3_TX_RING_SIZE, GFP_KERNEL);
+ if (!tp->tx_buffers)
goto err_out;
tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
--
1.6.3.3
^ permalink raw reply related
* [PATCH 04/17] tg3: Break out mini producer ring handling
From: Matt Carlson @ 2009-08-28 23:57 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch separates the code that sets up the mini producer ring from
the code that sets up the jumbo producer rings. The 5717 asic rev
devices do not have a mini ring, but do have a jumbo frame
implementation similar to the 5704 and previous devices.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 23 ++++++++++++-----------
1 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4c4d164..606703c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6967,19 +6967,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_BUFFER_DESC);
- /* Don't even try to program the JUMBO/MINI buffer descriptor
- * configs on 5705.
- */
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
- tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
- RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT);
- } else {
- tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
- RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
-
+ /* Disable the mini ring */
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
BDINFO_FLAGS_DISABLED);
+ /* Program the jumbo buffer descriptor ring control
+ * blocks on those devices that have them.
+ */
+ if ((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) &&
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
/* Setup replenish threshold. */
tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
@@ -6997,7 +6994,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
BDINFO_FLAGS_DISABLED);
}
- }
+ val = RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT;
+ } else
+ val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
+
+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
/* There is only one send ring on 5705/5750, no need to explicitly
* disable the others.
--
1.6.3.3
^ permalink raw reply related
* [PATCH 03/17] tg3: Reformat NVRAM case statements
From: Matt Carlson @ 2009-08-28 22:29 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch fixes up the NVRAM detection switch statements to conform
to the kernel coding style.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 369 ++++++++++++++++++++++++++---------------------------
1 files changed, 183 insertions(+), 186 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index d43b30b..4c4d164 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10302,8 +10302,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
nvcfg1 = tr32(NVRAM_CFG1);
if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
tp->tg3_flags2 |= TG3_FLG2_FLASH;
- }
- else {
+ } else {
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
tw32(NVRAM_CFG1, nvcfg1);
}
@@ -10311,37 +10310,36 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
- case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- break;
- case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
- break;
- case FLASH_VENDOR_ATMEL_EEPROM:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- break;
- case FLASH_VENDOR_ST:
- tp->nvram_jedecnum = JEDEC_ST;
- tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- break;
- case FLASH_VENDOR_SAIFUN:
- tp->nvram_jedecnum = JEDEC_SAIFUN;
- tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
- break;
- case FLASH_VENDOR_SST_SMALL:
- case FLASH_VENDOR_SST_LARGE:
- tp->nvram_jedecnum = JEDEC_SST;
- tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
- break;
+ case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ break;
+ case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
+ break;
+ case FLASH_VENDOR_ATMEL_EEPROM:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ break;
+ case FLASH_VENDOR_ST:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ break;
+ case FLASH_VENDOR_SAIFUN:
+ tp->nvram_jedecnum = JEDEC_SAIFUN;
+ tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
+ break;
+ case FLASH_VENDOR_SST_SMALL:
+ case FLASH_VENDOR_SST_LARGE:
+ tp->nvram_jedecnum = JEDEC_SST;
+ tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
+ break;
}
- }
- else {
+ } else {
tp->nvram_jedecnum = JEDEC_ATMEL;
tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
@@ -10359,48 +10357,47 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
- case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
- case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- break;
- case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- break;
- case FLASH_5752VENDOR_ST_M45PE10:
- case FLASH_5752VENDOR_ST_M45PE20:
- case FLASH_5752VENDOR_ST_M45PE40:
- tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- break;
+ case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+ case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ break;
+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ break;
}
if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
- case FLASH_5752PAGE_SIZE_256:
- tp->nvram_pagesize = 256;
- break;
- case FLASH_5752PAGE_SIZE_512:
- tp->nvram_pagesize = 512;
- break;
- case FLASH_5752PAGE_SIZE_1K:
- tp->nvram_pagesize = 1024;
- break;
- case FLASH_5752PAGE_SIZE_2K:
- tp->nvram_pagesize = 2048;
- break;
- case FLASH_5752PAGE_SIZE_4K:
- tp->nvram_pagesize = 4096;
- break;
- case FLASH_5752PAGE_SIZE_264:
- tp->nvram_pagesize = 264;
- break;
+ case FLASH_5752PAGE_SIZE_256:
+ tp->nvram_pagesize = 256;
+ break;
+ case FLASH_5752PAGE_SIZE_512:
+ tp->nvram_pagesize = 512;
+ break;
+ case FLASH_5752PAGE_SIZE_1K:
+ tp->nvram_pagesize = 1024;
+ break;
+ case FLASH_5752PAGE_SIZE_2K:
+ tp->nvram_pagesize = 2048;
+ break;
+ case FLASH_5752PAGE_SIZE_4K:
+ tp->nvram_pagesize = 4096;
+ break;
+ case FLASH_5752PAGE_SIZE_264:
+ tp->nvram_pagesize = 264;
+ break;
}
- }
- else {
+ } else {
/* For eeprom, set pagesize to maximum eeprom size */
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
@@ -10423,45 +10420,45 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
switch (nvcfg1) {
- case FLASH_5755VENDOR_ATMEL_FLASH_1:
- case FLASH_5755VENDOR_ATMEL_FLASH_2:
- case FLASH_5755VENDOR_ATMEL_FLASH_3:
- case FLASH_5755VENDOR_ATMEL_FLASH_5:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->nvram_pagesize = 264;
- if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
- nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
- tp->nvram_size = (protect ? 0x3e200 :
- TG3_NVRAM_SIZE_512KB);
- else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
- tp->nvram_size = (protect ? 0x1f200 :
- TG3_NVRAM_SIZE_256KB);
- else
- tp->nvram_size = (protect ? 0x1f200 :
- TG3_NVRAM_SIZE_128KB);
- break;
- case FLASH_5752VENDOR_ST_M45PE10:
- case FLASH_5752VENDOR_ST_M45PE20:
- case FLASH_5752VENDOR_ST_M45PE40:
- tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->nvram_pagesize = 256;
- if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
- tp->nvram_size = (protect ?
- TG3_NVRAM_SIZE_64KB :
- TG3_NVRAM_SIZE_128KB);
- else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
- tp->nvram_size = (protect ?
- TG3_NVRAM_SIZE_64KB :
- TG3_NVRAM_SIZE_256KB);
- else
- tp->nvram_size = (protect ?
- TG3_NVRAM_SIZE_128KB :
- TG3_NVRAM_SIZE_512KB);
- break;
+ case FLASH_5755VENDOR_ATMEL_FLASH_1:
+ case FLASH_5755VENDOR_ATMEL_FLASH_2:
+ case FLASH_5755VENDOR_ATMEL_FLASH_3:
+ case FLASH_5755VENDOR_ATMEL_FLASH_5:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 264;
+ if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+ nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
+ tp->nvram_size = (protect ? 0x3e200 :
+ TG3_NVRAM_SIZE_512KB);
+ else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
+ tp->nvram_size = (protect ? 0x1f200 :
+ TG3_NVRAM_SIZE_256KB);
+ else
+ tp->nvram_size = (protect ? 0x1f200 :
+ TG3_NVRAM_SIZE_128KB);
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 256;
+ if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
+ tp->nvram_size = (protect ?
+ TG3_NVRAM_SIZE_64KB :
+ TG3_NVRAM_SIZE_128KB);
+ else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
+ tp->nvram_size = (protect ?
+ TG3_NVRAM_SIZE_64KB :
+ TG3_NVRAM_SIZE_256KB);
+ else
+ tp->nvram_size = (protect ?
+ TG3_NVRAM_SIZE_128KB :
+ TG3_NVRAM_SIZE_512KB);
+ break;
}
}
@@ -10472,34 +10469,34 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
nvcfg1 = tr32(NVRAM_CFG1);
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
- case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
- case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
- case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
- case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+ case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
+ case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+ case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
+ case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
- nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
- tw32(NVRAM_CFG1, nvcfg1);
- break;
- case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
- case FLASH_5755VENDOR_ATMEL_FLASH_1:
- case FLASH_5755VENDOR_ATMEL_FLASH_2:
- case FLASH_5755VENDOR_ATMEL_FLASH_3:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->nvram_pagesize = 264;
- break;
- case FLASH_5752VENDOR_ST_M45PE10:
- case FLASH_5752VENDOR_ST_M45PE20:
- case FLASH_5752VENDOR_ST_M45PE40:
- tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->nvram_pagesize = 256;
- break;
+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+ tw32(NVRAM_CFG1, nvcfg1);
+ break;
+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+ case FLASH_5755VENDOR_ATMEL_FLASH_1:
+ case FLASH_5755VENDOR_ATMEL_FLASH_2:
+ case FLASH_5755VENDOR_ATMEL_FLASH_3:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 264;
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 256;
+ break;
}
}
@@ -10517,63 +10514,63 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
switch (nvcfg1) {
- case FLASH_5761VENDOR_ATMEL_ADB021D:
- case FLASH_5761VENDOR_ATMEL_ADB041D:
- case FLASH_5761VENDOR_ATMEL_ADB081D:
- case FLASH_5761VENDOR_ATMEL_ADB161D:
- case FLASH_5761VENDOR_ATMEL_MDB021D:
- case FLASH_5761VENDOR_ATMEL_MDB041D:
- case FLASH_5761VENDOR_ATMEL_MDB081D:
- case FLASH_5761VENDOR_ATMEL_MDB161D:
- tp->nvram_jedecnum = JEDEC_ATMEL;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
- tp->nvram_pagesize = 256;
- break;
- case FLASH_5761VENDOR_ST_A_M45PE20:
- case FLASH_5761VENDOR_ST_A_M45PE40:
- case FLASH_5761VENDOR_ST_A_M45PE80:
- case FLASH_5761VENDOR_ST_A_M45PE16:
- case FLASH_5761VENDOR_ST_M_M45PE20:
- case FLASH_5761VENDOR_ST_M_M45PE40:
- case FLASH_5761VENDOR_ST_M_M45PE80:
- case FLASH_5761VENDOR_ST_M_M45PE16:
- tp->nvram_jedecnum = JEDEC_ST;
- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
- tp->tg3_flags2 |= TG3_FLG2_FLASH;
- tp->nvram_pagesize = 256;
- break;
+ case FLASH_5761VENDOR_ATMEL_ADB021D:
+ case FLASH_5761VENDOR_ATMEL_ADB041D:
+ case FLASH_5761VENDOR_ATMEL_ADB081D:
+ case FLASH_5761VENDOR_ATMEL_ADB161D:
+ case FLASH_5761VENDOR_ATMEL_MDB021D:
+ case FLASH_5761VENDOR_ATMEL_MDB041D:
+ case FLASH_5761VENDOR_ATMEL_MDB081D:
+ case FLASH_5761VENDOR_ATMEL_MDB161D:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+ tp->nvram_pagesize = 256;
+ break;
+ case FLASH_5761VENDOR_ST_A_M45PE20:
+ case FLASH_5761VENDOR_ST_A_M45PE40:
+ case FLASH_5761VENDOR_ST_A_M45PE80:
+ case FLASH_5761VENDOR_ST_A_M45PE16:
+ case FLASH_5761VENDOR_ST_M_M45PE20:
+ case FLASH_5761VENDOR_ST_M_M45PE40:
+ case FLASH_5761VENDOR_ST_M_M45PE80:
+ case FLASH_5761VENDOR_ST_M_M45PE16:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 256;
+ break;
}
if (protect) {
tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT);
} else {
switch (nvcfg1) {
- case FLASH_5761VENDOR_ATMEL_ADB161D:
- case FLASH_5761VENDOR_ATMEL_MDB161D:
- case FLASH_5761VENDOR_ST_A_M45PE16:
- case FLASH_5761VENDOR_ST_M_M45PE16:
- tp->nvram_size = TG3_NVRAM_SIZE_2MB;
- break;
- case FLASH_5761VENDOR_ATMEL_ADB081D:
- case FLASH_5761VENDOR_ATMEL_MDB081D:
- case FLASH_5761VENDOR_ST_A_M45PE80:
- case FLASH_5761VENDOR_ST_M_M45PE80:
- tp->nvram_size = TG3_NVRAM_SIZE_1MB;
- break;
- case FLASH_5761VENDOR_ATMEL_ADB041D:
- case FLASH_5761VENDOR_ATMEL_MDB041D:
- case FLASH_5761VENDOR_ST_A_M45PE40:
- case FLASH_5761VENDOR_ST_M_M45PE40:
- tp->nvram_size = TG3_NVRAM_SIZE_512KB;
- break;
- case FLASH_5761VENDOR_ATMEL_ADB021D:
- case FLASH_5761VENDOR_ATMEL_MDB021D:
- case FLASH_5761VENDOR_ST_A_M45PE20:
- case FLASH_5761VENDOR_ST_M_M45PE20:
- tp->nvram_size = TG3_NVRAM_SIZE_256KB;
- break;
+ case FLASH_5761VENDOR_ATMEL_ADB161D:
+ case FLASH_5761VENDOR_ATMEL_MDB161D:
+ case FLASH_5761VENDOR_ST_A_M45PE16:
+ case FLASH_5761VENDOR_ST_M_M45PE16:
+ tp->nvram_size = TG3_NVRAM_SIZE_2MB;
+ break;
+ case FLASH_5761VENDOR_ATMEL_ADB081D:
+ case FLASH_5761VENDOR_ATMEL_MDB081D:
+ case FLASH_5761VENDOR_ST_A_M45PE80:
+ case FLASH_5761VENDOR_ST_M_M45PE80:
+ tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+ break;
+ case FLASH_5761VENDOR_ATMEL_ADB041D:
+ case FLASH_5761VENDOR_ATMEL_MDB041D:
+ case FLASH_5761VENDOR_ST_A_M45PE40:
+ case FLASH_5761VENDOR_ST_M_M45PE40:
+ tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+ break;
+ case FLASH_5761VENDOR_ATMEL_ADB021D:
+ case FLASH_5761VENDOR_ATMEL_MDB021D:
+ case FLASH_5761VENDOR_ST_A_M45PE20:
+ case FLASH_5761VENDOR_ST_M_M45PE20:
+ tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+ break;
}
}
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 02/17] tg3: Add new 5785 10/100 only device ID
From: Matt Carlson @ 2009-08-28 22:28 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch adds a new device ID for those 5785 devices that will only
use 10/100 phys.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 3 ++-
drivers/net/tg3.h | 2 ++
include/linux/pci_ids.h | 1 -
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ab3159e..d43b30b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -219,7 +219,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
- {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_G)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_F)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 60b12ab..1c9495d 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -44,6 +44,8 @@
#define TG3PCI_DEVICE_TIGON3_57760 0x1690
#define TG3PCI_DEVICE_TIGON3_57790 0x1694
#define TG3PCI_DEVICE_TIGON3_57788 0x1691
+#define TG3PCI_DEVICE_TIGON3_5785_G 0x1699 /* GPHY */
+#define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */
/* 0x04 --> 0x64 unused */
#define TG3PCI_MSI_DATA 0x00000064
/* 0x66 --> 0x68 unused */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index fdc3110..8549254 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2064,7 +2064,6 @@
#define PCI_DEVICE_ID_TIGON3_5787M 0x1693
#define PCI_DEVICE_ID_TIGON3_5782 0x1696
#define PCI_DEVICE_ID_TIGON3_5784 0x1698
-#define PCI_DEVICE_ID_TIGON3_5785 0x1699
#define PCI_DEVICE_ID_TIGON3_5786 0x169a
#define PCI_DEVICE_ID_TIGON3_5787 0x169b
#define PCI_DEVICE_ID_TIGON3_5788 0x169c
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] netns: embed ip6_dst_ops directly
From: Daniel Lezcano @ 2009-08-29 20:27 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: davem, netdev, benjamin.thery
In-Reply-To: <20090829113449.GA3067@x200.localdomain>
Alexey Dobriyan wrote:
> struct net::ipv6.ip6_dst_ops is separatedly dynamically allocated,
> but there is no fundamental reason for it. Embed it directly into
> struct netns_ipv6.
>
> For that:
> * move struct dst_ops into separate header to fix circular dependencies
> I honestly tried not to, it's pretty impossible to do other way
> * drop dynamical allocation, allocate together with netns
>
> For a change, remove struct dst_ops::dst_net, it's deducible
> by using container_of() given dst_ops pointer.
>
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
> ---
>
> include/net/dst.h | 23 +----------------------
> include/net/dst_ops.h | 28 ++++++++++++++++++++++++++++
> include/net/netns/ipv6.h | 3 ++-
> net/ipv6/route.c | 34 +++++++++++++---------------------
> 4 files changed, 44 insertions(+), 44 deletions(-)
>
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -8,6 +8,7 @@
> #ifndef _NET_DST_H
> #define _NET_DST_H
>
> +#include <net/dst_ops.h>
> #include <linux/netdevice.h>
> #include <linux/rtnetlink.h>
> #include <linux/rcupdate.h>
> @@ -102,28 +103,6 @@ struct dst_entry
> };
> };
>
> -
> -struct dst_ops
> -{
> - unsigned short family;
> - __be16 protocol;
> - unsigned gc_thresh;
> -
> - int (*gc)(struct dst_ops *ops);
> - struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
> - void (*destroy)(struct dst_entry *);
> - void (*ifdown)(struct dst_entry *,
> - struct net_device *dev, int how);
> - struct dst_entry * (*negative_advice)(struct dst_entry *);
> - void (*link_failure)(struct sk_buff *);
> - void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
> - int (*local_out)(struct sk_buff *skb);
> -
> - atomic_t entries;
> - struct kmem_cache *kmem_cachep;
> - struct net *dst_net;
> -};
You will lose entries, kmem_cachep and gc_thresh per namespace, no ?
^ permalink raw reply
* Re: [PATCH] atm: dereference of he_dev->rbps_virt in he_init_group()
From: Roel Kluin @ 2009-08-29 18:59 UTC (permalink / raw)
To: Roel Kluin; +Cc: Chas Williams, linux-atm-general, netdev, Andrew Morton
In-Reply-To: <4A9979CC.2090905@gmail.com>
he_dev->rbps_virt or he_dev->rbpl_virt allocation may fail.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
There was another in the same function.
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 2de6406..8af1d3e 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -795,6 +795,8 @@ he_init_group(struct he_dev *he_dev, int group)
}
memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
+ if (he_dev->rbps_virt == NULL)
+ return -ENOMEM;
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
dma_addr_t dma_handle;
@@ -838,6 +840,8 @@ he_init_group(struct he_dev *he_dev, int group)
}
memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp));
he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL);
+ if (he_dev->rbpl_virt == NULL)
+ return -ENOMEM;
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
dma_addr_t dma_handle;
^ permalink raw reply related
* [PATCH] atm: dereference of he_dev->rbps_virt in he_init_group()
From: Roel Kluin @ 2009-08-29 18:56 UTC (permalink / raw)
To: Chas Williams, linux-atm-general, netdev, Andrew Morton
he_dev->rbps_virt allocation may fail.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 2de6406..2d766d6 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -795,6 +795,8 @@ he_init_group(struct he_dev *he_dev, int group)
}
memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
+ if (he_dev->rbps_virt == NULL)
+ return -ENOMEM;
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
dma_addr_t dma_handle;
^ permalink raw reply related
* Re: [PATCH] sky2: Don't try to turn led off in sky2_down()
From: Stephen Hemminger @ 2009-08-29 17:57 UTC (permalink / raw)
To: Mike McCormack; +Cc: Stephen Hemminger, netdev, Rene Mayrhofer, Richard Leitner
In-Reply-To: <4A9928C9.7000907@ring3k.org>
On Sat, 29 Aug 2009 22:10:33 +0900
Mike McCormack <mikem@ring3k.org> wrote:
> There are a few problems with the following line of code in sky2_down()
>
> sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
>
> * It doesn't specify which port's LED to turn off.
> * We don't turn send LED_STAT_ON on in sky2_up()
> * B0_LED is 0x0006 in the vendor driver, but 0x0005 in sky2.
> B0_LED is right next to B0_POWER_CTRL, so this is possibly
> accounts for the device being accidently powered down as
> reported by Rene Mayrhofer.
I would rather just change the definition of B0_LED to the correct value.
^ permalink raw reply
* [PATCH net-next-2.6] can: use correct NET_RX_ return values
From: Oliver Hartkopp @ 2009-08-29 16:45 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
[-- Attachment #1: Type: text/plain, Size: 197 bytes --]
Dropped skb's should be documented by an appropriate return value.
Use the correct NET_RX_DROP and NET_RX_SUCCESS values for that reason.
Signed-off-by: Oliver Hartkopp <oliver@hartkopp.net>
---
[-- Attachment #2: can_use_correct_NET_RX_return_values.patch --]
[-- Type: text/x-patch, Size: 354 bytes --]
diff --git a/net/can/af_can.c b/net/can/af_can.c
index f9c027b..ef1c43a 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -686,11 +686,11 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
can_stats.matches_delta++;
}
- return 0;
+ return NET_RX_SUCCESS;
drop:
kfree_skb(skb);
- return 0;
+ return NET_RX_DROP;
}
/*
^ permalink raw reply related
* Re: r8169 NETDEV WATCHDOG: eth0: transmit timed out [0/8]
From: David Dillow @ 2009-08-29 13:39 UTC (permalink / raw)
To: roma1390; +Cc: linux-kernel, netdev
In-Reply-To: <b410963b0908290216x19206aa6o4458bb55b5578a04@mail.gmail.com>
On Sat, 2009-08-29 at 12:16 +0300, roma1390 wrote:
> Using 3 different r8169 devices on 2 servers (from 2 server so 100% of
> population) we getting
>
> NETDEV WATCHDOG: eth0: transmit timed out
You're running an old version of the kernel, and the driver was patched
to fix that issue in 2.6.30. It is also in the 2.6.29.x stable series,
and I think maybe the 2.6.28.x series -- please try those and see if you
problem is resolved.
We're aware of a possible issue with the fix in those kernels, and are
working it in another thread. A quick search of the archives should turn
it up. Will you be willing to test patches?
>From your dmesg, it looks like you have 8169c's, running in MSI mode.
Can you please confirm this by sending your /proc/interrupt info:
cat /proc/interrupts | grep eth0
Also, in the future, please cc netdev on network bug reports.
Thanks!
^ permalink raw reply
* Re: [PATCH] sky2: Don't try to turn led off in sky2_down()
From: Mike McCormack @ 2009-08-29 13:17 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <4A9928C9.7000907@ring3k.org>
Mike McCormack wrote:
> There are a few problems with the following line of code in sky2_down()
Apologies, there probably should have been a "next" in that subject line.
Mike
^ permalink raw reply
* [PATCH next] sky2: Create buffer alloc and free helpers
From: Mike McCormack @ 2009-08-29 13:13 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
Refactor similar two sections of code that free buffers into one.
Only call tx_init if all buffer allocations succeed.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 113 +++++++++++++++++++++++++++------------------------
1 files changed, 60 insertions(+), 53 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index aec8ad3..f0c9f39 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1399,6 +1399,61 @@ nomem:
return -ENOMEM;
}
+static int sky2_alloc_buffers(struct sky2_port *sky2)
+{
+ struct sky2_hw *hw = sky2->hw;
+
+ /* must be power of 2 */
+ sky2->tx_le = pci_alloc_consistent(hw->pdev,
+ sky2->tx_ring_size *
+ sizeof(struct sky2_tx_le),
+ &sky2->tx_le_map);
+ if (!sky2->tx_le)
+ goto nomem;
+
+ sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
+ GFP_KERNEL);
+ if (!sky2->tx_ring)
+ goto nomem;
+
+ sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+ &sky2->rx_le_map);
+ if (!sky2->rx_le)
+ goto nomem;
+ memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+ sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
+ GFP_KERNEL);
+ if (!sky2->rx_ring)
+ goto nomem;
+
+ return 0;
+nomem:
+ return -ENOMEM;
+}
+
+static void sky2_free_buffers(struct sky2_port *sky2)
+{
+ struct sky2_hw *hw = sky2->hw;
+
+ if (sky2->rx_le) {
+ pci_free_consistent(hw->pdev, RX_LE_BYTES,
+ sky2->rx_le, sky2->rx_le_map);
+ sky2->rx_le = NULL;
+ }
+ if (sky2->tx_le) {
+ pci_free_consistent(hw->pdev,
+ sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+ sky2->tx_le, sky2->tx_le_map);
+ sky2->tx_le = NULL;
+ }
+ kfree(sky2->tx_ring);
+ kfree(sky2->rx_ring);
+
+ sky2->tx_ring = NULL;
+ sky2->rx_ring = NULL;
+}
+
/* Bring up network interface. */
static int sky2_up(struct net_device *dev)
{
@@ -1406,7 +1461,7 @@ static int sky2_up(struct net_device *dev)
struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port;
u32 imask, ramsize;
- int cap, err = -ENOMEM;
+ int cap, err;
struct net_device *otherdev = hw->dev[sky2->port^1];
/*
@@ -1425,32 +1480,12 @@ static int sky2_up(struct net_device *dev)
netif_carrier_off(dev);
- /* must be power of 2 */
- sky2->tx_le = pci_alloc_consistent(hw->pdev,
- sky2->tx_ring_size *
- sizeof(struct sky2_tx_le),
- &sky2->tx_le_map);
- if (!sky2->tx_le)
- goto err_out;
-
- sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
- GFP_KERNEL);
- if (!sky2->tx_ring)
+ err = sky2_alloc_buffers(sky2);
+ if (err)
goto err_out;
tx_init(sky2);
- sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
- &sky2->rx_le_map);
- if (!sky2->rx_le)
- goto err_out;
- memset(sky2->rx_le, 0, RX_LE_BYTES);
-
- sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
- GFP_KERNEL);
- if (!sky2->rx_ring)
- goto err_out;
-
sky2_mac_init(hw, port);
/* Register is number of 4K blocks on internal RAM buffer. */
@@ -1507,22 +1542,7 @@ static int sky2_up(struct net_device *dev)
return 0;
err_out:
- if (sky2->rx_le) {
- pci_free_consistent(hw->pdev, RX_LE_BYTES,
- sky2->rx_le, sky2->rx_le_map);
- sky2->rx_le = NULL;
- }
- if (sky2->tx_le) {
- pci_free_consistent(hw->pdev,
- sky2->tx_ring_size * sizeof(struct sky2_tx_le),
- sky2->tx_le, sky2->tx_le_map);
- sky2->tx_le = NULL;
- }
- kfree(sky2->tx_ring);
- kfree(sky2->rx_ring);
-
- sky2->tx_ring = NULL;
- sky2->rx_ring = NULL;
+ sky2_free_buffers(sky2);
return err;
}
@@ -1873,20 +1893,7 @@ static int sky2_down(struct net_device *dev)
sky2_rx_clean(sky2);
- pci_free_consistent(hw->pdev, RX_LE_BYTES,
- sky2->rx_le, sky2->rx_le_map);
- kfree(sky2->rx_ring);
-
- pci_free_consistent(hw->pdev,
- sky2->tx_ring_size * sizeof(struct sky2_tx_le),
- sky2->tx_le, sky2->tx_le_map);
- kfree(sky2->tx_ring);
-
- sky2->tx_le = NULL;
- sky2->rx_le = NULL;
-
- sky2->rx_ring = NULL;
- sky2->tx_ring = NULL;
+ sky2_free_buffers(sky2);
return 0;
}
--
1.5.6.5
^ permalink raw reply related
* [PATCH] sky2: Don't try to turn led off in sky2_down()
From: Mike McCormack @ 2009-08-29 13:10 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Rene Mayrhofer, Richard Leitner
There are a few problems with the following line of code in sky2_down()
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
* It doesn't specify which port's LED to turn off.
* We don't turn send LED_STAT_ON on in sky2_up()
* B0_LED is 0x0006 in the vendor driver, but 0x0005 in sky2.
B0_LED is right next to B0_POWER_CTRL, so this is possibly
accounts for the device being accidently powered down as
reported by Rene Mayrhofer.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index dd630cf..aec8ad3 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1866,9 +1866,6 @@ static int sky2_down(struct net_device *dev)
sky2_phy_power_down(hw, port);
spin_unlock_bh(&sky2->phy_lock);
- /* turn off LED's */
- sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
-
sky2_tx_reset(hw, port);
/* Free any pending frames stuck in HW queue */
--
1.5.6.5
^ permalink raw reply related
* [PATCH] netns: embed ip6_dst_ops directly
From: Alexey Dobriyan @ 2009-08-29 11:34 UTC (permalink / raw)
To: davem; +Cc: netdev, benjamin.thery, dlezcano
struct net::ipv6.ip6_dst_ops is separatedly dynamically allocated,
but there is no fundamental reason for it. Embed it directly into
struct netns_ipv6.
For that:
* move struct dst_ops into separate header to fix circular dependencies
I honestly tried not to, it's pretty impossible to do other way
* drop dynamical allocation, allocate together with netns
For a change, remove struct dst_ops::dst_net, it's deducible
by using container_of() given dst_ops pointer.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
include/net/dst.h | 23 +----------------------
include/net/dst_ops.h | 28 ++++++++++++++++++++++++++++
include/net/netns/ipv6.h | 3 ++-
net/ipv6/route.c | 34 +++++++++++++---------------------
4 files changed, 44 insertions(+), 44 deletions(-)
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -8,6 +8,7 @@
#ifndef _NET_DST_H
#define _NET_DST_H
+#include <net/dst_ops.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/rcupdate.h>
@@ -102,28 +103,6 @@ struct dst_entry
};
};
-
-struct dst_ops
-{
- unsigned short family;
- __be16 protocol;
- unsigned gc_thresh;
-
- int (*gc)(struct dst_ops *ops);
- struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
- void (*destroy)(struct dst_entry *);
- void (*ifdown)(struct dst_entry *,
- struct net_device *dev, int how);
- struct dst_entry * (*negative_advice)(struct dst_entry *);
- void (*link_failure)(struct sk_buff *);
- void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
- int (*local_out)(struct sk_buff *skb);
-
- atomic_t entries;
- struct kmem_cache *kmem_cachep;
- struct net *dst_net;
-};
-
#ifdef __KERNEL__
static inline u32
new file mode 100644
--- /dev/null
+++ b/include/net/dst_ops.h
@@ -0,0 +1,28 @@
+#ifndef _NET_DST_OPS_H
+#define _NET_DST_OPS_H
+#include <linux/types.h>
+
+struct dst_entry;
+struct kmem_cachep;
+struct net_device;
+struct sk_buff;
+
+struct dst_ops {
+ unsigned short family;
+ __be16 protocol;
+ unsigned gc_thresh;
+
+ int (*gc)(struct dst_ops *ops);
+ struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
+ void (*destroy)(struct dst_entry *);
+ void (*ifdown)(struct dst_entry *,
+ struct net_device *dev, int how);
+ struct dst_entry * (*negative_advice)(struct dst_entry *);
+ void (*link_failure)(struct sk_buff *);
+ void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
+ int (*local_out)(struct sk_buff *skb);
+
+ atomic_t entries;
+ struct kmem_cache *kmem_cachep;
+};
+#endif
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -6,6 +6,7 @@
#ifndef __NETNS_IPV6_H__
#define __NETNS_IPV6_H__
+#include <net/dst_ops.h>
struct ctl_table_header;
@@ -42,7 +43,7 @@ struct netns_ipv6 {
struct timer_list ip6_fib_timer;
struct hlist_head *fib_table_hash;
struct fib6_table *fib6_main_tbl;
- struct dst_ops *ip6_dst_ops;
+ struct dst_ops ip6_dst_ops;
unsigned int ip6_rt_gc_expire;
unsigned long ip6_rt_last_gc;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -665,7 +665,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
net->ipv6.sysctl.ip6_rt_gc_elasticity = 1;
net->ipv6.sysctl.ip6_rt_gc_min_interval = 0;
- ip6_dst_gc(net->ipv6.ip6_dst_ops);
+ ip6_dst_gc(&net->ipv6.ip6_dst_ops);
net->ipv6.sysctl.ip6_rt_gc_elasticity =
saved_rt_elasticity;
@@ -970,7 +970,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
if (unlikely(idev == NULL))
return NULL;
- rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
if (unlikely(rt == NULL)) {
in6_dev_put(idev);
goto out;
@@ -1060,7 +1060,7 @@ static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg),
static int ip6_dst_gc(struct dst_ops *ops)
{
unsigned long now = jiffies;
- struct net *net = ops->dst_net;
+ struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops);
int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval;
int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size;
int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
@@ -1154,7 +1154,7 @@ int ip6_route_add(struct fib6_config *cfg)
goto out;
}
- rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
if (rt == NULL) {
err = -ENOMEM;
@@ -1643,7 +1643,7 @@ out:
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
{
struct net *net = dev_net(ort->rt6i_dev);
- struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
if (rt) {
rt->u.dst.input = ort->u.dst.input;
@@ -1923,7 +1923,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
int anycast)
{
struct net *net = dev_net(idev->dev);
- struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
struct neighbour *neigh;
if (rt == NULL)
@@ -2501,7 +2501,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
net->ipv6.rt6_stats->fib_rt_alloc,
net->ipv6.rt6_stats->fib_rt_entries,
net->ipv6.rt6_stats->fib_rt_cache,
- atomic_read(&net->ipv6.ip6_dst_ops->entries),
+ atomic_read(&net->ipv6.ip6_dst_ops.entries),
net->ipv6.rt6_stats->fib_discarded_routes);
return 0;
@@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
if (table) {
table[0].data = &net->ipv6.sysctl.flush_delay;
- table[1].data = &net->ipv6.ip6_dst_ops->gc_thresh;
+ table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh;
table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
@@ -2655,12 +2655,8 @@ static int ip6_route_net_init(struct net *net)
{
int ret = -ENOMEM;
- net->ipv6.ip6_dst_ops = kmemdup(&ip6_dst_ops_template,
- sizeof(*net->ipv6.ip6_dst_ops),
- GFP_KERNEL);
- if (!net->ipv6.ip6_dst_ops)
- goto out;
- net->ipv6.ip6_dst_ops->dst_net = hold_net(net);
+ memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template,
+ sizeof(net->ipv6.ip6_dst_ops));
net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
sizeof(*net->ipv6.ip6_null_entry),
@@ -2669,7 +2665,7 @@ static int ip6_route_net_init(struct net *net)
goto out_ip6_dst_ops;
net->ipv6.ip6_null_entry->u.dst.path =
(struct dst_entry *)net->ipv6.ip6_null_entry;
- net->ipv6.ip6_null_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+ net->ipv6.ip6_null_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2679,7 +2675,7 @@ static int ip6_route_net_init(struct net *net)
goto out_ip6_null_entry;
net->ipv6.ip6_prohibit_entry->u.dst.path =
(struct dst_entry *)net->ipv6.ip6_prohibit_entry;
- net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+ net->ipv6.ip6_prohibit_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2688,7 +2684,7 @@ static int ip6_route_net_init(struct net *net)
goto out_ip6_prohibit_entry;
net->ipv6.ip6_blk_hole_entry->u.dst.path =
(struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
- net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+ net->ipv6.ip6_blk_hole_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
#endif
net->ipv6.sysctl.flush_delay = 0;
@@ -2717,8 +2713,6 @@ out_ip6_null_entry:
kfree(net->ipv6.ip6_null_entry);
#endif
out_ip6_dst_ops:
- release_net(net->ipv6.ip6_dst_ops->dst_net);
- kfree(net->ipv6.ip6_dst_ops);
goto out;
}
@@ -2733,8 +2727,6 @@ static void ip6_route_net_exit(struct net *net)
kfree(net->ipv6.ip6_prohibit_entry);
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
- release_net(net->ipv6.ip6_dst_ops->dst_net);
- kfree(net->ipv6.ip6_dst_ops);
}
static struct pernet_operations ip6_route_net_ops = {
^ permalink raw reply
* [PATCH] atm/br2684: netif_stop_queue() when atm device busy and netif_wake_queue() when we can send packets again.
From: Karl Hiramoto @ 2009-08-29 11:24 UTC (permalink / raw)
To: netdev; +Cc: linux-atm-general, Karl Hiramoto
In-Reply-To: <4A9901E7.9040804@hiramoto.org>
This patch removes the call to dev_kfree_skb() when the atm device is busy.
Calling dev_kfree_skb() causes heavy packet loss then the device is under
heavy load, the more correct behavior should be to stop the upper layers,
then when the lower device can queue packets again wake the upper layers.
Signed-off-by: Karl Hiramoto <karl@hiramoto.org>
---
net/atm/br2684.c | 37 +++++++++++++++++++++++++++----------
1 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 2912665..5c42225 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -69,7 +69,7 @@ struct br2684_vcc {
struct net_device *device;
/* keep old push, pop functions for chaining */
void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb);
- /* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */
+ void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
enum br2684_encaps encaps;
struct list_head brvccs;
#ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -142,6 +142,22 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
return NULL;
}
+/* chained vcc->pop function. Check if we should wake the netif_queue */
+static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+ struct br2684_vcc *brvcc = BR2684_VCC(vcc);
+ struct net_device *net_dev = skb->dev;
+
+ pr_debug("br2684_pop(vcc %p ; net_dev %p )\n", vcc, net_dev);
+ brvcc->old_pop(vcc, skb);
+
+ if (!net_dev)
+ return;
+
+ if (atm_may_send(vcc, 0))
+ netif_wake_queue(net_dev);
+
+}
/*
* Send a packet out a particular vcc. Not to useful right now, but paves
* the way for multiple vcc's per itf. Returns true if we can send,
@@ -200,20 +216,19 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
- if (!atm_may_send(atmvcc, skb->truesize)) {
- /*
- * We free this here for now, because we cannot know in a higher
- * layer whether the skb pointer it supplied wasn't freed yet.
- * Now, it always is.
- */
- dev_kfree_skb(skb);
- return 0;
- }
atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
ATM_SKB(skb)->atm_options = atmvcc->atm_options;
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
atmvcc->send(atmvcc, skb);
+
+ if (!atm_may_send(atmvcc, 0)) {
+ netif_stop_queue(brvcc->device);
+ /*check for race with br2684_pop*/
+ if (atm_may_send(atmvcc, 0))
+ netif_start_queue(brvcc->device);
+ }
+
return 1;
}
@@ -503,8 +518,10 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
atmvcc->user_back = brvcc;
brvcc->encaps = (enum br2684_encaps)be.encaps;
brvcc->old_push = atmvcc->push;
+ brvcc->old_pop = atmvcc->pop;
barrier();
atmvcc->push = br2684_push;
+ atmvcc->pop = br2684_pop;
__skb_queue_head_init(&queue);
rq = &sk_atm(atmvcc)->sk_receive_queue;
--
1.6.3.3
^ permalink raw reply related
* Re: Crypto oops in async_chainiv_do_postponed
From: Herbert Xu @ 2009-08-29 10:46 UTC (permalink / raw)
To: Brad Bosch; +Cc: linux-crypto, netdev
In-Reply-To: <19095.1264.682820.125602@waldo.imnotcreative.homeip.net>
Hi Brad:
On Thu, Aug 27, 2009 at 05:13:04PM -0500, Brad Bosch wrote:
>
> I seem to have found a bug in chainiv.c. The following oops occured
> while using blowfish and hmac-sha with UDP. The patch (against
> 2.6.27.30) after the oops output below is an completely untested
> possible fix. We will be testing this fix starting tomorrow.
Thanks for the detailed analysis and patch!
> The null dereference occurs when subreq is dereferenced in
> async_chainiv_do_postponed(). My guess is that the
> skcipher_givcrypt_request block has been freed and subsequently
> overwritten by the time the postponed request is processed. This
> could happen if chainiv_givencrypt() returns anything other than
> -EINPROGRESS after postponing the request. From what I can see, this
> could indeed happen since the same err field in async_chainiv_ctx is
> used both when the request is postponed and also when it is later
> processed by the worker thread. Neither the lock, nor the
> CHAINIV_STATE_INUSE bit in ctx->state will prevent this race which
> results in the -EINPROGRESS err being overwritten between the time it
> is placed in ctx->err in async_chainiv_postpone_request() and when it
> is read back out in async_chainiv_schedule_work(). I am curious why
> this method of returning the error code was used in the first place.
Actually I think the problem is much less subtle than that :)
The problem is that whenever crypto_dequeue_request returns NULL,
chainiv will never see the NULL pointer because we end up converting
the pointer to skcipher_givcrypt_request which would have the value
(NULL - off) where off is non-zero.
Please let me know if this patch fixes the crash for you.
commit 0c7d400fafaeab6014504a6a6249f01bac7f7db4
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Sat Aug 29 20:44:04 2009 +1000
crypto: skcipher - Fix skcipher_dequeue_givcrypt NULL test
As struct skcipher_givcrypt_request includes struct crypto_request
at a non-zero offset, testing for NULL after converting the pointer
returned by crypto_dequeue_request does not work. This can result
in IPsec crashes when the queue is depleted.
This patch fixes it by doing the pointer conversion only when the
return value is non-NULL. In particular, we create a new function
__crypto_dequeue_request that does the pointer conversion.
Reported-by: Brad Bosch <bradbosch@comcast.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 56c62e2..df0863d 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -692,7 +692,7 @@ out:
}
EXPORT_SYMBOL_GPL(crypto_enqueue_request);
-struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
+void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset)
{
struct list_head *request;
@@ -707,7 +707,14 @@ struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
request = queue->list.next;
list_del(request);
- return list_entry(request, struct crypto_async_request, list);
+ return (char *)list_entry(request, struct crypto_async_request, list) -
+ offset;
+}
+EXPORT_SYMBOL_GPL(__crypto_dequeue_request);
+
+struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
+{
+ return __crypto_dequeue_request(queue, 0);
}
EXPORT_SYMBOL_GPL(crypto_dequeue_request);
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 0105454..5a2bd1c 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -137,6 +137,7 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
int crypto_enqueue_request(struct crypto_queue *queue,
struct crypto_async_request *request);
+void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset);
struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 2ba42cd..3a748a6 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -79,8 +79,8 @@ static inline int skcipher_enqueue_givcrypt(
static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt(
struct crypto_queue *queue)
{
- return container_of(ablkcipher_dequeue_request(queue),
- struct skcipher_givcrypt_request, creq);
+ return __crypto_dequeue_request(
+ queue, offsetof(struct skcipher_givcrypt_request, creq.base));
}
static inline void *skcipher_givcrypt_reqctx(
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related
* Re: [Linux-ATM-General] [PATCH] br2684 testing needed for packet loss and performance
From: Karl Hiramoto @ 2009-08-29 10:24 UTC (permalink / raw)
To: chas3; +Cc: linux-atm-general, netdev
In-Reply-To: <200908281225.n7SCPUC3031293@cmf.nrl.navy.mil>
Chas Williams (CONTRACTOR) wrote:
> In message <4A97B3A9.6040103@hiramoto.org>,Karl Hiramoto writes:
>
>> Anyone care to test or comment on these patches? I've attached
>> versions for 2.6.28 and 2.6.30.
>>
>
> this needs to be against the net-2.6 git repository. but the 2.6.30
> would probably apply just fine.
Ok i will resend the patch against net-2.6 or should i do net-next-2.6?
Do i have to wait for a merge window?
> except for the comments, below this
> patch looks fine and makes sense. a similar thing had to be done for
> the lec.c interface.
>
>
Ok I'll clean up all these issues.
--
karl
^ permalink raw reply
* Re: [PATCH] can: switch to seq_file
From: Oliver Hartkopp @ 2009-08-29 8:09 UTC (permalink / raw)
To: David Miller, adobriyan; +Cc: urs.thuermann, oliver.hartkopp, netdev
In-Reply-To: <20090829.002112.160212045.davem@davemloft.net>
David Miller wrote:
> From: Alexey Dobriyan <adobriyan@gmail.com>
> Date: Fri, 28 Aug 2009 23:57:21 +0400
>
>> create_proc_read_entry() is going to be removed soon.
>>
>> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
>
> Applied to net-next-2.6, thanks.
Good to see that it's obviously ok for Dave ;-)
Many thanks for the effort, Alexey!
I'll do some additional testing when i'm back in the office on Monday.
Tnx & best regards,
Oliver
^ 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