diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom')
20 files changed, 314 insertions, 475 deletions
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 90e54d5..9b017d9 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -596,7 +596,6 @@ static void b44_timer(unsigned long __opaque) static void b44_tx(struct b44 *bp) { u32 cur, cons; - unsigned bytes_compl = 0, pkts_compl = 0; cur = br32(bp, B44_DMATX_STAT) & DMATX_STAT_CDMASK; cur /= sizeof(struct dma_desc); @@ -613,14 +612,9 @@ static void b44_tx(struct b44 *bp) skb->len, DMA_TO_DEVICE); rp->skb = NULL; - - bytes_compl += skb->len; - pkts_compl++; - dev_kfree_skb_irq(skb); } - netdev_completed_queue(bp->dev, pkts_compl, bytes_compl); bp->tx_cons = cons; if (netif_queue_stopped(bp->dev) && TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH) @@ -1024,8 +1018,6 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev) if (bp->flags & B44_FLAG_REORDER_BUG) br32(bp, B44_DMATX_PTR); - netdev_sent_queue(dev, skb->len); - if (TX_BUFFS_AVAIL(bp) < 1) netif_stop_queue(dev); @@ -1424,8 +1416,6 @@ static void b44_init_hw(struct b44 *bp, int reset_kind) val = br32(bp, B44_ENET_CTRL); bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); - - netdev_reset_queue(bp->dev); } static int b44_open(struct net_device *dev) @@ -2111,7 +2101,7 @@ static int b44_get_invariants(struct b44 *bp) * valid PHY address. */ bp->phy_addr &= 0x1F; - memcpy(bp->dev->dev_addr, addr, ETH_ALEN); + memcpy(bp->dev->dev_addr, addr, 6); if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ pr_err("Invalid MAC address found in EEPROM\n"); @@ -2193,7 +2183,8 @@ static int b44_init_one(struct ssb_device *sdev, goto err_out_free_dev; } - if (dma_set_mask_and_coherent(sdev->dma_dev, DMA_BIT_MASK(30))) { + if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) || + dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) { dev_err(sdev->dev, "Required 30BIT DMA mask unsupported by the system\n"); goto err_out_powerdown; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index e2aa09c..249468f 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -149,8 +149,6 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, dma_desc->ctl0 = cpu_to_le32(ctl0); dma_desc->ctl1 = cpu_to_le32(ctl1); - netdev_sent_queue(net_dev, skb->len); - wmb(); /* Increase ring->end to point empty slot. We tell hardware the first @@ -180,7 +178,6 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) struct device *dma_dev = bgmac->core->dma_dev; int empty_slot; bool freed = false; - unsigned bytes_compl = 0, pkts_compl = 0; /* The last slot that hardware didn't consume yet */ empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS); @@ -198,9 +195,6 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) slot->skb->len, DMA_TO_DEVICE); slot->dma_addr = 0; - bytes_compl += slot->skb->len; - pkts_compl++; - /* Free memory! :) */ dev_kfree_skb(slot->skb); slot->skb = NULL; @@ -214,8 +208,6 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) freed = true; } - netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl); - if (freed && netif_queue_stopped(bgmac->net_dev)) netif_wake_queue(bgmac->net_dev); } @@ -252,59 +244,31 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, struct bgmac_slot_info *slot) { struct device *dma_dev = bgmac->core->dma_dev; - struct sk_buff *skb; - dma_addr_t dma_addr; struct bgmac_rx_header *rx; /* Alloc skb */ - skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); - if (!skb) + slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); + if (!slot->skb) return -ENOMEM; /* Poison - if everything goes fine, hardware will overwrite it */ - rx = (struct bgmac_rx_header *)skb->data; + rx = (struct bgmac_rx_header *)slot->skb->data; rx->len = cpu_to_le16(0xdead); rx->flags = cpu_to_le16(0xbeef); /* Map skb for the DMA */ - dma_addr = dma_map_single(dma_dev, skb->data, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_dev, dma_addr)) { + slot->dma_addr = dma_map_single(dma_dev, slot->skb->data, + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(dma_dev, slot->dma_addr)) { bgmac_err(bgmac, "DMA mapping error\n"); - dev_kfree_skb(skb); return -ENOMEM; } - - /* Update the slot */ - slot->skb = skb; - slot->dma_addr = dma_addr; - if (slot->dma_addr & 0xC0000000) bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); return 0; } -static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, - struct bgmac_dma_ring *ring, int desc_idx) -{ - struct bgmac_dma_desc *dma_desc = ring->cpu_base + desc_idx; - u32 ctl0 = 0, ctl1 = 0; - - if (desc_idx == ring->num_slots - 1) - ctl0 |= BGMAC_DESC_CTL0_EOT; - ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; - /* Is there any BGMAC device that requires extension? */ - /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & - * B43_DMA64_DCTL1_ADDREXT_MASK; - */ - - dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[desc_idx].dma_addr)); - dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr)); - dma_desc->ctl0 = cpu_to_le32(ctl0); - dma_desc->ctl1 = cpu_to_le32(ctl1); -} - static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, int weight) { @@ -323,6 +287,7 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, struct device *dma_dev = bgmac->core->dma_dev; struct bgmac_slot_info *slot = &ring->slots[ring->start]; struct sk_buff *skb = slot->skb; + struct sk_buff *new_skb; struct bgmac_rx_header *rx; u16 len, flags; @@ -335,51 +300,38 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, len = le16_to_cpu(rx->len); flags = le16_to_cpu(rx->flags); - do { - dma_addr_t old_dma_addr = slot->dma_addr; - int err; - - /* Check for poison and drop or pass the packet */ - if (len == 0xdead && flags == 0xbeef) { - bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", - ring->start); - dma_sync_single_for_device(dma_dev, - slot->dma_addr, - BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); - break; - } - + /* Check for poison and drop or pass the packet */ + if (len == 0xdead && flags == 0xbeef) { + bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", + ring->start); + } else { /* Omit CRC. */ len -= ETH_FCS_LEN; - /* Prepare new skb as replacement */ - err = bgmac_dma_rx_skb_for_slot(bgmac, slot); - if (err) { - /* Poison the old skb */ - rx->len = cpu_to_le16(0xdead); - rx->flags = cpu_to_le16(0xbeef); - - dma_sync_single_for_device(dma_dev, - slot->dma_addr, - BGMAC_RX_BUF_SIZE, - DMA_FROM_DEVICE); - break; + new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len); + if (new_skb) { + skb_put(new_skb, len); + skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET, + new_skb->data, + len); + skb_checksum_none_assert(skb); + new_skb->protocol = + eth_type_trans(new_skb, bgmac->net_dev); + netif_receive_skb(new_skb); + handled++; + } else { + bgmac->net_dev->stats.rx_dropped++; + bgmac_err(bgmac, "Allocation of skb for copying packet failed!\n"); } - bgmac_dma_rx_setup_desc(bgmac, ring, ring->start); - /* Unmap old skb, we'll pass it to the netfif */ - dma_unmap_single(dma_dev, old_dma_addr, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - - skb_put(skb, BGMAC_RX_FRAME_OFFSET + len); - skb_pull(skb, BGMAC_RX_FRAME_OFFSET); + /* Poison the old skb */ + rx->len = cpu_to_le16(0xdead); + rx->flags = cpu_to_le16(0xbeef); + } - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, bgmac->net_dev); - netif_receive_skb(skb); - handled++; - } while (0); + /* Make it back accessible to the hardware */ + dma_sync_single_for_device(dma_dev, slot->dma_addr, + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); if (++ring->start >= BGMAC_RX_RING_SLOTS) ring->start = 0; @@ -543,6 +495,8 @@ err_dma_free: static void bgmac_dma_init(struct bgmac *bgmac) { struct bgmac_dma_ring *ring; + struct bgmac_dma_desc *dma_desc; + u32 ctl0, ctl1; int i; for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { @@ -575,8 +529,23 @@ static void bgmac_dma_init(struct bgmac *bgmac) if (ring->unaligned) bgmac_dma_rx_enable(bgmac, ring); - for (j = 0; j < ring->num_slots; j++) - bgmac_dma_rx_setup_desc(bgmac, ring, j); + for (j = 0, dma_desc = ring->cpu_base; j < ring->num_slots; + j++, dma_desc++) { + ctl0 = ctl1 = 0; + + if (j == ring->num_slots - 1) + ctl0 |= BGMAC_DESC_CTL0_EOT; + ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; + /* Is there any BGMAC device that requires extension? */ + /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & + * B43_DMA64_DCTL1_ADDREXT_MASK; + */ + + dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[j].dma_addr)); + dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[j].dma_addr)); + dma_desc->ctl0 = cpu_to_le32(ctl0); + dma_desc->ctl1 = cpu_to_le32(ctl1); + } bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, ring->index_base + @@ -1019,8 +988,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac) bgmac_miiconfig(bgmac); bgmac_phy_init(bgmac); - netdev_reset_queue(bgmac->net_dev); - bgmac->int_status = 0; } diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index d9980ad..e838a3f 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -5761,8 +5761,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) if (!skb) return -ENOMEM; packet = skb_put(skb, pkt_size); - memcpy(packet, bp->dev->dev_addr, ETH_ALEN); - memset(packet + ETH_ALEN, 0x0, 8); + memcpy(packet, bp->dev->dev_addr, 6); + memset(packet + 6, 0x0, 8); for (i = 14; i < pkt_size; i++) packet[i] = (unsigned char) (i & 0xff); @@ -8413,6 +8413,7 @@ err_out_release: err_out_disable: pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); err_out: return rc; @@ -8513,7 +8514,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); - memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); + memcpy(dev->dev_addr, bp->mac_addr, 6); dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO_ECN | @@ -8545,6 +8546,7 @@ error: pci_iounmap(pdev, bp->regview); pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); err_free: free_netdev(dev); return rc; @@ -8576,6 +8578,7 @@ bnx2_remove_one(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); } static int diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index a1f66e2..c5e375d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1376,6 +1376,7 @@ enum { BNX2X_SP_RTNL_RX_MODE, BNX2X_SP_RTNL_HYPERVISOR_VLAN, BNX2X_SP_RTNL_TX_STOP, + BNX2X_SP_RTNL_TX_RESUME, }; struct bnx2x_prev_path_list { @@ -1545,7 +1546,6 @@ struct bnx2x { #define IS_VF_FLAG (1 << 22) #define INTERRUPTS_ENABLED_FLAG (1 << 23) #define BC_SUPPORTS_RMMOD_CMD (1 << 24) -#define HAS_PHYS_PORT_ID (1 << 25) #define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG) @@ -1876,8 +1876,6 @@ struct bnx2x { u32 dump_preset_idx; bool stats_started; struct semaphore stats_sema; - - u8 phys_port_id[ETH_ALEN]; }; /* Tx queues may be less or equal to Rx queues */ @@ -2234,7 +2232,7 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, #define BNX2X_NUM_TESTS_SF 7 #define BNX2X_NUM_TESTS_MF 3 #define BNX2X_NUM_TESTS(bp) (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \ - IS_VF(bp) ? 0 : BNX2X_NUM_TESTS_SF) + BNX2X_NUM_TESTS_SF) #define BNX2X_PHY_LOOPBACK 0 #define BNX2X_MAC_LOOPBACK 1 @@ -2494,6 +2492,12 @@ enum { #define NUM_MACS 8 +enum bnx2x_pci_bus_speed { + BNX2X_PCI_LINK_SPEED_2500 = 2500, + BNX2X_PCI_LINK_SPEED_5000 = 5000, + BNX2X_PCI_LINK_SPEED_8000 = 8000 +}; + void bnx2x_set_local_cmng(struct bnx2x *bp); #define MCPR_SCRATCH_BASE(bp) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index ec96130..4ab4c89 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2545,6 +2545,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } + /* Allocated memory for FW statistics */ + if (bnx2x_alloc_fw_stats_mem(bp)) + LOAD_ERROR_EXIT(bp, load_error0); + /* need to be done after alloc mem, since it's self adjusting to amount * of memory available for RSS queues */ @@ -2554,10 +2558,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) LOAD_ERROR_EXIT(bp, load_error0); } - /* Allocated memory for FW statistics */ - if (bnx2x_alloc_fw_stats_mem(bp)) - LOAD_ERROR_EXIT(bp, load_error0); - /* request pf to initialize status blocks */ if (IS_VF(bp)) { rc = bnx2x_vfpf_init(bp); @@ -2812,8 +2812,8 @@ load_error1: if (IS_PF(bp)) bnx2x_clear_pf_load(bp); load_error0: - bnx2x_free_fw_stats_mem(bp); bnx2x_free_fp_mem(bp); + bnx2x_free_fw_stats_mem(bp); bnx2x_free_mem(bp); return rc; @@ -2959,10 +2959,6 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) bp->port.pmf = 0; - /* clear pending work in rtnl task */ - bp->sp_rtnl_state = 0; - smp_mb(); - /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); if (CNIC_LOADED(bp)) @@ -3260,16 +3256,14 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) if (prot == IPPROTO_TCP) rc |= XMIT_CSUM_TCP; - if (skb_is_gso(skb)) { - if (skb_is_gso_v6(skb)) { - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP); - if (rc & XMIT_CSUM_ENC) - rc |= XMIT_GSO_ENC_V6; - } else { - rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP); - if (rc & XMIT_CSUM_ENC) - rc |= XMIT_GSO_ENC_V4; - } + if (skb_is_gso_v6(skb)) { + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V6; + } else if (skb_is_gso(skb)) { + rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V4; } return rc; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index fdace20..fcf2761 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -778,6 +778,11 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) /* ets may affect cmng configuration: reinit it in hw */ bnx2x_set_local_cmng(bp); + + set_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state); + + schedule_delayed_work(&bp->sp_rtnl_task, 0); + return; case BNX2X_DCBX_STATE_TX_RELEASED: DP(BNX2X_MSG_DCB, "BNX2X_DCBX_STATE_TX_RELEASED\n"); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 32d0f14..e8efa1c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -639,9 +639,6 @@ static int bnx2x_get_regs_len(struct net_device *dev) struct bnx2x *bp = netdev_priv(dev); int regdump_len = 0; - if (IS_VF(bp)) - return 0; - regdump_len = __bnx2x_get_regs_len(bp); regdump_len *= 4; regdump_len += sizeof(struct dump_header); @@ -2867,16 +2864,9 @@ static void bnx2x_self_test(struct net_device *dev, memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp)); - if (bnx2x_test_nvram(bp) != 0) { - if (!IS_MF(bp)) - buf[4] = 1; - else - buf[0] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - if (!netif_running(dev)) { - DP(BNX2X_MSG_ETHTOOL, "Interface is down\n"); + DP(BNX2X_MSG_ETHTOOL, + "Can't perform self-test when interface is down\n"); return; } @@ -2938,7 +2928,13 @@ static void bnx2x_self_test(struct net_device *dev, /* wait until link state is restored */ bnx2x_wait_for_link(bp, link_up, is_serdes); } - + if (bnx2x_test_nvram(bp) != 0) { + if (!IS_MF(bp)) + buf[4] = 1; + else + buf[0] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } if (bnx2x_test_intr(bp) != 0) { if (!IS_MF(bp)) buf[5] = 1; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index cf1df8b..32767f6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -172,7 +172,6 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_LED_MAC4 0x000c0000 #define SHARED_HW_CFG_LED_PHY8 0x000d0000 #define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000 - #define SHARED_HW_CFG_LED_EXTPHY2 0x000f0000 #define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 20dcc02..5146822 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -3122,7 +3122,7 @@ static void bnx2x_bsc_module_sel(struct link_params *params) } static int bnx2x_bsc_read(struct link_params *params, - struct bnx2x *bp, + struct bnx2x_phy *phy, u8 sl_devid, u16 sl_addr, u8 lc_addr, @@ -3131,6 +3131,7 @@ static int bnx2x_bsc_read(struct link_params *params, { u32 val, i; int rc = 0; + struct bnx2x *bp = params->bp; if (xfer_cnt > 16) { DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n", @@ -6370,15 +6371,9 @@ int bnx2x_set_led(struct link_params *params, * intended override. */ break; - } else { - u32 nig_led_mode = ((params->hw_led_mode << - SHARED_HW_CFG_LED_MODE_SHIFT) == - SHARED_HW_CFG_LED_EXTPHY2) ? - (SHARED_HW_CFG_LED_PHY1 >> - SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode; + } else REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - nig_led_mode); - } + hw_led_mode); REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); /* Set blinking rate to ~15.9Hz */ @@ -7922,7 +7917,7 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, usleep_range(1000, 2000); bnx2x_warpcore_power_module(params, 1); } - rc = bnx2x_bsc_read(params, bp, dev_addr, addr32, 0, byte_cnt, + rc = bnx2x_bsc_read(params, phy, dev_addr, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -10658,18 +10653,10 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, 0x40); } else { - /* EXTPHY2 LED mode indicate that the 100M/1G/10G LED - * sources are all wired through LED1, rather than only - * 10G in other modes. - */ - val = ((params->hw_led_mode << - SHARED_HW_CFG_LED_MODE_SHIFT) == - SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80; - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, - val); + 0x80); /* Tell LED3 to blink on source */ bnx2x_cl45_read(bp, phy, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 814d0ec..b42f89c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -577,9 +577,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp)); if (rc) { BNX2X_ERR("DMAE returned failure %d\n", rc); -#ifdef BNX2X_STOP_ON_ERROR bnx2x_panic(); -#endif } } @@ -616,9 +614,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp)); if (rc) { BNX2X_ERR("DMAE returned failure %d\n", rc); -#ifdef BNX2X_STOP_ON_ERROR bnx2x_panic(); -#endif } } @@ -5235,18 +5231,18 @@ static void bnx2x_eq_int(struct bnx2x *bp) case EVENT_RING_OPCODE_STOP_TRAFFIC: DP(BNX2X_MSG_SP | BNX2X_MSG_DCB, "got STOP TRAFFIC\n"); - bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_TX_STOP)) break; + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); goto next_spqe; case EVENT_RING_OPCODE_START_TRAFFIC: DP(BNX2X_MSG_SP | BNX2X_MSG_DCB, "got START TRAFFIC\n"); - bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_TX_START)) break; + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); goto next_spqe; case EVENT_RING_OPCODE_FUNCTION_UPDATE: @@ -9356,10 +9352,6 @@ static int bnx2x_process_kill(struct bnx2x *bp, bool global) bnx2x_process_kill_chip_reset(bp, global); barrier(); - /* clear errors in PGB */ - if (!CHIP_IS_E1x(bp)) - REG_WR(bp, PGLUE_B_REG_LATCHED_ERRORS_CLR, 0x7f); - /* Recover after reset: */ /* MCP */ if (global && bnx2x_reset_mcp_comp(bp, val)) @@ -9714,10 +9706,11 @@ sp_rtnl_not_reset: &bp->sp_rtnl_state)) bnx2x_pf_set_vfs_vlan(bp); - if (test_and_clear_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state)) { + if (test_and_clear_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state)) bnx2x_dcbx_stop_hw_tx(bp); + + if (test_and_clear_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state)) bnx2x_dcbx_resume_hw_tx(bp); - } /* work which needs rtnl lock not-taken (as it takes the lock itself and * can be called from other contexts as well) @@ -9923,7 +9916,7 @@ static int bnx2x_prev_path_mark_eeh(struct bnx2x *bp) static bool bnx2x_prev_is_path_marked(struct bnx2x *bp) { struct bnx2x_prev_path_list *tmp_list; - bool rc = false; + int rc = false; if (down_trylock(&bnx2x_prev_sem)) return false; @@ -11193,14 +11186,6 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp) bnx2x_get_cnic_mac_hwinfo(bp); } - if (!BP_NOMCP(bp)) { - /* Read physical port identifier from shmem */ - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); - bnx2x_set_mac_buf(bp->phys_port_id, val, val2); - bp->flags |= HAS_PHYS_PORT_ID; - } - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr)) @@ -11799,7 +11784,7 @@ static int bnx2x_open(struct net_device *dev) rc = bnx2x_nic_load(bp, LOAD_OPEN); if (rc) return rc; - return 0; + return bnx2x_open_epilog(bp); } /* called with rtnl_lock */ @@ -12097,20 +12082,6 @@ static int bnx2x_validate_addr(struct net_device *dev) return 0; } -static int bnx2x_get_phys_port_id(struct net_device *netdev, - struct netdev_phys_port_id *ppid) -{ - struct bnx2x *bp = netdev_priv(netdev); - - if (!(bp->flags & HAS_PHYS_PORT_ID)) - return -EOPNOTSUPP; - - ppid->id_len = sizeof(bp->phys_port_id); - memcpy(ppid->id, bp->phys_port_id, ppid->id_len); - - return 0; -} - static const struct net_device_ops bnx2x_netdev_ops = { .ndo_open = bnx2x_open, .ndo_stop = bnx2x_close, @@ -12140,15 +12111,18 @@ static const struct net_device_ops bnx2x_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll = bnx2x_low_latency_recv, #endif - .ndo_get_phys_port_id = bnx2x_get_phys_port_id, }; static int bnx2x_set_coherency_mask(struct bnx2x *bp) { struct device *dev = &bp->pdev->dev; - if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) != 0 && - dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)) != 0) { + if (dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) { + if (dma_set_coherent_mask(dev, DMA_BIT_MASK(64)) != 0) { + dev_err(dev, "dma_set_coherent_mask failed, aborting\n"); + return -EIO; + } + } else if (dma_set_mask(dev, DMA_BIT_MASK(32)) != 0) { dev_err(dev, "System does not support DMA, aborting\n"); return -EIO; } @@ -12300,13 +12274,10 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX; if (!CHIP_IS_E1x(bp)) { - dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT; + dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL; dev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | - NETIF_F_GSO_IPIP | - NETIF_F_GSO_SIT | NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL; } @@ -12339,11 +12310,34 @@ err_out_release: err_out_disable: pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); err_out: return rc; } +static void bnx2x_get_pcie_width_speed(struct bnx2x *bp, int *width, + enum bnx2x_pci_bus_speed *speed) +{ + u32 link_speed, val = 0; + + pci_read_config_dword(bp->pdev, PCICFG_LINK_CONTROL, &val); + *width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT; + + link_speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; + + switch (link_speed) { + case 3: + *speed = BNX2X_PCI_LINK_SPEED_8000; + break; + case 2: + *speed = BNX2X_PCI_LINK_SPEED_5000; + break; + default: + *speed = BNX2X_PCI_LINK_SPEED_2500; + } +} + static int bnx2x_check_firmware(struct bnx2x *bp) { const struct firmware *firmware = bp->firmware; @@ -12700,8 +12694,8 @@ static int bnx2x_init_one(struct pci_dev *pdev, { struct net_device *dev = NULL; struct bnx2x *bp; - enum pcie_link_width pcie_width; - enum pci_bus_speed pcie_speed; + int pcie_width; + enum bnx2x_pci_bus_speed pcie_speed; int rc, max_non_def_sbs; int rx_count, tx_count, rss_count, doorbell_size; int max_cos_est; @@ -12850,19 +12844,18 @@ static int bnx2x_init_one(struct pci_dev *pdev, dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); rtnl_unlock(); } - if (pcie_get_minimum_link(bp->pdev, &pcie_speed, &pcie_width) || - pcie_speed == PCI_SPEED_UNKNOWN || - pcie_width == PCIE_LNK_WIDTH_UNKNOWN) - BNX2X_DEV_INFO("Failed to determine PCI Express Bandwidth\n"); - else - BNX2X_DEV_INFO( - "%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n", + + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); + BNX2X_DEV_INFO("got pcie width %d and speed %d\n", + pcie_width, pcie_speed); + + BNX2X_DEV_INFO("%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), pcie_width, - pcie_speed == PCIE_SPEED_2_5GT ? "2.5GHz" : - pcie_speed == PCIE_SPEED_5_0GT ? "5.0GHz" : - pcie_speed == PCIE_SPEED_8_0GT ? "8.0GHz" : + pcie_speed == BNX2X_PCI_LINK_SPEED_2500 ? "2.5GHz" : + pcie_speed == BNX2X_PCI_LINK_SPEED_5000 ? "5.0GHz" : + pcie_speed == BNX2X_PCI_LINK_SPEED_8000 ? "8.0GHz" : "Unknown", dev->base_addr, bp->pdev->irq, dev->dev_addr); @@ -12881,6 +12874,7 @@ init_one_exit: pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); return rc; } @@ -12963,6 +12957,7 @@ static void __bnx2x_remove(struct pci_dev *pdev, pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); } static void bnx2x_remove_one(struct pci_dev *pdev) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 3efbb35..5ecf267 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -2864,17 +2864,6 @@ #define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ 0x9430 #define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE 0x9434 #define PGLUE_B_REG_INTERNAL_VFID_ENABLE 0x9438 -/* [W 7] Writing 1 to each bit in this register clears a corresponding error - * details register and enables logging new error details. Bit 0 - clears - * INCORRECT_RCV_DETAILS; Bit 1 - clears RX_ERR_DETAILS; Bit 2 - clears - * TX_ERR_WR_ADD_31_0 TX_ERR_WR_ADD_63_32 TX_ERR_WR_DETAILS - * TX_ERR_WR_DETAILS2 TX_ERR_RD_ADD_31_0 TX_ERR_RD_ADD_63_32 - * TX_ERR_RD_DETAILS TX_ERR_RD_DETAILS2 TX_ERR_WR_DETAILS_ICPL; Bit 3 - - * clears VF_LENGTH_VIOLATION_DETAILS. Bit 4 - clears - * VF_GRC_SPACE_VIOLATION_DETAILS. Bit 5 - clears RX_TCPL_ERR_DETAILS. Bit 6 - * - clears TCPL_IN_TWO_RCBS_DETAILS. */ -#define PGLUE_B_REG_LATCHED_ERRORS_CLR 0x943c - /* [R 9] Interrupt register #0 read */ #define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 /* [RC 9] Interrupt register #0 read clear */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 32c92ab..9fbeee5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1217,6 +1217,9 @@ static void bnx2x_set_one_vlan_mac_e1h(struct bnx2x *bp, ETH_VLAN_FILTER_CLASSIFY, config); } +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + /** * bnx2x_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element * diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 0216d59..bf08ad6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -2018,8 +2018,6 @@ failed: void bnx2x_iov_remove_one(struct bnx2x *bp) { - int vf_idx; - /* if SRIOV is not enabled there's nothing to do */ if (!IS_SRIOV(bp)) return; @@ -2028,18 +2026,6 @@ void bnx2x_iov_remove_one(struct bnx2x *bp) pci_disable_sriov(bp->pdev); DP(BNX2X_MSG_IOV, "sriov disabled\n"); - /* disable access to all VFs */ - for (vf_idx = 0; vf_idx < bp->vfdb->sriov.total; vf_idx++) { - bnx2x_pretend_func(bp, - HW_VF_HANDLE(bp, - bp->vfdb->sriov.first_vf_in_pf + - vf_idx)); - DP(BNX2X_MSG_IOV, "disabling internal access for vf %d\n", - bp->vfdb->sriov.first_vf_in_pf + vf_idx); - bnx2x_vf_enable_internal(bp, 0); - bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); - } - /* free vf database */ __bnx2x_iov_free_vfdb(bp); } @@ -2816,7 +2802,7 @@ struct set_vf_state_cookie { u8 state; }; -static void bnx2x_set_vf_state(void *cookie) +void bnx2x_set_vf_state(void *cookie) { struct set_vf_state_cookie *p = (struct set_vf_state_cookie *)cookie; @@ -3211,7 +3197,7 @@ int bnx2x_enable_sriov(struct bnx2x *bp) * the "acquire" messages to appear on the VF PF channel. */ DP(BNX2X_MSG_IOV, "about to call enable sriov\n"); - bnx2x_disable_sriov(bp); + pci_disable_sriov(bp->pdev); rc = pci_enable_sriov(bp->pdev, req_vfs); if (rc) { BNX2X_ERR("pci_enable_sriov failed with %d\n", rc); @@ -3239,9 +3225,8 @@ void bnx2x_disable_sriov(struct bnx2x *bp) pci_disable_sriov(bp->pdev); } -static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, - struct bnx2x_virtf **vf, - struct pf_vf_bulletin_content **bulletin) +int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, struct bnx2x_virtf **vf, + struct pf_vf_bulletin_content **bulletin) { if (bp->state != BNX2X_STATE_OPEN) { BNX2X_ERR("vf ndo called though PF is down\n"); @@ -3657,6 +3642,29 @@ alloc_mem_err: return -ENOMEM; } +int bnx2x_open_epilog(struct bnx2x *bp) +{ + /* Enable sriov via delayed work. This must be done via delayed work + * because it causes the probe of the vf devices to be run, which invoke + * register_netdevice which must have rtnl lock taken. As we are holding + * the lock right now, that could only work if the probe would not take + * the lock. However, as the probe of the vf may be called from other + * contexts as well (such as passthrough to vm fails) it can't assume + * the lock is being held for it. Using delayed work here allows the + * probe code to simply take the lock (i.e. wait for it to be released + * if it is being held). We only want to do this if the number of VFs + * was set before PF driver was loaded. + */ + if (IS_SRIOV(bp) && BNX2X_NR_VIRTFN(bp)) { + smp_mb__before_clear_bit(); + set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state); + smp_mb__after_clear_bit(); + schedule_delayed_work(&bp->sp_rtnl_task, 0); + } + + return 0; +} + void bnx2x_iov_channel_down(struct bnx2x *bp) { int vf_idx; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 1ff6a93..059f0d4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -782,6 +782,7 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp) void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs); void bnx2x_iov_channel_down(struct bnx2x *bp); +int bnx2x_open_epilog(struct bnx2x *bp); #else /* CONFIG_BNX2X_SRIOV */ @@ -841,6 +842,7 @@ static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {} +static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; } #endif /* CONFIG_BNX2X_SRIOV */ #endif /* bnx2x_sriov.h */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index efa8a15..28757df 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -60,30 +60,6 @@ void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv) mutex_unlock(&bp->vf2pf_mutex); } -/* Finds a TLV by type in a TLV buffer; If found, returns pointer to the TLV */ -static void *bnx2x_search_tlv_list(struct bnx2x *bp, void *tlvs_list, - enum channel_tlvs req_tlv) -{ - struct channel_tlv *tlv = (struct channel_tlv *)tlvs_list; - - do { - if (tlv->type == req_tlv) - return tlv; - - if (!tlv->length) { - BNX2X_ERR("Found TLV with length 0\n"); - return NULL; - } - - tlvs_list += tlv->length; - tlv = (struct channel_tlv *)tlvs_list; - } while (tlv->type != CHANNEL_TLV_LIST_END); - - DP(BNX2X_MSG_IOV, "TLV list does not contain %d TLV\n", req_tlv); - - return NULL; -} - /* list the types and lengths of the tlvs on the buffer */ void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list) { @@ -152,7 +128,7 @@ static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping) if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) { DP(BNX2X_MSG_IOV, "detecting channel down. Aborting message\n"); *done = PFVF_STATUS_SUCCESS; - return -EINVAL; + return 0; } /* Write message address */ @@ -220,7 +196,6 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) int rc = 0, attempts = 0; struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire; struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp; - struct vfpf_port_phys_id_resp_tlv *phys_port_resp; u32 vf_id; bool resources_acquired = false; @@ -244,14 +219,8 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) /* pf 2 vf bulletin board address */ req->bulletin_addr = bp->pf2vf_bulletin_mapping; - /* Request physical port identifier */ - bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, - CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv)); - /* add list termination tlv */ - bnx2x_add_tlv(bp, req, - req->first_tlv.tl.length + sizeof(struct channel_tlv), - CHANNEL_TLV_LIST_END, + bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); /* output tlvs list */ @@ -318,15 +287,6 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) } } - /* Retrieve physical port id (if possible) */ - phys_port_resp = (struct vfpf_port_phys_id_resp_tlv *) - bnx2x_search_tlv_list(bp, resp, - CHANNEL_TLV_PHYS_PORT_ID); - if (phys_port_resp) { - memcpy(bp->phys_port_id, phys_port_resp->id, ETH_ALEN); - bp->flags |= HAS_PHYS_PORT_ID; - } - /* get HW info */ bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff); bp->link_params.chip_id = bp->common.chip_id; @@ -1023,59 +983,53 @@ static int bnx2x_copy32_vf_dmae(struct bnx2x *bp, u8 from_vf, return bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp)); } -static void bnx2x_vf_mbx_resp_single_tlv(struct bnx2x *bp, - struct bnx2x_virtf *vf) +static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf) { struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index); + u64 vf_addr; + dma_addr_t pf_addr; u16 length, type; + int rc; + struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp; /* prepare response */ type = mbx->first_tlv.tl.type; length = type == CHANNEL_TLV_ACQUIRE ? sizeof(struct pfvf_acquire_resp_tlv) : sizeof(struct pfvf_general_resp_tlv); - bnx2x_add_tlv(bp, &mbx->msg->resp, 0, type, length); - bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END, + bnx2x_add_tlv(bp, resp, 0, type, length); + resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc); + bnx2x_add_tlv(bp, resp, length, CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); -} - -static void bnx2x_vf_mbx_resp_send_msg(struct bnx2x *bp, - struct bnx2x_virtf *vf) -{ - struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index); - struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp; - dma_addr_t pf_addr; - u64 vf_addr; - int rc; - bnx2x_dp_tlv_list(bp, resp); DP(BNX2X_MSG_IOV, "mailbox vf address hi 0x%x, lo 0x%x, offset 0x%x\n", mbx->vf_addr_hi, mbx->vf_addr_lo, mbx->first_tlv.resp_msg_offset); - resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc); - /* send response */ vf_addr = HILO_U64(mbx->vf_addr_hi, mbx->vf_addr_lo) + mbx->first_tlv.resp_msg_offset; pf_addr = mbx->msg_mapping + offsetof(struct bnx2x_vf_mbx_msg, resp); - /* Copy the response buffer. The first u64 is written afterwards, as - * the vf is sensitive to the header being written + /* copy the response body, if there is one, before the header, as the vf + * is sensitive to the header being written */ - vf_addr += sizeof(u64); - pf_addr += sizeof(u64); - rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid, - U64_HI(vf_addr), - U64_LO(vf_addr), - (sizeof(union pfvf_tlvs) - sizeof(u64))/4); - if (rc) { - BNX2X_ERR("Failed to copy response body to VF %d\n", - vf->abs_vfid); - goto mbx_error; + if (resp->hdr.tl.length > sizeof(u64)) { + length = resp->hdr.tl.length - sizeof(u64); + vf_addr += sizeof(u64); + pf_addr += sizeof(u64); + rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid, + U64_HI(vf_addr), + U64_LO(vf_addr), + length/4); + if (rc) { + BNX2X_ERR("Failed to copy response body to VF %d\n", + vf->abs_vfid); + goto mbx_error; + } + vf_addr -= sizeof(u64); + pf_addr -= sizeof(u64); } - vf_addr -= sizeof(u64); - pf_addr -= sizeof(u64); /* ack the FW */ storm_memset_vf_mbx_ack(bp, vf->abs_vfid); @@ -1106,36 +1060,6 @@ mbx_error: bnx2x_vf_release(bp, vf, false); /* non blocking */ } -static void bnx2x_vf_mbx_resp(struct bnx2x *bp, - struct bnx2x_virtf *vf) -{ - bnx2x_vf_mbx_resp_single_tlv(bp, vf); - bnx2x_vf_mbx_resp_send_msg(bp, vf); -} - -static void bnx2x_vf_mbx_resp_phys_port(struct bnx2x *bp, - struct bnx2x_virtf *vf, - void *buffer, - u16 *offset) -{ - struct vfpf_port_phys_id_resp_tlv *port_id; - - if (!(bp->flags & HAS_PHYS_PORT_ID)) - return; - - bnx2x_add_tlv(bp, buffer, *offset, CHANNEL_TLV_PHYS_PORT_ID, - sizeof(struct vfpf_port_phys_id_resp_tlv)); - - port_id = (struct vfpf_port_phys_id_resp_tlv *) - (((u8 *)buffer) + *offset); - memcpy(port_id->id, bp->phys_port_id, ETH_ALEN); - - /* Offset should continue representing the offset to the tail - * of TLV data (outside this function scope) - */ - *offset += sizeof(struct vfpf_port_phys_id_resp_tlv); -} - static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, struct bnx2x_vf_mbx *mbx, int vfop_status) { @@ -1143,7 +1067,6 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, struct pfvf_acquire_resp_tlv *resp = &mbx->msg->resp.acquire_resp; struct pf_vf_resc *resc = &resp->resc; u8 status = bnx2x_pfvf_status_codes(vfop_status); - u16 length; memset(resp, 0, sizeof(*resp)); @@ -1217,24 +1140,9 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, resc->hw_sbs[i].sb_qid); DP_CONT(BNX2X_MSG_IOV, "]\n"); - /* prepare response */ - length = sizeof(struct pfvf_acquire_resp_tlv); - bnx2x_add_tlv(bp, &mbx->msg->resp, 0, CHANNEL_TLV_ACQUIRE, length); - - /* Handle possible VF requests for physical port identifiers. - * 'length' should continue to indicate the offset of the first empty - * place in the buffer (i.e., where next TLV should be inserted) - */ - if (bnx2x_search_tlv_list(bp, &mbx->msg->req, - CHANNEL_TLV_PHYS_PORT_ID)) - bnx2x_vf_mbx_resp_phys_port(bp, vf, &mbx->msg->resp, &length); - - bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END, - sizeof(struct channel_list_end_tlv)); - /* send the response */ vf->op_rc = vfop_status; - bnx2x_vf_mbx_resp_send_msg(bp, vf); + bnx2x_vf_mbx_resp(bp, vf); } static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, @@ -1966,9 +1874,6 @@ void bnx2x_vf_mbx(struct bnx2x *bp, struct vf_pf_event_data *vfpf_event) /* process the VF message header */ mbx->first_tlv = mbx->msg->req.first_tlv; - /* Clean response buffer to refrain from falsely seeing chains */ - memset(&mbx->msg->resp, 0, sizeof(union pfvf_tlvs)); - /* dispatch the request (will prepare the response) */ bnx2x_vf_mbx_request(bp, vf, mbx); goto mbx_done; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h index 208568b..1179fe0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h @@ -188,12 +188,6 @@ struct pfvf_acquire_resp_tlv { } resc; }; -struct vfpf_port_phys_id_resp_tlv { - struct channel_tlv tl; - u8 id[ETH_ALEN]; - u8 padding[2]; -}; - #define VFPF_INIT_FLG_STATS_COALESCE (1 << 0) /* when set the VFs queues * stats will be coalesced on * the leading RSS queue @@ -404,7 +398,6 @@ enum channel_tlvs { CHANNEL_TLV_PF_SET_MAC, CHANNEL_TLV_PF_SET_VLAN, CHANNEL_TLV_UPDATE_RSS, - CHANNEL_TLV_PHYS_PORT_ID, CHANNEL_TLV_MAX }; diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index f58a8b8..99394bd 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -393,7 +393,7 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, csk->vlan_id = path_resp->vlan_id; - memcpy(csk->ha, path_resp->mac_addr, ETH_ALEN); + memcpy(csk->ha, path_resp->mac_addr, 6); if (test_bit(SK_F_IPV6, &csk->flags)) memcpy(&csk->src_ip[0], &path_resp->src.v6_addr, sizeof(struct in6_addr)); @@ -5572,7 +5572,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) if (cdev->max_fcoe_conn > BNX2X_FCOE_NUM_CONNECTIONS) cdev->max_fcoe_conn = BNX2X_FCOE_NUM_CONNECTIONS; - memcpy(cdev->mac_addr, ethdev->iscsi_mac, ETH_ALEN); + memcpy(cdev->mac_addr, ethdev->iscsi_mac, 6); cp->cnic_ops = &cnic_bnx2x_ops; cp->start_hw = cnic_start_bnx2x_hw; diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index ebbfe25..0658b43 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -353,8 +353,8 @@ struct cnic_ulp_ops { atomic_t ref_count; }; -int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops); +extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops); -int cnic_unregister_driver(int ulp_type); +extern int cnic_unregister_driver(int ulp_type); #endif diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 369b736..12d961c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 134 +#define TG3_MIN_NUM 133 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "Sep 16, 2013" +#define DRV_MODULE_RELDATE "Jul 29, 2013" #define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_INIT 1 @@ -337,11 +337,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -1331,12 +1326,6 @@ static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) return err; } -static int tg3_phy_shdw_write(struct tg3 *tp, int reg, u32 val) -{ - return tg3_writephy(tp, MII_TG3_MISC_SHDW, - reg | val | MII_TG3_MISC_SHDW_WREN); -} - static int tg3_bmcr_reset(struct tg3 *tp) { u32 phy_control; @@ -1375,7 +1364,7 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg) spin_lock_bh(&tp->lock); - if (__tg3_readphy(tp, mii_id, reg, &val)) + if (tg3_readphy(tp, reg, &val)) val = -EIO; spin_unlock_bh(&tp->lock); @@ -1390,7 +1379,7 @@ static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) spin_lock_bh(&tp->lock); - if (__tg3_writephy(tp, mii_id, reg, val)) + if (tg3_writephy(tp, reg, val)) ret = -EIO; spin_unlock_bh(&tp->lock); @@ -1408,7 +1397,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp) u32 val; struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) { case PHY_ID_BCM50610: case PHY_ID_BCM50610M: @@ -1513,13 +1502,6 @@ static int tg3_mdio_init(struct tg3 *tp) TG3_CPMU_PHY_STRAP_IS_SERDES; if (is_serdes) tp->phy_addr += 7; - } else if (tg3_flag(tp, IS_SSB_CORE) && tg3_flag(tp, ROBOSWITCH)) { - int addr; - - addr = ssb_gige_get_phyaddr(tp->pdev); - if (addr < 0) - return addr; - tp->phy_addr = addr; } else tp->phy_addr = TG3_PHY_MII_ADDR; @@ -1540,7 +1522,7 @@ static int tg3_mdio_init(struct tg3 *tp) tp->mdio_bus->read = &tg3_mdio_read; tp->mdio_bus->write = &tg3_mdio_write; tp->mdio_bus->reset = &tg3_mdio_reset; - tp->mdio_bus->phy_mask = ~(1 << tp->phy_addr); + tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR); tp->mdio_bus->irq = &tp->mdio_irq[0]; for (i = 0; i < PHY_MAX_ADDR; i++) @@ -1561,7 +1543,7 @@ static int tg3_mdio_init(struct tg3 *tp) return i; } - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; if (!phydev || !phydev->drv) { dev_warn(&tp->pdev->dev, "No PHY devices\n"); @@ -1971,7 +1953,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) u32 old_tx_mode = tp->tx_mode; if (tg3_flag(tp, USE_PHYLIB)) - autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg; + autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg; else autoneg = tp->link_config.autoneg; @@ -2007,7 +1989,7 @@ static void tg3_adjust_link(struct net_device *dev) u8 oldflowctrl, linkmesg = 0; u32 mac_mode, lcl_adv, rmt_adv; struct tg3 *tp = netdev_priv(dev); - struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; spin_lock_bh(&tp->lock); @@ -2096,7 +2078,7 @@ static int tg3_phy_init(struct tg3 *tp) /* Bring the PHY back to a known state. */ tg3_bmcr_reset(tp); - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; /* Attach the MAC to the PHY. */ phydev = phy_connect(tp->dev, dev_name(&phydev->dev), @@ -2123,7 +2105,7 @@ static int tg3_phy_init(struct tg3 *tp) SUPPORTED_Asym_Pause); break; default: - phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); + phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); return -EINVAL; } @@ -2141,7 +2123,7 @@ static void tg3_phy_start(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; @@ -2161,13 +2143,13 @@ static void tg3_phy_stop(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return; - phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]); + phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); } static void tg3_phy_fini(struct tg3 *tp) { if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { - phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); + phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED; } } @@ -2236,21 +2218,25 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) return; } - reg = MII_TG3_MISC_SHDW_SCR5_LPED | + reg = MII_TG3_MISC_SHDW_WREN | + MII_TG3_MISC_SHDW_SCR5_SEL | + MII_TG3_MISC_SHDW_SCR5_LPED | MII_TG3_MISC_SHDW_SCR5_DLPTLM | MII_TG3_MISC_SHDW_SCR5_SDTL | MII_TG3_MISC_SHDW_SCR5_C125OE; if (tg3_asic_rev(tp) != ASIC_REV_5784 || !enable) reg |= MII_TG3_MISC_SHDW_SCR5_DLLAPD; - tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_SCR5_SEL, reg); + tg3_writephy(tp, MII_TG3_MISC_SHDW, reg); - reg = MII_TG3_MISC_SHDW_APD_WKTM_84MS; + reg = MII_TG3_MISC_SHDW_WREN | + MII_TG3_MISC_SHDW_APD_SEL | + MII_TG3_MISC_SHDW_APD_WKTM_84MS; if (enable) reg |= MII_TG3_MISC_SHDW_APD_ENABLE; - tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_APD_SEL, reg); + tg3_writephy(tp, MII_TG3_MISC_SHDW, reg); } static void tg3_phy_toggle_automdix(struct tg3 *tp, bool enable) @@ -4041,7 +4027,7 @@ static int tg3_power_down_prepare(struct tg3 *tp) struct phy_device *phydev; u32 phyid, advertising; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; @@ -6862,6 +6848,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) pci_unmap_single(tp->pdev, dma_addr, skb_size, PCI_DMA_FROMDEVICE); + skb = build_skb(data, frag_size); + if (!skb) { + tg3_frag_free(frag_size != 0, data); + goto drop_it_no_recycle; + } + skb_reserve(skb, TG3_RX_OFFSET(tp)); /* Ensure that the update to the data happens * after the usage of the old DMA mapping. */ @@ -6869,12 +6861,6 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) ri->data = NULL; - skb = build_skb(data, frag_size); - if (!skb) { - tg3_frag_free(frag_size != 0, data); - goto drop_it_no_recycle; - } - skb_reserve(skb, TG3_RX_OFFSET(tp)); } else { tg3_recycle_rx(tnapi, tpr, opaque_key, desc_idx, *post_ptr); @@ -9210,7 +9196,10 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent) memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); } - return err; + if (err) + return err; + + return 0; } static int tg3_set_mac_addr(struct net_device *dev, void *p) @@ -10629,8 +10618,10 @@ static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir) static ssize_t tg3_show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { + struct pci_dev *pdev = to_pci_dev(dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct tg3 *tp = netdev_priv(netdev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct tg3 *tp = dev_get_drvdata(dev); u32 temperature; spin_lock_bh(&tp->lock); @@ -10648,25 +10639,29 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL, static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL, TG3_TEMP_MAX_OFFSET); -static struct attribute *tg3_attrs[] = { +static struct attribute *tg3_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, NULL }; -ATTRIBUTE_GROUPS(tg3); + +static const struct attribute_group tg3_group = { + .attrs = tg3_attributes, +}; static void tg3_hwmon_close(struct tg3 *tp) { if (tp->hwmon_dev) { hwmon_device_unregister(tp->hwmon_dev); tp->hwmon_dev = NULL; + sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group); } } static void tg3_hwmon_open(struct tg3 *tp) { - int i; + int i, err; u32 size = 0; struct pci_dev *pdev = tp->pdev; struct tg3_ocir ocirs[TG3_SD_NUM_RECS]; @@ -10684,11 +10679,18 @@ static void tg3_hwmon_open(struct tg3 *tp) if (!size) return; - tp->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, "tg3", - tp, tg3_groups); + /* Register hwmon sysfs hooks */ + err = sysfs_create_group(&pdev->dev.kobj, &tg3_group); + if (err) { + dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n"); + return; + } + + tp->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(tp->hwmon_dev)) { tp->hwmon_dev = NULL; dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n"); + sysfs_remove_group(&pdev->dev.kobj, &tg3_group); } } @@ -11033,18 +11035,7 @@ static int tg3_request_irq(struct tg3 *tp, int irq_num) name = tp->dev->name; else { name = &tnapi->irq_lbl[0]; - if (tnapi->tx_buffers && tnapi->rx_rcb) - snprintf(name, IFNAMSIZ, - "%s-txrx-%d", tp->dev->name, irq_num); - else if (tnapi->tx_buffers) - snprintf(name, IFNAMSIZ, - "%s-tx-%d", tp->dev->name, irq_num); - else if (tnapi->rx_rcb) - snprintf(name, IFNAMSIZ, - "%s-rx-%d", tp->dev->name, irq_num); - else - snprintf(name, IFNAMSIZ, - "%s-%d", tp->dev->name, irq_num); + snprintf(name, IFNAMSIZ, "%s-%d", tp->dev->name, irq_num); name[IFNAMSIZ-1] = 0; } @@ -11916,7 +11907,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_ethtool_gset(phydev, cmd); } @@ -11983,7 +11974,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_ethtool_sset(phydev, cmd); } @@ -12102,10 +12093,12 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC); + spin_lock_bh(&tp->lock); if (device_may_wakeup(dp)) tg3_flag_set(tp, WOL_ENABLE); else tg3_flag_clear(tp, WOL_ENABLE); + spin_unlock_bh(&tp->lock); return 0; } @@ -12138,7 +12131,7 @@ static int tg3_nway_reset(struct net_device *dev) if (tg3_flag(tp, USE_PHYLIB)) { if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]); + r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); } else { u32 bmcr; @@ -12254,7 +12247,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam u32 newadv; struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; if (!(phydev->supported & SUPPORTED_Pause) || (!(phydev->supported & SUPPORTED_Asym_Pause) && @@ -13201,8 +13194,8 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) return -ENOMEM; tx_data = skb_put(skb, tx_len); - memcpy(tx_data, tp->dev->dev_addr, ETH_ALEN); - memset(tx_data + ETH_ALEN, 0x0, 8); + memcpy(tx_data, tp->dev->dev_addr, 6); + memset(tx_data + 6, 0x0, 8); tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN); @@ -13605,9 +13598,16 @@ static int tg3_hwtstamp_ioctl(struct net_device *dev, if (stmpconf.flags) return -EINVAL; - if (stmpconf.tx_type != HWTSTAMP_TX_ON && - stmpconf.tx_type != HWTSTAMP_TX_OFF) + switch (stmpconf.tx_type) { + case HWTSTAMP_TX_ON: + tg3_flag_set(tp, TX_TSTAMP_EN); + break; + case HWTSTAMP_TX_OFF: + tg3_flag_clear(tp, TX_TSTAMP_EN); + break; + default: return -ERANGE; + } switch (stmpconf.rx_filter) { case HWTSTAMP_FILTER_NONE: @@ -13669,11 +13669,6 @@ static int tg3_hwtstamp_ioctl(struct net_device *dev, tw32(TG3_RX_PTP_CTL, tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); - if (stmpconf.tx_type == HWTSTAMP_TX_ON) - tg3_flag_set(tp, TX_TSTAMP_EN); - else - tg3_flag_clear(tp, TX_TSTAMP_EN); - return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? -EFAULT : 0; } @@ -13688,7 +13683,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct phy_device *phydev; if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) return -EAGAIN; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_mii_ioctl(phydev, ifr, cmd); } @@ -14926,12 +14921,6 @@ static void tg3_get_eeprom_hw_cfg(struct tg3 *tp) tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A1) tp->led_ctrl |= (LED_CTRL_MODE_PHY_1 | LED_CTRL_MODE_PHY_2); - - if (tg3_flag(tp, 5717_PLUS) || - tg3_asic_rev(tp) == ASIC_REV_5762) - tp->led_ctrl |= LED_CTRL_BLINK_RATE_OVERRIDE | - LED_CTRL_BLINK_RATE_MASK; - break; case SHASTA_EXT_LED_MAC: @@ -15770,12 +15759,9 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) reg = TG3PCI_GEN2_PRODID_ASICREV; else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 || @@ -16646,8 +16632,8 @@ static int tg3_get_macaddr_sparc(struct tg3 *tp) int len; addr = of_get_property(dp, "local-mac-address", &len); - if (addr && len == ETH_ALEN) { - memcpy(dev->dev_addr, addr, ETH_ALEN); + if (addr && len == 6) { + memcpy(dev->dev_addr, addr, 6); return 0; } return -ENODEV; @@ -16657,7 +16643,7 @@ static int tg3_get_default_macaddr_sparc(struct tg3 *tp) { struct net_device *dev = tp->dev; - memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); + memcpy(dev->dev_addr, idprom->id_ethaddr, 6); return 0; } #endif @@ -17066,6 +17052,10 @@ static int tg3_test_dma(struct tg3 *tp) tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); +#if 0 + /* Unneeded, already done by tg3_get_invariants. */ + tg3_switch_clocks(tp); +#endif if (tg3_asic_rev(tp) != ASIC_REV_5700 && tg3_asic_rev(tp) != ASIC_REV_5701) @@ -17093,6 +17083,20 @@ static int tg3_test_dma(struct tg3 *tp) break; } +#if 0 + /* validate data reached card RAM correctly. */ + for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { + u32 val; + tg3_read_mem(tp, 0x2100 + (i*4), &val); + if (le32_to_cpu(val) != p[i]) { + dev_err(&tp->pdev->dev, + "%s: Buffer corrupted on device! " + "(%d != %d)\n", __func__, val, i); + /* ret = -ENODEV here? */ + } + p[i] = 0; + } +#endif /* Now read it back. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, false); if (ret) { @@ -17358,10 +17362,8 @@ static int tg3_init_one(struct pci_dev *pdev, tg3_flag_set(tp, FLUSH_POSTED_WRITES); if (ssb_gige_one_dma_at_once(pdev)) tg3_flag_set(tp, ONE_DMA_AT_ONCE); - if (ssb_gige_have_roboswitch(pdev)) { - tg3_flag_set(tp, USE_PHYLIB); + if (ssb_gige_have_roboswitch(pdev)) tg3_flag_set(tp, ROBOSWITCH); - } if (ssb_gige_is_rgmii(pdev)) tg3_flag_set(tp, RGMII_MODE); } @@ -17407,12 +17409,9 @@ static int tg3_init_one(struct pci_dev *pdev, tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) { + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) { tg3_flag_set(tp, ENABLE_APE); tp->aperegs = pci_ioremap_bar(pdev, BAR_2); if (!tp->aperegs) { @@ -17629,7 +17628,7 @@ static int tg3_init_one(struct pci_dev *pdev, if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { struct phy_device *phydev; - phydev = tp->mdio_bus->phy_map[tp->phy_addr]; + phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); @@ -17686,6 +17685,7 @@ err_out_free_res: err_out_disable_pdev: if (pci_is_enabled(pdev)) pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); return err; } @@ -17717,6 +17717,7 @@ static void tg3_remove_one(struct pci_dev *pdev) free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); } } diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 5c3835a..7025780 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -68,9 +68,6 @@ #define TG3PCI_DEVICE_TIGON3_5762 0x1687 #define TG3PCI_DEVICE_TIGON3_5725 0x1643 #define TG3PCI_DEVICE_TIGON3_5727 0x16f3 -#define TG3PCI_DEVICE_TIGON3_57764 0x1642 -#define TG3PCI_DEVICE_TIGON3_57767 0x1683 -#define TG3PCI_DEVICE_TIGON3_57787 0x1641 /* 0x04 --> 0x2c unused */ #define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM #define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644 |