#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.8.0"
-#define DRV_MODULE_RELDATE "Aug 14, 2008"
+#define DRV_MODULE_VERSION "1.9.0"
+#define DRV_MODULE_RELDATE "Dec 16, 2008"
#define RUN_AT(x) (jiffies + (x))
BCM5709,
BCM5709S,
BCM5716,
+ BCM5716S,
} board_t;
/* indexed by board_t, above */
{ "Broadcom NetXtreme II BCM5709 1000Base-T" },
{ "Broadcom NetXtreme II BCM5709 1000Base-SX" },
{ "Broadcom NetXtreme II BCM5716 1000Base-T" },
+ { "Broadcom NetXtreme II BCM5716 1000Base-SX" },
};
static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S },
{ PCI_VENDOR_ID_BROADCOM, 0x163b,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
+ { PCI_VENDOR_ID_BROADCOM, 0x163c,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716S },
{ 0, }
};
* exchanging base pages plus 3 next pages and
* normally completes in about 120 msec.
*/
- bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
bp->serdes_an_pending = 1;
mod_timer(&bp->timer, jiffies + bp->current_interval);
} else {
return 0;
/* wait for an acknowledgement. */
- for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
+ for (i = 0; i < (BNX2_FW_ACK_TIME_OUT_MS / 10); i++) {
msleep(10);
val = bnx2_shmem_rd(bp, BNX2_FW_MB);
return -ENOMEM;
mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(bp->pdev, mapping)) {
+ __free_page(page);
+ return -EIO;
+ }
+
rx_pg->page = page;
pci_unmap_addr_set(rx_pg, mapping, mapping);
rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(bp->pdev, mapping)) {
+ dev_kfree_skb(skb);
+ return -EIO;
+ }
rx_buf->skb = skb;
pci_unmap_addr_set(rx_buf, mapping, mapping);
sw_cons = txr->tx_cons;
while (sw_cons != hw_cons) {
- struct sw_bd *tx_buf;
+ struct sw_tx_bd *tx_buf;
struct sk_buff *skb;
int i, last;
}
}
- pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
tx_buf->skb = NULL;
last = skb_shinfo(skb)->nr_frags;
for (i = 0; i < last; i++) {
sw_cons = NEXT_TX_BD(sw_cons);
-
- pci_unmap_page(bp->pdev,
- pci_unmap_addr(
- &txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
- mapping),
- skb_shinfo(skb)->frags[i].size,
- PCI_DMA_TODEVICE);
}
sw_cons = NEXT_TX_BD(sw_cons);
{
struct sw_pg *cons_rx_pg, *prod_rx_pg;
struct rx_bd *cons_bd, *prod_bd;
- dma_addr_t mapping;
int i;
- u16 hw_prod = rxr->rx_pg_prod, prod;
+ u16 hw_prod, prod;
u16 cons = rxr->rx_pg_cons;
+ cons_rx_pg = &rxr->rx_pg_ring[cons];
+
+ /* The caller was unable to allocate a new page to replace the
+ * last one in the frags array, so we need to recycle that page
+ * and then free the skb.
+ */
+ if (skb) {
+ struct page *page;
+ struct skb_shared_info *shinfo;
+
+ shinfo = skb_shinfo(skb);
+ shinfo->nr_frags--;
+ page = shinfo->frags[shinfo->nr_frags].page;
+ shinfo->frags[shinfo->nr_frags].page = NULL;
+
+ cons_rx_pg->page = page;
+ dev_kfree_skb(skb);
+ }
+
+ hw_prod = rxr->rx_pg_prod;
+
for (i = 0; i < count; i++) {
prod = RX_PG_RING_IDX(hw_prod);
cons_bd = &rxr->rx_pg_desc_ring[RX_RING(cons)][RX_IDX(cons)];
prod_bd = &rxr->rx_pg_desc_ring[RX_RING(prod)][RX_IDX(prod)];
- if (i == 0 && skb) {
- struct page *page;
- struct skb_shared_info *shinfo;
-
- shinfo = skb_shinfo(skb);
- shinfo->nr_frags--;
- page = shinfo->frags[shinfo->nr_frags].page;
- shinfo->frags[shinfo->nr_frags].page = NULL;
- mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- cons_rx_pg->page = page;
- pci_unmap_addr_set(cons_rx_pg, mapping, mapping);
- dev_kfree_skb(skb);
- }
if (prod != cons) {
prod_rx_pg->page = cons_rx_pg->page;
cons_rx_pg->page = NULL;
skb_put(skb, hdr_len);
for (i = 0; i < pages; i++) {
+ dma_addr_t mapping_old;
+
frag_len = min(frag_size, (unsigned int) PAGE_SIZE);
if (unlikely(frag_len <= 4)) {
unsigned int tail = 4 - frag_len;
}
rx_pg = &rxr->rx_pg_ring[pg_cons];
- pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping),
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
-
+ /* Don't unmap yet. If we're unable to allocate a new
+ * page, we need to recycle the page and the DMA addr.
+ */
+ mapping_old = pci_unmap_addr(rx_pg, mapping);
if (i == pages - 1)
frag_len -= 4;
return err;
}
+ pci_unmap_page(bp->pdev, mapping_old,
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
+
frag_size -= frag_len;
skb->data_len += frag_len;
skb->truesize += frag_len;
#endif
netif_receive_skb(skb);
- bp->dev->last_rx = jiffies;
rx_pkt++;
next_rx:
return 0;
}
+static void
+bnx2_chk_missed_msi(struct bnx2 *bp)
+{
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ u32 msi_ctrl;
+
+ if (bnx2_has_work(bnapi)) {
+ msi_ctrl = REG_RD(bp, BNX2_PCICFG_MSI_CONTROL);
+ if (!(msi_ctrl & BNX2_PCICFG_MSI_CONTROL_ENABLE))
+ return;
+
+ if (bnapi->last_status_idx == bp->idle_chk_status_idx) {
+ REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl &
+ ~BNX2_PCICFG_MSI_CONTROL_ENABLE);
+ REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl);
+ bnx2_msi(bp->irq_tbl[0].vector, bnapi);
+ }
+ }
+
+ bp->idle_chk_status_idx = bnapi->last_status_idx;
+}
+
static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
{
struct status_block *sblk = bnapi->status_blk.msi;
work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
- if (unlikely(work_done >= budget))
- break;
-
/* bnapi->last_status_idx is used below to tell the hw how
* much work has been processed, so we must read it before
* checking for more work.
*/
bnapi->last_status_idx = sblk->status_idx;
+
+ if (unlikely(work_done >= budget))
+ break;
+
rmb();
if (likely(!bnx2_has_work(bnapi))) {
netif_rx_complete(bp->dev, napi);
struct dev_addr_list *uc_ptr;
int i;
+ if (!netif_running(dev))
+ return;
+
spin_lock_bh(&bp->phy_lock);
rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
static int
bnx2_init_chip(struct bnx2 *bp)
{
- u32 val;
+ u32 val, mtu;
int rc, i;
/* Make sure the interrupt is not active. */
REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
/* Program the MTU. Also include 4 bytes for CRC32. */
- val = bp->dev->mtu + ETH_HLEN + 4;
+ mtu = bp->dev->mtu;
+ val = mtu + ETH_HLEN + ETH_FCS_LEN;
if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
+ if (mtu < 1500)
+ mtu = 1500;
+
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG, BNX2_RBUF_CONFIG_VAL(mtu));
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG2, BNX2_RBUF_CONFIG2_VAL(mtu));
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
+
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
bp->bnx2_napi[i].last_status_idx = 0;
+ bp->idle_chk_status_idx = 0xffff;
+
bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
/* Set up how to generate a link change interrupt. */
continue;
for (j = 0; j < TX_DESC_CNT; ) {
- struct sw_bd *tx_buf = &txr->tx_buf_ring[j];
+ struct sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
struct sk_buff *skb = tx_buf->skb;
- int k, last;
if (skb == NULL) {
j++;
continue;
}
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(tx_buf, mapping),
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
tx_buf->skb = NULL;
- last = skb_shinfo(skb)->nr_frags;
- for (k = 0; k < last; k++) {
- tx_buf = &txr->tx_buf_ring[j + k + 1];
- pci_unmap_page(bp->pdev,
- pci_unmap_addr(tx_buf, mapping),
- skb_shinfo(skb)->frags[j].size,
- PCI_DMA_TODEVICE);
- }
+ j += skb_shinfo(skb)->nr_frags + 1;
dev_kfree_skb(skb);
- j += k + 1;
}
}
}
}
static int
+bnx2_shutdown_chip(struct bnx2 *bp)
+{
+ u32 reset_code;
+
+ if (bp->flags & BNX2_FLAG_NO_WOL)
+ reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
+ else if (bp->wol)
+ reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+ else
+ reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+
+ return bnx2_reset_chip(bp, reset_code);
+}
+
+static int
bnx2_test_registers(struct bnx2 *bp)
{
int ret;
for (i = 14; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
- map = pci_map_single(bp->pdev, skb->data, pkt_size,
- PCI_DMA_TODEVICE);
+ if (skb_dma_map(&bp->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_kfree_skb(skb);
+ return -EIO;
+ }
+ map = skb_shinfo(skb)->dma_maps[0];
REG_WR(bp, BNX2_HC_COMMAND,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
udelay(5);
- pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
+ skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
dev_kfree_skb(skb);
if (bnx2_get_hw_tx_cons(tx_napi) != txr->tx_prod)
{
u32 bmsr;
+ if (!netif_running(bp->dev))
+ return -ENODEV;
+
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
if (bp->link_up)
return 0;
} else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
u32 bmcr;
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
}
} else
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
if (check_link) {
u32 val;
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
if (bmcr & BMCR_ANENABLE) {
bnx2_enable_forced_2g5(bp);
- bp->current_interval = SERDES_FORCED_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_FORCED_TIMEOUT;
} else {
bnx2_disable_forced_2g5(bp);
bp->serdes_an_pending = 2;
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
}
} else
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
spin_unlock(&bp->phy_lock);
}
if (atomic_read(&bp->intr_sem) != 0)
goto bnx2_restart_timer;
+ if ((bp->flags & (BNX2_FLAG_USING_MSI | BNX2_FLAG_ONE_SHOT_MSI)) ==
+ BNX2_FLAG_USING_MSI)
+ bnx2_chk_missed_msi(bp);
+
bnx2_send_heart_beat(bp);
bp->stats_blk->stat_FwRxDrop =
{
int i, rc;
struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
+ struct net_device *dev = bp->dev;
+ const int len = sizeof(bp->irq_tbl[0].name);
bnx2_setup_msix_tbl(bp);
REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
- strcpy(bp->irq_tbl[i].name, bp->dev->name);
+ snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
bp->irq_tbl[i].handler = bnx2_msi_1shot;
}
struct bnx2 *bp = netdev_priv(dev);
dma_addr_t mapping;
struct tx_bd *txbd;
- struct sw_bd *tx_buf;
+ struct sw_tx_bd *tx_buf;
u32 len, vlan_tag_flags, last_frag, mss;
u16 prod, ring_prod;
int i;
struct bnx2_napi *bnapi;
struct bnx2_tx_ring_info *txr;
struct netdev_queue *txq;
+ struct skb_shared_info *sp;
/* Determine which tx ring we will be placed on */
i = skb_get_queue_mapping(skb);
}
#endif
if ((mss = skb_shinfo(skb)->gso_size)) {
- u32 tcp_opt_len, ip_tcp_len;
+ u32 tcp_opt_len;
struct iphdr *iph;
vlan_tag_flags |= TX_BD_FLAGS_SW_LSO;
mss |= (tcp_off & 0xc) << TX_BD_TCP6_OFF2_SHL;
}
} else {
- if (skb_header_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
- ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
-
iph = ip_hdr(skb);
- iph->check = 0;
- iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
- tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
if (tcp_opt_len || (iph->ihl > 5)) {
vlan_tag_flags |= ((iph->ihl - 5) +
(tcp_opt_len >> 2)) << 8;
} else
mss = 0;
- mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ if (skb_dma_map(&bp->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ sp = skb_shinfo(skb);
+ mapping = sp->dma_maps[0];
tx_buf = &txr->tx_buf_ring[ring_prod];
tx_buf->skb = skb;
- pci_unmap_addr_set(tx_buf, mapping, mapping);
txbd = &txr->tx_desc_ring[ring_prod];
txbd = &txr->tx_desc_ring[ring_prod];
len = frag->size;
- mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
- len, PCI_DMA_TODEVICE);
- pci_unmap_addr_set(&txr->tx_buf_ring[ring_prod],
- mapping, mapping);
+ mapping = sp->dma_maps[i + 1];
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
bnx2_close(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
- u32 reset_code;
cancel_work_sync(&bp->reset_task);
bnx2_disable_int_sync(bp);
bnx2_napi_disable(bp);
del_timer_sync(&bp->timer);
- if (bp->flags & BNX2_FLAG_NO_WOL)
- reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
- else if (bp->wol)
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
- else
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
- bnx2_reset_chip(bp, reset_code);
+ bnx2_shutdown_chip(bp);
bnx2_free_irq(bp);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
{
struct bnx2 *bp = netdev_priv(dev);
struct statistics_block *stats_blk = bp->stats_blk;
- struct net_device_stats *net_stats = &bp->net_stats;
+ struct net_device_stats *net_stats = &dev->stats;
if (bp->stats_blk == NULL) {
return net_stats;
struct bnx2 *bp = netdev_priv(dev);
u32 bmcr;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
if (!(bp->autoneg & AUTONEG_SPEED)) {
return -EINVAL;
}
spin_lock_bh(&bp->phy_lock);
- bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
bp->serdes_an_pending = 1;
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
struct bnx2 *bp = netdev_priv(dev);
int rc;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
/* parameters already validated in ethtool_get_eeprom */
rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
struct bnx2 *bp = netdev_priv(dev);
int rc;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
/* parameters already validated in ethtool_set_eeprom */
rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
bp->autoneg &= ~AUTONEG_FLOW_CTRL;
}
- spin_lock_bh(&bp->phy_lock);
-
- bnx2_setup_phy(bp, bp->phy_port);
-
- spin_unlock_bh(&bp->phy_lock);
+ if (netif_running(dev)) {
+ spin_lock_bh(&bp->phy_lock);
+ bnx2_setup_phy(bp, bp->phy_port);
+ spin_unlock_bh(&bp->phy_lock);
+ }
return 0;
}
{
struct bnx2 *bp = netdev_priv(dev);
+ bnx2_set_power_state(bp, PCI_D0);
+
memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int i;
if ((buf[2] = bnx2_test_loopback(bp)) != 0)
etest->flags |= ETH_TEST_FL_FAILED;
- if (!netif_running(bp->dev)) {
- bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
- }
+ if (!netif_running(bp->dev))
+ bnx2_shutdown_chip(bp);
else {
bnx2_init_nic(bp, 1);
bnx2_netif_start(bp);
etest->flags |= ETH_TEST_FL_FAILED;
}
+ if (!netif_running(bp->dev))
+ bnx2_set_power_state(bp, PCI_D3hot);
}
static void
int i;
u32 save;
+ bnx2_set_power_state(bp, PCI_D0);
+
if (data == 0)
data = 2;
}
REG_WR(bp, BNX2_EMAC_LED, 0);
REG_WR(bp, BNX2_MISC_CFG, save);
+
+ if (!netif_running(dev))
+ bnx2_set_power_state(bp, PCI_D3hot);
+
return 0;
}
poll_bnx2(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
+ int i;
- disable_irq(bp->pdev->irq);
- bnx2_interrupt(bp->pdev->irq, dev);
- enable_irq(bp->pdev->irq);
+ for (i = 0; i < bp->irq_nvecs; i++) {
+ disable_irq(bp->irq_tbl[i].vector);
+ bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]);
+ enable_irq(bp->irq_tbl[i].vector);
+ }
}
#endif
bp->stats_ticks = USEC_PER_SEC & BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
- bp->timer_interval = HZ;
- bp->current_interval = HZ;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
bp->phy_addr = 1;
if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
(CHIP_ID(bp) == CHIP_ID_5708_B0) ||
- (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
+ (CHIP_ID(bp) == CHIP_ID_5708_B1) ||
+ !(REG_RD(bp, BNX2_PCI_CONFIG_3) & BNX2_PCI_CONFIG_3_VAUX_PRESET)) {
bp->flags |= BNX2_FLAG_NO_WOL;
bp->wol = 0;
}
bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
init_timer(&bp->timer);
- bp->timer.expires = RUN_AT(bp->timer_interval);
+ bp->timer.expires = RUN_AT(BNX2_TIMER_INTERVAL);
bp->timer.data = (unsigned long) bp;
bp->timer.function = bnx2_timer;
}
}
+static const struct net_device_ops bnx2_netdev_ops = {
+ .ndo_open = bnx2_open,
+ .ndo_start_xmit = bnx2_start_xmit,
+ .ndo_stop = bnx2_close,
+ .ndo_get_stats = bnx2_get_stats,
+ .ndo_set_rx_mode = bnx2_set_rx_mode,
+ .ndo_do_ioctl = bnx2_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = bnx2_change_mac_addr,
+ .ndo_change_mtu = bnx2_change_mtu,
+ .ndo_tx_timeout = bnx2_tx_timeout,
+#ifdef BCM_VLAN
+ .ndo_vlan_rx_register = bnx2_vlan_rx_register,
+#endif
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+ .ndo_poll_controller = poll_bnx2,
+#endif
+};
+
static int __devinit
bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct bnx2 *bp;
int rc;
char str[40];
- DECLARE_MAC_BUF(mac);
if (version_printed++ == 0)
printk(KERN_INFO "%s", version);
return rc;
}
- dev->open = bnx2_open;
- dev->hard_start_xmit = bnx2_start_xmit;
- dev->stop = bnx2_close;
- dev->get_stats = bnx2_get_stats;
- dev->set_rx_mode = bnx2_set_rx_mode;
- dev->do_ioctl = bnx2_ioctl;
- dev->set_mac_address = bnx2_change_mac_addr;
- dev->change_mtu = bnx2_change_mtu;
- dev->tx_timeout = bnx2_tx_timeout;
+ dev->netdev_ops = &bnx2_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef BCM_VLAN
- dev->vlan_rx_register = bnx2_vlan_rx_register;
-#endif
dev->ethtool_ops = &bnx2_ethtool_ops;
bp = netdev_priv(dev);
bnx2_init_napi(bp);
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
- dev->poll_controller = poll_bnx2;
-#endif
-
pci_set_drvdata(pdev, dev);
memcpy(dev->dev_addr, bp->mac_addr, 6);
}
printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
- "IRQ %d, node addr %s\n",
+ "IRQ %d, node addr %pM\n",
dev->name,
board_info[ent->driver_data].name,
((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
((CHIP_ID(bp) & 0x0ff0) >> 4),
bnx2_bus_string(bp, str),
dev->base_addr,
- bp->pdev->irq, print_mac(mac, dev->dev_addr));
+ bp->pdev->irq, dev->dev_addr);
return 0;
}
{
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
- u32 reset_code;
/* PCI register 4 needs to be saved whether netif_running() or not.
* MSI address and data need to be saved if using MSI and
bnx2_netif_stop(bp);
netif_device_detach(dev);
del_timer_sync(&bp->timer);
- if (bp->flags & BNX2_FLAG_NO_WOL)
- reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
- else if (bp->wol)
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
- else
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
- bnx2_reset_chip(bp, reset_code);
+ bnx2_shutdown_chip(bp);
bnx2_free_skbs(bp);
bnx2_set_power_state(bp, pci_choose_state(pdev, state));
return 0;