diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-05-09 03:39:13 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-05-09 03:39:13 -0400 |
| commit | 10ee08292028d3d22d201a34ba7d24a085818cb3 (patch) | |
| tree | cf3bff48a7eab154574355f00a4b4f27dc85ff11 /drivers/net | |
| parent | 7da4b8b7378790dd1e4af1bb7522863127fa1438 (diff) | |
| parent | 44549e8f5eea4e0a41b487b63e616cb089922b99 (diff) | |
Merge 4.6-rc7 into tty-next
We want the pty fixes in here as well so that patches can build on it.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
41 files changed, 536 insertions, 286 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a24c18eee598..befd67df08e1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -62,9 +62,8 @@ config DUMMY | |||
| 62 | this device is consigned into oblivion) with a configurable IP | 62 | this device is consigned into oblivion) with a configurable IP |
| 63 | address. It is most commonly used in order to make your currently | 63 | address. It is most commonly used in order to make your currently |
| 64 | inactive SLIP address seem like a real address for local programs. | 64 | inactive SLIP address seem like a real address for local programs. |
| 65 | If you use SLIP or PPP, you might want to say Y here. Since this | 65 | If you use SLIP or PPP, you might want to say Y here. It won't |
| 66 | thing often comes in handy, the default is Y. It won't enlarge your | 66 | enlarge your kernel. What a deal. Read about it in the Network |
| 67 | kernel either. What a deal. Read about it in the Network | ||
| 68 | Administrator's Guide, available from | 67 | Administrator's Guide, available from |
| 69 | <http://www.tldp.org/docs.html#guide>. | 68 | <http://www.tldp.org/docs.html#guide>. |
| 70 | 69 | ||
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index a2904029cccc..5e572b3510b9 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
| @@ -2181,7 +2181,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, | |||
| 2181 | struct net_device *bridge) | 2181 | struct net_device *bridge) |
| 2182 | { | 2182 | { |
| 2183 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2183 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
| 2184 | int i, err; | 2184 | int i, err = 0; |
| 2185 | 2185 | ||
| 2186 | mutex_lock(&ps->smi_mutex); | 2186 | mutex_lock(&ps->smi_mutex); |
| 2187 | 2187 | ||
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 12a009d720cd..72eb29ed0359 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -581,12 +581,30 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, | |||
| 581 | struct page *page; | 581 | struct page *page; |
| 582 | dma_addr_t mapping; | 582 | dma_addr_t mapping; |
| 583 | u16 sw_prod = rxr->rx_sw_agg_prod; | 583 | u16 sw_prod = rxr->rx_sw_agg_prod; |
| 584 | unsigned int offset = 0; | ||
| 584 | 585 | ||
| 585 | page = alloc_page(gfp); | 586 | if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { |
| 586 | if (!page) | 587 | page = rxr->rx_page; |
| 587 | return -ENOMEM; | 588 | if (!page) { |
| 589 | page = alloc_page(gfp); | ||
| 590 | if (!page) | ||
| 591 | return -ENOMEM; | ||
| 592 | rxr->rx_page = page; | ||
| 593 | rxr->rx_page_offset = 0; | ||
| 594 | } | ||
| 595 | offset = rxr->rx_page_offset; | ||
| 596 | rxr->rx_page_offset += BNXT_RX_PAGE_SIZE; | ||
| 597 | if (rxr->rx_page_offset == PAGE_SIZE) | ||
| 598 | rxr->rx_page = NULL; | ||
| 599 | else | ||
| 600 | get_page(page); | ||
| 601 | } else { | ||
| 602 | page = alloc_page(gfp); | ||
| 603 | if (!page) | ||
| 604 | return -ENOMEM; | ||
| 605 | } | ||
| 588 | 606 | ||
| 589 | mapping = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, | 607 | mapping = dma_map_page(&pdev->dev, page, offset, BNXT_RX_PAGE_SIZE, |
| 590 | PCI_DMA_FROMDEVICE); | 608 | PCI_DMA_FROMDEVICE); |
| 591 | if (dma_mapping_error(&pdev->dev, mapping)) { | 609 | if (dma_mapping_error(&pdev->dev, mapping)) { |
| 592 | __free_page(page); | 610 | __free_page(page); |
| @@ -601,6 +619,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, | |||
| 601 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); | 619 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); |
| 602 | 620 | ||
| 603 | rx_agg_buf->page = page; | 621 | rx_agg_buf->page = page; |
| 622 | rx_agg_buf->offset = offset; | ||
| 604 | rx_agg_buf->mapping = mapping; | 623 | rx_agg_buf->mapping = mapping; |
| 605 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); | 624 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); |
| 606 | rxbd->rx_bd_opaque = sw_prod; | 625 | rxbd->rx_bd_opaque = sw_prod; |
| @@ -642,6 +661,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons, | |||
| 642 | page = cons_rx_buf->page; | 661 | page = cons_rx_buf->page; |
| 643 | cons_rx_buf->page = NULL; | 662 | cons_rx_buf->page = NULL; |
| 644 | prod_rx_buf->page = page; | 663 | prod_rx_buf->page = page; |
| 664 | prod_rx_buf->offset = cons_rx_buf->offset; | ||
| 645 | 665 | ||
| 646 | prod_rx_buf->mapping = cons_rx_buf->mapping; | 666 | prod_rx_buf->mapping = cons_rx_buf->mapping; |
| 647 | 667 | ||
| @@ -709,7 +729,8 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, | |||
| 709 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; | 729 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; |
| 710 | 730 | ||
| 711 | cons_rx_buf = &rxr->rx_agg_ring[cons]; | 731 | cons_rx_buf = &rxr->rx_agg_ring[cons]; |
| 712 | skb_fill_page_desc(skb, i, cons_rx_buf->page, 0, frag_len); | 732 | skb_fill_page_desc(skb, i, cons_rx_buf->page, |
| 733 | cons_rx_buf->offset, frag_len); | ||
| 713 | __clear_bit(cons, rxr->rx_agg_bmap); | 734 | __clear_bit(cons, rxr->rx_agg_bmap); |
| 714 | 735 | ||
| 715 | /* It is possible for bnxt_alloc_rx_page() to allocate | 736 | /* It is possible for bnxt_alloc_rx_page() to allocate |
| @@ -740,7 +761,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, | |||
| 740 | return NULL; | 761 | return NULL; |
| 741 | } | 762 | } |
| 742 | 763 | ||
| 743 | dma_unmap_page(&pdev->dev, mapping, PAGE_SIZE, | 764 | dma_unmap_page(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE, |
| 744 | PCI_DMA_FROMDEVICE); | 765 | PCI_DMA_FROMDEVICE); |
| 745 | 766 | ||
| 746 | skb->data_len += frag_len; | 767 | skb->data_len += frag_len; |
| @@ -1584,13 +1605,17 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) | |||
| 1584 | 1605 | ||
| 1585 | dma_unmap_page(&pdev->dev, | 1606 | dma_unmap_page(&pdev->dev, |
| 1586 | dma_unmap_addr(rx_agg_buf, mapping), | 1607 | dma_unmap_addr(rx_agg_buf, mapping), |
| 1587 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 1608 | BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); |
| 1588 | 1609 | ||
| 1589 | rx_agg_buf->page = NULL; | 1610 | rx_agg_buf->page = NULL; |
| 1590 | __clear_bit(j, rxr->rx_agg_bmap); | 1611 | __clear_bit(j, rxr->rx_agg_bmap); |
| 1591 | 1612 | ||
| 1592 | __free_page(page); | 1613 | __free_page(page); |
| 1593 | } | 1614 | } |
| 1615 | if (rxr->rx_page) { | ||
| 1616 | __free_page(rxr->rx_page); | ||
| 1617 | rxr->rx_page = NULL; | ||
| 1618 | } | ||
| 1594 | } | 1619 | } |
| 1595 | } | 1620 | } |
| 1596 | 1621 | ||
| @@ -1973,7 +1998,7 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) | |||
| 1973 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) | 1998 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) |
| 1974 | return 0; | 1999 | return 0; |
| 1975 | 2000 | ||
| 1976 | type = ((u32)PAGE_SIZE << RX_BD_LEN_SHIFT) | | 2001 | type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | |
| 1977 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; | 2002 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; |
| 1978 | 2003 | ||
| 1979 | bnxt_init_rxbd_pages(ring, type); | 2004 | bnxt_init_rxbd_pages(ring, type); |
| @@ -2164,7 +2189,7 @@ void bnxt_set_ring_params(struct bnxt *bp) | |||
| 2164 | bp->rx_agg_nr_pages = 0; | 2189 | bp->rx_agg_nr_pages = 0; |
| 2165 | 2190 | ||
| 2166 | if (bp->flags & BNXT_FLAG_TPA) | 2191 | if (bp->flags & BNXT_FLAG_TPA) |
| 2167 | agg_factor = 4; | 2192 | agg_factor = min_t(u32, 4, 65536 / BNXT_RX_PAGE_SIZE); |
| 2168 | 2193 | ||
| 2169 | bp->flags &= ~BNXT_FLAG_JUMBO; | 2194 | bp->flags &= ~BNXT_FLAG_JUMBO; |
| 2170 | if (rx_space > PAGE_SIZE) { | 2195 | if (rx_space > PAGE_SIZE) { |
| @@ -3020,12 +3045,12 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) | |||
| 3020 | /* Number of segs are log2 units, and first packet is not | 3045 | /* Number of segs are log2 units, and first packet is not |
| 3021 | * included as part of this units. | 3046 | * included as part of this units. |
| 3022 | */ | 3047 | */ |
| 3023 | if (mss <= PAGE_SIZE) { | 3048 | if (mss <= BNXT_RX_PAGE_SIZE) { |
| 3024 | n = PAGE_SIZE / mss; | 3049 | n = BNXT_RX_PAGE_SIZE / mss; |
| 3025 | nsegs = (MAX_SKB_FRAGS - 1) * n; | 3050 | nsegs = (MAX_SKB_FRAGS - 1) * n; |
| 3026 | } else { | 3051 | } else { |
| 3027 | n = mss / PAGE_SIZE; | 3052 | n = mss / BNXT_RX_PAGE_SIZE; |
| 3028 | if (mss & (PAGE_SIZE - 1)) | 3053 | if (mss & (BNXT_RX_PAGE_SIZE - 1)) |
| 3029 | n++; | 3054 | n++; |
| 3030 | nsegs = (MAX_SKB_FRAGS - n) / n; | 3055 | nsegs = (MAX_SKB_FRAGS - n) / n; |
| 3031 | } | 3056 | } |
| @@ -4309,7 +4334,7 @@ static int bnxt_setup_int_mode(struct bnxt *bp) | |||
| 4309 | if (bp->flags & BNXT_FLAG_MSIX_CAP) | 4334 | if (bp->flags & BNXT_FLAG_MSIX_CAP) |
| 4310 | rc = bnxt_setup_msix(bp); | 4335 | rc = bnxt_setup_msix(bp); |
| 4311 | 4336 | ||
| 4312 | if (!(bp->flags & BNXT_FLAG_USING_MSIX)) { | 4337 | if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) { |
| 4313 | /* fallback to INTA */ | 4338 | /* fallback to INTA */ |
| 4314 | rc = bnxt_setup_inta(bp); | 4339 | rc = bnxt_setup_inta(bp); |
| 4315 | } | 4340 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 709b95b8fcba..8b823ff558ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
| @@ -407,6 +407,15 @@ struct rx_tpa_end_cmp_ext { | |||
| 407 | 407 | ||
| 408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) | 408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) |
| 409 | 409 | ||
| 410 | /* The RXBD length is 16-bit so we can only support page sizes < 64K */ | ||
| 411 | #if (PAGE_SHIFT > 15) | ||
| 412 | #define BNXT_RX_PAGE_SHIFT 15 | ||
| 413 | #else | ||
| 414 | #define BNXT_RX_PAGE_SHIFT PAGE_SHIFT | ||
| 415 | #endif | ||
| 416 | |||
| 417 | #define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT) | ||
| 418 | |||
| 410 | #define BNXT_MIN_PKT_SIZE 45 | 419 | #define BNXT_MIN_PKT_SIZE 45 |
| 411 | 420 | ||
| 412 | #define BNXT_NUM_TESTS(bp) 0 | 421 | #define BNXT_NUM_TESTS(bp) 0 |
| @@ -506,6 +515,7 @@ struct bnxt_sw_rx_bd { | |||
| 506 | 515 | ||
| 507 | struct bnxt_sw_rx_agg_bd { | 516 | struct bnxt_sw_rx_agg_bd { |
| 508 | struct page *page; | 517 | struct page *page; |
| 518 | unsigned int offset; | ||
| 509 | dma_addr_t mapping; | 519 | dma_addr_t mapping; |
| 510 | }; | 520 | }; |
| 511 | 521 | ||
| @@ -586,6 +596,9 @@ struct bnxt_rx_ring_info { | |||
| 586 | unsigned long *rx_agg_bmap; | 596 | unsigned long *rx_agg_bmap; |
| 587 | u16 rx_agg_bmap_size; | 597 | u16 rx_agg_bmap_size; |
| 588 | 598 | ||
| 599 | struct page *rx_page; | ||
| 600 | unsigned int rx_page_offset; | ||
| 601 | |||
| 589 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; | 602 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; |
| 590 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; | 603 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; |
| 591 | 604 | ||
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 48a7d7dee846..a63551d0a18a 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
| @@ -441,7 +441,7 @@ static int macb_mii_init(struct macb *bp) | |||
| 441 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", | 441 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
| 442 | bp->pdev->name, bp->pdev->id); | 442 | bp->pdev->name, bp->pdev->id); |
| 443 | bp->mii_bus->priv = bp; | 443 | bp->mii_bus->priv = bp; |
| 444 | bp->mii_bus->parent = &bp->dev->dev; | 444 | bp->mii_bus->parent = &bp->pdev->dev; |
| 445 | pdata = dev_get_platdata(&bp->pdev->dev); | 445 | pdata = dev_get_platdata(&bp->pdev->dev); |
| 446 | 446 | ||
| 447 | dev_set_drvdata(&bp->dev->dev, bp->mii_bus); | 447 | dev_set_drvdata(&bp->dev->dev, bp->mii_bus); |
| @@ -458,7 +458,8 @@ static int macb_mii_init(struct macb *bp) | |||
| 458 | struct phy_device *phydev; | 458 | struct phy_device *phydev; |
| 459 | 459 | ||
| 460 | phydev = mdiobus_scan(bp->mii_bus, i); | 460 | phydev = mdiobus_scan(bp->mii_bus, i); |
| 461 | if (IS_ERR(phydev)) { | 461 | if (IS_ERR(phydev) && |
| 462 | PTR_ERR(phydev) != -ENODEV) { | ||
| 462 | err = PTR_ERR(phydev); | 463 | err = PTR_ERR(phydev); |
| 463 | break; | 464 | break; |
| 464 | } | 465 | } |
| @@ -3019,29 +3020,36 @@ static int macb_probe(struct platform_device *pdev) | |||
| 3019 | if (err) | 3020 | if (err) |
| 3020 | goto err_out_free_netdev; | 3021 | goto err_out_free_netdev; |
| 3021 | 3022 | ||
| 3023 | err = macb_mii_init(bp); | ||
| 3024 | if (err) | ||
| 3025 | goto err_out_free_netdev; | ||
| 3026 | |||
| 3027 | phydev = bp->phy_dev; | ||
| 3028 | |||
| 3029 | netif_carrier_off(dev); | ||
| 3030 | |||
| 3022 | err = register_netdev(dev); | 3031 | err = register_netdev(dev); |
| 3023 | if (err) { | 3032 | if (err) { |
| 3024 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); | 3033 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); |
| 3025 | goto err_out_unregister_netdev; | 3034 | goto err_out_unregister_mdio; |
| 3026 | } | 3035 | } |
| 3027 | 3036 | ||
| 3028 | err = macb_mii_init(bp); | 3037 | phy_attached_info(phydev); |
| 3029 | if (err) | ||
| 3030 | goto err_out_unregister_netdev; | ||
| 3031 | |||
| 3032 | netif_carrier_off(dev); | ||
| 3033 | 3038 | ||
| 3034 | netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", | 3039 | netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", |
| 3035 | macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), | 3040 | macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), |
| 3036 | dev->base_addr, dev->irq, dev->dev_addr); | 3041 | dev->base_addr, dev->irq, dev->dev_addr); |
| 3037 | 3042 | ||
| 3038 | phydev = bp->phy_dev; | ||
| 3039 | phy_attached_info(phydev); | ||
| 3040 | |||
| 3041 | return 0; | 3043 | return 0; |
| 3042 | 3044 | ||
| 3043 | err_out_unregister_netdev: | 3045 | err_out_unregister_mdio: |
| 3044 | unregister_netdev(dev); | 3046 | phy_disconnect(bp->phy_dev); |
| 3047 | mdiobus_unregister(bp->mii_bus); | ||
| 3048 | mdiobus_free(bp->mii_bus); | ||
| 3049 | |||
| 3050 | /* Shutdown the PHY if there is a GPIO reset */ | ||
| 3051 | if (bp->reset_gpio) | ||
| 3052 | gpiod_set_value(bp->reset_gpio, 0); | ||
| 3045 | 3053 | ||
| 3046 | err_out_free_netdev: | 3054 | err_out_free_netdev: |
| 3047 | free_netdev(dev); | 3055 | free_netdev(dev); |
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 60908eab3b3a..43da891fab97 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | |||
| @@ -576,7 +576,7 @@ static void setup_rss(struct adapter *adap) | |||
| 576 | unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; | 576 | unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; |
| 577 | unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; | 577 | unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; |
| 578 | u8 cpus[SGE_QSETS + 1]; | 578 | u8 cpus[SGE_QSETS + 1]; |
| 579 | u16 rspq_map[RSS_TABLE_SIZE]; | 579 | u16 rspq_map[RSS_TABLE_SIZE + 1]; |
| 580 | 580 | ||
| 581 | for (i = 0; i < SGE_QSETS; ++i) | 581 | for (i = 0; i < SGE_QSETS; ++i) |
| 582 | cpus[i] = i; | 582 | cpus[i] = i; |
| @@ -586,6 +586,7 @@ static void setup_rss(struct adapter *adap) | |||
| 586 | rspq_map[i] = i % nq0; | 586 | rspq_map[i] = i % nq0; |
| 587 | rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; | 587 | rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; |
| 588 | } | 588 | } |
| 589 | rspq_map[RSS_TABLE_SIZE] = 0xffff; /* terminator */ | ||
| 589 | 590 | ||
| 590 | t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | | 591 | t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | |
| 591 | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | | 592 | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 7fc490225da5..a6d26d351dfc 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -3354,8 +3354,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, | |||
| 3354 | /* Enable per-CPU interrupts on the CPU that is | 3354 | /* Enable per-CPU interrupts on the CPU that is |
| 3355 | * brought up. | 3355 | * brought up. |
| 3356 | */ | 3356 | */ |
| 3357 | smp_call_function_single(cpu, mvneta_percpu_enable, | 3357 | mvneta_percpu_enable(pp); |
| 3358 | pp, true); | ||
| 3359 | 3358 | ||
| 3360 | /* Enable per-CPU interrupt on the one CPU we care | 3359 | /* Enable per-CPU interrupt on the one CPU we care |
| 3361 | * about. | 3360 | * about. |
| @@ -3387,8 +3386,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, | |||
| 3387 | /* Disable per-CPU interrupts on the CPU that is | 3386 | /* Disable per-CPU interrupts on the CPU that is |
| 3388 | * brought down. | 3387 | * brought down. |
| 3389 | */ | 3388 | */ |
| 3390 | smp_call_function_single(cpu, mvneta_percpu_disable, | 3389 | mvneta_percpu_disable(pp); |
| 3391 | pp, true); | ||
| 3392 | 3390 | ||
| 3393 | break; | 3391 | break; |
| 3394 | case CPU_DEAD: | 3392 | case CPU_DEAD: |
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 7ace07dad6a3..c442f6ad15ff 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c | |||
| @@ -979,6 +979,8 @@ static int pxa168_init_phy(struct net_device *dev) | |||
| 979 | return 0; | 979 | return 0; |
| 980 | 980 | ||
| 981 | pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); | 981 | pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); |
| 982 | if (IS_ERR(pep->phy)) | ||
| 983 | return PTR_ERR(pep->phy); | ||
| 982 | if (!pep->phy) | 984 | if (!pep->phy) |
| 983 | return -ENODEV; | 985 | return -ENODEV; |
| 984 | 986 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index c0d7b7296236..a386f047c1af 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
| @@ -405,7 +405,6 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, | |||
| 405 | u32 packets = 0; | 405 | u32 packets = 0; |
| 406 | u32 bytes = 0; | 406 | u32 bytes = 0; |
| 407 | int factor = priv->cqe_factor; | 407 | int factor = priv->cqe_factor; |
| 408 | u64 timestamp = 0; | ||
| 409 | int done = 0; | 408 | int done = 0; |
| 410 | int budget = priv->tx_work_limit; | 409 | int budget = priv->tx_work_limit; |
| 411 | u32 last_nr_txbb; | 410 | u32 last_nr_txbb; |
| @@ -445,9 +444,12 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, | |||
| 445 | new_index = be16_to_cpu(cqe->wqe_index) & size_mask; | 444 | new_index = be16_to_cpu(cqe->wqe_index) & size_mask; |
| 446 | 445 | ||
| 447 | do { | 446 | do { |
| 447 | u64 timestamp = 0; | ||
| 448 | |||
| 448 | txbbs_skipped += last_nr_txbb; | 449 | txbbs_skipped += last_nr_txbb; |
| 449 | ring_index = (ring_index + last_nr_txbb) & size_mask; | 450 | ring_index = (ring_index + last_nr_txbb) & size_mask; |
| 450 | if (ring->tx_info[ring_index].ts_requested) | 451 | |
| 452 | if (unlikely(ring->tx_info[ring_index].ts_requested)) | ||
| 451 | timestamp = mlx4_en_get_cqe_ts(cqe); | 453 | timestamp = mlx4_en_get_cqe_ts(cqe); |
| 452 | 454 | ||
| 453 | /* free next descriptor */ | 455 | /* free next descriptor */ |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index 1cf722eba607..559d11a443bc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig | |||
| @@ -14,6 +14,7 @@ config MLX5_CORE_EN | |||
| 14 | bool "Mellanox Technologies ConnectX-4 Ethernet support" | 14 | bool "Mellanox Technologies ConnectX-4 Ethernet support" |
| 15 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE | 15 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
| 16 | select PTP_1588_CLOCK | 16 | select PTP_1588_CLOCK |
| 17 | select VXLAN if MLX5_CORE=y | ||
| 17 | default n | 18 | default n |
| 18 | ---help--- | 19 | ---help--- |
| 19 | Ethernet support in Mellanox Technologies ConnectX-4 NIC. | 20 | Ethernet support in Mellanox Technologies ConnectX-4 NIC. |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 879e6276c473..3881dce0cc30 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
| @@ -567,6 +567,7 @@ struct mlx5e_priv { | |||
| 567 | struct mlx5e_vxlan_db vxlan; | 567 | struct mlx5e_vxlan_db vxlan; |
| 568 | 568 | ||
| 569 | struct mlx5e_params params; | 569 | struct mlx5e_params params; |
| 570 | struct workqueue_struct *wq; | ||
| 570 | struct work_struct update_carrier_work; | 571 | struct work_struct update_carrier_work; |
| 571 | struct work_struct set_rx_mode_work; | 572 | struct work_struct set_rx_mode_work; |
| 572 | struct delayed_work update_stats_work; | 573 | struct delayed_work update_stats_work; |
| @@ -609,7 +610,7 @@ enum mlx5e_link_mode { | |||
| 609 | MLX5E_100GBASE_KR4 = 22, | 610 | MLX5E_100GBASE_KR4 = 22, |
| 610 | MLX5E_100GBASE_LR4 = 23, | 611 | MLX5E_100GBASE_LR4 = 23, |
| 611 | MLX5E_100BASE_TX = 24, | 612 | MLX5E_100BASE_TX = 24, |
| 612 | MLX5E_100BASE_T = 25, | 613 | MLX5E_1000BASE_T = 25, |
| 613 | MLX5E_10GBASE_T = 26, | 614 | MLX5E_10GBASE_T = 26, |
| 614 | MLX5E_25GBASE_CR = 27, | 615 | MLX5E_25GBASE_CR = 27, |
| 615 | MLX5E_25GBASE_KR = 28, | 616 | MLX5E_25GBASE_KR = 28, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 68834b715f6c..3476ab844634 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
| @@ -138,10 +138,10 @@ static const struct { | |||
| 138 | [MLX5E_100BASE_TX] = { | 138 | [MLX5E_100BASE_TX] = { |
| 139 | .speed = 100, | 139 | .speed = 100, |
| 140 | }, | 140 | }, |
| 141 | [MLX5E_100BASE_T] = { | 141 | [MLX5E_1000BASE_T] = { |
| 142 | .supported = SUPPORTED_100baseT_Full, | 142 | .supported = SUPPORTED_1000baseT_Full, |
| 143 | .advertised = ADVERTISED_100baseT_Full, | 143 | .advertised = ADVERTISED_1000baseT_Full, |
| 144 | .speed = 100, | 144 | .speed = 1000, |
| 145 | }, | 145 | }, |
| 146 | [MLX5E_10GBASE_T] = { | 146 | [MLX5E_10GBASE_T] = { |
| 147 | .supported = SUPPORTED_10000baseT_Full, | 147 | .supported = SUPPORTED_10000baseT_Full, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index e0adb604f461..d4dfc5ce516a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
| @@ -262,9 +262,8 @@ static void mlx5e_update_stats_work(struct work_struct *work) | |||
| 262 | mutex_lock(&priv->state_lock); | 262 | mutex_lock(&priv->state_lock); |
| 263 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { | 263 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 264 | mlx5e_update_stats(priv); | 264 | mlx5e_update_stats(priv); |
| 265 | schedule_delayed_work(dwork, | 265 | queue_delayed_work(priv->wq, dwork, |
| 266 | msecs_to_jiffies( | 266 | msecs_to_jiffies(MLX5E_UPDATE_STATS_INTERVAL)); |
| 267 | MLX5E_UPDATE_STATS_INTERVAL)); | ||
| 268 | } | 267 | } |
| 269 | mutex_unlock(&priv->state_lock); | 268 | mutex_unlock(&priv->state_lock); |
| 270 | } | 269 | } |
| @@ -280,7 +279,7 @@ static void mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv, | |||
| 280 | switch (event) { | 279 | switch (event) { |
| 281 | case MLX5_DEV_EVENT_PORT_UP: | 280 | case MLX5_DEV_EVENT_PORT_UP: |
| 282 | case MLX5_DEV_EVENT_PORT_DOWN: | 281 | case MLX5_DEV_EVENT_PORT_DOWN: |
| 283 | schedule_work(&priv->update_carrier_work); | 282 | queue_work(priv->wq, &priv->update_carrier_work); |
| 284 | break; | 283 | break; |
| 285 | 284 | ||
| 286 | default: | 285 | default: |
| @@ -1404,24 +1403,50 @@ static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv) | |||
| 1404 | return 0; | 1403 | return 0; |
| 1405 | } | 1404 | } |
| 1406 | 1405 | ||
| 1407 | static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | 1406 | static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) |
| 1408 | { | 1407 | { |
| 1409 | struct mlx5e_priv *priv = netdev_priv(netdev); | ||
| 1410 | struct mlx5_core_dev *mdev = priv->mdev; | 1408 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1411 | int hw_mtu; | 1409 | u16 hw_mtu = MLX5E_SW2HW_MTU(mtu); |
| 1412 | int err; | 1410 | int err; |
| 1413 | 1411 | ||
| 1414 | err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1); | 1412 | err = mlx5_set_port_mtu(mdev, hw_mtu, 1); |
| 1415 | if (err) | 1413 | if (err) |
| 1416 | return err; | 1414 | return err; |
| 1417 | 1415 | ||
| 1418 | mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); | 1416 | /* Update vport context MTU */ |
| 1417 | mlx5_modify_nic_vport_mtu(mdev, hw_mtu); | ||
| 1418 | return 0; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) | ||
| 1422 | { | ||
| 1423 | struct mlx5_core_dev *mdev = priv->mdev; | ||
| 1424 | u16 hw_mtu = 0; | ||
| 1425 | int err; | ||
| 1419 | 1426 | ||
| 1420 | if (MLX5E_HW2SW_MTU(hw_mtu) != netdev->mtu) | 1427 | err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu); |
| 1421 | netdev_warn(netdev, "%s: Port MTU %d is different than netdev mtu %d\n", | 1428 | if (err || !hw_mtu) /* fallback to port oper mtu */ |
| 1422 | __func__, MLX5E_HW2SW_MTU(hw_mtu), netdev->mtu); | 1429 | mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); |
| 1430 | |||
| 1431 | *mtu = MLX5E_HW2SW_MTU(hw_mtu); | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | ||
| 1435 | { | ||
| 1436 | struct mlx5e_priv *priv = netdev_priv(netdev); | ||
| 1437 | u16 mtu; | ||
| 1438 | int err; | ||
| 1423 | 1439 | ||
| 1424 | netdev->mtu = MLX5E_HW2SW_MTU(hw_mtu); | 1440 | err = mlx5e_set_mtu(priv, netdev->mtu); |
| 1441 | if (err) | ||
| 1442 | return err; | ||
| 1443 | |||
| 1444 | mlx5e_query_mtu(priv, &mtu); | ||
| 1445 | if (mtu != netdev->mtu) | ||
| 1446 | netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", | ||
| 1447 | __func__, mtu, netdev->mtu); | ||
| 1448 | |||
| 1449 | netdev->mtu = mtu; | ||
| 1425 | return 0; | 1450 | return 0; |
| 1426 | } | 1451 | } |
| 1427 | 1452 | ||
| @@ -1479,7 +1504,7 @@ int mlx5e_open_locked(struct net_device *netdev) | |||
| 1479 | mlx5e_update_carrier(priv); | 1504 | mlx5e_update_carrier(priv); |
| 1480 | mlx5e_timestamp_init(priv); | 1505 | mlx5e_timestamp_init(priv); |
| 1481 | 1506 | ||
| 1482 | schedule_delayed_work(&priv->update_stats_work, 0); | 1507 | queue_delayed_work(priv->wq, &priv->update_stats_work, 0); |
| 1483 | 1508 | ||
| 1484 | return 0; | 1509 | return 0; |
| 1485 | 1510 | ||
| @@ -1935,7 +1960,7 @@ static void mlx5e_set_rx_mode(struct net_device *dev) | |||
| 1935 | { | 1960 | { |
| 1936 | struct mlx5e_priv *priv = netdev_priv(dev); | 1961 | struct mlx5e_priv *priv = netdev_priv(dev); |
| 1937 | 1962 | ||
| 1938 | schedule_work(&priv->set_rx_mode_work); | 1963 | queue_work(priv->wq, &priv->set_rx_mode_work); |
| 1939 | } | 1964 | } |
| 1940 | 1965 | ||
| 1941 | static int mlx5e_set_mac(struct net_device *netdev, void *addr) | 1966 | static int mlx5e_set_mac(struct net_device *netdev, void *addr) |
| @@ -1950,7 +1975,7 @@ static int mlx5e_set_mac(struct net_device *netdev, void *addr) | |||
| 1950 | ether_addr_copy(netdev->dev_addr, saddr->sa_data); | 1975 | ether_addr_copy(netdev->dev_addr, saddr->sa_data); |
| 1951 | netif_addr_unlock_bh(netdev); | 1976 | netif_addr_unlock_bh(netdev); |
| 1952 | 1977 | ||
| 1953 | schedule_work(&priv->set_rx_mode_work); | 1978 | queue_work(priv->wq, &priv->set_rx_mode_work); |
| 1954 | 1979 | ||
| 1955 | return 0; | 1980 | return 0; |
| 1956 | } | 1981 | } |
| @@ -1999,22 +2024,27 @@ static int mlx5e_set_features(struct net_device *netdev, | |||
| 1999 | return err; | 2024 | return err; |
| 2000 | } | 2025 | } |
| 2001 | 2026 | ||
| 2027 | #define MXL5_HW_MIN_MTU 64 | ||
| 2028 | #define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN) | ||
| 2029 | |||
| 2002 | static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) | 2030 | static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) |
| 2003 | { | 2031 | { |
| 2004 | struct mlx5e_priv *priv = netdev_priv(netdev); | 2032 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 2005 | struct mlx5_core_dev *mdev = priv->mdev; | 2033 | struct mlx5_core_dev *mdev = priv->mdev; |
| 2006 | bool was_opened; | 2034 | bool was_opened; |
| 2007 | int max_mtu; | 2035 | u16 max_mtu; |
| 2036 | u16 min_mtu; | ||
| 2008 | int err = 0; | 2037 | int err = 0; |
| 2009 | 2038 | ||
| 2010 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); | 2039 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); |
| 2011 | 2040 | ||
| 2012 | max_mtu = MLX5E_HW2SW_MTU(max_mtu); | 2041 | max_mtu = MLX5E_HW2SW_MTU(max_mtu); |
| 2042 | min_mtu = MLX5E_HW2SW_MTU(MXL5E_MIN_MTU); | ||
| 2013 | 2043 | ||
| 2014 | if (new_mtu > max_mtu) { | 2044 | if (new_mtu > max_mtu || new_mtu < min_mtu) { |
| 2015 | netdev_err(netdev, | 2045 | netdev_err(netdev, |
| 2016 | "%s: Bad MTU (%d) > (%d) Max\n", | 2046 | "%s: Bad MTU (%d), valid range is: [%d..%d]\n", |
| 2017 | __func__, new_mtu, max_mtu); | 2047 | __func__, new_mtu, min_mtu, max_mtu); |
| 2018 | return -EINVAL; | 2048 | return -EINVAL; |
| 2019 | } | 2049 | } |
| 2020 | 2050 | ||
| @@ -2127,7 +2157,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev, | |||
| 2127 | if (!mlx5e_vxlan_allowed(priv->mdev)) | 2157 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2128 | return; | 2158 | return; |
| 2129 | 2159 | ||
| 2130 | mlx5e_vxlan_add_port(priv, be16_to_cpu(port)); | 2160 | mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 1); |
| 2131 | } | 2161 | } |
| 2132 | 2162 | ||
| 2133 | static void mlx5e_del_vxlan_port(struct net_device *netdev, | 2163 | static void mlx5e_del_vxlan_port(struct net_device *netdev, |
| @@ -2138,7 +2168,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev, | |||
| 2138 | if (!mlx5e_vxlan_allowed(priv->mdev)) | 2168 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2139 | return; | 2169 | return; |
| 2140 | 2170 | ||
| 2141 | mlx5e_vxlan_del_port(priv, be16_to_cpu(port)); | 2171 | mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 0); |
| 2142 | } | 2172 | } |
| 2143 | 2173 | ||
| 2144 | static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, | 2174 | static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, |
| @@ -2467,10 +2497,14 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) | |||
| 2467 | 2497 | ||
| 2468 | priv = netdev_priv(netdev); | 2498 | priv = netdev_priv(netdev); |
| 2469 | 2499 | ||
| 2500 | priv->wq = create_singlethread_workqueue("mlx5e"); | ||
| 2501 | if (!priv->wq) | ||
| 2502 | goto err_free_netdev; | ||
| 2503 | |||
| 2470 | err = mlx5_alloc_map_uar(mdev, &priv->cq_uar, false); | 2504 | err = mlx5_alloc_map_uar(mdev, &priv->cq_uar, false); |
| 2471 | if (err) { | 2505 | if (err) { |
| 2472 | mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err); | 2506 | mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err); |
| 2473 | goto err_free_netdev; | 2507 | goto err_destroy_wq; |
| 2474 | } | 2508 | } |
| 2475 | 2509 | ||
| 2476 | err = mlx5_core_alloc_pd(mdev, &priv->pdn); | 2510 | err = mlx5_core_alloc_pd(mdev, &priv->pdn); |
| @@ -2549,7 +2583,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) | |||
| 2549 | vxlan_get_rx_port(netdev); | 2583 | vxlan_get_rx_port(netdev); |
| 2550 | 2584 | ||
| 2551 | mlx5e_enable_async_events(priv); | 2585 | mlx5e_enable_async_events(priv); |
| 2552 | schedule_work(&priv->set_rx_mode_work); | 2586 | queue_work(priv->wq, &priv->set_rx_mode_work); |
| 2553 | 2587 | ||
| 2554 | return priv; | 2588 | return priv; |
| 2555 | 2589 | ||
| @@ -2586,6 +2620,9 @@ err_dealloc_pd: | |||
| 2586 | err_unmap_free_uar: | 2620 | err_unmap_free_uar: |
| 2587 | mlx5_unmap_free_uar(mdev, &priv->cq_uar); | 2621 | mlx5_unmap_free_uar(mdev, &priv->cq_uar); |
| 2588 | 2622 | ||
| 2623 | err_destroy_wq: | ||
| 2624 | destroy_workqueue(priv->wq); | ||
| 2625 | |||
| 2589 | err_free_netdev: | 2626 | err_free_netdev: |
| 2590 | free_netdev(netdev); | 2627 | free_netdev(netdev); |
| 2591 | 2628 | ||
| @@ -2599,10 +2636,19 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) | |||
| 2599 | 2636 | ||
| 2600 | set_bit(MLX5E_STATE_DESTROYING, &priv->state); | 2637 | set_bit(MLX5E_STATE_DESTROYING, &priv->state); |
| 2601 | 2638 | ||
| 2602 | schedule_work(&priv->set_rx_mode_work); | 2639 | queue_work(priv->wq, &priv->set_rx_mode_work); |
| 2603 | mlx5e_disable_async_events(priv); | 2640 | mlx5e_disable_async_events(priv); |
| 2604 | flush_scheduled_work(); | 2641 | flush_workqueue(priv->wq); |
| 2605 | unregister_netdev(netdev); | 2642 | if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { |
| 2643 | netif_device_detach(netdev); | ||
| 2644 | mutex_lock(&priv->state_lock); | ||
| 2645 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) | ||
| 2646 | mlx5e_close_locked(netdev); | ||
| 2647 | mutex_unlock(&priv->state_lock); | ||
| 2648 | } else { | ||
| 2649 | unregister_netdev(netdev); | ||
| 2650 | } | ||
| 2651 | |||
| 2606 | mlx5e_tc_cleanup(priv); | 2652 | mlx5e_tc_cleanup(priv); |
| 2607 | mlx5e_vxlan_cleanup(priv); | 2653 | mlx5e_vxlan_cleanup(priv); |
| 2608 | mlx5e_destroy_flow_tables(priv); | 2654 | mlx5e_destroy_flow_tables(priv); |
| @@ -2615,7 +2661,11 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) | |||
| 2615 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); | 2661 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); |
| 2616 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); | 2662 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); |
| 2617 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); | 2663 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); |
| 2618 | free_netdev(netdev); | 2664 | cancel_delayed_work_sync(&priv->update_stats_work); |
| 2665 | destroy_workqueue(priv->wq); | ||
| 2666 | |||
| 2667 | if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) | ||
| 2668 | free_netdev(netdev); | ||
| 2619 | } | 2669 | } |
| 2620 | 2670 | ||
| 2621 | static void *mlx5e_get_netdev(void *vpriv) | 2671 | static void *mlx5e_get_netdev(void *vpriv) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5121be4675d1..89cce97d46c6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
| @@ -1065,33 +1065,6 @@ unlock_fg: | |||
| 1065 | return rule; | 1065 | return rule; |
| 1066 | } | 1066 | } |
| 1067 | 1067 | ||
| 1068 | static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft, | ||
| 1069 | u8 match_criteria_enable, | ||
| 1070 | u32 *match_criteria, | ||
| 1071 | u32 *match_value, | ||
| 1072 | u8 action, | ||
| 1073 | u32 flow_tag, | ||
| 1074 | struct mlx5_flow_destination *dest) | ||
| 1075 | { | ||
| 1076 | struct mlx5_flow_rule *rule; | ||
| 1077 | struct mlx5_flow_group *g; | ||
| 1078 | |||
| 1079 | g = create_autogroup(ft, match_criteria_enable, match_criteria); | ||
| 1080 | if (IS_ERR(g)) | ||
| 1081 | return (void *)g; | ||
| 1082 | |||
| 1083 | rule = add_rule_fg(g, match_value, | ||
| 1084 | action, flow_tag, dest); | ||
| 1085 | if (IS_ERR(rule)) { | ||
| 1086 | /* Remove assumes refcount > 0 and autogroup creates a group | ||
| 1087 | * with a refcount = 0. | ||
| 1088 | */ | ||
| 1089 | tree_get_node(&g->node); | ||
| 1090 | tree_remove_node(&g->node); | ||
| 1091 | } | ||
| 1092 | return rule; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | static struct mlx5_flow_rule * | 1068 | static struct mlx5_flow_rule * |
| 1096 | _mlx5_add_flow_rule(struct mlx5_flow_table *ft, | 1069 | _mlx5_add_flow_rule(struct mlx5_flow_table *ft, |
| 1097 | u8 match_criteria_enable, | 1070 | u8 match_criteria_enable, |
| @@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft, | |||
| 1119 | goto unlock; | 1092 | goto unlock; |
| 1120 | } | 1093 | } |
| 1121 | 1094 | ||
| 1122 | rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria, | 1095 | g = create_autogroup(ft, match_criteria_enable, match_criteria); |
| 1123 | match_value, action, flow_tag, dest); | 1096 | if (IS_ERR(g)) { |
| 1097 | rule = (void *)g; | ||
| 1098 | goto unlock; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | rule = add_rule_fg(g, match_value, | ||
| 1102 | action, flow_tag, dest); | ||
| 1103 | if (IS_ERR(rule)) { | ||
| 1104 | /* Remove assumes refcount > 0 and autogroup creates a group | ||
| 1105 | * with a refcount = 0. | ||
| 1106 | */ | ||
| 1107 | unlock_ref_node(&ft->node); | ||
| 1108 | tree_get_node(&g->node); | ||
| 1109 | tree_remove_node(&g->node); | ||
| 1110 | return rule; | ||
| 1111 | } | ||
| 1124 | unlock: | 1112 | unlock: |
| 1125 | unlock_ref_node(&ft->node); | 1113 | unlock_ref_node(&ft->node); |
| 1126 | return rule; | 1114 | return rule; |
| @@ -1288,7 +1276,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, | |||
| 1288 | { | 1276 | { |
| 1289 | struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; | 1277 | struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; |
| 1290 | int prio; | 1278 | int prio; |
| 1291 | static struct fs_prio *fs_prio; | 1279 | struct fs_prio *fs_prio; |
| 1292 | struct mlx5_flow_namespace *ns; | 1280 | struct mlx5_flow_namespace *ns; |
| 1293 | 1281 | ||
| 1294 | if (!root_ns) | 1282 | if (!root_ns) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 3f3b2fae4991..6892746fd10d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
| @@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
| 966 | int err; | 966 | int err; |
| 967 | 967 | ||
| 968 | mutex_lock(&dev->intf_state_mutex); | 968 | mutex_lock(&dev->intf_state_mutex); |
| 969 | if (dev->interface_state == MLX5_INTERFACE_STATE_UP) { | 969 | if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
| 970 | dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", | 970 | dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", |
| 971 | __func__); | 971 | __func__); |
| 972 | goto out; | 972 | goto out; |
| @@ -1133,7 +1133,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
| 1133 | if (err) | 1133 | if (err) |
| 1134 | pr_info("failed request module on %s\n", MLX5_IB_MOD); | 1134 | pr_info("failed request module on %s\n", MLX5_IB_MOD); |
| 1135 | 1135 | ||
| 1136 | dev->interface_state = MLX5_INTERFACE_STATE_UP; | 1136 | clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); |
| 1137 | set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | ||
| 1137 | out: | 1138 | out: |
| 1138 | mutex_unlock(&dev->intf_state_mutex); | 1139 | mutex_unlock(&dev->intf_state_mutex); |
| 1139 | 1140 | ||
| @@ -1207,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
| 1207 | } | 1208 | } |
| 1208 | 1209 | ||
| 1209 | mutex_lock(&dev->intf_state_mutex); | 1210 | mutex_lock(&dev->intf_state_mutex); |
| 1210 | if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) { | 1211 | if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { |
| 1211 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", | 1212 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", |
| 1212 | __func__); | 1213 | __func__); |
| 1213 | goto out; | 1214 | goto out; |
| @@ -1241,7 +1242,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
| 1241 | mlx5_cmd_cleanup(dev); | 1242 | mlx5_cmd_cleanup(dev); |
| 1242 | 1243 | ||
| 1243 | out: | 1244 | out: |
| 1244 | dev->interface_state = MLX5_INTERFACE_STATE_DOWN; | 1245 | clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
| 1246 | set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | ||
| 1245 | mutex_unlock(&dev->intf_state_mutex); | 1247 | mutex_unlock(&dev->intf_state_mutex); |
| 1246 | return err; | 1248 | return err; |
| 1247 | } | 1249 | } |
| @@ -1452,6 +1454,18 @@ static const struct pci_error_handlers mlx5_err_handler = { | |||
| 1452 | .resume = mlx5_pci_resume | 1454 | .resume = mlx5_pci_resume |
| 1453 | }; | 1455 | }; |
| 1454 | 1456 | ||
| 1457 | static void shutdown(struct pci_dev *pdev) | ||
| 1458 | { | ||
| 1459 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | ||
| 1460 | struct mlx5_priv *priv = &dev->priv; | ||
| 1461 | |||
| 1462 | dev_info(&pdev->dev, "Shutdown was called\n"); | ||
| 1463 | /* Notify mlx5 clients that the kernel is being shut down */ | ||
| 1464 | set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state); | ||
| 1465 | mlx5_unload_one(dev, priv); | ||
| 1466 | mlx5_pci_disable_device(dev); | ||
| 1467 | } | ||
| 1468 | |||
| 1455 | static const struct pci_device_id mlx5_core_pci_table[] = { | 1469 | static const struct pci_device_id mlx5_core_pci_table[] = { |
| 1456 | { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ | 1470 | { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ |
| 1457 | { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ | 1471 | { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ |
| @@ -1459,6 +1473,8 @@ static const struct pci_device_id mlx5_core_pci_table[] = { | |||
| 1459 | { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ | 1473 | { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ |
| 1460 | { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ | 1474 | { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ |
| 1461 | { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ | 1475 | { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ |
| 1476 | { PCI_VDEVICE(MELLANOX, 0x1017) }, /* ConnectX-5 */ | ||
| 1477 | { PCI_VDEVICE(MELLANOX, 0x1018), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 VF */ | ||
| 1462 | { 0, } | 1478 | { 0, } |
| 1463 | }; | 1479 | }; |
| 1464 | 1480 | ||
| @@ -1469,6 +1485,7 @@ static struct pci_driver mlx5_core_driver = { | |||
| 1469 | .id_table = mlx5_core_pci_table, | 1485 | .id_table = mlx5_core_pci_table, |
| 1470 | .probe = init_one, | 1486 | .probe = init_one, |
| 1471 | .remove = remove_one, | 1487 | .remove = remove_one, |
| 1488 | .shutdown = shutdown, | ||
| 1472 | .err_handler = &mlx5_err_handler, | 1489 | .err_handler = &mlx5_err_handler, |
| 1473 | .sriov_configure = mlx5_core_sriov_configure, | 1490 | .sriov_configure = mlx5_core_sriov_configure, |
| 1474 | }; | 1491 | }; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index ae378c575deb..53cc1e2c693b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c | |||
| @@ -247,8 +247,8 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, | |||
| 247 | } | 247 | } |
| 248 | EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); | 248 | EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); |
| 249 | 249 | ||
| 250 | static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, | 250 | static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu, |
| 251 | int *max_mtu, int *oper_mtu, u8 port) | 251 | u16 *max_mtu, u16 *oper_mtu, u8 port) |
| 252 | { | 252 | { |
| 253 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; | 253 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
| 254 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; | 254 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
| @@ -268,7 +268,7 @@ static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, | |||
| 268 | *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); | 268 | *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) | 271 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port) |
| 272 | { | 272 | { |
| 273 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; | 273 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
| 274 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; | 274 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
| @@ -283,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) | |||
| 283 | } | 283 | } |
| 284 | EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); | 284 | EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); |
| 285 | 285 | ||
| 286 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, | 286 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, |
| 287 | u8 port) | 287 | u8 port) |
| 288 | { | 288 | { |
| 289 | mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); | 289 | mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); |
| 290 | } | 290 | } |
| 291 | EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); | 291 | EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); |
| 292 | 292 | ||
| 293 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, | 293 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, |
| 294 | u8 port) | 294 | u8 port) |
| 295 | { | 295 | { |
| 296 | mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); | 296 | mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/uar.c b/drivers/net/ethernet/mellanox/mlx5/core/uar.c index 8ba080e441a1..5ff8af472bf5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/uar.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/uar.c | |||
| @@ -269,8 +269,10 @@ EXPORT_SYMBOL(mlx5_alloc_map_uar); | |||
| 269 | 269 | ||
| 270 | void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar) | 270 | void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar) |
| 271 | { | 271 | { |
| 272 | iounmap(uar->map); | 272 | if (uar->map) |
| 273 | iounmap(uar->bf_map); | 273 | iounmap(uar->map); |
| 274 | else | ||
| 275 | iounmap(uar->bf_map); | ||
| 274 | mlx5_cmd_free_uar(mdev, uar->index); | 276 | mlx5_cmd_free_uar(mdev, uar->index); |
| 275 | } | 277 | } |
| 276 | EXPORT_SYMBOL(mlx5_unmap_free_uar); | 278 | EXPORT_SYMBOL(mlx5_unmap_free_uar); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index bd518405859e..b69dadcfb897 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c | |||
| @@ -196,6 +196,46 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev, | |||
| 196 | } | 196 | } |
| 197 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); | 197 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); |
| 198 | 198 | ||
| 199 | int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu) | ||
| 200 | { | ||
| 201 | int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); | ||
| 202 | u32 *out; | ||
| 203 | int err; | ||
| 204 | |||
| 205 | out = mlx5_vzalloc(outlen); | ||
| 206 | if (!out) | ||
| 207 | return -ENOMEM; | ||
| 208 | |||
| 209 | err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); | ||
| 210 | if (!err) | ||
| 211 | *mtu = MLX5_GET(query_nic_vport_context_out, out, | ||
| 212 | nic_vport_context.mtu); | ||
| 213 | |||
| 214 | kvfree(out); | ||
| 215 | return err; | ||
| 216 | } | ||
| 217 | EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mtu); | ||
| 218 | |||
| 219 | int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu) | ||
| 220 | { | ||
| 221 | int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); | ||
| 222 | void *in; | ||
| 223 | int err; | ||
| 224 | |||
| 225 | in = mlx5_vzalloc(inlen); | ||
| 226 | if (!in) | ||
| 227 | return -ENOMEM; | ||
| 228 | |||
| 229 | MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1); | ||
| 230 | MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu); | ||
| 231 | |||
| 232 | err = mlx5_modify_nic_vport_context(mdev, in, inlen); | ||
| 233 | |||
| 234 | kvfree(in); | ||
| 235 | return err; | ||
| 236 | } | ||
| 237 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu); | ||
| 238 | |||
| 199 | int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, | 239 | int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, |
| 200 | u32 vport, | 240 | u32 vport, |
| 201 | enum mlx5_list_type list_type, | 241 | enum mlx5_list_type list_type, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c index 9f10df25f3cd..f2fd1ef16da7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | |||
| @@ -95,21 +95,22 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) | |||
| 95 | return vxlan; | 95 | return vxlan; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) | 98 | static void mlx5e_vxlan_add_port(struct work_struct *work) |
| 99 | { | 99 | { |
| 100 | struct mlx5e_vxlan_work *vxlan_work = | ||
| 101 | container_of(work, struct mlx5e_vxlan_work, work); | ||
| 102 | struct mlx5e_priv *priv = vxlan_work->priv; | ||
| 100 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; | 103 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 104 | u16 port = vxlan_work->port; | ||
| 101 | struct mlx5e_vxlan *vxlan; | 105 | struct mlx5e_vxlan *vxlan; |
| 102 | int err; | 106 | int err; |
| 103 | 107 | ||
| 104 | err = mlx5e_vxlan_core_add_port_cmd(priv->mdev, port); | 108 | if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) |
| 105 | if (err) | 109 | goto free_work; |
| 106 | return err; | ||
| 107 | 110 | ||
| 108 | vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); | 111 | vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); |
| 109 | if (!vxlan) { | 112 | if (!vxlan) |
| 110 | err = -ENOMEM; | ||
| 111 | goto err_delete_port; | 113 | goto err_delete_port; |
| 112 | } | ||
| 113 | 114 | ||
| 114 | vxlan->udp_port = port; | 115 | vxlan->udp_port = port; |
| 115 | 116 | ||
| @@ -119,13 +120,14 @@ int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) | |||
| 119 | if (err) | 120 | if (err) |
| 120 | goto err_free; | 121 | goto err_free; |
| 121 | 122 | ||
| 122 | return 0; | 123 | goto free_work; |
| 123 | 124 | ||
| 124 | err_free: | 125 | err_free: |
| 125 | kfree(vxlan); | 126 | kfree(vxlan); |
| 126 | err_delete_port: | 127 | err_delete_port: |
| 127 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); | 128 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 128 | return err; | 129 | free_work: |
| 130 | kfree(vxlan_work); | ||
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) | 133 | static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) |
| @@ -145,12 +147,36 @@ static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) | |||
| 145 | kfree(vxlan); | 147 | kfree(vxlan); |
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port) | 150 | static void mlx5e_vxlan_del_port(struct work_struct *work) |
| 149 | { | 151 | { |
| 150 | if (!mlx5e_vxlan_lookup_port(priv, port)) | 152 | struct mlx5e_vxlan_work *vxlan_work = |
| 151 | return; | 153 | container_of(work, struct mlx5e_vxlan_work, work); |
| 154 | struct mlx5e_priv *priv = vxlan_work->priv; | ||
| 155 | u16 port = vxlan_work->port; | ||
| 152 | 156 | ||
| 153 | __mlx5e_vxlan_core_del_port(priv, port); | 157 | __mlx5e_vxlan_core_del_port(priv, port); |
| 158 | |||
| 159 | kfree(vxlan_work); | ||
| 160 | } | ||
| 161 | |||
| 162 | void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, | ||
| 163 | u16 port, int add) | ||
| 164 | { | ||
| 165 | struct mlx5e_vxlan_work *vxlan_work; | ||
| 166 | |||
| 167 | vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC); | ||
| 168 | if (!vxlan_work) | ||
| 169 | return; | ||
| 170 | |||
| 171 | if (add) | ||
| 172 | INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_port); | ||
| 173 | else | ||
| 174 | INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_port); | ||
| 175 | |||
| 176 | vxlan_work->priv = priv; | ||
| 177 | vxlan_work->port = port; | ||
| 178 | vxlan_work->sa_family = sa_family; | ||
| 179 | queue_work(priv->wq, &vxlan_work->work); | ||
| 154 | } | 180 | } |
| 155 | 181 | ||
| 156 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) | 182 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h index a01685056ab1..129f3527aa14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | |||
| @@ -39,6 +39,13 @@ struct mlx5e_vxlan { | |||
| 39 | u16 udp_port; | 39 | u16 udp_port; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | struct mlx5e_vxlan_work { | ||
| 43 | struct work_struct work; | ||
| 44 | struct mlx5e_priv *priv; | ||
| 45 | sa_family_t sa_family; | ||
| 46 | u16 port; | ||
| 47 | }; | ||
| 48 | |||
| 42 | static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) | 49 | static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) |
| 43 | { | 50 | { |
| 44 | return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) && | 51 | return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) && |
| @@ -46,8 +53,8 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) | |||
| 46 | } | 53 | } |
| 47 | 54 | ||
| 48 | void mlx5e_vxlan_init(struct mlx5e_priv *priv); | 55 | void mlx5e_vxlan_init(struct mlx5e_priv *priv); |
| 49 | int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port); | 56 | void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, |
| 50 | void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port); | 57 | u16 port, int add); |
| 51 | struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port); | 58 | struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port); |
| 52 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv); | 59 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv); |
| 53 | 60 | ||
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 270c9eeb7ab6..6d1a956e3f77 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c | |||
| @@ -2668,9 +2668,9 @@ static int myri10ge_close(struct net_device *dev) | |||
| 2668 | 2668 | ||
| 2669 | del_timer_sync(&mgp->watchdog_timer); | 2669 | del_timer_sync(&mgp->watchdog_timer); |
| 2670 | mgp->running = MYRI10GE_ETH_STOPPING; | 2670 | mgp->running = MYRI10GE_ETH_STOPPING; |
| 2671 | local_bh_disable(); /* myri10ge_ss_lock_napi needs bh disabled */ | ||
| 2672 | for (i = 0; i < mgp->num_slices; i++) { | 2671 | for (i = 0; i < mgp->num_slices; i++) { |
| 2673 | napi_disable(&mgp->ss[i].napi); | 2672 | napi_disable(&mgp->ss[i].napi); |
| 2673 | local_bh_disable(); /* myri10ge_ss_lock_napi needs this */ | ||
| 2674 | /* Lock the slice to prevent the busy_poll handler from | 2674 | /* Lock the slice to prevent the busy_poll handler from |
| 2675 | * accessing it. Later when we bring the NIC up, myri10ge_open | 2675 | * accessing it. Later when we bring the NIC up, myri10ge_open |
| 2676 | * resets the slice including this lock. | 2676 | * resets the slice including this lock. |
| @@ -2679,8 +2679,8 @@ static int myri10ge_close(struct net_device *dev) | |||
| 2679 | pr_info("Slice %d locked\n", i); | 2679 | pr_info("Slice %d locked\n", i); |
| 2680 | mdelay(1); | 2680 | mdelay(1); |
| 2681 | } | 2681 | } |
| 2682 | local_bh_enable(); | ||
| 2682 | } | 2683 | } |
| 2683 | local_bh_enable(); | ||
| 2684 | netif_carrier_off(dev); | 2684 | netif_carrier_off(dev); |
| 2685 | 2685 | ||
| 2686 | netif_tx_stop_all_queues(dev); | 2686 | netif_tx_stop_all_queues(dev); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 55007f1e6bbc..caf6ddb7ea76 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
| @@ -37,8 +37,8 @@ | |||
| 37 | 37 | ||
| 38 | #define _QLCNIC_LINUX_MAJOR 5 | 38 | #define _QLCNIC_LINUX_MAJOR 5 |
| 39 | #define _QLCNIC_LINUX_MINOR 3 | 39 | #define _QLCNIC_LINUX_MINOR 3 |
| 40 | #define _QLCNIC_LINUX_SUBVERSION 63 | 40 | #define _QLCNIC_LINUX_SUBVERSION 64 |
| 41 | #define QLCNIC_LINUX_VERSIONID "5.3.63" | 41 | #define QLCNIC_LINUX_VERSIONID "5.3.64" |
| 42 | #define QLCNIC_DRV_IDC_VER 0x01 | 42 | #define QLCNIC_DRV_IDC_VER 0x01 |
| 43 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 43 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
| 44 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 44 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 98d33d462c6c..1681084cc96f 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
| @@ -1920,6 +1920,10 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context, | |||
| 1920 | return 0; | 1920 | return 0; |
| 1921 | } | 1921 | } |
| 1922 | 1922 | ||
| 1923 | if (nic_data->datapath_caps & | ||
| 1924 | 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN) | ||
| 1925 | return -EOPNOTSUPP; | ||
| 1926 | |||
| 1923 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, | 1927 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, |
| 1924 | nic_data->vport_id); | 1928 | nic_data->vport_id); |
| 1925 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type); | 1929 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type); |
| @@ -2923,9 +2927,16 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, | |||
| 2923 | bool replacing) | 2927 | bool replacing) |
| 2924 | { | 2928 | { |
| 2925 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | 2929 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 2930 | u32 flags = spec->flags; | ||
| 2926 | 2931 | ||
| 2927 | memset(inbuf, 0, MC_CMD_FILTER_OP_IN_LEN); | 2932 | memset(inbuf, 0, MC_CMD_FILTER_OP_IN_LEN); |
| 2928 | 2933 | ||
| 2934 | /* Remove RSS flag if we don't have an RSS context. */ | ||
| 2935 | if (flags & EFX_FILTER_FLAG_RX_RSS && | ||
| 2936 | spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT && | ||
| 2937 | nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) | ||
| 2938 | flags &= ~EFX_FILTER_FLAG_RX_RSS; | ||
| 2939 | |||
| 2929 | if (replacing) { | 2940 | if (replacing) { |
| 2930 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, | 2941 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, |
| 2931 | MC_CMD_FILTER_OP_IN_OP_REPLACE); | 2942 | MC_CMD_FILTER_OP_IN_OP_REPLACE); |
| @@ -2985,10 +2996,10 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, | |||
| 2985 | spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ? | 2996 | spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ? |
| 2986 | 0 : spec->dmaq_id); | 2997 | 0 : spec->dmaq_id); |
| 2987 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE, | 2998 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE, |
| 2988 | (spec->flags & EFX_FILTER_FLAG_RX_RSS) ? | 2999 | (flags & EFX_FILTER_FLAG_RX_RSS) ? |
| 2989 | MC_CMD_FILTER_OP_IN_RX_MODE_RSS : | 3000 | MC_CMD_FILTER_OP_IN_RX_MODE_RSS : |
| 2990 | MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); | 3001 | MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); |
| 2991 | if (spec->flags & EFX_FILTER_FLAG_RX_RSS) | 3002 | if (flags & EFX_FILTER_FLAG_RX_RSS) |
| 2992 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, | 3003 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, |
| 2993 | spec->rss_context != | 3004 | spec->rss_context != |
| 2994 | EFX_FILTER_RSS_CONTEXT_DEFAULT ? | 3005 | EFX_FILTER_RSS_CONTEXT_DEFAULT ? |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 44022b1845ce..afb90d129cb6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | |||
| @@ -49,7 +49,6 @@ struct socfpga_dwmac { | |||
| 49 | u32 reg_shift; | 49 | u32 reg_shift; |
| 50 | struct device *dev; | 50 | struct device *dev; |
| 51 | struct regmap *sys_mgr_base_addr; | 51 | struct regmap *sys_mgr_base_addr; |
| 52 | struct reset_control *stmmac_rst; | ||
| 53 | void __iomem *splitter_base; | 52 | void __iomem *splitter_base; |
| 54 | bool f2h_ptp_ref_clk; | 53 | bool f2h_ptp_ref_clk; |
| 55 | }; | 54 | }; |
| @@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * | |||
| 92 | struct device_node *np_splitter; | 91 | struct device_node *np_splitter; |
| 93 | struct resource res_splitter; | 92 | struct resource res_splitter; |
| 94 | 93 | ||
| 95 | dwmac->stmmac_rst = devm_reset_control_get(dev, | ||
| 96 | STMMAC_RESOURCE_NAME); | ||
| 97 | if (IS_ERR(dwmac->stmmac_rst)) { | ||
| 98 | dev_info(dev, "Could not get reset control!\n"); | ||
| 99 | if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER) | ||
| 100 | return -EPROBE_DEFER; | ||
| 101 | dwmac->stmmac_rst = NULL; | ||
| 102 | } | ||
| 103 | |||
| 104 | dwmac->interface = of_get_phy_mode(np); | 94 | dwmac->interface = of_get_phy_mode(np); |
| 105 | 95 | ||
| 106 | sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); | 96 | sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); |
| @@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) | |||
| 194 | return 0; | 184 | return 0; |
| 195 | } | 185 | } |
| 196 | 186 | ||
| 197 | static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) | ||
| 198 | { | ||
| 199 | struct socfpga_dwmac *dwmac = priv; | ||
| 200 | |||
| 201 | /* On socfpga platform exit, assert and hold reset to the | ||
| 202 | * enet controller - the default state after a hard reset. | ||
| 203 | */ | ||
| 204 | if (dwmac->stmmac_rst) | ||
| 205 | reset_control_assert(dwmac->stmmac_rst); | ||
| 206 | } | ||
| 207 | |||
| 208 | static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | 187 | static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) |
| 209 | { | 188 | { |
| 210 | struct socfpga_dwmac *dwmac = priv; | 189 | struct socfpga_dwmac *dwmac = priv; |
| 211 | struct net_device *ndev = platform_get_drvdata(pdev); | 190 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 212 | struct stmmac_priv *stpriv = NULL; | 191 | struct stmmac_priv *stpriv = NULL; |
| 213 | int ret = 0; | 192 | int ret = 0; |
| 214 | 193 | ||
| 215 | if (ndev) | 194 | if (!ndev) |
| 216 | stpriv = netdev_priv(ndev); | 195 | return -EINVAL; |
| 196 | |||
| 197 | stpriv = netdev_priv(ndev); | ||
| 198 | if (!stpriv) | ||
| 199 | return -EINVAL; | ||
| 217 | 200 | ||
| 218 | /* Assert reset to the enet controller before changing the phy mode */ | 201 | /* Assert reset to the enet controller before changing the phy mode */ |
| 219 | if (dwmac->stmmac_rst) | 202 | if (stpriv->stmmac_rst) |
| 220 | reset_control_assert(dwmac->stmmac_rst); | 203 | reset_control_assert(stpriv->stmmac_rst); |
| 221 | 204 | ||
| 222 | /* Setup the phy mode in the system manager registers according to | 205 | /* Setup the phy mode in the system manager registers according to |
| 223 | * devicetree configuration | 206 | * devicetree configuration |
| @@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | |||
| 227 | /* Deassert reset for the phy configuration to be sampled by | 210 | /* Deassert reset for the phy configuration to be sampled by |
| 228 | * the enet controller, and operation to start in requested mode | 211 | * the enet controller, and operation to start in requested mode |
| 229 | */ | 212 | */ |
| 230 | if (dwmac->stmmac_rst) | 213 | if (stpriv->stmmac_rst) |
| 231 | reset_control_deassert(dwmac->stmmac_rst); | 214 | reset_control_deassert(stpriv->stmmac_rst); |
| 232 | 215 | ||
| 233 | /* Before the enet controller is suspended, the phy is suspended. | 216 | /* Before the enet controller is suspended, the phy is suspended. |
| 234 | * This causes the phy clock to be gated. The enet controller is | 217 | * This causes the phy clock to be gated. The enet controller is |
| @@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | |||
| 245 | * control register 0, and can be modified by the phy driver | 228 | * control register 0, and can be modified by the phy driver |
| 246 | * framework. | 229 | * framework. |
| 247 | */ | 230 | */ |
| 248 | if (stpriv && stpriv->phydev) | 231 | if (stpriv->phydev) |
| 249 | phy_resume(stpriv->phydev); | 232 | phy_resume(stpriv->phydev); |
| 250 | 233 | ||
| 251 | return ret; | 234 | return ret; |
| @@ -285,14 +268,13 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) | |||
| 285 | 268 | ||
| 286 | plat_dat->bsp_priv = dwmac; | 269 | plat_dat->bsp_priv = dwmac; |
| 287 | plat_dat->init = socfpga_dwmac_init; | 270 | plat_dat->init = socfpga_dwmac_init; |
| 288 | plat_dat->exit = socfpga_dwmac_exit; | ||
| 289 | plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; | 271 | plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; |
| 290 | 272 | ||
| 291 | ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv); | 273 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
| 292 | if (ret) | 274 | if (!ret) |
| 293 | return ret; | 275 | ret = socfpga_dwmac_init(pdev, dwmac); |
| 294 | 276 | ||
| 295 | return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | 277 | return ret; |
| 296 | } | 278 | } |
| 297 | 279 | ||
| 298 | static const struct of_device_id socfpga_dwmac_match[] = { | 280 | static const struct of_device_id socfpga_dwmac_match[] = { |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index bbb77cd8ad67..e2fcdf1eec44 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -367,7 +367,6 @@ struct cpsw_priv { | |||
| 367 | spinlock_t lock; | 367 | spinlock_t lock; |
| 368 | struct platform_device *pdev; | 368 | struct platform_device *pdev; |
| 369 | struct net_device *ndev; | 369 | struct net_device *ndev; |
| 370 | struct device_node *phy_node; | ||
| 371 | struct napi_struct napi_rx; | 370 | struct napi_struct napi_rx; |
| 372 | struct napi_struct napi_tx; | 371 | struct napi_struct napi_tx; |
| 373 | struct device *dev; | 372 | struct device *dev; |
| @@ -1148,25 +1147,34 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) | |||
| 1148 | cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, | 1147 | cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, |
| 1149 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); | 1148 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); |
| 1150 | 1149 | ||
| 1151 | if (priv->phy_node) | 1150 | if (slave->data->phy_node) { |
| 1152 | slave->phy = of_phy_connect(priv->ndev, priv->phy_node, | 1151 | slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, |
| 1153 | &cpsw_adjust_link, 0, slave->data->phy_if); | 1152 | &cpsw_adjust_link, 0, slave->data->phy_if); |
| 1154 | else | 1153 | if (!slave->phy) { |
| 1154 | dev_err(priv->dev, "phy \"%s\" not found on slave %d\n", | ||
| 1155 | slave->data->phy_node->full_name, | ||
| 1156 | slave->slave_num); | ||
| 1157 | return; | ||
| 1158 | } | ||
| 1159 | } else { | ||
| 1155 | slave->phy = phy_connect(priv->ndev, slave->data->phy_id, | 1160 | slave->phy = phy_connect(priv->ndev, slave->data->phy_id, |
| 1156 | &cpsw_adjust_link, slave->data->phy_if); | 1161 | &cpsw_adjust_link, slave->data->phy_if); |
| 1157 | if (IS_ERR(slave->phy)) { | 1162 | if (IS_ERR(slave->phy)) { |
| 1158 | dev_err(priv->dev, "phy %s not found on slave %d\n", | 1163 | dev_err(priv->dev, |
| 1159 | slave->data->phy_id, slave->slave_num); | 1164 | "phy \"%s\" not found on slave %d, err %ld\n", |
| 1160 | slave->phy = NULL; | 1165 | slave->data->phy_id, slave->slave_num, |
| 1161 | } else { | 1166 | PTR_ERR(slave->phy)); |
| 1162 | phy_attached_info(slave->phy); | 1167 | slave->phy = NULL; |
| 1168 | return; | ||
| 1169 | } | ||
| 1170 | } | ||
| 1163 | 1171 | ||
| 1164 | phy_start(slave->phy); | 1172 | phy_attached_info(slave->phy); |
| 1165 | 1173 | ||
| 1166 | /* Configure GMII_SEL register */ | 1174 | phy_start(slave->phy); |
| 1167 | cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, | 1175 | |
| 1168 | slave->slave_num); | 1176 | /* Configure GMII_SEL register */ |
| 1169 | } | 1177 | cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); |
| 1170 | } | 1178 | } |
| 1171 | 1179 | ||
| 1172 | static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) | 1180 | static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) |
| @@ -1940,12 +1948,11 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, | |||
| 1940 | slave->port_vlan = data->dual_emac_res_vlan; | 1948 | slave->port_vlan = data->dual_emac_res_vlan; |
| 1941 | } | 1949 | } |
| 1942 | 1950 | ||
| 1943 | static int cpsw_probe_dt(struct cpsw_priv *priv, | 1951 | static int cpsw_probe_dt(struct cpsw_platform_data *data, |
| 1944 | struct platform_device *pdev) | 1952 | struct platform_device *pdev) |
| 1945 | { | 1953 | { |
| 1946 | struct device_node *node = pdev->dev.of_node; | 1954 | struct device_node *node = pdev->dev.of_node; |
| 1947 | struct device_node *slave_node; | 1955 | struct device_node *slave_node; |
| 1948 | struct cpsw_platform_data *data = &priv->data; | ||
| 1949 | int i = 0, ret; | 1956 | int i = 0, ret; |
| 1950 | u32 prop; | 1957 | u32 prop; |
| 1951 | 1958 | ||
| @@ -2033,25 +2040,21 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, | |||
| 2033 | if (strcmp(slave_node->name, "slave")) | 2040 | if (strcmp(slave_node->name, "slave")) |
| 2034 | continue; | 2041 | continue; |
| 2035 | 2042 | ||
| 2036 | priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); | 2043 | slave_data->phy_node = of_parse_phandle(slave_node, |
| 2044 | "phy-handle", 0); | ||
| 2037 | parp = of_get_property(slave_node, "phy_id", &lenp); | 2045 | parp = of_get_property(slave_node, "phy_id", &lenp); |
| 2038 | if (of_phy_is_fixed_link(slave_node)) { | 2046 | if (slave_data->phy_node) { |
| 2039 | struct device_node *phy_node; | 2047 | dev_dbg(&pdev->dev, |
| 2040 | struct phy_device *phy_dev; | 2048 | "slave[%d] using phy-handle=\"%s\"\n", |
| 2041 | 2049 | i, slave_data->phy_node->full_name); | |
| 2050 | } else if (of_phy_is_fixed_link(slave_node)) { | ||
| 2042 | /* In the case of a fixed PHY, the DT node associated | 2051 | /* In the case of a fixed PHY, the DT node associated |
| 2043 | * to the PHY is the Ethernet MAC DT node. | 2052 | * to the PHY is the Ethernet MAC DT node. |
| 2044 | */ | 2053 | */ |
| 2045 | ret = of_phy_register_fixed_link(slave_node); | 2054 | ret = of_phy_register_fixed_link(slave_node); |
| 2046 | if (ret) | 2055 | if (ret) |
| 2047 | return ret; | 2056 | return ret; |
| 2048 | phy_node = of_node_get(slave_node); | 2057 | slave_data->phy_node = of_node_get(slave_node); |
| 2049 | phy_dev = of_phy_find_device(phy_node); | ||
| 2050 | if (!phy_dev) | ||
| 2051 | return -ENODEV; | ||
| 2052 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
| 2053 | PHY_ID_FMT, phy_dev->mdio.bus->id, | ||
| 2054 | phy_dev->mdio.addr); | ||
| 2055 | } else if (parp) { | 2058 | } else if (parp) { |
| 2056 | u32 phyid; | 2059 | u32 phyid; |
| 2057 | struct device_node *mdio_node; | 2060 | struct device_node *mdio_node; |
| @@ -2072,7 +2075,9 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, | |||
| 2072 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | 2075 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), |
| 2073 | PHY_ID_FMT, mdio->name, phyid); | 2076 | PHY_ID_FMT, mdio->name, phyid); |
| 2074 | } else { | 2077 | } else { |
| 2075 | dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i); | 2078 | dev_err(&pdev->dev, |
| 2079 | "No slave[%d] phy_id, phy-handle, or fixed-link property\n", | ||
| 2080 | i); | ||
| 2076 | goto no_phy_slave; | 2081 | goto no_phy_slave; |
| 2077 | } | 2082 | } |
| 2078 | slave_data->phy_if = of_get_phy_mode(slave_node); | 2083 | slave_data->phy_if = of_get_phy_mode(slave_node); |
| @@ -2275,7 +2280,7 @@ static int cpsw_probe(struct platform_device *pdev) | |||
| 2275 | /* Select default pin state */ | 2280 | /* Select default pin state */ |
| 2276 | pinctrl_pm_select_default_state(&pdev->dev); | 2281 | pinctrl_pm_select_default_state(&pdev->dev); |
| 2277 | 2282 | ||
| 2278 | if (cpsw_probe_dt(priv, pdev)) { | 2283 | if (cpsw_probe_dt(&priv->data, pdev)) { |
| 2279 | dev_err(&pdev->dev, "cpsw: platform data missing\n"); | 2284 | dev_err(&pdev->dev, "cpsw: platform data missing\n"); |
| 2280 | ret = -ENODEV; | 2285 | ret = -ENODEV; |
| 2281 | goto clean_runtime_disable_ret; | 2286 | goto clean_runtime_disable_ret; |
diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h index 442a7038e660..e50afd1b2eda 100644 --- a/drivers/net/ethernet/ti/cpsw.h +++ b/drivers/net/ethernet/ti/cpsw.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/phy.h> | 18 | #include <linux/phy.h> |
| 19 | 19 | ||
| 20 | struct cpsw_slave_data { | 20 | struct cpsw_slave_data { |
| 21 | struct device_node *phy_node; | ||
| 21 | char phy_id[MII_BUS_ID_SIZE]; | 22 | char phy_id[MII_BUS_ID_SIZE]; |
| 22 | int phy_if; | 23 | int phy_if; |
| 23 | u8 mac_addr[ETH_ALEN]; | 24 | u8 mac_addr[ETH_ALEN]; |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 58d58f002559..f56d66e6ec15 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
| @@ -1512,7 +1512,10 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) | |||
| 1512 | 1512 | ||
| 1513 | /* TODO: Add phy read and write and private statistics get feature */ | 1513 | /* TODO: Add phy read and write and private statistics get feature */ |
| 1514 | 1514 | ||
| 1515 | return phy_mii_ioctl(priv->phydev, ifrq, cmd); | 1515 | if (priv->phydev) |
| 1516 | return phy_mii_ioctl(priv->phydev, ifrq, cmd); | ||
| 1517 | else | ||
| 1518 | return -EOPNOTSUPP; | ||
| 1516 | } | 1519 | } |
| 1517 | 1520 | ||
| 1518 | static int match_first_device(struct device *dev, void *data) | 1521 | static int match_first_device(struct device *dev, void *data) |
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 13214a6492ac..743b18266a7c 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | |||
| @@ -1622,7 +1622,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) | |||
| 1622 | continue; | 1622 | continue; |
| 1623 | 1623 | ||
| 1624 | /* copy hw scan info */ | 1624 | /* copy hw scan info */ |
| 1625 | memcpy(target->hwinfo, scan_info, scan_info->size); | 1625 | memcpy(target->hwinfo, scan_info, be16_to_cpu(scan_info->size)); |
| 1626 | target->essid_len = strnlen(scan_info->essid, | 1626 | target->essid_len = strnlen(scan_info->essid, |
| 1627 | sizeof(scan_info->essid)); | 1627 | sizeof(scan_info->essid)); |
| 1628 | target->rate_len = 0; | 1628 | target->rate_len = 0; |
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 84d3e5ca8817..c6385617bfb2 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
| @@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
| 880 | macsec_skb_cb(skb)->valid = false; | 880 | macsec_skb_cb(skb)->valid = false; |
| 881 | skb = skb_share_check(skb, GFP_ATOMIC); | 881 | skb = skb_share_check(skb, GFP_ATOMIC); |
| 882 | if (!skb) | 882 | if (!skb) |
| 883 | return NULL; | 883 | return ERR_PTR(-ENOMEM); |
| 884 | 884 | ||
| 885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); | 885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); |
| 886 | if (!req) { | 886 | if (!req) { |
| 887 | kfree_skb(skb); | 887 | kfree_skb(skb); |
| 888 | return NULL; | 888 | return ERR_PTR(-ENOMEM); |
| 889 | } | 889 | } |
| 890 | 890 | ||
| 891 | hdr = (struct macsec_eth_header *)skb->data; | 891 | hdr = (struct macsec_eth_header *)skb->data; |
| @@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
| 905 | skb = skb_unshare(skb, GFP_ATOMIC); | 905 | skb = skb_unshare(skb, GFP_ATOMIC); |
| 906 | if (!skb) { | 906 | if (!skb) { |
| 907 | aead_request_free(req); | 907 | aead_request_free(req); |
| 908 | return NULL; | 908 | return ERR_PTR(-ENOMEM); |
| 909 | } | 909 | } |
| 910 | } else { | 910 | } else { |
| 911 | /* integrity only: all headers + data authenticated */ | 911 | /* integrity only: all headers + data authenticated */ |
| @@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
| 921 | dev_hold(dev); | 921 | dev_hold(dev); |
| 922 | ret = crypto_aead_decrypt(req); | 922 | ret = crypto_aead_decrypt(req); |
| 923 | if (ret == -EINPROGRESS) { | 923 | if (ret == -EINPROGRESS) { |
| 924 | return NULL; | 924 | return ERR_PTR(ret); |
| 925 | } else if (ret != 0) { | 925 | } else if (ret != 0) { |
| 926 | /* decryption/authentication failed | 926 | /* decryption/authentication failed |
| 927 | * 10.6 if validateFrames is disabled, deliver anyway | 927 | * 10.6 if validateFrames is disabled, deliver anyway |
| 928 | */ | 928 | */ |
| 929 | if (ret != -EBADMSG) { | 929 | if (ret != -EBADMSG) { |
| 930 | kfree_skb(skb); | 930 | kfree_skb(skb); |
| 931 | skb = NULL; | 931 | skb = ERR_PTR(ret); |
| 932 | } | 932 | } |
| 933 | } else { | 933 | } else { |
| 934 | macsec_skb_cb(skb)->valid = true; | 934 | macsec_skb_cb(skb)->valid = true; |
| @@ -1146,8 +1146,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) | |||
| 1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) | 1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) |
| 1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); | 1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); |
| 1148 | 1148 | ||
| 1149 | if (!skb) { | 1149 | if (IS_ERR(skb)) { |
| 1150 | macsec_rxsa_put(rx_sa); | 1150 | /* the decrypt callback needs the reference */ |
| 1151 | if (PTR_ERR(skb) != -EINPROGRESS) | ||
| 1152 | macsec_rxsa_put(rx_sa); | ||
| 1151 | rcu_read_unlock(); | 1153 | rcu_read_unlock(); |
| 1152 | *pskb = NULL; | 1154 | *pskb = NULL; |
| 1153 | return RX_HANDLER_CONSUMED; | 1155 | return RX_HANDLER_CONSUMED; |
| @@ -1161,7 +1163,8 @@ deliver: | |||
| 1161 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); | 1163 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); |
| 1162 | macsec_reset_skb(skb, secy->netdev); | 1164 | macsec_reset_skb(skb, secy->netdev); |
| 1163 | 1165 | ||
| 1164 | macsec_rxsa_put(rx_sa); | 1166 | if (rx_sa) |
| 1167 | macsec_rxsa_put(rx_sa); | ||
| 1165 | count_rx(dev, skb->len); | 1168 | count_rx(dev, skb->len); |
| 1166 | 1169 | ||
| 1167 | rcu_read_unlock(); | 1170 | rcu_read_unlock(); |
| @@ -1622,8 +1625,9 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) | |||
| 1622 | } | 1625 | } |
| 1623 | 1626 | ||
| 1624 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); | 1627 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); |
| 1625 | if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, | 1628 | if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
| 1626 | secy->icv_len)) { | 1629 | secy->key_len, secy->icv_len)) { |
| 1630 | kfree(rx_sa); | ||
| 1627 | rtnl_unlock(); | 1631 | rtnl_unlock(); |
| 1628 | return -ENOMEM; | 1632 | return -ENOMEM; |
| 1629 | } | 1633 | } |
| @@ -1768,6 +1772,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) | |||
| 1768 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); | 1772 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); |
| 1769 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), | 1773 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
| 1770 | secy->key_len, secy->icv_len)) { | 1774 | secy->key_len, secy->icv_len)) { |
| 1775 | kfree(tx_sa); | ||
| 1771 | rtnl_unlock(); | 1776 | rtnl_unlock(); |
| 1772 | return -ENOMEM; | 1777 | return -ENOMEM; |
| 1773 | } | 1778 | } |
| @@ -2227,7 +2232,8 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) | |||
| 2227 | return 1; | 2232 | return 1; |
| 2228 | 2233 | ||
| 2229 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || | 2234 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || |
| 2230 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 2235 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, |
| 2236 | MACSEC_DEFAULT_CIPHER_ID) || | ||
| 2231 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || | 2237 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || |
| 2232 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || | 2238 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || |
| 2233 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || | 2239 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || |
| @@ -2268,7 +2274,7 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
| 2268 | if (!hdr) | 2274 | if (!hdr) |
| 2269 | return -EMSGSIZE; | 2275 | return -EMSGSIZE; |
| 2270 | 2276 | ||
| 2271 | rtnl_lock(); | 2277 | genl_dump_check_consistent(cb, hdr, &macsec_fam); |
| 2272 | 2278 | ||
| 2273 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) | 2279 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) |
| 2274 | goto nla_put_failure; | 2280 | goto nla_put_failure; |
| @@ -2429,18 +2435,17 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
| 2429 | 2435 | ||
| 2430 | nla_nest_end(skb, rxsc_list); | 2436 | nla_nest_end(skb, rxsc_list); |
| 2431 | 2437 | ||
| 2432 | rtnl_unlock(); | ||
| 2433 | |||
| 2434 | genlmsg_end(skb, hdr); | 2438 | genlmsg_end(skb, hdr); |
| 2435 | 2439 | ||
| 2436 | return 0; | 2440 | return 0; |
| 2437 | 2441 | ||
| 2438 | nla_put_failure: | 2442 | nla_put_failure: |
| 2439 | rtnl_unlock(); | ||
| 2440 | genlmsg_cancel(skb, hdr); | 2443 | genlmsg_cancel(skb, hdr); |
| 2441 | return -EMSGSIZE; | 2444 | return -EMSGSIZE; |
| 2442 | } | 2445 | } |
| 2443 | 2446 | ||
| 2447 | static int macsec_generation = 1; /* protected by RTNL */ | ||
| 2448 | |||
| 2444 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | 2449 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) |
| 2445 | { | 2450 | { |
| 2446 | struct net *net = sock_net(skb->sk); | 2451 | struct net *net = sock_net(skb->sk); |
| @@ -2450,6 +2455,10 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2450 | dev_idx = cb->args[0]; | 2455 | dev_idx = cb->args[0]; |
| 2451 | 2456 | ||
| 2452 | d = 0; | 2457 | d = 0; |
| 2458 | rtnl_lock(); | ||
| 2459 | |||
| 2460 | cb->seq = macsec_generation; | ||
| 2461 | |||
| 2453 | for_each_netdev(net, dev) { | 2462 | for_each_netdev(net, dev) { |
| 2454 | struct macsec_secy *secy; | 2463 | struct macsec_secy *secy; |
| 2455 | 2464 | ||
| @@ -2467,6 +2476,7 @@ next: | |||
| 2467 | } | 2476 | } |
| 2468 | 2477 | ||
| 2469 | done: | 2478 | done: |
| 2479 | rtnl_unlock(); | ||
| 2470 | cb->args[0] = d; | 2480 | cb->args[0] = d; |
| 2471 | return skb->len; | 2481 | return skb->len; |
| 2472 | } | 2482 | } |
| @@ -2920,10 +2930,14 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) | |||
| 2920 | struct net_device *real_dev = macsec->real_dev; | 2930 | struct net_device *real_dev = macsec->real_dev; |
| 2921 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); | 2931 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); |
| 2922 | 2932 | ||
| 2933 | macsec_generation++; | ||
| 2934 | |||
| 2923 | unregister_netdevice_queue(dev, head); | 2935 | unregister_netdevice_queue(dev, head); |
| 2924 | list_del_rcu(&macsec->secys); | 2936 | list_del_rcu(&macsec->secys); |
| 2925 | if (list_empty(&rxd->secys)) | 2937 | if (list_empty(&rxd->secys)) { |
| 2926 | netdev_rx_handler_unregister(real_dev); | 2938 | netdev_rx_handler_unregister(real_dev); |
| 2939 | kfree(rxd); | ||
| 2940 | } | ||
| 2927 | 2941 | ||
| 2928 | macsec_del_dev(macsec); | 2942 | macsec_del_dev(macsec); |
| 2929 | } | 2943 | } |
| @@ -2945,8 +2959,10 @@ static int register_macsec_dev(struct net_device *real_dev, | |||
| 2945 | 2959 | ||
| 2946 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, | 2960 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, |
| 2947 | rxd); | 2961 | rxd); |
| 2948 | if (err < 0) | 2962 | if (err < 0) { |
| 2963 | kfree(rxd); | ||
| 2949 | return err; | 2964 | return err; |
| 2965 | } | ||
| 2950 | } | 2966 | } |
| 2951 | 2967 | ||
| 2952 | list_add_tail_rcu(&macsec->secys, &rxd->secys); | 2968 | list_add_tail_rcu(&macsec->secys, &rxd->secys); |
| @@ -3066,6 +3082,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, | |||
| 3066 | if (err < 0) | 3082 | if (err < 0) |
| 3067 | goto del_dev; | 3083 | goto del_dev; |
| 3068 | 3084 | ||
| 3085 | macsec_generation++; | ||
| 3086 | |||
| 3069 | dev_hold(real_dev); | 3087 | dev_hold(real_dev); |
| 3070 | 3088 | ||
| 3071 | return 0; | 3089 | return 0; |
| @@ -3079,7 +3097,7 @@ unregister: | |||
| 3079 | 3097 | ||
| 3080 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | 3098 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) |
| 3081 | { | 3099 | { |
| 3082 | u64 csid = DEFAULT_CIPHER_ID; | 3100 | u64 csid = MACSEC_DEFAULT_CIPHER_ID; |
| 3083 | u8 icv_len = DEFAULT_ICV_LEN; | 3101 | u8 icv_len = DEFAULT_ICV_LEN; |
| 3084 | int flag; | 3102 | int flag; |
| 3085 | bool es, scb, sci; | 3103 | bool es, scb, sci; |
| @@ -3094,8 +3112,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
| 3094 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); | 3112 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); |
| 3095 | 3113 | ||
| 3096 | switch (csid) { | 3114 | switch (csid) { |
| 3097 | case DEFAULT_CIPHER_ID: | 3115 | case MACSEC_DEFAULT_CIPHER_ID: |
| 3098 | case DEFAULT_CIPHER_ALT: | 3116 | case MACSEC_DEFAULT_CIPHER_ALT: |
| 3099 | if (icv_len < MACSEC_MIN_ICV_LEN || | 3117 | if (icv_len < MACSEC_MIN_ICV_LEN || |
| 3100 | icv_len > MACSEC_MAX_ICV_LEN) | 3118 | icv_len > MACSEC_MAX_ICV_LEN) |
| 3101 | return -EINVAL; | 3119 | return -EINVAL; |
| @@ -3129,8 +3147,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
| 3129 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) | 3147 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) |
| 3130 | return -EINVAL; | 3148 | return -EINVAL; |
| 3131 | 3149 | ||
| 3132 | if ((data[IFLA_MACSEC_PROTECT] && | 3150 | if ((data[IFLA_MACSEC_REPLAY_PROTECT] && |
| 3133 | nla_get_u8(data[IFLA_MACSEC_PROTECT])) && | 3151 | nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT])) && |
| 3134 | !data[IFLA_MACSEC_WINDOW]) | 3152 | !data[IFLA_MACSEC_WINDOW]) |
| 3135 | return -EINVAL; | 3153 | return -EINVAL; |
| 3136 | 3154 | ||
| @@ -3168,7 +3186,8 @@ static int macsec_fill_info(struct sk_buff *skb, | |||
| 3168 | 3186 | ||
| 3169 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || | 3187 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || |
| 3170 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || | 3188 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || |
| 3171 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 3189 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, |
| 3190 | MACSEC_DEFAULT_CIPHER_ID) || | ||
| 3172 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || | 3191 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || |
| 3173 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || | 3192 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || |
| 3174 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || | 3193 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || |
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index b3ffaee30858..f279a897a5c7 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c | |||
| @@ -359,27 +359,25 @@ static void at803x_link_change_notify(struct phy_device *phydev) | |||
| 359 | * in the FIFO. In such cases, the FIFO enters an error mode it | 359 | * in the FIFO. In such cases, the FIFO enters an error mode it |
| 360 | * cannot recover from by software. | 360 | * cannot recover from by software. |
| 361 | */ | 361 | */ |
| 362 | if (phydev->drv->phy_id == ATH8030_PHY_ID) { | 362 | if (phydev->state == PHY_NOLINK) { |
| 363 | if (phydev->state == PHY_NOLINK) { | 363 | if (priv->gpiod_reset && !priv->phy_reset) { |
| 364 | if (priv->gpiod_reset && !priv->phy_reset) { | 364 | struct at803x_context context; |
| 365 | struct at803x_context context; | 365 | |
| 366 | 366 | at803x_context_save(phydev, &context); | |
| 367 | at803x_context_save(phydev, &context); | 367 | |
| 368 | 368 | gpiod_set_value(priv->gpiod_reset, 1); | |
| 369 | gpiod_set_value(priv->gpiod_reset, 1); | 369 | msleep(1); |
| 370 | msleep(1); | 370 | gpiod_set_value(priv->gpiod_reset, 0); |
| 371 | gpiod_set_value(priv->gpiod_reset, 0); | 371 | msleep(1); |
| 372 | msleep(1); | 372 | |
| 373 | 373 | at803x_context_restore(phydev, &context); | |
| 374 | at803x_context_restore(phydev, &context); | 374 | |
| 375 | 375 | phydev_dbg(phydev, "%s(): phy was reset\n", | |
| 376 | phydev_dbg(phydev, "%s(): phy was reset\n", | 376 | __func__); |
| 377 | __func__); | 377 | priv->phy_reset = true; |
| 378 | priv->phy_reset = true; | ||
| 379 | } | ||
| 380 | } else { | ||
| 381 | priv->phy_reset = false; | ||
| 382 | } | 378 | } |
| 379 | } else { | ||
| 380 | priv->phy_reset = false; | ||
| 383 | } | 381 | } |
| 384 | } | 382 | } |
| 385 | 383 | ||
| @@ -391,7 +389,6 @@ static struct phy_driver at803x_driver[] = { | |||
| 391 | .phy_id_mask = 0xffffffef, | 389 | .phy_id_mask = 0xffffffef, |
| 392 | .probe = at803x_probe, | 390 | .probe = at803x_probe, |
| 393 | .config_init = at803x_config_init, | 391 | .config_init = at803x_config_init, |
| 394 | .link_change_notify = at803x_link_change_notify, | ||
| 395 | .set_wol = at803x_set_wol, | 392 | .set_wol = at803x_set_wol, |
| 396 | .get_wol = at803x_get_wol, | 393 | .get_wol = at803x_get_wol, |
| 397 | .suspend = at803x_suspend, | 394 | .suspend = at803x_suspend, |
| @@ -427,7 +424,6 @@ static struct phy_driver at803x_driver[] = { | |||
| 427 | .phy_id_mask = 0xffffffef, | 424 | .phy_id_mask = 0xffffffef, |
| 428 | .probe = at803x_probe, | 425 | .probe = at803x_probe, |
| 429 | .config_init = at803x_config_init, | 426 | .config_init = at803x_config_init, |
| 430 | .link_change_notify = at803x_link_change_notify, | ||
| 431 | .set_wol = at803x_set_wol, | 427 | .set_wol = at803x_set_wol, |
| 432 | .get_wol = at803x_get_wol, | 428 | .get_wol = at803x_get_wol, |
| 433 | .suspend = at803x_suspend, | 429 | .suspend = at803x_suspend, |
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index f20890ee03f3..f64778ad9753 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c | |||
| @@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */ | |||
| 269 | struct lan78xx_net *dev; | 269 | struct lan78xx_net *dev; |
| 270 | enum skb_state state; | 270 | enum skb_state state; |
| 271 | size_t length; | 271 | size_t length; |
| 272 | int num_of_packet; | ||
| 272 | }; | 273 | }; |
| 273 | 274 | ||
| 274 | struct usb_context { | 275 | struct usb_context { |
| @@ -1803,7 +1804,34 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) | |||
| 1803 | 1804 | ||
| 1804 | static void lan78xx_link_status_change(struct net_device *net) | 1805 | static void lan78xx_link_status_change(struct net_device *net) |
| 1805 | { | 1806 | { |
| 1806 | /* nothing to do */ | 1807 | struct phy_device *phydev = net->phydev; |
| 1808 | int ret, temp; | ||
| 1809 | |||
| 1810 | /* At forced 100 F/H mode, chip may fail to set mode correctly | ||
| 1811 | * when cable is switched between long(~50+m) and short one. | ||
| 1812 | * As workaround, set to 10 before setting to 100 | ||
| 1813 | * at forced 100 F/H mode. | ||
| 1814 | */ | ||
| 1815 | if (!phydev->autoneg && (phydev->speed == 100)) { | ||
| 1816 | /* disable phy interrupt */ | ||
| 1817 | temp = phy_read(phydev, LAN88XX_INT_MASK); | ||
| 1818 | temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; | ||
| 1819 | ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | ||
| 1820 | |||
| 1821 | temp = phy_read(phydev, MII_BMCR); | ||
| 1822 | temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); | ||
| 1823 | phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ | ||
| 1824 | temp |= BMCR_SPEED100; | ||
| 1825 | phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ | ||
| 1826 | |||
| 1827 | /* clear pending interrupt generated while workaround */ | ||
| 1828 | temp = phy_read(phydev, LAN88XX_INT_STS); | ||
| 1829 | |||
| 1830 | /* enable phy interrupt back */ | ||
| 1831 | temp = phy_read(phydev, LAN88XX_INT_MASK); | ||
| 1832 | temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; | ||
| 1833 | ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | ||
| 1834 | } | ||
| 1807 | } | 1835 | } |
| 1808 | 1836 | ||
| 1809 | static int lan78xx_phy_init(struct lan78xx_net *dev) | 1837 | static int lan78xx_phy_init(struct lan78xx_net *dev) |
| @@ -2464,7 +2492,7 @@ static void tx_complete(struct urb *urb) | |||
| 2464 | struct lan78xx_net *dev = entry->dev; | 2492 | struct lan78xx_net *dev = entry->dev; |
| 2465 | 2493 | ||
| 2466 | if (urb->status == 0) { | 2494 | if (urb->status == 0) { |
| 2467 | dev->net->stats.tx_packets++; | 2495 | dev->net->stats.tx_packets += entry->num_of_packet; |
| 2468 | dev->net->stats.tx_bytes += entry->length; | 2496 | dev->net->stats.tx_bytes += entry->length; |
| 2469 | } else { | 2497 | } else { |
| 2470 | dev->net->stats.tx_errors++; | 2498 | dev->net->stats.tx_errors++; |
| @@ -2681,10 +2709,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) | |||
| 2681 | return; | 2709 | return; |
| 2682 | } | 2710 | } |
| 2683 | 2711 | ||
| 2684 | skb->protocol = eth_type_trans(skb, dev->net); | ||
| 2685 | dev->net->stats.rx_packets++; | 2712 | dev->net->stats.rx_packets++; |
| 2686 | dev->net->stats.rx_bytes += skb->len; | 2713 | dev->net->stats.rx_bytes += skb->len; |
| 2687 | 2714 | ||
| 2715 | skb->protocol = eth_type_trans(skb, dev->net); | ||
| 2716 | |||
| 2688 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", | 2717 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", |
| 2689 | skb->len + sizeof(struct ethhdr), skb->protocol); | 2718 | skb->len + sizeof(struct ethhdr), skb->protocol); |
| 2690 | memset(skb->cb, 0, sizeof(struct skb_data)); | 2719 | memset(skb->cb, 0, sizeof(struct skb_data)); |
| @@ -2934,13 +2963,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) | |||
| 2934 | 2963 | ||
| 2935 | skb_totallen = 0; | 2964 | skb_totallen = 0; |
| 2936 | pkt_cnt = 0; | 2965 | pkt_cnt = 0; |
| 2966 | count = 0; | ||
| 2967 | length = 0; | ||
| 2937 | for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { | 2968 | for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { |
| 2938 | if (skb_is_gso(skb)) { | 2969 | if (skb_is_gso(skb)) { |
| 2939 | if (pkt_cnt) { | 2970 | if (pkt_cnt) { |
| 2940 | /* handle previous packets first */ | 2971 | /* handle previous packets first */ |
| 2941 | break; | 2972 | break; |
| 2942 | } | 2973 | } |
| 2943 | length = skb->len; | 2974 | count = 1; |
| 2975 | length = skb->len - TX_OVERHEAD; | ||
| 2944 | skb2 = skb_dequeue(tqp); | 2976 | skb2 = skb_dequeue(tqp); |
| 2945 | goto gso_skb; | 2977 | goto gso_skb; |
| 2946 | } | 2978 | } |
| @@ -2961,14 +2993,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) | |||
| 2961 | for (count = pos = 0; count < pkt_cnt; count++) { | 2993 | for (count = pos = 0; count < pkt_cnt; count++) { |
| 2962 | skb2 = skb_dequeue(tqp); | 2994 | skb2 = skb_dequeue(tqp); |
| 2963 | if (skb2) { | 2995 | if (skb2) { |
| 2996 | length += (skb2->len - TX_OVERHEAD); | ||
| 2964 | memcpy(skb->data + pos, skb2->data, skb2->len); | 2997 | memcpy(skb->data + pos, skb2->data, skb2->len); |
| 2965 | pos += roundup(skb2->len, sizeof(u32)); | 2998 | pos += roundup(skb2->len, sizeof(u32)); |
| 2966 | dev_kfree_skb(skb2); | 2999 | dev_kfree_skb(skb2); |
| 2967 | } | 3000 | } |
| 2968 | } | 3001 | } |
| 2969 | 3002 | ||
| 2970 | length = skb_totallen; | ||
| 2971 | |||
| 2972 | gso_skb: | 3003 | gso_skb: |
| 2973 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 3004 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 2974 | if (!urb) { | 3005 | if (!urb) { |
| @@ -2980,6 +3011,7 @@ gso_skb: | |||
| 2980 | entry->urb = urb; | 3011 | entry->urb = urb; |
| 2981 | entry->dev = dev; | 3012 | entry->dev = dev; |
| 2982 | entry->length = length; | 3013 | entry->length = length; |
| 3014 | entry->num_of_packet = count; | ||
| 2983 | 3015 | ||
| 2984 | spin_lock_irqsave(&dev->txq.lock, flags); | 3016 | spin_lock_irqsave(&dev->txq.lock, flags); |
| 2985 | ret = usb_autopm_get_interface_async(dev->intf); | 3017 | ret = usb_autopm_get_interface_async(dev->intf); |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index f84080215915..82129eef7774 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
| @@ -411,7 +411,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
| 411 | int ret; | 411 | int ret; |
| 412 | 412 | ||
| 413 | read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); | 413 | read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); |
| 414 | data[0] = 0xc9; | 414 | data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ |
| 415 | data[1] = 0; | 415 | data[1] = 0; |
| 416 | if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) | 416 | if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) |
| 417 | data[1] |= 0x20; /* set full duplex */ | 417 | data[1] |= 0x20; /* set full duplex */ |
| @@ -497,7 +497,7 @@ static void read_bulk_callback(struct urb *urb) | |||
| 497 | pkt_len = buf[count - 3] << 8; | 497 | pkt_len = buf[count - 3] << 8; |
| 498 | pkt_len += buf[count - 4]; | 498 | pkt_len += buf[count - 4]; |
| 499 | pkt_len &= 0xfff; | 499 | pkt_len &= 0xfff; |
| 500 | pkt_len -= 8; | 500 | pkt_len -= 4; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | /* | 503 | /* |
| @@ -528,7 +528,7 @@ static void read_bulk_callback(struct urb *urb) | |||
| 528 | goon: | 528 | goon: |
| 529 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, | 529 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 530 | usb_rcvbulkpipe(pegasus->usb, 1), | 530 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 531 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 531 | pegasus->rx_skb->data, PEGASUS_MTU, |
| 532 | read_bulk_callback, pegasus); | 532 | read_bulk_callback, pegasus); |
| 533 | rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); | 533 | rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| 534 | if (rx_status == -ENODEV) | 534 | if (rx_status == -ENODEV) |
| @@ -569,7 +569,7 @@ static void rx_fixup(unsigned long data) | |||
| 569 | } | 569 | } |
| 570 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, | 570 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 571 | usb_rcvbulkpipe(pegasus->usb, 1), | 571 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 572 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 572 | pegasus->rx_skb->data, PEGASUS_MTU, |
| 573 | read_bulk_callback, pegasus); | 573 | read_bulk_callback, pegasus); |
| 574 | try_again: | 574 | try_again: |
| 575 | status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); | 575 | status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| @@ -823,7 +823,7 @@ static int pegasus_open(struct net_device *net) | |||
| 823 | 823 | ||
| 824 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, | 824 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 825 | usb_rcvbulkpipe(pegasus->usb, 1), | 825 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 826 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 826 | pegasus->rx_skb->data, PEGASUS_MTU, |
| 827 | read_bulk_callback, pegasus); | 827 | read_bulk_callback, pegasus); |
| 828 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { | 828 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { |
| 829 | if (res == -ENODEV) | 829 | if (res == -ENODEV) |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 30033dbe6662..c369db99c005 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/crc32.h> | 29 | #include <linux/crc32.h> |
| 30 | #include <linux/usb/usbnet.h> | 30 | #include <linux/usb/usbnet.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/of_net.h> | ||
| 32 | #include "smsc75xx.h" | 33 | #include "smsc75xx.h" |
| 33 | 34 | ||
| 34 | #define SMSC_CHIPNAME "smsc75xx" | 35 | #define SMSC_CHIPNAME "smsc75xx" |
| @@ -761,6 +762,15 @@ static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | |||
| 761 | 762 | ||
| 762 | static void smsc75xx_init_mac_address(struct usbnet *dev) | 763 | static void smsc75xx_init_mac_address(struct usbnet *dev) |
| 763 | { | 764 | { |
| 765 | const u8 *mac_addr; | ||
| 766 | |||
| 767 | /* maybe the boot loader passed the MAC address in devicetree */ | ||
| 768 | mac_addr = of_get_mac_address(dev->udev->dev.of_node); | ||
| 769 | if (mac_addr) { | ||
| 770 | memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | |||
| 764 | /* try reading mac address from EEPROM */ | 774 | /* try reading mac address from EEPROM */ |
| 765 | if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, | 775 | if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 766 | dev->net->dev_addr) == 0) { | 776 | dev->net->dev_addr) == 0) { |
| @@ -772,7 +782,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev) | |||
| 772 | } | 782 | } |
| 773 | } | 783 | } |
| 774 | 784 | ||
| 775 | /* no eeprom, or eeprom values are invalid. generate random MAC */ | 785 | /* no useful static MAC address found. generate a random one */ |
| 776 | eth_hw_addr_random(dev->net); | 786 | eth_hw_addr_random(dev->net); |
| 777 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); | 787 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 778 | } | 788 | } |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 66b3ab9f614e..2edc2bc6d1b9 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/crc32.h> | 29 | #include <linux/crc32.h> |
| 30 | #include <linux/usb/usbnet.h> | 30 | #include <linux/usb/usbnet.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/of_net.h> | ||
| 32 | #include "smsc95xx.h" | 33 | #include "smsc95xx.h" |
| 33 | 34 | ||
| 34 | #define SMSC_CHIPNAME "smsc95xx" | 35 | #define SMSC_CHIPNAME "smsc95xx" |
| @@ -765,6 +766,15 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | |||
| 765 | 766 | ||
| 766 | static void smsc95xx_init_mac_address(struct usbnet *dev) | 767 | static void smsc95xx_init_mac_address(struct usbnet *dev) |
| 767 | { | 768 | { |
| 769 | const u8 *mac_addr; | ||
| 770 | |||
| 771 | /* maybe the boot loader passed the MAC address in devicetree */ | ||
| 772 | mac_addr = of_get_mac_address(dev->udev->dev.of_node); | ||
| 773 | if (mac_addr) { | ||
| 774 | memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | ||
| 775 | return; | ||
| 776 | } | ||
| 777 | |||
| 768 | /* try reading mac address from EEPROM */ | 778 | /* try reading mac address from EEPROM */ |
| 769 | if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, | 779 | if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 770 | dev->net->dev_addr) == 0) { | 780 | dev->net->dev_addr) == 0) { |
| @@ -775,7 +785,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) | |||
| 775 | } | 785 | } |
| 776 | } | 786 | } |
| 777 | 787 | ||
| 778 | /* no eeprom, or eeprom values are invalid. generate random MAC */ | 788 | /* no useful static MAC address found. generate a random one */ |
| 779 | eth_hw_addr_random(dev->net); | 789 | eth_hw_addr_random(dev->net); |
| 780 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); | 790 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 781 | } | 791 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 8f8793004b9f..1b271b99c49e 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
| @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, | |||
| 274 | }; | 274 | }; |
| 275 | static const int inc[4] = { 0, 100, 0, 0 }; | 275 | static const int inc[4] = { 0, 100, 0, 0 }; |
| 276 | 276 | ||
| 277 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
| 278 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
| 279 | |||
| 277 | cur_bin = -6000; | 280 | cur_bin = -6000; |
| 278 | upper = bin + 100; | 281 | upper = bin + 100; |
| 279 | lower = bin - 100; | 282 | lower = bin - 100; |
| @@ -424,14 +427,9 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, | |||
| 424 | int tmp, new; | 427 | int tmp, new; |
| 425 | int i; | 428 | int i; |
| 426 | 429 | ||
| 427 | int8_t mask_m[123]; | ||
| 428 | int8_t mask_p[123]; | ||
| 429 | int cur_bb_spur; | 430 | int cur_bb_spur; |
| 430 | bool is2GHz = IS_CHAN_2GHZ(chan); | 431 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 431 | 432 | ||
| 432 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
| 433 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
| 434 | |||
| 435 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 433 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
| 436 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | 434 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); |
| 437 | if (AR_NO_SPUR == cur_bb_spur) | 435 | if (AR_NO_SPUR == cur_bb_spur) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index db6624527d99..53d7445a5d12 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
| @@ -178,14 +178,9 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, | |||
| 178 | int i; | 178 | int i; |
| 179 | struct chan_centers centers; | 179 | struct chan_centers centers; |
| 180 | 180 | ||
| 181 | int8_t mask_m[123]; | ||
| 182 | int8_t mask_p[123]; | ||
| 183 | int cur_bb_spur; | 181 | int cur_bb_spur; |
| 184 | bool is2GHz = IS_CHAN_2GHZ(chan); | 182 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 185 | 183 | ||
| 186 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
| 187 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
| 188 | |||
| 189 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 184 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
| 190 | freq = centers.synth_center; | 185 | freq = centers.synth_center; |
| 191 | 186 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index 97be104d1203..b5c57eebf995 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c | |||
| @@ -93,7 +93,7 @@ | |||
| 93 | #define IWL8260_SMEM_OFFSET 0x400000 | 93 | #define IWL8260_SMEM_OFFSET 0x400000 |
| 94 | #define IWL8260_SMEM_LEN 0x68000 | 94 | #define IWL8260_SMEM_LEN 0x68000 |
| 95 | 95 | ||
| 96 | #define IWL8000_FW_PRE "iwlwifi-8000" | 96 | #define IWL8000_FW_PRE "iwlwifi-8000C-" |
| 97 | #define IWL8000_MODULE_FIRMWARE(api) \ | 97 | #define IWL8000_MODULE_FIRMWARE(api) \ |
| 98 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" | 98 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" |
| 99 | 99 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index f899666acb41..9e45bf9c6071 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c | |||
| @@ -238,19 +238,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) | |||
| 238 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", | 238 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", |
| 239 | name_pre, tag); | 239 | name_pre, tag); |
| 240 | 240 | ||
| 241 | /* | ||
| 242 | * Starting 8000B - FW name format has changed. This overwrites the | ||
| 243 | * previous name and uses the new format. | ||
| 244 | */ | ||
| 245 | if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | ||
| 246 | char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); | ||
| 247 | |||
| 248 | if (rev_step != 'A') | ||
| 249 | snprintf(drv->firmware_name, | ||
| 250 | sizeof(drv->firmware_name), "%s%c-%s.ucode", | ||
| 251 | name_pre, rev_step, tag); | ||
| 252 | } | ||
| 253 | |||
| 254 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | 241 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", |
| 255 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | 242 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) |
| 256 | ? "EXPERIMENTAL " : "", | 243 | ? "EXPERIMENTAL " : "", |
| @@ -1060,11 +1047,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
| 1060 | return -EINVAL; | 1047 | return -EINVAL; |
| 1061 | } | 1048 | } |
| 1062 | 1049 | ||
| 1063 | if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && | 1050 | /* |
| 1064 | !gscan_capa, | 1051 | * If ucode advertises that it supports GSCAN but GSCAN |
| 1065 | "GSCAN is supported but capabilities TLV is unavailable\n")) | 1052 | * capabilities TLV is not present, or if it has an old format, |
| 1053 | * warn and continue without GSCAN. | ||
| 1054 | */ | ||
| 1055 | if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && | ||
| 1056 | !gscan_capa) { | ||
| 1057 | IWL_DEBUG_INFO(drv, | ||
| 1058 | "GSCAN is supported but capabilities TLV is unavailable\n"); | ||
| 1066 | __clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT, | 1059 | __clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT, |
| 1067 | capa->_capa); | 1060 | capa->_capa); |
| 1061 | } | ||
| 1068 | 1062 | ||
| 1069 | return 0; | 1063 | return 0; |
| 1070 | 1064 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 4856eac120f6..6938cd37be57 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | |||
| @@ -526,7 +526,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
| 526 | file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; | 526 | file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; |
| 527 | 527 | ||
| 528 | /* Make room for fw's virtual image pages, if it exists */ | 528 | /* Make room for fw's virtual image pages, if it exists */ |
| 529 | if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) | 529 | if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && |
| 530 | mvm->fw_paging_db[0].fw_paging_block) | ||
| 530 | file_len += mvm->num_of_paging_blk * | 531 | file_len += mvm->num_of_paging_blk * |
| 531 | (sizeof(*dump_data) + | 532 | (sizeof(*dump_data) + |
| 532 | sizeof(struct iwl_fw_error_dump_paging) + | 533 | sizeof(struct iwl_fw_error_dump_paging) + |
| @@ -643,7 +644,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
| 643 | } | 644 | } |
| 644 | 645 | ||
| 645 | /* Dump fw's virtual image */ | 646 | /* Dump fw's virtual image */ |
| 646 | if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) { | 647 | if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && |
| 648 | mvm->fw_paging_db[0].fw_paging_block) { | ||
| 647 | for (i = 1; i < mvm->num_of_paging_blk + 1; i++) { | 649 | for (i = 1; i < mvm->num_of_paging_blk + 1; i++) { |
| 648 | struct iwl_fw_error_dump_paging *paging; | 650 | struct iwl_fw_error_dump_paging *paging; |
| 649 | struct page *pages = | 651 | struct page *pages = |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 594cd0dc7df9..09d895fafaf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
| @@ -144,9 +144,11 @@ void iwl_free_fw_paging(struct iwl_mvm *mvm) | |||
| 144 | 144 | ||
| 145 | __free_pages(mvm->fw_paging_db[i].fw_paging_block, | 145 | __free_pages(mvm->fw_paging_db[i].fw_paging_block, |
| 146 | get_order(mvm->fw_paging_db[i].fw_paging_size)); | 146 | get_order(mvm->fw_paging_db[i].fw_paging_size)); |
| 147 | mvm->fw_paging_db[i].fw_paging_block = NULL; | ||
| 147 | } | 148 | } |
| 148 | kfree(mvm->trans->paging_download_buf); | 149 | kfree(mvm->trans->paging_download_buf); |
| 149 | mvm->trans->paging_download_buf = NULL; | 150 | mvm->trans->paging_download_buf = NULL; |
| 151 | mvm->trans->paging_db = NULL; | ||
| 150 | 152 | ||
| 151 | memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db)); | 153 | memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db)); |
| 152 | } | 154 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 05b968506836..79d7cd7d461e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c | |||
| @@ -479,8 +479,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 479 | {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, | 479 | {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, |
| 480 | {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, | 480 | {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, |
| 481 | {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, | 481 | {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, |
| 482 | {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, | ||
| 483 | {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, | ||
| 484 | {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, | ||
| 485 | {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, | ||
| 486 | {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)}, | ||
| 487 | {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)}, | ||
| 488 | {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)}, | ||
| 489 | {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)}, | ||
| 482 | {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, | 490 | {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, |
| 483 | {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, | 491 | {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, |
| 492 | {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, | ||
| 493 | {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, | ||
| 484 | 494 | ||
| 485 | /* 9000 Series */ | 495 | /* 9000 Series */ |
| 486 | {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, | 496 | {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, |
