Skip to content

Commit

Permalink
[BNX2]: Enable new tx ring.
Browse files Browse the repository at this point in the history
Enable new tx ring and add new MSIX handler and NAPI poll function
for the new tx ring.  Enable MSIX when the hardware supports it.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Jan 28, 2008
1 parent c76c047 commit 57851d8
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 8 deletions.
87 changes: 80 additions & 7 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
struct bnx2_napi *bnapi = &bp->bnx2_napi[i];

bnapi->status_blk = (void *)
bnapi->status_blk_msix = (void *)
((unsigned long) bp->status_blk +
BNX2_SBLK_MSIX_ALIGN_SIZE * i);
bnapi->int_num = i << 24;
Expand Down Expand Up @@ -2388,10 +2388,11 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
return cons;
}

static void
bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
static int
bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
{
u16 hw_cons, sw_cons, sw_ring_cons;
int tx_pkt = 0;

hw_cons = bnx2_get_hw_tx_cons(bnapi);
sw_cons = bnapi->tx_cons;
Expand Down Expand Up @@ -2442,6 +2443,9 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
sw_cons = NEXT_TX_BD(sw_cons);

dev_kfree_skb(skb);
tx_pkt++;
if (tx_pkt == budget)
break;

hw_cons = bnx2_get_hw_tx_cons(bnapi);
}
Expand All @@ -2463,6 +2467,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
netif_wake_queue(bp->dev);
netif_tx_unlock(bp->dev);
}
return tx_pkt;
}

static void
Expand Down Expand Up @@ -2875,6 +2880,23 @@ bnx2_interrupt(int irq, void *dev_instance)
return IRQ_HANDLED;
}

static irqreturn_t
bnx2_tx_msix(int irq, void *dev_instance)
{
struct net_device *dev = dev_instance;
struct bnx2 *bp = netdev_priv(dev);
struct bnx2_napi *bnapi = &bp->bnx2_napi[BNX2_TX_VEC];

prefetch(bnapi->status_blk_msix);

/* Return here if interrupt is disabled. */
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;

netif_rx_schedule(dev, &bnapi->napi);
return IRQ_HANDLED;
}

#define STATUS_ATTN_EVENTS (STATUS_ATTN_BITS_LINK_STATE | \
STATUS_ATTN_BITS_TIMER_ABORT)

Expand All @@ -2895,6 +2917,29 @@ bnx2_has_work(struct bnx2_napi *bnapi)
return 0;
}

static int bnx2_tx_poll(struct napi_struct *napi, int budget)
{
struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
struct bnx2 *bp = bnapi->bp;
int work_done = 0;
struct status_block_msix *sblk = bnapi->status_blk_msix;

do {
work_done += bnx2_tx_int(bp, bnapi, budget - work_done);
if (unlikely(work_done >= budget))
return work_done;

bnapi->last_status_idx = sblk->status_idx;
rmb();
} while (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons);

netif_rx_complete(bp->dev, napi);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
bnapi->last_status_idx);
return work_done;
}

static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
int work_done, int budget)
{
Expand All @@ -2916,7 +2961,7 @@ static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
}

if (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons)
bnx2_tx_int(bp, bnapi);
bnx2_tx_int(bp, bnapi, 0);

if (bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons)
work_done += bnx2_rx_int(bp, bnapi, budget - work_done);
Expand Down Expand Up @@ -5399,10 +5444,35 @@ bnx2_free_irq(struct bnx2 *bp)
static void
bnx2_enable_msix(struct bnx2 *bp)
{
int i, rc;
struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];

bnx2_setup_msix_tbl(bp);
REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);

for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
}

rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
if (rc != 0)
return;

bp->irq_tbl[BNX2_BASE_VEC].handler = bnx2_msi_1shot;
bp->irq_tbl[BNX2_TX_VEC].handler = bnx2_tx_msix;

strcpy(bp->irq_tbl[BNX2_BASE_VEC].name, bp->dev->name);
strcat(bp->irq_tbl[BNX2_BASE_VEC].name, "-base");
strcpy(bp->irq_tbl[BNX2_TX_VEC].name, bp->dev->name);
strcat(bp->irq_tbl[BNX2_TX_VEC].name, "-tx");

bp->irq_nvecs = BNX2_MAX_MSIX_VEC;
bp->flags |= USING_MSIX_FLAG | ONE_SHOT_MSI_FLAG;
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
bp->irq_tbl[i].vector = msix_ent[i].vector;
}

static void
Expand Down Expand Up @@ -5504,9 +5574,10 @@ bnx2_open(struct net_device *dev)
bnx2_enable_int(bp);
}
}
if (bp->flags & USING_MSI_FLAG) {
if (bp->flags & USING_MSI_FLAG)
printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
}
else if (bp->flags & USING_MSIX_FLAG)
printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);

netif_start_queue(dev);

Expand Down Expand Up @@ -5570,7 +5641,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 len, vlan_tag_flags, last_frag, mss;
u16 prod, ring_prod;
int i;
struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
struct bnx2_napi *bnapi = &bp->bnx2_napi[bp->tx_vec];

if (unlikely(bnx2_tx_avail(bp, bnapi) <
(skb_shinfo(skb)->nr_frags + 1))) {
Expand Down Expand Up @@ -7253,6 +7324,8 @@ bnx2_init_napi(struct bnx2 *bp)
bnapi->bp = bp;
}
netif_napi_add(bp->dev, &bp->bnx2_napi[0].napi, bnx2_poll, 64);
netif_napi_add(bp->dev, &bp->bnx2_napi[BNX2_TX_VEC].napi, bnx2_tx_poll,
64);
}

static int __devinit
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/bnx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -6528,7 +6528,7 @@ struct flash_spec {
};

#define BNX2_MAX_MSIX_HW_VEC 9
#define BNX2_MAX_MSIX_VEC 1
#define BNX2_MAX_MSIX_VEC 2
#define BNX2_BASE_VEC 0
#define BNX2_TX_VEC 1
#define BNX2_TX_INT_NUM (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT)
Expand Down

0 comments on commit 57851d8

Please sign in to comment.