diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 162 | 
1 files changed, 116 insertions, 46 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index fa314cb005a..06a9d18bbdb 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -40,19 +40,27 @@  #define IXGBE_ALL_RAR_ENTRIES 16 +enum {NETDEV_STATS, IXGBE_STATS}; +  struct ixgbe_stats {  	char stat_string[ETH_GSTRING_LEN]; +	int type;  	int sizeof_stat;  	int stat_offset;  }; -#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \ -                             offsetof(struct ixgbe_adapter, m) +#define IXGBE_STAT(m)		IXGBE_STATS, \ +				sizeof(((struct ixgbe_adapter *)0)->m), \ +				offsetof(struct ixgbe_adapter, m) +#define IXGBE_NETDEV_STAT(m)	NETDEV_STATS, \ +				sizeof(((struct net_device *)0)->m), \ +				offsetof(struct net_device, m) +  static struct ixgbe_stats ixgbe_gstrings_stats[] = { -	{"rx_packets", IXGBE_STAT(net_stats.rx_packets)}, -	{"tx_packets", IXGBE_STAT(net_stats.tx_packets)}, -	{"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)}, -	{"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)}, +	{"rx_packets", IXGBE_NETDEV_STAT(stats.rx_packets)}, +	{"tx_packets", IXGBE_NETDEV_STAT(stats.tx_packets)}, +	{"rx_bytes", IXGBE_NETDEV_STAT(stats.rx_bytes)}, +	{"tx_bytes", IXGBE_NETDEV_STAT(stats.tx_bytes)},  	{"rx_pkts_nic", IXGBE_STAT(stats.gprc)},  	{"tx_pkts_nic", IXGBE_STAT(stats.gptc)},  	{"rx_bytes_nic", IXGBE_STAT(stats.gorc)}, @@ -60,40 +68,36 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {  	{"lsc_int", IXGBE_STAT(lsc_int)},  	{"tx_busy", IXGBE_STAT(tx_busy)},  	{"non_eop_descs", IXGBE_STAT(non_eop_descs)}, -	{"rx_errors", IXGBE_STAT(net_stats.rx_errors)}, -	{"tx_errors", IXGBE_STAT(net_stats.tx_errors)}, -	{"rx_dropped", IXGBE_STAT(net_stats.rx_dropped)}, -	{"tx_dropped", IXGBE_STAT(net_stats.tx_dropped)}, -	{"multicast", IXGBE_STAT(net_stats.multicast)}, +	{"rx_errors", IXGBE_NETDEV_STAT(stats.rx_errors)}, +	{"tx_errors", IXGBE_NETDEV_STAT(stats.tx_errors)}, +	{"rx_dropped", IXGBE_NETDEV_STAT(stats.rx_dropped)}, +	{"tx_dropped", IXGBE_NETDEV_STAT(stats.tx_dropped)}, +	{"multicast", IXGBE_NETDEV_STAT(stats.multicast)},  	{"broadcast", IXGBE_STAT(stats.bprc)},  	{"rx_no_buffer_count", IXGBE_STAT(stats.rnbc[0]) }, -	{"collisions", IXGBE_STAT(net_stats.collisions)}, -	{"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)}, -	{"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, -	{"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, -	{"hw_rsc_count", IXGBE_STAT(rsc_count)}, +	{"collisions", IXGBE_NETDEV_STAT(stats.collisions)}, +	{"rx_over_errors", IXGBE_NETDEV_STAT(stats.rx_over_errors)}, +	{"rx_crc_errors", IXGBE_NETDEV_STAT(stats.rx_crc_errors)}, +	{"rx_frame_errors", IXGBE_NETDEV_STAT(stats.rx_frame_errors)}, +	{"hw_rsc_aggregated", IXGBE_STAT(rsc_total_count)}, +	{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},  	{"fdir_match", IXGBE_STAT(stats.fdirmatch)},  	{"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, -	{"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, -	{"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, -	{"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, -	{"tx_carrier_errors", IXGBE_STAT(net_stats.tx_carrier_errors)}, -	{"tx_fifo_errors", IXGBE_STAT(net_stats.tx_fifo_errors)}, -	{"tx_heartbeat_errors", IXGBE_STAT(net_stats.tx_heartbeat_errors)}, +	{"rx_fifo_errors", IXGBE_NETDEV_STAT(stats.rx_fifo_errors)}, +	{"rx_missed_errors", IXGBE_NETDEV_STAT(stats.rx_missed_errors)}, +	{"tx_aborted_errors", IXGBE_NETDEV_STAT(stats.tx_aborted_errors)}, +	{"tx_carrier_errors", IXGBE_NETDEV_STAT(stats.tx_carrier_errors)}, +	{"tx_fifo_errors", IXGBE_NETDEV_STAT(stats.tx_fifo_errors)}, +	{"tx_heartbeat_errors", IXGBE_NETDEV_STAT(stats.tx_heartbeat_errors)},  	{"tx_timeout_count", IXGBE_STAT(tx_timeout_count)},  	{"tx_restart_queue", IXGBE_STAT(restart_queue)},  	{"rx_long_length_errors", IXGBE_STAT(stats.roc)},  	{"rx_short_length_errors", IXGBE_STAT(stats.ruc)}, -	{"tx_tcp4_seg_ctxt", IXGBE_STAT(hw_tso_ctxt)}, -	{"tx_tcp6_seg_ctxt", IXGBE_STAT(hw_tso6_ctxt)},  	{"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)},  	{"rx_flow_control_xon", IXGBE_STAT(stats.lxonrxc)},  	{"tx_flow_control_xoff", IXGBE_STAT(stats.lxofftxc)},  	{"rx_flow_control_xoff", IXGBE_STAT(stats.lxoffrxc)}, -	{"rx_csum_offload_good", IXGBE_STAT(hw_csum_rx_good)},  	{"rx_csum_offload_errors", IXGBE_STAT(hw_csum_rx_error)}, -	{"tx_csum_offload_ctxt", IXGBE_STAT(hw_csum_tx_good)}, -	{"rx_header_split", IXGBE_STAT(rx_hdr_split)},  	{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},  	{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},  	{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, @@ -196,6 +200,56 @@ static int ixgbe_get_settings(struct net_device *netdev,  		ecmd->autoneg = AUTONEG_DISABLE;  	} +	/* Get PHY type */ +	switch (adapter->hw.phy.type) { +	case ixgbe_phy_tn: +	case ixgbe_phy_cu_unknown: +		/* Copper 10G-BASET */ +		ecmd->port = PORT_TP; +		break; +	case ixgbe_phy_qt: +		ecmd->port = PORT_FIBRE; +		break; +	case ixgbe_phy_nl: +	case ixgbe_phy_tw_tyco: +	case ixgbe_phy_tw_unknown: +	case ixgbe_phy_sfp_ftl: +	case ixgbe_phy_sfp_avago: +	case ixgbe_phy_sfp_intel: +	case ixgbe_phy_sfp_unknown: +		switch (adapter->hw.phy.sfp_type) { +		/* SFP+ devices, further checking needed */ +		case ixgbe_sfp_type_da_cu: +		case ixgbe_sfp_type_da_cu_core0: +		case ixgbe_sfp_type_da_cu_core1: +			ecmd->port = PORT_DA; +			break; +		case ixgbe_sfp_type_sr: +		case ixgbe_sfp_type_lr: +		case ixgbe_sfp_type_srlr_core0: +		case ixgbe_sfp_type_srlr_core1: +			ecmd->port = PORT_FIBRE; +			break; +		case ixgbe_sfp_type_not_present: +			ecmd->port = PORT_NONE; +			break; +		case ixgbe_sfp_type_unknown: +		default: +			ecmd->port = PORT_OTHER; +			break; +		} +		break; +	case ixgbe_phy_xaui: +		ecmd->port = PORT_NONE; +		break; +	case ixgbe_phy_unknown: +	case ixgbe_phy_generic: +	case ixgbe_phy_sfp_unsupported: +	default: +		ecmd->port = PORT_OTHER; +		break; +	} +  	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);  	if (link_up) {  		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? @@ -798,7 +852,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,  {  	struct ixgbe_adapter *adapter = netdev_priv(netdev);  	struct ixgbe_ring *temp_tx_ring, *temp_rx_ring; -	int i, err; +	int i, err = 0;  	u32 new_rx_count, new_tx_count;  	bool need_update = false; @@ -822,6 +876,16 @@ static int ixgbe_set_ringparam(struct net_device *netdev,  	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))  		msleep(1); +	if (!netif_running(adapter->netdev)) { +		for (i = 0; i < adapter->num_tx_queues; i++) +			adapter->tx_ring[i].count = new_tx_count; +		for (i = 0; i < adapter->num_rx_queues; i++) +			adapter->rx_ring[i].count = new_rx_count; +		adapter->tx_ring_count = new_tx_count; +		adapter->rx_ring_count = new_rx_count; +		goto err_setup; +	} +  	temp_tx_ring = kcalloc(adapter->num_tx_queues,  	                       sizeof(struct ixgbe_ring), GFP_KERNEL);  	if (!temp_tx_ring) { @@ -879,8 +943,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,  	/* if rings need to be updated, here's the place to do it in one shot */  	if (need_update) { -		if (netif_running(netdev)) -			ixgbe_down(adapter); +		ixgbe_down(adapter);  		/* tx */  		if (new_tx_count != adapter->tx_ring_count) { @@ -897,13 +960,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev,  			temp_rx_ring = NULL;  			adapter->rx_ring_count = new_rx_count;  		} -	} - -	/* success! */ -	err = 0; -	if (netif_running(netdev))  		ixgbe_up(adapter); - +	}  err_setup:  	clear_bit(__IXGBE_RESETTING, &adapter->state);  	return err; @@ -929,10 +987,21 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,  	int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);  	int j, k;  	int i; +	char *p = NULL;  	ixgbe_update_stats(adapter);  	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { -		char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset; +		switch (ixgbe_gstrings_stats[i].type) { +		case NETDEV_STATS: +			p = (char *) netdev + +					ixgbe_gstrings_stats[i].stat_offset; +			break; +		case IXGBE_STATS: +			p = (char *) adapter + +					ixgbe_gstrings_stats[i].stat_offset; +			break; +		} +  		data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==  		           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;  	} @@ -1251,15 +1320,15 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)  		return 0;  	} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {  		shared_int = false; -		if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name, +		if (request_irq(irq, ixgbe_test_intr, 0, netdev->name,  				netdev)) {  			*data = 1;  			return -1;  		} -	} else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED, +	} else if (!request_irq(irq, ixgbe_test_intr, IRQF_PROBE_SHARED,  	                        netdev->name, netdev)) {  		shared_int = false; -	} else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED, +	} else if (request_irq(irq, ixgbe_test_intr, IRQF_SHARED,  	                       netdev->name, netdev)) {  		*data = 1;  		return -1; @@ -1948,6 +2017,10 @@ static int ixgbe_get_coalesce(struct net_device *netdev,  		break;  	} +	/* if in mixed tx/rx queues per vector mode, report only rx settings */ +	if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) +		return 0; +  	/* only valid if in constant ITR mode */  	switch (adapter->tx_itr_setting) {  	case 0: @@ -1973,12 +2046,9 @@ static int ixgbe_set_coalesce(struct net_device *netdev,  	struct ixgbe_q_vector *q_vector;  	int i; -	/* -	 * don't accept tx specific changes if we've got mixed RxTx vectors -	 * test and jump out here if needed before changing the rx numbers -	 */ -	if ((1000000/ec->tx_coalesce_usecs) != adapter->tx_eitr_param && -	    adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) +	/* don't accept tx specific changes if we've got mixed RxTx vectors */ +	if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count +	   && ec->tx_coalesce_usecs)  		return -EINVAL;  	if (ec->tx_max_coalesced_frames_irq)  |