diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic')
| -rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 21 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 15 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 37 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlge/qlge.h | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c | 315 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlge/qlge_main.c | 100 | 
12 files changed, 327 insertions, 206 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 37ccbe54e62..eb3dfdbb642 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -53,8 +53,8 @@  #define _NETXEN_NIC_LINUX_MAJOR 4  #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 79 -#define NETXEN_NIC_LINUX_VERSIONID  "4.0.79" +#define _NETXEN_NIC_LINUX_SUBVERSION 80 +#define NETXEN_NIC_LINUX_VERSIONID  "4.0.80"  #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))  #define _major(v)	(((v) >> 24) & 0xff) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 39730403782..10468e7932d 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -489,7 +489,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,  	int port = adapter->physical_port;  	if (adapter->ahw.port_type == NETXEN_NIC_GBE) { -		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) +		if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))  			return;  		/* get flow control settings */  		val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); @@ -511,7 +511,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,  				break;  		}  	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { -		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) +		if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))  			return;  		pause->rx_pause = 1;  		val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); @@ -534,7 +534,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,  	int port = adapter->physical_port;  	/* read mode */  	if (adapter->ahw.port_type == NETXEN_NIC_GBE) { -		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) +		if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))  			return -EIO;  		/* set flow control */  		val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); @@ -577,7 +577,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,  		}  		NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);  	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { -		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) +		if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))  			return -EIO;  		val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);  		if (port == 0) { @@ -826,7 +826,12 @@ netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)  		dump->len = mdump->md_dump_size;  	else  		dump->len = 0; -	dump->flag = mdump->md_capture_mask; + +	if (!mdump->md_enabled) +		dump->flag = ETH_FW_DUMP_DISABLE; +	else +		dump->flag = mdump->md_capture_mask; +  	dump->version = adapter->fw_version;  	return 0;  } @@ -840,8 +845,10 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)  	switch (val->flag) {  	case NX_FORCE_FW_DUMP_KEY: -		if (!mdump->md_enabled) -			mdump->md_enabled = 1; +		if (!mdump->md_enabled) { +			netdev_info(netdev, "FW dump not enabled\n"); +			return 0; +		}  		if (adapter->fw_mdump_rdy) {  			netdev_info(netdev, "Previous dump not cleared, not forcing dump\n");  			return 0; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index de96a948bb7..946160fa584 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -365,7 +365,7 @@ static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)  	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))  		return 0; -	if (port > NETXEN_NIU_MAX_XG_PORTS) +	if (port >= NETXEN_NIU_MAX_XG_PORTS)  		return -EINVAL;  	mac_cfg = 0; @@ -392,7 +392,7 @@ static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)  	u32 port = adapter->physical_port;  	u16 board_type = adapter->ahw.board_type; -	if (port > NETXEN_NIU_MAX_XG_PORTS) +	if (port >= NETXEN_NIU_MAX_XG_PORTS)  		return -EINVAL;  	mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 8694124ef77..bc165f4d0f6 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -1437,8 +1437,6 @@ netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)  				netdev->name, cable_len);  	} -	netxen_advert_link_change(adapter, link_status); -  	/* update link parameters */  	if (duplex == LINKEVENT_FULL_DUPLEX)  		adapter->link_duplex = DUPLEX_FULL; @@ -1447,6 +1445,8 @@ netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)  	adapter->module_type = module;  	adapter->link_autoneg = autoneg;  	adapter->link_speed = link_speed; + +	netxen_advert_link_change(adapter, link_status);  }  static void @@ -1532,8 +1532,6 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,  	} else  		skb->ip_summed = CHECKSUM_NONE; -	skb->dev = adapter->netdev; -  	buffer->skb = NULL;  no_skb:  	buffer->state = NETXEN_BUFFER_FREE; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 8680a5dae4a..eaa1db9fec3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -36,8 +36,8 @@  #define _QLCNIC_LINUX_MAJOR 5  #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 28 -#define QLCNIC_LINUX_VERSIONID  "5.0.28" +#define _QLCNIC_LINUX_SUBVERSION 29 +#define QLCNIC_LINUX_VERSIONID  "5.0.29"  #define QLCNIC_DRV_IDC_VER  0x01  #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\  		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -258,6 +258,8 @@ struct rcv_desc {  	(((sts_data) >> 52) & 0x1)  #define qlcnic_get_lro_sts_seq_number(sts_data)		\  	((sts_data) & 0x0FFFFFFFF) +#define qlcnic_get_lro_sts_mss(sts_data1)		\ +	((sts_data1 >> 32) & 0x0FFFF)  struct status_desc { @@ -610,7 +612,11 @@ struct qlcnic_recv_context {  #define QLCNIC_CDRP_CMD_GET_MAC_STATS		0x00000037  #define QLCNIC_RCODE_SUCCESS		0 +#define QLCNIC_RCODE_INVALID_ARGS	6  #define QLCNIC_RCODE_NOT_SUPPORTED	9 +#define QLCNIC_RCODE_NOT_PERMITTED	10 +#define QLCNIC_RCODE_NOT_IMPL		15 +#define QLCNIC_RCODE_INVALID		16  #define QLCNIC_RCODE_TIMEOUT		17  #define QLCNIC_DESTROY_CTX_RESET	0 @@ -623,6 +629,7 @@ struct qlcnic_recv_context {  #define QLCNIC_CAP0_JUMBO_CONTIGUOUS	(1 << 7)  #define QLCNIC_CAP0_LRO_CONTIGUOUS	(1 << 8)  #define QLCNIC_CAP0_VALIDOFF		(1 << 11) +#define QLCNIC_CAP0_LRO_MSS		(1 << 21)  /*   * Context state @@ -829,6 +836,9 @@ struct qlcnic_mac_list_s {  #define QLCNIC_FW_CAPABILITY_FVLANTX		BIT_9  #define QLCNIC_FW_CAPABILITY_HW_LRO		BIT_10  #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK	BIT_27 +#define QLCNIC_FW_CAPABILITY_MORE_CAPS		BIT_31 + +#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG	BIT_2  /* module types */  #define LINKEVENT_MODULE_NOT_PRESENT			1 @@ -918,6 +928,7 @@ struct qlcnic_ipaddr {  #define QLCNIC_NEED_FLR			0x1000  #define QLCNIC_FW_RESET_OWNER		0x2000  #define QLCNIC_FW_HANG			0x4000 +#define QLCNIC_FW_LRO_MSS_CAP		0x8000  #define QLCNIC_IS_MSI_FAMILY(adapter) \  	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 8db85244e8a..b8ead696141 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)  	rsp = qlcnic_poll_rsp(adapter);  	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { -		dev_err(&pdev->dev, "card response timeout.\n"); +		dev_err(&pdev->dev, "CDRP response timeout.\n");  		cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT;  	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {  		cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); -		dev_err(&pdev->dev, "failed card response code:0x%x\n", +		switch (cmd->rsp.cmd) { +		case QLCNIC_RCODE_INVALID_ARGS: +			dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n",  				cmd->rsp.cmd); +			break; +		case QLCNIC_RCODE_NOT_SUPPORTED: +		case QLCNIC_RCODE_NOT_IMPL: +			dev_err(&pdev->dev, +				"CDRP command not supported: 0x%x.\n", +				cmd->rsp.cmd); +			break; +		case QLCNIC_RCODE_NOT_PERMITTED: +			dev_err(&pdev->dev, +				"CDRP requested action not permitted: 0x%x.\n", +				cmd->rsp.cmd); +			break; +		case QLCNIC_RCODE_INVALID: +			dev_err(&pdev->dev, +				"CDRP invalid or unknown cmd received: 0x%x.\n", +				cmd->rsp.cmd); +			break; +		case QLCNIC_RCODE_TIMEOUT: +			dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n", +				cmd->rsp.cmd); +			break; +		default: +			dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n", +				cmd->rsp.cmd); +		}  	} else if (rsp == QLCNIC_CDRP_RSP_OK) {  		cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS;  		if (cmd->rsp.arg2) @@ -237,6 +264,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)  						| QLCNIC_CAP0_VALIDOFF);  	cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); +	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) +		cap |= QLCNIC_CAP0_LRO_MSS; +  	prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,  							 msix_handler);  	prq->txrx_sds_binding = nsds_rings - 1; @@ -954,9 +984,6 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter,  		mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber);  		mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped);  		mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); -	} else { -		dev_info(&adapter->pdev->dev, -			"%s: Get mac stats failed =%d.\n", __func__, err);  	}  	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index 6ced3195aad..28a6b28192e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h @@ -588,6 +588,7 @@ enum {  #define CRB_DRIVER_VERSION		(QLCNIC_REG(0x2a0))  #define CRB_FW_CAPABILITIES_1		(QLCNIC_CAM_RAM(0x128)) +#define CRB_FW_CAPABILITIES_2		(QLCNIC_CAM_RAM(0x12c))  #define CRB_MAC_BLOCK_START		(QLCNIC_CAM_RAM(0x1c0))  /* diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 799fd40ed03..0bcda9c51e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -1488,8 +1488,6 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,  		skb_checksum_none_assert(skb);  	} -	skb->dev = adapter->netdev; -  	buffer->skb = NULL;  	return skb; @@ -1653,6 +1651,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,  	length = skb->len; +	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) +		skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1); +  	if (vid != 0xffff)  		__vlan_hwaccel_put_tag(skb, vid);  	netif_receive_skb(skb); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c512..212c1219327 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -479,7 +479,7 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)  	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {  		pfn = pci_info[i].id; -		if (pfn > QLCNIC_MAX_PCI_FUNC) { +		if (pfn >= QLCNIC_MAX_PCI_FUNC) {  			ret = QL_STATUS_INVALID_PARAM;  			goto err_eswitch;  		} @@ -1136,6 +1136,8 @@ static int  __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)  {  	int ring; +	u32 capab2; +  	struct qlcnic_host_rds_ring *rds_ring;  	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) @@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)  	if (qlcnic_set_eswitch_port_config(adapter))  		return -EIO; +	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { +		capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2); +		if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) +			adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; +	} +  	if (qlcnic_fw_create_ctx(adapter))  		return -EIO; @@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)  	qlcnic_napi_disable(adapter);  	qlcnic_fw_destroy_ctx(adapter); +	adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP;  	qlcnic_reset_rx_buffers_list(adapter);  	qlcnic_release_tx_buffers(adapter); @@ -2024,6 +2033,7 @@ qlcnic_tx_pkt(struct qlcnic_adapter *adapter,  		vh = (struct vlan_ethhdr *)skb->data;  		flags = FLAGS_VLAN_TAGGED;  		vlan_tci = vh->h_vlan_TCI; +		protocol = ntohs(vh->h_vlan_encapsulated_proto);  	} else if (vlan_tx_tag_present(skb)) {  		flags = FLAGS_VLAN_OOB;  		vlan_tci = vlan_tx_tag_get(skb); diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index 5a639df33f1..a131d7b5d2f 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -18,13 +18,15 @@   */  #define DRV_NAME  	"qlge"  #define DRV_STRING 	"QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION	"v1.00.00.30.00.00-01" +#define DRV_VERSION	"v1.00.00.31"  #define WQ_ADDR_ALIGN	0x3	/* 4 byte alignment */  #define QLGE_VENDOR_ID    0x1077  #define QLGE_DEVICE_ID_8012	0x8012  #define QLGE_DEVICE_ID_8000	0x8000 +#define QLGE_MEZZ_SSYS_ID_068	0x0068 +#define QLGE_MEZZ_SSYS_ID_180	0x0180  #define MAX_CPUS 8  #define MAX_TX_RINGS MAX_CPUS  #define MAX_RX_RINGS ((MAX_CPUS * 2) + 1) @@ -1397,7 +1399,6 @@ struct tx_ring {  	struct tx_ring_desc *q;	/* descriptor list for the queue */  	spinlock_t lock;  	atomic_t tx_count;	/* counts down for every outstanding IO */ -	atomic_t queue_stopped;	/* Turns queue off when full. */  	struct delayed_work tx_work;  	struct ql_adapter *qdev;  	u64 tx_packets; @@ -1535,6 +1536,14 @@ struct nic_stats {  	u64 rx_1024_to_1518_pkts;  	u64 rx_1519_to_max_pkts;  	u64 rx_len_err_pkts; +	/* Receive Mac Err stats */ +	u64 rx_code_err; +	u64 rx_oversize_err; +	u64 rx_undersize_err; +	u64 rx_preamble_err; +	u64 rx_frame_len_err; +	u64 rx_crc_err; +	u64 rx_err_count;  	/*  	 * These stats come from offset 500h to 5C8h  	 * in the XGMAC register. diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c index 8e2c2a74f3a..6f316ab2325 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c @@ -35,10 +35,152 @@  #include "qlge.h" +struct ql_stats { +	char stat_string[ETH_GSTRING_LEN]; +	int sizeof_stat; +	int stat_offset; +}; + +#define QL_SIZEOF(m) FIELD_SIZEOF(struct ql_adapter, m) +#define QL_OFF(m) offsetof(struct ql_adapter, m) + +static const struct ql_stats ql_gstrings_stats[] = { +	{"tx_pkts", QL_SIZEOF(nic_stats.tx_pkts), QL_OFF(nic_stats.tx_pkts)}, +	{"tx_bytes", QL_SIZEOF(nic_stats.tx_bytes), QL_OFF(nic_stats.tx_bytes)}, +	{"tx_mcast_pkts", QL_SIZEOF(nic_stats.tx_mcast_pkts), +					QL_OFF(nic_stats.tx_mcast_pkts)}, +	{"tx_bcast_pkts", QL_SIZEOF(nic_stats.tx_bcast_pkts), +					QL_OFF(nic_stats.tx_bcast_pkts)}, +	{"tx_ucast_pkts", QL_SIZEOF(nic_stats.tx_ucast_pkts), +					QL_OFF(nic_stats.tx_ucast_pkts)}, +	{"tx_ctl_pkts", QL_SIZEOF(nic_stats.tx_ctl_pkts), +					QL_OFF(nic_stats.tx_ctl_pkts)}, +	{"tx_pause_pkts", QL_SIZEOF(nic_stats.tx_pause_pkts), +					QL_OFF(nic_stats.tx_pause_pkts)}, +	{"tx_64_pkts", QL_SIZEOF(nic_stats.tx_64_pkt), +					QL_OFF(nic_stats.tx_64_pkt)}, +	{"tx_65_to_127_pkts", QL_SIZEOF(nic_stats.tx_65_to_127_pkt), +					QL_OFF(nic_stats.tx_65_to_127_pkt)}, +	{"tx_128_to_255_pkts", QL_SIZEOF(nic_stats.tx_128_to_255_pkt), +					QL_OFF(nic_stats.tx_128_to_255_pkt)}, +	{"tx_256_511_pkts", QL_SIZEOF(nic_stats.tx_256_511_pkt), +					QL_OFF(nic_stats.tx_256_511_pkt)}, +	{"tx_512_to_1023_pkts",	QL_SIZEOF(nic_stats.tx_512_to_1023_pkt), +					QL_OFF(nic_stats.tx_512_to_1023_pkt)}, +	{"tx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.tx_1024_to_1518_pkt), +					QL_OFF(nic_stats.tx_1024_to_1518_pkt)}, +	{"tx_1519_to_max_pkts",	QL_SIZEOF(nic_stats.tx_1519_to_max_pkt), +					QL_OFF(nic_stats.tx_1519_to_max_pkt)}, +	{"tx_undersize_pkts", QL_SIZEOF(nic_stats.tx_undersize_pkt), +					QL_OFF(nic_stats.tx_undersize_pkt)}, +	{"tx_oversize_pkts", QL_SIZEOF(nic_stats.tx_oversize_pkt), +					QL_OFF(nic_stats.tx_oversize_pkt)}, +	{"rx_bytes", QL_SIZEOF(nic_stats.rx_bytes), QL_OFF(nic_stats.rx_bytes)}, +	{"rx_bytes_ok",	QL_SIZEOF(nic_stats.rx_bytes_ok), +					QL_OFF(nic_stats.rx_bytes_ok)}, +	{"rx_pkts", QL_SIZEOF(nic_stats.rx_pkts), QL_OFF(nic_stats.rx_pkts)}, +	{"rx_pkts_ok", QL_SIZEOF(nic_stats.rx_pkts_ok), +					QL_OFF(nic_stats.rx_pkts_ok)}, +	{"rx_bcast_pkts", QL_SIZEOF(nic_stats.rx_bcast_pkts), +					QL_OFF(nic_stats.rx_bcast_pkts)}, +	{"rx_mcast_pkts", QL_SIZEOF(nic_stats.rx_mcast_pkts), +					QL_OFF(nic_stats.rx_mcast_pkts)}, +	{"rx_ucast_pkts", QL_SIZEOF(nic_stats.rx_ucast_pkts), +					QL_OFF(nic_stats.rx_ucast_pkts)}, +	{"rx_undersize_pkts", QL_SIZEOF(nic_stats.rx_undersize_pkts), +					QL_OFF(nic_stats.rx_undersize_pkts)}, +	{"rx_oversize_pkts", QL_SIZEOF(nic_stats.rx_oversize_pkts), +					QL_OFF(nic_stats.rx_oversize_pkts)}, +	{"rx_jabber_pkts", QL_SIZEOF(nic_stats.rx_jabber_pkts), +					QL_OFF(nic_stats.rx_jabber_pkts)}, +	{"rx_undersize_fcerr_pkts", +		QL_SIZEOF(nic_stats.rx_undersize_fcerr_pkts), +				QL_OFF(nic_stats.rx_undersize_fcerr_pkts)}, +	{"rx_drop_events", QL_SIZEOF(nic_stats.rx_drop_events), +					QL_OFF(nic_stats.rx_drop_events)}, +	{"rx_fcerr_pkts", QL_SIZEOF(nic_stats.rx_fcerr_pkts), +					QL_OFF(nic_stats.rx_fcerr_pkts)}, +	{"rx_align_err", QL_SIZEOF(nic_stats.rx_align_err), +					QL_OFF(nic_stats.rx_align_err)}, +	{"rx_symbol_err", QL_SIZEOF(nic_stats.rx_symbol_err), +					QL_OFF(nic_stats.rx_symbol_err)}, +	{"rx_mac_err", QL_SIZEOF(nic_stats.rx_mac_err), +					QL_OFF(nic_stats.rx_mac_err)}, +	{"rx_ctl_pkts",	QL_SIZEOF(nic_stats.rx_ctl_pkts), +					QL_OFF(nic_stats.rx_ctl_pkts)}, +	{"rx_pause_pkts", QL_SIZEOF(nic_stats.rx_pause_pkts), +					QL_OFF(nic_stats.rx_pause_pkts)}, +	{"rx_64_pkts", QL_SIZEOF(nic_stats.rx_64_pkts), +					QL_OFF(nic_stats.rx_64_pkts)}, +	{"rx_65_to_127_pkts", QL_SIZEOF(nic_stats.rx_65_to_127_pkts), +					QL_OFF(nic_stats.rx_65_to_127_pkts)}, +	{"rx_128_255_pkts", QL_SIZEOF(nic_stats.rx_128_255_pkts), +					QL_OFF(nic_stats.rx_128_255_pkts)}, +	{"rx_256_511_pkts", QL_SIZEOF(nic_stats.rx_256_511_pkts), +					QL_OFF(nic_stats.rx_256_511_pkts)}, +	{"rx_512_to_1023_pkts",	QL_SIZEOF(nic_stats.rx_512_to_1023_pkts), +					QL_OFF(nic_stats.rx_512_to_1023_pkts)}, +	{"rx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.rx_1024_to_1518_pkts), +					QL_OFF(nic_stats.rx_1024_to_1518_pkts)}, +	{"rx_1519_to_max_pkts",	QL_SIZEOF(nic_stats.rx_1519_to_max_pkts), +					QL_OFF(nic_stats.rx_1519_to_max_pkts)}, +	{"rx_len_err_pkts", QL_SIZEOF(nic_stats.rx_len_err_pkts), +					QL_OFF(nic_stats.rx_len_err_pkts)}, +	{"rx_code_err",	QL_SIZEOF(nic_stats.rx_code_err), +					QL_OFF(nic_stats.rx_code_err)}, +	{"rx_oversize_err", QL_SIZEOF(nic_stats.rx_oversize_err), +					QL_OFF(nic_stats.rx_oversize_err)}, +	{"rx_undersize_err", QL_SIZEOF(nic_stats.rx_undersize_err), +					QL_OFF(nic_stats.rx_undersize_err)}, +	{"rx_preamble_err", QL_SIZEOF(nic_stats.rx_preamble_err), +					QL_OFF(nic_stats.rx_preamble_err)}, +	{"rx_frame_len_err", QL_SIZEOF(nic_stats.rx_frame_len_err), +					QL_OFF(nic_stats.rx_frame_len_err)}, +	{"rx_crc_err", QL_SIZEOF(nic_stats.rx_crc_err), +					QL_OFF(nic_stats.rx_crc_err)}, +	{"rx_err_count", QL_SIZEOF(nic_stats.rx_err_count), +					QL_OFF(nic_stats.rx_err_count)}, +	{"tx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames0), +				QL_OFF(nic_stats.tx_cbfc_pause_frames0)}, +	{"tx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames1), +				QL_OFF(nic_stats.tx_cbfc_pause_frames1)}, +	{"tx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames2), +				QL_OFF(nic_stats.tx_cbfc_pause_frames2)}, +	{"tx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames3), +				QL_OFF(nic_stats.tx_cbfc_pause_frames3)}, +	{"tx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames4), +				QL_OFF(nic_stats.tx_cbfc_pause_frames4)}, +	{"tx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames5), +				QL_OFF(nic_stats.tx_cbfc_pause_frames5)}, +	{"tx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames6), +				QL_OFF(nic_stats.tx_cbfc_pause_frames6)}, +	{"tx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames7), +				QL_OFF(nic_stats.tx_cbfc_pause_frames7)}, +	{"rx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames0), +				QL_OFF(nic_stats.rx_cbfc_pause_frames0)}, +	{"rx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames1), +				QL_OFF(nic_stats.rx_cbfc_pause_frames1)}, +	{"rx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames2), +				QL_OFF(nic_stats.rx_cbfc_pause_frames2)}, +	{"rx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames3), +				QL_OFF(nic_stats.rx_cbfc_pause_frames3)}, +	{"rx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames4), +				QL_OFF(nic_stats.rx_cbfc_pause_frames4)}, +	{"rx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames5), +				QL_OFF(nic_stats.rx_cbfc_pause_frames5)}, +	{"rx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames6), +				QL_OFF(nic_stats.rx_cbfc_pause_frames6)}, +	{"rx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames7), +				QL_OFF(nic_stats.rx_cbfc_pause_frames7)}, +	{"rx_nic_fifo_drop", QL_SIZEOF(nic_stats.rx_nic_fifo_drop), +					QL_OFF(nic_stats.rx_nic_fifo_drop)}, +}; +  static const char ql_gstrings_test[][ETH_GSTRING_LEN] = {  	"Loopback test  (offline)"  };  #define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN) +#define QLGE_STATS_LEN ARRAY_SIZE(ql_gstrings_stats)  static int ql_update_ring_coalescing(struct ql_adapter *qdev)  { @@ -183,73 +325,19 @@ quit:  	QL_DUMP_STAT(qdev);  } -static char ql_stats_str_arr[][ETH_GSTRING_LEN] = { -	{"tx_pkts"}, -	{"tx_bytes"}, -	{"tx_mcast_pkts"}, -	{"tx_bcast_pkts"}, -	{"tx_ucast_pkts"}, -	{"tx_ctl_pkts"}, -	{"tx_pause_pkts"}, -	{"tx_64_pkts"}, -	{"tx_65_to_127_pkts"}, -	{"tx_128_to_255_pkts"}, -	{"tx_256_511_pkts"}, -	{"tx_512_to_1023_pkts"}, -	{"tx_1024_to_1518_pkts"}, -	{"tx_1519_to_max_pkts"}, -	{"tx_undersize_pkts"}, -	{"tx_oversize_pkts"}, -	{"rx_bytes"}, -	{"rx_bytes_ok"}, -	{"rx_pkts"}, -	{"rx_pkts_ok"}, -	{"rx_bcast_pkts"}, -	{"rx_mcast_pkts"}, -	{"rx_ucast_pkts"}, -	{"rx_undersize_pkts"}, -	{"rx_oversize_pkts"}, -	{"rx_jabber_pkts"}, -	{"rx_undersize_fcerr_pkts"}, -	{"rx_drop_events"}, -	{"rx_fcerr_pkts"}, -	{"rx_align_err"}, -	{"rx_symbol_err"}, -	{"rx_mac_err"}, -	{"rx_ctl_pkts"}, -	{"rx_pause_pkts"}, -	{"rx_64_pkts"}, -	{"rx_65_to_127_pkts"}, -	{"rx_128_255_pkts"}, -	{"rx_256_511_pkts"}, -	{"rx_512_to_1023_pkts"}, -	{"rx_1024_to_1518_pkts"}, -	{"rx_1519_to_max_pkts"}, -	{"rx_len_err_pkts"}, -	{"tx_cbfc_pause_frames0"}, -	{"tx_cbfc_pause_frames1"}, -	{"tx_cbfc_pause_frames2"}, -	{"tx_cbfc_pause_frames3"}, -	{"tx_cbfc_pause_frames4"}, -	{"tx_cbfc_pause_frames5"}, -	{"tx_cbfc_pause_frames6"}, -	{"tx_cbfc_pause_frames7"}, -	{"rx_cbfc_pause_frames0"}, -	{"rx_cbfc_pause_frames1"}, -	{"rx_cbfc_pause_frames2"}, -	{"rx_cbfc_pause_frames3"}, -	{"rx_cbfc_pause_frames4"}, -	{"rx_cbfc_pause_frames5"}, -	{"rx_cbfc_pause_frames6"}, -	{"rx_cbfc_pause_frames7"}, -	{"rx_nic_fifo_drop"}, -}; -  static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)  { +	int index;  	switch (stringset) { +	case ETH_SS_TEST: +		memcpy(buf, *ql_gstrings_test, QLGE_TEST_LEN * ETH_GSTRING_LEN); +		break;  	case ETH_SS_STATS: -		memcpy(buf, ql_stats_str_arr, sizeof(ql_stats_str_arr)); +		for (index = 0; index < QLGE_STATS_LEN; index++) { +			memcpy(buf + index * ETH_GSTRING_LEN, +				ql_gstrings_stats[index].stat_string, +				ETH_GSTRING_LEN); +		}  		break;  	}  } @@ -260,7 +348,7 @@ static int ql_get_sset_count(struct net_device *dev, int sset)  	case ETH_SS_TEST:  		return QLGE_TEST_LEN;  	case ETH_SS_STATS: -		return ARRAY_SIZE(ql_stats_str_arr); +		return QLGE_STATS_LEN;  	default:  		return -EOPNOTSUPP;  	} @@ -271,69 +359,17 @@ ql_get_ethtool_stats(struct net_device *ndev,  		     struct ethtool_stats *stats, u64 *data)  {  	struct ql_adapter *qdev = netdev_priv(ndev); -	struct nic_stats *s = &qdev->nic_stats; +	int index, length; +	length = QLGE_STATS_LEN;  	ql_update_stats(qdev); -	*data++ = s->tx_pkts; -	*data++ = s->tx_bytes; -	*data++ = s->tx_mcast_pkts; -	*data++ = s->tx_bcast_pkts; -	*data++ = s->tx_ucast_pkts; -	*data++ = s->tx_ctl_pkts; -	*data++ = s->tx_pause_pkts; -	*data++ = s->tx_64_pkt; -	*data++ = s->tx_65_to_127_pkt; -	*data++ = s->tx_128_to_255_pkt; -	*data++ = s->tx_256_511_pkt; -	*data++ = s->tx_512_to_1023_pkt; -	*data++ = s->tx_1024_to_1518_pkt; -	*data++ = s->tx_1519_to_max_pkt; -	*data++ = s->tx_undersize_pkt; -	*data++ = s->tx_oversize_pkt; -	*data++ = s->rx_bytes; -	*data++ = s->rx_bytes_ok; -	*data++ = s->rx_pkts; -	*data++ = s->rx_pkts_ok; -	*data++ = s->rx_bcast_pkts; -	*data++ = s->rx_mcast_pkts; -	*data++ = s->rx_ucast_pkts; -	*data++ = s->rx_undersize_pkts; -	*data++ = s->rx_oversize_pkts; -	*data++ = s->rx_jabber_pkts; -	*data++ = s->rx_undersize_fcerr_pkts; -	*data++ = s->rx_drop_events; -	*data++ = s->rx_fcerr_pkts; -	*data++ = s->rx_align_err; -	*data++ = s->rx_symbol_err; -	*data++ = s->rx_mac_err; -	*data++ = s->rx_ctl_pkts; -	*data++ = s->rx_pause_pkts; -	*data++ = s->rx_64_pkts; -	*data++ = s->rx_65_to_127_pkts; -	*data++ = s->rx_128_255_pkts; -	*data++ = s->rx_256_511_pkts; -	*data++ = s->rx_512_to_1023_pkts; -	*data++ = s->rx_1024_to_1518_pkts; -	*data++ = s->rx_1519_to_max_pkts; -	*data++ = s->rx_len_err_pkts; -	*data++ = s->tx_cbfc_pause_frames0; -	*data++ = s->tx_cbfc_pause_frames1; -	*data++ = s->tx_cbfc_pause_frames2; -	*data++ = s->tx_cbfc_pause_frames3; -	*data++ = s->tx_cbfc_pause_frames4; -	*data++ = s->tx_cbfc_pause_frames5; -	*data++ = s->tx_cbfc_pause_frames6; -	*data++ = s->tx_cbfc_pause_frames7; -	*data++ = s->rx_cbfc_pause_frames0; -	*data++ = s->rx_cbfc_pause_frames1; -	*data++ = s->rx_cbfc_pause_frames2; -	*data++ = s->rx_cbfc_pause_frames3; -	*data++ = s->rx_cbfc_pause_frames4; -	*data++ = s->rx_cbfc_pause_frames5; -	*data++ = s->rx_cbfc_pause_frames6; -	*data++ = s->rx_cbfc_pause_frames7; -	*data++ = s->rx_nic_fifo_drop; +	for (index = 0; index < length; index++) { +		char *p = (char *)qdev + +			ql_gstrings_stats[index].stat_offset; +		*data++ = (ql_gstrings_stats[index].sizeof_stat == +			sizeof(u64)) ? *(u64 *)p : (*(u32 *)p); +	}  }  static int ql_get_settings(struct net_device *ndev, @@ -388,30 +424,33 @@ static void ql_get_drvinfo(struct net_device *ndev,  static void ql_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)  {  	struct ql_adapter *qdev = netdev_priv(ndev); -	/* What we support. */ -	wol->supported = WAKE_MAGIC; -	/* What we've currently got set. */ -	wol->wolopts = qdev->wol; +	unsigned short ssys_dev = qdev->pdev->subsystem_device; + +	/* WOL is only supported for mezz card. */ +	if (ssys_dev == QLGE_MEZZ_SSYS_ID_068 || +			ssys_dev == QLGE_MEZZ_SSYS_ID_180) { +		wol->supported = WAKE_MAGIC; +		wol->wolopts = qdev->wol; +	}  }  static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)  {  	struct ql_adapter *qdev = netdev_priv(ndev); -	int status; +	unsigned short ssys_dev = qdev->pdev->subsystem_device; +	/* WOL is only supported for mezz card. */ +	if (ssys_dev != QLGE_MEZZ_SSYS_ID_068 && +			ssys_dev != QLGE_MEZZ_SSYS_ID_180) { +		netif_info(qdev, drv, qdev->ndev, +				"WOL is only supported for mezz card\n"); +		return -EOPNOTSUPP; +	}  	if (wol->wolopts & ~WAKE_MAGIC)  		return -EINVAL;  	qdev->wol = wol->wolopts;  	netif_info(qdev, drv, qdev->ndev, "Set wol option 0x%x\n", qdev->wol); -	if (!qdev->wol) { -		u32 wol = 0; -		status = ql_mb_wol_mode(qdev, wol); -		netif_err(qdev, drv, qdev->ndev, "WOL %s (wol code 0x%x)\n", -			  status == 0 ? "cleared successfully" : "clear failed", -			  wol); -	} -  	return 0;  } @@ -528,6 +567,8 @@ static void ql_self_test(struct net_device *ndev,  {  	struct ql_adapter *qdev = netdev_priv(ndev); +	memset(data, 0, sizeof(u64) * QLGE_TEST_LEN); +  	if (netif_running(ndev)) {  		set_bit(QL_SELFTEST, &qdev->flags);  		if (eth_test->flags == ETH_TEST_FL_OFFLINE) { diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 09d8d33171d..3769f5711cc 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1433,6 +1433,36 @@ map_error:  	return NETDEV_TX_BUSY;  } +/* Categorizing receive firmware frame errors */ +static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err) +{ +	struct nic_stats *stats = &qdev->nic_stats; + +	stats->rx_err_count++; + +	switch (rx_err & IB_MAC_IOCB_RSP_ERR_MASK) { +	case IB_MAC_IOCB_RSP_ERR_CODE_ERR: +		stats->rx_code_err++; +		break; +	case IB_MAC_IOCB_RSP_ERR_OVERSIZE: +		stats->rx_oversize_err++; +		break; +	case IB_MAC_IOCB_RSP_ERR_UNDERSIZE: +		stats->rx_undersize_err++; +		break; +	case IB_MAC_IOCB_RSP_ERR_PREAMBLE: +		stats->rx_preamble_err++; +		break; +	case IB_MAC_IOCB_RSP_ERR_FRAME_LEN: +		stats->rx_frame_len_err++; +		break; +	case IB_MAC_IOCB_RSP_ERR_CRC: +		stats->rx_crc_err++; +	default: +		break; +	} +} +  /* Process an inbound completion from an rx ring. */  static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev,  					struct rx_ring *rx_ring, @@ -1499,15 +1529,6 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,  	addr = lbq_desc->p.pg_chunk.va;  	prefetch(addr); - -	/* Frame error, so drop the packet. */ -	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { -		netif_info(qdev, drv, qdev->ndev, -			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2); -		rx_ring->rx_errors++; -		goto err_out; -	} -  	/* The max framesize filter on this chip is set higher than  	 * MTU since FCoE uses 2k frames.  	 */ @@ -1546,7 +1567,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,  			struct iphdr *iph =  				(struct iphdr *) ((u8 *)addr + ETH_HLEN);  			if (!(iph->frag_off & -				cpu_to_be16(IP_MF|IP_OFFSET))) { +				htons(IP_MF|IP_OFFSET))) {  				skb->ip_summed = CHECKSUM_UNNECESSARY;  				netif_printk(qdev, rx_status, KERN_DEBUG,  					     qdev->ndev, @@ -1593,15 +1614,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,  	memcpy(skb_put(new_skb, length), skb->data, length);  	skb = new_skb; -	/* Frame error, so drop the packet. */ -	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { -		netif_info(qdev, drv, qdev->ndev, -			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2); -		dev_kfree_skb_any(skb); -		rx_ring->rx_errors++; -		return; -	} -  	/* loopback self test for ethtool */  	if (test_bit(QL_SELFTEST, &qdev->flags)) {  		ql_check_lb_frame(qdev, skb); @@ -1619,7 +1631,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,  	}  	prefetch(skb->data); -	skb->dev = ndev;  	if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {  		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,  			     "%s Multicast.\n", @@ -1654,7 +1665,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,  			/* Unfragmented ipv4 UDP frame. */  			struct iphdr *iph = (struct iphdr *) skb->data;  			if (!(iph->frag_off & -				ntohs(IP_MF|IP_OFFSET))) { +				htons(IP_MF|IP_OFFSET))) {  				skb->ip_summed = CHECKSUM_UNNECESSARY;  				netif_printk(qdev, rx_status, KERN_DEBUG,  					     qdev->ndev, @@ -1908,15 +1919,6 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,  		return;  	} -	/* Frame error, so drop the packet. */ -	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { -		netif_info(qdev, drv, qdev->ndev, -			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2); -		dev_kfree_skb_any(skb); -		rx_ring->rx_errors++; -		return; -	} -  	/* The max framesize filter on this chip is set higher than  	 * MTU since FCoE uses 2k frames.  	 */ @@ -1934,7 +1936,6 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,  	}  	prefetch(skb->data); -	skb->dev = ndev;  	if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {  		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "%s Multicast.\n",  			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == @@ -1968,7 +1969,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,  		/* Unfragmented ipv4 UDP frame. */  			struct iphdr *iph = (struct iphdr *) skb->data;  			if (!(iph->frag_off & -				ntohs(IP_MF|IP_OFFSET))) { +				htons(IP_MF|IP_OFFSET))) {  				skb->ip_summed = CHECKSUM_UNNECESSARY;  				netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,  					     "TCP checksum done!\n"); @@ -1999,6 +2000,12 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev,  	QL_DUMP_IB_MAC_RSP(ib_mac_rsp); +	/* Frame error, so drop the packet. */ +	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { +		ql_categorize_rx_err(qdev, ib_mac_rsp->flags2); +		return (unsigned long)length; +	} +  	if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) {  		/* The data and headers are split into  		 * separate buffers. @@ -2173,8 +2180,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)  	ql_write_cq_idx(rx_ring);  	tx_ring = &qdev->tx_ring[net_rsp->txq_idx];  	if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) { -		if (atomic_read(&tx_ring->queue_stopped) && -		    (atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) +		if ((atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))  			/*  			 * The queue got stopped because the tx_ring was full.  			 * Wake it up, because it's now at least 25% empty. @@ -2558,10 +2564,9 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)  	if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) {  		netif_info(qdev, tx_queued, qdev->ndev, -			   "%s: shutting down tx queue %d du to lack of resources.\n", +			   "%s: BUG! shutting down tx queue %d due to lack of resources.\n",  			   __func__, tx_ring_idx);  		netif_stop_subqueue(ndev, tx_ring->wq_id); -		atomic_inc(&tx_ring->queue_stopped);  		tx_ring->tx_errors++;  		return NETDEV_TX_BUSY;  	} @@ -2612,6 +2617,16 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)  		     tx_ring->prod_idx, skb->len);  	atomic_dec(&tx_ring->tx_count); + +	if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) { +		netif_stop_subqueue(ndev, tx_ring->wq_id); +		if ((atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) +			/* +			 * The queue got stopped because the tx_ring was full. +			 * Wake it up, because it's now at least 25% empty. +			 */ +			netif_wake_subqueue(qdev->ndev, tx_ring->wq_id); +	}  	return NETDEV_TX_OK;  } @@ -2680,7 +2695,6 @@ static void ql_init_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)  		tx_ring_desc++;  	}  	atomic_set(&tx_ring->tx_count, tx_ring->wq_len); -	atomic_set(&tx_ring->queue_stopped, 0);  }  static void ql_free_tx_resources(struct ql_adapter *qdev, @@ -2703,10 +2717,9 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev,  				 &tx_ring->wq_base_dma);  	if ((tx_ring->wq_base == NULL) || -	    tx_ring->wq_base_dma & WQ_ADDR_ALIGN) { -		netif_err(qdev, ifup, qdev->ndev, "tx_ring alloc failed.\n"); -		return -ENOMEM; -	} +	    tx_ring->wq_base_dma & WQ_ADDR_ALIGN) +		goto pci_alloc_err; +  	tx_ring->q =  	    kmalloc(tx_ring->wq_len * sizeof(struct tx_ring_desc), GFP_KERNEL);  	if (tx_ring->q == NULL) @@ -2716,6 +2729,9 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev,  err:  	pci_free_consistent(qdev->pdev, tx_ring->wq_size,  			    tx_ring->wq_base, tx_ring->wq_base_dma); +	tx_ring->wq_base = NULL; +pci_alloc_err: +	netif_err(qdev, ifup, qdev->ndev, "tx_ring alloc failed.\n");  	return -ENOMEM;  } @@ -4649,7 +4665,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev,  	int err = 0;  	ndev = alloc_etherdev_mq(sizeof(struct ql_adapter), -			min(MAX_CPUS, (int)num_online_cpus())); +			min(MAX_CPUS, netif_get_num_default_rss_queues()));  	if (!ndev)  		return -ENOMEM;  |