diff options
Diffstat (limited to 'drivers/net/ethernet')
33 files changed, 527 insertions, 102 deletions
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 1f7b5aa114fa..8a7bf7dad898 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -1484,6 +1484,10 @@ static int b44_open(struct net_device *dev)  	add_timer(&bp->timer);  	b44_enable_ints(bp); + +	if (bp->flags & B44_FLAG_EXTERNAL_PHY) +		phy_start(bp->phydev); +  	netif_start_queue(dev);  out:  	return err; @@ -1646,6 +1650,9 @@ static int b44_close(struct net_device *dev)  	netif_stop_queue(dev); +	if (bp->flags & B44_FLAG_EXTERNAL_PHY) +		phy_stop(bp->phydev); +  	napi_disable(&bp->napi);  	del_timer_sync(&bp->timer); @@ -2222,7 +2229,12 @@ static void b44_adjust_link(struct net_device *dev)  	}  	if (status_changed) { -		b44_check_phy(bp); +		u32 val = br32(bp, B44_TX_CTRL); +		if (bp->flags & B44_FLAG_FULL_DUPLEX) +			val |= TX_CTRL_DUPLEX; +		else +			val &= ~TX_CTRL_DUPLEX; +		bw32(bp, B44_TX_CTRL, val);  		phy_print_status(phydev);  	}  } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9d7419e0390b..dbcff509dc3f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1873,7 +1873,7 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)  }  u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, -		       void *accel_priv) +		       void *accel_priv, select_queue_fallback_t fallback)  {  	struct bnx2x *bp = netdev_priv(dev); @@ -1895,7 +1895,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,  	}  	/* select a non-FCoE queue */ -	return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); +	return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);  }  void bnx2x_set_num_queues(struct bnx2x *bp) @@ -3875,7 +3875,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)  						     xmit_type);  		} -		/* Add the macs to the parsing BD this is a vf */ +		/* Add the macs to the parsing BD if this is a vf or if +		 * Tx Switching is enabled. +		 */  		if (IS_VF(bp)) {  			/* override GRE parameters in BD */  			bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, @@ -3887,6 +3889,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)  					      &pbd_e2->data.mac_addr.dst_mid,  					      &pbd_e2->data.mac_addr.dst_lo,  					      eth->h_dest); +		} else if (bp->flags & TX_SWITCHING) { +			bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi, +					      &pbd_e2->data.mac_addr.dst_mid, +					      &pbd_e2->data.mac_addr.dst_lo, +					      eth->h_dest);  		}  		SET_FLAG(pbd_e2_parsing_data, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bfc58d488bb5..a89a40f88c25 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -496,7 +496,7 @@ int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);  /* select_queue callback */  u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, -		       void *accel_priv); +		       void *accel_priv, select_queue_fallback_t fallback);  static inline void bnx2x_update_rx_prod(struct bnx2x *bp,  					struct bnx2x_fastpath *fp, diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 3167ed6593b0..3b6d0ba86c71 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6843,8 +6843,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)  		work_mask |= opaque_key; -		if ((desc->err_vlan & RXD_ERR_MASK) != 0 && -		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) { +		if (desc->err_vlan & RXD_ERR_MASK) {  		drop_it:  			tg3_recycle_rx(tnapi, tpr, opaque_key,  				       desc_idx, *post_ptr); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index ef472385bce4..04321e5a356e 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -2608,7 +2608,11 @@ struct tg3_rx_buffer_desc {  #define RXD_ERR_TOO_SMALL		0x00400000  #define RXD_ERR_NO_RESOURCES		0x00800000  #define RXD_ERR_HUGE_FRAME		0x01000000 -#define RXD_ERR_MASK			0xffff0000 + +#define RXD_ERR_MASK	(RXD_ERR_BAD_CRC | RXD_ERR_COLLISION |		\ +			 RXD_ERR_LINK_LOST | RXD_ERR_PHY_DECODE |	\ +			 RXD_ERR_MAC_ABRT | RXD_ERR_TOO_SMALL |		\ +			 RXD_ERR_NO_RESOURCES | RXD_ERR_HUGE_FRAME)  	u32				reserved;  	u32				opaque; diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index cf64f3d0b60d..4ad1187e82fb 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -707,7 +707,8 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)  		else  			skb_checksum_none_assert(skb); -		if (flags & BNA_CQ_EF_VLAN) +		if ((flags & BNA_CQ_EF_VLAN) && +		    (bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX))  			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(cmpl->vlan_tag));  		if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) @@ -2094,7 +2095,9 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)  		rx_config->q1_buf_size = BFI_SMALL_RXBUF_SIZE;  	} -	rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; +	rx_config->vlan_strip_status = +		(bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) ? +		BNA_STATUS_T_ENABLED : BNA_STATUS_T_DISABLED;  }  static void @@ -3245,11 +3248,6 @@ bnad_set_rx_mode(struct net_device *netdev)  			BNA_RXMODE_ALLMULTI;  	bna_rx_mode_set(bnad->rx_info[0].rx, new_mode, mode_mask, NULL); -	if (bnad->cfg_flags & BNAD_CF_PROMISC) -		bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); -	else -		bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); -  	spin_unlock_irqrestore(&bnad->bna_lock, flags);  } @@ -3374,6 +3372,27 @@ bnad_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)  	return 0;  } +static int bnad_set_features(struct net_device *dev, netdev_features_t features) +{ +	struct bnad *bnad = netdev_priv(dev); +	netdev_features_t changed = features ^ dev->features; + +	if ((changed & NETIF_F_HW_VLAN_CTAG_RX) && netif_running(dev)) { +		unsigned long flags; + +		spin_lock_irqsave(&bnad->bna_lock, flags); + +		if (features & NETIF_F_HW_VLAN_CTAG_RX) +			bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); +		else +			bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); + +		spin_unlock_irqrestore(&bnad->bna_lock, flags); +	} + +	return 0; +} +  #ifdef CONFIG_NET_POLL_CONTROLLER  static void  bnad_netpoll(struct net_device *netdev) @@ -3421,6 +3440,7 @@ static const struct net_device_ops bnad_netdev_ops = {  	.ndo_change_mtu		= bnad_change_mtu,  	.ndo_vlan_rx_add_vid    = bnad_vlan_rx_add_vid,  	.ndo_vlan_rx_kill_vid   = bnad_vlan_rx_kill_vid, +	.ndo_set_features	= bnad_set_features,  #ifdef CONFIG_NET_POLL_CONTROLLER  	.ndo_poll_controller    = bnad_netpoll  #endif @@ -3433,14 +3453,14 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac)  	netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |  		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -		NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX; +		NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX | +		NETIF_F_HW_VLAN_CTAG_RX;  	netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA |  		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |  		NETIF_F_TSO | NETIF_F_TSO6; -	netdev->features |= netdev->hw_features | -		NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; +	netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;  	if (using_dac)  		netdev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 43ab35fea48d..34e2488767d9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -6179,6 +6179,7 @@ static struct pci_driver cxgb4_driver = {  	.id_table = cxgb4_pci_tbl,  	.probe    = init_one,  	.remove   = remove_one, +	.shutdown = remove_one,  	.err_handler = &cxgb4_eeh,  }; diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index add05f14b38b..1642de78aac8 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -1939,6 +1939,7 @@ static void tulip_remove_one(struct pci_dev *pdev)  	pci_iounmap(pdev, tp->base_addr);  	free_netdev (dev);  	pci_release_regions (pdev); +	pci_disable_device(pdev);  	/* pci_power_off (pdev, -1); */  } diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 8d09615da585..05529e273050 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -350,11 +350,13 @@ struct be_drv_stats {  	u32 roce_drops_crc;  }; +/* A vlan-id of 0xFFFF must be used to clear transparent vlan-tagging */ +#define BE_RESET_VLAN_TAG_ID	0xFFFF +  struct be_vf_cfg {  	unsigned char mac_addr[ETH_ALEN];  	int if_handle;  	int pmac_id; -	u16 def_vid;  	u16 vlan_tag;  	u32 tx_rate;  }; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 04ac9c6a0d39..36c80612e21a 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -913,24 +913,14 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter,  	return BE3_chip(adapter) && be_ipv6_exthdr_check(skb);  } -static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, -					   struct sk_buff *skb, -					   bool *skip_hw_vlan) +static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, +						  struct sk_buff *skb, +						  bool *skip_hw_vlan)  {  	struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;  	unsigned int eth_hdr_len;  	struct iphdr *ip; -	/* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less -	 * may cause a transmit stall on that port. So the work-around is to -	 * pad short packets (<= 32 bytes) to a 36-byte length. -	 */ -	if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { -		if (skb_padto(skb, 36)) -			goto tx_drop; -		skb->len = 36; -	} -  	/* For padded packets, BE HW modifies tot_len field in IP header  	 * incorrecly when VLAN tag is inserted by HW.  	 * For padded packets, Lancer computes incorrect checksum. @@ -959,7 +949,7 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,  	    vlan_tx_tag_present(skb)) {  		skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);  		if (unlikely(!skb)) -			goto tx_drop; +			goto err;  	}  	/* HW may lockup when VLAN HW tagging is requested on @@ -981,15 +971,39 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,  	    be_vlan_tag_tx_chk(adapter, skb)) {  		skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);  		if (unlikely(!skb)) -			goto tx_drop; +			goto err;  	}  	return skb;  tx_drop:  	dev_kfree_skb_any(skb); +err:  	return NULL;  } +static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, +					   struct sk_buff *skb, +					   bool *skip_hw_vlan) +{ +	/* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or +	 * less may cause a transmit stall on that port. So the work-around is +	 * to pad short packets (<= 32 bytes) to a 36-byte length. +	 */ +	if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { +		if (skb_padto(skb, 36)) +			return NULL; +		skb->len = 36; +	} + +	if (BEx_chip(adapter) || lancer_chip(adapter)) { +		skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan); +		if (!skb) +			return NULL; +	} + +	return skb; +} +  static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)  {  	struct be_adapter *adapter = netdev_priv(netdev); @@ -1157,6 +1171,14 @@ ret:  	return status;  } +static void be_clear_promisc(struct be_adapter *adapter) +{ +	adapter->promiscuous = false; +	adapter->flags &= ~BE_FLAGS_VLAN_PROMISC; + +	be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); +} +  static void be_set_rx_mode(struct net_device *netdev)  {  	struct be_adapter *adapter = netdev_priv(netdev); @@ -1170,9 +1192,7 @@ static void be_set_rx_mode(struct net_device *netdev)  	/* BE was previously in promiscuous mode; disable it */  	if (adapter->promiscuous) { -		adapter->promiscuous = false; -		be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); - +		be_clear_promisc(adapter);  		if (adapter->vlans_added)  			be_vid_config(adapter);  	} @@ -1287,24 +1307,20 @@ static int be_set_vf_vlan(struct net_device *netdev,  	if (vlan || qos) {  		vlan |= qos << VLAN_PRIO_SHIFT; -		if (vf_cfg->vlan_tag != vlan) { -			/* If this is new value, program it. Else skip. */ -			vf_cfg->vlan_tag = vlan; +		if (vf_cfg->vlan_tag != vlan)  			status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,  						       vf_cfg->if_handle, 0); -		}  	} else {  		/* Reset Transparent Vlan Tagging. */ -		vf_cfg->vlan_tag = 0; -		vlan = vf_cfg->def_vid; -		status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, -					       vf_cfg->if_handle, 0); +		status = be_cmd_set_hsw_config(adapter, BE_RESET_VLAN_TAG_ID, +					       vf + 1, vf_cfg->if_handle, 0);  	} - -	if (status) +	if (!status) +		vf_cfg->vlan_tag = vlan; +	else  		dev_info(&adapter->pdev->dev, -				"VLAN %d config on VF %d failed\n", vlan, vf); +			 "VLAN %d config on VF %d failed\n", vlan, vf);  	return status;  } @@ -3013,11 +3029,11 @@ static int be_vf_setup_init(struct be_adapter *adapter)  static int be_vf_setup(struct be_adapter *adapter)  { +	struct device *dev = &adapter->pdev->dev;  	struct be_vf_cfg *vf_cfg; -	u16 def_vlan, lnk_speed;  	int status, old_vfs, vf; -	struct device *dev = &adapter->pdev->dev;  	u32 privileges; +	u16 lnk_speed;  	old_vfs = pci_num_vf(adapter->pdev);  	if (old_vfs) { @@ -3084,12 +3100,6 @@ static int be_vf_setup(struct be_adapter *adapter)  		if (!status)  			vf_cfg->tx_rate = lnk_speed; -		status = be_cmd_get_hsw_config(adapter, &def_vlan, -					       vf + 1, vf_cfg->if_handle, NULL); -		if (status) -			goto err; -		vf_cfg->def_vid = def_vlan; -  		if (!old_vfs)  			be_cmd_enable_vf(adapter, vf + 1);  	} diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d4782b42401b..479a7cba45c0 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -389,12 +389,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)  			netdev_err(ndev, "Tx DMA memory map failed\n");  		return NETDEV_TX_OK;  	} -	/* Send it on its way.  Tell FEC it's ready, interrupt when done, -	 * it's the last BD of the frame, and to put the CRC on the end. -	 */ -	status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR -			| BD_ENET_TX_LAST | BD_ENET_TX_TC); -	bdp->cbd_sc = status;  	if (fep->bufdesc_ex) { @@ -416,6 +410,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)  		}  	} +	/* Send it on its way.  Tell FEC it's ready, interrupt when done, +	 * it's the last BD of the frame, and to put the CRC on the end. +	 */ +	status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR +			| BD_ENET_TX_LAST | BD_ENET_TX_TC); +	bdp->cbd_sc = status; +  	bdp_pre = fec_enet_get_prevdesc(bdp, fep);  	if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&  	    !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { @@ -1778,8 +1779,6 @@ fec_enet_open(struct net_device *ndev)  	struct fec_enet_private *fep = netdev_priv(ndev);  	int ret; -	napi_enable(&fep->napi); -  	/* I should reset the ring buffers here, but I don't yet know  	 * a simple way to do that.  	 */ @@ -1794,6 +1793,8 @@ fec_enet_open(struct net_device *ndev)  		fec_enet_free_buffers(ndev);  		return ret;  	} + +	napi_enable(&fep->napi);  	phy_start(fep->phy_dev);  	netif_start_queue(ndev);  	fep->opened = 1; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6d4ada72dfd0..18076c4178b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6881,7 +6881,7 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)  }  static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, -			      void *accel_priv) +			      void *accel_priv, select_queue_fallback_t fallback)  {  	struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;  #ifdef IXGBE_FCOE @@ -6907,7 +6907,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,  		if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)  			break;  	default: -		return __netdev_pick_tx(dev, skb); +		return fallback(dev, skb);  	}  	f = &adapter->ring_feature[RING_F_FCOE]; @@ -6920,7 +6920,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,  	return txq + f->offset;  #else -	return __netdev_pick_tx(dev, skb); +	return fallback(dev, skb);  #endif  } diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 8f9266c64c75..fd4b6aecf6ee 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -619,7 +619,7 @@ ltq_etop_set_multicast_list(struct net_device *dev)  static u16  ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, -		      void *accel_priv) +		      void *accel_priv, select_queue_fallback_t fallback)  {  	/* we are currently only using the first queue */  	return 0; diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 6300fd27f2db..68e6a6613e9a 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig @@ -43,12 +43,12 @@ config MVMDIO  	  This driver is used by the MV643XX_ETH and MVNETA drivers.  config MVNETA -	tristate "Marvell Armada 370/XP network interface support" -	depends on MACH_ARMADA_370_XP +	tristate "Marvell Armada 370/38x/XP network interface support" +	depends on PLAT_ORION  	select MVMDIO  	---help---  	  This driver supports the network interface units in the -	  Marvell ARMADA XP and ARMADA 370 SoC family. +	  Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.  	  Note that this driver is distinct from the mv643xx_eth  	  driver, which should be used for the older Marvell SoCs diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 8e8a7eb43a2c..13457032d15f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -629,7 +629,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk  }  u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, -			 void *accel_priv) +			 void *accel_priv, select_queue_fallback_t fallback)  {  	struct mlx4_en_priv *priv = netdev_priv(dev);  	u16 rings_p_up = priv->num_tx_rings_p_up; @@ -641,7 +641,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,  	if (vlan_tx_tag_present(skb))  		up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; -	return __netdev_pick_tx(dev, skb) % rings_p_up + up * rings_p_up; +	return fallback(dev, skb) % rings_p_up + up * rings_p_up;  }  static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 6b65f7795215..7aec6c833973 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -51,8 +51,8 @@  #define DRV_NAME	"mlx4_core"  #define PFX		DRV_NAME ": " -#define DRV_VERSION	"1.1" -#define DRV_RELDATE	"Dec, 2011" +#define DRV_VERSION	"2.2-1" +#define DRV_RELDATE	"Feb, 2014"  #define MLX4_FS_UDP_UC_EN		(1 << 1)  #define MLX4_FS_TCP_UC_EN		(1 << 2) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 3af04c3f42ea..b57e8c87a34e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -57,8 +57,8 @@  #include "en_port.h"  #define DRV_NAME	"mlx4_en" -#define DRV_VERSION	"2.0" -#define DRV_RELDATE	"Dec 2011" +#define DRV_VERSION	"2.2-1" +#define DRV_RELDATE	"Feb 2014"  #define MLX4_EN_MSG_LEVEL	(NETIF_MSG_LINK | NETIF_MSG_IFDOWN) @@ -723,7 +723,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);  void mlx4_en_tx_irq(struct mlx4_cq *mcq);  u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, -			 void *accel_priv); +			 void *accel_priv, select_queue_fallback_t fallback);  netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);  int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index a064f06e0cb8..23b7e2d35a93 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -46,8 +46,8 @@  #include "mlx5_core.h"  #define DRIVER_NAME "mlx5_core" -#define DRIVER_VERSION "1.0" -#define DRIVER_RELDATE	"June 2013" +#define DRIVER_VERSION "2.2-1" +#define DRIVER_RELDATE	"Feb 2014"  MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");  MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library"); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 4146664d4d6a..27c4f131863b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -340,6 +340,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)  			if (qlcnic_sriov_vf_check(adapter))  				return -EINVAL;  			num_msix = 1; +			adapter->drv_sds_rings = QLCNIC_SINGLE_RING;  			adapter->drv_tx_rings = QLCNIC_SINGLE_RING;  		}  	} diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 77f1bce432d2..7d4f54912bad 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c @@ -807,7 +807,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,  	    !type->tc_param_valid)  		return; -	if (tc < 0 || (tc > QLC_DCB_MAX_TC)) +	if (tc < 0 || (tc >= QLC_DCB_MAX_TC))  		return;  	tc_cfg = &type->tc_cfg[tc]; @@ -843,7 +843,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,  	    !type->tc_param_valid)  		return; -	if (pgid < 0 || pgid > QLC_DCB_MAX_PG) +	if (pgid < 0 || pgid >= QLC_DCB_MAX_PG)  		return;  	pgcfg = &type->pg_cfg[pgid]; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ba78c7481fa3..1222865cfb73 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -816,9 +816,10 @@ static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter)  		if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {  			qlcnic_disable_multi_tx(adapter); +			adapter->drv_sds_rings = QLCNIC_SINGLE_RING;  			err = qlcnic_enable_msi_legacy(adapter); -			if (!err) +			if (err)  				return err;  		}  	} @@ -3863,7 +3864,7 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt,  		strcpy(buf, "Tx");  	} -	if (!qlcnic_use_msi_x && !qlcnic_use_msi) { +	if (!QLCNIC_IS_MSI_FAMILY(adapter)) {  		netdev_err(netdev, "No RSS/TSS support in INT-x mode\n");  		return -EINVAL;  	} diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 09acf15c3a56..e5277a632671 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -13,8 +13,6 @@  #define QLC_VF_MIN_TX_RATE	100  #define QLC_VF_MAX_TX_RATE	9999  #define QLC_MAC_OPCODE_MASK	0x7 -#define QLC_MAC_STAR_ADD	6 -#define QLC_MAC_STAR_DEL	7  #define QLC_VF_FLOOD_BIT	BIT_16  #define QLC_FLOOD_MODE		0x5 @@ -1206,13 +1204,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,  	struct qlcnic_vport *vp = vf->vp;  	u8 op, new_op; -	if (((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_ADD) || -	    ((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_DEL)) { -		netdev_err(adapter->netdev, "MAC + any VLAN filter not allowed from VF %d\n", -			   vf->pci_func); -		return -EINVAL; -	} -  	if (!(cmd->req.arg[1] & BIT_8))  		return -EINVAL; diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 91a67ae8f17b..e9779653cd4c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -7118,6 +7118,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	}  	mutex_init(&tp->wk.mutex); +	u64_stats_init(&tp->rx_stats.syncp); +	u64_stats_init(&tp->tx_stats.syncp);  	/* Get MAC address */  	for (i = 0; i < ETH_ALEN; i++) diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index eb75fbd11a01..d7a36829649a 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1668,6 +1668,13 @@ void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev)  	struct efx_ptp_data *ptp = efx->ptp_data;  	int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); +	if (!ptp) { +		if (net_ratelimit()) +			netif_warn(efx, drv, efx->net_dev, +				   "Received PTP event but PTP not set up\n"); +		return; +	} +  	if (!ptp->enabled)  		return; diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index e2f202e3932f..f2d7c702c77f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -37,6 +37,17 @@ config DWMAC_SUNXI  	  stmmac device driver. This driver is used for A20/A31  	  GMAC 	  ethernet controller. +config DWMAC_STI +	bool "STi GMAC support" +	depends on STMMAC_PLATFORM && ARCH_STI +	default y +	---help--- +	  Support for ethernet controller on STi SOCs. + +	  This selects STi SoC glue layer support for the stmmac +	  device driver. This driver is used on for the STi series +	  SOCs GMAC ethernet controller. +  config STMMAC_PCI  	bool "STMMAC PCI bus support"  	depends on STMMAC_ETH && PCI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index ecadecea79b2..dcef28775dad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o  stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o  stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o  stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o +stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o  stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\  	      chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \  	      dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c new file mode 100644 index 000000000000..552bbc17863c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c @@ -0,0 +1,330 @@ +/** + * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer + * + * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited + * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/stmmac.h> +#include <linux/phy.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_net.h> + +/** + *			STi GMAC glue logic. + *			-------------------- + * + *		 _ + *		|  \ + *	--------|0  \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK + * phyclk	|    |___________________________________________ + *		|    |	|			(phyclk-in) + *	--------|1  /	| + * int-clk	|_ /	| + *			|	 _ + *			|	|  \ + *			|_______|1  \ ETH_SEL_TX_RETIME_CLK + *				|    |___________________________ + *				|    |		(tx-retime-clk) + *			 _______|0  / + *			|	|_ / + *		 _	| + *		|  \	| + *	--------|0  \	| + * clk_125	|    |__| + *		|    |	ETH_SEL_TXCLK_NOT_CLK125 + *	--------|1  / + * txclk	|_ / + * + * + * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can + * generate 50MHz clock or MAC can generate it. + * This bit is configured by "st,ext-phyclk" property. + * + * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz + * clock either comes from clk-125 pin or txclk pin. This configuration is + * totally driven by the board wiring. This bit is configured by + * "st,tx-retime-src" property. + * + * TXCLK configuration is different for different phy interface modes + * and changes according to link speed in modes like RGMII. + * + * Below table summarizes the clock requirement and clock sources for + * supported phy interface modes with link speeds. + * ________________________________________________ + *|  PHY_MODE	| 1000 Mbit Link | 100 Mbit Link   | + * ------------------------------------------------ + *|	MII	|	n/a	 |	25Mhz	   | + *|		|		 |	txclk	   | + * ------------------------------------------------ + *|	GMII	|     125Mhz	 |	25Mhz	   | + *|		|  clk-125/txclk |	txclk	   | + * ------------------------------------------------ + *|	RGMII	|     125Mhz	 |	25Mhz	   | + *|		|  clk-125/txclk |	clkgen     | + * ------------------------------------------------ + *|	RMII	|	n/a	 |	25Mhz	   | + *|		|		 |clkgen/phyclk-in | + * ------------------------------------------------ + * + * TX lines are always retimed with a clk, which can vary depending + * on the board configuration. Below is the table of these bits + * in eth configuration register depending on source of retime clk. + * + *--------------------------------------------------------------- + * src	 | tx_rt_clk	| int_not_ext_phyclk	| txclk_n_clk125| + *--------------------------------------------------------------- + * txclk |	0	|	n/a		|	1	| + *--------------------------------------------------------------- + * ck_125|	0	|	n/a		|	0	| + *--------------------------------------------------------------- + * phyclk|	1	|	0		|	n/a	| + *--------------------------------------------------------------- + * clkgen|	1	|	1		|	n/a	| + *--------------------------------------------------------------- + */ + + /* Register definition */ + + /* 3 bits [8:6] +  *  [6:6]      ETH_SEL_TXCLK_NOT_CLK125 +  *  [7:7]      ETH_SEL_INTERNAL_NOTEXT_PHYCLK +  *  [8:8]      ETH_SEL_TX_RETIME_CLK +  * +  */ + +#define TX_RETIME_SRC_MASK		GENMASK(8, 6) +#define ETH_SEL_TX_RETIME_CLK		BIT(8) +#define ETH_SEL_INTERNAL_NOTEXT_PHYCLK	BIT(7) +#define ETH_SEL_TXCLK_NOT_CLK125	BIT(6) + +#define ENMII_MASK			GENMASK(5, 5) +#define ENMII				BIT(5) + +/** + * 3 bits [4:2] + *	000-GMII/MII + *	001-RGMII + *	010-SGMII + *	100-RMII +*/ +#define MII_PHY_SEL_MASK		GENMASK(4, 2) +#define ETH_PHY_SEL_RMII		BIT(4) +#define ETH_PHY_SEL_SGMII		BIT(3) +#define ETH_PHY_SEL_RGMII		BIT(2) +#define ETH_PHY_SEL_GMII		0x0 +#define ETH_PHY_SEL_MII			0x0 + +#define IS_PHY_IF_MODE_RGMII(iface)	(iface == PHY_INTERFACE_MODE_RGMII || \ +			iface == PHY_INTERFACE_MODE_RGMII_ID || \ +			iface == PHY_INTERFACE_MODE_RGMII_RXID || \ +			iface == PHY_INTERFACE_MODE_RGMII_TXID) + +#define IS_PHY_IF_MODE_GBIT(iface)	(IS_PHY_IF_MODE_RGMII(iface) || \ +			iface == PHY_INTERFACE_MODE_GMII) + +struct sti_dwmac { +	int interface; +	bool ext_phyclk; +	bool is_tx_retime_src_clk_125; +	struct clk *clk; +	int reg; +	struct device *dev; +	struct regmap *regmap; +}; + +static u32 phy_intf_sels[] = { +	[PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII, +	[PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII, +	[PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII, +	[PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII, +	[PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII, +	[PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII, +}; + +enum { +	TX_RETIME_SRC_NA = 0, +	TX_RETIME_SRC_TXCLK = 1, +	TX_RETIME_SRC_CLK_125, +	TX_RETIME_SRC_PHYCLK, +	TX_RETIME_SRC_CLKGEN, +}; + +static const char *const tx_retime_srcs[] = { +	[TX_RETIME_SRC_NA] = "", +	[TX_RETIME_SRC_TXCLK] = "txclk", +	[TX_RETIME_SRC_CLK_125] = "clk_125", +	[TX_RETIME_SRC_PHYCLK] = "phyclk", +	[TX_RETIME_SRC_CLKGEN] = "clkgen", +}; + +static u32 tx_retime_val[] = { +	[TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125, +	[TX_RETIME_SRC_CLK_125] = 0x0, +	[TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, +	[TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | +	    ETH_SEL_INTERNAL_NOTEXT_PHYCLK, +}; + +static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) +{ +	u32 src = 0, freq = 0; + +	if (spd == SPEED_100) { +		if (dwmac->interface == PHY_INTERFACE_MODE_MII || +		    dwmac->interface == PHY_INTERFACE_MODE_GMII) { +			src = TX_RETIME_SRC_TXCLK; +		} else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { +			if (dwmac->ext_phyclk) { +				src = TX_RETIME_SRC_PHYCLK; +			} else { +				src = TX_RETIME_SRC_CLKGEN; +				freq = 50000000; +			} + +		} else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) { +			src = TX_RETIME_SRC_CLKGEN; +			freq = 25000000; +		} + +		if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) +			clk_set_rate(dwmac->clk, freq); + +	} else if (spd == SPEED_1000) { +		if (dwmac->is_tx_retime_src_clk_125) +			src = TX_RETIME_SRC_CLK_125; +		else +			src = TX_RETIME_SRC_TXCLK; +	} + +	regmap_update_bits(dwmac->regmap, dwmac->reg, +			   TX_RETIME_SRC_MASK, tx_retime_val[src]); +} + +static void sti_dwmac_exit(struct platform_device *pdev, void *priv) +{ +	struct sti_dwmac *dwmac = priv; + +	if (dwmac->clk) +		clk_disable_unprepare(dwmac->clk); +} + +static void sti_fix_mac_speed(void *priv, unsigned int spd) +{ +	struct sti_dwmac *dwmac = priv; + +	setup_retime_src(dwmac, spd); + +	return; +} + +static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, +				struct platform_device *pdev) +{ +	struct resource *res; +	struct device *dev = &pdev->dev; +	struct device_node *np = dev->of_node; +	struct regmap *regmap; +	int err; + +	if (!np) +		return -EINVAL; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); +	if (!res) +		return -ENODATA; + +	regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); +	if (IS_ERR(regmap)) +		return PTR_ERR(regmap); + +	dwmac->dev = dev; +	dwmac->interface = of_get_phy_mode(np); +	dwmac->regmap = regmap; +	dwmac->reg = res->start; +	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); +	dwmac->is_tx_retime_src_clk_125 = false; + +	if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { +		const char *rs; + +		err = of_property_read_string(np, "st,tx-retime-src", &rs); +		if (err < 0) { +			dev_err(dev, "st,tx-retime-src not specified\n"); +			return err; +		} + +		if (!strcasecmp(rs, "clk_125")) +			dwmac->is_tx_retime_src_clk_125 = true; +	} + +	dwmac->clk = devm_clk_get(dev, "sti-ethclk"); + +	if (IS_ERR(dwmac->clk)) +		dwmac->clk = NULL; + +	return 0; +} + +static int sti_dwmac_init(struct platform_device *pdev, void *priv) +{ +	struct sti_dwmac *dwmac = priv; +	struct regmap *regmap = dwmac->regmap; +	int iface = dwmac->interface; +	u32 reg = dwmac->reg; +	u32 val, spd; + +	if (dwmac->clk) +		clk_prepare_enable(dwmac->clk); + +	regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]); + +	val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII; +	regmap_update_bits(regmap, reg, ENMII_MASK, val); + +	if (IS_PHY_IF_MODE_GBIT(iface)) +		spd = SPEED_1000; +	else +		spd = SPEED_100; + +	setup_retime_src(dwmac, spd); + +	return 0; +} + +static void *sti_dwmac_setup(struct platform_device *pdev) +{ +	struct sti_dwmac *dwmac; +	int ret; + +	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); +	if (!dwmac) +		return ERR_PTR(-ENOMEM); + +	ret = sti_dwmac_parse_data(dwmac, pdev); +	if (ret) { +		dev_err(&pdev->dev, "Unable to parse OF data\n"); +		return ERR_PTR(ret); +	} + +	return dwmac; +} + +const struct stmmac_of_data sti_gmac_data = { +	.fix_mac_speed = sti_fix_mac_speed, +	.setup = sti_dwmac_setup, +	.init = sti_dwmac_init, +	.exit = sti_dwmac_exit, +}; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index d9af26ed58ee..f9e60d7918c4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -133,6 +133,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv);  #ifdef CONFIG_DWMAC_SUNXI  extern const struct stmmac_of_data sun7i_gmac_data;  #endif +#ifdef CONFIG_DWMAC_STI +extern const struct stmmac_of_data sti_gmac_data; +#endif  extern struct platform_driver stmmac_pltfr_driver;  static inline int stmmac_register_platform(void)  { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a2e7d2c96e36..078ad0ec8593 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1705,7 +1705,7 @@ static int stmmac_open(struct net_device *dev)  	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);  	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); -	alloc_dma_desc_resources(priv); +	ret = alloc_dma_desc_resources(priv);  	if (ret < 0) {  		pr_err("%s: DMA descriptors allocation failed\n", __func__);  		goto dma_desc_error; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 5884a7d2063b..c61bc72b8e90 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -33,6 +33,11 @@ static const struct of_device_id stmmac_dt_ids[] = {  #ifdef CONFIG_DWMAC_SUNXI  	{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},  #endif +#ifdef CONFIG_DWMAC_STI +	{ .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, +	{ .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, +	{ .compatible = "st,stih127-dwmac", .data = &sti_gmac_data}, +#endif  	/* SoC specific glue layers should come before generic bindings */  	{ .compatible = "st,spear600-gmac"},  	{ .compatible = "snps,dwmac-3.610"}, diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 1d860ce914ed..ffd4d12acf6d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -554,7 +554,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)  		 * common for both the interface as the interface shares  		 * the same hardware resource.  		 */ -		for (i = 0; i <= priv->data.slaves; i++) +		for (i = 0; i < priv->data.slaves; i++)  			if (priv->slaves[i].ndev->flags & IFF_PROMISC)  				flag = true; @@ -578,7 +578,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)  			unsigned long timeout = jiffies + HZ;  			/* Disable Learn for all ports */ -			for (i = 0; i <= priv->data.slaves; i++) { +			for (i = 0; i < priv->data.slaves; i++) {  				cpsw_ale_control_set(ale, i,  						     ALE_PORT_NOLEARN, 1);  				cpsw_ale_control_set(ale, i, @@ -606,7 +606,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)  			cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);  			/* Enable Learn for all ports */ -			for (i = 0; i <= priv->data.slaves; i++) { +			for (i = 0; i < priv->data.slaves; i++) {  				cpsw_ale_control_set(ale, i,  						     ALE_PORT_NOLEARN, 0);  				cpsw_ale_control_set(ale, i, @@ -1164,11 +1164,17 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)  static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)  { +	u32 slave_port; + +	slave_port = cpsw_get_slave_port(priv, slave->slave_num); +  	if (!slave->phy)  		return;  	phy_stop(slave->phy);  	phy_disconnect(slave->phy);  	slave->phy = NULL; +	cpsw_ale_control_set(priv->ale, slave_port, +			     ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);  }  static int cpsw_ndo_open(struct net_device *ndev) @@ -1896,6 +1902,11 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,  			memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);  		slave_data->phy_if = of_get_phy_mode(slave_node); +		if (slave_data->phy_if < 0) { +			pr_err("Missing or malformed slave[%d] phy-mode property\n", +			       i); +			return slave_data->phy_if; +		}  		if (data->dual_emac) {  			if (of_property_read_u32(slave_node, "dual_emac_res_vlan", diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 023237a65720..17503da9f7a5 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -2071,7 +2071,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)  /* Return subqueue id on this core (one per core). */  static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, -				 void *accel_priv) +				 void *accel_priv, select_queue_fallback_t fallback)  {  	return smp_processor_id();  } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1ec65feebb9e..4bfdf8c7ada0 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -26,6 +26,7 @@  #include <linux/netdevice.h>  #include <linux/of_mdio.h>  #include <linux/of_platform.h> +#include <linux/of_irq.h>  #include <linux/of_address.h>  #include <linux/skbuff.h>  #include <linux/spinlock.h> @@ -600,7 +601,8 @@ static void axienet_start_xmit_done(struct net_device *ndev)  		size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;  		packets++; -		lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; +		++lp->tx_bd_ci; +		lp->tx_bd_ci %= TX_BD_NUM;  		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];  		status = cur_p->status;  	} @@ -686,7 +688,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)  				     skb_headlen(skb), DMA_TO_DEVICE);  	for (ii = 0; ii < num_frag; ii++) { -		lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; +		++lp->tx_bd_tail; +		lp->tx_bd_tail %= TX_BD_NUM;  		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];  		frag = &skb_shinfo(skb)->frags[ii];  		cur_p->phys = dma_map_single(ndev->dev.parent, @@ -702,7 +705,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)  	tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;  	/* Start the transfer */  	axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); -	lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; +	++lp->tx_bd_tail; +	lp->tx_bd_tail %= TX_BD_NUM;  	return NETDEV_TX_OK;  } @@ -774,7 +778,8 @@ static void axienet_recv(struct net_device *ndev)  		cur_p->status = 0;  		cur_p->sw_id_offset = (u32) new_skb; -		lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; +		++lp->rx_bd_ci; +		lp->rx_bd_ci %= RX_BD_NUM;  		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];  	}  |