diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-24 06:54:12 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-24 06:54:12 -0700 |
commit | ba3e2084f268bdfed7627046e58a2218037e15af (patch) | |
tree | 36b99da43ee72f81b31f0627dbfc69f50c97378f /drivers/net/ethernet | |
parent | a72c9512bf2bef12c5e66a4d910c4b348fe31d61 (diff) | |
parent | ce9d9b8e5c2b7486edf76958bcdb5e6534a915b0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/ipv6/xfrm6_output.c
net/openvswitch/flow_netlink.c
net/openvswitch/vport-gre.c
net/openvswitch/vport-vxlan.c
net/openvswitch/vport.c
net/openvswitch/vport.h
The openvswitch conflicts were overlapping changes. One was
the egress tunnel info fix in 'net' and the other was the
vport ->send() op simplification in 'net-next'.
The xfrm6_output.c conflicts was also a simplification
overlapping a bug fix.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/allwinner/sun4i-emac.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bcm63xx_enet.c | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 15 |
9 files changed, 98 insertions, 33 deletions
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 48ce83e443c2..8d50314ac3eb 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -847,21 +847,25 @@ static int emac_probe(struct platform_device *pdev) if (ndev->irq == -ENXIO) { netdev_err(ndev, "No irq resource\n"); ret = ndev->irq; - goto out; + goto out_iounmap; } db->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(db->clk)) { ret = PTR_ERR(db->clk); - goto out; + goto out_iounmap; } - clk_prepare_enable(db->clk); + ret = clk_prepare_enable(db->clk); + if (ret) { + dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); + goto out_iounmap; + } ret = sunxi_sram_claim(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); - goto out; + goto out_clk_disable_unprepare; } db->phy_node = of_parse_phandle(np, "phy", 0); @@ -910,6 +914,10 @@ static int emac_probe(struct platform_device *pdev) out_release_sram: sunxi_sram_release(&pdev->dev); +out_clk_disable_unprepare: + clk_disable_unprepare(db->clk); +out_iounmap: + iounmap(db->membase); out: dev_err(db->dev, "not found (%d).\n", ret); @@ -921,8 +929,12 @@ out: static int emac_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct emac_board_info *db = netdev_priv(ndev); unregister_netdev(ndev); + sunxi_sram_release(&pdev->dev); + clk_disable_unprepare(db->clk); + iounmap(db->membase); free_netdev(ndev); dev_dbg(&pdev->dev, "released and freed device\n"); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 45512242baea..112f1bc8bcee 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1595,7 +1595,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) packet->rdesc_count, 1); /* Make sure ownership is written to the descriptor */ - dma_wmb(); + wmb(); ring->cur = cur_index + 1; if (!packet->skb->xmit_more || diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 49f796aaad4f..cff8940e1694 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1811,6 +1811,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) struct netdev_queue *txq; int processed = 0; unsigned int tx_packets = 0, tx_bytes = 0; + unsigned int cur; DBGPR("-->xgbe_tx_poll\n"); @@ -1818,10 +1819,11 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) if (!ring) return 0; + cur = ring->cur; txq = netdev_get_tx_queue(netdev, channel->queue_index); while ((processed < XGBE_TX_DESC_MAX_PROC) && - (ring->dirty != ring->cur)) { + (ring->dirty != cur)) { rdata = XGBE_GET_DESC_DATA(ring, ring->dirty); rdesc = rdata->rdesc; diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 95af75d35bc5..8b1929e9f698 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -2048,7 +2048,7 @@ static void swphy_poll_timer(unsigned long data) for (i = 0; i < priv->num_ports; i++) { struct bcm63xx_enetsw_port *port; - int val, j, up, advertise, lpa, lpa2, speed, duplex, media; + int val, j, up, advertise, lpa, speed, duplex, media; int external_phy = bcm_enet_port_is_rgmii(i); u8 override; @@ -2091,22 +2091,27 @@ static void swphy_poll_timer(unsigned long data) lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, MII_LPA); - lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, - MII_STAT1000); - /* figure out media and duplex from advertise and LPA values */ media = mii_nway_result(lpa & advertise); duplex = (media & ADVERTISE_FULL) ? 1 : 0; - if (lpa2 & LPA_1000FULL) - duplex = 1; - - if (lpa2 & (LPA_1000FULL | LPA_1000HALF)) - speed = 1000; - else { - if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) - speed = 100; - else - speed = 10; + + if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) + speed = 100; + else + speed = 10; + + if (val & BMSR_ESTATEN) { + advertise = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_CTRL1000); + + lpa = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_STAT1000); + + if (advertise & (ADVERTISE_1000FULL | ADVERTISE_1000HALF) + && lpa & (LPA_1000FULL | LPA_1000HALF)) { + speed = 1000; + duplex = (lpa & LPA_1000FULL); + } } dev_info(&priv->pdev->dev, diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig index 9b35d142f47a..8fb84e69c30e 100644 --- a/drivers/net/ethernet/cavium/Kconfig +++ b/drivers/net/ethernet/cavium/Kconfig @@ -3,7 +3,7 @@ # config NET_VENDOR_CAVIUM - tristate "Cavium ethernet drivers" + bool "Cavium ethernet drivers" depends on PCI default y ---help--- diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 8fd26fdd7705..3f385ffe420f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1406,6 +1406,12 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } + for (j = 0; j < I40E_MAX_TRAFFIC_CLASS; j++) { + data[i++] = veb->tc_stats.tc_tx_packets[j]; + data[i++] = veb->tc_stats.tc_tx_bytes[j]; + data[i++] = veb->tc_stats.tc_rx_packets[j]; + data[i++] = veb->tc_stats.tc_rx_bytes[j]; + } } for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) { p = (char *)pf + i40e_gstrings_stats[j].stat_offset; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3e595adfb0bf..b825f978d441 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8154,6 +8154,7 @@ static int i40e_sw_init(struct i40e_pf *pf) if (pf->hw.func_caps.vmdq) { pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI; pf->flags |= I40E_FLAG_VMDQ_ENABLED; + pf->num_vmdq_qps = i40e_default_queues_per_vmdq(pf); } #ifdef I40E_FCOE diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 603d29df5832..6bf725921e79 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -759,11 +759,23 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, desc->l4i_chk = 0; desc->byte_cnt = length; - desc->buf_ptr = dma_map_single(dev->dev.parent, data, - length, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev->dev.parent, desc->buf_ptr))) { - WARN(1, "dma_map_single failed!\n"); - return -ENOMEM; + + if (length <= 8 && (uintptr_t)data & 0x7) { + /* Copy unaligned small data fragment to TSO header data area */ + memcpy(txq->tso_hdrs + txq->tx_curr_desc * TSO_HEADER_SIZE, + data, length); + desc->buf_ptr = txq->tso_hdrs_dma + + txq->tx_curr_desc * TSO_HEADER_SIZE; + } else { + /* Alignment is okay, map buffer and hand off to hardware */ + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; + desc->buf_ptr = dma_map_single(dev->dev.parent, data, + length, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev->dev.parent, + desc->buf_ptr))) { + WARN(1, "dma_map_single failed!\n"); + return -ENOMEM; + } } cmd_sts = BUFFER_OWNED_BY_DMA; @@ -779,7 +791,8 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, } static inline void -txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length) +txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length, + u32 *first_cmd_sts, bool first_desc) { struct mv643xx_eth_private *mp = txq_to_mp(txq); int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); @@ -788,6 +801,7 @@ txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length) int ret; u32 cmd_csum = 0; u16 l4i_chk = 0; + u32 cmd_sts; tx_index = txq->tx_curr_desc; desc = &txq->tx_desc_area[tx_index]; @@ -803,9 +817,17 @@ txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length) desc->byte_cnt = hdr_len; desc->buf_ptr = txq->tso_hdrs_dma + txq->tx_curr_desc * TSO_HEADER_SIZE; - desc->cmd_sts = cmd_csum | BUFFER_OWNED_BY_DMA | TX_FIRST_DESC | + cmd_sts = cmd_csum | BUFFER_OWNED_BY_DMA | TX_FIRST_DESC | GEN_CRC; + /* Defer updating the first command descriptor until all + * following descriptors have been written. + */ + if (first_desc) + *first_cmd_sts = cmd_sts; + else + desc->cmd_sts = cmd_sts; + txq->tx_curr_desc++; if (txq->tx_curr_desc == txq->tx_ring_size) txq->tx_curr_desc = 0; @@ -819,6 +841,8 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb, int desc_count = 0; struct tso_t tso; int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + struct tx_desc *first_tx_desc; + u32 first_cmd_sts = 0; /* Count needed descriptors */ if ((txq->tx_desc_count + tso_count_descs(skb)) >= txq->tx_ring_size) { @@ -826,11 +850,14 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb, return -EBUSY; } + first_tx_desc = &txq->tx_desc_area[txq->tx_curr_desc]; + /* Initialize the TSO handler, and prepare the first payload */ tso_start(skb, &tso); total_len = skb->len - hdr_len; while (total_len > 0) { + bool first_desc = (desc_count == 0); char *hdr; data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len); @@ -840,7 +867,8 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb, /* prepare packet headers: MAC + IP + TCP */ hdr = txq->tso_hdrs + txq->tx_curr_desc * TSO_HEADER_SIZE; tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0); - txq_put_hdr_tso(skb, txq, data_left); + txq_put_hdr_tso(skb, txq, data_left, &first_cmd_sts, + first_desc); while (data_left > 0) { int size; @@ -860,6 +888,10 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb, __skb_queue_tail(&txq->tx_skb, skb); skb_tx_timestamp(skb); + /* ensure all other descriptors are written before first cmd_sts */ + wmb(); + first_tx_desc->cmd_sts = first_cmd_sts; + /* clear TX_END status */ mp->work_tx_end &= ~(1 << txq->index); diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 55d2d8577d07..040fbc1e5508 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -31,6 +31,7 @@ #include <linux/pm_runtime.h> #include <linux/gpio.h> #include <linux/of.h> +#include <linux/of_mdio.h> #include <linux/of_net.h> #include <linux/of_device.h> #include <linux/if_vlan.h> @@ -366,6 +367,7 @@ struct cpsw_priv { spinlock_t lock; struct platform_device *pdev; struct net_device *ndev; + struct device_node *phy_node; struct napi_struct napi_rx; struct napi_struct napi_tx; struct device *dev; @@ -1146,7 +1148,11 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - slave->phy = phy_connect(priv->ndev, slave->data->phy_id, + if (priv->phy_node) + slave->phy = of_phy_connect(priv->ndev, priv->phy_node, + &cpsw_adjust_link, 0, slave->data->phy_if); + else + slave->phy = phy_connect(priv->ndev, slave->data->phy_id, &cpsw_adjust_link, slave->data->phy_if); if (IS_ERR(slave->phy)) { dev_err(priv->dev, "phy %s not found on slave %d\n", @@ -1934,11 +1940,12 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, slave->port_vlan = data->dual_emac_res_vlan; } -static int cpsw_probe_dt(struct cpsw_platform_data *data, +static int cpsw_probe_dt(struct cpsw_priv *priv, struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct device_node *slave_node; + struct cpsw_platform_data *data = &priv->data; int i = 0, ret; u32 prop; @@ -2029,6 +2036,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, if (strcmp(slave_node->name, "slave")) continue; + priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); parp = of_get_property(slave_node, "phy_id", &lenp); if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i); @@ -2044,7 +2052,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), PHY_ID_FMT, mdio->name, phyid); - slave_data->phy_if = of_get_phy_mode(slave_node); if (slave_data->phy_if < 0) { dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n", @@ -2245,7 +2252,7 @@ static int cpsw_probe(struct platform_device *pdev) /* Select default pin state */ pinctrl_pm_select_default_state(&pdev->dev); - if (cpsw_probe_dt(&priv->data, pdev)) { + if (cpsw_probe_dt(priv, pdev)) { dev_err(&pdev->dev, "cpsw: platform data missing\n"); ret = -ENODEV; goto clean_runtime_disable_ret; |