diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 68 | 
1 files changed, 50 insertions, 18 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 684af371462..6c00ee493a3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -36,6 +36,7 @@  #include <linux/tcp.h>  #include <linux/pkt_sched.h>  #include <linux/ipv6.h> +#include <linux/slab.h>  #include <net/checksum.h>  #include <net/ip6_checksum.h>  #include <linux/ethtool.h> @@ -935,10 +936,12 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,  			if (skb->prev)  				skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));  			if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { -				if (IXGBE_RSC_CB(skb)->dma) +				if (IXGBE_RSC_CB(skb)->dma) {  					pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma,  					                 rx_ring->rx_buf_len,  					                 PCI_DMA_FROMDEVICE); +					IXGBE_RSC_CB(skb)->dma = 0; +				}  				if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)  					rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;  				else @@ -2979,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)  	else  		ixgbe_configure_msi_and_legacy(adapter); +	/* enable the optics */ +	if (hw->phy.multispeed_fiber) +		hw->mac.ops.enable_tx_laser(hw); +  	clear_bit(__IXGBE_DOWN, &adapter->state);  	ixgbe_napi_enable_all(adapter); @@ -3054,6 +3061,14 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)  	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))  		msleep(1);  	ixgbe_down(adapter); +	/* +	 * If SR-IOV enabled then wait a bit before bringing the adapter +	 * back up to give the VFs time to respond to the reset.  The +	 * two second wait is based upon the watchdog timer cycle in +	 * the VF driver. +	 */ +	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) +		msleep(2000);  	ixgbe_up(adapter);  	clear_bit(__IXGBE_RESETTING, &adapter->state);  } @@ -3126,10 +3141,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,  			rx_buffer_info->skb = NULL;  			do {  				struct sk_buff *this = skb; -				if (IXGBE_RSC_CB(this)->dma) +				if (IXGBE_RSC_CB(this)->dma) {  					pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma,  					                 rx_ring->rx_buf_len,  					                 PCI_DMA_FROMDEVICE); +					IXGBE_RSC_CB(this)->dma = 0; +				}  				skb = skb->prev;  				dev_kfree_skb(this);  			} while (skb); @@ -3230,15 +3247,21 @@ void ixgbe_down(struct ixgbe_adapter *adapter)  	/* signal that we are down to the interrupt handler */  	set_bit(__IXGBE_DOWN, &adapter->state); +	/* power down the optics */ +	if (hw->phy.multispeed_fiber) +		hw->mac.ops.disable_tx_laser(hw); +  	/* disable receive for all VFs and wait one second */  	if (adapter->num_vfs) { -		for (i = 0 ; i < adapter->num_vfs; i++) -			adapter->vfinfo[i].clear_to_send = 0; -  		/* ping all the active vfs to let them know we are going down */  		ixgbe_ping_all_vfs(adapter); +  		/* Disable all VFTE/VFRE TX/RX */  		ixgbe_disable_tx_rx(adapter); + +		/* Mark all the VFs as inactive */ +		for (i = 0 ; i < adapter->num_vfs; i++) +			adapter->vfinfo[i].clear_to_send = 0;  	}  	/* disable receives */ @@ -5018,6 +5041,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)  	autoneg = hw->phy.autoneg_advertised;  	if ((!autoneg) && (hw->mac.ops.get_link_capabilities))  		hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); +	hw->mac.autotry_restart = false;  	if (hw->mac.ops.setup_link)  		hw->mac.ops.setup_link(hw, autoneg, negotiation, true);  	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; @@ -5633,7 +5657,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)  #ifdef IXGBE_FCOE  	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && -	    (skb->protocol == htons(ETH_P_FCOE))) { +	    ((skb->protocol == htons(ETH_P_FCOE)) || +	     (skb->protocol == htons(ETH_P_FIP)))) {  		txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);  		txq += adapter->ring_feature[RING_F_FCOE].mask;  		return txq; @@ -5680,18 +5705,25 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,  	tx_ring = adapter->tx_ring[skb->queue_mapping]; -	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && -	    (skb->protocol == htons(ETH_P_FCOE))) { -		tx_flags |= IXGBE_TX_FLAGS_FCOE;  #ifdef IXGBE_FCOE +	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {  #ifdef CONFIG_IXGBE_DCB -		tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK -			      << IXGBE_TX_FLAGS_VLAN_SHIFT); -		tx_flags |= ((adapter->fcoe.up << 13) -			      << IXGBE_TX_FLAGS_VLAN_SHIFT); -#endif +		/* for FCoE with DCB, we force the priority to what +		 * was specified by the switch */ +		if ((skb->protocol == htons(ETH_P_FCOE)) || +		    (skb->protocol == htons(ETH_P_FIP))) { +			tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK +				      << IXGBE_TX_FLAGS_VLAN_SHIFT); +			tx_flags |= ((adapter->fcoe.up << 13) +				     << IXGBE_TX_FLAGS_VLAN_SHIFT); +		}  #endif +		/* flag for FCoE offloads */ +		if (skb->protocol == htons(ETH_P_FCOE)) +			tx_flags |= IXGBE_TX_FLAGS_FCOE;  	} +#endif +  	/* four things can cause us to need a context descriptor */  	if (skb_is_gso(skb) ||  	    (skb->ip_summed == CHECKSUM_PARTIAL) || @@ -6046,7 +6078,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,  	indices += min_t(unsigned int, num_possible_cpus(),  			 IXGBE_MAX_FCOE_INDICES);  #endif -	indices = min_t(unsigned int, indices, MAX_TX_QUEUES);  	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);  	if (!netdev) {  		err = -ENOMEM; @@ -6230,6 +6261,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,  		goto err_eeprom;  	} +	/* power down the optics */ +	if (hw->phy.multispeed_fiber) +		hw->mac.ops.disable_tx_laser(hw); +  	init_timer(&adapter->watchdog_timer);  	adapter->watchdog_timer.function = &ixgbe_watchdog;  	adapter->watchdog_timer.data = (unsigned long)adapter; @@ -6245,9 +6280,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,  	case IXGBE_DEV_ID_82599_KX4:  		adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |  		                IXGBE_WUFC_MC | IXGBE_WUFC_BC); -		/* Enable ACPI wakeup in GRC */ -		IXGBE_WRITE_REG(hw, IXGBE_GRC, -		             (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));  		break;  	default:  		adapter->wol = 0;  |