diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 14:47:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 14:47:58 -0400 |
commit | 6ba74014c1ab0e37af7de6f64b4eccbbae3cb9e7 (patch) | |
tree | 8f3892fc44f1e403675a6d7e88fda5c70e56ee4c /drivers/net/enic | |
parent | 5abd9ccced7a726c817dd6b5b96bc933859138d1 (diff) | |
parent | 3ff1c25927e3af61c6bf0e4ed959504058ae4565 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1443 commits)
phy/marvell: add 88ec048 support
igb: Program MDICNFG register prior to PHY init
e1000e: correct MAC-PHY interconnect register offset for 82579
hso: Add new product ID
can: Add driver for esd CAN-USB/2 device
l2tp: fix export of header file for userspace
can-raw: Fix skb_orphan_try handling
Revert "net: remove zap_completion_queue"
net: cleanup inclusion
phy/marvell: add 88e1121 interface mode support
u32: negative offset fix
net: Fix a typo from "dev" to "ndev"
igb: Use irq_synchronize per vector when using MSI-X
ixgbevf: fix null pointer dereference due to filter being set for VLAN 0
e1000e: Fix irq_synchronize in MSI-X case
e1000e: register pm_qos request on hardware activation
ip_fragment: fix subtracting PPPOE_SES_HLEN from mtu twice
net: Add getsockopt support for TCP thin-streams
cxgb4: update driver version
cxgb4: add new PCI IDs
...
Manually fix up conflicts in:
- drivers/net/e1000e/netdev.c: due to pm_qos registration
infrastructure changes
- drivers/net/phy/marvell.c: conflict between adding 88ec048 support
and cleaning up the IDs
- drivers/net/wireless/ipw2x00/ipw2100.c: trivial ipw2100_pm_qos_req
conflict (registration change vs marking it static)
Diffstat (limited to 'drivers/net/enic')
26 files changed, 715 insertions, 401 deletions
diff --git a/drivers/net/enic/cq_desc.h b/drivers/net/enic/cq_desc.h index 1eb289f773bf..d6dd1b4edf6e 100644 --- a/drivers/net/enic/cq_desc.h +++ b/drivers/net/enic/cq_desc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/cq_enet_desc.h b/drivers/net/enic/cq_enet_desc.h index 337d1943af46..c2c0680a1146 100644 --- a/drivers/net/enic/cq_enet_desc.h +++ b/drivers/net/enic/cq_enet_desc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -73,7 +73,16 @@ struct cq_enet_rq_desc { | |||
73 | #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14) | 73 | #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14) |
74 | #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15) | 74 | #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15) |
75 | 75 | ||
76 | #define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4 | 76 | #define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS 12 |
77 | #define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK \ | ||
78 | ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS) - 1) | ||
79 | #define CQ_ENET_RQ_DESC_VLAN_TCI_CFI_MASK (0x1 << 12) | ||
80 | #define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS 3 | ||
81 | #define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_MASK \ | ||
82 | ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS) - 1) | ||
83 | #define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_SHIFT 13 | ||
84 | |||
85 | #define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 8 | ||
77 | #define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \ | 86 | #define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \ |
78 | ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1) | 87 | ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1) |
79 | #define CQ_ENET_RQ_DESC_FCOE_EOF_BITS 8 | 88 | #define CQ_ENET_RQ_DESC_FCOE_EOF_BITS 8 |
@@ -96,7 +105,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, | |||
96 | u8 *type, u8 *color, u16 *q_number, u16 *completed_index, | 105 | u8 *type, u8 *color, u16 *q_number, u16 *completed_index, |
97 | u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, | 106 | u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, |
98 | u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error, | 107 | u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error, |
99 | u8 *vlan_stripped, u16 *vlan, u16 *checksum, u8 *fcoe_sof, | 108 | u8 *vlan_stripped, u16 *vlan_tci, u16 *checksum, u8 *fcoe_sof, |
100 | u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof, | 109 | u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof, |
101 | u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok, | 110 | u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok, |
102 | u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok) | 111 | u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok) |
@@ -136,7 +145,10 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, | |||
136 | *vlan_stripped = (bytes_written_flags & | 145 | *vlan_stripped = (bytes_written_flags & |
137 | CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; | 146 | CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; |
138 | 147 | ||
139 | *vlan = le16_to_cpu(desc->vlan); | 148 | /* |
149 | * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12) | ||
150 | */ | ||
151 | *vlan_tci = le16_to_cpu(desc->vlan); | ||
140 | 152 | ||
141 | if (*fcoe) { | 153 | if (*fcoe) { |
142 | *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & | 154 | *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & |
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 45e86d1e5b1b..f239aa8c6f4c 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -20,8 +20,6 @@ | |||
20 | #ifndef _ENIC_H_ | 20 | #ifndef _ENIC_H_ |
21 | #define _ENIC_H_ | 21 | #define _ENIC_H_ |
22 | 22 | ||
23 | #include <linux/inet_lro.h> | ||
24 | |||
25 | #include "vnic_enet.h" | 23 | #include "vnic_enet.h" |
26 | #include "vnic_dev.h" | 24 | #include "vnic_dev.h" |
27 | #include "vnic_wq.h" | 25 | #include "vnic_wq.h" |
@@ -34,12 +32,8 @@ | |||
34 | 32 | ||
35 | #define DRV_NAME "enic" | 33 | #define DRV_NAME "enic" |
36 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" | 34 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" |
37 | #define DRV_VERSION "1.3.1.1-pp" | 35 | #define DRV_VERSION "1.4.1.1" |
38 | #define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc" | 36 | #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" |
39 | #define PFX DRV_NAME ": " | ||
40 | |||
41 | #define ENIC_LRO_MAX_DESC 8 | ||
42 | #define ENIC_LRO_MAX_AGGR 64 | ||
43 | 37 | ||
44 | #define ENIC_BARS_MAX 6 | 38 | #define ENIC_BARS_MAX 6 |
45 | 39 | ||
@@ -116,6 +110,8 @@ struct enic { | |||
116 | spinlock_t wq_lock[ENIC_WQ_MAX]; | 110 | spinlock_t wq_lock[ENIC_WQ_MAX]; |
117 | unsigned int wq_count; | 111 | unsigned int wq_count; |
118 | struct vlan_group *vlan_group; | 112 | struct vlan_group *vlan_group; |
113 | u16 loop_enable; | ||
114 | u16 loop_tag; | ||
119 | 115 | ||
120 | /* receive queue cache line section */ | 116 | /* receive queue cache line section */ |
121 | ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; | 117 | ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; |
@@ -124,8 +120,6 @@ struct enic { | |||
124 | u64 rq_truncated_pkts; | 120 | u64 rq_truncated_pkts; |
125 | u64 rq_bad_fcs; | 121 | u64 rq_bad_fcs; |
126 | struct napi_struct napi; | 122 | struct napi_struct napi; |
127 | struct net_lro_mgr lro_mgr; | ||
128 | struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC]; | ||
129 | 123 | ||
130 | /* interrupt resource cache line section */ | 124 | /* interrupt resource cache line section */ |
131 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; | 125 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; |
@@ -137,4 +131,9 @@ struct enic { | |||
137 | unsigned int cq_count; | 131 | unsigned int cq_count; |
138 | }; | 132 | }; |
139 | 133 | ||
134 | static inline struct device *enic_get_dev(struct enic *enic) | ||
135 | { | ||
136 | return &(enic->pdev->dev); | ||
137 | } | ||
138 | |||
140 | #endif /* _ENIC_H_ */ | 139 | #endif /* _ENIC_H_ */ |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index bc7d6b96de3d..77a7f87d498e 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -29,12 +29,12 @@ | |||
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <linux/if_ether.h> | 30 | #include <linux/if_ether.h> |
31 | #include <linux/if_vlan.h> | 31 | #include <linux/if_vlan.h> |
32 | #include <linux/if_link.h> | ||
33 | #include <linux/ethtool.h> | 32 | #include <linux/ethtool.h> |
34 | #include <linux/in.h> | 33 | #include <linux/in.h> |
35 | #include <linux/ip.h> | 34 | #include <linux/ip.h> |
36 | #include <linux/ipv6.h> | 35 | #include <linux/ipv6.h> |
37 | #include <linux/tcp.h> | 36 | #include <linux/tcp.h> |
37 | #include <linux/rtnetlink.h> | ||
38 | #include <net/ip6_checksum.h> | 38 | #include <net/ip6_checksum.h> |
39 | 39 | ||
40 | #include "cq_enet_desc.h" | 40 | #include "cq_enet_desc.h" |
@@ -145,15 +145,25 @@ static int enic_get_settings(struct net_device *netdev, | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int enic_dev_fw_info(struct enic *enic, | ||
149 | struct vnic_devcmd_fw_info **fw_info) | ||
150 | { | ||
151 | int err; | ||
152 | |||
153 | spin_lock(&enic->devcmd_lock); | ||
154 | err = vnic_dev_fw_info(enic->vdev, fw_info); | ||
155 | spin_unlock(&enic->devcmd_lock); | ||
156 | |||
157 | return err; | ||
158 | } | ||
159 | |||
148 | static void enic_get_drvinfo(struct net_device *netdev, | 160 | static void enic_get_drvinfo(struct net_device *netdev, |
149 | struct ethtool_drvinfo *drvinfo) | 161 | struct ethtool_drvinfo *drvinfo) |
150 | { | 162 | { |
151 | struct enic *enic = netdev_priv(netdev); | 163 | struct enic *enic = netdev_priv(netdev); |
152 | struct vnic_devcmd_fw_info *fw_info; | 164 | struct vnic_devcmd_fw_info *fw_info; |
153 | 165 | ||
154 | spin_lock(&enic->devcmd_lock); | 166 | enic_dev_fw_info(enic, &fw_info); |
155 | vnic_dev_fw_info(enic->vdev, &fw_info); | ||
156 | spin_unlock(&enic->devcmd_lock); | ||
157 | 167 | ||
158 | strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); | 168 | strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
159 | strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); | 169 | strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
@@ -191,6 +201,17 @@ static int enic_get_sset_count(struct net_device *netdev, int sset) | |||
191 | } | 201 | } |
192 | } | 202 | } |
193 | 203 | ||
204 | static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) | ||
205 | { | ||
206 | int err; | ||
207 | |||
208 | spin_lock(&enic->devcmd_lock); | ||
209 | err = vnic_dev_stats_dump(enic->vdev, vstats); | ||
210 | spin_unlock(&enic->devcmd_lock); | ||
211 | |||
212 | return err; | ||
213 | } | ||
214 | |||
194 | static void enic_get_ethtool_stats(struct net_device *netdev, | 215 | static void enic_get_ethtool_stats(struct net_device *netdev, |
195 | struct ethtool_stats *stats, u64 *data) | 216 | struct ethtool_stats *stats, u64 *data) |
196 | { | 217 | { |
@@ -198,9 +219,7 @@ static void enic_get_ethtool_stats(struct net_device *netdev, | |||
198 | struct vnic_stats *vstats; | 219 | struct vnic_stats *vstats; |
199 | unsigned int i; | 220 | unsigned int i; |
200 | 221 | ||
201 | spin_lock(&enic->devcmd_lock); | 222 | enic_dev_stats_dump(enic, &vstats); |
202 | vnic_dev_stats_dump(enic->vdev, &vstats); | ||
203 | spin_unlock(&enic->devcmd_lock); | ||
204 | 223 | ||
205 | for (i = 0; i < enic_n_tx_stats; i++) | 224 | for (i = 0; i < enic_n_tx_stats; i++) |
206 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset]; | 225 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset]; |
@@ -346,7 +365,6 @@ static const struct ethtool_ops enic_ethtool_ops = { | |||
346 | .get_coalesce = enic_get_coalesce, | 365 | .get_coalesce = enic_get_coalesce, |
347 | .set_coalesce = enic_set_coalesce, | 366 | .set_coalesce = enic_set_coalesce, |
348 | .get_flags = ethtool_op_get_flags, | 367 | .get_flags = ethtool_op_get_flags, |
349 | .set_flags = ethtool_op_set_flags, | ||
350 | }; | 368 | }; |
351 | 369 | ||
352 | static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) | 370 | static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) |
@@ -399,54 +417,55 @@ static void enic_log_q_error(struct enic *enic) | |||
399 | for (i = 0; i < enic->wq_count; i++) { | 417 | for (i = 0; i < enic->wq_count; i++) { |
400 | error_status = vnic_wq_error_status(&enic->wq[i]); | 418 | error_status = vnic_wq_error_status(&enic->wq[i]); |
401 | if (error_status) | 419 | if (error_status) |
402 | printk(KERN_ERR PFX "%s: WQ[%d] error_status %d\n", | 420 | netdev_err(enic->netdev, "WQ[%d] error_status %d\n", |
403 | enic->netdev->name, i, error_status); | 421 | i, error_status); |
404 | } | 422 | } |
405 | 423 | ||
406 | for (i = 0; i < enic->rq_count; i++) { | 424 | for (i = 0; i < enic->rq_count; i++) { |
407 | error_status = vnic_rq_error_status(&enic->rq[i]); | 425 | error_status = vnic_rq_error_status(&enic->rq[i]); |
408 | if (error_status) | 426 | if (error_status) |
409 | printk(KERN_ERR PFX "%s: RQ[%d] error_status %d\n", | 427 | netdev_err(enic->netdev, "RQ[%d] error_status %d\n", |
410 | enic->netdev->name, i, error_status); | 428 | i, error_status); |
411 | } | 429 | } |
412 | } | 430 | } |
413 | 431 | ||
414 | static void enic_link_check(struct enic *enic) | 432 | static void enic_msglvl_check(struct enic *enic) |
415 | { | 433 | { |
416 | int link_status = vnic_dev_link_status(enic->vdev); | 434 | u32 msg_enable = vnic_dev_msg_lvl(enic->vdev); |
417 | int carrier_ok = netif_carrier_ok(enic->netdev); | ||
418 | 435 | ||
419 | if (link_status && !carrier_ok) { | 436 | if (msg_enable != enic->msg_enable) { |
420 | printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name); | 437 | netdev_info(enic->netdev, "msg lvl changed from 0x%x to 0x%x\n", |
421 | netif_carrier_on(enic->netdev); | 438 | enic->msg_enable, msg_enable); |
422 | } else if (!link_status && carrier_ok) { | 439 | enic->msg_enable = msg_enable; |
423 | printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name); | ||
424 | netif_carrier_off(enic->netdev); | ||
425 | } | 440 | } |
426 | } | 441 | } |
427 | 442 | ||
428 | static void enic_mtu_check(struct enic *enic) | 443 | static void enic_mtu_check(struct enic *enic) |
429 | { | 444 | { |
430 | u32 mtu = vnic_dev_mtu(enic->vdev); | 445 | u32 mtu = vnic_dev_mtu(enic->vdev); |
446 | struct net_device *netdev = enic->netdev; | ||
431 | 447 | ||
432 | if (mtu && mtu != enic->port_mtu) { | 448 | if (mtu && mtu != enic->port_mtu) { |
433 | enic->port_mtu = mtu; | 449 | enic->port_mtu = mtu; |
434 | if (mtu < enic->netdev->mtu) | 450 | if (mtu < netdev->mtu) |
435 | printk(KERN_WARNING PFX | 451 | netdev_warn(netdev, |
436 | "%s: interface MTU (%d) set higher " | 452 | "interface MTU (%d) set higher " |
437 | "than switch port MTU (%d)\n", | 453 | "than switch port MTU (%d)\n", |
438 | enic->netdev->name, enic->netdev->mtu, mtu); | 454 | netdev->mtu, mtu); |
439 | } | 455 | } |
440 | } | 456 | } |
441 | 457 | ||
442 | static void enic_msglvl_check(struct enic *enic) | 458 | static void enic_link_check(struct enic *enic) |
443 | { | 459 | { |
444 | u32 msg_enable = vnic_dev_msg_lvl(enic->vdev); | 460 | int link_status = vnic_dev_link_status(enic->vdev); |
461 | int carrier_ok = netif_carrier_ok(enic->netdev); | ||
445 | 462 | ||
446 | if (msg_enable != enic->msg_enable) { | 463 | if (link_status && !carrier_ok) { |
447 | printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n", | 464 | netdev_info(enic->netdev, "Link UP\n"); |
448 | enic->netdev->name, enic->msg_enable, msg_enable); | 465 | netif_carrier_on(enic->netdev); |
449 | enic->msg_enable = msg_enable; | 466 | } else if (!link_status && carrier_ok) { |
467 | netdev_info(enic->netdev, "Link DOWN\n"); | ||
468 | netif_carrier_off(enic->netdev); | ||
450 | } | 469 | } |
451 | } | 470 | } |
452 | 471 | ||
@@ -574,7 +593,7 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data) | |||
574 | 593 | ||
575 | static inline void enic_queue_wq_skb_cont(struct enic *enic, | 594 | static inline void enic_queue_wq_skb_cont(struct enic *enic, |
576 | struct vnic_wq *wq, struct sk_buff *skb, | 595 | struct vnic_wq *wq, struct sk_buff *skb, |
577 | unsigned int len_left) | 596 | unsigned int len_left, int loopback) |
578 | { | 597 | { |
579 | skb_frag_t *frag; | 598 | skb_frag_t *frag; |
580 | 599 | ||
@@ -586,13 +605,14 @@ static inline void enic_queue_wq_skb_cont(struct enic *enic, | |||
586 | frag->page_offset, frag->size, | 605 | frag->page_offset, frag->size, |
587 | PCI_DMA_TODEVICE), | 606 | PCI_DMA_TODEVICE), |
588 | frag->size, | 607 | frag->size, |
589 | (len_left == 0)); /* EOP? */ | 608 | (len_left == 0), /* EOP? */ |
609 | loopback); | ||
590 | } | 610 | } |
591 | } | 611 | } |
592 | 612 | ||
593 | static inline void enic_queue_wq_skb_vlan(struct enic *enic, | 613 | static inline void enic_queue_wq_skb_vlan(struct enic *enic, |
594 | struct vnic_wq *wq, struct sk_buff *skb, | 614 | struct vnic_wq *wq, struct sk_buff *skb, |
595 | int vlan_tag_insert, unsigned int vlan_tag) | 615 | int vlan_tag_insert, unsigned int vlan_tag, int loopback) |
596 | { | 616 | { |
597 | unsigned int head_len = skb_headlen(skb); | 617 | unsigned int head_len = skb_headlen(skb); |
598 | unsigned int len_left = skb->len - head_len; | 618 | unsigned int len_left = skb->len - head_len; |
@@ -608,15 +628,15 @@ static inline void enic_queue_wq_skb_vlan(struct enic *enic, | |||
608 | head_len, PCI_DMA_TODEVICE), | 628 | head_len, PCI_DMA_TODEVICE), |
609 | head_len, | 629 | head_len, |
610 | vlan_tag_insert, vlan_tag, | 630 | vlan_tag_insert, vlan_tag, |
611 | eop); | 631 | eop, loopback); |
612 | 632 | ||
613 | if (!eop) | 633 | if (!eop) |
614 | enic_queue_wq_skb_cont(enic, wq, skb, len_left); | 634 | enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback); |
615 | } | 635 | } |
616 | 636 | ||
617 | static inline void enic_queue_wq_skb_csum_l4(struct enic *enic, | 637 | static inline void enic_queue_wq_skb_csum_l4(struct enic *enic, |
618 | struct vnic_wq *wq, struct sk_buff *skb, | 638 | struct vnic_wq *wq, struct sk_buff *skb, |
619 | int vlan_tag_insert, unsigned int vlan_tag) | 639 | int vlan_tag_insert, unsigned int vlan_tag, int loopback) |
620 | { | 640 | { |
621 | unsigned int head_len = skb_headlen(skb); | 641 | unsigned int head_len = skb_headlen(skb); |
622 | unsigned int len_left = skb->len - head_len; | 642 | unsigned int len_left = skb->len - head_len; |
@@ -636,15 +656,15 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic, | |||
636 | csum_offset, | 656 | csum_offset, |
637 | hdr_len, | 657 | hdr_len, |
638 | vlan_tag_insert, vlan_tag, | 658 | vlan_tag_insert, vlan_tag, |
639 | eop); | 659 | eop, loopback); |
640 | 660 | ||
641 | if (!eop) | 661 | if (!eop) |
642 | enic_queue_wq_skb_cont(enic, wq, skb, len_left); | 662 | enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback); |
643 | } | 663 | } |
644 | 664 | ||
645 | static inline void enic_queue_wq_skb_tso(struct enic *enic, | 665 | static inline void enic_queue_wq_skb_tso(struct enic *enic, |
646 | struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss, | 666 | struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss, |
647 | int vlan_tag_insert, unsigned int vlan_tag) | 667 | int vlan_tag_insert, unsigned int vlan_tag, int loopback) |
648 | { | 668 | { |
649 | unsigned int frag_len_left = skb_headlen(skb); | 669 | unsigned int frag_len_left = skb_headlen(skb); |
650 | unsigned int len_left = skb->len - frag_len_left; | 670 | unsigned int len_left = skb->len - frag_len_left; |
@@ -681,7 +701,7 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic, | |||
681 | len, | 701 | len, |
682 | mss, hdr_len, | 702 | mss, hdr_len, |
683 | vlan_tag_insert, vlan_tag, | 703 | vlan_tag_insert, vlan_tag, |
684 | eop && (len == frag_len_left)); | 704 | eop && (len == frag_len_left), loopback); |
685 | frag_len_left -= len; | 705 | frag_len_left -= len; |
686 | offset += len; | 706 | offset += len; |
687 | } | 707 | } |
@@ -707,7 +727,8 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic, | |||
707 | dma_addr, | 727 | dma_addr, |
708 | len, | 728 | len, |
709 | (len_left == 0) && | 729 | (len_left == 0) && |
710 | (len == frag_len_left)); /* EOP? */ | 730 | (len == frag_len_left), /* EOP? */ |
731 | loopback); | ||
711 | frag_len_left -= len; | 732 | frag_len_left -= len; |
712 | offset += len; | 733 | offset += len; |
713 | } | 734 | } |
@@ -720,22 +741,26 @@ static inline void enic_queue_wq_skb(struct enic *enic, | |||
720 | unsigned int mss = skb_shinfo(skb)->gso_size; | 741 | unsigned int mss = skb_shinfo(skb)->gso_size; |
721 | unsigned int vlan_tag = 0; | 742 | unsigned int vlan_tag = 0; |
722 | int vlan_tag_insert = 0; | 743 | int vlan_tag_insert = 0; |
744 | int loopback = 0; | ||
723 | 745 | ||
724 | if (enic->vlan_group && vlan_tx_tag_present(skb)) { | 746 | if (enic->vlan_group && vlan_tx_tag_present(skb)) { |
725 | /* VLAN tag from trunking driver */ | 747 | /* VLAN tag from trunking driver */ |
726 | vlan_tag_insert = 1; | 748 | vlan_tag_insert = 1; |
727 | vlan_tag = vlan_tx_tag_get(skb); | 749 | vlan_tag = vlan_tx_tag_get(skb); |
750 | } else if (enic->loop_enable) { | ||
751 | vlan_tag = enic->loop_tag; | ||
752 | loopback = 1; | ||
728 | } | 753 | } |
729 | 754 | ||
730 | if (mss) | 755 | if (mss) |
731 | enic_queue_wq_skb_tso(enic, wq, skb, mss, | 756 | enic_queue_wq_skb_tso(enic, wq, skb, mss, |
732 | vlan_tag_insert, vlan_tag); | 757 | vlan_tag_insert, vlan_tag, loopback); |
733 | else if (skb->ip_summed == CHECKSUM_PARTIAL) | 758 | else if (skb->ip_summed == CHECKSUM_PARTIAL) |
734 | enic_queue_wq_skb_csum_l4(enic, wq, skb, | 759 | enic_queue_wq_skb_csum_l4(enic, wq, skb, |
735 | vlan_tag_insert, vlan_tag); | 760 | vlan_tag_insert, vlan_tag, loopback); |
736 | else | 761 | else |
737 | enic_queue_wq_skb_vlan(enic, wq, skb, | 762 | enic_queue_wq_skb_vlan(enic, wq, skb, |
738 | vlan_tag_insert, vlan_tag); | 763 | vlan_tag_insert, vlan_tag, loopback); |
739 | } | 764 | } |
740 | 765 | ||
741 | /* netif_tx_lock held, process context with BHs disabled, or BH */ | 766 | /* netif_tx_lock held, process context with BHs disabled, or BH */ |
@@ -769,8 +794,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, | |||
769 | skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { | 794 | skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { |
770 | netif_stop_queue(netdev); | 795 | netif_stop_queue(netdev); |
771 | /* This is a hard error, log it */ | 796 | /* This is a hard error, log it */ |
772 | printk(KERN_ERR PFX "%s: BUG! Tx ring full when " | 797 | netdev_err(netdev, "BUG! Tx ring full when queue awake!\n"); |
773 | "queue awake!\n", netdev->name); | ||
774 | spin_unlock_irqrestore(&enic->wq_lock[0], flags); | 798 | spin_unlock_irqrestore(&enic->wq_lock[0], flags); |
775 | return NETDEV_TX_BUSY; | 799 | return NETDEV_TX_BUSY; |
776 | } | 800 | } |
@@ -792,9 +816,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev) | |||
792 | struct net_device_stats *net_stats = &netdev->stats; | 816 | struct net_device_stats *net_stats = &netdev->stats; |
793 | struct vnic_stats *stats; | 817 | struct vnic_stats *stats; |
794 | 818 | ||
795 | spin_lock(&enic->devcmd_lock); | 819 | enic_dev_stats_dump(enic, &stats); |
796 | vnic_dev_stats_dump(enic->vdev, &stats); | ||
797 | spin_unlock(&enic->devcmd_lock); | ||
798 | 820 | ||
799 | net_stats->tx_packets = stats->tx.tx_frames_ok; | 821 | net_stats->tx_packets = stats->tx.tx_frames_ok; |
800 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; | 822 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; |
@@ -812,9 +834,10 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev) | |||
812 | return net_stats; | 834 | return net_stats; |
813 | } | 835 | } |
814 | 836 | ||
815 | static void enic_reset_mcaddrs(struct enic *enic) | 837 | static void enic_reset_multicast_list(struct enic *enic) |
816 | { | 838 | { |
817 | enic->mc_count = 0; | 839 | enic->mc_count = 0; |
840 | enic->flags = 0; | ||
818 | } | 841 | } |
819 | 842 | ||
820 | static int enic_set_mac_addr(struct net_device *netdev, char *addr) | 843 | static int enic_set_mac_addr(struct net_device *netdev, char *addr) |
@@ -891,6 +914,41 @@ static int enic_set_mac_address(struct net_device *netdev, void *p) | |||
891 | return -EOPNOTSUPP; | 914 | return -EOPNOTSUPP; |
892 | } | 915 | } |
893 | 916 | ||
917 | static int enic_dev_packet_filter(struct enic *enic, int directed, | ||
918 | int multicast, int broadcast, int promisc, int allmulti) | ||
919 | { | ||
920 | int err; | ||
921 | |||
922 | spin_lock(&enic->devcmd_lock); | ||
923 | err = vnic_dev_packet_filter(enic->vdev, directed, | ||
924 | multicast, broadcast, promisc, allmulti); | ||
925 | spin_unlock(&enic->devcmd_lock); | ||
926 | |||
927 | return err; | ||
928 | } | ||
929 | |||
930 | static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr) | ||
931 | { | ||
932 | int err; | ||
933 | |||
934 | spin_lock(&enic->devcmd_lock); | ||
935 | err = vnic_dev_add_addr(enic->vdev, addr); | ||
936 | spin_unlock(&enic->devcmd_lock); | ||
937 | |||
938 | return err; | ||
939 | } | ||
940 | |||
941 | static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr) | ||
942 | { | ||
943 | int err; | ||
944 | |||
945 | spin_lock(&enic->devcmd_lock); | ||
946 | err = vnic_dev_del_addr(enic->vdev, addr); | ||
947 | spin_unlock(&enic->devcmd_lock); | ||
948 | |||
949 | return err; | ||
950 | } | ||
951 | |||
894 | /* netif_tx_lock held, BHs disabled */ | 952 | /* netif_tx_lock held, BHs disabled */ |
895 | static void enic_set_multicast_list(struct net_device *netdev) | 953 | static void enic_set_multicast_list(struct net_device *netdev) |
896 | { | 954 | { |
@@ -910,11 +968,9 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
910 | if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) | 968 | if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) |
911 | mc_count = ENIC_MULTICAST_PERFECT_FILTERS; | 969 | mc_count = ENIC_MULTICAST_PERFECT_FILTERS; |
912 | 970 | ||
913 | spin_lock(&enic->devcmd_lock); | ||
914 | |||
915 | if (enic->flags != flags) { | 971 | if (enic->flags != flags) { |
916 | enic->flags = flags; | 972 | enic->flags = flags; |
917 | vnic_dev_packet_filter(enic->vdev, directed, | 973 | enic_dev_packet_filter(enic, directed, |
918 | multicast, broadcast, promisc, allmulti); | 974 | multicast, broadcast, promisc, allmulti); |
919 | } | 975 | } |
920 | 976 | ||
@@ -937,7 +993,7 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
937 | mc_addr[j]) == 0) | 993 | mc_addr[j]) == 0) |
938 | break; | 994 | break; |
939 | if (j == mc_count) | 995 | if (j == mc_count) |
940 | enic_del_multicast_addr(enic, enic->mc_addr[i]); | 996 | enic_dev_del_multicast_addr(enic, enic->mc_addr[i]); |
941 | } | 997 | } |
942 | 998 | ||
943 | for (i = 0; i < mc_count; i++) { | 999 | for (i = 0; i < mc_count; i++) { |
@@ -946,7 +1002,7 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
946 | enic->mc_addr[j]) == 0) | 1002 | enic->mc_addr[j]) == 0) |
947 | break; | 1003 | break; |
948 | if (j == enic->mc_count) | 1004 | if (j == enic->mc_count) |
949 | enic_add_multicast_addr(enic, mc_addr[i]); | 1005 | enic_dev_add_multicast_addr(enic, mc_addr[i]); |
950 | } | 1006 | } |
951 | 1007 | ||
952 | /* Save the list to compare against next time | 1008 | /* Save the list to compare against next time |
@@ -956,8 +1012,6 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
956 | memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN); | 1012 | memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN); |
957 | 1013 | ||
958 | enic->mc_count = mc_count; | 1014 | enic->mc_count = mc_count; |
959 | |||
960 | spin_unlock(&enic->devcmd_lock); | ||
961 | } | 1015 | } |
962 | 1016 | ||
963 | /* rtnl lock is held */ | 1017 | /* rtnl lock is held */ |
@@ -1226,7 +1280,7 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq) | |||
1226 | struct enic *enic = vnic_dev_priv(rq->vdev); | 1280 | struct enic *enic = vnic_dev_priv(rq->vdev); |
1227 | struct net_device *netdev = enic->netdev; | 1281 | struct net_device *netdev = enic->netdev; |
1228 | struct sk_buff *skb; | 1282 | struct sk_buff *skb; |
1229 | unsigned int len = netdev->mtu + ETH_HLEN; | 1283 | unsigned int len = netdev->mtu + VLAN_ETH_HLEN; |
1230 | unsigned int os_buf_index = 0; | 1284 | unsigned int os_buf_index = 0; |
1231 | dma_addr_t dma_addr; | 1285 | dma_addr_t dma_addr; |
1232 | 1286 | ||
@@ -1263,12 +1317,24 @@ static int enic_rq_alloc_buf_a1(struct vnic_rq *rq) | |||
1263 | return 0; | 1317 | return 0; |
1264 | } | 1318 | } |
1265 | 1319 | ||
1320 | static int enic_dev_hw_version(struct enic *enic, | ||
1321 | enum vnic_dev_hw_version *hw_ver) | ||
1322 | { | ||
1323 | int err; | ||
1324 | |||
1325 | spin_lock(&enic->devcmd_lock); | ||
1326 | err = vnic_dev_hw_version(enic->vdev, hw_ver); | ||
1327 | spin_unlock(&enic->devcmd_lock); | ||
1328 | |||
1329 | return err; | ||
1330 | } | ||
1331 | |||
1266 | static int enic_set_rq_alloc_buf(struct enic *enic) | 1332 | static int enic_set_rq_alloc_buf(struct enic *enic) |
1267 | { | 1333 | { |
1268 | enum vnic_dev_hw_version hw_ver; | 1334 | enum vnic_dev_hw_version hw_ver; |
1269 | int err; | 1335 | int err; |
1270 | 1336 | ||
1271 | err = vnic_dev_hw_version(enic->vdev, &hw_ver); | 1337 | err = enic_dev_hw_version(enic, &hw_ver); |
1272 | if (err) | 1338 | if (err) |
1273 | return err; | 1339 | return err; |
1274 | 1340 | ||
@@ -1287,51 +1353,6 @@ static int enic_set_rq_alloc_buf(struct enic *enic) | |||
1287 | return 0; | 1353 | return 0; |
1288 | } | 1354 | } |
1289 | 1355 | ||
1290 | static int enic_get_skb_header(struct sk_buff *skb, void **iphdr, | ||
1291 | void **tcph, u64 *hdr_flags, void *priv) | ||
1292 | { | ||
1293 | struct cq_enet_rq_desc *cq_desc = priv; | ||
1294 | unsigned int ip_len; | ||
1295 | struct iphdr *iph; | ||
1296 | |||
1297 | u8 type, color, eop, sop, ingress_port, vlan_stripped; | ||
1298 | u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof; | ||
1299 | u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; | ||
1300 | u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; | ||
1301 | u8 packet_error; | ||
1302 | u16 q_number, completed_index, bytes_written, vlan, checksum; | ||
1303 | u32 rss_hash; | ||
1304 | |||
1305 | cq_enet_rq_desc_dec(cq_desc, | ||
1306 | &type, &color, &q_number, &completed_index, | ||
1307 | &ingress_port, &fcoe, &eop, &sop, &rss_type, | ||
1308 | &csum_not_calc, &rss_hash, &bytes_written, | ||
1309 | &packet_error, &vlan_stripped, &vlan, &checksum, | ||
1310 | &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, | ||
1311 | &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, | ||
1312 | &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, | ||
1313 | &fcs_ok); | ||
1314 | |||
1315 | if (!(ipv4 && tcp && !ipv4_fragment)) | ||
1316 | return -1; | ||
1317 | |||
1318 | skb_reset_network_header(skb); | ||
1319 | iph = ip_hdr(skb); | ||
1320 | |||
1321 | ip_len = ip_hdrlen(skb); | ||
1322 | skb_set_transport_header(skb, ip_len); | ||
1323 | |||
1324 | /* check if ip header and tcp header are complete */ | ||
1325 | if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) | ||
1326 | return -1; | ||
1327 | |||
1328 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
1329 | *tcph = tcp_hdr(skb); | ||
1330 | *iphdr = iph; | ||
1331 | |||
1332 | return 0; | ||
1333 | } | ||
1334 | |||
1335 | static void enic_rq_indicate_buf(struct vnic_rq *rq, | 1356 | static void enic_rq_indicate_buf(struct vnic_rq *rq, |
1336 | struct cq_desc *cq_desc, struct vnic_rq_buf *buf, | 1357 | struct cq_desc *cq_desc, struct vnic_rq_buf *buf, |
1337 | int skipped, void *opaque) | 1358 | int skipped, void *opaque) |
@@ -1345,7 +1366,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1345 | u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; | 1366 | u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; |
1346 | u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; | 1367 | u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; |
1347 | u8 packet_error; | 1368 | u8 packet_error; |
1348 | u16 q_number, completed_index, bytes_written, vlan, checksum; | 1369 | u16 q_number, completed_index, bytes_written, vlan_tci, checksum; |
1349 | u32 rss_hash; | 1370 | u32 rss_hash; |
1350 | 1371 | ||
1351 | if (skipped) | 1372 | if (skipped) |
@@ -1360,7 +1381,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1360 | &type, &color, &q_number, &completed_index, | 1381 | &type, &color, &q_number, &completed_index, |
1361 | &ingress_port, &fcoe, &eop, &sop, &rss_type, | 1382 | &ingress_port, &fcoe, &eop, &sop, &rss_type, |
1362 | &csum_not_calc, &rss_hash, &bytes_written, | 1383 | &csum_not_calc, &rss_hash, &bytes_written, |
1363 | &packet_error, &vlan_stripped, &vlan, &checksum, | 1384 | &packet_error, &vlan_stripped, &vlan_tci, &checksum, |
1364 | &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, | 1385 | &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, |
1365 | &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, | 1386 | &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, |
1366 | &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, | 1387 | &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, |
@@ -1395,20 +1416,20 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1395 | 1416 | ||
1396 | skb->dev = netdev; | 1417 | skb->dev = netdev; |
1397 | 1418 | ||
1398 | if (enic->vlan_group && vlan_stripped) { | 1419 | if (enic->vlan_group && vlan_stripped && |
1420 | (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) { | ||
1399 | 1421 | ||
1400 | if ((netdev->features & NETIF_F_LRO) && ipv4) | 1422 | if (netdev->features & NETIF_F_GRO) |
1401 | lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, | 1423 | vlan_gro_receive(&enic->napi, enic->vlan_group, |
1402 | skb, enic->vlan_group, | 1424 | vlan_tci, skb); |
1403 | vlan, cq_desc); | ||
1404 | else | 1425 | else |
1405 | vlan_hwaccel_receive_skb(skb, | 1426 | vlan_hwaccel_receive_skb(skb, |
1406 | enic->vlan_group, vlan); | 1427 | enic->vlan_group, vlan_tci); |
1407 | 1428 | ||
1408 | } else { | 1429 | } else { |
1409 | 1430 | ||
1410 | if ((netdev->features & NETIF_F_LRO) && ipv4) | 1431 | if (netdev->features & NETIF_F_GRO) |
1411 | lro_receive_skb(&enic->lro_mgr, skb, cq_desc); | 1432 | napi_gro_receive(&enic->napi, skb); |
1412 | else | 1433 | else |
1413 | netif_receive_skb(skb); | 1434 | netif_receive_skb(skb); |
1414 | 1435 | ||
@@ -1438,7 +1459,6 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, | |||
1438 | static int enic_poll(struct napi_struct *napi, int budget) | 1459 | static int enic_poll(struct napi_struct *napi, int budget) |
1439 | { | 1460 | { |
1440 | struct enic *enic = container_of(napi, struct enic, napi); | 1461 | struct enic *enic = container_of(napi, struct enic, napi); |
1441 | struct net_device *netdev = enic->netdev; | ||
1442 | unsigned int rq_work_to_do = budget; | 1462 | unsigned int rq_work_to_do = budget; |
1443 | unsigned int wq_work_to_do = -1; /* no limit */ | 1463 | unsigned int wq_work_to_do = -1; /* no limit */ |
1444 | unsigned int work_done, rq_work_done, wq_work_done; | 1464 | unsigned int work_done, rq_work_done, wq_work_done; |
@@ -1478,12 +1498,9 @@ static int enic_poll(struct napi_struct *napi, int budget) | |||
1478 | if (rq_work_done < rq_work_to_do) { | 1498 | if (rq_work_done < rq_work_to_do) { |
1479 | 1499 | ||
1480 | /* Some work done, but not enough to stay in polling, | 1500 | /* Some work done, but not enough to stay in polling, |
1481 | * flush all LROs and exit polling | 1501 | * exit polling |
1482 | */ | 1502 | */ |
1483 | 1503 | ||
1484 | if (netdev->features & NETIF_F_LRO) | ||
1485 | lro_flush_all(&enic->lro_mgr); | ||
1486 | |||
1487 | napi_complete(napi); | 1504 | napi_complete(napi); |
1488 | vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); | 1505 | vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); |
1489 | } | 1506 | } |
@@ -1494,7 +1511,6 @@ static int enic_poll(struct napi_struct *napi, int budget) | |||
1494 | static int enic_poll_msix(struct napi_struct *napi, int budget) | 1511 | static int enic_poll_msix(struct napi_struct *napi, int budget) |
1495 | { | 1512 | { |
1496 | struct enic *enic = container_of(napi, struct enic, napi); | 1513 | struct enic *enic = container_of(napi, struct enic, napi); |
1497 | struct net_device *netdev = enic->netdev; | ||
1498 | unsigned int work_to_do = budget; | 1514 | unsigned int work_to_do = budget; |
1499 | unsigned int work_done; | 1515 | unsigned int work_done; |
1500 | int err; | 1516 | int err; |
@@ -1528,12 +1544,9 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) | |||
1528 | if (work_done < work_to_do) { | 1544 | if (work_done < work_to_do) { |
1529 | 1545 | ||
1530 | /* Some work done, but not enough to stay in polling, | 1546 | /* Some work done, but not enough to stay in polling, |
1531 | * flush all LROs and exit polling | 1547 | * exit polling |
1532 | */ | 1548 | */ |
1533 | 1549 | ||
1534 | if (netdev->features & NETIF_F_LRO) | ||
1535 | lro_flush_all(&enic->lro_mgr); | ||
1536 | |||
1537 | napi_complete(napi); | 1550 | napi_complete(napi); |
1538 | vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); | 1551 | vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); |
1539 | } | 1552 | } |
@@ -1655,7 +1668,7 @@ static void enic_synchronize_irqs(struct enic *enic) | |||
1655 | } | 1668 | } |
1656 | } | 1669 | } |
1657 | 1670 | ||
1658 | static int enic_notify_set(struct enic *enic) | 1671 | static int enic_dev_notify_set(struct enic *enic) |
1659 | { | 1672 | { |
1660 | int err; | 1673 | int err; |
1661 | 1674 | ||
@@ -1676,6 +1689,39 @@ static int enic_notify_set(struct enic *enic) | |||
1676 | return err; | 1689 | return err; |
1677 | } | 1690 | } |
1678 | 1691 | ||
1692 | static int enic_dev_notify_unset(struct enic *enic) | ||
1693 | { | ||
1694 | int err; | ||
1695 | |||
1696 | spin_lock(&enic->devcmd_lock); | ||
1697 | err = vnic_dev_notify_unset(enic->vdev); | ||
1698 | spin_unlock(&enic->devcmd_lock); | ||
1699 | |||
1700 | return err; | ||
1701 | } | ||
1702 | |||
1703 | static int enic_dev_enable(struct enic *enic) | ||
1704 | { | ||
1705 | int err; | ||
1706 | |||
1707 | spin_lock(&enic->devcmd_lock); | ||
1708 | err = vnic_dev_enable(enic->vdev); | ||
1709 | spin_unlock(&enic->devcmd_lock); | ||
1710 | |||
1711 | return err; | ||
1712 | } | ||
1713 | |||
1714 | static int enic_dev_disable(struct enic *enic) | ||
1715 | { | ||
1716 | int err; | ||
1717 | |||
1718 | spin_lock(&enic->devcmd_lock); | ||
1719 | err = vnic_dev_disable(enic->vdev); | ||
1720 | spin_unlock(&enic->devcmd_lock); | ||
1721 | |||
1722 | return err; | ||
1723 | } | ||
1724 | |||
1679 | static void enic_notify_timer_start(struct enic *enic) | 1725 | static void enic_notify_timer_start(struct enic *enic) |
1680 | { | 1726 | { |
1681 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | 1727 | switch (vnic_dev_get_intr_mode(enic->vdev)) { |
@@ -1697,16 +1743,14 @@ static int enic_open(struct net_device *netdev) | |||
1697 | 1743 | ||
1698 | err = enic_request_intr(enic); | 1744 | err = enic_request_intr(enic); |
1699 | if (err) { | 1745 | if (err) { |
1700 | printk(KERN_ERR PFX "%s: Unable to request irq.\n", | 1746 | netdev_err(netdev, "Unable to request irq.\n"); |
1701 | netdev->name); | ||
1702 | return err; | 1747 | return err; |
1703 | } | 1748 | } |
1704 | 1749 | ||
1705 | err = enic_notify_set(enic); | 1750 | err = enic_dev_notify_set(enic); |
1706 | if (err) { | 1751 | if (err) { |
1707 | printk(KERN_ERR PFX | 1752 | netdev_err(netdev, |
1708 | "%s: Failed to alloc notify buffer, aborting.\n", | 1753 | "Failed to alloc notify buffer, aborting.\n"); |
1709 | netdev->name); | ||
1710 | goto err_out_free_intr; | 1754 | goto err_out_free_intr; |
1711 | } | 1755 | } |
1712 | 1756 | ||
@@ -1714,9 +1758,7 @@ static int enic_open(struct net_device *netdev) | |||
1714 | vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf); | 1758 | vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf); |
1715 | /* Need at least one buffer on ring to get going */ | 1759 | /* Need at least one buffer on ring to get going */ |
1716 | if (vnic_rq_desc_used(&enic->rq[i]) == 0) { | 1760 | if (vnic_rq_desc_used(&enic->rq[i]) == 0) { |
1717 | printk(KERN_ERR PFX | 1761 | netdev_err(netdev, "Unable to alloc receive buffers\n"); |
1718 | "%s: Unable to alloc receive buffers.\n", | ||
1719 | netdev->name); | ||
1720 | err = -ENOMEM; | 1762 | err = -ENOMEM; |
1721 | goto err_out_notify_unset; | 1763 | goto err_out_notify_unset; |
1722 | } | 1764 | } |
@@ -1732,9 +1774,7 @@ static int enic_open(struct net_device *netdev) | |||
1732 | 1774 | ||
1733 | netif_wake_queue(netdev); | 1775 | netif_wake_queue(netdev); |
1734 | napi_enable(&enic->napi); | 1776 | napi_enable(&enic->napi); |
1735 | spin_lock(&enic->devcmd_lock); | 1777 | enic_dev_enable(enic); |
1736 | vnic_dev_enable(enic->vdev); | ||
1737 | spin_unlock(&enic->devcmd_lock); | ||
1738 | 1778 | ||
1739 | for (i = 0; i < enic->intr_count; i++) | 1779 | for (i = 0; i < enic->intr_count; i++) |
1740 | vnic_intr_unmask(&enic->intr[i]); | 1780 | vnic_intr_unmask(&enic->intr[i]); |
@@ -1744,9 +1784,7 @@ static int enic_open(struct net_device *netdev) | |||
1744 | return 0; | 1784 | return 0; |
1745 | 1785 | ||
1746 | err_out_notify_unset: | 1786 | err_out_notify_unset: |
1747 | spin_lock(&enic->devcmd_lock); | 1787 | enic_dev_notify_unset(enic); |
1748 | vnic_dev_notify_unset(enic->vdev); | ||
1749 | spin_unlock(&enic->devcmd_lock); | ||
1750 | err_out_free_intr: | 1788 | err_out_free_intr: |
1751 | enic_free_intr(enic); | 1789 | enic_free_intr(enic); |
1752 | 1790 | ||
@@ -1760,20 +1798,19 @@ static int enic_stop(struct net_device *netdev) | |||
1760 | unsigned int i; | 1798 | unsigned int i; |
1761 | int err; | 1799 | int err; |
1762 | 1800 | ||
1763 | for (i = 0; i < enic->intr_count; i++) | 1801 | for (i = 0; i < enic->intr_count; i++) { |
1764 | vnic_intr_mask(&enic->intr[i]); | 1802 | vnic_intr_mask(&enic->intr[i]); |
1803 | (void)vnic_intr_masked(&enic->intr[i]); /* flush write */ | ||
1804 | } | ||
1765 | 1805 | ||
1766 | enic_synchronize_irqs(enic); | 1806 | enic_synchronize_irqs(enic); |
1767 | 1807 | ||
1768 | del_timer_sync(&enic->notify_timer); | 1808 | del_timer_sync(&enic->notify_timer); |
1769 | 1809 | ||
1770 | spin_lock(&enic->devcmd_lock); | 1810 | enic_dev_disable(enic); |
1771 | vnic_dev_disable(enic->vdev); | ||
1772 | spin_unlock(&enic->devcmd_lock); | ||
1773 | napi_disable(&enic->napi); | 1811 | napi_disable(&enic->napi); |
1774 | netif_carrier_off(netdev); | 1812 | netif_carrier_off(netdev); |
1775 | netif_tx_disable(netdev); | 1813 | netif_tx_disable(netdev); |
1776 | |||
1777 | enic_dev_del_station_addr(enic); | 1814 | enic_dev_del_station_addr(enic); |
1778 | 1815 | ||
1779 | for (i = 0; i < enic->wq_count; i++) { | 1816 | for (i = 0; i < enic->wq_count; i++) { |
@@ -1787,9 +1824,7 @@ static int enic_stop(struct net_device *netdev) | |||
1787 | return err; | 1824 | return err; |
1788 | } | 1825 | } |
1789 | 1826 | ||
1790 | spin_lock(&enic->devcmd_lock); | 1827 | enic_dev_notify_unset(enic); |
1791 | vnic_dev_notify_unset(enic->vdev); | ||
1792 | spin_unlock(&enic->devcmd_lock); | ||
1793 | enic_free_intr(enic); | 1828 | enic_free_intr(enic); |
1794 | 1829 | ||
1795 | for (i = 0; i < enic->wq_count; i++) | 1830 | for (i = 0; i < enic->wq_count; i++) |
@@ -1818,10 +1853,9 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) | |||
1818 | netdev->mtu = new_mtu; | 1853 | netdev->mtu = new_mtu; |
1819 | 1854 | ||
1820 | if (netdev->mtu > enic->port_mtu) | 1855 | if (netdev->mtu > enic->port_mtu) |
1821 | printk(KERN_WARNING PFX | 1856 | netdev_warn(netdev, |
1822 | "%s: interface MTU (%d) set higher " | 1857 | "interface MTU (%d) set higher than port MTU (%d)\n", |
1823 | "than port MTU (%d)\n", | 1858 | netdev->mtu, enic->port_mtu); |
1824 | netdev->name, netdev->mtu, enic->port_mtu); | ||
1825 | 1859 | ||
1826 | if (running) | 1860 | if (running) |
1827 | enic_open(netdev); | 1861 | enic_open(netdev); |
@@ -1894,21 +1928,21 @@ static int enic_dev_open(struct enic *enic) | |||
1894 | err = enic_dev_wait(enic->vdev, vnic_dev_open, | 1928 | err = enic_dev_wait(enic->vdev, vnic_dev_open, |
1895 | vnic_dev_open_done, 0); | 1929 | vnic_dev_open_done, 0); |
1896 | if (err) | 1930 | if (err) |
1897 | printk(KERN_ERR PFX | 1931 | dev_err(enic_get_dev(enic), "vNIC device open failed, err %d\n", |
1898 | "vNIC device open failed, err %d.\n", err); | 1932 | err); |
1899 | 1933 | ||
1900 | return err; | 1934 | return err; |
1901 | } | 1935 | } |
1902 | 1936 | ||
1903 | static int enic_dev_soft_reset(struct enic *enic) | 1937 | static int enic_dev_hang_reset(struct enic *enic) |
1904 | { | 1938 | { |
1905 | int err; | 1939 | int err; |
1906 | 1940 | ||
1907 | err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset, | 1941 | err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset, |
1908 | vnic_dev_soft_reset_done, 0); | 1942 | vnic_dev_hang_reset_done, 0); |
1909 | if (err) | 1943 | if (err) |
1910 | printk(KERN_ERR PFX | 1944 | netdev_err(enic->netdev, "vNIC hang reset failed, err %d\n", |
1911 | "vNIC soft reset failed, err %d.\n", err); | 1945 | err); |
1912 | 1946 | ||
1913 | return err; | 1947 | return err; |
1914 | } | 1948 | } |
@@ -1922,15 +1956,43 @@ static int enic_set_niccfg(struct enic *enic) | |||
1922 | const u8 rss_enable = 0; | 1956 | const u8 rss_enable = 0; |
1923 | const u8 tso_ipid_split_en = 0; | 1957 | const u8 tso_ipid_split_en = 0; |
1924 | const u8 ig_vlan_strip_en = 1; | 1958 | const u8 ig_vlan_strip_en = 1; |
1959 | int err; | ||
1925 | 1960 | ||
1926 | /* Enable VLAN tag stripping. RSS not enabled (yet). | 1961 | /* Enable VLAN tag stripping. RSS not enabled (yet). |
1927 | */ | 1962 | */ |
1928 | 1963 | ||
1929 | return enic_set_nic_cfg(enic, | 1964 | spin_lock(&enic->devcmd_lock); |
1965 | err = enic_set_nic_cfg(enic, | ||
1930 | rss_default_cpu, rss_hash_type, | 1966 | rss_default_cpu, rss_hash_type, |
1931 | rss_hash_bits, rss_base_cpu, | 1967 | rss_hash_bits, rss_base_cpu, |
1932 | rss_enable, tso_ipid_split_en, | 1968 | rss_enable, tso_ipid_split_en, |
1933 | ig_vlan_strip_en); | 1969 | ig_vlan_strip_en); |
1970 | spin_unlock(&enic->devcmd_lock); | ||
1971 | |||
1972 | return err; | ||
1973 | } | ||
1974 | |||
1975 | static int enic_dev_hang_notify(struct enic *enic) | ||
1976 | { | ||
1977 | int err; | ||
1978 | |||
1979 | spin_lock(&enic->devcmd_lock); | ||
1980 | err = vnic_dev_hang_notify(enic->vdev); | ||
1981 | spin_unlock(&enic->devcmd_lock); | ||
1982 | |||
1983 | return err; | ||
1984 | } | ||
1985 | |||
1986 | int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) | ||
1987 | { | ||
1988 | int err; | ||
1989 | |||
1990 | spin_lock(&enic->devcmd_lock); | ||
1991 | err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev, | ||
1992 | IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN); | ||
1993 | spin_unlock(&enic->devcmd_lock); | ||
1994 | |||
1995 | return err; | ||
1934 | } | 1996 | } |
1935 | 1997 | ||
1936 | static void enic_reset(struct work_struct *work) | 1998 | static void enic_reset(struct work_struct *work) |
@@ -1942,16 +2004,13 @@ static void enic_reset(struct work_struct *work) | |||
1942 | 2004 | ||
1943 | rtnl_lock(); | 2005 | rtnl_lock(); |
1944 | 2006 | ||
1945 | spin_lock(&enic->devcmd_lock); | 2007 | enic_dev_hang_notify(enic); |
1946 | vnic_dev_hang_notify(enic->vdev); | ||
1947 | spin_unlock(&enic->devcmd_lock); | ||
1948 | |||
1949 | enic_stop(enic->netdev); | 2008 | enic_stop(enic->netdev); |
1950 | enic_dev_soft_reset(enic); | 2009 | enic_dev_hang_reset(enic); |
1951 | vnic_dev_init(enic->vdev, 0); | 2010 | enic_reset_multicast_list(enic); |
1952 | enic_reset_mcaddrs(enic); | ||
1953 | enic_init_vnic_resources(enic); | 2011 | enic_init_vnic_resources(enic); |
1954 | enic_set_niccfg(enic); | 2012 | enic_set_niccfg(enic); |
2013 | enic_dev_set_ig_vlan_rewrite_mode(enic); | ||
1955 | enic_open(enic->netdev); | 2014 | enic_open(enic->netdev); |
1956 | 2015 | ||
1957 | rtnl_unlock(); | 2016 | rtnl_unlock(); |
@@ -2087,8 +2146,8 @@ static const struct net_device_ops enic_netdev_ops = { | |||
2087 | .ndo_start_xmit = enic_hard_start_xmit, | 2146 | .ndo_start_xmit = enic_hard_start_xmit, |
2088 | .ndo_get_stats = enic_get_stats, | 2147 | .ndo_get_stats = enic_get_stats, |
2089 | .ndo_validate_addr = eth_validate_addr, | 2148 | .ndo_validate_addr = eth_validate_addr, |
2090 | .ndo_set_multicast_list = enic_set_multicast_list, | ||
2091 | .ndo_set_mac_address = enic_set_mac_address, | 2149 | .ndo_set_mac_address = enic_set_mac_address, |
2150 | .ndo_set_multicast_list = enic_set_multicast_list, | ||
2092 | .ndo_change_mtu = enic_change_mtu, | 2151 | .ndo_change_mtu = enic_change_mtu, |
2093 | .ndo_vlan_rx_register = enic_vlan_rx_register, | 2152 | .ndo_vlan_rx_register = enic_vlan_rx_register, |
2094 | .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, | 2153 | .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, |
@@ -2106,8 +2165,20 @@ void enic_dev_deinit(struct enic *enic) | |||
2106 | enic_clear_intr_mode(enic); | 2165 | enic_clear_intr_mode(enic); |
2107 | } | 2166 | } |
2108 | 2167 | ||
2168 | static int enic_dev_stats_clear(struct enic *enic) | ||
2169 | { | ||
2170 | int err; | ||
2171 | |||
2172 | spin_lock(&enic->devcmd_lock); | ||
2173 | err = vnic_dev_stats_clear(enic->vdev); | ||
2174 | spin_unlock(&enic->devcmd_lock); | ||
2175 | |||
2176 | return err; | ||
2177 | } | ||
2178 | |||
2109 | int enic_dev_init(struct enic *enic) | 2179 | int enic_dev_init(struct enic *enic) |
2110 | { | 2180 | { |
2181 | struct device *dev = enic_get_dev(enic); | ||
2111 | struct net_device *netdev = enic->netdev; | 2182 | struct net_device *netdev = enic->netdev; |
2112 | int err; | 2183 | int err; |
2113 | 2184 | ||
@@ -2116,8 +2187,7 @@ int enic_dev_init(struct enic *enic) | |||
2116 | 2187 | ||
2117 | err = enic_get_vnic_config(enic); | 2188 | err = enic_get_vnic_config(enic); |
2118 | if (err) { | 2189 | if (err) { |
2119 | printk(KERN_ERR PFX | 2190 | dev_err(dev, "Get vNIC configuration failed, aborting\n"); |
2120 | "Get vNIC configuration failed, aborting.\n"); | ||
2121 | return err; | 2191 | return err; |
2122 | } | 2192 | } |
2123 | 2193 | ||
@@ -2132,9 +2202,8 @@ int enic_dev_init(struct enic *enic) | |||
2132 | 2202 | ||
2133 | err = enic_set_intr_mode(enic); | 2203 | err = enic_set_intr_mode(enic); |
2134 | if (err) { | 2204 | if (err) { |
2135 | printk(KERN_ERR PFX | 2205 | dev_err(dev, "Failed to set intr mode based on resource " |
2136 | "Failed to set intr mode based on resource " | 2206 | "counts and system capabilities, aborting\n"); |
2137 | "counts and system capabilities, aborting.\n"); | ||
2138 | return err; | 2207 | return err; |
2139 | } | 2208 | } |
2140 | 2209 | ||
@@ -2143,24 +2212,32 @@ int enic_dev_init(struct enic *enic) | |||
2143 | 2212 | ||
2144 | err = enic_alloc_vnic_resources(enic); | 2213 | err = enic_alloc_vnic_resources(enic); |
2145 | if (err) { | 2214 | if (err) { |
2146 | printk(KERN_ERR PFX | 2215 | dev_err(dev, "Failed to alloc vNIC resources, aborting\n"); |
2147 | "Failed to alloc vNIC resources, aborting.\n"); | ||
2148 | goto err_out_free_vnic_resources; | 2216 | goto err_out_free_vnic_resources; |
2149 | } | 2217 | } |
2150 | 2218 | ||
2151 | enic_init_vnic_resources(enic); | 2219 | enic_init_vnic_resources(enic); |
2152 | 2220 | ||
2221 | /* Clear LIF stats | ||
2222 | */ | ||
2223 | enic_dev_stats_clear(enic); | ||
2224 | |||
2153 | err = enic_set_rq_alloc_buf(enic); | 2225 | err = enic_set_rq_alloc_buf(enic); |
2154 | if (err) { | 2226 | if (err) { |
2155 | printk(KERN_ERR PFX | 2227 | dev_err(dev, "Failed to set RQ buffer allocator, aborting\n"); |
2156 | "Failed to set RQ buffer allocator, aborting.\n"); | ||
2157 | goto err_out_free_vnic_resources; | 2228 | goto err_out_free_vnic_resources; |
2158 | } | 2229 | } |
2159 | 2230 | ||
2160 | err = enic_set_niccfg(enic); | 2231 | err = enic_set_niccfg(enic); |
2161 | if (err) { | 2232 | if (err) { |
2162 | printk(KERN_ERR PFX | 2233 | dev_err(dev, "Failed to config nic, aborting\n"); |
2163 | "Failed to config nic, aborting.\n"); | 2234 | goto err_out_free_vnic_resources; |
2235 | } | ||
2236 | |||
2237 | err = enic_dev_set_ig_vlan_rewrite_mode(enic); | ||
2238 | if (err) { | ||
2239 | netdev_err(netdev, | ||
2240 | "Failed to set ingress vlan rewrite mode, aborting.\n"); | ||
2164 | goto err_out_free_vnic_resources; | 2241 | goto err_out_free_vnic_resources; |
2165 | } | 2242 | } |
2166 | 2243 | ||
@@ -2194,6 +2271,7 @@ static void enic_iounmap(struct enic *enic) | |||
2194 | static int __devinit enic_probe(struct pci_dev *pdev, | 2271 | static int __devinit enic_probe(struct pci_dev *pdev, |
2195 | const struct pci_device_id *ent) | 2272 | const struct pci_device_id *ent) |
2196 | { | 2273 | { |
2274 | struct device *dev = &pdev->dev; | ||
2197 | struct net_device *netdev; | 2275 | struct net_device *netdev; |
2198 | struct enic *enic; | 2276 | struct enic *enic; |
2199 | int using_dac = 0; | 2277 | int using_dac = 0; |
@@ -2206,7 +2284,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2206 | 2284 | ||
2207 | netdev = alloc_etherdev(sizeof(struct enic)); | 2285 | netdev = alloc_etherdev(sizeof(struct enic)); |
2208 | if (!netdev) { | 2286 | if (!netdev) { |
2209 | printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); | 2287 | pr_err("Etherdev alloc failed, aborting\n"); |
2210 | return -ENOMEM; | 2288 | return -ENOMEM; |
2211 | } | 2289 | } |
2212 | 2290 | ||
@@ -2221,17 +2299,15 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2221 | /* Setup PCI resources | 2299 | /* Setup PCI resources |
2222 | */ | 2300 | */ |
2223 | 2301 | ||
2224 | err = pci_enable_device(pdev); | 2302 | err = pci_enable_device_mem(pdev); |
2225 | if (err) { | 2303 | if (err) { |
2226 | printk(KERN_ERR PFX | 2304 | dev_err(dev, "Cannot enable PCI device, aborting\n"); |
2227 | "Cannot enable PCI device, aborting.\n"); | ||
2228 | goto err_out_free_netdev; | 2305 | goto err_out_free_netdev; |
2229 | } | 2306 | } |
2230 | 2307 | ||
2231 | err = pci_request_regions(pdev, DRV_NAME); | 2308 | err = pci_request_regions(pdev, DRV_NAME); |
2232 | if (err) { | 2309 | if (err) { |
2233 | printk(KERN_ERR PFX | 2310 | dev_err(dev, "Cannot request PCI regions, aborting\n"); |
2234 | "Cannot request PCI regions, aborting.\n"); | ||
2235 | goto err_out_disable_device; | 2311 | goto err_out_disable_device; |
2236 | } | 2312 | } |
2237 | 2313 | ||
@@ -2246,23 +2322,20 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2246 | if (err) { | 2322 | if (err) { |
2247 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2323 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
2248 | if (err) { | 2324 | if (err) { |
2249 | printk(KERN_ERR PFX | 2325 | dev_err(dev, "No usable DMA configuration, aborting\n"); |
2250 | "No usable DMA configuration, aborting.\n"); | ||
2251 | goto err_out_release_regions; | 2326 | goto err_out_release_regions; |
2252 | } | 2327 | } |
2253 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 2328 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
2254 | if (err) { | 2329 | if (err) { |
2255 | printk(KERN_ERR PFX | 2330 | dev_err(dev, "Unable to obtain %u-bit DMA " |
2256 | "Unable to obtain 32-bit DMA " | 2331 | "for consistent allocations, aborting\n", 32); |
2257 | "for consistent allocations, aborting.\n"); | ||
2258 | goto err_out_release_regions; | 2332 | goto err_out_release_regions; |
2259 | } | 2333 | } |
2260 | } else { | 2334 | } else { |
2261 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); | 2335 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); |
2262 | if (err) { | 2336 | if (err) { |
2263 | printk(KERN_ERR PFX | 2337 | dev_err(dev, "Unable to obtain %u-bit DMA " |
2264 | "Unable to obtain 40-bit DMA " | 2338 | "for consistent allocations, aborting\n", 40); |
2265 | "for consistent allocations, aborting.\n"); | ||
2266 | goto err_out_release_regions; | 2339 | goto err_out_release_regions; |
2267 | } | 2340 | } |
2268 | using_dac = 1; | 2341 | using_dac = 1; |
@@ -2277,8 +2350,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2277 | enic->bar[i].len = pci_resource_len(pdev, i); | 2350 | enic->bar[i].len = pci_resource_len(pdev, i); |
2278 | enic->bar[i].vaddr = pci_iomap(pdev, i, enic->bar[i].len); | 2351 | enic->bar[i].vaddr = pci_iomap(pdev, i, enic->bar[i].len); |
2279 | if (!enic->bar[i].vaddr) { | 2352 | if (!enic->bar[i].vaddr) { |
2280 | printk(KERN_ERR PFX | 2353 | dev_err(dev, "Cannot memory-map BAR %d, aborting\n", i); |
2281 | "Cannot memory-map BAR %d, aborting.\n", i); | ||
2282 | err = -ENODEV; | 2354 | err = -ENODEV; |
2283 | goto err_out_iounmap; | 2355 | goto err_out_iounmap; |
2284 | } | 2356 | } |
@@ -2291,8 +2363,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2291 | enic->vdev = vnic_dev_register(NULL, enic, pdev, enic->bar, | 2363 | enic->vdev = vnic_dev_register(NULL, enic, pdev, enic->bar, |
2292 | ARRAY_SIZE(enic->bar)); | 2364 | ARRAY_SIZE(enic->bar)); |
2293 | if (!enic->vdev) { | 2365 | if (!enic->vdev) { |
2294 | printk(KERN_ERR PFX | 2366 | dev_err(dev, "vNIC registration failed, aborting\n"); |
2295 | "vNIC registration failed, aborting.\n"); | ||
2296 | err = -ENODEV; | 2367 | err = -ENODEV; |
2297 | goto err_out_iounmap; | 2368 | goto err_out_iounmap; |
2298 | } | 2369 | } |
@@ -2302,8 +2373,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2302 | 2373 | ||
2303 | err = enic_dev_open(enic); | 2374 | err = enic_dev_open(enic); |
2304 | if (err) { | 2375 | if (err) { |
2305 | printk(KERN_ERR PFX | 2376 | dev_err(dev, "vNIC dev open failed, aborting\n"); |
2306 | "vNIC dev open failed, aborting.\n"); | ||
2307 | goto err_out_vnic_unregister; | 2377 | goto err_out_vnic_unregister; |
2308 | } | 2378 | } |
2309 | 2379 | ||
@@ -2317,23 +2387,31 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2317 | 2387 | ||
2318 | netif_carrier_off(netdev); | 2388 | netif_carrier_off(netdev); |
2319 | 2389 | ||
2390 | /* Do not call dev_init for a dynamic vnic. | ||
2391 | * For a dynamic vnic, init_prov_info will be | ||
2392 | * called later by an upper layer. | ||
2393 | */ | ||
2394 | |||
2320 | if (!enic_is_dynamic(enic)) { | 2395 | if (!enic_is_dynamic(enic)) { |
2321 | err = vnic_dev_init(enic->vdev, 0); | 2396 | err = vnic_dev_init(enic->vdev, 0); |
2322 | if (err) { | 2397 | if (err) { |
2323 | printk(KERN_ERR PFX | 2398 | dev_err(dev, "vNIC dev init failed, aborting\n"); |
2324 | "vNIC dev init failed, aborting.\n"); | ||
2325 | goto err_out_dev_close; | 2399 | goto err_out_dev_close; |
2326 | } | 2400 | } |
2327 | } | 2401 | } |
2328 | 2402 | ||
2403 | /* Setup devcmd lock | ||
2404 | */ | ||
2405 | |||
2406 | spin_lock_init(&enic->devcmd_lock); | ||
2407 | |||
2329 | err = enic_dev_init(enic); | 2408 | err = enic_dev_init(enic); |
2330 | if (err) { | 2409 | if (err) { |
2331 | printk(KERN_ERR PFX | 2410 | dev_err(dev, "Device initialization failed, aborting\n"); |
2332 | "Device initialization failed, aborting.\n"); | ||
2333 | goto err_out_dev_close; | 2411 | goto err_out_dev_close; |
2334 | } | 2412 | } |
2335 | 2413 | ||
2336 | /* Setup notification timer, HW reset task, and locks | 2414 | /* Setup notification timer, HW reset task, and wq locks |
2337 | */ | 2415 | */ |
2338 | 2416 | ||
2339 | init_timer(&enic->notify_timer); | 2417 | init_timer(&enic->notify_timer); |
@@ -2345,8 +2423,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2345 | for (i = 0; i < enic->wq_count; i++) | 2423 | for (i = 0; i < enic->wq_count; i++) |
2346 | spin_lock_init(&enic->wq_lock[i]); | 2424 | spin_lock_init(&enic->wq_lock[i]); |
2347 | 2425 | ||
2348 | spin_lock_init(&enic->devcmd_lock); | ||
2349 | |||
2350 | /* Register net device | 2426 | /* Register net device |
2351 | */ | 2427 | */ |
2352 | 2428 | ||
@@ -2355,8 +2431,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2355 | 2431 | ||
2356 | err = enic_set_mac_addr(netdev, enic->mac_addr); | 2432 | err = enic_set_mac_addr(netdev, enic->mac_addr); |
2357 | if (err) { | 2433 | if (err) { |
2358 | printk(KERN_ERR PFX | 2434 | dev_err(dev, "Invalid MAC address, aborting\n"); |
2359 | "Invalid MAC address, aborting.\n"); | ||
2360 | goto err_out_dev_deinit; | 2435 | goto err_out_dev_deinit; |
2361 | } | 2436 | } |
2362 | 2437 | ||
@@ -2372,31 +2447,27 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2372 | netdev->ethtool_ops = &enic_ethtool_ops; | 2447 | netdev->ethtool_ops = &enic_ethtool_ops; |
2373 | 2448 | ||
2374 | netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 2449 | netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
2450 | if (ENIC_SETTING(enic, LOOP)) { | ||
2451 | netdev->features &= ~NETIF_F_HW_VLAN_TX; | ||
2452 | enic->loop_enable = 1; | ||
2453 | enic->loop_tag = enic->config.loop_tag; | ||
2454 | dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag); | ||
2455 | } | ||
2375 | if (ENIC_SETTING(enic, TXCSUM)) | 2456 | if (ENIC_SETTING(enic, TXCSUM)) |
2376 | netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; | 2457 | netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; |
2377 | if (ENIC_SETTING(enic, TSO)) | 2458 | if (ENIC_SETTING(enic, TSO)) |
2378 | netdev->features |= NETIF_F_TSO | | 2459 | netdev->features |= NETIF_F_TSO | |
2379 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; | 2460 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; |
2380 | if (ENIC_SETTING(enic, LRO)) | 2461 | if (ENIC_SETTING(enic, LRO)) |
2381 | netdev->features |= NETIF_F_LRO; | 2462 | netdev->features |= NETIF_F_GRO; |
2382 | if (using_dac) | 2463 | if (using_dac) |
2383 | netdev->features |= NETIF_F_HIGHDMA; | 2464 | netdev->features |= NETIF_F_HIGHDMA; |
2384 | 2465 | ||
2385 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); | 2466 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); |
2386 | 2467 | ||
2387 | enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR; | ||
2388 | enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC; | ||
2389 | enic->lro_mgr.lro_arr = enic->lro_desc; | ||
2390 | enic->lro_mgr.get_skb_header = enic_get_skb_header; | ||
2391 | enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; | ||
2392 | enic->lro_mgr.dev = netdev; | ||
2393 | enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE; | ||
2394 | enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
2395 | |||
2396 | err = register_netdev(netdev); | 2468 | err = register_netdev(netdev); |
2397 | if (err) { | 2469 | if (err) { |
2398 | printk(KERN_ERR PFX | 2470 | dev_err(dev, "Cannot register net device, aborting\n"); |
2399 | "Cannot register net device, aborting.\n"); | ||
2400 | goto err_out_dev_deinit; | 2471 | goto err_out_dev_deinit; |
2401 | } | 2472 | } |
2402 | 2473 | ||
@@ -2450,7 +2521,7 @@ static struct pci_driver enic_driver = { | |||
2450 | 2521 | ||
2451 | static int __init enic_init_module(void) | 2522 | static int __init enic_init_module(void) |
2452 | { | 2523 | { |
2453 | printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION); | 2524 | pr_info("%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION); |
2454 | 2525 | ||
2455 | return pci_register_driver(&enic_driver); | 2526 | return pci_register_driver(&enic_driver); |
2456 | } | 2527 | } |
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 9b18840cba96..29ede8a17a2c 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -46,7 +46,8 @@ int enic_get_vnic_config(struct enic *enic) | |||
46 | 46 | ||
47 | err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr); | 47 | err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr); |
48 | if (err) { | 48 | if (err) { |
49 | printk(KERN_ERR PFX "Error getting MAC addr, %d\n", err); | 49 | dev_err(enic_get_dev(enic), |
50 | "Error getting MAC addr, %d\n", err); | ||
50 | return err; | 51 | return err; |
51 | } | 52 | } |
52 | 53 | ||
@@ -56,7 +57,7 @@ int enic_get_vnic_config(struct enic *enic) | |||
56 | offsetof(struct vnic_enet_config, m), \ | 57 | offsetof(struct vnic_enet_config, m), \ |
57 | sizeof(c->m), &c->m); \ | 58 | sizeof(c->m), &c->m); \ |
58 | if (err) { \ | 59 | if (err) { \ |
59 | printk(KERN_ERR PFX \ | 60 | dev_err(enic_get_dev(enic), \ |
60 | "Error getting %s, %d\n", #m, err); \ | 61 | "Error getting %s, %d\n", #m, err); \ |
61 | return err; \ | 62 | return err; \ |
62 | } \ | 63 | } \ |
@@ -69,6 +70,7 @@ int enic_get_vnic_config(struct enic *enic) | |||
69 | GET_CONFIG(intr_timer_type); | 70 | GET_CONFIG(intr_timer_type); |
70 | GET_CONFIG(intr_mode); | 71 | GET_CONFIG(intr_mode); |
71 | GET_CONFIG(intr_timer_usec); | 72 | GET_CONFIG(intr_timer_usec); |
73 | GET_CONFIG(loop_tag); | ||
72 | 74 | ||
73 | c->wq_desc_count = | 75 | c->wq_desc_count = |
74 | min_t(u32, ENIC_MAX_WQ_DESCS, | 76 | min_t(u32, ENIC_MAX_WQ_DESCS, |
@@ -92,10 +94,10 @@ int enic_get_vnic_config(struct enic *enic) | |||
92 | INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), | 94 | INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), |
93 | c->intr_timer_usec); | 95 | c->intr_timer_usec); |
94 | 96 | ||
95 | printk(KERN_INFO PFX "vNIC MAC addr %pM wq/rq %d/%d\n", | 97 | dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n", |
96 | enic->mac_addr, c->wq_desc_count, c->rq_desc_count); | 98 | enic->mac_addr, c->wq_desc_count, c->rq_desc_count); |
97 | printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d " | 99 | dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d " |
98 | "intr timer %d usec\n", | 100 | "tso/lro %d/%d intr timer %d usec\n", |
99 | c->mtu, ENIC_SETTING(enic, TXCSUM), | 101 | c->mtu, ENIC_SETTING(enic, TXCSUM), |
100 | ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO), | 102 | ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO), |
101 | ENIC_SETTING(enic, LRO), c->intr_timer_usec); | 103 | ENIC_SETTING(enic, LRO), c->intr_timer_usec); |
@@ -103,17 +105,7 @@ int enic_get_vnic_config(struct enic *enic) | |||
103 | return 0; | 105 | return 0; |
104 | } | 106 | } |
105 | 107 | ||
106 | void enic_add_multicast_addr(struct enic *enic, u8 *addr) | 108 | int enic_add_vlan(struct enic *enic, u16 vlanid) |
107 | { | ||
108 | vnic_dev_add_addr(enic->vdev, addr); | ||
109 | } | ||
110 | |||
111 | void enic_del_multicast_addr(struct enic *enic, u8 *addr) | ||
112 | { | ||
113 | vnic_dev_del_addr(enic->vdev, addr); | ||
114 | } | ||
115 | |||
116 | void enic_add_vlan(struct enic *enic, u16 vlanid) | ||
117 | { | 109 | { |
118 | u64 a0 = vlanid, a1 = 0; | 110 | u64 a0 = vlanid, a1 = 0; |
119 | int wait = 1000; | 111 | int wait = 1000; |
@@ -121,10 +113,12 @@ void enic_add_vlan(struct enic *enic, u16 vlanid) | |||
121 | 113 | ||
122 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait); | 114 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait); |
123 | if (err) | 115 | if (err) |
124 | printk(KERN_ERR PFX "Can't add vlan id, %d\n", err); | 116 | dev_err(enic_get_dev(enic), "Can't add vlan id, %d\n", err); |
117 | |||
118 | return err; | ||
125 | } | 119 | } |
126 | 120 | ||
127 | void enic_del_vlan(struct enic *enic, u16 vlanid) | 121 | int enic_del_vlan(struct enic *enic, u16 vlanid) |
128 | { | 122 | { |
129 | u64 a0 = vlanid, a1 = 0; | 123 | u64 a0 = vlanid, a1 = 0; |
130 | int wait = 1000; | 124 | int wait = 1000; |
@@ -132,7 +126,9 @@ void enic_del_vlan(struct enic *enic, u16 vlanid) | |||
132 | 126 | ||
133 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait); | 127 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait); |
134 | if (err) | 128 | if (err) |
135 | printk(KERN_ERR PFX "Can't delete vlan id, %d\n", err); | 129 | dev_err(enic_get_dev(enic), "Can't delete vlan id, %d\n", err); |
130 | |||
131 | return err; | ||
136 | } | 132 | } |
137 | 133 | ||
138 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | 134 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, |
@@ -198,8 +194,8 @@ void enic_get_res_counts(struct enic *enic) | |||
198 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL), | 194 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL), |
199 | ENIC_INTR_MAX); | 195 | ENIC_INTR_MAX); |
200 | 196 | ||
201 | printk(KERN_INFO PFX "vNIC resources avail: " | 197 | dev_info(enic_get_dev(enic), |
202 | "wq %d rq %d cq %d intr %d\n", | 198 | "vNIC resources avail: wq %d rq %d cq %d intr %d\n", |
203 | enic->wq_count, enic->rq_count, | 199 | enic->wq_count, enic->rq_count, |
204 | enic->cq_count, enic->intr_count); | 200 | enic->cq_count, enic->intr_count); |
205 | } | 201 | } |
@@ -304,11 +300,6 @@ void enic_init_vnic_resources(struct enic *enic) | |||
304 | enic->config.intr_timer_type, | 300 | enic->config.intr_timer_type, |
305 | mask_on_assertion); | 301 | mask_on_assertion); |
306 | } | 302 | } |
307 | |||
308 | /* Clear LIF stats | ||
309 | */ | ||
310 | |||
311 | vnic_dev_stats_clear(enic->vdev); | ||
312 | } | 303 | } |
313 | 304 | ||
314 | int enic_alloc_vnic_resources(struct enic *enic) | 305 | int enic_alloc_vnic_resources(struct enic *enic) |
@@ -319,15 +310,14 @@ int enic_alloc_vnic_resources(struct enic *enic) | |||
319 | 310 | ||
320 | intr_mode = vnic_dev_get_intr_mode(enic->vdev); | 311 | intr_mode = vnic_dev_get_intr_mode(enic->vdev); |
321 | 312 | ||
322 | printk(KERN_INFO PFX "vNIC resources used: " | 313 | dev_info(enic_get_dev(enic), "vNIC resources used: " |
323 | "wq %d rq %d cq %d intr %d intr mode %s\n", | 314 | "wq %d rq %d cq %d intr %d intr mode %s\n", |
324 | enic->wq_count, enic->rq_count, | 315 | enic->wq_count, enic->rq_count, |
325 | enic->cq_count, enic->intr_count, | 316 | enic->cq_count, enic->intr_count, |
326 | intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" : | 317 | intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" : |
327 | intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" : | 318 | intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" : |
328 | intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" : | 319 | intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" : |
329 | "unknown" | 320 | "unknown"); |
330 | ); | ||
331 | 321 | ||
332 | /* Allocate queue resources | 322 | /* Allocate queue resources |
333 | */ | 323 | */ |
@@ -373,7 +363,8 @@ int enic_alloc_vnic_resources(struct enic *enic) | |||
373 | enic->legacy_pba = vnic_dev_get_res(enic->vdev, | 363 | enic->legacy_pba = vnic_dev_get_res(enic->vdev, |
374 | RES_TYPE_INTR_PBA_LEGACY, 0); | 364 | RES_TYPE_INTR_PBA_LEGACY, 0); |
375 | if (!enic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) { | 365 | if (!enic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) { |
376 | printk(KERN_ERR PFX "Failed to hook legacy pba resource\n"); | 366 | dev_err(enic_get_dev(enic), |
367 | "Failed to hook legacy pba resource\n"); | ||
377 | err = -ENODEV; | 368 | err = -ENODEV; |
378 | goto err_out_cleanup; | 369 | goto err_out_cleanup; |
379 | } | 370 | } |
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 494664f7fccc..83bd172c356c 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -43,7 +43,7 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq, | |||
43 | void *os_buf, dma_addr_t dma_addr, unsigned int len, | 43 | void *os_buf, dma_addr_t dma_addr, unsigned int len, |
44 | unsigned int mss_or_csum_offset, unsigned int hdr_len, | 44 | unsigned int mss_or_csum_offset, unsigned int hdr_len, |
45 | int vlan_tag_insert, unsigned int vlan_tag, | 45 | int vlan_tag_insert, unsigned int vlan_tag, |
46 | int offload_mode, int cq_entry, int sop, int eop) | 46 | int offload_mode, int cq_entry, int sop, int eop, int loopback) |
47 | { | 47 | { |
48 | struct wq_enet_desc *desc = vnic_wq_next_desc(wq); | 48 | struct wq_enet_desc *desc = vnic_wq_next_desc(wq); |
49 | 49 | ||
@@ -56,61 +56,62 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq, | |||
56 | 0, /* fcoe_encap */ | 56 | 0, /* fcoe_encap */ |
57 | (u8)vlan_tag_insert, | 57 | (u8)vlan_tag_insert, |
58 | (u16)vlan_tag, | 58 | (u16)vlan_tag, |
59 | 0 /* loopback */); | 59 | (u8)loopback); |
60 | 60 | ||
61 | vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop); | 61 | vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop); |
62 | } | 62 | } |
63 | 63 | ||
64 | static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq, | 64 | static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq, |
65 | void *os_buf, dma_addr_t dma_addr, unsigned int len, int eop) | 65 | void *os_buf, dma_addr_t dma_addr, unsigned int len, |
66 | int eop, int loopback) | ||
66 | { | 67 | { |
67 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, | 68 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, |
68 | 0, 0, 0, 0, 0, | 69 | 0, 0, 0, 0, 0, |
69 | eop, 0 /* !SOP */, eop); | 70 | eop, 0 /* !SOP */, eop, loopback); |
70 | } | 71 | } |
71 | 72 | ||
72 | static inline void enic_queue_wq_desc(struct vnic_wq *wq, void *os_buf, | 73 | static inline void enic_queue_wq_desc(struct vnic_wq *wq, void *os_buf, |
73 | dma_addr_t dma_addr, unsigned int len, int vlan_tag_insert, | 74 | dma_addr_t dma_addr, unsigned int len, int vlan_tag_insert, |
74 | unsigned int vlan_tag, int eop) | 75 | unsigned int vlan_tag, int eop, int loopback) |
75 | { | 76 | { |
76 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, | 77 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, |
77 | 0, 0, vlan_tag_insert, vlan_tag, | 78 | 0, 0, vlan_tag_insert, vlan_tag, |
78 | WQ_ENET_OFFLOAD_MODE_CSUM, | 79 | WQ_ENET_OFFLOAD_MODE_CSUM, |
79 | eop, 1 /* SOP */, eop); | 80 | eop, 1 /* SOP */, eop, loopback); |
80 | } | 81 | } |
81 | 82 | ||
82 | static inline void enic_queue_wq_desc_csum(struct vnic_wq *wq, | 83 | static inline void enic_queue_wq_desc_csum(struct vnic_wq *wq, |
83 | void *os_buf, dma_addr_t dma_addr, unsigned int len, | 84 | void *os_buf, dma_addr_t dma_addr, unsigned int len, |
84 | int ip_csum, int tcpudp_csum, int vlan_tag_insert, | 85 | int ip_csum, int tcpudp_csum, int vlan_tag_insert, |
85 | unsigned int vlan_tag, int eop) | 86 | unsigned int vlan_tag, int eop, int loopback) |
86 | { | 87 | { |
87 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, | 88 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, |
88 | (ip_csum ? 1 : 0) + (tcpudp_csum ? 2 : 0), | 89 | (ip_csum ? 1 : 0) + (tcpudp_csum ? 2 : 0), |
89 | 0, vlan_tag_insert, vlan_tag, | 90 | 0, vlan_tag_insert, vlan_tag, |
90 | WQ_ENET_OFFLOAD_MODE_CSUM, | 91 | WQ_ENET_OFFLOAD_MODE_CSUM, |
91 | eop, 1 /* SOP */, eop); | 92 | eop, 1 /* SOP */, eop, loopback); |
92 | } | 93 | } |
93 | 94 | ||
94 | static inline void enic_queue_wq_desc_csum_l4(struct vnic_wq *wq, | 95 | static inline void enic_queue_wq_desc_csum_l4(struct vnic_wq *wq, |
95 | void *os_buf, dma_addr_t dma_addr, unsigned int len, | 96 | void *os_buf, dma_addr_t dma_addr, unsigned int len, |
96 | unsigned int csum_offset, unsigned int hdr_len, | 97 | unsigned int csum_offset, unsigned int hdr_len, |
97 | int vlan_tag_insert, unsigned int vlan_tag, int eop) | 98 | int vlan_tag_insert, unsigned int vlan_tag, int eop, int loopback) |
98 | { | 99 | { |
99 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, | 100 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, |
100 | csum_offset, hdr_len, vlan_tag_insert, vlan_tag, | 101 | csum_offset, hdr_len, vlan_tag_insert, vlan_tag, |
101 | WQ_ENET_OFFLOAD_MODE_CSUM_L4, | 102 | WQ_ENET_OFFLOAD_MODE_CSUM_L4, |
102 | eop, 1 /* SOP */, eop); | 103 | eop, 1 /* SOP */, eop, loopback); |
103 | } | 104 | } |
104 | 105 | ||
105 | static inline void enic_queue_wq_desc_tso(struct vnic_wq *wq, | 106 | static inline void enic_queue_wq_desc_tso(struct vnic_wq *wq, |
106 | void *os_buf, dma_addr_t dma_addr, unsigned int len, | 107 | void *os_buf, dma_addr_t dma_addr, unsigned int len, |
107 | unsigned int mss, unsigned int hdr_len, int vlan_tag_insert, | 108 | unsigned int mss, unsigned int hdr_len, int vlan_tag_insert, |
108 | unsigned int vlan_tag, int eop) | 109 | unsigned int vlan_tag, int eop, int loopback) |
109 | { | 110 | { |
110 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, | 111 | enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len, |
111 | mss, hdr_len, vlan_tag_insert, vlan_tag, | 112 | mss, hdr_len, vlan_tag_insert, vlan_tag, |
112 | WQ_ENET_OFFLOAD_MODE_TSO, | 113 | WQ_ENET_OFFLOAD_MODE_TSO, |
113 | eop, 1 /* SOP */, eop); | 114 | eop, 1 /* SOP */, eop, loopback); |
114 | } | 115 | } |
115 | 116 | ||
116 | static inline void enic_queue_rq_desc(struct vnic_rq *rq, | 117 | static inline void enic_queue_rq_desc(struct vnic_rq *rq, |
@@ -131,10 +132,8 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq, | |||
131 | struct enic; | 132 | struct enic; |
132 | 133 | ||
133 | int enic_get_vnic_config(struct enic *); | 134 | int enic_get_vnic_config(struct enic *); |
134 | void enic_add_multicast_addr(struct enic *enic, u8 *addr); | 135 | int enic_add_vlan(struct enic *enic, u16 vlanid); |
135 | void enic_del_multicast_addr(struct enic *enic, u8 *addr); | 136 | int enic_del_vlan(struct enic *enic, u16 vlanid); |
136 | void enic_add_vlan(struct enic *enic, u16 vlanid); | ||
137 | void enic_del_vlan(struct enic *enic, u16 vlanid); | ||
138 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | 137 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, |
139 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, | 138 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, |
140 | u8 ig_vlan_strip_en); | 139 | u8 ig_vlan_strip_en); |
diff --git a/drivers/net/enic/rq_enet_desc.h b/drivers/net/enic/rq_enet_desc.h index a06e649010ce..e6dd30988d6f 100644 --- a/drivers/net/enic/rq_enet_desc.h +++ b/drivers/net/enic/rq_enet_desc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_cq.c b/drivers/net/enic/vnic_cq.c index 020ae6c3f3d9..b86d6ef8dad3 100644 --- a/drivers/net/enic/vnic_cq.c +++ b/drivers/net/enic/vnic_cq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -42,7 +42,7 @@ int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index, | |||
42 | 42 | ||
43 | cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index); | 43 | cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index); |
44 | if (!cq->ctrl) { | 44 | if (!cq->ctrl) { |
45 | printk(KERN_ERR "Failed to hook CQ[%d] resource\n", index); | 45 | pr_err("Failed to hook CQ[%d] resource\n", index); |
46 | return -EINVAL; | 46 | return -EINVAL; |
47 | } | 47 | } |
48 | 48 | ||
diff --git a/drivers/net/enic/vnic_cq.h b/drivers/net/enic/vnic_cq.h index 114763cbc2f8..552d3daf2508 100644 --- a/drivers/net/enic/vnic_cq.h +++ b/drivers/net/enic/vnic_cq.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index e0d33281ec98..6a5b578a69e1 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -23,21 +23,23 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/if_ether.h> | 25 | #include <linux/if_ether.h> |
26 | #include <linux/slab.h> | ||
27 | 26 | ||
28 | #include "vnic_resource.h" | 27 | #include "vnic_resource.h" |
29 | #include "vnic_devcmd.h" | 28 | #include "vnic_devcmd.h" |
30 | #include "vnic_dev.h" | 29 | #include "vnic_dev.h" |
31 | #include "vnic_stats.h" | 30 | #include "vnic_stats.h" |
32 | 31 | ||
32 | enum vnic_proxy_type { | ||
33 | PROXY_NONE, | ||
34 | PROXY_BY_BDF, | ||
35 | }; | ||
36 | |||
33 | struct vnic_res { | 37 | struct vnic_res { |
34 | void __iomem *vaddr; | 38 | void __iomem *vaddr; |
35 | dma_addr_t bus_addr; | 39 | dma_addr_t bus_addr; |
36 | unsigned int count; | 40 | unsigned int count; |
37 | }; | 41 | }; |
38 | 42 | ||
39 | #define VNIC_DEV_CAP_INIT 0x0001 | ||
40 | |||
41 | struct vnic_dev { | 43 | struct vnic_dev { |
42 | void *priv; | 44 | void *priv; |
43 | struct pci_dev *pdev; | 45 | struct pci_dev *pdev; |
@@ -48,13 +50,14 @@ struct vnic_dev { | |||
48 | struct vnic_devcmd_notify notify_copy; | 50 | struct vnic_devcmd_notify notify_copy; |
49 | dma_addr_t notify_pa; | 51 | dma_addr_t notify_pa; |
50 | u32 notify_sz; | 52 | u32 notify_sz; |
51 | u32 *linkstatus; | ||
52 | dma_addr_t linkstatus_pa; | 53 | dma_addr_t linkstatus_pa; |
53 | struct vnic_stats *stats; | 54 | struct vnic_stats *stats; |
54 | dma_addr_t stats_pa; | 55 | dma_addr_t stats_pa; |
55 | struct vnic_devcmd_fw_info *fw_info; | 56 | struct vnic_devcmd_fw_info *fw_info; |
56 | dma_addr_t fw_info_pa; | 57 | dma_addr_t fw_info_pa; |
57 | u32 cap_flags; | 58 | enum vnic_proxy_type proxy; |
59 | u32 proxy_index; | ||
60 | u64 args[VNIC_DEVCMD_NARGS]; | ||
58 | }; | 61 | }; |
59 | 62 | ||
60 | #define VNIC_MAX_RES_HDR_SIZE \ | 63 | #define VNIC_MAX_RES_HDR_SIZE \ |
@@ -78,19 +81,19 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
78 | return -EINVAL; | 81 | return -EINVAL; |
79 | 82 | ||
80 | if (bar->len < VNIC_MAX_RES_HDR_SIZE) { | 83 | if (bar->len < VNIC_MAX_RES_HDR_SIZE) { |
81 | printk(KERN_ERR "vNIC BAR0 res hdr length error\n"); | 84 | pr_err("vNIC BAR0 res hdr length error\n"); |
82 | return -EINVAL; | 85 | return -EINVAL; |
83 | } | 86 | } |
84 | 87 | ||
85 | rh = bar->vaddr; | 88 | rh = bar->vaddr; |
86 | if (!rh) { | 89 | if (!rh) { |
87 | printk(KERN_ERR "vNIC BAR0 res hdr not mem-mapped\n"); | 90 | pr_err("vNIC BAR0 res hdr not mem-mapped\n"); |
88 | return -EINVAL; | 91 | return -EINVAL; |
89 | } | 92 | } |
90 | 93 | ||
91 | if (ioread32(&rh->magic) != VNIC_RES_MAGIC || | 94 | if (ioread32(&rh->magic) != VNIC_RES_MAGIC || |
92 | ioread32(&rh->version) != VNIC_RES_VERSION) { | 95 | ioread32(&rh->version) != VNIC_RES_VERSION) { |
93 | printk(KERN_ERR "vNIC BAR0 res magic/version error " | 96 | pr_err("vNIC BAR0 res magic/version error " |
94 | "exp (%lx/%lx) curr (%x/%x)\n", | 97 | "exp (%lx/%lx) curr (%x/%x)\n", |
95 | VNIC_RES_MAGIC, VNIC_RES_VERSION, | 98 | VNIC_RES_MAGIC, VNIC_RES_VERSION, |
96 | ioread32(&rh->magic), ioread32(&rh->version)); | 99 | ioread32(&rh->magic), ioread32(&rh->version)); |
@@ -122,7 +125,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
122 | /* each count is stride bytes long */ | 125 | /* each count is stride bytes long */ |
123 | len = count * VNIC_RES_STRIDE; | 126 | len = count * VNIC_RES_STRIDE; |
124 | if (len + bar_offset > bar[bar_num].len) { | 127 | if (len + bar_offset > bar[bar_num].len) { |
125 | printk(KERN_ERR "vNIC BAR0 resource %d " | 128 | pr_err("vNIC BAR0 resource %d " |
126 | "out-of-bounds, offset 0x%x + " | 129 | "out-of-bounds, offset 0x%x + " |
127 | "size 0x%x > bar len 0x%lx\n", | 130 | "size 0x%x > bar len 0x%lx\n", |
128 | type, bar_offset, | 131 | type, bar_offset, |
@@ -229,8 +232,7 @@ int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, | |||
229 | &ring->base_addr_unaligned); | 232 | &ring->base_addr_unaligned); |
230 | 233 | ||
231 | if (!ring->descs_unaligned) { | 234 | if (!ring->descs_unaligned) { |
232 | printk(KERN_ERR | 235 | pr_err("Failed to allocate ring (size=%d), aborting\n", |
233 | "Failed to allocate ring (size=%d), aborting\n", | ||
234 | (int)ring->size); | 236 | (int)ring->size); |
235 | return -ENOMEM; | 237 | return -ENOMEM; |
236 | } | 238 | } |
@@ -258,23 +260,28 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring) | |||
258 | } | 260 | } |
259 | } | 261 | } |
260 | 262 | ||
261 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | 263 | static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
262 | u64 *a0, u64 *a1, int wait) | 264 | int wait) |
263 | { | 265 | { |
264 | struct vnic_devcmd __iomem *devcmd = vdev->devcmd; | 266 | struct vnic_devcmd __iomem *devcmd = vdev->devcmd; |
267 | unsigned int i; | ||
265 | int delay; | 268 | int delay; |
266 | u32 status; | 269 | u32 status; |
267 | int err; | 270 | int err; |
268 | 271 | ||
269 | status = ioread32(&devcmd->status); | 272 | status = ioread32(&devcmd->status); |
273 | if (status == 0xFFFFFFFF) { | ||
274 | /* PCI-e target device is gone */ | ||
275 | return -ENODEV; | ||
276 | } | ||
270 | if (status & STAT_BUSY) { | 277 | if (status & STAT_BUSY) { |
271 | printk(KERN_ERR "Busy devcmd %d\n", _CMD_N(cmd)); | 278 | pr_err("Busy devcmd %d\n", _CMD_N(cmd)); |
272 | return -EBUSY; | 279 | return -EBUSY; |
273 | } | 280 | } |
274 | 281 | ||
275 | if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) { | 282 | if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) { |
276 | writeq(*a0, &devcmd->args[0]); | 283 | for (i = 0; i < VNIC_DEVCMD_NARGS; i++) |
277 | writeq(*a1, &devcmd->args[1]); | 284 | writeq(vdev->args[i], &devcmd->args[i]); |
278 | wmb(); | 285 | wmb(); |
279 | } | 286 | } |
280 | 287 | ||
@@ -288,31 +295,110 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | |||
288 | udelay(100); | 295 | udelay(100); |
289 | 296 | ||
290 | status = ioread32(&devcmd->status); | 297 | status = ioread32(&devcmd->status); |
298 | if (status == 0xFFFFFFFF) { | ||
299 | /* PCI-e target device is gone */ | ||
300 | return -ENODEV; | ||
301 | } | ||
302 | |||
291 | if (!(status & STAT_BUSY)) { | 303 | if (!(status & STAT_BUSY)) { |
292 | 304 | ||
293 | if (status & STAT_ERROR) { | 305 | if (status & STAT_ERROR) { |
294 | err = (int)readq(&devcmd->args[0]); | 306 | err = (int)readq(&devcmd->args[0]); |
295 | if (err != ERR_ECMDUNKNOWN || | 307 | if (err != ERR_ECMDUNKNOWN || |
296 | cmd != CMD_CAPABILITY) | 308 | cmd != CMD_CAPABILITY) |
297 | printk(KERN_ERR "Error %d devcmd %d\n", | 309 | pr_err("Error %d devcmd %d\n", |
298 | err, _CMD_N(cmd)); | 310 | err, _CMD_N(cmd)); |
299 | return err; | 311 | return err; |
300 | } | 312 | } |
301 | 313 | ||
302 | if (_CMD_DIR(cmd) & _CMD_DIR_READ) { | 314 | if (_CMD_DIR(cmd) & _CMD_DIR_READ) { |
303 | rmb(); | 315 | rmb(); |
304 | *a0 = readq(&devcmd->args[0]); | 316 | for (i = 0; i < VNIC_DEVCMD_NARGS; i++) |
305 | *a1 = readq(&devcmd->args[1]); | 317 | vdev->args[i] = readq(&devcmd->args[i]); |
306 | } | 318 | } |
307 | 319 | ||
308 | return 0; | 320 | return 0; |
309 | } | 321 | } |
310 | } | 322 | } |
311 | 323 | ||
312 | printk(KERN_ERR "Timedout devcmd %d\n", _CMD_N(cmd)); | 324 | pr_err("Timedout devcmd %d\n", _CMD_N(cmd)); |
313 | return -ETIMEDOUT; | 325 | return -ETIMEDOUT; |
314 | } | 326 | } |
315 | 327 | ||
328 | static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev, | ||
329 | enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait) | ||
330 | { | ||
331 | u32 status; | ||
332 | int err; | ||
333 | |||
334 | memset(vdev->args, 0, sizeof(vdev->args)); | ||
335 | |||
336 | vdev->args[0] = vdev->proxy_index; /* bdf */ | ||
337 | vdev->args[1] = cmd; | ||
338 | vdev->args[2] = *a0; | ||
339 | vdev->args[3] = *a1; | ||
340 | |||
341 | err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait); | ||
342 | if (err) | ||
343 | return err; | ||
344 | |||
345 | status = (u32)vdev->args[0]; | ||
346 | if (status & STAT_ERROR) { | ||
347 | err = (int)vdev->args[1]; | ||
348 | if (err != ERR_ECMDUNKNOWN || | ||
349 | cmd != CMD_CAPABILITY) | ||
350 | pr_err("Error %d proxy devcmd %d\n", err, _CMD_N(cmd)); | ||
351 | return err; | ||
352 | } | ||
353 | |||
354 | *a0 = vdev->args[1]; | ||
355 | *a1 = vdev->args[2]; | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, | ||
361 | enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait) | ||
362 | { | ||
363 | int err; | ||
364 | |||
365 | vdev->args[0] = *a0; | ||
366 | vdev->args[1] = *a1; | ||
367 | |||
368 | err = _vnic_dev_cmd(vdev, cmd, wait); | ||
369 | |||
370 | *a0 = vdev->args[0]; | ||
371 | *a1 = vdev->args[1]; | ||
372 | |||
373 | return err; | ||
374 | } | ||
375 | |||
376 | void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf) | ||
377 | { | ||
378 | vdev->proxy = PROXY_BY_BDF; | ||
379 | vdev->proxy_index = bdf; | ||
380 | } | ||
381 | |||
382 | void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) | ||
383 | { | ||
384 | vdev->proxy = PROXY_NONE; | ||
385 | vdev->proxy_index = 0; | ||
386 | } | ||
387 | |||
388 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | ||
389 | u64 *a0, u64 *a1, int wait) | ||
390 | { | ||
391 | memset(vdev->args, 0, sizeof(vdev->args)); | ||
392 | |||
393 | switch (vdev->proxy) { | ||
394 | case PROXY_BY_BDF: | ||
395 | return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait); | ||
396 | case PROXY_NONE: | ||
397 | default: | ||
398 | return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait); | ||
399 | } | ||
400 | } | ||
401 | |||
316 | static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd) | 402 | static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd) |
317 | { | 403 | { |
318 | u64 a0 = (u32)cmd, a1 = 0; | 404 | u64 a0 = (u32)cmd, a1 = 0; |
@@ -431,6 +517,19 @@ int vnic_dev_enable(struct vnic_dev *vdev) | |||
431 | return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); | 517 | return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); |
432 | } | 518 | } |
433 | 519 | ||
520 | int vnic_dev_enable_wait(struct vnic_dev *vdev) | ||
521 | { | ||
522 | u64 a0 = 0, a1 = 0; | ||
523 | int wait = 1000; | ||
524 | int err; | ||
525 | |||
526 | err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); | ||
527 | if (err == ERR_ECMDUNKNOWN) | ||
528 | return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); | ||
529 | |||
530 | return err; | ||
531 | } | ||
532 | |||
434 | int vnic_dev_disable(struct vnic_dev *vdev) | 533 | int vnic_dev_disable(struct vnic_dev *vdev) |
435 | { | 534 | { |
436 | u64 a0 = 0, a1 = 0; | 535 | u64 a0 = 0, a1 = 0; |
@@ -486,6 +585,44 @@ int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) | |||
486 | return 0; | 585 | return 0; |
487 | } | 586 | } |
488 | 587 | ||
588 | int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg) | ||
589 | { | ||
590 | u64 a0 = (u32)arg, a1 = 0; | ||
591 | int wait = 1000; | ||
592 | int err; | ||
593 | |||
594 | err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait); | ||
595 | if (err == ERR_ECMDUNKNOWN) { | ||
596 | err = vnic_dev_soft_reset(vdev, arg); | ||
597 | if (err) | ||
598 | return err; | ||
599 | |||
600 | return vnic_dev_init(vdev, 0); | ||
601 | } | ||
602 | |||
603 | return err; | ||
604 | } | ||
605 | |||
606 | int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done) | ||
607 | { | ||
608 | u64 a0 = 0, a1 = 0; | ||
609 | int wait = 1000; | ||
610 | int err; | ||
611 | |||
612 | *done = 0; | ||
613 | |||
614 | err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait); | ||
615 | if (err) { | ||
616 | if (err == ERR_ECMDUNKNOWN) | ||
617 | return vnic_dev_soft_reset_done(vdev, done); | ||
618 | return err; | ||
619 | } | ||
620 | |||
621 | *done = (a0 == 0); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
489 | int vnic_dev_hang_notify(struct vnic_dev *vdev) | 626 | int vnic_dev_hang_notify(struct vnic_dev *vdev) |
490 | { | 627 | { |
491 | u64 a0, a1; | 628 | u64 a0, a1; |
@@ -512,7 +649,7 @@ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) | |||
512 | return 0; | 649 | return 0; |
513 | } | 650 | } |
514 | 651 | ||
515 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | 652 | int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, |
516 | int broadcast, int promisc, int allmulti) | 653 | int broadcast, int promisc, int allmulti) |
517 | { | 654 | { |
518 | u64 a0, a1 = 0; | 655 | u64 a0, a1 = 0; |
@@ -527,7 +664,29 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | |||
527 | 664 | ||
528 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); | 665 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); |
529 | if (err) | 666 | if (err) |
530 | printk(KERN_ERR "Can't set packet filter\n"); | 667 | pr_err("Can't set packet filter\n"); |
668 | |||
669 | return err; | ||
670 | } | ||
671 | |||
672 | int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, | ||
673 | int multicast, int broadcast, int promisc, int allmulti) | ||
674 | { | ||
675 | u64 a0, a1 = 0; | ||
676 | int wait = 1000; | ||
677 | int err; | ||
678 | |||
679 | a0 = (directed ? CMD_PFILTER_DIRECTED : 0) | | ||
680 | (multicast ? CMD_PFILTER_MULTICAST : 0) | | ||
681 | (broadcast ? CMD_PFILTER_BROADCAST : 0) | | ||
682 | (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | | ||
683 | (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); | ||
684 | |||
685 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); | ||
686 | if (err) | ||
687 | pr_err("Can't set packet filter\n"); | ||
688 | |||
689 | return err; | ||
531 | } | 690 | } |
532 | 691 | ||
533 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | 692 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) |
@@ -542,7 +701,7 @@ int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | |||
542 | 701 | ||
543 | err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); | 702 | err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); |
544 | if (err) | 703 | if (err) |
545 | printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err); | 704 | pr_err("Can't add addr [%pM], %d\n", addr, err); |
546 | 705 | ||
547 | return err; | 706 | return err; |
548 | } | 707 | } |
@@ -559,7 +718,21 @@ int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) | |||
559 | 718 | ||
560 | err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); | 719 | err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); |
561 | if (err) | 720 | if (err) |
562 | printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err); | 721 | pr_err("Can't del addr [%pM], %d\n", addr, err); |
722 | |||
723 | return err; | ||
724 | } | ||
725 | |||
726 | int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, | ||
727 | u8 ig_vlan_rewrite_mode) | ||
728 | { | ||
729 | u64 a0 = ig_vlan_rewrite_mode, a1 = 0; | ||
730 | int wait = 1000; | ||
731 | int err; | ||
732 | |||
733 | err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait); | ||
734 | if (err == ERR_ECMDUNKNOWN) | ||
735 | return 0; | ||
563 | 736 | ||
564 | return err; | 737 | return err; |
565 | } | 738 | } |
@@ -572,8 +745,7 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) | |||
572 | 745 | ||
573 | err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait); | 746 | err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait); |
574 | if (err) | 747 | if (err) |
575 | printk(KERN_ERR "Failed to raise INTR[%d], err %d\n", | 748 | pr_err("Failed to raise INTR[%d], err %d\n", intr, err); |
576 | intr, err); | ||
577 | 749 | ||
578 | return err; | 750 | return err; |
579 | } | 751 | } |
@@ -604,8 +776,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
604 | dma_addr_t notify_pa; | 776 | dma_addr_t notify_pa; |
605 | 777 | ||
606 | if (vdev->notify || vdev->notify_pa) { | 778 | if (vdev->notify || vdev->notify_pa) { |
607 | printk(KERN_ERR "notify block %p still allocated", | 779 | pr_err("notify block %p still allocated", vdev->notify); |
608 | vdev->notify); | ||
609 | return -EINVAL; | 780 | return -EINVAL; |
610 | } | 781 | } |
611 | 782 | ||
@@ -618,22 +789,25 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
618 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); | 789 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); |
619 | } | 790 | } |
620 | 791 | ||
621 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) | 792 | int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) |
622 | { | 793 | { |
623 | u64 a0, a1; | 794 | u64 a0, a1; |
624 | int wait = 1000; | 795 | int wait = 1000; |
796 | int err; | ||
625 | 797 | ||
626 | a0 = 0; /* paddr = 0 to unset notify buffer */ | 798 | a0 = 0; /* paddr = 0 to unset notify buffer */ |
627 | a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */ | 799 | a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */ |
628 | a1 += sizeof(struct vnic_devcmd_notify); | 800 | a1 += sizeof(struct vnic_devcmd_notify); |
629 | 801 | ||
630 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | 802 | err = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); |
631 | vdev->notify = NULL; | 803 | vdev->notify = NULL; |
632 | vdev->notify_pa = 0; | 804 | vdev->notify_pa = 0; |
633 | vdev->notify_sz = 0; | 805 | vdev->notify_sz = 0; |
806 | |||
807 | return err; | ||
634 | } | 808 | } |
635 | 809 | ||
636 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | 810 | int vnic_dev_notify_unset(struct vnic_dev *vdev) |
637 | { | 811 | { |
638 | if (vdev->notify) { | 812 | if (vdev->notify) { |
639 | pci_free_consistent(vdev->pdev, | 813 | pci_free_consistent(vdev->pdev, |
@@ -642,7 +816,7 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev) | |||
642 | vdev->notify_pa); | 816 | vdev->notify_pa); |
643 | } | 817 | } |
644 | 818 | ||
645 | vnic_dev_notify_unsetcmd(vdev); | 819 | return vnic_dev_notify_unsetcmd(vdev); |
646 | } | 820 | } |
647 | 821 | ||
648 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) | 822 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) |
@@ -672,13 +846,14 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) | |||
672 | int wait = 1000; | 846 | int wait = 1000; |
673 | int r = 0; | 847 | int r = 0; |
674 | 848 | ||
675 | if (vdev->cap_flags & VNIC_DEV_CAP_INIT) | 849 | if (vnic_dev_capable(vdev, CMD_INIT)) |
676 | r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); | 850 | r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); |
677 | else { | 851 | else { |
678 | vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait); | 852 | vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait); |
679 | if (a0 & CMD_INITF_DEFAULT_MAC) { | 853 | if (a0 & CMD_INITF_DEFAULT_MAC) { |
680 | // Emulate these for old CMD_INIT_v1 which | 854 | /* Emulate these for old CMD_INIT_v1 which |
681 | // didn't pass a0 so no CMD_INITF_*. | 855 | * didn't pass a0 so no CMD_INITF_*. |
856 | */ | ||
682 | vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); | 857 | vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); |
683 | vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); | 858 | vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); |
684 | } | 859 | } |
@@ -700,7 +875,7 @@ int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err) | |||
700 | 875 | ||
701 | *done = (a0 == 0); | 876 | *done = (a0 == 0); |
702 | 877 | ||
703 | *err = (a0 == 0) ? a1 : 0; | 878 | *err = (a0 == 0) ? (int)a1:0; |
704 | 879 | ||
705 | return 0; | 880 | return 0; |
706 | } | 881 | } |
@@ -738,9 +913,6 @@ int vnic_dev_deinit(struct vnic_dev *vdev) | |||
738 | 913 | ||
739 | int vnic_dev_link_status(struct vnic_dev *vdev) | 914 | int vnic_dev_link_status(struct vnic_dev *vdev) |
740 | { | 915 | { |
741 | if (vdev->linkstatus) | ||
742 | return *vdev->linkstatus; | ||
743 | |||
744 | if (!vnic_dev_notify_ready(vdev)) | 916 | if (!vnic_dev_notify_ready(vdev)) |
745 | return 0; | 917 | return 0; |
746 | 918 | ||
@@ -787,6 +959,14 @@ u32 vnic_dev_notify_status(struct vnic_dev *vdev) | |||
787 | return vdev->notify_copy.status; | 959 | return vdev->notify_copy.status; |
788 | } | 960 | } |
789 | 961 | ||
962 | u32 vnic_dev_uif(struct vnic_dev *vdev) | ||
963 | { | ||
964 | if (!vnic_dev_notify_ready(vdev)) | ||
965 | return 0; | ||
966 | |||
967 | return vdev->notify_copy.uif; | ||
968 | } | ||
969 | |||
790 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | 970 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, |
791 | enum vnic_dev_intr_mode intr_mode) | 971 | enum vnic_dev_intr_mode intr_mode) |
792 | { | 972 | { |
@@ -807,14 +987,9 @@ void vnic_dev_unregister(struct vnic_dev *vdev) | |||
807 | sizeof(struct vnic_devcmd_notify), | 987 | sizeof(struct vnic_devcmd_notify), |
808 | vdev->notify, | 988 | vdev->notify, |
809 | vdev->notify_pa); | 989 | vdev->notify_pa); |
810 | if (vdev->linkstatus) | ||
811 | pci_free_consistent(vdev->pdev, | ||
812 | sizeof(u32), | ||
813 | vdev->linkstatus, | ||
814 | vdev->linkstatus_pa); | ||
815 | if (vdev->stats) | 990 | if (vdev->stats) |
816 | pci_free_consistent(vdev->pdev, | 991 | pci_free_consistent(vdev->pdev, |
817 | sizeof(struct vnic_dev), | 992 | sizeof(struct vnic_stats), |
818 | vdev->stats, vdev->stats_pa); | 993 | vdev->stats, vdev->stats_pa); |
819 | if (vdev->fw_info) | 994 | if (vdev->fw_info) |
820 | pci_free_consistent(vdev->pdev, | 995 | pci_free_consistent(vdev->pdev, |
@@ -844,11 +1019,6 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | |||
844 | if (!vdev->devcmd) | 1019 | if (!vdev->devcmd) |
845 | goto err_out; | 1020 | goto err_out; |
846 | 1021 | ||
847 | vdev->cap_flags = 0; | ||
848 | |||
849 | if (vnic_dev_capable(vdev, CMD_INIT)) | ||
850 | vdev->cap_flags |= VNIC_DEV_CAP_INIT; | ||
851 | |||
852 | return vdev; | 1022 | return vdev; |
853 | 1023 | ||
854 | err_out: | 1024 | err_out: |
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index caccce36957b..3a61873138b6 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -41,6 +41,9 @@ static inline void writeq(u64 val, void __iomem *reg) | |||
41 | } | 41 | } |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #undef pr_fmt | ||
45 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
46 | |||
44 | enum vnic_dev_hw_version { | 47 | enum vnic_dev_hw_version { |
45 | VNIC_DEV_HW_VER_UNKNOWN, | 48 | VNIC_DEV_HW_VER_UNKNOWN, |
46 | VNIC_DEV_HW_VER_A1, | 49 | VNIC_DEV_HW_VER_A1, |
@@ -92,6 +95,8 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, | |||
92 | struct vnic_dev_ring *ring); | 95 | struct vnic_dev_ring *ring); |
93 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | 96 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
94 | u64 *a0, u64 *a1, int wait); | 97 | u64 *a0, u64 *a1, int wait); |
98 | void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf); | ||
99 | void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev); | ||
95 | int vnic_dev_fw_info(struct vnic_dev *vdev, | 100 | int vnic_dev_fw_info(struct vnic_dev *vdev, |
96 | struct vnic_devcmd_fw_info **fw_info); | 101 | struct vnic_devcmd_fw_info **fw_info); |
97 | int vnic_dev_hw_version(struct vnic_dev *vdev, | 102 | int vnic_dev_hw_version(struct vnic_dev *vdev, |
@@ -101,8 +106,10 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | |||
101 | int vnic_dev_stats_clear(struct vnic_dev *vdev); | 106 | int vnic_dev_stats_clear(struct vnic_dev *vdev); |
102 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); | 107 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); |
103 | int vnic_dev_hang_notify(struct vnic_dev *vdev); | 108 | int vnic_dev_hang_notify(struct vnic_dev *vdev); |
104 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | 109 | int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, |
105 | int broadcast, int promisc, int allmulti); | 110 | int broadcast, int promisc, int allmulti); |
111 | int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, | ||
112 | int multicast, int broadcast, int promisc, int allmulti); | ||
106 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); | 113 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); |
107 | int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); | 114 | int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); |
108 | int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); | 115 | int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); |
@@ -110,16 +117,18 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr); | |||
110 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, | 117 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, |
111 | void *notify_addr, dma_addr_t notify_pa, u16 intr); | 118 | void *notify_addr, dma_addr_t notify_pa, u16 intr); |
112 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); | 119 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); |
113 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); | 120 | int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); |
114 | void vnic_dev_notify_unset(struct vnic_dev *vdev); | 121 | int vnic_dev_notify_unset(struct vnic_dev *vdev); |
115 | int vnic_dev_link_status(struct vnic_dev *vdev); | 122 | int vnic_dev_link_status(struct vnic_dev *vdev); |
116 | u32 vnic_dev_port_speed(struct vnic_dev *vdev); | 123 | u32 vnic_dev_port_speed(struct vnic_dev *vdev); |
117 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); | 124 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); |
118 | u32 vnic_dev_mtu(struct vnic_dev *vdev); | 125 | u32 vnic_dev_mtu(struct vnic_dev *vdev); |
119 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); | 126 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); |
120 | u32 vnic_dev_notify_status(struct vnic_dev *vdev); | 127 | u32 vnic_dev_notify_status(struct vnic_dev *vdev); |
128 | u32 vnic_dev_uif(struct vnic_dev *vdev); | ||
121 | int vnic_dev_close(struct vnic_dev *vdev); | 129 | int vnic_dev_close(struct vnic_dev *vdev); |
122 | int vnic_dev_enable(struct vnic_dev *vdev); | 130 | int vnic_dev_enable(struct vnic_dev *vdev); |
131 | int vnic_dev_enable_wait(struct vnic_dev *vdev); | ||
123 | int vnic_dev_disable(struct vnic_dev *vdev); | 132 | int vnic_dev_disable(struct vnic_dev *vdev); |
124 | int vnic_dev_open(struct vnic_dev *vdev, int arg); | 133 | int vnic_dev_open(struct vnic_dev *vdev, int arg); |
125 | int vnic_dev_open_done(struct vnic_dev *vdev, int *done); | 134 | int vnic_dev_open_done(struct vnic_dev *vdev, int *done); |
@@ -129,10 +138,14 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len); | |||
129 | int vnic_dev_deinit(struct vnic_dev *vdev); | 138 | int vnic_dev_deinit(struct vnic_dev *vdev); |
130 | int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); | 139 | int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); |
131 | int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); | 140 | int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); |
141 | int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg); | ||
142 | int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done); | ||
132 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | 143 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, |
133 | enum vnic_dev_intr_mode intr_mode); | 144 | enum vnic_dev_intr_mode intr_mode); |
134 | enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); | 145 | enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); |
135 | void vnic_dev_unregister(struct vnic_dev *vdev); | 146 | void vnic_dev_unregister(struct vnic_dev *vdev); |
147 | int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, | ||
148 | u8 ig_vlan_rewrite_mode); | ||
136 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | 149 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, |
137 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, | 150 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, |
138 | unsigned int num_bars); | 151 | unsigned int num_bars); |
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index d78bbcc1fdf9..20661755df6b 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -98,6 +98,9 @@ enum vnic_devcmd_cmd { | |||
98 | /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */ | 98 | /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */ |
99 | CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7), | 99 | CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7), |
100 | 100 | ||
101 | /* set Rx packet filter for all: (u32)a0=filters (see CMD_PFILTER_*) */ | ||
102 | CMD_PACKET_FILTER_ALL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 7), | ||
103 | |||
101 | /* hang detection notification */ | 104 | /* hang detection notification */ |
102 | CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8), | 105 | CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8), |
103 | 106 | ||
@@ -171,6 +174,9 @@ enum vnic_devcmd_cmd { | |||
171 | /* enable virtual link */ | 174 | /* enable virtual link */ |
172 | CMD_ENABLE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28), | 175 | CMD_ENABLE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28), |
173 | 176 | ||
177 | /* enable virtual link, waiting variant. */ | ||
178 | CMD_ENABLE_WAIT = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28), | ||
179 | |||
174 | /* disable virtual link */ | 180 | /* disable virtual link */ |
175 | CMD_DISABLE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29), | 181 | CMD_DISABLE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29), |
176 | 182 | ||
@@ -211,6 +217,27 @@ enum vnic_devcmd_cmd { | |||
211 | * in: (u16)a0=interrupt number to assert | 217 | * in: (u16)a0=interrupt number to assert |
212 | */ | 218 | */ |
213 | CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38), | 219 | CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38), |
220 | |||
221 | /* initiate hangreset, like softreset after hang detected */ | ||
222 | CMD_HANG_RESET = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 39), | ||
223 | |||
224 | /* hangreset status: | ||
225 | * out: a0=0 reset complete, a0=1 reset in progress */ | ||
226 | CMD_HANG_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 40), | ||
227 | |||
228 | /* | ||
229 | * Set hw ingress packet vlan rewrite mode: | ||
230 | * in: (u32)a0=new vlan rewrite mode | ||
231 | * out: (u32)a0=old vlan rewrite mode */ | ||
232 | CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41), | ||
233 | |||
234 | /* | ||
235 | * in: (u16)a0=bdf of target vnic | ||
236 | * (u32)a1=cmd to proxy | ||
237 | * a2-a15=args to cmd in a1 | ||
238 | * out: (u32)a0=status of proxied cmd | ||
239 | * a1-a15=out args of proxied cmd */ | ||
240 | CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42), | ||
214 | }; | 241 | }; |
215 | 242 | ||
216 | /* flags for CMD_OPEN */ | 243 | /* flags for CMD_OPEN */ |
@@ -226,6 +253,12 @@ enum vnic_devcmd_cmd { | |||
226 | #define CMD_PFILTER_PROMISCUOUS 0x08 | 253 | #define CMD_PFILTER_PROMISCUOUS 0x08 |
227 | #define CMD_PFILTER_ALL_MULTICAST 0x10 | 254 | #define CMD_PFILTER_ALL_MULTICAST 0x10 |
228 | 255 | ||
256 | /* rewrite modes for CMD_IG_VLAN_REWRITE_MODE */ | ||
257 | #define IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK 0 | ||
258 | #define IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN 1 | ||
259 | #define IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN 2 | ||
260 | #define IG_VLAN_REWRITE_MODE_PASS_THRU 3 | ||
261 | |||
229 | enum vnic_devcmd_status { | 262 | enum vnic_devcmd_status { |
230 | STAT_NONE = 0, | 263 | STAT_NONE = 0, |
231 | STAT_BUSY = 1 << 0, /* cmd in progress */ | 264 | STAT_BUSY = 1 << 0, /* cmd in progress */ |
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h index 8eeb6758491b..3b3291248956 100644 --- a/drivers/net/enic/vnic_enet.h +++ b/drivers/net/enic/vnic_enet.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -35,6 +35,7 @@ struct vnic_enet_config { | |||
35 | u8 intr_mode; | 35 | u8 intr_mode; |
36 | char devname[16]; | 36 | char devname[16]; |
37 | u32 intr_timer_usec; | 37 | u32 intr_timer_usec; |
38 | u16 loop_tag; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | #define VENETF_TSO 0x1 /* TSO enabled */ | 41 | #define VENETF_TSO 0x1 /* TSO enabled */ |
@@ -48,5 +49,6 @@ struct vnic_enet_config { | |||
48 | #define VENETF_RSSHASH_TCPIPV6 0x100 /* Hash on TCP + IPv6 fields */ | 49 | #define VENETF_RSSHASH_TCPIPV6 0x100 /* Hash on TCP + IPv6 fields */ |
49 | #define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */ | 50 | #define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */ |
50 | #define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */ | 51 | #define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */ |
52 | #define VENETF_LOOP 0x800 /* Loopback enabled */ | ||
51 | 53 | ||
52 | #endif /* _VNIC_ENIC_H_ */ | 54 | #endif /* _VNIC_ENIC_H_ */ |
diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c index 3934309a9498..52ab61af2750 100644 --- a/drivers/net/enic/vnic_intr.c +++ b/drivers/net/enic/vnic_intr.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -39,8 +39,7 @@ int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr, | |||
39 | 39 | ||
40 | intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index); | 40 | intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index); |
41 | if (!intr->ctrl) { | 41 | if (!intr->ctrl) { |
42 | printk(KERN_ERR "Failed to hook INTR[%d].ctrl resource\n", | 42 | pr_err("Failed to hook INTR[%d].ctrl resource\n", index); |
43 | index); | ||
44 | return -EINVAL; | 43 | return -EINVAL; |
45 | } | 44 | } |
46 | 45 | ||
diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h index 2fe6c6339e3c..09dc0b73ff46 100644 --- a/drivers/net/enic/vnic_intr.h +++ b/drivers/net/enic/vnic_intr.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -61,7 +61,11 @@ static inline void vnic_intr_unmask(struct vnic_intr *intr) | |||
61 | static inline void vnic_intr_mask(struct vnic_intr *intr) | 61 | static inline void vnic_intr_mask(struct vnic_intr *intr) |
62 | { | 62 | { |
63 | iowrite32(1, &intr->ctrl->mask); | 63 | iowrite32(1, &intr->ctrl->mask); |
64 | (void)ioread32(&intr->ctrl->mask); | 64 | } |
65 | |||
66 | static inline int vnic_intr_masked(struct vnic_intr *intr) | ||
67 | { | ||
68 | return ioread32(&intr->ctrl->mask); | ||
65 | } | 69 | } |
66 | 70 | ||
67 | static inline void vnic_intr_return_credits(struct vnic_intr *intr, | 71 | static inline void vnic_intr_return_credits(struct vnic_intr *intr, |
diff --git a/drivers/net/enic/vnic_nic.h b/drivers/net/enic/vnic_nic.h index cf80ab46d582..995a50dd4c99 100644 --- a/drivers/net/enic/vnic_nic.h +++ b/drivers/net/enic/vnic_nic.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h index b61c22aec41a..810287beff14 100644 --- a/drivers/net/enic/vnic_resource.h +++ b/drivers/net/enic/vnic_resource.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c index cc580cfec41d..dbb2aca258b9 100644 --- a/drivers/net/enic/vnic_rq.c +++ b/drivers/net/enic/vnic_rq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -37,23 +37,23 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq) | |||
37 | vdev = rq->vdev; | 37 | vdev = rq->vdev; |
38 | 38 | ||
39 | for (i = 0; i < blks; i++) { | 39 | for (i = 0; i < blks; i++) { |
40 | rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ, GFP_ATOMIC); | 40 | rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC); |
41 | if (!rq->bufs[i]) { | 41 | if (!rq->bufs[i]) { |
42 | printk(KERN_ERR "Failed to alloc rq_bufs\n"); | 42 | pr_err("Failed to alloc rq_bufs\n"); |
43 | return -ENOMEM; | 43 | return -ENOMEM; |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | for (i = 0; i < blks; i++) { | 47 | for (i = 0; i < blks; i++) { |
48 | buf = rq->bufs[i]; | 48 | buf = rq->bufs[i]; |
49 | for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES; j++) { | 49 | for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES(count); j++) { |
50 | buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES + j; | 50 | buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES(count) + j; |
51 | buf->desc = (u8 *)rq->ring.descs + | 51 | buf->desc = (u8 *)rq->ring.descs + |
52 | rq->ring.desc_size * buf->index; | 52 | rq->ring.desc_size * buf->index; |
53 | if (buf->index + 1 == count) { | 53 | if (buf->index + 1 == count) { |
54 | buf->next = rq->bufs[0]; | 54 | buf->next = rq->bufs[0]; |
55 | break; | 55 | break; |
56 | } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES) { | 56 | } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES(count)) { |
57 | buf->next = rq->bufs[i + 1]; | 57 | buf->next = rq->bufs[i + 1]; |
58 | } else { | 58 | } else { |
59 | buf->next = buf + 1; | 59 | buf->next = buf + 1; |
@@ -94,7 +94,7 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, | |||
94 | 94 | ||
95 | rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index); | 95 | rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index); |
96 | if (!rq->ctrl) { | 96 | if (!rq->ctrl) { |
97 | printk(KERN_ERR "Failed to hook RQ[%d] resource\n", index); | 97 | pr_err("Failed to hook RQ[%d] resource\n", index); |
98 | return -EINVAL; | 98 | return -EINVAL; |
99 | } | 99 | } |
100 | 100 | ||
@@ -119,10 +119,11 @@ void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, | |||
119 | unsigned int error_interrupt_offset) | 119 | unsigned int error_interrupt_offset) |
120 | { | 120 | { |
121 | u64 paddr; | 121 | u64 paddr; |
122 | unsigned int count = rq->ring.desc_count; | ||
122 | 123 | ||
123 | paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET; | 124 | paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET; |
124 | writeq(paddr, &rq->ctrl->ring_base); | 125 | writeq(paddr, &rq->ctrl->ring_base); |
125 | iowrite32(rq->ring.desc_count, &rq->ctrl->ring_size); | 126 | iowrite32(count, &rq->ctrl->ring_size); |
126 | iowrite32(cq_index, &rq->ctrl->cq_index); | 127 | iowrite32(cq_index, &rq->ctrl->cq_index); |
127 | iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable); | 128 | iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable); |
128 | iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset); | 129 | iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset); |
@@ -132,8 +133,8 @@ void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, | |||
132 | iowrite32(posted_index, &rq->ctrl->posted_index); | 133 | iowrite32(posted_index, &rq->ctrl->posted_index); |
133 | 134 | ||
134 | rq->to_use = rq->to_clean = | 135 | rq->to_use = rq->to_clean = |
135 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES] | 136 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)] |
136 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES]; | 137 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)]; |
137 | } | 138 | } |
138 | 139 | ||
139 | void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, | 140 | void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, |
@@ -145,6 +146,11 @@ void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, | |||
145 | /* Use current fetch_index as the ring starting point */ | 146 | /* Use current fetch_index as the ring starting point */ |
146 | fetch_index = ioread32(&rq->ctrl->fetch_index); | 147 | fetch_index = ioread32(&rq->ctrl->fetch_index); |
147 | 148 | ||
149 | if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ | ||
150 | /* Hardware surprise removal: reset fetch_index */ | ||
151 | fetch_index = 0; | ||
152 | } | ||
153 | |||
148 | vnic_rq_init_start(rq, cq_index, | 154 | vnic_rq_init_start(rq, cq_index, |
149 | fetch_index, fetch_index, | 155 | fetch_index, fetch_index, |
150 | error_interrupt_enable, | 156 | error_interrupt_enable, |
@@ -174,7 +180,7 @@ int vnic_rq_disable(struct vnic_rq *rq) | |||
174 | udelay(10); | 180 | udelay(10); |
175 | } | 181 | } |
176 | 182 | ||
177 | printk(KERN_ERR "Failed to disable RQ[%d]\n", rq->index); | 183 | pr_err("Failed to disable RQ[%d]\n", rq->index); |
178 | 184 | ||
179 | return -ETIMEDOUT; | 185 | return -ETIMEDOUT; |
180 | } | 186 | } |
@@ -184,8 +190,7 @@ void vnic_rq_clean(struct vnic_rq *rq, | |||
184 | { | 190 | { |
185 | struct vnic_rq_buf *buf; | 191 | struct vnic_rq_buf *buf; |
186 | u32 fetch_index; | 192 | u32 fetch_index; |
187 | 193 | unsigned int count = rq->ring.desc_count; | |
188 | BUG_ON(ioread32(&rq->ctrl->enable)); | ||
189 | 194 | ||
190 | buf = rq->to_clean; | 195 | buf = rq->to_clean; |
191 | 196 | ||
@@ -199,9 +204,14 @@ void vnic_rq_clean(struct vnic_rq *rq, | |||
199 | 204 | ||
200 | /* Use current fetch_index as the ring starting point */ | 205 | /* Use current fetch_index as the ring starting point */ |
201 | fetch_index = ioread32(&rq->ctrl->fetch_index); | 206 | fetch_index = ioread32(&rq->ctrl->fetch_index); |
207 | |||
208 | if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ | ||
209 | /* Hardware surprise removal: reset fetch_index */ | ||
210 | fetch_index = 0; | ||
211 | } | ||
202 | rq->to_use = rq->to_clean = | 212 | rq->to_use = rq->to_clean = |
203 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES] | 213 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)] |
204 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES]; | 214 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)]; |
205 | iowrite32(fetch_index, &rq->ctrl->posted_index); | 215 | iowrite32(fetch_index, &rq->ctrl->posted_index); |
206 | 216 | ||
207 | vnic_dev_clear_desc_ring(&rq->ring); | 217 | vnic_dev_clear_desc_ring(&rq->ring); |
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h index 35e736cc2d88..2dc48f91abf7 100644 --- a/drivers/net/enic/vnic_rq.h +++ b/drivers/net/enic/vnic_rq.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008, 2009 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -52,12 +52,16 @@ struct vnic_rq_ctrl { | |||
52 | u32 pad10; | 52 | u32 pad10; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | /* Break the vnic_rq_buf allocations into blocks of 64 entries */ | 55 | /* Break the vnic_rq_buf allocations into blocks of 32/64 entries */ |
56 | #define VNIC_RQ_BUF_BLK_ENTRIES 64 | 56 | #define VNIC_RQ_BUF_MIN_BLK_ENTRIES 32 |
57 | #define VNIC_RQ_BUF_BLK_SZ \ | 57 | #define VNIC_RQ_BUF_DFLT_BLK_ENTRIES 64 |
58 | (VNIC_RQ_BUF_BLK_ENTRIES * sizeof(struct vnic_rq_buf)) | 58 | #define VNIC_RQ_BUF_BLK_ENTRIES(entries) \ |
59 | ((unsigned int)((entries < VNIC_RQ_BUF_DFLT_BLK_ENTRIES) ? \ | ||
60 | VNIC_RQ_BUF_MIN_BLK_ENTRIES : VNIC_RQ_BUF_DFLT_BLK_ENTRIES)) | ||
61 | #define VNIC_RQ_BUF_BLK_SZ(entries) \ | ||
62 | (VNIC_RQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_rq_buf)) | ||
59 | #define VNIC_RQ_BUF_BLKS_NEEDED(entries) \ | 63 | #define VNIC_RQ_BUF_BLKS_NEEDED(entries) \ |
60 | DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES) | 64 | DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES(entries)) |
61 | #define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096) | 65 | #define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096) |
62 | 66 | ||
63 | struct vnic_rq_buf { | 67 | struct vnic_rq_buf { |
diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h index 5fbb3c923bcd..f62d18719629 100644 --- a/drivers/net/enic/vnic_rss.h +++ b/drivers/net/enic/vnic_rss.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_stats.h b/drivers/net/enic/vnic_stats.h index 9ff9614d89b1..77750ec93954 100644 --- a/drivers/net/enic/vnic_stats.h +++ b/drivers/net/enic/vnic_stats.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c index d769772998c6..197c9d24af82 100644 --- a/drivers/net/enic/vnic_vic.c +++ b/drivers/net/enic/vnic_vic.c | |||
@@ -25,9 +25,13 @@ | |||
25 | 25 | ||
26 | struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type) | 26 | struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type) |
27 | { | 27 | { |
28 | struct vic_provinfo *vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); | 28 | struct vic_provinfo *vp; |
29 | 29 | ||
30 | if (!vp || !oui) | 30 | if (!oui) |
31 | return NULL; | ||
32 | |||
33 | vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); | ||
34 | if (!vp) | ||
31 | return NULL; | 35 | return NULL; |
32 | 36 | ||
33 | memcpy(vp->oui, oui, sizeof(vp->oui)); | 37 | memcpy(vp->oui, oui, sizeof(vp->oui)); |
diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h index 085c2a274cb1..7e46e5e8600f 100644 --- a/drivers/net/enic/vnic_vic.h +++ b/drivers/net/enic/vnic_vic.h | |||
@@ -44,7 +44,7 @@ struct vic_provinfo { | |||
44 | u16 length; | 44 | u16 length; |
45 | u8 value[0]; | 45 | u8 value[0]; |
46 | } tlv[0]; | 46 | } tlv[0]; |
47 | } __attribute__ ((packed)); | 47 | } __packed; |
48 | 48 | ||
49 | #define VIC_PROVINFO_MAX_DATA 1385 | 49 | #define VIC_PROVINFO_MAX_DATA 1385 |
50 | #define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \ | 50 | #define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \ |
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c index 1378afbdfe67..122e33bcc578 100644 --- a/drivers/net/enic/vnic_wq.c +++ b/drivers/net/enic/vnic_wq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -37,23 +37,23 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq) | |||
37 | vdev = wq->vdev; | 37 | vdev = wq->vdev; |
38 | 38 | ||
39 | for (i = 0; i < blks; i++) { | 39 | for (i = 0; i < blks; i++) { |
40 | wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ, GFP_ATOMIC); | 40 | wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC); |
41 | if (!wq->bufs[i]) { | 41 | if (!wq->bufs[i]) { |
42 | printk(KERN_ERR "Failed to alloc wq_bufs\n"); | 42 | pr_err("Failed to alloc wq_bufs\n"); |
43 | return -ENOMEM; | 43 | return -ENOMEM; |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | for (i = 0; i < blks; i++) { | 47 | for (i = 0; i < blks; i++) { |
48 | buf = wq->bufs[i]; | 48 | buf = wq->bufs[i]; |
49 | for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES; j++) { | 49 | for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES(count); j++) { |
50 | buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES + j; | 50 | buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES(count) + j; |
51 | buf->desc = (u8 *)wq->ring.descs + | 51 | buf->desc = (u8 *)wq->ring.descs + |
52 | wq->ring.desc_size * buf->index; | 52 | wq->ring.desc_size * buf->index; |
53 | if (buf->index + 1 == count) { | 53 | if (buf->index + 1 == count) { |
54 | buf->next = wq->bufs[0]; | 54 | buf->next = wq->bufs[0]; |
55 | break; | 55 | break; |
56 | } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES) { | 56 | } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES(count)) { |
57 | buf->next = wq->bufs[i + 1]; | 57 | buf->next = wq->bufs[i + 1]; |
58 | } else { | 58 | } else { |
59 | buf->next = buf + 1; | 59 | buf->next = buf + 1; |
@@ -94,7 +94,7 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, | |||
94 | 94 | ||
95 | wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index); | 95 | wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index); |
96 | if (!wq->ctrl) { | 96 | if (!wq->ctrl) { |
97 | printk(KERN_ERR "Failed to hook WQ[%d] resource\n", index); | 97 | pr_err("Failed to hook WQ[%d] resource\n", index); |
98 | return -EINVAL; | 98 | return -EINVAL; |
99 | } | 99 | } |
100 | 100 | ||
@@ -119,10 +119,11 @@ void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, | |||
119 | unsigned int error_interrupt_offset) | 119 | unsigned int error_interrupt_offset) |
120 | { | 120 | { |
121 | u64 paddr; | 121 | u64 paddr; |
122 | unsigned int count = wq->ring.desc_count; | ||
122 | 123 | ||
123 | paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET; | 124 | paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET; |
124 | writeq(paddr, &wq->ctrl->ring_base); | 125 | writeq(paddr, &wq->ctrl->ring_base); |
125 | iowrite32(wq->ring.desc_count, &wq->ctrl->ring_size); | 126 | iowrite32(count, &wq->ctrl->ring_size); |
126 | iowrite32(fetch_index, &wq->ctrl->fetch_index); | 127 | iowrite32(fetch_index, &wq->ctrl->fetch_index); |
127 | iowrite32(posted_index, &wq->ctrl->posted_index); | 128 | iowrite32(posted_index, &wq->ctrl->posted_index); |
128 | iowrite32(cq_index, &wq->ctrl->cq_index); | 129 | iowrite32(cq_index, &wq->ctrl->cq_index); |
@@ -131,8 +132,8 @@ void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, | |||
131 | iowrite32(0, &wq->ctrl->error_status); | 132 | iowrite32(0, &wq->ctrl->error_status); |
132 | 133 | ||
133 | wq->to_use = wq->to_clean = | 134 | wq->to_use = wq->to_clean = |
134 | &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES] | 135 | &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES(count)] |
135 | [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES]; | 136 | [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES(count)]; |
136 | } | 137 | } |
137 | 138 | ||
138 | void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, | 139 | void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, |
@@ -167,7 +168,7 @@ int vnic_wq_disable(struct vnic_wq *wq) | |||
167 | udelay(10); | 168 | udelay(10); |
168 | } | 169 | } |
169 | 170 | ||
170 | printk(KERN_ERR "Failed to disable WQ[%d]\n", wq->index); | 171 | pr_err("Failed to disable WQ[%d]\n", wq->index); |
171 | 172 | ||
172 | return -ETIMEDOUT; | 173 | return -ETIMEDOUT; |
173 | } | 174 | } |
@@ -177,8 +178,6 @@ void vnic_wq_clean(struct vnic_wq *wq, | |||
177 | { | 178 | { |
178 | struct vnic_wq_buf *buf; | 179 | struct vnic_wq_buf *buf; |
179 | 180 | ||
180 | BUG_ON(ioread32(&wq->ctrl->enable)); | ||
181 | |||
182 | buf = wq->to_clean; | 181 | buf = wq->to_clean; |
183 | 182 | ||
184 | while (vnic_wq_desc_used(wq) > 0) { | 183 | while (vnic_wq_desc_used(wq) > 0) { |
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h index 9c34d41a887e..94ac4621acc5 100644 --- a/drivers/net/enic/vnic_wq.h +++ b/drivers/net/enic/vnic_wq.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |
@@ -60,12 +60,16 @@ struct vnic_wq_buf { | |||
60 | void *desc; | 60 | void *desc; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* Break the vnic_wq_buf allocations into blocks of 64 entries */ | 63 | /* Break the vnic_wq_buf allocations into blocks of 32/64 entries */ |
64 | #define VNIC_WQ_BUF_BLK_ENTRIES 64 | 64 | #define VNIC_WQ_BUF_MIN_BLK_ENTRIES 32 |
65 | #define VNIC_WQ_BUF_BLK_SZ \ | 65 | #define VNIC_WQ_BUF_DFLT_BLK_ENTRIES 64 |
66 | (VNIC_WQ_BUF_BLK_ENTRIES * sizeof(struct vnic_wq_buf)) | 66 | #define VNIC_WQ_BUF_BLK_ENTRIES(entries) \ |
67 | ((unsigned int)((entries < VNIC_WQ_BUF_DFLT_BLK_ENTRIES) ? \ | ||
68 | VNIC_WQ_BUF_MIN_BLK_ENTRIES : VNIC_WQ_BUF_DFLT_BLK_ENTRIES)) | ||
69 | #define VNIC_WQ_BUF_BLK_SZ(entries) \ | ||
70 | (VNIC_WQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_wq_buf)) | ||
67 | #define VNIC_WQ_BUF_BLKS_NEEDED(entries) \ | 71 | #define VNIC_WQ_BUF_BLKS_NEEDED(entries) \ |
68 | DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES) | 72 | DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES(entries)) |
69 | #define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096) | 73 | #define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096) |
70 | 74 | ||
71 | struct vnic_wq { | 75 | struct vnic_wq { |
diff --git a/drivers/net/enic/wq_enet_desc.h b/drivers/net/enic/wq_enet_desc.h index 483596c2d8bf..c7021e3a631f 100644 --- a/drivers/net/enic/wq_enet_desc.h +++ b/drivers/net/enic/wq_enet_desc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | 3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you may redistribute it and/or modify | 5 | * This program is free software; you may redistribute it and/or modify |