* [PATCH 15/17] tg3: Move per-int rx members to per-int struct
From: Matt Carlson @ 2009-08-29 0:03 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch moves the rx_rcb, rx_rcb_mapping, and rx_rcb_ptr return ring
device members to a per-interrupt structure. It also adds a new return
ring consumer mailbox register member (consmbox) and converts the code
to use it rather than a preprocessor constant.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 57 +++++++++++++++++++++++++++++-----------------------
drivers/net/tg3.h | 9 ++++---
2 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5b8d6e0..939574c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -657,7 +657,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
}
/* check for RX/TX work to do */
if (sblk->idx[0].tx_consumer != tp->tx_cons ||
- sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+ sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
work_exists = 1;
return work_exists;
@@ -4480,7 +4480,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
{
struct tg3 *tp = tnapi->tp;
u32 work_mask, rx_std_posted = 0;
- u32 sw_idx = tp->rx_rcb_ptr;
+ u32 sw_idx = tnapi->rx_rcb_ptr;
u16 hw_idx;
int received;
struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
@@ -4494,7 +4494,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
work_mask = 0;
received = 0;
while (sw_idx != hw_idx && budget > 0) {
- struct tg3_rx_buffer_desc *desc = &tp->rx_rcb[sw_idx];
+ struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
unsigned int len;
struct sk_buff *skb;
dma_addr_t dma_addr;
@@ -4622,8 +4622,8 @@ next_pkt_nopost:
}
/* ACK the status ring. */
- tp->rx_rcb_ptr = sw_idx;
- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
+ tnapi->rx_rcb_ptr = sw_idx;
+ tw32_rx_mbox(tnapi->consmbox, sw_idx);
/* Refill RX ring(s). */
if (work_mask & RXD_OPAQUE_RING_STD) {
@@ -4678,7 +4678,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
* All RX "locking" is done by ensuring outside
* code synchronizes with tg3->napi.poll()
*/
- if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+ if (sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
work_done += tg3_rx(tnapi, budget - work_done);
return work_done;
@@ -4768,7 +4768,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
struct tg3 *tp = tnapi->tp;
prefetch(tnapi->hw_status);
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
napi_schedule(&tnapi->napi);
@@ -4786,7 +4786,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
struct tg3 *tp = tnapi->tp;
prefetch(tnapi->hw_status);
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
* chip-internal interrupt pending events.
@@ -4837,7 +4837,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tnapi))) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
napi_schedule(&tnapi->napi);
} else {
/* No work, shared interrupt perhaps? re-enable
@@ -4894,7 +4894,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
if (tg3_irq_sync(tp))
goto out;
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
napi_schedule(&tnapi->napi);
@@ -5745,13 +5745,17 @@ static void tg3_free_rings(struct tg3 *tp)
*/
static int tg3_init_rings(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
+
/* 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);
+ tnapi->rx_rcb_ptr = 0;
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
}
@@ -5765,16 +5769,16 @@ 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);
- tp->rx_rcb = NULL;
- }
if (tp->tx_ring) {
pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
tp->tx_ring, tp->tx_desc_mapping);
tp->tx_ring = NULL;
}
+ if (tnapi->rx_rcb) {
+ pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
+ tnapi->rx_rcb, tnapi->rx_rcb_mapping);
+ tnapi->rx_rcb = NULL;
+ }
if (tnapi->hw_status) {
pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
tnapi->hw_status,
@@ -5805,11 +5809,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!tp->tx_buffers)
goto err_out;
- tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
- &tp->rx_rcb_mapping);
- if (!tp->rx_rcb)
- goto err_out;
-
tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
&tp->tx_desc_mapping);
if (!tp->tx_ring)
@@ -5823,6 +5822,14 @@ static int tg3_alloc_consistent(struct tg3 *tp)
memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+ tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ &tnapi->rx_rcb_mapping);
+ if (!tnapi->rx_rcb)
+ goto err_out;
+
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
&tp->stats_mapping);
@@ -7109,11 +7116,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
}
- tp->rx_rcb_ptr = 0;
- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
+ tw32_rx_mbox(tp->napi[0].consmbox, 0);
tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB,
- tp->rx_rcb_mapping,
+ tp->napi[0].rx_rcb_mapping,
(TG3_RX_RCB_RING_SIZE(tp) <<
BDINFO_FLAGS_MAXLEN_SHIFT),
0);
@@ -9956,7 +9962,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
if (rx_idx != rx_start_idx + num_pkts)
goto out;
- desc = &tp->rx_rcb[rx_start_idx];
+ desc = &rnapi->rx_rcb[rx_start_idx];
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
if (opaque_key != RXD_OPAQUE_RING_STD)
@@ -13413,6 +13419,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->napi[0].tp = tp;
tp->napi[0].int_mbox = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+ tp->napi[0].consmbox = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index f46e619..b91ac29 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2497,8 +2497,13 @@ struct tg3_napi {
u32 last_tag;
u32 last_irq_tag;
u32 int_mbox;
+ u32 consmbox;
+ u32 rx_rcb_ptr;
+
+ struct tg3_rx_buffer_desc *rx_rcb;
dma_addr_t status_mapping;
+ dma_addr_t rx_rcb_mapping;
};
struct tg3 {
@@ -2570,7 +2575,6 @@ struct tg3 {
struct tg3_napi napi[TG3_IRQ_MAX_VECS];
void (*write32_rx_mbox) (struct tg3 *, u32,
u32);
- u32 rx_rcb_ptr;
u32 rx_pending;
u32 rx_jumbo_pending;
u32 rx_std_max_post;
@@ -2579,9 +2583,6 @@ struct tg3 {
struct vlan_group *vlgrp;
#endif
- struct tg3_rx_buffer_desc *rx_rcb;
- dma_addr_t rx_rcb_mapping;
-
struct tg3_rx_prodring_set prodring[1];
--
1.6.3.3
^ permalink raw reply related
* [PATCH 14/17] tg3: Move general int members to a per-int struct
From: Matt Carlson @ 2009-08-29 0:02 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch moves the last_tag, last_tag_irq, and hw_status device
members to a per-interrupt structure. It also adds a new interrupt
mailbox member (int_mbox) and converts the code to use it rather than a
direct preprocessor constant.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 134 +++++++++++++++++++++++++++++------------------------
drivers/net/tg3.h | 12 +++--
2 files changed, 80 insertions(+), 66 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 27ebe3b..5b8d6e0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -615,13 +615,13 @@ static void tg3_disable_ints(struct tg3 *tp)
{
tw32(TG3PCI_MISC_HOST_CTRL,
(tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ tw32_mailbox_f(tp->napi[0].int_mbox, 0x00000001);
}
static inline void tg3_cond_int(struct tg3 *tp)
{
if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
- (tp->hw_status->status & SD_STATUS_UPDATED))
+ (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
else
tw32(HOSTCC_MODE, tp->coalesce_mode |
@@ -630,23 +630,22 @@ static inline void tg3_cond_int(struct tg3 *tp)
static void tg3_enable_ints(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
tp->irq_sync = 0;
wmb();
tw32(TG3PCI_MISC_HOST_CTRL,
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- (tp->last_tag << 24));
+ tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- (tp->last_tag << 24));
+ tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
tg3_cond_int(tp);
}
static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
{
struct tg3 *tp = tnapi->tp;
- struct tg3_hw_status *sblk = tp->hw_status;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
unsigned int work_exists = 0;
/* check for phy events */
@@ -673,8 +672,7 @@ static void tg3_int_reenable(struct tg3_napi *tnapi)
{
struct tg3 *tp = tnapi->tp;
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- tp->last_tag << 24);
+ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
mmiowb();
/* When doing tagged status, this work check is unnecessary.
@@ -696,13 +694,14 @@ static inline void tg3_netif_stop(struct tg3 *tp)
static inline void tg3_netif_start(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
netif_wake_queue(tp->dev);
/* NOTE: unconditional netif_wake_queue is only appropriate
* so long as all callers are assured to have free tx slots
* (such as after tg3_init_hw)
*/
- napi_enable(&tp->napi[0].napi);
- tp->hw_status->status |= SD_STATUS_UPDATED;
+ napi_enable(&tnapi->napi);
+ tnapi->hw_status->status |= SD_STATUS_UPDATED;
tg3_enable_ints(tp);
}
@@ -3902,9 +3901,9 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
else
current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
- tp->hw_status->status =
+ tp->napi[0].hw_status->status =
(SD_STATUS_UPDATED |
- (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
+ (tp->napi[0].hw_status->status & ~SD_STATUS_LINK_CHG));
for (i = 0; i < 100; i++) {
tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
@@ -4284,7 +4283,7 @@ static inline u32 tg3_tx_avail(struct tg3 *tp)
static void tg3_tx(struct tg3_napi *tnapi)
{
struct tg3 *tp = tnapi->tp;
- u32 hw_idx = tp->hw_status->idx[0].tx_consumer;
+ u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
u32 sw_idx = tp->tx_cons;
while (sw_idx != hw_idx) {
@@ -4486,7 +4485,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
int received;
struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
- hw_idx = tp->hw_status->idx[0].rx_producer;
+ hw_idx = tnapi->hw_status->idx[0].rx_producer;
/*
* We need to order the read of hw_idx and the read of
* the opaque cookie.
@@ -4617,7 +4616,7 @@ next_pkt_nopost:
/* Refresh hw_idx to see if there is new work */
if (sw_idx == hw_idx) {
- hw_idx = tp->hw_status->idx[0].rx_producer;
+ hw_idx = tnapi->hw_status->idx[0].rx_producer;
rmb();
}
}
@@ -4645,7 +4644,7 @@ next_pkt_nopost:
static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
{
struct tg3 *tp = tnapi->tp;
- struct tg3_hw_status *sblk = tp->hw_status;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
/* handle link change and other phy events */
if (!(tp->tg3_flags &
@@ -4690,7 +4689,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
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;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
while (1) {
work_done = tg3_poll_work(tnapi, work_done, budget);
@@ -4706,8 +4705,8 @@ static int tg3_poll(struct napi_struct *napi, int budget)
* to tell the hw how much work has been processed,
* so we must read it before checking for more work.
*/
- tp->last_tag = sblk->status_tag;
- tp->last_irq_tag = tp->last_tag;
+ tnapi->last_tag = sblk->status_tag;
+ tnapi->last_irq_tag = tnapi->last_tag;
rmb();
} else
sblk->status &= ~SD_STATUS_UPDATED;
@@ -4768,7 +4767,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
struct tg3_napi *tnapi = dev_id;
struct tg3 *tp = tnapi->tp;
- prefetch(tp->hw_status);
+ prefetch(tnapi->hw_status);
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
@@ -4786,7 +4785,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
struct tg3_napi *tnapi = dev_id;
struct tg3 *tp = tnapi->tp;
- prefetch(tp->hw_status);
+ prefetch(tnapi->hw_status);
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
@@ -4806,7 +4805,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
{
struct tg3_napi *tnapi = dev_id;
struct tg3 *tp = tnapi->tp;
- struct tg3_hw_status *sblk = tp->hw_status;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
unsigned int handled = 1;
/* In INTx mode, it is possible for the interrupt to arrive at
@@ -4855,7 +4854,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
{
struct tg3_napi *tnapi = dev_id;
struct tg3 *tp = tnapi->tp;
- struct tg3_hw_status *sblk = tp->hw_status;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
unsigned int handled = 1;
/* In INTx mode, it is possible for the interrupt to arrive at
@@ -4863,7 +4862,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
+ if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
handled = 0;
@@ -4890,7 +4889,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* so that the above check can report that the screaming interrupts
* are unhandled. Eventually they will be silenced.
*/
- tp->last_irq_tag = sblk->status_tag;
+ tnapi->last_irq_tag = sblk->status_tag;
if (tg3_irq_sync(tp))
goto out;
@@ -4908,7 +4907,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id)
{
struct tg3_napi *tnapi = dev_id;
struct tg3 *tp = tnapi->tp;
- struct tg3_hw_status *sblk = tp->hw_status;
+ struct tg3_hw_status *sblk = tnapi->hw_status;
if ((sblk->status & SD_STATUS_UPDATED) ||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
@@ -5762,6 +5761,8 @@ static int tg3_init_rings(struct tg3 *tp)
*/
static void tg3_free_consistent(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
+
kfree(tp->tx_buffers);
tp->tx_buffers = NULL;
if (tp->rx_rcb) {
@@ -5774,10 +5775,11 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->tx_ring, tp->tx_desc_mapping);
tp->tx_ring = NULL;
}
- if (tp->hw_status) {
+ if (tnapi->hw_status) {
pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
- tp->hw_status, tp->status_mapping);
- tp->hw_status = NULL;
+ tnapi->hw_status,
+ tnapi->status_mapping);
+ tnapi->hw_status = NULL;
}
if (tp->hw_stats) {
pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
@@ -5793,6 +5795,8 @@ static void tg3_free_consistent(struct tg3 *tp)
*/
static int tg3_alloc_consistent(struct tg3 *tp)
{
+ struct tg3_napi *tnapi = &tp->napi[0];
+
if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
return -ENOMEM;
@@ -5811,19 +5815,20 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!tp->tx_ring)
goto err_out;
- tp->hw_status = pci_alloc_consistent(tp->pdev,
- TG3_HW_STATUS_SIZE,
- &tp->status_mapping);
- if (!tp->hw_status)
+ tnapi->hw_status = pci_alloc_consistent(tp->pdev,
+ TG3_HW_STATUS_SIZE,
+ &tnapi->status_mapping);
+ if (!tnapi->hw_status)
goto err_out;
+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
&tp->stats_mapping);
if (!tp->hw_stats)
goto err_out;
- memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
return 0;
@@ -5885,6 +5890,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
static int tg3_abort_hw(struct tg3 *tp, int silent)
{
int i, err;
+ struct tg3_napi *tnapi = &tp->napi[0];
tg3_disable_ints(tp);
@@ -5936,8 +5942,8 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
- if (tp->hw_status)
- memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+ if (tnapi->hw_status)
+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
if (tp->hw_stats)
memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
@@ -6264,12 +6270,12 @@ static int tg3_chip_reset(struct tg3 *tp)
* sharing or irqpoll.
*/
tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
- if (tp->hw_status) {
- tp->hw_status->status = 0;
- tp->hw_status->status_tag = 0;
+ if (tp->napi[0].hw_status) {
+ tp->napi[0].hw_status->status = 0;
+ tp->napi[0].hw_status->status_tag = 0;
}
- tp->last_tag = 0;
- tp->last_irq_tag = 0;
+ tp->napi[0].last_tag = 0;
+ tp->napi[0].last_irq_tag = 0;
smp_mb();
synchronize_irq(tp->pdev->irq);
@@ -7210,9 +7216,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
/* set status block DMA address */
tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
- ((u64) tp->status_mapping >> 32));
+ ((u64) tp->napi[0].status_mapping >> 32));
tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
- ((u64) tp->status_mapping & 0xffffffff));
+ ((u64) tp->napi[0].status_mapping & 0xffffffff));
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
/* Status/statistics block address. See tg3_timer,
@@ -7241,7 +7247,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tg3_write_mem(tp, i, 0);
udelay(40);
}
- memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+ memset(tp->napi[0].hw_status, 0, TG3_HW_STATUS_SIZE);
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
@@ -7294,7 +7300,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(100);
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
+ tw32_mailbox_f(tp->napi[0].int_mbox, 0);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -7596,7 +7602,7 @@ static void tg3_timer(unsigned long __opaque)
* IRQ status the mailbox/status_block protocol the chip
* uses with the cpu is race prone.
*/
- if (tp->hw_status->status & SD_STATUS_UPDATED) {
+ if (tp->napi[0].hw_status->status & SD_STATUS_UPDATED) {
tw32(GRC_LOCAL_CTRL,
tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
} else {
@@ -7740,7 +7746,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
if (err)
return err;
- tp->hw_status->status &= ~SD_STATUS_UPDATED;
+ tnapi->hw_status->status &= ~SD_STATUS_UPDATED;
tg3_enable_ints(tp);
tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
@@ -7749,8 +7755,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
for (i = 0; i < 5; i++) {
u32 int_mbox, misc_host_ctrl;
- int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
- TG3_64BIT_REG_LOW);
+ int_mbox = tr32_mailbox(tnapi->int_mbox);
misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
if ((int_mbox != 0) ||
@@ -8027,6 +8032,7 @@ err_out1:
u32 val32, val32_2, val32_3, val32_4, val32_5;
u16 val16;
int i;
+ struct tg3_hw_status *sblk = tp->napi[0]->hw_status;
pci_read_config_word(tp->pdev, PCI_STATUS, &val16);
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &val32);
@@ -8179,14 +8185,15 @@ err_out1:
val32, val32_2, val32_3, val32_4, val32_5);
/* SW status block */
- printk("DEBUG: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
- tp->hw_status->status,
- tp->hw_status->status_tag,
- tp->hw_status->rx_jumbo_consumer,
- tp->hw_status->rx_consumer,
- tp->hw_status->rx_mini_consumer,
- tp->hw_status->idx[0].rx_producer,
- tp->hw_status->idx[0].tx_consumer);
+ printk(KERN_DEBUG
+ "Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+ sblk->status,
+ sblk->status_tag,
+ sblk->rx_jumbo_consumer,
+ sblk->rx_consumer,
+ sblk->rx_mini_consumer,
+ sblk->idx[0].rx_producer,
+ sblk->idx[0].tx_consumer);
/* SW statistics block */
printk("DEBUG: Host statistics block [%08x:%08x:%08x:%08x]\n",
@@ -9824,8 +9831,12 @@ 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_napi *tnapi, *rnapi;
struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+ tnapi = &tp->napi[0];
+ rnapi = &tp->napi[0];
+
if (loopback_mode == TG3_MAC_LOOPBACK) {
/* HW errata - mac loopback fails in some cases on 5780.
* Normal traffic and PHY loopback are not affected by
@@ -9907,7 +9918,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
udelay(10);
- rx_start_idx = tp->hw_status->idx[0].rx_producer;
+ rx_start_idx = rnapi->hw_status->idx[0].rx_producer;
num_pkts = 0;
@@ -9929,8 +9940,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
udelay(10);
- tx_idx = tp->hw_status->idx[0].tx_consumer;
- rx_idx = tp->hw_status->idx[0].rx_producer;
+ tx_idx = tnapi->hw_status->idx[0].tx_consumer;
+ rx_idx = rnapi->hw_status->idx[0].rx_producer;
if ((tx_idx == tp->tx_prod) &&
(rx_idx == (rx_start_idx + num_pkts)))
break;
@@ -13401,6 +13412,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->tx_pending = TG3_DEF_TX_RING_PENDING;
tp->napi[0].tp = tp;
+ tp->napi[0].int_mbox = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index aff3f04..f46e619 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2492,6 +2492,13 @@ struct tg3_rx_prodring_set {
struct tg3_napi {
struct napi_struct napi ____cacheline_aligned;
struct tg3 *tp;
+ struct tg3_hw_status *hw_status;
+
+ u32 last_tag;
+ u32 last_irq_tag;
+ u32 int_mbox;
+
+ dma_addr_t status_mapping;
};
struct tg3 {
@@ -2546,11 +2553,6 @@ struct tg3 {
struct net_device *dev;
struct pci_dev *pdev;
- struct tg3_hw_status *hw_status;
- dma_addr_t status_mapping;
- u32 last_tag;
- u32 last_irq_tag;
-
u32 msg_enable;
/* begin "tx thread" cacheline section */
--
1.6.3.3
^ permalink raw reply related
* [PATCH 13/17] tg3: Convert napi handlers to use tnapi
From: Matt Carlson @ 2009-08-29 0:02 UTC (permalink / raw)
To: davem; +Cc: netdev, andy
This patch converts the napi interrupt handler functions to accept and
use tg3_napi structures.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 55 ++++++++++++++++++++++++++++++----------------------
1 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index bf9a333..27ebe3b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -643,8 +643,9 @@ static void tg3_enable_ints(struct tg3 *tp)
tg3_cond_int(tp);
}
-static inline unsigned int tg3_has_work(struct tg3 *tp)
+static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
{
+ struct tg3 *tp = tnapi->tp;
struct tg3_hw_status *sblk = tp->hw_status;
unsigned int work_exists = 0;
@@ -663,13 +664,15 @@ static inline unsigned int tg3_has_work(struct tg3 *tp)
return work_exists;
}
-/* tg3_restart_ints
+/* tg3_int_reenable
* similar to tg3_enable_ints, but it accurately determines whether there
* is new work pending and can return without flushing the PIO write
* which reenables interrupts
*/
-static void tg3_restart_ints(struct tg3 *tp)
+static void tg3_int_reenable(struct tg3_napi *tnapi)
{
+ struct tg3 *tp = tnapi->tp;
+
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
tp->last_tag << 24);
mmiowb();
@@ -679,7 +682,7 @@ static void tg3_restart_ints(struct tg3 *tp)
* work we've completed.
*/
if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
- tg3_has_work(tp))
+ tg3_has_work(tnapi))
tw32(HOSTCC_MODE, tp->coalesce_mode |
(HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
}
@@ -4278,8 +4281,9 @@ static inline u32 tg3_tx_avail(struct tg3 *tp)
* need special logic to handle SKBs that have not had all
* of their frags sent yet, like SunGEM does.
*/
-static void tg3_tx(struct tg3 *tp)
+static void tg3_tx(struct tg3_napi *tnapi)
{
+ struct tg3 *tp = tnapi->tp;
u32 hw_idx = tp->hw_status->idx[0].tx_consumer;
u32 sw_idx = tp->tx_cons;
@@ -4344,9 +4348,10 @@ static void tg3_tx(struct tg3 *tp)
* buffers the cpu only reads the last cacheline of the RX descriptor
* (to fetch the error flags, vlan tag, checksum, and opaque cookie).
*/
-static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
+static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
int src_idx, u32 dest_idx_unmasked)
{
+ struct tg3 *tp = tnapi->tp;
struct tg3_rx_buffer_desc *desc;
struct ring_info *map, *src_map;
struct sk_buff *skb;
@@ -4409,9 +4414,10 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
* members of the RX descriptor are invariant. See notes above
* tg3_alloc_rx_skb for full details.
*/
-static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
+static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
int src_idx, u32 dest_idx_unmasked)
{
+ struct tg3 *tp = tnapi->tp;
struct tg3_rx_buffer_desc *src_desc, *dest_desc;
struct ring_info *src_map, *dest_map;
int dest_idx;
@@ -4471,8 +4477,9 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
* If both the host and chip were to write into the same ring, cache line
* eviction could occur since both entities want it in an exclusive state.
*/
-static int tg3_rx(struct tg3 *tp, int budget)
+static int tg3_rx(struct tg3_napi *tnapi, int budget)
{
+ struct tg3 *tp = tnapi->tp;
u32 work_mask, rx_std_posted = 0;
u32 sw_idx = tp->rx_rcb_ptr;
u16 hw_idx;
@@ -4515,7 +4522,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
(desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
drop_it:
- tg3_recycle_rx(tp, opaque_key,
+ tg3_recycle_rx(tnapi, opaque_key,
desc_idx, *post_ptr);
drop_it_no_recycle:
/* Other statistics kept track of by card. */
@@ -4535,7 +4542,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
) {
int skb_size;
- skb_size = tg3_alloc_rx_skb(tp, opaque_key,
+ skb_size = tg3_alloc_rx_skb(tnapi, opaque_key,
desc_idx, *post_ptr);
if (skb_size < 0)
goto drop_it;
@@ -4547,7 +4554,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
} else {
struct sk_buff *copy_skb;
- tg3_recycle_rx(tp, opaque_key,
+ tg3_recycle_rx(tnapi, opaque_key,
desc_idx, *post_ptr);
copy_skb = netdev_alloc_skb(tp->dev,
@@ -4584,11 +4591,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) {
- vlan_gro_receive(&tp->napi[0].napi, tp->vlgrp,
+ vlan_gro_receive(&tnapi->napi, tp->vlgrp,
desc->err_vlan & RXD_VLAN_MASK, skb);
} else
#endif
- napi_gro_receive(&tp->napi[0].napi, skb);
+ napi_gro_receive(&tnapi->napi, skb);
received++;
budget--;
@@ -4635,8 +4642,9 @@ next_pkt_nopost:
return received;
}
-static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
{
+ struct tg3 *tp = tnapi->tp;
struct tg3_hw_status *sblk = tp->hw_status;
/* handle link change and other phy events */
@@ -4662,7 +4670,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
/* run TX completion thread */
if (sblk->idx[0].tx_consumer != tp->tx_cons) {
- tg3_tx(tp);
+ tg3_tx(tnapi);
if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
return work_done;
}
@@ -4672,7 +4680,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
* code synchronizes with tg3->napi.poll()
*/
if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
- work_done += tg3_rx(tp, budget - work_done);
+ work_done += tg3_rx(tnapi, budget - work_done);
return work_done;
}
@@ -4685,7 +4693,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
struct tg3_hw_status *sblk = tp->hw_status;
while (1) {
- work_done = tg3_poll_work(tp, work_done, budget);
+ work_done = tg3_poll_work(tnapi, work_done, budget);
if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
goto tx_recovery;
@@ -4694,7 +4702,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
break;
if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
- /* tp->last_tag is used in tg3_restart_ints() below
+ /* tp->last_tag is used in tg3_int_reenable() below
* to tell the hw how much work has been processed,
* so we must read it before checking for more work.
*/
@@ -4704,9 +4712,9 @@ static int tg3_poll(struct napi_struct *napi, int budget)
} else
sblk->status &= ~SD_STATUS_UPDATED;
- if (likely(!tg3_has_work(tp))) {
+ if (likely(!tg3_has_work(tnapi))) {
napi_complete(napi);
- tg3_restart_ints(tp);
+ tg3_int_reenable(tnapi);
break;
}
}
@@ -4829,7 +4837,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
if (tg3_irq_sync(tp))
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
- if (likely(tg3_has_work(tp))) {
+ if (likely(tg3_has_work(tnapi))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
napi_schedule(&tnapi->napi);
} else {
@@ -5560,6 +5568,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
struct tg3_rx_prodring_set *tpr)
{
u32 i, rx_pkt_dma_sz;
+ struct tg3_napi *tnapi = &tp->napi[0];
/* Zero out all descriptors. */
memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
@@ -5586,7 +5595,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
/* 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) {
+ if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_STD, -1, i) < 0) {
printk(KERN_WARNING PFX
"%s: Using a smaller RX standard ring, "
"only %d out of %d buffers were allocated "
@@ -5617,7 +5626,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
}
for (i = 0; i < tp->rx_jumbo_pending; i++) {
- if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
+ if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_JUMBO,
-1, i) < 0) {
printk(KERN_WARNING PFX
"%s: Using a smaller RX jumbo ring, "
--
1.6.3.3
^ permalink raw reply related
* [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
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