aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cisco
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-05-14 01:20:35 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-11 05:42:06 -0400
commita6a5580c4d90788d67a77c689d3ab22aa5eecfc3 (patch)
tree89080daf4b0b4939daadb807f19eca3e977d42cb /drivers/net/ethernet/cisco
parent9aa3283595451ca093500ff0977b106e1f465586 (diff)
enic: Move the Cisco driver
Move the Cisco driver into drivers/net/ethernet/cisco/ and make the necessary Kconfig and Makefile changes. CC: Christian Benvenuti <benve@cisco.com> CC: Vasanthy Kolluri <vkolluri@cisco.com> CC: Roopa Prabhu <roprabhu@cisco.com> CC: David Wang <dwang2@cisco.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/cisco')
-rw-r--r--drivers/net/ethernet/cisco/Kconfig22
-rw-r--r--drivers/net/ethernet/cisco/Makefile5
-rw-r--r--drivers/net/ethernet/cisco/enic/Kconfig9
-rw-r--r--drivers/net/ethernet/cisco/enic/Makefile5
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_desc.h80
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_enet_desc.h185
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h124
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.c286
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.h45
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c2513
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.c264
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.h27
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_res.c384
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_res.h148
-rw-r--r--drivers/net/ethernet/cisco/enic/rq_enet_desc.h60
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_cq.c91
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_cq.h114
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.c1003
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.h133
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_devcmd.h450
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_enet.h57
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_intr.c68
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_intr.h111
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_nic.h72
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_resource.h76
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.c221
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.h209
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rss.h40
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_stats.h70
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_vic.c79
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_vic.h83
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_wq.c200
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_wq.h165
-rw-r--r--drivers/net/ethernet/cisco/enic/wq_enet_desc.h98
34 files changed, 7497 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cisco/Kconfig b/drivers/net/ethernet/cisco/Kconfig
new file mode 100644
index 000000000000..bbd534880670
--- /dev/null
+++ b/drivers/net/ethernet/cisco/Kconfig
@@ -0,0 +1,22 @@
1#
2# Cisco device configuration
3#
4
5config NET_VENDOR_CISCO
6 bool "Cisco devices"
7 depends on PCI && INET
8 ---help---
9 If you have a network (Ethernet) card belonging to this class, say Y
10 and read the Ethernet-HOWTO, available from
11 <http://www.tldp.org/docs.html#howto>.
12
13 Note that the answer to this question doesn't directly affect the
14 kernel: saying N will just cause the configurator to skip all
15 the questions about Cisco cards. If you say Y, you will be asked for
16 your specific card in the following questions.
17
18if NET_VENDOR_CISCO
19
20source "drivers/net/ethernet/cisco/enic/Kconfig"
21
22endif # NET_VENDOR_CISCO
diff --git a/drivers/net/ethernet/cisco/Makefile b/drivers/net/ethernet/cisco/Makefile
new file mode 100644
index 000000000000..6c7437bc4a92
--- /dev/null
+++ b/drivers/net/ethernet/cisco/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the Cisco device drivers.
3#
4
5obj-$(CONFIG_ENIC) += enic/
diff --git a/drivers/net/ethernet/cisco/enic/Kconfig b/drivers/net/ethernet/cisco/enic/Kconfig
new file mode 100644
index 000000000000..9cc706a6cffd
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/Kconfig
@@ -0,0 +1,9 @@
1#
2# Cisco device configuration
3#
4
5config ENIC
6 tristate "Cisco VIC Ethernet NIC Support"
7 depends on PCI && INET
8 ---help---
9 This enables the support for the Cisco VIC Ethernet card.
diff --git a/drivers/net/ethernet/cisco/enic/Makefile b/drivers/net/ethernet/cisco/enic/Makefile
new file mode 100644
index 000000000000..9d4974bba247
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_ENIC) := enic.o
2
3enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
4 enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o
5
diff --git a/drivers/net/ethernet/cisco/enic/cq_desc.h b/drivers/net/ethernet/cisco/enic/cq_desc.h
new file mode 100644
index 000000000000..d6dd1b4edf6e
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/cq_desc.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _CQ_DESC_H_
21#define _CQ_DESC_H_
22
23/*
24 * Completion queue descriptor types
25 */
26enum cq_desc_types {
27 CQ_DESC_TYPE_WQ_ENET = 0,
28 CQ_DESC_TYPE_DESC_COPY = 1,
29 CQ_DESC_TYPE_WQ_EXCH = 2,
30 CQ_DESC_TYPE_RQ_ENET = 3,
31 CQ_DESC_TYPE_RQ_FCP = 4,
32};
33
34/* Completion queue descriptor: 16B
35 *
36 * All completion queues have this basic layout. The
37 * type_specfic area is unique for each completion
38 * queue type.
39 */
40struct cq_desc {
41 __le16 completed_index;
42 __le16 q_number;
43 u8 type_specfic[11];
44 u8 type_color;
45};
46
47#define CQ_DESC_TYPE_BITS 4
48#define CQ_DESC_TYPE_MASK ((1 << CQ_DESC_TYPE_BITS) - 1)
49#define CQ_DESC_COLOR_MASK 1
50#define CQ_DESC_COLOR_SHIFT 7
51#define CQ_DESC_Q_NUM_BITS 10
52#define CQ_DESC_Q_NUM_MASK ((1 << CQ_DESC_Q_NUM_BITS) - 1)
53#define CQ_DESC_COMP_NDX_BITS 12
54#define CQ_DESC_COMP_NDX_MASK ((1 << CQ_DESC_COMP_NDX_BITS) - 1)
55
56static inline void cq_desc_dec(const struct cq_desc *desc_arg,
57 u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
58{
59 const struct cq_desc *desc = desc_arg;
60 const u8 type_color = desc->type_color;
61
62 *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
63
64 /*
65 * Make sure color bit is read from desc *before* other fields
66 * are read from desc. Hardware guarantees color bit is last
67 * bit (byte) written. Adding the rmb() prevents the compiler
68 * and/or CPU from reordering the reads which would potentially
69 * result in reading stale values.
70 */
71
72 rmb();
73
74 *type = type_color & CQ_DESC_TYPE_MASK;
75 *q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
76 *completed_index = le16_to_cpu(desc->completed_index) &
77 CQ_DESC_COMP_NDX_MASK;
78}
79
80#endif /* _CQ_DESC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
new file mode 100644
index 000000000000..c2c0680a1146
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
@@ -0,0 +1,185 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _CQ_ENET_DESC_H_
21#define _CQ_ENET_DESC_H_
22
23#include "cq_desc.h"
24
25/* Ethernet completion queue descriptor: 16B */
26struct cq_enet_wq_desc {
27 __le16 completed_index;
28 __le16 q_number;
29 u8 reserved[11];
30 u8 type_color;
31};
32
33static inline void cq_enet_wq_desc_dec(struct cq_enet_wq_desc *desc,
34 u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
35{
36 cq_desc_dec((struct cq_desc *)desc, type,
37 color, q_number, completed_index);
38}
39
40/* Completion queue descriptor: Ethernet receive queue, 16B */
41struct cq_enet_rq_desc {
42 __le16 completed_index_flags;
43 __le16 q_number_rss_type_flags;
44 __le32 rss_hash;
45 __le16 bytes_written_flags;
46 __le16 vlan;
47 __le16 checksum_fcoe;
48 u8 flags;
49 u8 type_color;
50};
51
52#define CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT (0x1 << 12)
53#define CQ_ENET_RQ_DESC_FLAGS_FCOE (0x1 << 13)
54#define CQ_ENET_RQ_DESC_FLAGS_EOP (0x1 << 14)
55#define CQ_ENET_RQ_DESC_FLAGS_SOP (0x1 << 15)
56
57#define CQ_ENET_RQ_DESC_RSS_TYPE_BITS 4
58#define CQ_ENET_RQ_DESC_RSS_TYPE_MASK \
59 ((1 << CQ_ENET_RQ_DESC_RSS_TYPE_BITS) - 1)
60#define CQ_ENET_RQ_DESC_RSS_TYPE_NONE 0
61#define CQ_ENET_RQ_DESC_RSS_TYPE_IPv4 1
62#define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4 2
63#define CQ_ENET_RQ_DESC_RSS_TYPE_IPv6 3
64#define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6 4
65#define CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX 5
66#define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX 6
67
68#define CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC (0x1 << 14)
69
70#define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS 14
71#define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \
72 ((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1)
73#define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
74#define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
75
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
86#define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \
87 ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1)
88#define CQ_ENET_RQ_DESC_FCOE_EOF_BITS 8
89#define CQ_ENET_RQ_DESC_FCOE_EOF_MASK \
90 ((1 << CQ_ENET_RQ_DESC_FCOE_EOF_BITS) - 1)
91#define CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT 8
92
93#define CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK (0x1 << 0)
94#define CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK (0x1 << 0)
95#define CQ_ENET_RQ_DESC_FLAGS_UDP (0x1 << 1)
96#define CQ_ENET_RQ_DESC_FCOE_ENC_ERROR (0x1 << 1)
97#define CQ_ENET_RQ_DESC_FLAGS_TCP (0x1 << 2)
98#define CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK (0x1 << 3)
99#define CQ_ENET_RQ_DESC_FLAGS_IPV6 (0x1 << 4)
100#define CQ_ENET_RQ_DESC_FLAGS_IPV4 (0x1 << 5)
101#define CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT (0x1 << 6)
102#define CQ_ENET_RQ_DESC_FLAGS_FCS_OK (0x1 << 7)
103
104static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
105 u8 *type, u8 *color, u16 *q_number, u16 *completed_index,
106 u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
107 u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error,
108 u8 *vlan_stripped, u16 *vlan_tci, u16 *checksum, u8 *fcoe_sof,
109 u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof,
110 u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok,
111 u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok)
112{
113 u16 completed_index_flags;
114 u16 q_number_rss_type_flags;
115 u16 bytes_written_flags;
116
117 cq_desc_dec((struct cq_desc *)desc, type,
118 color, q_number, completed_index);
119
120 completed_index_flags = le16_to_cpu(desc->completed_index_flags);
121 q_number_rss_type_flags =
122 le16_to_cpu(desc->q_number_rss_type_flags);
123 bytes_written_flags = le16_to_cpu(desc->bytes_written_flags);
124
125 *ingress_port = (completed_index_flags &
126 CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT) ? 1 : 0;
127 *fcoe = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_FCOE) ?
128 1 : 0;
129 *eop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_EOP) ?
130 1 : 0;
131 *sop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_SOP) ?
132 1 : 0;
133
134 *rss_type = (u8)((q_number_rss_type_flags >> CQ_DESC_Q_NUM_BITS) &
135 CQ_ENET_RQ_DESC_RSS_TYPE_MASK);
136 *csum_not_calc = (q_number_rss_type_flags &
137 CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ? 1 : 0;
138
139 *rss_hash = le32_to_cpu(desc->rss_hash);
140
141 *bytes_written = bytes_written_flags &
142 CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
143 *packet_error = (bytes_written_flags &
144 CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ? 1 : 0;
145 *vlan_stripped = (bytes_written_flags &
146 CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0;
147
148 /*
149 * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12)
150 */
151 *vlan_tci = le16_to_cpu(desc->vlan);
152
153 if (*fcoe) {
154 *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) &
155 CQ_ENET_RQ_DESC_FCOE_SOF_MASK);
156 *fcoe_fc_crc_ok = (desc->flags &
157 CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0;
158 *fcoe_enc_error = (desc->flags &
159 CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0;
160 *fcoe_eof = (u8)((desc->checksum_fcoe >>
161 CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) &
162 CQ_ENET_RQ_DESC_FCOE_EOF_MASK);
163 *checksum = 0;
164 } else {
165 *fcoe_sof = 0;
166 *fcoe_fc_crc_ok = 0;
167 *fcoe_enc_error = 0;
168 *fcoe_eof = 0;
169 *checksum = le16_to_cpu(desc->checksum_fcoe);
170 }
171
172 *tcp_udp_csum_ok =
173 (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ? 1 : 0;
174 *udp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_UDP) ? 1 : 0;
175 *tcp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP) ? 1 : 0;
176 *ipv4_csum_ok =
177 (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ? 1 : 0;
178 *ipv6 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV6) ? 1 : 0;
179 *ipv4 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4) ? 1 : 0;
180 *ipv4_fragment =
181 (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT) ? 1 : 0;
182 *fcs_ok = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ? 1 : 0;
183}
184
185#endif /* _CQ_ENET_DESC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
new file mode 100644
index 000000000000..ce76d9a8ca6e
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -0,0 +1,124 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _ENIC_H_
21#define _ENIC_H_
22
23#include "vnic_enet.h"
24#include "vnic_dev.h"
25#include "vnic_wq.h"
26#include "vnic_rq.h"
27#include "vnic_cq.h"
28#include "vnic_intr.h"
29#include "vnic_stats.h"
30#include "vnic_nic.h"
31#include "vnic_rss.h"
32
33#define DRV_NAME "enic"
34#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
35#define DRV_VERSION "2.1.1.24"
36#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
37
38#define ENIC_BARS_MAX 6
39
40#define ENIC_WQ_MAX 1
41#define ENIC_RQ_MAX 1
42#define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX)
43#define ENIC_INTR_MAX (ENIC_CQ_MAX + 2)
44
45struct enic_msix_entry {
46 int requested;
47 char devname[IFNAMSIZ];
48 irqreturn_t (*isr)(int, void *);
49 void *devid;
50};
51
52#define ENIC_PORT_REQUEST_APPLIED (1 << 0)
53#define ENIC_SET_REQUEST (1 << 1)
54#define ENIC_SET_NAME (1 << 2)
55#define ENIC_SET_INSTANCE (1 << 3)
56#define ENIC_SET_HOST (1 << 4)
57
58struct enic_port_profile {
59 u32 set;
60 u8 request;
61 char name[PORT_PROFILE_MAX];
62 u8 instance_uuid[PORT_UUID_MAX];
63 u8 host_uuid[PORT_UUID_MAX];
64 u8 vf_mac[ETH_ALEN];
65 u8 mac_addr[ETH_ALEN];
66};
67
68/* Per-instance private data structure */
69struct enic {
70 struct net_device *netdev;
71 struct pci_dev *pdev;
72 struct vnic_enet_config config;
73 struct vnic_dev_bar bar[ENIC_BARS_MAX];
74 struct vnic_dev *vdev;
75 struct timer_list notify_timer;
76 struct work_struct reset;
77 struct work_struct change_mtu_work;
78 struct msix_entry msix_entry[ENIC_INTR_MAX];
79 struct enic_msix_entry msix[ENIC_INTR_MAX];
80 u32 msg_enable;
81 spinlock_t devcmd_lock;
82 u8 mac_addr[ETH_ALEN];
83 u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
84 u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
85 unsigned int flags;
86 unsigned int mc_count;
87 unsigned int uc_count;
88 u32 port_mtu;
89 u32 rx_coalesce_usecs;
90 u32 tx_coalesce_usecs;
91 struct enic_port_profile pp;
92
93 /* work queue cache line section */
94 ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
95 spinlock_t wq_lock[ENIC_WQ_MAX];
96 unsigned int wq_count;
97 u16 loop_enable;
98 u16 loop_tag;
99
100 /* receive queue cache line section */
101 ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX];
102 unsigned int rq_count;
103 u64 rq_truncated_pkts;
104 u64 rq_bad_fcs;
105 struct napi_struct napi[ENIC_RQ_MAX];
106
107 /* interrupt resource cache line section */
108 ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
109 unsigned int intr_count;
110 u32 __iomem *legacy_pba; /* memory-mapped */
111
112 /* completion queue cache line section */
113 ____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX];
114 unsigned int cq_count;
115};
116
117static inline struct device *enic_get_dev(struct enic *enic)
118{
119 return &(enic->pdev->dev);
120}
121
122void enic_reset_addr_lists(struct enic *enic);
123
124#endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.c b/drivers/net/ethernet/cisco/enic/enic_dev.c
new file mode 100644
index 000000000000..fd6247b3c0ee
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.c
@@ -0,0 +1,286 @@
1/*
2 * Copyright 2011 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#include <linux/pci.h>
20#include <linux/etherdevice.h>
21
22#include "vnic_dev.h"
23#include "vnic_vic.h"
24#include "enic_res.h"
25#include "enic.h"
26#include "enic_dev.h"
27
28int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info)
29{
30 int err;
31
32 spin_lock(&enic->devcmd_lock);
33 err = vnic_dev_fw_info(enic->vdev, fw_info);
34 spin_unlock(&enic->devcmd_lock);
35
36 return err;
37}
38
39int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
40{
41 int err;
42
43 spin_lock(&enic->devcmd_lock);
44 err = vnic_dev_stats_dump(enic->vdev, vstats);
45 spin_unlock(&enic->devcmd_lock);
46
47 return err;
48}
49
50int enic_dev_add_station_addr(struct enic *enic)
51{
52 int err;
53
54 if (!is_valid_ether_addr(enic->netdev->dev_addr))
55 return -EADDRNOTAVAIL;
56
57 spin_lock(&enic->devcmd_lock);
58 err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
59 spin_unlock(&enic->devcmd_lock);
60
61 return err;
62}
63
64int enic_dev_del_station_addr(struct enic *enic)
65{
66 int err;
67
68 if (!is_valid_ether_addr(enic->netdev->dev_addr))
69 return -EADDRNOTAVAIL;
70
71 spin_lock(&enic->devcmd_lock);
72 err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
73 spin_unlock(&enic->devcmd_lock);
74
75 return err;
76}
77
78int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
79 int broadcast, int promisc, int allmulti)
80{
81 int err;
82
83 spin_lock(&enic->devcmd_lock);
84 err = vnic_dev_packet_filter(enic->vdev, directed,
85 multicast, broadcast, promisc, allmulti);
86 spin_unlock(&enic->devcmd_lock);
87
88 return err;
89}
90
91int enic_dev_add_addr(struct enic *enic, u8 *addr)
92{
93 int err;
94
95 spin_lock(&enic->devcmd_lock);
96 err = vnic_dev_add_addr(enic->vdev, addr);
97 spin_unlock(&enic->devcmd_lock);
98
99 return err;
100}
101
102int enic_dev_del_addr(struct enic *enic, u8 *addr)
103{
104 int err;
105
106 spin_lock(&enic->devcmd_lock);
107 err = vnic_dev_del_addr(enic->vdev, addr);
108 spin_unlock(&enic->devcmd_lock);
109
110 return err;
111}
112
113int enic_dev_notify_unset(struct enic *enic)
114{
115 int err;
116
117 spin_lock(&enic->devcmd_lock);
118 err = vnic_dev_notify_unset(enic->vdev);
119 spin_unlock(&enic->devcmd_lock);
120
121 return err;
122}
123
124int enic_dev_hang_notify(struct enic *enic)
125{
126 int err;
127
128 spin_lock(&enic->devcmd_lock);
129 err = vnic_dev_hang_notify(enic->vdev);
130 spin_unlock(&enic->devcmd_lock);
131
132 return err;
133}
134
135int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
136{
137 int err;
138
139 spin_lock(&enic->devcmd_lock);
140 err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
141 IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
142 spin_unlock(&enic->devcmd_lock);
143
144 return err;
145}
146
147int enic_dev_enable(struct enic *enic)
148{
149 int err;
150
151 spin_lock(&enic->devcmd_lock);
152 err = vnic_dev_enable_wait(enic->vdev);
153 spin_unlock(&enic->devcmd_lock);
154
155 return err;
156}
157
158int enic_dev_disable(struct enic *enic)
159{
160 int err;
161
162 spin_lock(&enic->devcmd_lock);
163 err = vnic_dev_disable(enic->vdev);
164 spin_unlock(&enic->devcmd_lock);
165
166 return err;
167}
168
169int enic_dev_intr_coal_timer_info(struct enic *enic)
170{
171 int err;
172
173 spin_lock(&enic->devcmd_lock);
174 err = vnic_dev_intr_coal_timer_info(enic->vdev);
175 spin_unlock(&enic->devcmd_lock);
176
177 return err;
178}
179
180int enic_vnic_dev_deinit(struct enic *enic)
181{
182 int err;
183
184 spin_lock(&enic->devcmd_lock);
185 err = vnic_dev_deinit(enic->vdev);
186 spin_unlock(&enic->devcmd_lock);
187
188 return err;
189}
190
191int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
192{
193 int err;
194
195 spin_lock(&enic->devcmd_lock);
196 err = vnic_dev_init_prov2(enic->vdev,
197 (u8 *)vp, vic_provinfo_size(vp));
198 spin_unlock(&enic->devcmd_lock);
199
200 return err;
201}
202
203int enic_dev_deinit_done(struct enic *enic, int *status)
204{
205 int err;
206
207 spin_lock(&enic->devcmd_lock);
208 err = vnic_dev_deinit_done(enic->vdev, status);
209 spin_unlock(&enic->devcmd_lock);
210
211 return err;
212}
213
214/* rtnl lock is held */
215void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
216{
217 struct enic *enic = netdev_priv(netdev);
218
219 spin_lock(&enic->devcmd_lock);
220 enic_add_vlan(enic, vid);
221 spin_unlock(&enic->devcmd_lock);
222}
223
224/* rtnl lock is held */
225void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
226{
227 struct enic *enic = netdev_priv(netdev);
228
229 spin_lock(&enic->devcmd_lock);
230 enic_del_vlan(enic, vid);
231 spin_unlock(&enic->devcmd_lock);
232}
233
234int enic_dev_enable2(struct enic *enic, int active)
235{
236 int err;
237
238 spin_lock(&enic->devcmd_lock);
239 err = vnic_dev_enable2(enic->vdev, active);
240 spin_unlock(&enic->devcmd_lock);
241
242 return err;
243}
244
245int enic_dev_enable2_done(struct enic *enic, int *status)
246{
247 int err;
248
249 spin_lock(&enic->devcmd_lock);
250 err = vnic_dev_enable2_done(enic->vdev, status);
251 spin_unlock(&enic->devcmd_lock);
252
253 return err;
254}
255
256int enic_dev_status_to_errno(int devcmd_status)
257{
258 switch (devcmd_status) {
259 case ERR_SUCCESS:
260 return 0;
261 case ERR_EINVAL:
262 return -EINVAL;
263 case ERR_EFAULT:
264 return -EFAULT;
265 case ERR_EPERM:
266 return -EPERM;
267 case ERR_EBUSY:
268 return -EBUSY;
269 case ERR_ECMDUNKNOWN:
270 case ERR_ENOTSUPPORTED:
271 return -EOPNOTSUPP;
272 case ERR_EBADSTATE:
273 return -EINVAL;
274 case ERR_ENOMEM:
275 return -ENOMEM;
276 case ERR_ETIMEDOUT:
277 return -ETIMEDOUT;
278 case ERR_ELINKDOWN:
279 return -ENETDOWN;
280 case ERR_EINPROGRESS:
281 return -EINPROGRESS;
282 case ERR_EMAXRES:
283 default:
284 return (devcmd_status < 0) ? devcmd_status : -1;
285 }
286}
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.h b/drivers/net/ethernet/cisco/enic/enic_dev.h
new file mode 100644
index 000000000000..ff8e87fdfc1d
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright 2011 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef _ENIC_DEV_H_
20#define _ENIC_DEV_H_
21
22int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info);
23int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats);
24int enic_dev_add_station_addr(struct enic *enic);
25int enic_dev_del_station_addr(struct enic *enic);
26int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
27 int broadcast, int promisc, int allmulti);
28int enic_dev_add_addr(struct enic *enic, u8 *addr);
29int enic_dev_del_addr(struct enic *enic, u8 *addr);
30void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
31void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
32int enic_dev_notify_unset(struct enic *enic);
33int enic_dev_hang_notify(struct enic *enic);
34int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
35int enic_dev_enable(struct enic *enic);
36int enic_dev_disable(struct enic *enic);
37int enic_dev_intr_coal_timer_info(struct enic *enic);
38int enic_vnic_dev_deinit(struct enic *enic);
39int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
40int enic_dev_deinit_done(struct enic *enic, int *status);
41int enic_dev_enable2(struct enic *enic, int arg);
42int enic_dev_enable2_done(struct enic *enic, int *status);
43int enic_dev_status_to_errno(int devcmd_status);
44
45#endif /* _ENIC_DEV_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
new file mode 100644
index 000000000000..67a27cd304dd
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -0,0 +1,2513 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/string.h>
23#include <linux/errno.h>
24#include <linux/types.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/workqueue.h>
28#include <linux/pci.h>
29#include <linux/netdevice.h>
30#include <linux/etherdevice.h>
31#include <linux/if_ether.h>
32#include <linux/if_vlan.h>
33#include <linux/ethtool.h>
34#include <linux/in.h>
35#include <linux/ip.h>
36#include <linux/ipv6.h>
37#include <linux/tcp.h>
38#include <linux/rtnetlink.h>
39#include <linux/prefetch.h>
40#include <net/ip6_checksum.h>
41
42#include "cq_enet_desc.h"
43#include "vnic_dev.h"
44#include "vnic_intr.h"
45#include "vnic_stats.h"
46#include "vnic_vic.h"
47#include "enic_res.h"
48#include "enic.h"
49#include "enic_dev.h"
50#include "enic_pp.h"
51
52#define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ)
53#define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS)
54#define MAX_TSO (1 << 16)
55#define ENIC_DESC_MAX_SPLITS (MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1)
56
57#define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
58#define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */
59
60/* Supported devices */
61static DEFINE_PCI_DEVICE_TABLE(enic_id_table) = {
62 { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
63 { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_DYN) },
64 { 0, } /* end of table */
65};
66
67MODULE_DESCRIPTION(DRV_DESCRIPTION);
68MODULE_AUTHOR("Scott Feldman <scofeldm@cisco.com>");
69MODULE_LICENSE("GPL");
70MODULE_VERSION(DRV_VERSION);
71MODULE_DEVICE_TABLE(pci, enic_id_table);
72
73struct enic_stat {
74 char name[ETH_GSTRING_LEN];
75 unsigned int offset;
76};
77
78#define ENIC_TX_STAT(stat) \
79 { .name = #stat, .offset = offsetof(struct vnic_tx_stats, stat) / 8 }
80#define ENIC_RX_STAT(stat) \
81 { .name = #stat, .offset = offsetof(struct vnic_rx_stats, stat) / 8 }
82
83static const struct enic_stat enic_tx_stats[] = {
84 ENIC_TX_STAT(tx_frames_ok),
85 ENIC_TX_STAT(tx_unicast_frames_ok),
86 ENIC_TX_STAT(tx_multicast_frames_ok),
87 ENIC_TX_STAT(tx_broadcast_frames_ok),
88 ENIC_TX_STAT(tx_bytes_ok),
89 ENIC_TX_STAT(tx_unicast_bytes_ok),
90 ENIC_TX_STAT(tx_multicast_bytes_ok),
91 ENIC_TX_STAT(tx_broadcast_bytes_ok),
92 ENIC_TX_STAT(tx_drops),
93 ENIC_TX_STAT(tx_errors),
94 ENIC_TX_STAT(tx_tso),
95};
96
97static const struct enic_stat enic_rx_stats[] = {
98 ENIC_RX_STAT(rx_frames_ok),
99 ENIC_RX_STAT(rx_frames_total),
100 ENIC_RX_STAT(rx_unicast_frames_ok),
101 ENIC_RX_STAT(rx_multicast_frames_ok),
102 ENIC_RX_STAT(rx_broadcast_frames_ok),
103 ENIC_RX_STAT(rx_bytes_ok),
104 ENIC_RX_STAT(rx_unicast_bytes_ok),
105 ENIC_RX_STAT(rx_multicast_bytes_ok),
106 ENIC_RX_STAT(rx_broadcast_bytes_ok),
107 ENIC_RX_STAT(rx_drop),
108 ENIC_RX_STAT(rx_no_bufs),
109 ENIC_RX_STAT(rx_errors),
110 ENIC_RX_STAT(rx_rss),
111 ENIC_RX_STAT(rx_crc_errors),
112 ENIC_RX_STAT(rx_frames_64),
113 ENIC_RX_STAT(rx_frames_127),
114 ENIC_RX_STAT(rx_frames_255),
115 ENIC_RX_STAT(rx_frames_511),
116 ENIC_RX_STAT(rx_frames_1023),
117 ENIC_RX_STAT(rx_frames_1518),
118 ENIC_RX_STAT(rx_frames_to_max),
119};
120
121static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
122static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
123
124static int enic_is_dynamic(struct enic *enic)
125{
126 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
127}
128
129static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
130{
131 return rq;
132}
133
134static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
135{
136 return enic->rq_count + wq;
137}
138
139static inline unsigned int enic_legacy_io_intr(void)
140{
141 return 0;
142}
143
144static inline unsigned int enic_legacy_err_intr(void)
145{
146 return 1;
147}
148
149static inline unsigned int enic_legacy_notify_intr(void)
150{
151 return 2;
152}
153
154static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq)
155{
156 return enic->cq[enic_cq_rq(enic, rq)].interrupt_offset;
157}
158
159static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq)
160{
161 return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset;
162}
163
164static inline unsigned int enic_msix_err_intr(struct enic *enic)
165{
166 return enic->rq_count + enic->wq_count;
167}
168
169static inline unsigned int enic_msix_notify_intr(struct enic *enic)
170{
171 return enic->rq_count + enic->wq_count + 1;
172}
173
174static int enic_get_settings(struct net_device *netdev,
175 struct ethtool_cmd *ecmd)
176{
177 struct enic *enic = netdev_priv(netdev);
178
179 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
180 ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
181 ecmd->port = PORT_FIBRE;
182 ecmd->transceiver = XCVR_EXTERNAL;
183
184 if (netif_carrier_ok(netdev)) {
185 ethtool_cmd_speed_set(ecmd, vnic_dev_port_speed(enic->vdev));
186 ecmd->duplex = DUPLEX_FULL;
187 } else {
188 ethtool_cmd_speed_set(ecmd, -1);
189 ecmd->duplex = -1;
190 }
191
192 ecmd->autoneg = AUTONEG_DISABLE;
193
194 return 0;
195}
196
197static void enic_get_drvinfo(struct net_device *netdev,
198 struct ethtool_drvinfo *drvinfo)
199{
200 struct enic *enic = netdev_priv(netdev);
201 struct vnic_devcmd_fw_info *fw_info;
202
203 enic_dev_fw_info(enic, &fw_info);
204
205 strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
206 strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
207 strncpy(drvinfo->fw_version, fw_info->fw_version,
208 sizeof(drvinfo->fw_version));
209 strncpy(drvinfo->bus_info, pci_name(enic->pdev),
210 sizeof(drvinfo->bus_info));
211}
212
213static void enic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
214{
215 unsigned int i;
216
217 switch (stringset) {
218 case ETH_SS_STATS:
219 for (i = 0; i < enic_n_tx_stats; i++) {
220 memcpy(data, enic_tx_stats[i].name, ETH_GSTRING_LEN);
221 data += ETH_GSTRING_LEN;
222 }
223 for (i = 0; i < enic_n_rx_stats; i++) {
224 memcpy(data, enic_rx_stats[i].name, ETH_GSTRING_LEN);
225 data += ETH_GSTRING_LEN;
226 }
227 break;
228 }
229}
230
231static int enic_get_sset_count(struct net_device *netdev, int sset)
232{
233 switch (sset) {
234 case ETH_SS_STATS:
235 return enic_n_tx_stats + enic_n_rx_stats;
236 default:
237 return -EOPNOTSUPP;
238 }
239}
240
241static void enic_get_ethtool_stats(struct net_device *netdev,
242 struct ethtool_stats *stats, u64 *data)
243{
244 struct enic *enic = netdev_priv(netdev);
245 struct vnic_stats *vstats;
246 unsigned int i;
247
248 enic_dev_stats_dump(enic, &vstats);
249
250 for (i = 0; i < enic_n_tx_stats; i++)
251 *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset];
252 for (i = 0; i < enic_n_rx_stats; i++)
253 *(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset];
254}
255
256static u32 enic_get_msglevel(struct net_device *netdev)
257{
258 struct enic *enic = netdev_priv(netdev);
259 return enic->msg_enable;
260}
261
262static void enic_set_msglevel(struct net_device *netdev, u32 value)
263{
264 struct enic *enic = netdev_priv(netdev);
265 enic->msg_enable = value;
266}
267
268static int enic_get_coalesce(struct net_device *netdev,
269 struct ethtool_coalesce *ecmd)
270{
271 struct enic *enic = netdev_priv(netdev);
272
273 ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs;
274 ecmd->rx_coalesce_usecs = enic->rx_coalesce_usecs;
275
276 return 0;
277}
278
279static int enic_set_coalesce(struct net_device *netdev,
280 struct ethtool_coalesce *ecmd)
281{
282 struct enic *enic = netdev_priv(netdev);
283 u32 tx_coalesce_usecs;
284 u32 rx_coalesce_usecs;
285 unsigned int i, intr;
286
287 tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs,
288 vnic_dev_get_intr_coal_timer_max(enic->vdev));
289 rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs,
290 vnic_dev_get_intr_coal_timer_max(enic->vdev));
291
292 switch (vnic_dev_get_intr_mode(enic->vdev)) {
293 case VNIC_DEV_INTR_MODE_INTX:
294 if (tx_coalesce_usecs != rx_coalesce_usecs)
295 return -EINVAL;
296
297 intr = enic_legacy_io_intr();
298 vnic_intr_coalescing_timer_set(&enic->intr[intr],
299 tx_coalesce_usecs);
300 break;
301 case VNIC_DEV_INTR_MODE_MSI:
302 if (tx_coalesce_usecs != rx_coalesce_usecs)
303 return -EINVAL;
304
305 vnic_intr_coalescing_timer_set(&enic->intr[0],
306 tx_coalesce_usecs);
307 break;
308 case VNIC_DEV_INTR_MODE_MSIX:
309 for (i = 0; i < enic->wq_count; i++) {
310 intr = enic_msix_wq_intr(enic, i);
311 vnic_intr_coalescing_timer_set(&enic->intr[intr],
312 tx_coalesce_usecs);
313 }
314
315 for (i = 0; i < enic->rq_count; i++) {
316 intr = enic_msix_rq_intr(enic, i);
317 vnic_intr_coalescing_timer_set(&enic->intr[intr],
318 rx_coalesce_usecs);
319 }
320
321 break;
322 default:
323 break;
324 }
325
326 enic->tx_coalesce_usecs = tx_coalesce_usecs;
327 enic->rx_coalesce_usecs = rx_coalesce_usecs;
328
329 return 0;
330}
331
332static const struct ethtool_ops enic_ethtool_ops = {
333 .get_settings = enic_get_settings,
334 .get_drvinfo = enic_get_drvinfo,
335 .get_msglevel = enic_get_msglevel,
336 .set_msglevel = enic_set_msglevel,
337 .get_link = ethtool_op_get_link,
338 .get_strings = enic_get_strings,
339 .get_sset_count = enic_get_sset_count,
340 .get_ethtool_stats = enic_get_ethtool_stats,
341 .get_coalesce = enic_get_coalesce,
342 .set_coalesce = enic_set_coalesce,
343};
344
345static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
346{
347 struct enic *enic = vnic_dev_priv(wq->vdev);
348
349 if (buf->sop)
350 pci_unmap_single(enic->pdev, buf->dma_addr,
351 buf->len, PCI_DMA_TODEVICE);
352 else
353 pci_unmap_page(enic->pdev, buf->dma_addr,
354 buf->len, PCI_DMA_TODEVICE);
355
356 if (buf->os_buf)
357 dev_kfree_skb_any(buf->os_buf);
358}
359
360static void enic_wq_free_buf(struct vnic_wq *wq,
361 struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque)
362{
363 enic_free_wq_buf(wq, buf);
364}
365
366static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
367 u8 type, u16 q_number, u16 completed_index, void *opaque)
368{
369 struct enic *enic = vnic_dev_priv(vdev);
370
371 spin_lock(&enic->wq_lock[q_number]);
372
373 vnic_wq_service(&enic->wq[q_number], cq_desc,
374 completed_index, enic_wq_free_buf,
375 opaque);
376
377 if (netif_queue_stopped(enic->netdev) &&
378 vnic_wq_desc_avail(&enic->wq[q_number]) >=
379 (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS))
380 netif_wake_queue(enic->netdev);
381
382 spin_unlock(&enic->wq_lock[q_number]);
383
384 return 0;
385}
386
387static void enic_log_q_error(struct enic *enic)
388{
389 unsigned int i;
390 u32 error_status;
391
392 for (i = 0; i < enic->wq_count; i++) {
393 error_status = vnic_wq_error_status(&enic->wq[i]);
394 if (error_status)
395 netdev_err(enic->netdev, "WQ[%d] error_status %d\n",
396 i, error_status);
397 }
398
399 for (i = 0; i < enic->rq_count; i++) {
400 error_status = vnic_rq_error_status(&enic->rq[i]);
401 if (error_status)
402 netdev_err(enic->netdev, "RQ[%d] error_status %d\n",
403 i, error_status);
404 }
405}
406
407static void enic_msglvl_check(struct enic *enic)
408{
409 u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
410
411 if (msg_enable != enic->msg_enable) {
412 netdev_info(enic->netdev, "msg lvl changed from 0x%x to 0x%x\n",
413 enic->msg_enable, msg_enable);
414 enic->msg_enable = msg_enable;
415 }
416}
417
418static void enic_mtu_check(struct enic *enic)
419{
420 u32 mtu = vnic_dev_mtu(enic->vdev);
421 struct net_device *netdev = enic->netdev;
422
423 if (mtu && mtu != enic->port_mtu) {
424 enic->port_mtu = mtu;
425 if (enic_is_dynamic(enic)) {
426 mtu = max_t(int, ENIC_MIN_MTU,
427 min_t(int, ENIC_MAX_MTU, mtu));
428 if (mtu != netdev->mtu)
429 schedule_work(&enic->change_mtu_work);
430 } else {
431 if (mtu < netdev->mtu)
432 netdev_warn(netdev,
433 "interface MTU (%d) set higher "
434 "than switch port MTU (%d)\n",
435 netdev->mtu, mtu);
436 }
437 }
438}
439
440static void enic_link_check(struct enic *enic)
441{
442 int link_status = vnic_dev_link_status(enic->vdev);
443 int carrier_ok = netif_carrier_ok(enic->netdev);
444
445 if (link_status && !carrier_ok) {
446 netdev_info(enic->netdev, "Link UP\n");
447 netif_carrier_on(enic->netdev);
448 } else if (!link_status && carrier_ok) {
449 netdev_info(enic->netdev, "Link DOWN\n");
450 netif_carrier_off(enic->netdev);
451 }
452}
453
454static void enic_notify_check(struct enic *enic)
455{
456 enic_msglvl_check(enic);
457 enic_mtu_check(enic);
458 enic_link_check(enic);
459}
460
461#define ENIC_TEST_INTR(pba, i) (pba & (1 << i))
462
463static irqreturn_t enic_isr_legacy(int irq, void *data)
464{
465 struct net_device *netdev = data;
466 struct enic *enic = netdev_priv(netdev);
467 unsigned int io_intr = enic_legacy_io_intr();
468 unsigned int err_intr = enic_legacy_err_intr();
469 unsigned int notify_intr = enic_legacy_notify_intr();
470 u32 pba;
471
472 vnic_intr_mask(&enic->intr[io_intr]);
473
474 pba = vnic_intr_legacy_pba(enic->legacy_pba);
475 if (!pba) {
476 vnic_intr_unmask(&enic->intr[io_intr]);
477 return IRQ_NONE; /* not our interrupt */
478 }
479
480 if (ENIC_TEST_INTR(pba, notify_intr)) {
481 vnic_intr_return_all_credits(&enic->intr[notify_intr]);
482 enic_notify_check(enic);
483 }
484
485 if (ENIC_TEST_INTR(pba, err_intr)) {
486 vnic_intr_return_all_credits(&enic->intr[err_intr]);
487 enic_log_q_error(enic);
488 /* schedule recovery from WQ/RQ error */
489 schedule_work(&enic->reset);
490 return IRQ_HANDLED;
491 }
492
493 if (ENIC_TEST_INTR(pba, io_intr)) {
494 if (napi_schedule_prep(&enic->napi[0]))
495 __napi_schedule(&enic->napi[0]);
496 } else {
497 vnic_intr_unmask(&enic->intr[io_intr]);
498 }
499
500 return IRQ_HANDLED;
501}
502
503static irqreturn_t enic_isr_msi(int irq, void *data)
504{
505 struct enic *enic = data;
506
507 /* With MSI, there is no sharing of interrupts, so this is
508 * our interrupt and there is no need to ack it. The device
509 * is not providing per-vector masking, so the OS will not
510 * write to PCI config space to mask/unmask the interrupt.
511 * We're using mask_on_assertion for MSI, so the device
512 * automatically masks the interrupt when the interrupt is
513 * generated. Later, when exiting polling, the interrupt
514 * will be unmasked (see enic_poll).
515 *
516 * Also, the device uses the same PCIe Traffic Class (TC)
517 * for Memory Write data and MSI, so there are no ordering
518 * issues; the MSI will always arrive at the Root Complex
519 * _after_ corresponding Memory Writes (i.e. descriptor
520 * writes).
521 */
522
523 napi_schedule(&enic->napi[0]);
524
525 return IRQ_HANDLED;
526}
527
528static irqreturn_t enic_isr_msix_rq(int irq, void *data)
529{
530 struct napi_struct *napi = data;
531
532 /* schedule NAPI polling for RQ cleanup */
533 napi_schedule(napi);
534
535 return IRQ_HANDLED;
536}
537
538static irqreturn_t enic_isr_msix_wq(int irq, void *data)
539{
540 struct enic *enic = data;
541 unsigned int cq = enic_cq_wq(enic, 0);
542 unsigned int intr = enic_msix_wq_intr(enic, 0);
543 unsigned int wq_work_to_do = -1; /* no limit */
544 unsigned int wq_work_done;
545
546 wq_work_done = vnic_cq_service(&enic->cq[cq],
547 wq_work_to_do, enic_wq_service, NULL);
548
549 vnic_intr_return_credits(&enic->intr[intr],
550 wq_work_done,
551 1 /* unmask intr */,
552 1 /* reset intr timer */);
553
554 return IRQ_HANDLED;
555}
556
557static irqreturn_t enic_isr_msix_err(int irq, void *data)
558{
559 struct enic *enic = data;
560 unsigned int intr = enic_msix_err_intr(enic);
561
562 vnic_intr_return_all_credits(&enic->intr[intr]);
563
564 enic_log_q_error(enic);
565
566 /* schedule recovery from WQ/RQ error */
567 schedule_work(&enic->reset);
568
569 return IRQ_HANDLED;
570}
571
572static irqreturn_t enic_isr_msix_notify(int irq, void *data)
573{
574 struct enic *enic = data;
575 unsigned int intr = enic_msix_notify_intr(enic);
576
577 vnic_intr_return_all_credits(&enic->intr[intr]);
578 enic_notify_check(enic);
579
580 return IRQ_HANDLED;
581}
582
583static inline void enic_queue_wq_skb_cont(struct enic *enic,
584 struct vnic_wq *wq, struct sk_buff *skb,
585 unsigned int len_left, int loopback)
586{
587 skb_frag_t *frag;
588
589 /* Queue additional data fragments */
590 for (frag = skb_shinfo(skb)->frags; len_left; frag++) {
591 len_left -= frag->size;
592 enic_queue_wq_desc_cont(wq, skb,
593 pci_map_page(enic->pdev, frag->page,
594 frag->page_offset, frag->size,
595 PCI_DMA_TODEVICE),
596 frag->size,
597 (len_left == 0), /* EOP? */
598 loopback);
599 }
600}
601
602static inline void enic_queue_wq_skb_vlan(struct enic *enic,
603 struct vnic_wq *wq, struct sk_buff *skb,
604 int vlan_tag_insert, unsigned int vlan_tag, int loopback)
605{
606 unsigned int head_len = skb_headlen(skb);
607 unsigned int len_left = skb->len - head_len;
608 int eop = (len_left == 0);
609
610 /* Queue the main skb fragment. The fragments are no larger
611 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
612 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
613 * per fragment is queued.
614 */
615 enic_queue_wq_desc(wq, skb,
616 pci_map_single(enic->pdev, skb->data,
617 head_len, PCI_DMA_TODEVICE),
618 head_len,
619 vlan_tag_insert, vlan_tag,
620 eop, loopback);
621
622 if (!eop)
623 enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
624}
625
626static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
627 struct vnic_wq *wq, struct sk_buff *skb,
628 int vlan_tag_insert, unsigned int vlan_tag, int loopback)
629{
630 unsigned int head_len = skb_headlen(skb);
631 unsigned int len_left = skb->len - head_len;
632 unsigned int hdr_len = skb_checksum_start_offset(skb);
633 unsigned int csum_offset = hdr_len + skb->csum_offset;
634 int eop = (len_left == 0);
635
636 /* Queue the main skb fragment. The fragments are no larger
637 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
638 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
639 * per fragment is queued.
640 */
641 enic_queue_wq_desc_csum_l4(wq, skb,
642 pci_map_single(enic->pdev, skb->data,
643 head_len, PCI_DMA_TODEVICE),
644 head_len,
645 csum_offset,
646 hdr_len,
647 vlan_tag_insert, vlan_tag,
648 eop, loopback);
649
650 if (!eop)
651 enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
652}
653
654static inline void enic_queue_wq_skb_tso(struct enic *enic,
655 struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss,
656 int vlan_tag_insert, unsigned int vlan_tag, int loopback)
657{
658 unsigned int frag_len_left = skb_headlen(skb);
659 unsigned int len_left = skb->len - frag_len_left;
660 unsigned int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
661 int eop = (len_left == 0);
662 unsigned int len;
663 dma_addr_t dma_addr;
664 unsigned int offset = 0;
665 skb_frag_t *frag;
666
667 /* Preload TCP csum field with IP pseudo hdr calculated
668 * with IP length set to zero. HW will later add in length
669 * to each TCP segment resulting from the TSO.
670 */
671
672 if (skb->protocol == cpu_to_be16(ETH_P_IP)) {
673 ip_hdr(skb)->check = 0;
674 tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
675 ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
676 } else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
677 tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
678 &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
679 }
680
681 /* Queue WQ_ENET_MAX_DESC_LEN length descriptors
682 * for the main skb fragment
683 */
684 while (frag_len_left) {
685 len = min(frag_len_left, (unsigned int)WQ_ENET_MAX_DESC_LEN);
686 dma_addr = pci_map_single(enic->pdev, skb->data + offset,
687 len, PCI_DMA_TODEVICE);
688 enic_queue_wq_desc_tso(wq, skb,
689 dma_addr,
690 len,
691 mss, hdr_len,
692 vlan_tag_insert, vlan_tag,
693 eop && (len == frag_len_left), loopback);
694 frag_len_left -= len;
695 offset += len;
696 }
697
698 if (eop)
699 return;
700
701 /* Queue WQ_ENET_MAX_DESC_LEN length descriptors
702 * for additional data fragments
703 */
704 for (frag = skb_shinfo(skb)->frags; len_left; frag++) {
705 len_left -= frag->size;
706 frag_len_left = frag->size;
707 offset = frag->page_offset;
708
709 while (frag_len_left) {
710 len = min(frag_len_left,
711 (unsigned int)WQ_ENET_MAX_DESC_LEN);
712 dma_addr = pci_map_page(enic->pdev, frag->page,
713 offset, len,
714 PCI_DMA_TODEVICE);
715 enic_queue_wq_desc_cont(wq, skb,
716 dma_addr,
717 len,
718 (len_left == 0) &&
719 (len == frag_len_left), /* EOP? */
720 loopback);
721 frag_len_left -= len;
722 offset += len;
723 }
724 }
725}
726
727static inline void enic_queue_wq_skb(struct enic *enic,
728 struct vnic_wq *wq, struct sk_buff *skb)
729{
730 unsigned int mss = skb_shinfo(skb)->gso_size;
731 unsigned int vlan_tag = 0;
732 int vlan_tag_insert = 0;
733 int loopback = 0;
734
735 if (vlan_tx_tag_present(skb)) {
736 /* VLAN tag from trunking driver */
737 vlan_tag_insert = 1;
738 vlan_tag = vlan_tx_tag_get(skb);
739 } else if (enic->loop_enable) {
740 vlan_tag = enic->loop_tag;
741 loopback = 1;
742 }
743
744 if (mss)
745 enic_queue_wq_skb_tso(enic, wq, skb, mss,
746 vlan_tag_insert, vlan_tag, loopback);
747 else if (skb->ip_summed == CHECKSUM_PARTIAL)
748 enic_queue_wq_skb_csum_l4(enic, wq, skb,
749 vlan_tag_insert, vlan_tag, loopback);
750 else
751 enic_queue_wq_skb_vlan(enic, wq, skb,
752 vlan_tag_insert, vlan_tag, loopback);
753}
754
755/* netif_tx_lock held, process context with BHs disabled, or BH */
756static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
757 struct net_device *netdev)
758{
759 struct enic *enic = netdev_priv(netdev);
760 struct vnic_wq *wq = &enic->wq[0];
761 unsigned long flags;
762
763 if (skb->len <= 0) {
764 dev_kfree_skb(skb);
765 return NETDEV_TX_OK;
766 }
767
768 /* Non-TSO sends must fit within ENIC_NON_TSO_MAX_DESC descs,
769 * which is very likely. In the off chance it's going to take
770 * more than * ENIC_NON_TSO_MAX_DESC, linearize the skb.
771 */
772
773 if (skb_shinfo(skb)->gso_size == 0 &&
774 skb_shinfo(skb)->nr_frags + 1 > ENIC_NON_TSO_MAX_DESC &&
775 skb_linearize(skb)) {
776 dev_kfree_skb(skb);
777 return NETDEV_TX_OK;
778 }
779
780 spin_lock_irqsave(&enic->wq_lock[0], flags);
781
782 if (vnic_wq_desc_avail(wq) <
783 skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) {
784 netif_stop_queue(netdev);
785 /* This is a hard error, log it */
786 netdev_err(netdev, "BUG! Tx ring full when queue awake!\n");
787 spin_unlock_irqrestore(&enic->wq_lock[0], flags);
788 return NETDEV_TX_BUSY;
789 }
790
791 enic_queue_wq_skb(enic, wq, skb);
792
793 if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)
794 netif_stop_queue(netdev);
795
796 spin_unlock_irqrestore(&enic->wq_lock[0], flags);
797
798 return NETDEV_TX_OK;
799}
800
801/* dev_base_lock rwlock held, nominally process context */
802static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev,
803 struct rtnl_link_stats64 *net_stats)
804{
805 struct enic *enic = netdev_priv(netdev);
806 struct vnic_stats *stats;
807
808 enic_dev_stats_dump(enic, &stats);
809
810 net_stats->tx_packets = stats->tx.tx_frames_ok;
811 net_stats->tx_bytes = stats->tx.tx_bytes_ok;
812 net_stats->tx_errors = stats->tx.tx_errors;
813 net_stats->tx_dropped = stats->tx.tx_drops;
814
815 net_stats->rx_packets = stats->rx.rx_frames_ok;
816 net_stats->rx_bytes = stats->rx.rx_bytes_ok;
817 net_stats->rx_errors = stats->rx.rx_errors;
818 net_stats->multicast = stats->rx.rx_multicast_frames_ok;
819 net_stats->rx_over_errors = enic->rq_truncated_pkts;
820 net_stats->rx_crc_errors = enic->rq_bad_fcs;
821 net_stats->rx_dropped = stats->rx.rx_no_bufs + stats->rx.rx_drop;
822
823 return net_stats;
824}
825
826void enic_reset_addr_lists(struct enic *enic)
827{
828 enic->mc_count = 0;
829 enic->uc_count = 0;
830 enic->flags = 0;
831}
832
833static int enic_set_mac_addr(struct net_device *netdev, char *addr)
834{
835 struct enic *enic = netdev_priv(netdev);
836
837 if (enic_is_dynamic(enic)) {
838 if (!is_valid_ether_addr(addr) && !is_zero_ether_addr(addr))
839 return -EADDRNOTAVAIL;
840 } else {
841 if (!is_valid_ether_addr(addr))
842 return -EADDRNOTAVAIL;
843 }
844
845 memcpy(netdev->dev_addr, addr, netdev->addr_len);
846
847 return 0;
848}
849
850static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p)
851{
852 struct enic *enic = netdev_priv(netdev);
853 struct sockaddr *saddr = p;
854 char *addr = saddr->sa_data;
855 int err;
856
857 if (netif_running(enic->netdev)) {
858 err = enic_dev_del_station_addr(enic);
859 if (err)
860 return err;
861 }
862
863 err = enic_set_mac_addr(netdev, addr);
864 if (err)
865 return err;
866
867 if (netif_running(enic->netdev)) {
868 err = enic_dev_add_station_addr(enic);
869 if (err)
870 return err;
871 }
872
873 return err;
874}
875
876static int enic_set_mac_address(struct net_device *netdev, void *p)
877{
878 struct sockaddr *saddr = p;
879 char *addr = saddr->sa_data;
880 struct enic *enic = netdev_priv(netdev);
881 int err;
882
883 err = enic_dev_del_station_addr(enic);
884 if (err)
885 return err;
886
887 err = enic_set_mac_addr(netdev, addr);
888 if (err)
889 return err;
890
891 return enic_dev_add_station_addr(enic);
892}
893
894static void enic_update_multicast_addr_list(struct enic *enic)
895{
896 struct net_device *netdev = enic->netdev;
897 struct netdev_hw_addr *ha;
898 unsigned int mc_count = netdev_mc_count(netdev);
899 u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
900 unsigned int i, j;
901
902 if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) {
903 netdev_warn(netdev, "Registering only %d out of %d "
904 "multicast addresses\n",
905 ENIC_MULTICAST_PERFECT_FILTERS, mc_count);
906 mc_count = ENIC_MULTICAST_PERFECT_FILTERS;
907 }
908
909 /* Is there an easier way? Trying to minimize to
910 * calls to add/del multicast addrs. We keep the
911 * addrs from the last call in enic->mc_addr and
912 * look for changes to add/del.
913 */
914
915 i = 0;
916 netdev_for_each_mc_addr(ha, netdev) {
917 if (i == mc_count)
918 break;
919 memcpy(mc_addr[i++], ha->addr, ETH_ALEN);
920 }
921
922 for (i = 0; i < enic->mc_count; i++) {
923 for (j = 0; j < mc_count; j++)
924 if (compare_ether_addr(enic->mc_addr[i],
925 mc_addr[j]) == 0)
926 break;
927 if (j == mc_count)
928 enic_dev_del_addr(enic, enic->mc_addr[i]);
929 }
930
931 for (i = 0; i < mc_count; i++) {
932 for (j = 0; j < enic->mc_count; j++)
933 if (compare_ether_addr(mc_addr[i],
934 enic->mc_addr[j]) == 0)
935 break;
936 if (j == enic->mc_count)
937 enic_dev_add_addr(enic, mc_addr[i]);
938 }
939
940 /* Save the list to compare against next time
941 */
942
943 for (i = 0; i < mc_count; i++)
944 memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN);
945
946 enic->mc_count = mc_count;
947}
948
949static void enic_update_unicast_addr_list(struct enic *enic)
950{
951 struct net_device *netdev = enic->netdev;
952 struct netdev_hw_addr *ha;
953 unsigned int uc_count = netdev_uc_count(netdev);
954 u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
955 unsigned int i, j;
956
957 if (uc_count > ENIC_UNICAST_PERFECT_FILTERS) {
958 netdev_warn(netdev, "Registering only %d out of %d "
959 "unicast addresses\n",
960 ENIC_UNICAST_PERFECT_FILTERS, uc_count);
961 uc_count = ENIC_UNICAST_PERFECT_FILTERS;
962 }
963
964 /* Is there an easier way? Trying to minimize to
965 * calls to add/del unicast addrs. We keep the
966 * addrs from the last call in enic->uc_addr and
967 * look for changes to add/del.
968 */
969
970 i = 0;
971 netdev_for_each_uc_addr(ha, netdev) {
972 if (i == uc_count)
973 break;
974 memcpy(uc_addr[i++], ha->addr, ETH_ALEN);
975 }
976
977 for (i = 0; i < enic->uc_count; i++) {
978 for (j = 0; j < uc_count; j++)
979 if (compare_ether_addr(enic->uc_addr[i],
980 uc_addr[j]) == 0)
981 break;
982 if (j == uc_count)
983 enic_dev_del_addr(enic, enic->uc_addr[i]);
984 }
985
986 for (i = 0; i < uc_count; i++) {
987 for (j = 0; j < enic->uc_count; j++)
988 if (compare_ether_addr(uc_addr[i],
989 enic->uc_addr[j]) == 0)
990 break;
991 if (j == enic->uc_count)
992 enic_dev_add_addr(enic, uc_addr[i]);
993 }
994
995 /* Save the list to compare against next time
996 */
997
998 for (i = 0; i < uc_count; i++)
999 memcpy(enic->uc_addr[i], uc_addr[i], ETH_ALEN);
1000
1001 enic->uc_count = uc_count;
1002}
1003
1004/* netif_tx_lock held, BHs disabled */
1005static void enic_set_rx_mode(struct net_device *netdev)
1006{
1007 struct enic *enic = netdev_priv(netdev);
1008 int directed = 1;
1009 int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
1010 int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
1011 int promisc = (netdev->flags & IFF_PROMISC) ||
1012 netdev_uc_count(netdev) > ENIC_UNICAST_PERFECT_FILTERS;
1013 int allmulti = (netdev->flags & IFF_ALLMULTI) ||
1014 netdev_mc_count(netdev) > ENIC_MULTICAST_PERFECT_FILTERS;
1015 unsigned int flags = netdev->flags |
1016 (allmulti ? IFF_ALLMULTI : 0) |
1017 (promisc ? IFF_PROMISC : 0);
1018
1019 if (enic->flags != flags) {
1020 enic->flags = flags;
1021 enic_dev_packet_filter(enic, directed,
1022 multicast, broadcast, promisc, allmulti);
1023 }
1024
1025 if (!promisc) {
1026 enic_update_unicast_addr_list(enic);
1027 if (!allmulti)
1028 enic_update_multicast_addr_list(enic);
1029 }
1030}
1031
1032/* netif_tx_lock held, BHs disabled */
1033static void enic_tx_timeout(struct net_device *netdev)
1034{
1035 struct enic *enic = netdev_priv(netdev);
1036 schedule_work(&enic->reset);
1037}
1038
1039static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
1040{
1041 struct enic *enic = netdev_priv(netdev);
1042
1043 if (vf != PORT_SELF_VF)
1044 return -EOPNOTSUPP;
1045
1046 /* Ignore the vf argument for now. We can assume the request
1047 * is coming on a vf.
1048 */
1049 if (is_valid_ether_addr(mac)) {
1050 memcpy(enic->pp.vf_mac, mac, ETH_ALEN);
1051 return 0;
1052 } else
1053 return -EINVAL;
1054}
1055
1056static int enic_set_vf_port(struct net_device *netdev, int vf,
1057 struct nlattr *port[])
1058{
1059 struct enic *enic = netdev_priv(netdev);
1060 struct enic_port_profile prev_pp;
1061 int err = 0, restore_pp = 1;
1062
1063 /* don't support VFs, yet */
1064 if (vf != PORT_SELF_VF)
1065 return -EOPNOTSUPP;
1066
1067 if (!port[IFLA_PORT_REQUEST])
1068 return -EOPNOTSUPP;
1069
1070 memcpy(&prev_pp, &enic->pp, sizeof(enic->pp));
1071 memset(&enic->pp, 0, sizeof(enic->pp));
1072
1073 enic->pp.set |= ENIC_SET_REQUEST;
1074 enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
1075
1076 if (port[IFLA_PORT_PROFILE]) {
1077 enic->pp.set |= ENIC_SET_NAME;
1078 memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
1079 PORT_PROFILE_MAX);
1080 }
1081
1082 if (port[IFLA_PORT_INSTANCE_UUID]) {
1083 enic->pp.set |= ENIC_SET_INSTANCE;
1084 memcpy(enic->pp.instance_uuid,
1085 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
1086 }
1087
1088 if (port[IFLA_PORT_HOST_UUID]) {
1089 enic->pp.set |= ENIC_SET_HOST;
1090 memcpy(enic->pp.host_uuid,
1091 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
1092 }
1093
1094 /* Special case handling: mac came from IFLA_VF_MAC */
1095 if (!is_zero_ether_addr(prev_pp.vf_mac))
1096 memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN);
1097
1098 if (is_zero_ether_addr(netdev->dev_addr))
1099 random_ether_addr(netdev->dev_addr);
1100
1101 err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp);
1102 if (err) {
1103 if (restore_pp) {
1104 /* Things are still the way they were: Implicit
1105 * DISASSOCIATE failed
1106 */
1107 memcpy(&enic->pp, &prev_pp, sizeof(enic->pp));
1108 } else {
1109 memset(&enic->pp, 0, sizeof(enic->pp));
1110 memset(netdev->dev_addr, 0, ETH_ALEN);
1111 }
1112 } else {
1113 /* Set flag to indicate that the port assoc/disassoc
1114 * request has been sent out to fw
1115 */
1116 enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
1117
1118 /* If DISASSOCIATE, clean up all assigned/saved macaddresses */
1119 if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
1120 memset(enic->pp.mac_addr, 0, ETH_ALEN);
1121 memset(netdev->dev_addr, 0, ETH_ALEN);
1122 }
1123 }
1124
1125 memset(enic->pp.vf_mac, 0, ETH_ALEN);
1126
1127 return err;
1128}
1129
1130static int enic_get_vf_port(struct net_device *netdev, int vf,
1131 struct sk_buff *skb)
1132{
1133 struct enic *enic = netdev_priv(netdev);
1134 u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
1135 int err;
1136
1137 if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED))
1138 return -ENODATA;
1139
1140 err = enic_process_get_pp_request(enic, enic->pp.request, &response);
1141 if (err)
1142 return err;
1143
1144 NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
1145 NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
1146 if (enic->pp.set & ENIC_SET_NAME)
1147 NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
1148 enic->pp.name);
1149 if (enic->pp.set & ENIC_SET_INSTANCE)
1150 NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
1151 enic->pp.instance_uuid);
1152 if (enic->pp.set & ENIC_SET_HOST)
1153 NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
1154 enic->pp.host_uuid);
1155
1156 return 0;
1157
1158nla_put_failure:
1159 return -EMSGSIZE;
1160}
1161
1162static void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
1163{
1164 struct enic *enic = vnic_dev_priv(rq->vdev);
1165
1166 if (!buf->os_buf)
1167 return;
1168
1169 pci_unmap_single(enic->pdev, buf->dma_addr,
1170 buf->len, PCI_DMA_FROMDEVICE);
1171 dev_kfree_skb_any(buf->os_buf);
1172}
1173
1174static int enic_rq_alloc_buf(struct vnic_rq *rq)
1175{
1176 struct enic *enic = vnic_dev_priv(rq->vdev);
1177 struct net_device *netdev = enic->netdev;
1178 struct sk_buff *skb;
1179 unsigned int len = netdev->mtu + VLAN_ETH_HLEN;
1180 unsigned int os_buf_index = 0;
1181 dma_addr_t dma_addr;
1182
1183 skb = netdev_alloc_skb_ip_align(netdev, len);
1184 if (!skb)
1185 return -ENOMEM;
1186
1187 dma_addr = pci_map_single(enic->pdev, skb->data,
1188 len, PCI_DMA_FROMDEVICE);
1189
1190 enic_queue_rq_desc(rq, skb, os_buf_index,
1191 dma_addr, len);
1192
1193 return 0;
1194}
1195
1196static void enic_rq_indicate_buf(struct vnic_rq *rq,
1197 struct cq_desc *cq_desc, struct vnic_rq_buf *buf,
1198 int skipped, void *opaque)
1199{
1200 struct enic *enic = vnic_dev_priv(rq->vdev);
1201 struct net_device *netdev = enic->netdev;
1202 struct sk_buff *skb;
1203
1204 u8 type, color, eop, sop, ingress_port, vlan_stripped;
1205 u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof;
1206 u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
1207 u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
1208 u8 packet_error;
1209 u16 q_number, completed_index, bytes_written, vlan_tci, checksum;
1210 u32 rss_hash;
1211
1212 if (skipped)
1213 return;
1214
1215 skb = buf->os_buf;
1216 prefetch(skb->data - NET_IP_ALIGN);
1217 pci_unmap_single(enic->pdev, buf->dma_addr,
1218 buf->len, PCI_DMA_FROMDEVICE);
1219
1220 cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
1221 &type, &color, &q_number, &completed_index,
1222 &ingress_port, &fcoe, &eop, &sop, &rss_type,
1223 &csum_not_calc, &rss_hash, &bytes_written,
1224 &packet_error, &vlan_stripped, &vlan_tci, &checksum,
1225 &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error,
1226 &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp,
1227 &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
1228 &fcs_ok);
1229
1230 if (packet_error) {
1231
1232 if (!fcs_ok) {
1233 if (bytes_written > 0)
1234 enic->rq_bad_fcs++;
1235 else if (bytes_written == 0)
1236 enic->rq_truncated_pkts++;
1237 }
1238
1239 dev_kfree_skb_any(skb);
1240
1241 return;
1242 }
1243
1244 if (eop && bytes_written > 0) {
1245
1246 /* Good receive
1247 */
1248
1249 skb_put(skb, bytes_written);
1250 skb->protocol = eth_type_trans(skb, netdev);
1251
1252 if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
1253 skb->csum = htons(checksum);
1254 skb->ip_summed = CHECKSUM_COMPLETE;
1255 }
1256
1257 skb->dev = netdev;
1258
1259 if (vlan_stripped)
1260 __vlan_hwaccel_put_tag(skb, vlan_tci);
1261
1262 if (netdev->features & NETIF_F_GRO)
1263 napi_gro_receive(&enic->napi[q_number], skb);
1264 else
1265 netif_receive_skb(skb);
1266 } else {
1267
1268 /* Buffer overflow
1269 */
1270
1271 dev_kfree_skb_any(skb);
1272 }
1273}
1274
1275static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
1276 u8 type, u16 q_number, u16 completed_index, void *opaque)
1277{
1278 struct enic *enic = vnic_dev_priv(vdev);
1279
1280 vnic_rq_service(&enic->rq[q_number], cq_desc,
1281 completed_index, VNIC_RQ_RETURN_DESC,
1282 enic_rq_indicate_buf, opaque);
1283
1284 return 0;
1285}
1286
1287static int enic_poll(struct napi_struct *napi, int budget)
1288{
1289 struct net_device *netdev = napi->dev;
1290 struct enic *enic = netdev_priv(netdev);
1291 unsigned int cq_rq = enic_cq_rq(enic, 0);
1292 unsigned int cq_wq = enic_cq_wq(enic, 0);
1293 unsigned int intr = enic_legacy_io_intr();
1294 unsigned int rq_work_to_do = budget;
1295 unsigned int wq_work_to_do = -1; /* no limit */
1296 unsigned int work_done, rq_work_done, wq_work_done;
1297 int err;
1298
1299 /* Service RQ (first) and WQ
1300 */
1301
1302 rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
1303 rq_work_to_do, enic_rq_service, NULL);
1304
1305 wq_work_done = vnic_cq_service(&enic->cq[cq_wq],
1306 wq_work_to_do, enic_wq_service, NULL);
1307
1308 /* Accumulate intr event credits for this polling
1309 * cycle. An intr event is the completion of a
1310 * a WQ or RQ packet.
1311 */
1312
1313 work_done = rq_work_done + wq_work_done;
1314
1315 if (work_done > 0)
1316 vnic_intr_return_credits(&enic->intr[intr],
1317 work_done,
1318 0 /* don't unmask intr */,
1319 0 /* don't reset intr timer */);
1320
1321 err = vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
1322
1323 /* Buffer allocation failed. Stay in polling
1324 * mode so we can try to fill the ring again.
1325 */
1326
1327 if (err)
1328 rq_work_done = rq_work_to_do;
1329
1330 if (rq_work_done < rq_work_to_do) {
1331
1332 /* Some work done, but not enough to stay in polling,
1333 * exit polling
1334 */
1335
1336 napi_complete(napi);
1337 vnic_intr_unmask(&enic->intr[intr]);
1338 }
1339
1340 return rq_work_done;
1341}
1342
1343static int enic_poll_msix(struct napi_struct *napi, int budget)
1344{
1345 struct net_device *netdev = napi->dev;
1346 struct enic *enic = netdev_priv(netdev);
1347 unsigned int rq = (napi - &enic->napi[0]);
1348 unsigned int cq = enic_cq_rq(enic, rq);
1349 unsigned int intr = enic_msix_rq_intr(enic, rq);
1350 unsigned int work_to_do = budget;
1351 unsigned int work_done;
1352 int err;
1353
1354 /* Service RQ
1355 */
1356
1357 work_done = vnic_cq_service(&enic->cq[cq],
1358 work_to_do, enic_rq_service, NULL);
1359
1360 /* Return intr event credits for this polling
1361 * cycle. An intr event is the completion of a
1362 * RQ packet.
1363 */
1364
1365 if (work_done > 0)
1366 vnic_intr_return_credits(&enic->intr[intr],
1367 work_done,
1368 0 /* don't unmask intr */,
1369 0 /* don't reset intr timer */);
1370
1371 err = vnic_rq_fill(&enic->rq[rq], enic_rq_alloc_buf);
1372
1373 /* Buffer allocation failed. Stay in polling mode
1374 * so we can try to fill the ring again.
1375 */
1376
1377 if (err)
1378 work_done = work_to_do;
1379
1380 if (work_done < work_to_do) {
1381
1382 /* Some work done, but not enough to stay in polling,
1383 * exit polling
1384 */
1385
1386 napi_complete(napi);
1387 vnic_intr_unmask(&enic->intr[intr]);
1388 }
1389
1390 return work_done;
1391}
1392
1393static void enic_notify_timer(unsigned long data)
1394{
1395 struct enic *enic = (struct enic *)data;
1396
1397 enic_notify_check(enic);
1398
1399 mod_timer(&enic->notify_timer,
1400 round_jiffies(jiffies + ENIC_NOTIFY_TIMER_PERIOD));
1401}
1402
1403static void enic_free_intr(struct enic *enic)
1404{
1405 struct net_device *netdev = enic->netdev;
1406 unsigned int i;
1407
1408 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1409 case VNIC_DEV_INTR_MODE_INTX:
1410 free_irq(enic->pdev->irq, netdev);
1411 break;
1412 case VNIC_DEV_INTR_MODE_MSI:
1413 free_irq(enic->pdev->irq, enic);
1414 break;
1415 case VNIC_DEV_INTR_MODE_MSIX:
1416 for (i = 0; i < ARRAY_SIZE(enic->msix); i++)
1417 if (enic->msix[i].requested)
1418 free_irq(enic->msix_entry[i].vector,
1419 enic->msix[i].devid);
1420 break;
1421 default:
1422 break;
1423 }
1424}
1425
1426static int enic_request_intr(struct enic *enic)
1427{
1428 struct net_device *netdev = enic->netdev;
1429 unsigned int i, intr;
1430 int err = 0;
1431
1432 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1433
1434 case VNIC_DEV_INTR_MODE_INTX:
1435
1436 err = request_irq(enic->pdev->irq, enic_isr_legacy,
1437 IRQF_SHARED, netdev->name, netdev);
1438 break;
1439
1440 case VNIC_DEV_INTR_MODE_MSI:
1441
1442 err = request_irq(enic->pdev->irq, enic_isr_msi,
1443 0, netdev->name, enic);
1444 break;
1445
1446 case VNIC_DEV_INTR_MODE_MSIX:
1447
1448 for (i = 0; i < enic->rq_count; i++) {
1449 intr = enic_msix_rq_intr(enic, i);
1450 sprintf(enic->msix[intr].devname,
1451 "%.11s-rx-%d", netdev->name, i);
1452 enic->msix[intr].isr = enic_isr_msix_rq;
1453 enic->msix[intr].devid = &enic->napi[i];
1454 }
1455
1456 for (i = 0; i < enic->wq_count; i++) {
1457 intr = enic_msix_wq_intr(enic, i);
1458 sprintf(enic->msix[intr].devname,
1459 "%.11s-tx-%d", netdev->name, i);
1460 enic->msix[intr].isr = enic_isr_msix_wq;
1461 enic->msix[intr].devid = enic;
1462 }
1463
1464 intr = enic_msix_err_intr(enic);
1465 sprintf(enic->msix[intr].devname,
1466 "%.11s-err", netdev->name);
1467 enic->msix[intr].isr = enic_isr_msix_err;
1468 enic->msix[intr].devid = enic;
1469
1470 intr = enic_msix_notify_intr(enic);
1471 sprintf(enic->msix[intr].devname,
1472 "%.11s-notify", netdev->name);
1473 enic->msix[intr].isr = enic_isr_msix_notify;
1474 enic->msix[intr].devid = enic;
1475
1476 for (i = 0; i < ARRAY_SIZE(enic->msix); i++)
1477 enic->msix[i].requested = 0;
1478
1479 for (i = 0; i < enic->intr_count; i++) {
1480 err = request_irq(enic->msix_entry[i].vector,
1481 enic->msix[i].isr, 0,
1482 enic->msix[i].devname,
1483 enic->msix[i].devid);
1484 if (err) {
1485 enic_free_intr(enic);
1486 break;
1487 }
1488 enic->msix[i].requested = 1;
1489 }
1490
1491 break;
1492
1493 default:
1494 break;
1495 }
1496
1497 return err;
1498}
1499
1500static void enic_synchronize_irqs(struct enic *enic)
1501{
1502 unsigned int i;
1503
1504 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1505 case VNIC_DEV_INTR_MODE_INTX:
1506 case VNIC_DEV_INTR_MODE_MSI:
1507 synchronize_irq(enic->pdev->irq);
1508 break;
1509 case VNIC_DEV_INTR_MODE_MSIX:
1510 for (i = 0; i < enic->intr_count; i++)
1511 synchronize_irq(enic->msix_entry[i].vector);
1512 break;
1513 default:
1514 break;
1515 }
1516}
1517
1518static int enic_dev_notify_set(struct enic *enic)
1519{
1520 int err;
1521
1522 spin_lock(&enic->devcmd_lock);
1523 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1524 case VNIC_DEV_INTR_MODE_INTX:
1525 err = vnic_dev_notify_set(enic->vdev,
1526 enic_legacy_notify_intr());
1527 break;
1528 case VNIC_DEV_INTR_MODE_MSIX:
1529 err = vnic_dev_notify_set(enic->vdev,
1530 enic_msix_notify_intr(enic));
1531 break;
1532 default:
1533 err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */);
1534 break;
1535 }
1536 spin_unlock(&enic->devcmd_lock);
1537
1538 return err;
1539}
1540
1541static void enic_notify_timer_start(struct enic *enic)
1542{
1543 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1544 case VNIC_DEV_INTR_MODE_MSI:
1545 mod_timer(&enic->notify_timer, jiffies);
1546 break;
1547 default:
1548 /* Using intr for notification for INTx/MSI-X */
1549 break;
1550 }
1551}
1552
1553/* rtnl lock is held, process context */
1554static int enic_open(struct net_device *netdev)
1555{
1556 struct enic *enic = netdev_priv(netdev);
1557 unsigned int i;
1558 int err;
1559
1560 err = enic_request_intr(enic);
1561 if (err) {
1562 netdev_err(netdev, "Unable to request irq.\n");
1563 return err;
1564 }
1565
1566 err = enic_dev_notify_set(enic);
1567 if (err) {
1568 netdev_err(netdev,
1569 "Failed to alloc notify buffer, aborting.\n");
1570 goto err_out_free_intr;
1571 }
1572
1573 for (i = 0; i < enic->rq_count; i++) {
1574 vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf);
1575 /* Need at least one buffer on ring to get going */
1576 if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
1577 netdev_err(netdev, "Unable to alloc receive buffers\n");
1578 err = -ENOMEM;
1579 goto err_out_notify_unset;
1580 }
1581 }
1582
1583 for (i = 0; i < enic->wq_count; i++)
1584 vnic_wq_enable(&enic->wq[i]);
1585 for (i = 0; i < enic->rq_count; i++)
1586 vnic_rq_enable(&enic->rq[i]);
1587
1588 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
1589 enic_dev_add_addr(enic, enic->pp.mac_addr);
1590 else
1591 enic_dev_add_station_addr(enic);
1592 enic_set_rx_mode(netdev);
1593
1594 netif_wake_queue(netdev);
1595
1596 for (i = 0; i < enic->rq_count; i++)
1597 napi_enable(&enic->napi[i]);
1598
1599 enic_dev_enable(enic);
1600
1601 for (i = 0; i < enic->intr_count; i++)
1602 vnic_intr_unmask(&enic->intr[i]);
1603
1604 enic_notify_timer_start(enic);
1605
1606 return 0;
1607
1608err_out_notify_unset:
1609 enic_dev_notify_unset(enic);
1610err_out_free_intr:
1611 enic_free_intr(enic);
1612
1613 return err;
1614}
1615
1616/* rtnl lock is held, process context */
1617static int enic_stop(struct net_device *netdev)
1618{
1619 struct enic *enic = netdev_priv(netdev);
1620 unsigned int i;
1621 int err;
1622
1623 for (i = 0; i < enic->intr_count; i++) {
1624 vnic_intr_mask(&enic->intr[i]);
1625 (void)vnic_intr_masked(&enic->intr[i]); /* flush write */
1626 }
1627
1628 enic_synchronize_irqs(enic);
1629
1630 del_timer_sync(&enic->notify_timer);
1631
1632 enic_dev_disable(enic);
1633
1634 for (i = 0; i < enic->rq_count; i++)
1635 napi_disable(&enic->napi[i]);
1636
1637 netif_carrier_off(netdev);
1638 netif_tx_disable(netdev);
1639 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
1640 enic_dev_del_addr(enic, enic->pp.mac_addr);
1641 else
1642 enic_dev_del_station_addr(enic);
1643
1644 for (i = 0; i < enic->wq_count; i++) {
1645 err = vnic_wq_disable(&enic->wq[i]);
1646 if (err)
1647 return err;
1648 }
1649 for (i = 0; i < enic->rq_count; i++) {
1650 err = vnic_rq_disable(&enic->rq[i]);
1651 if (err)
1652 return err;
1653 }
1654
1655 enic_dev_notify_unset(enic);
1656 enic_free_intr(enic);
1657
1658 for (i = 0; i < enic->wq_count; i++)
1659 vnic_wq_clean(&enic->wq[i], enic_free_wq_buf);
1660 for (i = 0; i < enic->rq_count; i++)
1661 vnic_rq_clean(&enic->rq[i], enic_free_rq_buf);
1662 for (i = 0; i < enic->cq_count; i++)
1663 vnic_cq_clean(&enic->cq[i]);
1664 for (i = 0; i < enic->intr_count; i++)
1665 vnic_intr_clean(&enic->intr[i]);
1666
1667 return 0;
1668}
1669
1670static int enic_change_mtu(struct net_device *netdev, int new_mtu)
1671{
1672 struct enic *enic = netdev_priv(netdev);
1673 int running = netif_running(netdev);
1674
1675 if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU)
1676 return -EINVAL;
1677
1678 if (enic_is_dynamic(enic))
1679 return -EOPNOTSUPP;
1680
1681 if (running)
1682 enic_stop(netdev);
1683
1684 netdev->mtu = new_mtu;
1685
1686 if (netdev->mtu > enic->port_mtu)
1687 netdev_warn(netdev,
1688 "interface MTU (%d) set higher than port MTU (%d)\n",
1689 netdev->mtu, enic->port_mtu);
1690
1691 if (running)
1692 enic_open(netdev);
1693
1694 return 0;
1695}
1696
1697static void enic_change_mtu_work(struct work_struct *work)
1698{
1699 struct enic *enic = container_of(work, struct enic, change_mtu_work);
1700 struct net_device *netdev = enic->netdev;
1701 int new_mtu = vnic_dev_mtu(enic->vdev);
1702 int err;
1703 unsigned int i;
1704
1705 new_mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, new_mtu));
1706
1707 rtnl_lock();
1708
1709 /* Stop RQ */
1710 del_timer_sync(&enic->notify_timer);
1711
1712 for (i = 0; i < enic->rq_count; i++)
1713 napi_disable(&enic->napi[i]);
1714
1715 vnic_intr_mask(&enic->intr[0]);
1716 enic_synchronize_irqs(enic);
1717 err = vnic_rq_disable(&enic->rq[0]);
1718 if (err) {
1719 netdev_err(netdev, "Unable to disable RQ.\n");
1720 return;
1721 }
1722 vnic_rq_clean(&enic->rq[0], enic_free_rq_buf);
1723 vnic_cq_clean(&enic->cq[0]);
1724 vnic_intr_clean(&enic->intr[0]);
1725
1726 /* Fill RQ with new_mtu-sized buffers */
1727 netdev->mtu = new_mtu;
1728 vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
1729 /* Need at least one buffer on ring to get going */
1730 if (vnic_rq_desc_used(&enic->rq[0]) == 0) {
1731 netdev_err(netdev, "Unable to alloc receive buffers.\n");
1732 return;
1733 }
1734
1735 /* Start RQ */
1736 vnic_rq_enable(&enic->rq[0]);
1737 napi_enable(&enic->napi[0]);
1738 vnic_intr_unmask(&enic->intr[0]);
1739 enic_notify_timer_start(enic);
1740
1741 rtnl_unlock();
1742
1743 netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu);
1744}
1745
1746#ifdef CONFIG_NET_POLL_CONTROLLER
1747static void enic_poll_controller(struct net_device *netdev)
1748{
1749 struct enic *enic = netdev_priv(netdev);
1750 struct vnic_dev *vdev = enic->vdev;
1751 unsigned int i, intr;
1752
1753 switch (vnic_dev_get_intr_mode(vdev)) {
1754 case VNIC_DEV_INTR_MODE_MSIX:
1755 for (i = 0; i < enic->rq_count; i++) {
1756 intr = enic_msix_rq_intr(enic, i);
1757 enic_isr_msix_rq(enic->msix_entry[intr].vector,
1758 &enic->napi[i]);
1759 }
1760
1761 for (i = 0; i < enic->wq_count; i++) {
1762 intr = enic_msix_wq_intr(enic, i);
1763 enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
1764 }
1765
1766 break;
1767 case VNIC_DEV_INTR_MODE_MSI:
1768 enic_isr_msi(enic->pdev->irq, enic);
1769 break;
1770 case VNIC_DEV_INTR_MODE_INTX:
1771 enic_isr_legacy(enic->pdev->irq, netdev);
1772 break;
1773 default:
1774 break;
1775 }
1776}
1777#endif
1778
1779static int enic_dev_wait(struct vnic_dev *vdev,
1780 int (*start)(struct vnic_dev *, int),
1781 int (*finished)(struct vnic_dev *, int *),
1782 int arg)
1783{
1784 unsigned long time;
1785 int done;
1786 int err;
1787
1788 BUG_ON(in_interrupt());
1789
1790 err = start(vdev, arg);
1791 if (err)
1792 return err;
1793
1794 /* Wait for func to complete...2 seconds max
1795 */
1796
1797 time = jiffies + (HZ * 2);
1798 do {
1799
1800 err = finished(vdev, &done);
1801 if (err)
1802 return err;
1803
1804 if (done)
1805 return 0;
1806
1807 schedule_timeout_uninterruptible(HZ / 10);
1808
1809 } while (time_after(time, jiffies));
1810
1811 return -ETIMEDOUT;
1812}
1813
1814static int enic_dev_open(struct enic *enic)
1815{
1816 int err;
1817
1818 err = enic_dev_wait(enic->vdev, vnic_dev_open,
1819 vnic_dev_open_done, 0);
1820 if (err)
1821 dev_err(enic_get_dev(enic), "vNIC device open failed, err %d\n",
1822 err);
1823
1824 return err;
1825}
1826
1827static int enic_dev_hang_reset(struct enic *enic)
1828{
1829 int err;
1830
1831 err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset,
1832 vnic_dev_hang_reset_done, 0);
1833 if (err)
1834 netdev_err(enic->netdev, "vNIC hang reset failed, err %d\n",
1835 err);
1836
1837 return err;
1838}
1839
1840static int enic_set_rsskey(struct enic *enic)
1841{
1842 dma_addr_t rss_key_buf_pa;
1843 union vnic_rss_key *rss_key_buf_va = NULL;
1844 union vnic_rss_key rss_key = {
1845 .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101},
1846 .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101},
1847 .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115},
1848 .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108},
1849 };
1850 int err;
1851
1852 rss_key_buf_va = pci_alloc_consistent(enic->pdev,
1853 sizeof(union vnic_rss_key), &rss_key_buf_pa);
1854 if (!rss_key_buf_va)
1855 return -ENOMEM;
1856
1857 memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key));
1858
1859 spin_lock(&enic->devcmd_lock);
1860 err = enic_set_rss_key(enic,
1861 rss_key_buf_pa,
1862 sizeof(union vnic_rss_key));
1863 spin_unlock(&enic->devcmd_lock);
1864
1865 pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key),
1866 rss_key_buf_va, rss_key_buf_pa);
1867
1868 return err;
1869}
1870
1871static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits)
1872{
1873 dma_addr_t rss_cpu_buf_pa;
1874 union vnic_rss_cpu *rss_cpu_buf_va = NULL;
1875 unsigned int i;
1876 int err;
1877
1878 rss_cpu_buf_va = pci_alloc_consistent(enic->pdev,
1879 sizeof(union vnic_rss_cpu), &rss_cpu_buf_pa);
1880 if (!rss_cpu_buf_va)
1881 return -ENOMEM;
1882
1883 for (i = 0; i < (1 << rss_hash_bits); i++)
1884 (*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count;
1885
1886 spin_lock(&enic->devcmd_lock);
1887 err = enic_set_rss_cpu(enic,
1888 rss_cpu_buf_pa,
1889 sizeof(union vnic_rss_cpu));
1890 spin_unlock(&enic->devcmd_lock);
1891
1892 pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu),
1893 rss_cpu_buf_va, rss_cpu_buf_pa);
1894
1895 return err;
1896}
1897
1898static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu,
1899 u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable)
1900{
1901 const u8 tso_ipid_split_en = 0;
1902 const u8 ig_vlan_strip_en = 1;
1903 int err;
1904
1905 /* Enable VLAN tag stripping.
1906 */
1907
1908 spin_lock(&enic->devcmd_lock);
1909 err = enic_set_nic_cfg(enic,
1910 rss_default_cpu, rss_hash_type,
1911 rss_hash_bits, rss_base_cpu,
1912 rss_enable, tso_ipid_split_en,
1913 ig_vlan_strip_en);
1914 spin_unlock(&enic->devcmd_lock);
1915
1916 return err;
1917}
1918
1919static int enic_set_rss_nic_cfg(struct enic *enic)
1920{
1921 struct device *dev = enic_get_dev(enic);
1922 const u8 rss_default_cpu = 0;
1923 const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
1924 NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
1925 NIC_CFG_RSS_HASH_TYPE_IPV6 |
1926 NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
1927 const u8 rss_hash_bits = 7;
1928 const u8 rss_base_cpu = 0;
1929 u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
1930
1931 if (rss_enable) {
1932 if (!enic_set_rsskey(enic)) {
1933 if (enic_set_rsscpu(enic, rss_hash_bits)) {
1934 rss_enable = 0;
1935 dev_warn(dev, "RSS disabled, "
1936 "Failed to set RSS cpu indirection table.");
1937 }
1938 } else {
1939 rss_enable = 0;
1940 dev_warn(dev, "RSS disabled, Failed to set RSS key.\n");
1941 }
1942 }
1943
1944 return enic_set_niccfg(enic, rss_default_cpu, rss_hash_type,
1945 rss_hash_bits, rss_base_cpu, rss_enable);
1946}
1947
1948static void enic_reset(struct work_struct *work)
1949{
1950 struct enic *enic = container_of(work, struct enic, reset);
1951
1952 if (!netif_running(enic->netdev))
1953 return;
1954
1955 rtnl_lock();
1956
1957 enic_dev_hang_notify(enic);
1958 enic_stop(enic->netdev);
1959 enic_dev_hang_reset(enic);
1960 enic_reset_addr_lists(enic);
1961 enic_init_vnic_resources(enic);
1962 enic_set_rss_nic_cfg(enic);
1963 enic_dev_set_ig_vlan_rewrite_mode(enic);
1964 enic_open(enic->netdev);
1965
1966 rtnl_unlock();
1967}
1968
1969static int enic_set_intr_mode(struct enic *enic)
1970{
1971 unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX);
1972 unsigned int m = min_t(unsigned int, enic->wq_count, ENIC_WQ_MAX);
1973 unsigned int i;
1974
1975 /* Set interrupt mode (INTx, MSI, MSI-X) depending
1976 * on system capabilities.
1977 *
1978 * Try MSI-X first
1979 *
1980 * We need n RQs, m WQs, n+m CQs, and n+m+2 INTRs
1981 * (the second to last INTR is used for WQ/RQ errors)
1982 * (the last INTR is used for notifications)
1983 */
1984
1985 BUG_ON(ARRAY_SIZE(enic->msix_entry) < n + m + 2);
1986 for (i = 0; i < n + m + 2; i++)
1987 enic->msix_entry[i].entry = i;
1988
1989 /* Use multiple RQs if RSS is enabled
1990 */
1991
1992 if (ENIC_SETTING(enic, RSS) &&
1993 enic->config.intr_mode < 1 &&
1994 enic->rq_count >= n &&
1995 enic->wq_count >= m &&
1996 enic->cq_count >= n + m &&
1997 enic->intr_count >= n + m + 2) {
1998
1999 if (!pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) {
2000
2001 enic->rq_count = n;
2002 enic->wq_count = m;
2003 enic->cq_count = n + m;
2004 enic->intr_count = n + m + 2;
2005
2006 vnic_dev_set_intr_mode(enic->vdev,
2007 VNIC_DEV_INTR_MODE_MSIX);
2008
2009 return 0;
2010 }
2011 }
2012
2013 if (enic->config.intr_mode < 1 &&
2014 enic->rq_count >= 1 &&
2015 enic->wq_count >= m &&
2016 enic->cq_count >= 1 + m &&
2017 enic->intr_count >= 1 + m + 2) {
2018 if (!pci_enable_msix(enic->pdev, enic->msix_entry, 1 + m + 2)) {
2019
2020 enic->rq_count = 1;
2021 enic->wq_count = m;
2022 enic->cq_count = 1 + m;
2023 enic->intr_count = 1 + m + 2;
2024
2025 vnic_dev_set_intr_mode(enic->vdev,
2026 VNIC_DEV_INTR_MODE_MSIX);
2027
2028 return 0;
2029 }
2030 }
2031
2032 /* Next try MSI
2033 *
2034 * We need 1 RQ, 1 WQ, 2 CQs, and 1 INTR
2035 */
2036
2037 if (enic->config.intr_mode < 2 &&
2038 enic->rq_count >= 1 &&
2039 enic->wq_count >= 1 &&
2040 enic->cq_count >= 2 &&
2041 enic->intr_count >= 1 &&
2042 !pci_enable_msi(enic->pdev)) {
2043
2044 enic->rq_count = 1;
2045 enic->wq_count = 1;
2046 enic->cq_count = 2;
2047 enic->intr_count = 1;
2048
2049 vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSI);
2050
2051 return 0;
2052 }
2053
2054 /* Next try INTx
2055 *
2056 * We need 1 RQ, 1 WQ, 2 CQs, and 3 INTRs
2057 * (the first INTR is used for WQ/RQ)
2058 * (the second INTR is used for WQ/RQ errors)
2059 * (the last INTR is used for notifications)
2060 */
2061
2062 if (enic->config.intr_mode < 3 &&
2063 enic->rq_count >= 1 &&
2064 enic->wq_count >= 1 &&
2065 enic->cq_count >= 2 &&
2066 enic->intr_count >= 3) {
2067
2068 enic->rq_count = 1;
2069 enic->wq_count = 1;
2070 enic->cq_count = 2;
2071 enic->intr_count = 3;
2072
2073 vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_INTX);
2074
2075 return 0;
2076 }
2077
2078 vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_UNKNOWN);
2079
2080 return -EINVAL;
2081}
2082
2083static void enic_clear_intr_mode(struct enic *enic)
2084{
2085 switch (vnic_dev_get_intr_mode(enic->vdev)) {
2086 case VNIC_DEV_INTR_MODE_MSIX:
2087 pci_disable_msix(enic->pdev);
2088 break;
2089 case VNIC_DEV_INTR_MODE_MSI:
2090 pci_disable_msi(enic->pdev);
2091 break;
2092 default:
2093 break;
2094 }
2095
2096 vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_UNKNOWN);
2097}
2098
2099static const struct net_device_ops enic_netdev_dynamic_ops = {
2100 .ndo_open = enic_open,
2101 .ndo_stop = enic_stop,
2102 .ndo_start_xmit = enic_hard_start_xmit,
2103 .ndo_get_stats64 = enic_get_stats,
2104 .ndo_validate_addr = eth_validate_addr,
2105 .ndo_set_rx_mode = enic_set_rx_mode,
2106 .ndo_set_multicast_list = enic_set_rx_mode,
2107 .ndo_set_mac_address = enic_set_mac_address_dynamic,
2108 .ndo_change_mtu = enic_change_mtu,
2109 .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
2110 .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
2111 .ndo_tx_timeout = enic_tx_timeout,
2112 .ndo_set_vf_port = enic_set_vf_port,
2113 .ndo_get_vf_port = enic_get_vf_port,
2114 .ndo_set_vf_mac = enic_set_vf_mac,
2115#ifdef CONFIG_NET_POLL_CONTROLLER
2116 .ndo_poll_controller = enic_poll_controller,
2117#endif
2118};
2119
2120static const struct net_device_ops enic_netdev_ops = {
2121 .ndo_open = enic_open,
2122 .ndo_stop = enic_stop,
2123 .ndo_start_xmit = enic_hard_start_xmit,
2124 .ndo_get_stats64 = enic_get_stats,
2125 .ndo_validate_addr = eth_validate_addr,
2126 .ndo_set_mac_address = enic_set_mac_address,
2127 .ndo_set_rx_mode = enic_set_rx_mode,
2128 .ndo_set_multicast_list = enic_set_rx_mode,
2129 .ndo_change_mtu = enic_change_mtu,
2130 .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
2131 .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
2132 .ndo_tx_timeout = enic_tx_timeout,
2133#ifdef CONFIG_NET_POLL_CONTROLLER
2134 .ndo_poll_controller = enic_poll_controller,
2135#endif
2136};
2137
2138static void enic_dev_deinit(struct enic *enic)
2139{
2140 unsigned int i;
2141
2142 for (i = 0; i < enic->rq_count; i++)
2143 netif_napi_del(&enic->napi[i]);
2144
2145 enic_free_vnic_resources(enic);
2146 enic_clear_intr_mode(enic);
2147}
2148
2149static int enic_dev_init(struct enic *enic)
2150{
2151 struct device *dev = enic_get_dev(enic);
2152 struct net_device *netdev = enic->netdev;
2153 unsigned int i;
2154 int err;
2155
2156 /* Get interrupt coalesce timer info */
2157 err = enic_dev_intr_coal_timer_info(enic);
2158 if (err) {
2159 dev_warn(dev, "Using default conversion factor for "
2160 "interrupt coalesce timer\n");
2161 vnic_dev_intr_coal_timer_info_default(enic->vdev);
2162 }
2163
2164 /* Get vNIC configuration
2165 */
2166
2167 err = enic_get_vnic_config(enic);
2168 if (err) {
2169 dev_err(dev, "Get vNIC configuration failed, aborting\n");
2170 return err;
2171 }
2172
2173 /* Get available resource counts
2174 */
2175
2176 enic_get_res_counts(enic);
2177
2178 /* Set interrupt mode based on resource counts and system
2179 * capabilities
2180 */
2181
2182 err = enic_set_intr_mode(enic);
2183 if (err) {
2184 dev_err(dev, "Failed to set intr mode based on resource "
2185 "counts and system capabilities, aborting\n");
2186 return err;
2187 }
2188
2189 /* Allocate and configure vNIC resources
2190 */
2191
2192 err = enic_alloc_vnic_resources(enic);
2193 if (err) {
2194 dev_err(dev, "Failed to alloc vNIC resources, aborting\n");
2195 goto err_out_free_vnic_resources;
2196 }
2197
2198 enic_init_vnic_resources(enic);
2199
2200 err = enic_set_rss_nic_cfg(enic);
2201 if (err) {
2202 dev_err(dev, "Failed to config nic, aborting\n");
2203 goto err_out_free_vnic_resources;
2204 }
2205
2206 switch (vnic_dev_get_intr_mode(enic->vdev)) {
2207 default:
2208 netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
2209 break;
2210 case VNIC_DEV_INTR_MODE_MSIX:
2211 for (i = 0; i < enic->rq_count; i++)
2212 netif_napi_add(netdev, &enic->napi[i],
2213 enic_poll_msix, 64);
2214 break;
2215 }
2216
2217 return 0;
2218
2219err_out_free_vnic_resources:
2220 enic_clear_intr_mode(enic);
2221 enic_free_vnic_resources(enic);
2222
2223 return err;
2224}
2225
2226static void enic_iounmap(struct enic *enic)
2227{
2228 unsigned int i;
2229
2230 for (i = 0; i < ARRAY_SIZE(enic->bar); i++)
2231 if (enic->bar[i].vaddr)
2232 iounmap(enic->bar[i].vaddr);
2233}
2234
2235static int __devinit enic_probe(struct pci_dev *pdev,
2236 const struct pci_device_id *ent)
2237{
2238 struct device *dev = &pdev->dev;
2239 struct net_device *netdev;
2240 struct enic *enic;
2241 int using_dac = 0;
2242 unsigned int i;
2243 int err;
2244
2245 /* Allocate net device structure and initialize. Private
2246 * instance data is initialized to zero.
2247 */
2248
2249 netdev = alloc_etherdev(sizeof(struct enic));
2250 if (!netdev) {
2251 pr_err("Etherdev alloc failed, aborting\n");
2252 return -ENOMEM;
2253 }
2254
2255 pci_set_drvdata(pdev, netdev);
2256
2257 SET_NETDEV_DEV(netdev, &pdev->dev);
2258
2259 enic = netdev_priv(netdev);
2260 enic->netdev = netdev;
2261 enic->pdev = pdev;
2262
2263 /* Setup PCI resources
2264 */
2265
2266 err = pci_enable_device_mem(pdev);
2267 if (err) {
2268 dev_err(dev, "Cannot enable PCI device, aborting\n");
2269 goto err_out_free_netdev;
2270 }
2271
2272 err = pci_request_regions(pdev, DRV_NAME);
2273 if (err) {
2274 dev_err(dev, "Cannot request PCI regions, aborting\n");
2275 goto err_out_disable_device;
2276 }
2277
2278 pci_set_master(pdev);
2279
2280 /* Query PCI controller on system for DMA addressing
2281 * limitation for the device. Try 40-bit first, and
2282 * fail to 32-bit.
2283 */
2284
2285 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
2286 if (err) {
2287 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2288 if (err) {
2289 dev_err(dev, "No usable DMA configuration, aborting\n");
2290 goto err_out_release_regions;
2291 }
2292 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2293 if (err) {
2294 dev_err(dev, "Unable to obtain %u-bit DMA "
2295 "for consistent allocations, aborting\n", 32);
2296 goto err_out_release_regions;
2297 }
2298 } else {
2299 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
2300 if (err) {
2301 dev_err(dev, "Unable to obtain %u-bit DMA "
2302 "for consistent allocations, aborting\n", 40);
2303 goto err_out_release_regions;
2304 }
2305 using_dac = 1;
2306 }
2307
2308 /* Map vNIC resources from BAR0-5
2309 */
2310
2311 for (i = 0; i < ARRAY_SIZE(enic->bar); i++) {
2312 if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
2313 continue;
2314 enic->bar[i].len = pci_resource_len(pdev, i);
2315 enic->bar[i].vaddr = pci_iomap(pdev, i, enic->bar[i].len);
2316 if (!enic->bar[i].vaddr) {
2317 dev_err(dev, "Cannot memory-map BAR %d, aborting\n", i);
2318 err = -ENODEV;
2319 goto err_out_iounmap;
2320 }
2321 enic->bar[i].bus_addr = pci_resource_start(pdev, i);
2322 }
2323
2324 /* Register vNIC device
2325 */
2326
2327 enic->vdev = vnic_dev_register(NULL, enic, pdev, enic->bar,
2328 ARRAY_SIZE(enic->bar));
2329 if (!enic->vdev) {
2330 dev_err(dev, "vNIC registration failed, aborting\n");
2331 err = -ENODEV;
2332 goto err_out_iounmap;
2333 }
2334
2335 /* Issue device open to get device in known state
2336 */
2337
2338 err = enic_dev_open(enic);
2339 if (err) {
2340 dev_err(dev, "vNIC dev open failed, aborting\n");
2341 goto err_out_vnic_unregister;
2342 }
2343
2344 /* Setup devcmd lock
2345 */
2346
2347 spin_lock_init(&enic->devcmd_lock);
2348
2349 /*
2350 * Set ingress vlan rewrite mode before vnic initialization
2351 */
2352
2353 err = enic_dev_set_ig_vlan_rewrite_mode(enic);
2354 if (err) {
2355 dev_err(dev,
2356 "Failed to set ingress vlan rewrite mode, aborting.\n");
2357 goto err_out_dev_close;
2358 }
2359
2360 /* Issue device init to initialize the vnic-to-switch link.
2361 * We'll start with carrier off and wait for link UP
2362 * notification later to turn on carrier. We don't need
2363 * to wait here for the vnic-to-switch link initialization
2364 * to complete; link UP notification is the indication that
2365 * the process is complete.
2366 */
2367
2368 netif_carrier_off(netdev);
2369
2370 /* Do not call dev_init for a dynamic vnic.
2371 * For a dynamic vnic, init_prov_info will be
2372 * called later by an upper layer.
2373 */
2374
2375 if (!enic_is_dynamic(enic)) {
2376 err = vnic_dev_init(enic->vdev, 0);
2377 if (err) {
2378 dev_err(dev, "vNIC dev init failed, aborting\n");
2379 goto err_out_dev_close;
2380 }
2381 }
2382
2383 err = enic_dev_init(enic);
2384 if (err) {
2385 dev_err(dev, "Device initialization failed, aborting\n");
2386 goto err_out_dev_close;
2387 }
2388
2389 /* Setup notification timer, HW reset task, and wq locks
2390 */
2391
2392 init_timer(&enic->notify_timer);
2393 enic->notify_timer.function = enic_notify_timer;
2394 enic->notify_timer.data = (unsigned long)enic;
2395
2396 INIT_WORK(&enic->reset, enic_reset);
2397 INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work);
2398
2399 for (i = 0; i < enic->wq_count; i++)
2400 spin_lock_init(&enic->wq_lock[i]);
2401
2402 /* Register net device
2403 */
2404
2405 enic->port_mtu = enic->config.mtu;
2406 (void)enic_change_mtu(netdev, enic->port_mtu);
2407
2408 err = enic_set_mac_addr(netdev, enic->mac_addr);
2409 if (err) {
2410 dev_err(dev, "Invalid MAC address, aborting\n");
2411 goto err_out_dev_deinit;
2412 }
2413
2414 enic->tx_coalesce_usecs = enic->config.intr_timer_usec;
2415 enic->rx_coalesce_usecs = enic->tx_coalesce_usecs;
2416
2417 if (enic_is_dynamic(enic))
2418 netdev->netdev_ops = &enic_netdev_dynamic_ops;
2419 else
2420 netdev->netdev_ops = &enic_netdev_ops;
2421
2422 netdev->watchdog_timeo = 2 * HZ;
2423 netdev->ethtool_ops = &enic_ethtool_ops;
2424
2425 netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
2426 if (ENIC_SETTING(enic, LOOP)) {
2427 netdev->features &= ~NETIF_F_HW_VLAN_TX;
2428 enic->loop_enable = 1;
2429 enic->loop_tag = enic->config.loop_tag;
2430 dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
2431 }
2432 if (ENIC_SETTING(enic, TXCSUM))
2433 netdev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
2434 if (ENIC_SETTING(enic, TSO))
2435 netdev->hw_features |= NETIF_F_TSO |
2436 NETIF_F_TSO6 | NETIF_F_TSO_ECN;
2437 if (ENIC_SETTING(enic, RXCSUM))
2438 netdev->hw_features |= NETIF_F_RXCSUM;
2439
2440 netdev->features |= netdev->hw_features;
2441
2442 if (using_dac)
2443 netdev->features |= NETIF_F_HIGHDMA;
2444
2445 err = register_netdev(netdev);
2446 if (err) {
2447 dev_err(dev, "Cannot register net device, aborting\n");
2448 goto err_out_dev_deinit;
2449 }
2450
2451 return 0;
2452
2453err_out_dev_deinit:
2454 enic_dev_deinit(enic);
2455err_out_dev_close:
2456 vnic_dev_close(enic->vdev);
2457err_out_vnic_unregister:
2458 vnic_dev_unregister(enic->vdev);
2459err_out_iounmap:
2460 enic_iounmap(enic);
2461err_out_release_regions:
2462 pci_release_regions(pdev);
2463err_out_disable_device:
2464 pci_disable_device(pdev);
2465err_out_free_netdev:
2466 pci_set_drvdata(pdev, NULL);
2467 free_netdev(netdev);
2468
2469 return err;
2470}
2471
2472static void __devexit enic_remove(struct pci_dev *pdev)
2473{
2474 struct net_device *netdev = pci_get_drvdata(pdev);
2475
2476 if (netdev) {
2477 struct enic *enic = netdev_priv(netdev);
2478
2479 cancel_work_sync(&enic->reset);
2480 cancel_work_sync(&enic->change_mtu_work);
2481 unregister_netdev(netdev);
2482 enic_dev_deinit(enic);
2483 vnic_dev_close(enic->vdev);
2484 vnic_dev_unregister(enic->vdev);
2485 enic_iounmap(enic);
2486 pci_release_regions(pdev);
2487 pci_disable_device(pdev);
2488 pci_set_drvdata(pdev, NULL);
2489 free_netdev(netdev);
2490 }
2491}
2492
2493static struct pci_driver enic_driver = {
2494 .name = DRV_NAME,
2495 .id_table = enic_id_table,
2496 .probe = enic_probe,
2497 .remove = __devexit_p(enic_remove),
2498};
2499
2500static int __init enic_init_module(void)
2501{
2502 pr_info("%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
2503
2504 return pci_register_driver(&enic_driver);
2505}
2506
2507static void __exit enic_cleanup_module(void)
2508{
2509 pci_unregister_driver(&enic_driver);
2510}
2511
2512module_init(enic_init_module);
2513module_exit(enic_cleanup_module);
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
new file mode 100644
index 000000000000..ffaa75dd1ded
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -0,0 +1,264 @@
1/*
2 * Copyright 2011 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/string.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/netdevice.h>
24#include <linux/etherdevice.h>
25#include <linux/rtnetlink.h>
26#include <net/ip.h>
27
28#include "vnic_vic.h"
29#include "enic_res.h"
30#include "enic.h"
31#include "enic_dev.h"
32
33static int enic_set_port_profile(struct enic *enic)
34{
35 struct net_device *netdev = enic->netdev;
36 struct vic_provinfo *vp;
37 const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
38 const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
39 char uuid_str[38];
40 char client_mac_str[18];
41 u8 *client_mac;
42 int err;
43
44 if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
45 return -EINVAL;
46
47 vp = vic_provinfo_alloc(GFP_KERNEL, oui,
48 VIC_PROVINFO_GENERIC_TYPE);
49 if (!vp)
50 return -ENOMEM;
51
52 VIC_PROVINFO_ADD_TLV(vp,
53 VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
54 strlen(enic->pp.name) + 1, enic->pp.name);
55
56 if (!is_zero_ether_addr(enic->pp.mac_addr))
57 client_mac = enic->pp.mac_addr;
58 else
59 client_mac = netdev->dev_addr;
60
61 VIC_PROVINFO_ADD_TLV(vp,
62 VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
63 ETH_ALEN, client_mac);
64
65 snprintf(client_mac_str, sizeof(client_mac_str), "%pM", client_mac);
66 VIC_PROVINFO_ADD_TLV(vp,
67 VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
68 sizeof(client_mac_str), client_mac_str);
69
70 if (enic->pp.set & ENIC_SET_INSTANCE) {
71 sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
72 VIC_PROVINFO_ADD_TLV(vp,
73 VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
74 sizeof(uuid_str), uuid_str);
75 }
76
77 if (enic->pp.set & ENIC_SET_HOST) {
78 sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
79 VIC_PROVINFO_ADD_TLV(vp,
80 VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
81 sizeof(uuid_str), uuid_str);
82 }
83
84 VIC_PROVINFO_ADD_TLV(vp,
85 VIC_GENERIC_PROV_TLV_OS_TYPE,
86 sizeof(os_type), &os_type);
87
88 err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp));
89
90add_tlv_failure:
91 vic_provinfo_free(vp);
92
93 return err;
94}
95
96static int enic_unset_port_profile(struct enic *enic)
97{
98 int err;
99
100 err = enic_vnic_dev_deinit(enic);
101 if (err)
102 return enic_dev_status_to_errno(err);
103
104 enic_reset_addr_lists(enic);
105
106 return 0;
107}
108
109static int enic_are_pp_different(struct enic_port_profile *pp1,
110 struct enic_port_profile *pp2)
111{
112 return strcmp(pp1->name, pp2->name) | !!memcmp(pp1->instance_uuid,
113 pp2->instance_uuid, PORT_UUID_MAX) |
114 !!memcmp(pp1->host_uuid, pp2->host_uuid, PORT_UUID_MAX) |
115 !!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
116}
117
118static int enic_pp_preassociate(struct enic *enic,
119 struct enic_port_profile *prev_pp, int *restore_pp);
120static int enic_pp_disassociate(struct enic *enic,
121 struct enic_port_profile *prev_pp, int *restore_pp);
122static int enic_pp_preassociate_rr(struct enic *enic,
123 struct enic_port_profile *prev_pp, int *restore_pp);
124static int enic_pp_associate(struct enic *enic,
125 struct enic_port_profile *prev_pp, int *restore_pp);
126
127static int (*enic_pp_handlers[])(struct enic *enic,
128 struct enic_port_profile *prev_state, int *restore_pp) = {
129 [PORT_REQUEST_PREASSOCIATE] = enic_pp_preassociate,
130 [PORT_REQUEST_PREASSOCIATE_RR] = enic_pp_preassociate_rr,
131 [PORT_REQUEST_ASSOCIATE] = enic_pp_associate,
132 [PORT_REQUEST_DISASSOCIATE] = enic_pp_disassociate,
133};
134
135static const int enic_pp_handlers_count =
136 sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
137
138static int enic_pp_preassociate(struct enic *enic,
139 struct enic_port_profile *prev_pp, int *restore_pp)
140{
141 return -EOPNOTSUPP;
142}
143
144static int enic_pp_disassociate(struct enic *enic,
145 struct enic_port_profile *prev_pp, int *restore_pp)
146{
147 return enic_unset_port_profile(enic);
148}
149
150static int enic_pp_preassociate_rr(struct enic *enic,
151 struct enic_port_profile *prev_pp, int *restore_pp)
152{
153 int err;
154 int active = 0;
155
156 if (enic->pp.request != PORT_REQUEST_ASSOCIATE) {
157 /* If pre-associate is not part of an associate.
158 We always disassociate first */
159 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic,
160 prev_pp, restore_pp);
161 if (err)
162 return err;
163
164 *restore_pp = 0;
165 }
166
167 *restore_pp = 0;
168
169 err = enic_set_port_profile(enic);
170 if (err)
171 return err;
172
173 /* If pre-associate is not part of an associate. */
174 if (enic->pp.request != PORT_REQUEST_ASSOCIATE)
175 err = enic_dev_status_to_errno(enic_dev_enable2(enic, active));
176
177 return err;
178}
179
180static int enic_pp_associate(struct enic *enic,
181 struct enic_port_profile *prev_pp, int *restore_pp)
182{
183 int err;
184 int active = 1;
185
186 /* Check if a pre-associate was called before */
187 if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
188 (prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
189 enic_are_pp_different(prev_pp, &enic->pp))) {
190 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
191 enic, prev_pp, restore_pp);
192 if (err)
193 return err;
194
195 *restore_pp = 0;
196 }
197
198 err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
199 enic, prev_pp, restore_pp);
200 if (err)
201 return err;
202
203 *restore_pp = 0;
204
205 return enic_dev_status_to_errno(enic_dev_enable2(enic, active));
206}
207
208int enic_process_set_pp_request(struct enic *enic,
209 struct enic_port_profile *prev_pp, int *restore_pp)
210{
211 if (enic->pp.request < enic_pp_handlers_count
212 && enic_pp_handlers[enic->pp.request])
213 return enic_pp_handlers[enic->pp.request](enic,
214 prev_pp, restore_pp);
215 else
216 return -EOPNOTSUPP;
217}
218
219int enic_process_get_pp_request(struct enic *enic, int request,
220 u16 *response)
221{
222 int err, status = ERR_SUCCESS;
223
224 switch (request) {
225
226 case PORT_REQUEST_PREASSOCIATE_RR:
227 case PORT_REQUEST_ASSOCIATE:
228 err = enic_dev_enable2_done(enic, &status);
229 break;
230
231 case PORT_REQUEST_DISASSOCIATE:
232 err = enic_dev_deinit_done(enic, &status);
233 break;
234
235 default:
236 return -EINVAL;
237 }
238
239 if (err)
240 status = err;
241
242 switch (status) {
243 case ERR_SUCCESS:
244 *response = PORT_PROFILE_RESPONSE_SUCCESS;
245 break;
246 case ERR_EINVAL:
247 *response = PORT_PROFILE_RESPONSE_INVALID;
248 break;
249 case ERR_EBADSTATE:
250 *response = PORT_PROFILE_RESPONSE_BADSTATE;
251 break;
252 case ERR_ENOMEM:
253 *response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES;
254 break;
255 case ERR_EINPROGRESS:
256 *response = PORT_PROFILE_RESPONSE_INPROGRESS;
257 break;
258 default:
259 *response = PORT_PROFILE_RESPONSE_ERROR;
260 break;
261 }
262
263 return 0;
264}
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.h b/drivers/net/ethernet/cisco/enic/enic_pp.h
new file mode 100644
index 000000000000..699e365a944d
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright 2011 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef _ENIC_PP_H_
20#define _ENIC_PP_H_
21
22int enic_process_set_pp_request(struct enic *enic,
23 struct enic_port_profile *prev_pp, int *restore_pp);
24int enic_process_get_pp_request(struct enic *enic, int request,
25 u16 *response);
26
27#endif /* _ENIC_PP_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_res.c b/drivers/net/ethernet/cisco/enic/enic_res.c
new file mode 100644
index 000000000000..4a35367de790
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_res.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/netdevice.h>
25
26#include "wq_enet_desc.h"
27#include "rq_enet_desc.h"
28#include "cq_enet_desc.h"
29#include "vnic_resource.h"
30#include "vnic_enet.h"
31#include "vnic_dev.h"
32#include "vnic_wq.h"
33#include "vnic_rq.h"
34#include "vnic_cq.h"
35#include "vnic_intr.h"
36#include "vnic_stats.h"
37#include "vnic_nic.h"
38#include "vnic_rss.h"
39#include "enic_res.h"
40#include "enic.h"
41
42int enic_get_vnic_config(struct enic *enic)
43{
44 struct vnic_enet_config *c = &enic->config;
45 int err;
46
47 err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr);
48 if (err) {
49 dev_err(enic_get_dev(enic),
50 "Error getting MAC addr, %d\n", err);
51 return err;
52 }
53
54#define GET_CONFIG(m) \
55 do { \
56 err = vnic_dev_spec(enic->vdev, \
57 offsetof(struct vnic_enet_config, m), \
58 sizeof(c->m), &c->m); \
59 if (err) { \
60 dev_err(enic_get_dev(enic), \
61 "Error getting %s, %d\n", #m, err); \
62 return err; \
63 } \
64 } while (0)
65
66 GET_CONFIG(flags);
67 GET_CONFIG(wq_desc_count);
68 GET_CONFIG(rq_desc_count);
69 GET_CONFIG(mtu);
70 GET_CONFIG(intr_timer_type);
71 GET_CONFIG(intr_mode);
72 GET_CONFIG(intr_timer_usec);
73 GET_CONFIG(loop_tag);
74
75 c->wq_desc_count =
76 min_t(u32, ENIC_MAX_WQ_DESCS,
77 max_t(u32, ENIC_MIN_WQ_DESCS,
78 c->wq_desc_count));
79 c->wq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
80
81 c->rq_desc_count =
82 min_t(u32, ENIC_MAX_RQ_DESCS,
83 max_t(u32, ENIC_MIN_RQ_DESCS,
84 c->rq_desc_count));
85 c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
86
87 if (c->mtu == 0)
88 c->mtu = 1500;
89 c->mtu = min_t(u16, ENIC_MAX_MTU,
90 max_t(u16, ENIC_MIN_MTU,
91 c->mtu));
92
93 c->intr_timer_usec = min_t(u32, c->intr_timer_usec,
94 vnic_dev_get_intr_coal_timer_max(enic->vdev));
95
96 dev_info(enic_get_dev(enic),
97 "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
98 enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu);
99
100 dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s "
101 "tso/lro %s/%s rss %s intr mode %s type %s timer %d usec "
102 "loopback tag 0x%04x\n",
103 ENIC_SETTING(enic, TXCSUM) ? "yes" : "no",
104 ENIC_SETTING(enic, RXCSUM) ? "yes" : "no",
105 ENIC_SETTING(enic, TSO) ? "yes" : "no",
106 ENIC_SETTING(enic, LRO) ? "yes" : "no",
107 ENIC_SETTING(enic, RSS) ? "yes" : "no",
108 c->intr_mode == VENET_INTR_MODE_INTX ? "INTx" :
109 c->intr_mode == VENET_INTR_MODE_MSI ? "MSI" :
110 c->intr_mode == VENET_INTR_MODE_ANY ? "any" :
111 "unknown",
112 c->intr_timer_type == VENET_INTR_TYPE_MIN ? "min" :
113 c->intr_timer_type == VENET_INTR_TYPE_IDLE ? "idle" :
114 "unknown",
115 c->intr_timer_usec,
116 c->loop_tag);
117
118 return 0;
119}
120
121int enic_add_vlan(struct enic *enic, u16 vlanid)
122{
123 u64 a0 = vlanid, a1 = 0;
124 int wait = 1000;
125 int err;
126
127 err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait);
128 if (err)
129 dev_err(enic_get_dev(enic), "Can't add vlan id, %d\n", err);
130
131 return err;
132}
133
134int enic_del_vlan(struct enic *enic, u16 vlanid)
135{
136 u64 a0 = vlanid, a1 = 0;
137 int wait = 1000;
138 int err;
139
140 err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait);
141 if (err)
142 dev_err(enic_get_dev(enic), "Can't delete vlan id, %d\n", err);
143
144 return err;
145}
146
147int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
148 u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
149 u8 ig_vlan_strip_en)
150{
151 u64 a0, a1;
152 u32 nic_cfg;
153 int wait = 1000;
154
155 vnic_set_nic_cfg(&nic_cfg, rss_default_cpu,
156 rss_hash_type, rss_hash_bits, rss_base_cpu,
157 rss_enable, tso_ipid_split_en, ig_vlan_strip_en);
158
159 a0 = nic_cfg;
160 a1 = 0;
161
162 return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait);
163}
164
165int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len)
166{
167 u64 a0 = (u64)key_pa, a1 = len;
168 int wait = 1000;
169
170 return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait);
171}
172
173int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len)
174{
175 u64 a0 = (u64)cpu_pa, a1 = len;
176 int wait = 1000;
177
178 return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait);
179}
180
181void enic_free_vnic_resources(struct enic *enic)
182{
183 unsigned int i;
184
185 for (i = 0; i < enic->wq_count; i++)
186 vnic_wq_free(&enic->wq[i]);
187 for (i = 0; i < enic->rq_count; i++)
188 vnic_rq_free(&enic->rq[i]);
189 for (i = 0; i < enic->cq_count; i++)
190 vnic_cq_free(&enic->cq[i]);
191 for (i = 0; i < enic->intr_count; i++)
192 vnic_intr_free(&enic->intr[i]);
193}
194
195void enic_get_res_counts(struct enic *enic)
196{
197 enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ);
198 enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ);
199 enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ);
200 enic->intr_count = vnic_dev_get_res_count(enic->vdev,
201 RES_TYPE_INTR_CTRL);
202
203 dev_info(enic_get_dev(enic),
204 "vNIC resources avail: wq %d rq %d cq %d intr %d\n",
205 enic->wq_count, enic->rq_count,
206 enic->cq_count, enic->intr_count);
207}
208
209void enic_init_vnic_resources(struct enic *enic)
210{
211 enum vnic_dev_intr_mode intr_mode;
212 unsigned int mask_on_assertion;
213 unsigned int interrupt_offset;
214 unsigned int error_interrupt_enable;
215 unsigned int error_interrupt_offset;
216 unsigned int cq_index;
217 unsigned int i;
218
219 intr_mode = vnic_dev_get_intr_mode(enic->vdev);
220
221 /* Init RQ/WQ resources.
222 *
223 * RQ[0 - n-1] point to CQ[0 - n-1]
224 * WQ[0 - m-1] point to CQ[n - n+m-1]
225 *
226 * Error interrupt is not enabled for MSI.
227 */
228
229 switch (intr_mode) {
230 case VNIC_DEV_INTR_MODE_INTX:
231 case VNIC_DEV_INTR_MODE_MSIX:
232 error_interrupt_enable = 1;
233 error_interrupt_offset = enic->intr_count - 2;
234 break;
235 default:
236 error_interrupt_enable = 0;
237 error_interrupt_offset = 0;
238 break;
239 }
240
241 for (i = 0; i < enic->rq_count; i++) {
242 cq_index = i;
243 vnic_rq_init(&enic->rq[i],
244 cq_index,
245 error_interrupt_enable,
246 error_interrupt_offset);
247 }
248
249 for (i = 0; i < enic->wq_count; i++) {
250 cq_index = enic->rq_count + i;
251 vnic_wq_init(&enic->wq[i],
252 cq_index,
253 error_interrupt_enable,
254 error_interrupt_offset);
255 }
256
257 /* Init CQ resources
258 *
259 * CQ[0 - n+m-1] point to INTR[0] for INTx, MSI
260 * CQ[0 - n+m-1] point to INTR[0 - n+m-1] for MSI-X
261 */
262
263 for (i = 0; i < enic->cq_count; i++) {
264
265 switch (intr_mode) {
266 case VNIC_DEV_INTR_MODE_MSIX:
267 interrupt_offset = i;
268 break;
269 default:
270 interrupt_offset = 0;
271 break;
272 }
273
274 vnic_cq_init(&enic->cq[i],
275 0 /* flow_control_enable */,
276 1 /* color_enable */,
277 0 /* cq_head */,
278 0 /* cq_tail */,
279 1 /* cq_tail_color */,
280 1 /* interrupt_enable */,
281 1 /* cq_entry_enable */,
282 0 /* cq_message_enable */,
283 interrupt_offset,
284 0 /* cq_message_addr */);
285 }
286
287 /* Init INTR resources
288 *
289 * mask_on_assertion is not used for INTx due to the level-
290 * triggered nature of INTx
291 */
292
293 switch (intr_mode) {
294 case VNIC_DEV_INTR_MODE_MSI:
295 case VNIC_DEV_INTR_MODE_MSIX:
296 mask_on_assertion = 1;
297 break;
298 default:
299 mask_on_assertion = 0;
300 break;
301 }
302
303 for (i = 0; i < enic->intr_count; i++) {
304 vnic_intr_init(&enic->intr[i],
305 enic->config.intr_timer_usec,
306 enic->config.intr_timer_type,
307 mask_on_assertion);
308 }
309}
310
311int enic_alloc_vnic_resources(struct enic *enic)
312{
313 enum vnic_dev_intr_mode intr_mode;
314 unsigned int i;
315 int err;
316
317 intr_mode = vnic_dev_get_intr_mode(enic->vdev);
318
319 dev_info(enic_get_dev(enic), "vNIC resources used: "
320 "wq %d rq %d cq %d intr %d intr mode %s\n",
321 enic->wq_count, enic->rq_count,
322 enic->cq_count, enic->intr_count,
323 intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" :
324 intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" :
325 intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" :
326 "unknown");
327
328 /* Allocate queue resources
329 */
330
331 for (i = 0; i < enic->wq_count; i++) {
332 err = vnic_wq_alloc(enic->vdev, &enic->wq[i], i,
333 enic->config.wq_desc_count,
334 sizeof(struct wq_enet_desc));
335 if (err)
336 goto err_out_cleanup;
337 }
338
339 for (i = 0; i < enic->rq_count; i++) {
340 err = vnic_rq_alloc(enic->vdev, &enic->rq[i], i,
341 enic->config.rq_desc_count,
342 sizeof(struct rq_enet_desc));
343 if (err)
344 goto err_out_cleanup;
345 }
346
347 for (i = 0; i < enic->cq_count; i++) {
348 if (i < enic->rq_count)
349 err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i,
350 enic->config.rq_desc_count,
351 sizeof(struct cq_enet_rq_desc));
352 else
353 err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i,
354 enic->config.wq_desc_count,
355 sizeof(struct cq_enet_wq_desc));
356 if (err)
357 goto err_out_cleanup;
358 }
359
360 for (i = 0; i < enic->intr_count; i++) {
361 err = vnic_intr_alloc(enic->vdev, &enic->intr[i], i);
362 if (err)
363 goto err_out_cleanup;
364 }
365
366 /* Hook remaining resource
367 */
368
369 enic->legacy_pba = vnic_dev_get_res(enic->vdev,
370 RES_TYPE_INTR_PBA_LEGACY, 0);
371 if (!enic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) {
372 dev_err(enic_get_dev(enic),
373 "Failed to hook legacy pba resource\n");
374 err = -ENODEV;
375 goto err_out_cleanup;
376 }
377
378 return 0;
379
380err_out_cleanup:
381 enic_free_vnic_resources(enic);
382
383 return err;
384}
diff --git a/drivers/net/ethernet/cisco/enic/enic_res.h b/drivers/net/ethernet/cisco/enic/enic_res.h
new file mode 100644
index 000000000000..25be2734c3fe
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_res.h
@@ -0,0 +1,148 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _ENIC_RES_H_
21#define _ENIC_RES_H_
22
23#include "wq_enet_desc.h"
24#include "rq_enet_desc.h"
25#include "vnic_wq.h"
26#include "vnic_rq.h"
27
28#define ENIC_MIN_WQ_DESCS 64
29#define ENIC_MAX_WQ_DESCS 4096
30#define ENIC_MIN_RQ_DESCS 64
31#define ENIC_MAX_RQ_DESCS 4096
32
33#define ENIC_MIN_MTU 68
34#define ENIC_MAX_MTU 9000
35
36#define ENIC_MULTICAST_PERFECT_FILTERS 32
37#define ENIC_UNICAST_PERFECT_FILTERS 32
38
39#define ENIC_NON_TSO_MAX_DESC 16
40
41#define ENIC_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)
42
43static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
44 void *os_buf, dma_addr_t dma_addr, unsigned int len,
45 unsigned int mss_or_csum_offset, unsigned int hdr_len,
46 int vlan_tag_insert, unsigned int vlan_tag,
47 int offload_mode, int cq_entry, int sop, int eop, int loopback)
48{
49 struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
50
51 wq_enet_desc_enc(desc,
52 (u64)dma_addr | VNIC_PADDR_TARGET,
53 (u16)len,
54 (u16)mss_or_csum_offset,
55 (u16)hdr_len, (u8)offload_mode,
56 (u8)eop, (u8)cq_entry,
57 0, /* fcoe_encap */
58 (u8)vlan_tag_insert,
59 (u16)vlan_tag,
60 (u8)loopback);
61
62 vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
63}
64
65static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq,
66 void *os_buf, dma_addr_t dma_addr, unsigned int len,
67 int eop, int loopback)
68{
69 enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
70 0, 0, 0, 0, 0,
71 eop, 0 /* !SOP */, eop, loopback);
72}
73
74static inline void enic_queue_wq_desc(struct vnic_wq *wq, void *os_buf,
75 dma_addr_t dma_addr, unsigned int len, int vlan_tag_insert,
76 unsigned int vlan_tag, int eop, int loopback)
77{
78 enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
79 0, 0, vlan_tag_insert, vlan_tag,
80 WQ_ENET_OFFLOAD_MODE_CSUM,
81 eop, 1 /* SOP */, eop, loopback);
82}
83
84static inline void enic_queue_wq_desc_csum(struct vnic_wq *wq,
85 void *os_buf, dma_addr_t dma_addr, unsigned int len,
86 int ip_csum, int tcpudp_csum, int vlan_tag_insert,
87 unsigned int vlan_tag, int eop, int loopback)
88{
89 enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
90 (ip_csum ? 1 : 0) + (tcpudp_csum ? 2 : 0),
91 0, vlan_tag_insert, vlan_tag,
92 WQ_ENET_OFFLOAD_MODE_CSUM,
93 eop, 1 /* SOP */, eop, loopback);
94}
95
96static inline void enic_queue_wq_desc_csum_l4(struct vnic_wq *wq,
97 void *os_buf, dma_addr_t dma_addr, unsigned int len,
98 unsigned int csum_offset, unsigned int hdr_len,
99 int vlan_tag_insert, unsigned int vlan_tag, int eop, int loopback)
100{
101 enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
102 csum_offset, hdr_len, vlan_tag_insert, vlan_tag,
103 WQ_ENET_OFFLOAD_MODE_CSUM_L4,
104 eop, 1 /* SOP */, eop, loopback);
105}
106
107static inline void enic_queue_wq_desc_tso(struct vnic_wq *wq,
108 void *os_buf, dma_addr_t dma_addr, unsigned int len,
109 unsigned int mss, unsigned int hdr_len, int vlan_tag_insert,
110 unsigned int vlan_tag, int eop, int loopback)
111{
112 enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
113 mss, hdr_len, vlan_tag_insert, vlan_tag,
114 WQ_ENET_OFFLOAD_MODE_TSO,
115 eop, 1 /* SOP */, eop, loopback);
116}
117
118static inline void enic_queue_rq_desc(struct vnic_rq *rq,
119 void *os_buf, unsigned int os_buf_index,
120 dma_addr_t dma_addr, unsigned int len)
121{
122 struct rq_enet_desc *desc = vnic_rq_next_desc(rq);
123 u8 type = os_buf_index ?
124 RQ_ENET_TYPE_NOT_SOP : RQ_ENET_TYPE_ONLY_SOP;
125
126 rq_enet_desc_enc(desc,
127 (u64)dma_addr | VNIC_PADDR_TARGET,
128 type, (u16)len);
129
130 vnic_rq_post(rq, os_buf, os_buf_index, dma_addr, len);
131}
132
133struct enic;
134
135int enic_get_vnic_config(struct enic *);
136int enic_add_vlan(struct enic *enic, u16 vlanid);
137int enic_del_vlan(struct enic *enic, u16 vlanid);
138int 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,
140 u8 ig_vlan_strip_en);
141int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len);
142int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len);
143void enic_get_res_counts(struct enic *enic);
144void enic_init_vnic_resources(struct enic *enic);
145int enic_alloc_vnic_resources(struct enic *);
146void enic_free_vnic_resources(struct enic *);
147
148#endif /* _ENIC_RES_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/rq_enet_desc.h b/drivers/net/ethernet/cisco/enic/rq_enet_desc.h
new file mode 100644
index 000000000000..e6dd30988d6f
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/rq_enet_desc.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _RQ_ENET_DESC_H_
21#define _RQ_ENET_DESC_H_
22
23/* Ethernet receive queue descriptor: 16B */
24struct rq_enet_desc {
25 __le64 address;
26 __le16 length_type;
27 u8 reserved[6];
28};
29
30enum rq_enet_type_types {
31 RQ_ENET_TYPE_ONLY_SOP = 0,
32 RQ_ENET_TYPE_NOT_SOP = 1,
33 RQ_ENET_TYPE_RESV2 = 2,
34 RQ_ENET_TYPE_RESV3 = 3,
35};
36
37#define RQ_ENET_ADDR_BITS 64
38#define RQ_ENET_LEN_BITS 14
39#define RQ_ENET_LEN_MASK ((1 << RQ_ENET_LEN_BITS) - 1)
40#define RQ_ENET_TYPE_BITS 2
41#define RQ_ENET_TYPE_MASK ((1 << RQ_ENET_TYPE_BITS) - 1)
42
43static inline void rq_enet_desc_enc(struct rq_enet_desc *desc,
44 u64 address, u8 type, u16 length)
45{
46 desc->address = cpu_to_le64(address);
47 desc->length_type = cpu_to_le16((length & RQ_ENET_LEN_MASK) |
48 ((type & RQ_ENET_TYPE_MASK) << RQ_ENET_LEN_BITS));
49}
50
51static inline void rq_enet_desc_dec(struct rq_enet_desc *desc,
52 u64 *address, u8 *type, u16 *length)
53{
54 *address = le64_to_cpu(desc->address);
55 *length = le16_to_cpu(desc->length_type) & RQ_ENET_LEN_MASK;
56 *type = (u8)((le16_to_cpu(desc->length_type) >> RQ_ENET_LEN_BITS) &
57 RQ_ENET_TYPE_MASK);
58}
59
60#endif /* _RQ_ENET_DESC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_cq.c b/drivers/net/ethernet/cisco/enic/vnic_cq.c
new file mode 100644
index 000000000000..0daa1c7073cb
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_cq.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24
25#include "vnic_dev.h"
26#include "vnic_cq.h"
27
28void vnic_cq_free(struct vnic_cq *cq)
29{
30 vnic_dev_free_desc_ring(cq->vdev, &cq->ring);
31
32 cq->ctrl = NULL;
33}
34
35int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
36 unsigned int desc_count, unsigned int desc_size)
37{
38 int err;
39
40 cq->index = index;
41 cq->vdev = vdev;
42
43 cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index);
44 if (!cq->ctrl) {
45 pr_err("Failed to hook CQ[%d] resource\n", index);
46 return -EINVAL;
47 }
48
49 err = vnic_dev_alloc_desc_ring(vdev, &cq->ring, desc_count, desc_size);
50 if (err)
51 return err;
52
53 return 0;
54}
55
56void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable,
57 unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail,
58 unsigned int cq_tail_color, unsigned int interrupt_enable,
59 unsigned int cq_entry_enable, unsigned int cq_message_enable,
60 unsigned int interrupt_offset, u64 cq_message_addr)
61{
62 u64 paddr;
63
64 paddr = (u64)cq->ring.base_addr | VNIC_PADDR_TARGET;
65 writeq(paddr, &cq->ctrl->ring_base);
66 iowrite32(cq->ring.desc_count, &cq->ctrl->ring_size);
67 iowrite32(flow_control_enable, &cq->ctrl->flow_control_enable);
68 iowrite32(color_enable, &cq->ctrl->color_enable);
69 iowrite32(cq_head, &cq->ctrl->cq_head);
70 iowrite32(cq_tail, &cq->ctrl->cq_tail);
71 iowrite32(cq_tail_color, &cq->ctrl->cq_tail_color);
72 iowrite32(interrupt_enable, &cq->ctrl->interrupt_enable);
73 iowrite32(cq_entry_enable, &cq->ctrl->cq_entry_enable);
74 iowrite32(cq_message_enable, &cq->ctrl->cq_message_enable);
75 iowrite32(interrupt_offset, &cq->ctrl->interrupt_offset);
76 writeq(cq_message_addr, &cq->ctrl->cq_message_addr);
77
78 cq->interrupt_offset = interrupt_offset;
79}
80
81void vnic_cq_clean(struct vnic_cq *cq)
82{
83 cq->to_clean = 0;
84 cq->last_color = 0;
85
86 iowrite32(0, &cq->ctrl->cq_head);
87 iowrite32(0, &cq->ctrl->cq_tail);
88 iowrite32(1, &cq->ctrl->cq_tail_color);
89
90 vnic_dev_clear_desc_ring(&cq->ring);
91}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_cq.h b/drivers/net/ethernet/cisco/enic/vnic_cq.h
new file mode 100644
index 000000000000..579315cbe803
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_cq.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_CQ_H_
21#define _VNIC_CQ_H_
22
23#include "cq_desc.h"
24#include "vnic_dev.h"
25
26/* Completion queue control */
27struct vnic_cq_ctrl {
28 u64 ring_base; /* 0x00 */
29 u32 ring_size; /* 0x08 */
30 u32 pad0;
31 u32 flow_control_enable; /* 0x10 */
32 u32 pad1;
33 u32 color_enable; /* 0x18 */
34 u32 pad2;
35 u32 cq_head; /* 0x20 */
36 u32 pad3;
37 u32 cq_tail; /* 0x28 */
38 u32 pad4;
39 u32 cq_tail_color; /* 0x30 */
40 u32 pad5;
41 u32 interrupt_enable; /* 0x38 */
42 u32 pad6;
43 u32 cq_entry_enable; /* 0x40 */
44 u32 pad7;
45 u32 cq_message_enable; /* 0x48 */
46 u32 pad8;
47 u32 interrupt_offset; /* 0x50 */
48 u32 pad9;
49 u64 cq_message_addr; /* 0x58 */
50 u32 pad10;
51};
52
53struct vnic_cq {
54 unsigned int index;
55 struct vnic_dev *vdev;
56 struct vnic_cq_ctrl __iomem *ctrl; /* memory-mapped */
57 struct vnic_dev_ring ring;
58 unsigned int to_clean;
59 unsigned int last_color;
60 unsigned int interrupt_offset;
61};
62
63static inline unsigned int vnic_cq_service(struct vnic_cq *cq,
64 unsigned int work_to_do,
65 int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc,
66 u8 type, u16 q_number, u16 completed_index, void *opaque),
67 void *opaque)
68{
69 struct cq_desc *cq_desc;
70 unsigned int work_done = 0;
71 u16 q_number, completed_index;
72 u8 type, color;
73
74 cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
75 cq->ring.desc_size * cq->to_clean);
76 cq_desc_dec(cq_desc, &type, &color,
77 &q_number, &completed_index);
78
79 while (color != cq->last_color) {
80
81 if ((*q_service)(cq->vdev, cq_desc, type,
82 q_number, completed_index, opaque))
83 break;
84
85 cq->to_clean++;
86 if (cq->to_clean == cq->ring.desc_count) {
87 cq->to_clean = 0;
88 cq->last_color = cq->last_color ? 0 : 1;
89 }
90
91 cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
92 cq->ring.desc_size * cq->to_clean);
93 cq_desc_dec(cq_desc, &type, &color,
94 &q_number, &completed_index);
95
96 work_done++;
97 if (work_done >= work_to_do)
98 break;
99 }
100
101 return work_done;
102}
103
104void vnic_cq_free(struct vnic_cq *cq);
105int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
106 unsigned int desc_count, unsigned int desc_size);
107void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable,
108 unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail,
109 unsigned int cq_tail_color, unsigned int interrupt_enable,
110 unsigned int cq_entry_enable, unsigned int message_enable,
111 unsigned int interrupt_offset, u64 message_addr);
112void vnic_cq_clean(struct vnic_cq *cq);
113
114#endif /* _VNIC_CQ_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
new file mode 100644
index 000000000000..8c4c8cf486f6
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -0,0 +1,1003 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <linux/if_ether.h>
26
27#include "vnic_resource.h"
28#include "vnic_devcmd.h"
29#include "vnic_dev.h"
30#include "vnic_stats.h"
31
32enum vnic_proxy_type {
33 PROXY_NONE,
34 PROXY_BY_BDF,
35};
36
37struct vnic_res {
38 void __iomem *vaddr;
39 dma_addr_t bus_addr;
40 unsigned int count;
41};
42
43struct vnic_intr_coal_timer_info {
44 u32 mul;
45 u32 div;
46 u32 max_usec;
47};
48
49struct vnic_dev {
50 void *priv;
51 struct pci_dev *pdev;
52 struct vnic_res res[RES_TYPE_MAX];
53 enum vnic_dev_intr_mode intr_mode;
54 struct vnic_devcmd __iomem *devcmd;
55 struct vnic_devcmd_notify *notify;
56 struct vnic_devcmd_notify notify_copy;
57 dma_addr_t notify_pa;
58 u32 notify_sz;
59 dma_addr_t linkstatus_pa;
60 struct vnic_stats *stats;
61 dma_addr_t stats_pa;
62 struct vnic_devcmd_fw_info *fw_info;
63 dma_addr_t fw_info_pa;
64 enum vnic_proxy_type proxy;
65 u32 proxy_index;
66 u64 args[VNIC_DEVCMD_NARGS];
67 struct vnic_intr_coal_timer_info intr_coal_timer_info;
68};
69
70#define VNIC_MAX_RES_HDR_SIZE \
71 (sizeof(struct vnic_resource_header) + \
72 sizeof(struct vnic_resource) * RES_TYPE_MAX)
73#define VNIC_RES_STRIDE 128
74
75void *vnic_dev_priv(struct vnic_dev *vdev)
76{
77 return vdev->priv;
78}
79
80static int vnic_dev_discover_res(struct vnic_dev *vdev,
81 struct vnic_dev_bar *bar, unsigned int num_bars)
82{
83 struct vnic_resource_header __iomem *rh;
84 struct mgmt_barmap_hdr __iomem *mrh;
85 struct vnic_resource __iomem *r;
86 u8 type;
87
88 if (num_bars == 0)
89 return -EINVAL;
90
91 if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
92 pr_err("vNIC BAR0 res hdr length error\n");
93 return -EINVAL;
94 }
95
96 rh = bar->vaddr;
97 mrh = bar->vaddr;
98 if (!rh) {
99 pr_err("vNIC BAR0 res hdr not mem-mapped\n");
100 return -EINVAL;
101 }
102
103 /* Check for mgmt vnic in addition to normal vnic */
104 if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) ||
105 (ioread32(&rh->version) != VNIC_RES_VERSION)) {
106 if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) ||
107 (ioread32(&mrh->version) != MGMTVNIC_VERSION)) {
108 pr_err("vNIC BAR0 res magic/version error "
109 "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n",
110 VNIC_RES_MAGIC, VNIC_RES_VERSION,
111 MGMTVNIC_MAGIC, MGMTVNIC_VERSION,
112 ioread32(&rh->magic), ioread32(&rh->version));
113 return -EINVAL;
114 }
115 }
116
117 if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC)
118 r = (struct vnic_resource __iomem *)(mrh + 1);
119 else
120 r = (struct vnic_resource __iomem *)(rh + 1);
121
122
123 while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {
124
125 u8 bar_num = ioread8(&r->bar);
126 u32 bar_offset = ioread32(&r->bar_offset);
127 u32 count = ioread32(&r->count);
128 u32 len;
129
130 r++;
131
132 if (bar_num >= num_bars)
133 continue;
134
135 if (!bar[bar_num].len || !bar[bar_num].vaddr)
136 continue;
137
138 switch (type) {
139 case RES_TYPE_WQ:
140 case RES_TYPE_RQ:
141 case RES_TYPE_CQ:
142 case RES_TYPE_INTR_CTRL:
143 /* each count is stride bytes long */
144 len = count * VNIC_RES_STRIDE;
145 if (len + bar_offset > bar[bar_num].len) {
146 pr_err("vNIC BAR0 resource %d "
147 "out-of-bounds, offset 0x%x + "
148 "size 0x%x > bar len 0x%lx\n",
149 type, bar_offset,
150 len,
151 bar[bar_num].len);
152 return -EINVAL;
153 }
154 break;
155 case RES_TYPE_INTR_PBA_LEGACY:
156 case RES_TYPE_DEVCMD:
157 len = count;
158 break;
159 default:
160 continue;
161 }
162
163 vdev->res[type].count = count;
164 vdev->res[type].vaddr = (char __iomem *)bar[bar_num].vaddr +
165 bar_offset;
166 vdev->res[type].bus_addr = bar[bar_num].bus_addr + bar_offset;
167 }
168
169 return 0;
170}
171
172unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
173 enum vnic_res_type type)
174{
175 return vdev->res[type].count;
176}
177
178void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
179 unsigned int index)
180{
181 if (!vdev->res[type].vaddr)
182 return NULL;
183
184 switch (type) {
185 case RES_TYPE_WQ:
186 case RES_TYPE_RQ:
187 case RES_TYPE_CQ:
188 case RES_TYPE_INTR_CTRL:
189 return (char __iomem *)vdev->res[type].vaddr +
190 index * VNIC_RES_STRIDE;
191 default:
192 return (char __iomem *)vdev->res[type].vaddr;
193 }
194}
195
196static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
197 unsigned int desc_count, unsigned int desc_size)
198{
199 /* The base address of the desc rings must be 512 byte aligned.
200 * Descriptor count is aligned to groups of 32 descriptors. A
201 * count of 0 means the maximum 4096 descriptors. Descriptor
202 * size is aligned to 16 bytes.
203 */
204
205 unsigned int count_align = 32;
206 unsigned int desc_align = 16;
207
208 ring->base_align = 512;
209
210 if (desc_count == 0)
211 desc_count = 4096;
212
213 ring->desc_count = ALIGN(desc_count, count_align);
214
215 ring->desc_size = ALIGN(desc_size, desc_align);
216
217 ring->size = ring->desc_count * ring->desc_size;
218 ring->size_unaligned = ring->size + ring->base_align;
219
220 return ring->size_unaligned;
221}
222
223void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring)
224{
225 memset(ring->descs, 0, ring->size);
226}
227
228int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
229 unsigned int desc_count, unsigned int desc_size)
230{
231 vnic_dev_desc_ring_size(ring, desc_count, desc_size);
232
233 ring->descs_unaligned = pci_alloc_consistent(vdev->pdev,
234 ring->size_unaligned,
235 &ring->base_addr_unaligned);
236
237 if (!ring->descs_unaligned) {
238 pr_err("Failed to allocate ring (size=%d), aborting\n",
239 (int)ring->size);
240 return -ENOMEM;
241 }
242
243 ring->base_addr = ALIGN(ring->base_addr_unaligned,
244 ring->base_align);
245 ring->descs = (u8 *)ring->descs_unaligned +
246 (ring->base_addr - ring->base_addr_unaligned);
247
248 vnic_dev_clear_desc_ring(ring);
249
250 ring->desc_avail = ring->desc_count - 1;
251
252 return 0;
253}
254
255void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
256{
257 if (ring->descs) {
258 pci_free_consistent(vdev->pdev,
259 ring->size_unaligned,
260 ring->descs_unaligned,
261 ring->base_addr_unaligned);
262 ring->descs = NULL;
263 }
264}
265
266static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
267 int wait)
268{
269 struct vnic_devcmd __iomem *devcmd = vdev->devcmd;
270 unsigned int i;
271 int delay;
272 u32 status;
273 int err;
274
275 status = ioread32(&devcmd->status);
276 if (status == 0xFFFFFFFF) {
277 /* PCI-e target device is gone */
278 return -ENODEV;
279 }
280 if (status & STAT_BUSY) {
281 pr_err("Busy devcmd %d\n", _CMD_N(cmd));
282 return -EBUSY;
283 }
284
285 if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {
286 for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
287 writeq(vdev->args[i], &devcmd->args[i]);
288 wmb();
289 }
290
291 iowrite32(cmd, &devcmd->cmd);
292
293 if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))
294 return 0;
295
296 for (delay = 0; delay < wait; delay++) {
297
298 udelay(100);
299
300 status = ioread32(&devcmd->status);
301 if (status == 0xFFFFFFFF) {
302 /* PCI-e target device is gone */
303 return -ENODEV;
304 }
305
306 if (!(status & STAT_BUSY)) {
307
308 if (status & STAT_ERROR) {
309 err = (int)readq(&devcmd->args[0]);
310 if (err != ERR_ECMDUNKNOWN ||
311 cmd != CMD_CAPABILITY)
312 pr_err("Error %d devcmd %d\n",
313 err, _CMD_N(cmd));
314 return err;
315 }
316
317 if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
318 rmb();
319 for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
320 vdev->args[i] = readq(&devcmd->args[i]);
321 }
322
323 return 0;
324 }
325 }
326
327 pr_err("Timedout devcmd %d\n", _CMD_N(cmd));
328 return -ETIMEDOUT;
329}
330
331static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev,
332 enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
333{
334 u32 status;
335 int err;
336
337 memset(vdev->args, 0, sizeof(vdev->args));
338
339 vdev->args[0] = vdev->proxy_index; /* bdf */
340 vdev->args[1] = cmd;
341 vdev->args[2] = *a0;
342 vdev->args[3] = *a1;
343
344 err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait);
345 if (err)
346 return err;
347
348 status = (u32)vdev->args[0];
349 if (status & STAT_ERROR) {
350 err = (int)vdev->args[1];
351 if (err != ERR_ECMDUNKNOWN ||
352 cmd != CMD_CAPABILITY)
353 pr_err("Error %d proxy devcmd %d\n", err, _CMD_N(cmd));
354 return err;
355 }
356
357 *a0 = vdev->args[1];
358 *a1 = vdev->args[2];
359
360 return 0;
361}
362
363static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
364 enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
365{
366 int err;
367
368 vdev->args[0] = *a0;
369 vdev->args[1] = *a1;
370
371 err = _vnic_dev_cmd(vdev, cmd, wait);
372
373 *a0 = vdev->args[0];
374 *a1 = vdev->args[1];
375
376 return err;
377}
378
379int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
380 u64 *a0, u64 *a1, int wait)
381{
382 memset(vdev->args, 0, sizeof(vdev->args));
383
384 switch (vdev->proxy) {
385 case PROXY_BY_BDF:
386 return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait);
387 case PROXY_NONE:
388 default:
389 return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);
390 }
391}
392
393static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
394{
395 u64 a0 = (u32)cmd, a1 = 0;
396 int wait = 1000;
397 int err;
398
399 err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
400
401 return !(err || a0);
402}
403
404int vnic_dev_fw_info(struct vnic_dev *vdev,
405 struct vnic_devcmd_fw_info **fw_info)
406{
407 u64 a0, a1 = 0;
408 int wait = 1000;
409 int err = 0;
410
411 if (!vdev->fw_info) {
412 vdev->fw_info = pci_alloc_consistent(vdev->pdev,
413 sizeof(struct vnic_devcmd_fw_info),
414 &vdev->fw_info_pa);
415 if (!vdev->fw_info)
416 return -ENOMEM;
417
418 memset(vdev->fw_info, 0, sizeof(struct vnic_devcmd_fw_info));
419
420 a0 = vdev->fw_info_pa;
421 a1 = sizeof(struct vnic_devcmd_fw_info);
422
423 /* only get fw_info once and cache it */
424 err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait);
425 if (err == ERR_ECMDUNKNOWN) {
426 err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD,
427 &a0, &a1, wait);
428 }
429 }
430
431 *fw_info = vdev->fw_info;
432
433 return err;
434}
435
436int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
437 void *value)
438{
439 u64 a0, a1;
440 int wait = 1000;
441 int err;
442
443 a0 = offset;
444 a1 = size;
445
446 err = vnic_dev_cmd(vdev, CMD_DEV_SPEC, &a0, &a1, wait);
447
448 switch (size) {
449 case 1: *(u8 *)value = (u8)a0; break;
450 case 2: *(u16 *)value = (u16)a0; break;
451 case 4: *(u32 *)value = (u32)a0; break;
452 case 8: *(u64 *)value = a0; break;
453 default: BUG(); break;
454 }
455
456 return err;
457}
458
459int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
460{
461 u64 a0, a1;
462 int wait = 1000;
463
464 if (!vdev->stats) {
465 vdev->stats = pci_alloc_consistent(vdev->pdev,
466 sizeof(struct vnic_stats), &vdev->stats_pa);
467 if (!vdev->stats)
468 return -ENOMEM;
469 }
470
471 *stats = vdev->stats;
472 a0 = vdev->stats_pa;
473 a1 = sizeof(struct vnic_stats);
474
475 return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);
476}
477
478int vnic_dev_close(struct vnic_dev *vdev)
479{
480 u64 a0 = 0, a1 = 0;
481 int wait = 1000;
482 return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait);
483}
484
485int vnic_dev_enable_wait(struct vnic_dev *vdev)
486{
487 u64 a0 = 0, a1 = 0;
488 int wait = 1000;
489 int err;
490
491 err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait);
492 if (err == ERR_ECMDUNKNOWN)
493 return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
494
495 return err;
496}
497
498int vnic_dev_disable(struct vnic_dev *vdev)
499{
500 u64 a0 = 0, a1 = 0;
501 int wait = 1000;
502 return vnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait);
503}
504
505int vnic_dev_open(struct vnic_dev *vdev, int arg)
506{
507 u64 a0 = (u32)arg, a1 = 0;
508 int wait = 1000;
509 return vnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait);
510}
511
512int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
513{
514 u64 a0 = 0, a1 = 0;
515 int wait = 1000;
516 int err;
517
518 *done = 0;
519
520 err = vnic_dev_cmd(vdev, CMD_OPEN_STATUS, &a0, &a1, wait);
521 if (err)
522 return err;
523
524 *done = (a0 == 0);
525
526 return 0;
527}
528
529static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
530{
531 u64 a0 = (u32)arg, a1 = 0;
532 int wait = 1000;
533 return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);
534}
535
536static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
537{
538 u64 a0 = 0, a1 = 0;
539 int wait = 1000;
540 int err;
541
542 *done = 0;
543
544 err = vnic_dev_cmd(vdev, CMD_SOFT_RESET_STATUS, &a0, &a1, wait);
545 if (err)
546 return err;
547
548 *done = (a0 == 0);
549
550 return 0;
551}
552
553int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg)
554{
555 u64 a0 = (u32)arg, a1 = 0;
556 int wait = 1000;
557 int err;
558
559 err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait);
560 if (err == ERR_ECMDUNKNOWN) {
561 err = vnic_dev_soft_reset(vdev, arg);
562 if (err)
563 return err;
564
565 return vnic_dev_init(vdev, 0);
566 }
567
568 return err;
569}
570
571int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done)
572{
573 u64 a0 = 0, a1 = 0;
574 int wait = 1000;
575 int err;
576
577 *done = 0;
578
579 err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait);
580 if (err) {
581 if (err == ERR_ECMDUNKNOWN)
582 return vnic_dev_soft_reset_done(vdev, done);
583 return err;
584 }
585
586 *done = (a0 == 0);
587
588 return 0;
589}
590
591int vnic_dev_hang_notify(struct vnic_dev *vdev)
592{
593 u64 a0, a1;
594 int wait = 1000;
595 return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
596}
597
598int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
599{
600 u64 a0, a1;
601 int wait = 1000;
602 int err, i;
603
604 for (i = 0; i < ETH_ALEN; i++)
605 mac_addr[i] = 0;
606
607 err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
608 if (err)
609 return err;
610
611 for (i = 0; i < ETH_ALEN; i++)
612 mac_addr[i] = ((u8 *)&a0)[i];
613
614 return 0;
615}
616
617int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
618 int broadcast, int promisc, int allmulti)
619{
620 u64 a0, a1 = 0;
621 int wait = 1000;
622 int err;
623
624 a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |
625 (multicast ? CMD_PFILTER_MULTICAST : 0) |
626 (broadcast ? CMD_PFILTER_BROADCAST : 0) |
627 (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |
628 (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);
629
630 err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait);
631 if (err)
632 pr_err("Can't set packet filter\n");
633
634 return err;
635}
636
637int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
638{
639 u64 a0 = 0, a1 = 0;
640 int wait = 1000;
641 int err;
642 int i;
643
644 for (i = 0; i < ETH_ALEN; i++)
645 ((u8 *)&a0)[i] = addr[i];
646
647 err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
648 if (err)
649 pr_err("Can't add addr [%pM], %d\n", addr, err);
650
651 return err;
652}
653
654int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
655{
656 u64 a0 = 0, a1 = 0;
657 int wait = 1000;
658 int err;
659 int i;
660
661 for (i = 0; i < ETH_ALEN; i++)
662 ((u8 *)&a0)[i] = addr[i];
663
664 err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
665 if (err)
666 pr_err("Can't del addr [%pM], %d\n", addr, err);
667
668 return err;
669}
670
671int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
672 u8 ig_vlan_rewrite_mode)
673{
674 u64 a0 = ig_vlan_rewrite_mode, a1 = 0;
675 int wait = 1000;
676 int err;
677
678 err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait);
679 if (err == ERR_ECMDUNKNOWN)
680 return 0;
681
682 return err;
683}
684
685static int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
686 void *notify_addr, dma_addr_t notify_pa, u16 intr)
687{
688 u64 a0, a1;
689 int wait = 1000;
690 int r;
691
692 memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
693 vdev->notify = notify_addr;
694 vdev->notify_pa = notify_pa;
695
696 a0 = (u64)notify_pa;
697 a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
698 a1 += sizeof(struct vnic_devcmd_notify);
699
700 r = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
701 vdev->notify_sz = (r == 0) ? (u32)a1 : 0;
702 return r;
703}
704
705int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
706{
707 void *notify_addr;
708 dma_addr_t notify_pa;
709
710 if (vdev->notify || vdev->notify_pa) {
711 pr_err("notify block %p still allocated", vdev->notify);
712 return -EINVAL;
713 }
714
715 notify_addr = pci_alloc_consistent(vdev->pdev,
716 sizeof(struct vnic_devcmd_notify),
717 &notify_pa);
718 if (!notify_addr)
719 return -ENOMEM;
720
721 return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
722}
723
724static int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
725{
726 u64 a0, a1;
727 int wait = 1000;
728 int err;
729
730 a0 = 0; /* paddr = 0 to unset notify buffer */
731 a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */
732 a1 += sizeof(struct vnic_devcmd_notify);
733
734 err = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
735 vdev->notify = NULL;
736 vdev->notify_pa = 0;
737 vdev->notify_sz = 0;
738
739 return err;
740}
741
742int vnic_dev_notify_unset(struct vnic_dev *vdev)
743{
744 if (vdev->notify) {
745 pci_free_consistent(vdev->pdev,
746 sizeof(struct vnic_devcmd_notify),
747 vdev->notify,
748 vdev->notify_pa);
749 }
750
751 return vnic_dev_notify_unsetcmd(vdev);
752}
753
754static int vnic_dev_notify_ready(struct vnic_dev *vdev)
755{
756 u32 *words;
757 unsigned int nwords = vdev->notify_sz / 4;
758 unsigned int i;
759 u32 csum;
760
761 if (!vdev->notify || !vdev->notify_sz)
762 return 0;
763
764 do {
765 csum = 0;
766 memcpy(&vdev->notify_copy, vdev->notify, vdev->notify_sz);
767 words = (u32 *)&vdev->notify_copy;
768 for (i = 1; i < nwords; i++)
769 csum += words[i];
770 } while (csum != words[0]);
771
772 return 1;
773}
774
775int vnic_dev_init(struct vnic_dev *vdev, int arg)
776{
777 u64 a0 = (u32)arg, a1 = 0;
778 int wait = 1000;
779 int r = 0;
780
781 if (vnic_dev_capable(vdev, CMD_INIT))
782 r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
783 else {
784 vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
785 if (a0 & CMD_INITF_DEFAULT_MAC) {
786 /* Emulate these for old CMD_INIT_v1 which
787 * didn't pass a0 so no CMD_INITF_*.
788 */
789 vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
790 vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
791 }
792 }
793 return r;
794}
795
796int vnic_dev_deinit(struct vnic_dev *vdev)
797{
798 u64 a0 = 0, a1 = 0;
799 int wait = 1000;
800
801 return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
802}
803
804void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev)
805{
806 /* Default: hardware intr coal timer is in units of 1.5 usecs */
807 vdev->intr_coal_timer_info.mul = 2;
808 vdev->intr_coal_timer_info.div = 3;
809 vdev->intr_coal_timer_info.max_usec =
810 vnic_dev_intr_coal_timer_hw_to_usec(vdev, 0xffff);
811}
812
813int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev)
814{
815 int wait = 1000;
816 int err;
817
818 memset(vdev->args, 0, sizeof(vdev->args));
819
820 err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait);
821
822 /* Use defaults when firmware doesn't support the devcmd at all or
823 * supports it for only specific hardware
824 */
825 if ((err == ERR_ECMDUNKNOWN) ||
826 (!err && !(vdev->args[0] && vdev->args[1] && vdev->args[2]))) {
827 pr_warning("Using default conversion factor for "
828 "interrupt coalesce timer\n");
829 vnic_dev_intr_coal_timer_info_default(vdev);
830 return 0;
831 }
832
833 vdev->intr_coal_timer_info.mul = (u32) vdev->args[0];
834 vdev->intr_coal_timer_info.div = (u32) vdev->args[1];
835 vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2];
836
837 return err;
838}
839
840int vnic_dev_link_status(struct vnic_dev *vdev)
841{
842 if (!vnic_dev_notify_ready(vdev))
843 return 0;
844
845 return vdev->notify_copy.link_state;
846}
847
848u32 vnic_dev_port_speed(struct vnic_dev *vdev)
849{
850 if (!vnic_dev_notify_ready(vdev))
851 return 0;
852
853 return vdev->notify_copy.port_speed;
854}
855
856u32 vnic_dev_msg_lvl(struct vnic_dev *vdev)
857{
858 if (!vnic_dev_notify_ready(vdev))
859 return 0;
860
861 return vdev->notify_copy.msglvl;
862}
863
864u32 vnic_dev_mtu(struct vnic_dev *vdev)
865{
866 if (!vnic_dev_notify_ready(vdev))
867 return 0;
868
869 return vdev->notify_copy.mtu;
870}
871
872void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
873 enum vnic_dev_intr_mode intr_mode)
874{
875 vdev->intr_mode = intr_mode;
876}
877
878enum vnic_dev_intr_mode vnic_dev_get_intr_mode(
879 struct vnic_dev *vdev)
880{
881 return vdev->intr_mode;
882}
883
884u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec)
885{
886 return (usec * vdev->intr_coal_timer_info.mul) /
887 vdev->intr_coal_timer_info.div;
888}
889
890u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles)
891{
892 return (hw_cycles * vdev->intr_coal_timer_info.div) /
893 vdev->intr_coal_timer_info.mul;
894}
895
896u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev)
897{
898 return vdev->intr_coal_timer_info.max_usec;
899}
900
901void vnic_dev_unregister(struct vnic_dev *vdev)
902{
903 if (vdev) {
904 if (vdev->notify)
905 pci_free_consistent(vdev->pdev,
906 sizeof(struct vnic_devcmd_notify),
907 vdev->notify,
908 vdev->notify_pa);
909 if (vdev->stats)
910 pci_free_consistent(vdev->pdev,
911 sizeof(struct vnic_stats),
912 vdev->stats, vdev->stats_pa);
913 if (vdev->fw_info)
914 pci_free_consistent(vdev->pdev,
915 sizeof(struct vnic_devcmd_fw_info),
916 vdev->fw_info, vdev->fw_info_pa);
917 kfree(vdev);
918 }
919}
920
921struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
922 void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
923 unsigned int num_bars)
924{
925 if (!vdev) {
926 vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC);
927 if (!vdev)
928 return NULL;
929 }
930
931 vdev->priv = priv;
932 vdev->pdev = pdev;
933
934 if (vnic_dev_discover_res(vdev, bar, num_bars))
935 goto err_out;
936
937 vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);
938 if (!vdev->devcmd)
939 goto err_out;
940
941 return vdev;
942
943err_out:
944 vnic_dev_unregister(vdev);
945 return NULL;
946}
947
948int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len)
949{
950 u64 a0, a1 = len;
951 int wait = 1000;
952 dma_addr_t prov_pa;
953 void *prov_buf;
954 int ret;
955
956 prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
957 if (!prov_buf)
958 return -ENOMEM;
959
960 memcpy(prov_buf, buf, len);
961
962 a0 = prov_pa;
963
964 ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO2, &a0, &a1, wait);
965
966 pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
967
968 return ret;
969}
970
971int vnic_dev_enable2(struct vnic_dev *vdev, int active)
972{
973 u64 a0, a1 = 0;
974 int wait = 1000;
975
976 a0 = (active ? CMD_ENABLE2_ACTIVE : 0);
977
978 return vnic_dev_cmd(vdev, CMD_ENABLE2, &a0, &a1, wait);
979}
980
981static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
982 int *status)
983{
984 u64 a0 = cmd, a1 = 0;
985 int wait = 1000;
986 int ret;
987
988 ret = vnic_dev_cmd(vdev, CMD_STATUS, &a0, &a1, wait);
989 if (!ret)
990 *status = (int)a0;
991
992 return ret;
993}
994
995int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status)
996{
997 return vnic_dev_cmd_status(vdev, CMD_ENABLE2, status);
998}
999
1000int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status)
1001{
1002 return vnic_dev_cmd_status(vdev, CMD_DEINIT, status);
1003}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
new file mode 100644
index 000000000000..852b698fbe7d
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -0,0 +1,133 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_DEV_H_
21#define _VNIC_DEV_H_
22
23#include "vnic_resource.h"
24#include "vnic_devcmd.h"
25
26#ifndef VNIC_PADDR_TARGET
27#define VNIC_PADDR_TARGET 0x0000000000000000ULL
28#endif
29
30#ifndef readq
31static inline u64 readq(void __iomem *reg)
32{
33 return (((u64)readl(reg + 0x4UL) << 32) |
34 (u64)readl(reg));
35}
36
37static inline void writeq(u64 val, void __iomem *reg)
38{
39 writel(val & 0xffffffff, reg);
40 writel(val >> 32, reg + 0x4UL);
41}
42#endif
43
44#undef pr_fmt
45#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
46
47enum vnic_dev_intr_mode {
48 VNIC_DEV_INTR_MODE_UNKNOWN,
49 VNIC_DEV_INTR_MODE_INTX,
50 VNIC_DEV_INTR_MODE_MSI,
51 VNIC_DEV_INTR_MODE_MSIX,
52};
53
54struct vnic_dev_bar {
55 void __iomem *vaddr;
56 dma_addr_t bus_addr;
57 unsigned long len;
58};
59
60struct vnic_dev_ring {
61 void *descs;
62 size_t size;
63 dma_addr_t base_addr;
64 size_t base_align;
65 void *descs_unaligned;
66 size_t size_unaligned;
67 dma_addr_t base_addr_unaligned;
68 unsigned int desc_size;
69 unsigned int desc_count;
70 unsigned int desc_avail;
71};
72
73struct vnic_dev;
74struct vnic_stats;
75
76void *vnic_dev_priv(struct vnic_dev *vdev);
77unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
78 enum vnic_res_type type);
79void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
80 unsigned int index);
81void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring);
82int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
83 unsigned int desc_count, unsigned int desc_size);
84void vnic_dev_free_desc_ring(struct vnic_dev *vdev,
85 struct vnic_dev_ring *ring);
86int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
87 u64 *a0, u64 *a1, int wait);
88int vnic_dev_fw_info(struct vnic_dev *vdev,
89 struct vnic_devcmd_fw_info **fw_info);
90int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
91 void *value);
92int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats);
93int vnic_dev_hang_notify(struct vnic_dev *vdev);
94int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
95 int broadcast, int promisc, int allmulti);
96int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
97int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
98int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
99int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr);
100int vnic_dev_notify_unset(struct vnic_dev *vdev);
101int vnic_dev_link_status(struct vnic_dev *vdev);
102u32 vnic_dev_port_speed(struct vnic_dev *vdev);
103u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
104u32 vnic_dev_mtu(struct vnic_dev *vdev);
105int vnic_dev_close(struct vnic_dev *vdev);
106int vnic_dev_enable_wait(struct vnic_dev *vdev);
107int vnic_dev_disable(struct vnic_dev *vdev);
108int vnic_dev_open(struct vnic_dev *vdev, int arg);
109int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
110int vnic_dev_init(struct vnic_dev *vdev, int arg);
111int vnic_dev_deinit(struct vnic_dev *vdev);
112void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev);
113int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev);
114int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
115int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
116void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
117 enum vnic_dev_intr_mode intr_mode);
118enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
119u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec);
120u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles);
121u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev);
122void vnic_dev_unregister(struct vnic_dev *vdev);
123int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
124 u8 ig_vlan_rewrite_mode);
125struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
126 void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
127 unsigned int num_bars);
128int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len);
129int vnic_dev_enable2(struct vnic_dev *vdev, int active);
130int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
131int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
132
133#endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
new file mode 100644
index 000000000000..8025e8808d61
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
@@ -0,0 +1,450 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_DEVCMD_H_
21#define _VNIC_DEVCMD_H_
22
23#define _CMD_NBITS 14
24#define _CMD_VTYPEBITS 10
25#define _CMD_FLAGSBITS 6
26#define _CMD_DIRBITS 2
27
28#define _CMD_NMASK ((1 << _CMD_NBITS)-1)
29#define _CMD_VTYPEMASK ((1 << _CMD_VTYPEBITS)-1)
30#define _CMD_FLAGSMASK ((1 << _CMD_FLAGSBITS)-1)
31#define _CMD_DIRMASK ((1 << _CMD_DIRBITS)-1)
32
33#define _CMD_NSHIFT 0
34#define _CMD_VTYPESHIFT (_CMD_NSHIFT+_CMD_NBITS)
35#define _CMD_FLAGSSHIFT (_CMD_VTYPESHIFT+_CMD_VTYPEBITS)
36#define _CMD_DIRSHIFT (_CMD_FLAGSSHIFT+_CMD_FLAGSBITS)
37
38/*
39 * Direction bits (from host perspective).
40 */
41#define _CMD_DIR_NONE 0U
42#define _CMD_DIR_WRITE 1U
43#define _CMD_DIR_READ 2U
44#define _CMD_DIR_RW (_CMD_DIR_WRITE | _CMD_DIR_READ)
45
46/*
47 * Flag bits.
48 */
49#define _CMD_FLAGS_NONE 0U
50#define _CMD_FLAGS_NOWAIT 1U
51
52/*
53 * vNIC type bits.
54 */
55#define _CMD_VTYPE_NONE 0U
56#define _CMD_VTYPE_ENET 1U
57#define _CMD_VTYPE_FC 2U
58#define _CMD_VTYPE_SCSI 4U
59#define _CMD_VTYPE_ALL (_CMD_VTYPE_ENET | _CMD_VTYPE_FC | _CMD_VTYPE_SCSI)
60
61/*
62 * Used to create cmds..
63*/
64#define _CMDCF(dir, flags, vtype, nr) \
65 (((dir) << _CMD_DIRSHIFT) | \
66 ((flags) << _CMD_FLAGSSHIFT) | \
67 ((vtype) << _CMD_VTYPESHIFT) | \
68 ((nr) << _CMD_NSHIFT))
69#define _CMDC(dir, vtype, nr) _CMDCF(dir, 0, vtype, nr)
70#define _CMDCNW(dir, vtype, nr) _CMDCF(dir, _CMD_FLAGS_NOWAIT, vtype, nr)
71
72/*
73 * Used to decode cmds..
74*/
75#define _CMD_DIR(cmd) (((cmd) >> _CMD_DIRSHIFT) & _CMD_DIRMASK)
76#define _CMD_FLAGS(cmd) (((cmd) >> _CMD_FLAGSSHIFT) & _CMD_FLAGSMASK)
77#define _CMD_VTYPE(cmd) (((cmd) >> _CMD_VTYPESHIFT) & _CMD_VTYPEMASK)
78#define _CMD_N(cmd) (((cmd) >> _CMD_NSHIFT) & _CMD_NMASK)
79
80enum vnic_devcmd_cmd {
81 CMD_NONE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_NONE, 0),
82
83 /*
84 * mcpu fw info in mem:
85 * in:
86 * (u64)a0=paddr to struct vnic_devcmd_fw_info
87 * action:
88 * Fills in struct vnic_devcmd_fw_info (128 bytes)
89 * note:
90 * An old definition of CMD_MCPU_FW_INFO
91 */
92 CMD_MCPU_FW_INFO_OLD = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 1),
93
94 /*
95 * mcpu fw info in mem:
96 * in:
97 * (u64)a0=paddr to struct vnic_devcmd_fw_info
98 * (u16)a1=size of the structure
99 * out:
100 * (u16)a1=0 for in:a1 = 0,
101 * data size actually written for other values.
102 * action:
103 * Fills in first 128 bytes of vnic_devcmd_fw_info for in:a1 = 0,
104 * first in:a1 bytes for 0 < in:a1 <= 132,
105 * 132 bytes for other values of in:a1.
106 * note:
107 * CMD_MCPU_FW_INFO and CMD_MCPU_FW_INFO_OLD have the same enum 1
108 * for source compatibility.
109 */
110 CMD_MCPU_FW_INFO = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 1),
111
112 /* dev-specific block member:
113 * in: (u16)a0=offset,(u8)a1=size
114 * out: a0=value */
115 CMD_DEV_SPEC = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 2),
116
117 /* stats clear */
118 CMD_STATS_CLEAR = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 3),
119
120 /* stats dump in mem: (u64)a0=paddr to stats area,
121 * (u16)a1=sizeof stats area */
122 CMD_STATS_DUMP = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 4),
123
124 /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */
125 CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7),
126
127 /* set Rx packet filter for all: (u32)a0=filters (see CMD_PFILTER_*) */
128 CMD_PACKET_FILTER_ALL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 7),
129
130 /* hang detection notification */
131 CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
132
133 /* MAC address in (u48)a0 */
134 CMD_MAC_ADDR = _CMDC(_CMD_DIR_READ,
135 _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9),
136
137 /* add addr from (u48)a0 */
138 CMD_ADDR_ADD = _CMDCNW(_CMD_DIR_WRITE,
139 _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 12),
140
141 /* del addr from (u48)a0 */
142 CMD_ADDR_DEL = _CMDCNW(_CMD_DIR_WRITE,
143 _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 13),
144
145 /* add VLAN id in (u16)a0 */
146 CMD_VLAN_ADD = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 14),
147
148 /* del VLAN id in (u16)a0 */
149 CMD_VLAN_DEL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 15),
150
151 /* nic_cfg in (u32)a0 */
152 CMD_NIC_CFG = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16),
153
154 /* union vnic_rss_key in mem: (u64)a0=paddr, (u16)a1=len */
155 CMD_RSS_KEY = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 17),
156
157 /* union vnic_rss_cpu in mem: (u64)a0=paddr, (u16)a1=len */
158 CMD_RSS_CPU = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 18),
159
160 /* initiate softreset */
161 CMD_SOFT_RESET = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 19),
162
163 /* softreset status:
164 * out: a0=0 reset complete, a0=1 reset in progress */
165 CMD_SOFT_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 20),
166
167 /* set struct vnic_devcmd_notify buffer in mem:
168 * in:
169 * (u64)a0=paddr to notify (set paddr=0 to unset)
170 * (u32)a1 & 0x00000000ffffffff=sizeof(struct vnic_devcmd_notify)
171 * (u16)a1 & 0x0000ffff00000000=intr num (-1 for no intr)
172 * out:
173 * (u32)a1 = effective size
174 */
175 CMD_NOTIFY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 21),
176
177 /* UNDI API: (u64)a0=paddr to s_PXENV_UNDI_ struct,
178 * (u8)a1=PXENV_UNDI_xxx */
179 CMD_UNDI = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 22),
180
181 /* initiate open sequence (u32)a0=flags (see CMD_OPENF_*) */
182 CMD_OPEN = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 23),
183
184 /* open status:
185 * out: a0=0 open complete, a0=1 open in progress */
186 CMD_OPEN_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 24),
187
188 /* close vnic */
189 CMD_CLOSE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 25),
190
191 /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */
192/***** Replaced by CMD_INIT *****/
193 CMD_INIT_v1 = _CMDCNW(_CMD_DIR_READ, _CMD_VTYPE_ALL, 26),
194
195 /* variant of CMD_INIT, with provisioning info
196 * (u64)a0=paddr of vnic_devcmd_provinfo
197 * (u32)a1=sizeof provision info */
198 CMD_INIT_PROV_INFO = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 27),
199
200 /* enable virtual link */
201 CMD_ENABLE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28),
202
203 /* enable virtual link, waiting variant. */
204 CMD_ENABLE_WAIT = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28),
205
206 /* disable virtual link */
207 CMD_DISABLE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29),
208
209 /* stats dump sum of all vnic stats on same uplink in mem:
210 * (u64)a0=paddr
211 * (u16)a1=sizeof stats area */
212 CMD_STATS_DUMP_ALL = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 30),
213
214 /* init status:
215 * out: a0=0 init complete, a0=1 init in progress
216 * if a0=0, a1=errno */
217 CMD_INIT_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 31),
218
219 /* INT13 API: (u64)a0=paddr to vnic_int13_params struct
220 * (u32)a1=INT13_CMD_xxx */
221 CMD_INT13 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_FC, 32),
222
223 /* logical uplink enable/disable: (u64)a0: 0/1=disable/enable */
224 CMD_LOGICAL_UPLINK = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 33),
225
226 /* undo initialize of virtual link */
227 CMD_DEINIT = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 34),
228
229 /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */
230 CMD_INIT = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 35),
231
232 /* check fw capability of a cmd:
233 * in: (u32)a0=cmd
234 * out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */
235 CMD_CAPABILITY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36),
236
237 /* persistent binding info
238 * in: (u64)a0=paddr of arg
239 * (u32)a1=CMD_PERBI_XXX */
240 CMD_PERBI = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
241
242 /* Interrupt Assert Register functionality
243 * in: (u16)a0=interrupt number to assert
244 */
245 CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
246
247 /* initiate hangreset, like softreset after hang detected */
248 CMD_HANG_RESET = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 39),
249
250 /* hangreset status:
251 * out: a0=0 reset complete, a0=1 reset in progress */
252 CMD_HANG_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 40),
253
254 /*
255 * Set hw ingress packet vlan rewrite mode:
256 * in: (u32)a0=new vlan rewrite mode
257 * out: (u32)a0=old vlan rewrite mode */
258 CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41),
259
260 /*
261 * in: (u16)a0=bdf of target vnic
262 * (u32)a1=cmd to proxy
263 * a2-a15=args to cmd in a1
264 * out: (u32)a0=status of proxied cmd
265 * a1-a15=out args of proxied cmd */
266 CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42),
267
268 /*
269 * As for BY_BDF except a0 is index of hvnlink subordinate vnic
270 * or SR-IOV virtual vnic
271 */
272 CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43),
273
274 /*
275 * For HPP toggle:
276 * adapter-info-get
277 * in: (u64)a0=phsical address of buffer passed in from caller.
278 * (u16)a1=size of buffer specified in a0.
279 * out: (u64)a0=phsical address of buffer passed in from caller.
280 * (u16)a1=actual bytes from VIF-CONFIG-INFO TLV, or
281 * 0 if no VIF-CONFIG-INFO TLV was ever received. */
282 CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
283
284 /* init_prov_info2:
285 * Variant of CMD_INIT_PROV_INFO, where it will not try to enable
286 * the vnic until CMD_ENABLE2 is issued.
287 * (u64)a0=paddr of vnic_devcmd_provinfo
288 * (u32)a1=sizeof provision info */
289 CMD_INIT_PROV_INFO2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 47),
290
291 /* enable2:
292 * (u32)a0=0 ==> standby
293 * =CMD_ENABLE2_ACTIVE ==> active
294 */
295 CMD_ENABLE2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 48),
296
297 /*
298 * cmd_status:
299 * Returns the status of the specified command
300 * Input:
301 * a0 = command for which status is being queried.
302 * Possible values are:
303 * CMD_SOFT_RESET
304 * CMD_HANG_RESET
305 * CMD_OPEN
306 * CMD_INIT
307 * CMD_INIT_PROV_INFO
308 * CMD_DEINIT
309 * CMD_INIT_PROV_INFO2
310 * CMD_ENABLE2
311 * Output:
312 * if status == STAT_ERROR
313 * a0 = ERR_ENOTSUPPORTED - status for command in a0 is
314 * not supported
315 * if status == STAT_NONE
316 * a0 = status of the devcmd specified in a0 as follows.
317 * ERR_SUCCESS - command in a0 completed successfully
318 * ERR_EINPROGRESS - command in a0 is still in progress
319 */
320 CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49),
321
322 /*
323 * Returns interrupt coalescing timer conversion factors.
324 * After calling this devcmd, ENIC driver can convert
325 * interrupt coalescing timer in usec into CPU cycles as follows:
326 *
327 * intr_timer_cycles = intr_timer_usec * multiplier / divisor
328 *
329 * Interrupt coalescing timer in usecs can be obtained from
330 * CPU cycles as follows:
331 *
332 * intr_timer_usec = intr_timer_cycles * divisor / multiplier
333 *
334 * in: none
335 * out: (u32)a0 = multiplier
336 * (u32)a1 = divisor
337 * (u32)a2 = maximum timer value in usec
338 */
339 CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50),
340};
341
342/* CMD_ENABLE2 flags */
343#define CMD_ENABLE2_ACTIVE 0x1
344
345/* flags for CMD_OPEN */
346#define CMD_OPENF_OPROM 0x1 /* open coming from option rom */
347
348/* flags for CMD_INIT */
349#define CMD_INITF_DEFAULT_MAC 0x1 /* init with default mac addr */
350
351/* flags for CMD_PACKET_FILTER */
352#define CMD_PFILTER_DIRECTED 0x01
353#define CMD_PFILTER_MULTICAST 0x02
354#define CMD_PFILTER_BROADCAST 0x04
355#define CMD_PFILTER_PROMISCUOUS 0x08
356#define CMD_PFILTER_ALL_MULTICAST 0x10
357
358/* rewrite modes for CMD_IG_VLAN_REWRITE_MODE */
359#define IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK 0
360#define IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN 1
361#define IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN 2
362#define IG_VLAN_REWRITE_MODE_PASS_THRU 3
363
364enum vnic_devcmd_status {
365 STAT_NONE = 0,
366 STAT_BUSY = 1 << 0, /* cmd in progress */
367 STAT_ERROR = 1 << 1, /* last cmd caused error (code in a0) */
368};
369
370enum vnic_devcmd_error {
371 ERR_SUCCESS = 0,
372 ERR_EINVAL = 1,
373 ERR_EFAULT = 2,
374 ERR_EPERM = 3,
375 ERR_EBUSY = 4,
376 ERR_ECMDUNKNOWN = 5,
377 ERR_EBADSTATE = 6,
378 ERR_ENOMEM = 7,
379 ERR_ETIMEDOUT = 8,
380 ERR_ELINKDOWN = 9,
381 ERR_EMAXRES = 10,
382 ERR_ENOTSUPPORTED = 11,
383 ERR_EINPROGRESS = 12,
384};
385
386/*
387 * note: hw_version and asic_rev refer to the same thing,
388 * but have different formats. hw_version is
389 * a 32-byte string (e.g. "A2") and asic_rev is
390 * a 16-bit integer (e.g. 0xA2).
391 */
392struct vnic_devcmd_fw_info {
393 char fw_version[32];
394 char fw_build[32];
395 char hw_version[32];
396 char hw_serial_number[32];
397 u16 asic_type;
398 u16 asic_rev;
399};
400
401struct vnic_devcmd_notify {
402 u32 csum; /* checksum over following words */
403
404 u32 link_state; /* link up == 1 */
405 u32 port_speed; /* effective port speed (rate limit) */
406 u32 mtu; /* MTU */
407 u32 msglvl; /* requested driver msg lvl */
408 u32 uif; /* uplink interface */
409 u32 status; /* status bits (see VNIC_STF_*) */
410 u32 error; /* error code (see ERR_*) for first ERR */
411 u32 link_down_cnt; /* running count of link down transitions */
412 u32 perbi_rebuild_cnt; /* running count of perbi rebuilds */
413};
414#define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */
415#define VNIC_STF_STD_PAUSE 0x0002 /* standard link-level pause on */
416#define VNIC_STF_PFC_PAUSE 0x0004 /* priority flow control pause on */
417/* all supported status flags */
418#define VNIC_STF_ALL (VNIC_STF_FATAL_ERR |\
419 VNIC_STF_STD_PAUSE |\
420 VNIC_STF_PFC_PAUSE |\
421 0)
422
423struct vnic_devcmd_provinfo {
424 u8 oui[3];
425 u8 type;
426 u8 data[0];
427};
428
429/*
430 * Writing cmd register causes STAT_BUSY to get set in status register.
431 * When cmd completes, STAT_BUSY will be cleared.
432 *
433 * If cmd completed successfully STAT_ERROR will be clear
434 * and args registers contain cmd-specific results.
435 *
436 * If cmd error, STAT_ERROR will be set and args[0] contains error code.
437 *
438 * status register is read-only. While STAT_BUSY is set,
439 * all other register contents are read-only.
440 */
441
442/* Make sizeof(vnic_devcmd) a power-of-2 for I/O BAR. */
443#define VNIC_DEVCMD_NARGS 15
444struct vnic_devcmd {
445 u32 status; /* RO */
446 u32 cmd; /* RW */
447 u64 args[VNIC_DEVCMD_NARGS]; /* RW cmd args (little-endian) */
448};
449
450#endif /* _VNIC_DEVCMD_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_enet.h b/drivers/net/ethernet/cisco/enic/vnic_enet.h
new file mode 100644
index 000000000000..609542848e02
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_enet.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_ENIC_H_
21#define _VNIC_ENIC_H_
22
23/* Device-specific region: enet configuration */
24struct vnic_enet_config {
25 u32 flags;
26 u32 wq_desc_count;
27 u32 rq_desc_count;
28 u16 mtu;
29 u16 intr_timer_deprecated;
30 u8 intr_timer_type;
31 u8 intr_mode;
32 char devname[16];
33 u32 intr_timer_usec;
34 u16 loop_tag;
35};
36
37#define VENETF_TSO 0x1 /* TSO enabled */
38#define VENETF_LRO 0x2 /* LRO enabled */
39#define VENETF_RXCSUM 0x4 /* RX csum enabled */
40#define VENETF_TXCSUM 0x8 /* TX csum enabled */
41#define VENETF_RSS 0x10 /* RSS enabled */
42#define VENETF_RSSHASH_IPV4 0x20 /* Hash on IPv4 fields */
43#define VENETF_RSSHASH_TCPIPV4 0x40 /* Hash on TCP + IPv4 fields */
44#define VENETF_RSSHASH_IPV6 0x80 /* Hash on IPv6 fields */
45#define VENETF_RSSHASH_TCPIPV6 0x100 /* Hash on TCP + IPv6 fields */
46#define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */
47#define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */
48#define VENETF_LOOP 0x800 /* Loopback enabled */
49
50#define VENET_INTR_TYPE_MIN 0 /* Timer specs min interrupt spacing */
51#define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */
52
53#define VENET_INTR_MODE_ANY 0 /* Try MSI-X, then MSI, then INTx */
54#define VENET_INTR_MODE_MSI 1 /* Try MSI then INTx */
55#define VENET_INTR_MODE_INTX 2 /* Try INTx only */
56
57#endif /* _VNIC_ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_intr.c b/drivers/net/ethernet/cisco/enic/vnic_intr.c
new file mode 100644
index 000000000000..0ca107f7bc8c
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_intr.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25
26#include "vnic_dev.h"
27#include "vnic_intr.h"
28
29void vnic_intr_free(struct vnic_intr *intr)
30{
31 intr->ctrl = NULL;
32}
33
34int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
35 unsigned int index)
36{
37 intr->index = index;
38 intr->vdev = vdev;
39
40 intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index);
41 if (!intr->ctrl) {
42 pr_err("Failed to hook INTR[%d].ctrl resource\n", index);
43 return -EINVAL;
44 }
45
46 return 0;
47}
48
49void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
50 unsigned int coalescing_type, unsigned int mask_on_assertion)
51{
52 vnic_intr_coalescing_timer_set(intr, coalescing_timer);
53 iowrite32(coalescing_type, &intr->ctrl->coalescing_type);
54 iowrite32(mask_on_assertion, &intr->ctrl->mask_on_assertion);
55 iowrite32(0, &intr->ctrl->int_credits);
56}
57
58void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
59 u32 coalescing_timer)
60{
61 iowrite32(vnic_dev_intr_coal_timer_usec_to_hw(intr->vdev,
62 coalescing_timer), &intr->ctrl->coalescing_timer);
63}
64
65void vnic_intr_clean(struct vnic_intr *intr)
66{
67 iowrite32(0, &intr->ctrl->int_credits);
68}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_intr.h b/drivers/net/ethernet/cisco/enic/vnic_intr.h
new file mode 100644
index 000000000000..2b1636392294
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_intr.h
@@ -0,0 +1,111 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_INTR_H_
21#define _VNIC_INTR_H_
22
23#include <linux/pci.h>
24
25#include "vnic_dev.h"
26
27#define VNIC_INTR_TIMER_TYPE_ABS 0
28#define VNIC_INTR_TIMER_TYPE_QUIET 1
29
30/* Interrupt control */
31struct vnic_intr_ctrl {
32 u32 coalescing_timer; /* 0x00 */
33 u32 pad0;
34 u32 coalescing_value; /* 0x08 */
35 u32 pad1;
36 u32 coalescing_type; /* 0x10 */
37 u32 pad2;
38 u32 mask_on_assertion; /* 0x18 */
39 u32 pad3;
40 u32 mask; /* 0x20 */
41 u32 pad4;
42 u32 int_credits; /* 0x28 */
43 u32 pad5;
44 u32 int_credit_return; /* 0x30 */
45 u32 pad6;
46};
47
48struct vnic_intr {
49 unsigned int index;
50 struct vnic_dev *vdev;
51 struct vnic_intr_ctrl __iomem *ctrl; /* memory-mapped */
52};
53
54static inline void vnic_intr_unmask(struct vnic_intr *intr)
55{
56 iowrite32(0, &intr->ctrl->mask);
57}
58
59static inline void vnic_intr_mask(struct vnic_intr *intr)
60{
61 iowrite32(1, &intr->ctrl->mask);
62}
63
64static inline int vnic_intr_masked(struct vnic_intr *intr)
65{
66 return ioread32(&intr->ctrl->mask);
67}
68
69static inline void vnic_intr_return_credits(struct vnic_intr *intr,
70 unsigned int credits, int unmask, int reset_timer)
71{
72#define VNIC_INTR_UNMASK_SHIFT 16
73#define VNIC_INTR_RESET_TIMER_SHIFT 17
74
75 u32 int_credit_return = (credits & 0xffff) |
76 (unmask ? (1 << VNIC_INTR_UNMASK_SHIFT) : 0) |
77 (reset_timer ? (1 << VNIC_INTR_RESET_TIMER_SHIFT) : 0);
78
79 iowrite32(int_credit_return, &intr->ctrl->int_credit_return);
80}
81
82static inline unsigned int vnic_intr_credits(struct vnic_intr *intr)
83{
84 return ioread32(&intr->ctrl->int_credits);
85}
86
87static inline void vnic_intr_return_all_credits(struct vnic_intr *intr)
88{
89 unsigned int credits = vnic_intr_credits(intr);
90 int unmask = 1;
91 int reset_timer = 1;
92
93 vnic_intr_return_credits(intr, credits, unmask, reset_timer);
94}
95
96static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
97{
98 /* read PBA without clearing */
99 return ioread32(legacy_pba);
100}
101
102void vnic_intr_free(struct vnic_intr *intr);
103int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
104 unsigned int index);
105void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
106 unsigned int coalescing_type, unsigned int mask_on_assertion);
107void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
108 u32 coalescing_timer);
109void vnic_intr_clean(struct vnic_intr *intr);
110
111#endif /* _VNIC_INTR_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_nic.h b/drivers/net/ethernet/cisco/enic/vnic_nic.h
new file mode 100644
index 000000000000..995a50dd4c99
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_nic.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_NIC_H_
21#define _VNIC_NIC_H_
22
23#define NIC_CFG_RSS_DEFAULT_CPU_MASK_FIELD 0xffUL
24#define NIC_CFG_RSS_DEFAULT_CPU_SHIFT 0
25#define NIC_CFG_RSS_HASH_TYPE (0xffUL << 8)
26#define NIC_CFG_RSS_HASH_TYPE_MASK_FIELD 0xffUL
27#define NIC_CFG_RSS_HASH_TYPE_SHIFT 8
28#define NIC_CFG_RSS_HASH_BITS (7UL << 16)
29#define NIC_CFG_RSS_HASH_BITS_MASK_FIELD 7UL
30#define NIC_CFG_RSS_HASH_BITS_SHIFT 16
31#define NIC_CFG_RSS_BASE_CPU (7UL << 19)
32#define NIC_CFG_RSS_BASE_CPU_MASK_FIELD 7UL
33#define NIC_CFG_RSS_BASE_CPU_SHIFT 19
34#define NIC_CFG_RSS_ENABLE (1UL << 22)
35#define NIC_CFG_RSS_ENABLE_MASK_FIELD 1UL
36#define NIC_CFG_RSS_ENABLE_SHIFT 22
37#define NIC_CFG_TSO_IPID_SPLIT_EN (1UL << 23)
38#define NIC_CFG_TSO_IPID_SPLIT_EN_MASK_FIELD 1UL
39#define NIC_CFG_TSO_IPID_SPLIT_EN_SHIFT 23
40#define NIC_CFG_IG_VLAN_STRIP_EN (1UL << 24)
41#define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD 1UL
42#define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT 24
43
44#define NIC_CFG_RSS_HASH_TYPE_IPV4 (1 << 1)
45#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 (1 << 2)
46#define NIC_CFG_RSS_HASH_TYPE_IPV6 (1 << 3)
47#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 (1 << 4)
48#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX (1 << 5)
49#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX (1 << 6)
50
51static inline void vnic_set_nic_cfg(u32 *nic_cfg,
52 u8 rss_default_cpu, u8 rss_hash_type,
53 u8 rss_hash_bits, u8 rss_base_cpu,
54 u8 rss_enable, u8 tso_ipid_split_en,
55 u8 ig_vlan_strip_en)
56{
57 *nic_cfg = (rss_default_cpu & NIC_CFG_RSS_DEFAULT_CPU_MASK_FIELD) |
58 ((rss_hash_type & NIC_CFG_RSS_HASH_TYPE_MASK_FIELD)
59 << NIC_CFG_RSS_HASH_TYPE_SHIFT) |
60 ((rss_hash_bits & NIC_CFG_RSS_HASH_BITS_MASK_FIELD)
61 << NIC_CFG_RSS_HASH_BITS_SHIFT) |
62 ((rss_base_cpu & NIC_CFG_RSS_BASE_CPU_MASK_FIELD)
63 << NIC_CFG_RSS_BASE_CPU_SHIFT) |
64 ((rss_enable & NIC_CFG_RSS_ENABLE_MASK_FIELD)
65 << NIC_CFG_RSS_ENABLE_SHIFT) |
66 ((tso_ipid_split_en & NIC_CFG_TSO_IPID_SPLIT_EN_MASK_FIELD)
67 << NIC_CFG_TSO_IPID_SPLIT_EN_SHIFT) |
68 ((ig_vlan_strip_en & NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD)
69 << NIC_CFG_IG_VLAN_STRIP_EN_SHIFT);
70}
71
72#endif /* _VNIC_NIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_resource.h b/drivers/net/ethernet/cisco/enic/vnic_resource.h
new file mode 100644
index 000000000000..e0a73f1ca6f4
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_resource.h
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_RESOURCE_H_
21#define _VNIC_RESOURCE_H_
22
23#define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */
24#define VNIC_RES_VERSION 0x00000000L
25#define MGMTVNIC_MAGIC 0x544d474dL /* 'MGMT' */
26#define MGMTVNIC_VERSION 0x00000000L
27
28/* The MAC address assigned to the CFG vNIC is fixed. */
29#define MGMTVNIC_MAC { 0x02, 0x00, 0x54, 0x4d, 0x47, 0x4d }
30
31/* vNIC resource types */
32enum vnic_res_type {
33 RES_TYPE_EOL, /* End-of-list */
34 RES_TYPE_WQ, /* Work queues */
35 RES_TYPE_RQ, /* Receive queues */
36 RES_TYPE_CQ, /* Completion queues */
37 RES_TYPE_RSVD1,
38 RES_TYPE_NIC_CFG, /* Enet NIC config registers */
39 RES_TYPE_RSVD2,
40 RES_TYPE_RSVD3,
41 RES_TYPE_RSVD4,
42 RES_TYPE_RSVD5,
43 RES_TYPE_INTR_CTRL, /* Interrupt ctrl table */
44 RES_TYPE_INTR_TABLE, /* MSI/MSI-X Interrupt table */
45 RES_TYPE_INTR_PBA, /* MSI/MSI-X PBA table */
46 RES_TYPE_INTR_PBA_LEGACY, /* Legacy intr status */
47 RES_TYPE_RSVD6,
48 RES_TYPE_RSVD7,
49 RES_TYPE_DEVCMD, /* Device command region */
50 RES_TYPE_PASS_THRU_PAGE, /* Pass-thru page */
51
52 RES_TYPE_MAX, /* Count of resource types */
53};
54
55struct vnic_resource_header {
56 u32 magic;
57 u32 version;
58};
59
60struct mgmt_barmap_hdr {
61 u32 magic; /* magic number */
62 u32 version; /* header format version */
63 u16 lif; /* loopback lif for mgmt frames */
64 u16 pci_slot; /* installed pci slot */
65 char serial[16]; /* card serial number */
66};
67
68struct vnic_resource {
69 u8 type;
70 u8 bar;
71 u8 pad[2];
72 u32 bar_offset;
73 u32 count;
74};
75
76#endif /* _VNIC_RESOURCE_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c
new file mode 100644
index 000000000000..34105e0951a5
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26
27#include "vnic_dev.h"
28#include "vnic_rq.h"
29
30static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
31{
32 struct vnic_rq_buf *buf;
33 struct vnic_dev *vdev;
34 unsigned int i, j, count = rq->ring.desc_count;
35 unsigned int blks = VNIC_RQ_BUF_BLKS_NEEDED(count);
36
37 vdev = rq->vdev;
38
39 for (i = 0; i < blks; i++) {
40 rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC);
41 if (!rq->bufs[i]) {
42 pr_err("Failed to alloc rq_bufs\n");
43 return -ENOMEM;
44 }
45 }
46
47 for (i = 0; i < blks; i++) {
48 buf = rq->bufs[i];
49 for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES(count); j++) {
50 buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES(count) + j;
51 buf->desc = (u8 *)rq->ring.descs +
52 rq->ring.desc_size * buf->index;
53 if (buf->index + 1 == count) {
54 buf->next = rq->bufs[0];
55 break;
56 } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES(count)) {
57 buf->next = rq->bufs[i + 1];
58 } else {
59 buf->next = buf + 1;
60 buf++;
61 }
62 }
63 }
64
65 rq->to_use = rq->to_clean = rq->bufs[0];
66
67 return 0;
68}
69
70void vnic_rq_free(struct vnic_rq *rq)
71{
72 struct vnic_dev *vdev;
73 unsigned int i;
74
75 vdev = rq->vdev;
76
77 vnic_dev_free_desc_ring(vdev, &rq->ring);
78
79 for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) {
80 if (rq->bufs[i]) {
81 kfree(rq->bufs[i]);
82 rq->bufs[i] = NULL;
83 }
84 }
85
86 rq->ctrl = NULL;
87}
88
89int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
90 unsigned int desc_count, unsigned int desc_size)
91{
92 int err;
93
94 rq->index = index;
95 rq->vdev = vdev;
96
97 rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index);
98 if (!rq->ctrl) {
99 pr_err("Failed to hook RQ[%d] resource\n", index);
100 return -EINVAL;
101 }
102
103 vnic_rq_disable(rq);
104
105 err = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size);
106 if (err)
107 return err;
108
109 err = vnic_rq_alloc_bufs(rq);
110 if (err) {
111 vnic_rq_free(rq);
112 return err;
113 }
114
115 return 0;
116}
117
118static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
119 unsigned int fetch_index, unsigned int posted_index,
120 unsigned int error_interrupt_enable,
121 unsigned int error_interrupt_offset)
122{
123 u64 paddr;
124 unsigned int count = rq->ring.desc_count;
125
126 paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
127 writeq(paddr, &rq->ctrl->ring_base);
128 iowrite32(count, &rq->ctrl->ring_size);
129 iowrite32(cq_index, &rq->ctrl->cq_index);
130 iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable);
131 iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset);
132 iowrite32(0, &rq->ctrl->dropped_packet_count);
133 iowrite32(0, &rq->ctrl->error_status);
134 iowrite32(fetch_index, &rq->ctrl->fetch_index);
135 iowrite32(posted_index, &rq->ctrl->posted_index);
136
137 rq->to_use = rq->to_clean =
138 &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
139 [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
140}
141
142void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
143 unsigned int error_interrupt_enable,
144 unsigned int error_interrupt_offset)
145{
146 u32 fetch_index;
147
148 /* Use current fetch_index as the ring starting point */
149 fetch_index = ioread32(&rq->ctrl->fetch_index);
150
151 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */
152 /* Hardware surprise removal: reset fetch_index */
153 fetch_index = 0;
154 }
155
156 vnic_rq_init_start(rq, cq_index,
157 fetch_index, fetch_index,
158 error_interrupt_enable,
159 error_interrupt_offset);
160}
161
162unsigned int vnic_rq_error_status(struct vnic_rq *rq)
163{
164 return ioread32(&rq->ctrl->error_status);
165}
166
167void vnic_rq_enable(struct vnic_rq *rq)
168{
169 iowrite32(1, &rq->ctrl->enable);
170}
171
172int vnic_rq_disable(struct vnic_rq *rq)
173{
174 unsigned int wait;
175
176 iowrite32(0, &rq->ctrl->enable);
177
178 /* Wait for HW to ACK disable request */
179 for (wait = 0; wait < 1000; wait++) {
180 if (!(ioread32(&rq->ctrl->running)))
181 return 0;
182 udelay(10);
183 }
184
185 pr_err("Failed to disable RQ[%d]\n", rq->index);
186
187 return -ETIMEDOUT;
188}
189
190void vnic_rq_clean(struct vnic_rq *rq,
191 void (*buf_clean)(struct vnic_rq *rq, struct vnic_rq_buf *buf))
192{
193 struct vnic_rq_buf *buf;
194 u32 fetch_index;
195 unsigned int count = rq->ring.desc_count;
196
197 buf = rq->to_clean;
198
199 while (vnic_rq_desc_used(rq) > 0) {
200
201 (*buf_clean)(rq, buf);
202
203 buf = rq->to_clean = buf->next;
204 rq->ring.desc_avail++;
205 }
206
207 /* Use current fetch_index as the ring starting point */
208 fetch_index = ioread32(&rq->ctrl->fetch_index);
209
210 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */
211 /* Hardware surprise removal: reset fetch_index */
212 fetch_index = 0;
213 }
214 rq->to_use = rq->to_clean =
215 &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
216 [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
217 iowrite32(fetch_index, &rq->ctrl->posted_index);
218
219 vnic_dev_clear_desc_ring(&rq->ring);
220}
221
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.h b/drivers/net/ethernet/cisco/enic/vnic_rq.h
new file mode 100644
index 000000000000..2056586f4d4b
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.h
@@ -0,0 +1,209 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_RQ_H_
21#define _VNIC_RQ_H_
22
23#include <linux/pci.h>
24
25#include "vnic_dev.h"
26#include "vnic_cq.h"
27
28/* Receive queue control */
29struct vnic_rq_ctrl {
30 u64 ring_base; /* 0x00 */
31 u32 ring_size; /* 0x08 */
32 u32 pad0;
33 u32 posted_index; /* 0x10 */
34 u32 pad1;
35 u32 cq_index; /* 0x18 */
36 u32 pad2;
37 u32 enable; /* 0x20 */
38 u32 pad3;
39 u32 running; /* 0x28 */
40 u32 pad4;
41 u32 fetch_index; /* 0x30 */
42 u32 pad5;
43 u32 error_interrupt_enable; /* 0x38 */
44 u32 pad6;
45 u32 error_interrupt_offset; /* 0x40 */
46 u32 pad7;
47 u32 error_status; /* 0x48 */
48 u32 pad8;
49 u32 dropped_packet_count; /* 0x50 */
50 u32 pad9;
51 u32 dropped_packet_count_rc; /* 0x58 */
52 u32 pad10;
53};
54
55/* Break the vnic_rq_buf allocations into blocks of 32/64 entries */
56#define VNIC_RQ_BUF_MIN_BLK_ENTRIES 32
57#define VNIC_RQ_BUF_DFLT_BLK_ENTRIES 64
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))
63#define VNIC_RQ_BUF_BLKS_NEEDED(entries) \
64 DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES(entries))
65#define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096)
66
67struct vnic_rq_buf {
68 struct vnic_rq_buf *next;
69 dma_addr_t dma_addr;
70 void *os_buf;
71 unsigned int os_buf_index;
72 unsigned int len;
73 unsigned int index;
74 void *desc;
75};
76
77struct vnic_rq {
78 unsigned int index;
79 struct vnic_dev *vdev;
80 struct vnic_rq_ctrl __iomem *ctrl; /* memory-mapped */
81 struct vnic_dev_ring ring;
82 struct vnic_rq_buf *bufs[VNIC_RQ_BUF_BLKS_MAX];
83 struct vnic_rq_buf *to_use;
84 struct vnic_rq_buf *to_clean;
85 void *os_buf_head;
86 unsigned int pkts_outstanding;
87};
88
89static inline unsigned int vnic_rq_desc_avail(struct vnic_rq *rq)
90{
91 /* how many does SW own? */
92 return rq->ring.desc_avail;
93}
94
95static inline unsigned int vnic_rq_desc_used(struct vnic_rq *rq)
96{
97 /* how many does HW own? */
98 return rq->ring.desc_count - rq->ring.desc_avail - 1;
99}
100
101static inline void *vnic_rq_next_desc(struct vnic_rq *rq)
102{
103 return rq->to_use->desc;
104}
105
106static inline unsigned int vnic_rq_next_index(struct vnic_rq *rq)
107{
108 return rq->to_use->index;
109}
110
111static inline void vnic_rq_post(struct vnic_rq *rq,
112 void *os_buf, unsigned int os_buf_index,
113 dma_addr_t dma_addr, unsigned int len)
114{
115 struct vnic_rq_buf *buf = rq->to_use;
116
117 buf->os_buf = os_buf;
118 buf->os_buf_index = os_buf_index;
119 buf->dma_addr = dma_addr;
120 buf->len = len;
121
122 buf = buf->next;
123 rq->to_use = buf;
124 rq->ring.desc_avail--;
125
126 /* Move the posted_index every nth descriptor
127 */
128
129#ifndef VNIC_RQ_RETURN_RATE
130#define VNIC_RQ_RETURN_RATE 0xf /* keep 2^n - 1 */
131#endif
132
133 if ((buf->index & VNIC_RQ_RETURN_RATE) == 0) {
134 /* Adding write memory barrier prevents compiler and/or CPU
135 * reordering, thus avoiding descriptor posting before
136 * descriptor is initialized. Otherwise, hardware can read
137 * stale descriptor fields.
138 */
139 wmb();
140 iowrite32(buf->index, &rq->ctrl->posted_index);
141 }
142}
143
144static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
145{
146 rq->ring.desc_avail += count;
147}
148
149enum desc_return_options {
150 VNIC_RQ_RETURN_DESC,
151 VNIC_RQ_DEFER_RETURN_DESC,
152};
153
154static inline void vnic_rq_service(struct vnic_rq *rq,
155 struct cq_desc *cq_desc, u16 completed_index,
156 int desc_return, void (*buf_service)(struct vnic_rq *rq,
157 struct cq_desc *cq_desc, struct vnic_rq_buf *buf,
158 int skipped, void *opaque), void *opaque)
159{
160 struct vnic_rq_buf *buf;
161 int skipped;
162
163 buf = rq->to_clean;
164 while (1) {
165
166 skipped = (buf->index != completed_index);
167
168 (*buf_service)(rq, cq_desc, buf, skipped, opaque);
169
170 if (desc_return == VNIC_RQ_RETURN_DESC)
171 rq->ring.desc_avail++;
172
173 rq->to_clean = buf->next;
174
175 if (!skipped)
176 break;
177
178 buf = rq->to_clean;
179 }
180}
181
182static inline int vnic_rq_fill(struct vnic_rq *rq,
183 int (*buf_fill)(struct vnic_rq *rq))
184{
185 int err;
186
187 while (vnic_rq_desc_avail(rq) > 0) {
188
189 err = (*buf_fill)(rq);
190 if (err)
191 return err;
192 }
193
194 return 0;
195}
196
197void vnic_rq_free(struct vnic_rq *rq);
198int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
199 unsigned int desc_count, unsigned int desc_size);
200void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
201 unsigned int error_interrupt_enable,
202 unsigned int error_interrupt_offset);
203unsigned int vnic_rq_error_status(struct vnic_rq *rq);
204void vnic_rq_enable(struct vnic_rq *rq);
205int vnic_rq_disable(struct vnic_rq *rq);
206void vnic_rq_clean(struct vnic_rq *rq,
207 void (*buf_clean)(struct vnic_rq *rq, struct vnic_rq_buf *buf));
208
209#endif /* _VNIC_RQ_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rss.h b/drivers/net/ethernet/cisco/enic/vnic_rss.h
new file mode 100644
index 000000000000..fa421baf45b8
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_rss.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 */
18
19#ifndef _VNIC_RSS_H_
20#define _VNIC_RSS_H_
21
22/* RSS key array */
23union vnic_rss_key {
24 struct {
25 u8 b[10];
26 u8 b_pad[6];
27 } key[4];
28 u64 raw[8];
29};
30
31/* RSS cpu array */
32union vnic_rss_cpu {
33 struct {
34 u8 b[4] ;
35 u8 b_pad[4];
36 } cpu[32];
37 u64 raw[32];
38};
39
40#endif /* _VNIC_RSS_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_stats.h b/drivers/net/ethernet/cisco/enic/vnic_stats.h
new file mode 100644
index 000000000000..77750ec93954
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_stats.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_STATS_H_
21#define _VNIC_STATS_H_
22
23/* Tx statistics */
24struct vnic_tx_stats {
25 u64 tx_frames_ok;
26 u64 tx_unicast_frames_ok;
27 u64 tx_multicast_frames_ok;
28 u64 tx_broadcast_frames_ok;
29 u64 tx_bytes_ok;
30 u64 tx_unicast_bytes_ok;
31 u64 tx_multicast_bytes_ok;
32 u64 tx_broadcast_bytes_ok;
33 u64 tx_drops;
34 u64 tx_errors;
35 u64 tx_tso;
36 u64 rsvd[16];
37};
38
39/* Rx statistics */
40struct vnic_rx_stats {
41 u64 rx_frames_ok;
42 u64 rx_frames_total;
43 u64 rx_unicast_frames_ok;
44 u64 rx_multicast_frames_ok;
45 u64 rx_broadcast_frames_ok;
46 u64 rx_bytes_ok;
47 u64 rx_unicast_bytes_ok;
48 u64 rx_multicast_bytes_ok;
49 u64 rx_broadcast_bytes_ok;
50 u64 rx_drop;
51 u64 rx_no_bufs;
52 u64 rx_errors;
53 u64 rx_rss;
54 u64 rx_crc_errors;
55 u64 rx_frames_64;
56 u64 rx_frames_127;
57 u64 rx_frames_255;
58 u64 rx_frames_511;
59 u64 rx_frames_1023;
60 u64 rx_frames_1518;
61 u64 rx_frames_to_max;
62 u64 rsvd[16];
63};
64
65struct vnic_stats {
66 struct vnic_tx_stats tx;
67 struct vnic_rx_stats rx;
68};
69
70#endif /* _VNIC_STATS_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_vic.c b/drivers/net/ethernet/cisco/enic/vnic_vic.c
new file mode 100644
index 000000000000..24ef8cd40545
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_vic.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright 2010 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/types.h>
22#include <linux/slab.h>
23
24#include "vnic_vic.h"
25
26struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
27 const u8 type)
28{
29 struct vic_provinfo *vp;
30
31 if (!oui)
32 return NULL;
33
34 vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags);
35 if (!vp)
36 return NULL;
37
38 memcpy(vp->oui, oui, sizeof(vp->oui));
39 vp->type = type;
40 vp->length = htonl(sizeof(vp->num_tlvs));
41
42 return vp;
43}
44
45void vic_provinfo_free(struct vic_provinfo *vp)
46{
47 kfree(vp);
48}
49
50int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
51 const void *value)
52{
53 struct vic_provinfo_tlv *tlv;
54
55 if (!vp || !value)
56 return -EINVAL;
57
58 if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) +
59 length > VIC_PROVINFO_MAX_TLV_DATA)
60 return -ENOMEM;
61
62 tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
63 ntohl(vp->length) - sizeof(vp->num_tlvs));
64
65 tlv->type = htons(type);
66 tlv->length = htons(length);
67 memcpy(tlv->value, value, length);
68
69 vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
70 vp->length = htonl(ntohl(vp->length) +
71 offsetof(struct vic_provinfo_tlv, value) + length);
72
73 return 0;
74}
75
76size_t vic_provinfo_size(struct vic_provinfo *vp)
77{
78 return vp ? ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0;
79}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_vic.h b/drivers/net/ethernet/cisco/enic/vnic_vic.h
new file mode 100644
index 000000000000..9ef81f148351
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_vic.h
@@ -0,0 +1,83 @@
1/*
2 * Copyright 2010 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef _VNIC_VIC_H_
20#define _VNIC_VIC_H_
21
22/* Note: All integer fields in NETWORK byte order */
23
24/* Note: String field lengths include null char */
25
26#define VIC_PROVINFO_CISCO_OUI { 0x00, 0x00, 0x0c }
27#define VIC_PROVINFO_GENERIC_TYPE 0x4
28
29enum vic_generic_prov_tlv_type {
30 VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR = 0,
31 VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR = 1,
32 VIC_GENERIC_PROV_TLV_CLIENT_NAME_STR = 2,
33 VIC_GENERIC_PROV_TLV_CLUSTER_PORT_NAME_STR = 3,
34 VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR = 4,
35 VIC_GENERIC_PROV_TLV_CLUSTER_UUID_STR = 5,
36 VIC_GENERIC_PROV_TLV_CLUSTER_NAME_STR = 7,
37 VIC_GENERIC_PROV_TLV_HOST_UUID_STR = 8,
38 VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR = 9,
39 VIC_GENERIC_PROV_TLV_INCARNATION_NUMBER = 10,
40 VIC_GENERIC_PROV_TLV_OS_TYPE = 11,
41 VIC_GENERIC_PROV_TLV_OS_VENDOR = 12,
42 VIC_GENERIC_PROV_TLV_CLIENT_TYPE = 15,
43};
44
45enum vic_generic_prov_os_type {
46 VIC_GENERIC_PROV_OS_TYPE_UNKNOWN = 0,
47 VIC_GENERIC_PROV_OS_TYPE_ESX = 1,
48 VIC_GENERIC_PROV_OS_TYPE_LINUX = 2,
49 VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3,
50 VIC_GENERIC_PROV_OS_TYPE_SOLARIS = 4,
51};
52
53struct vic_provinfo {
54 u8 oui[3]; /* OUI of data provider */
55 u8 type; /* provider-specific type */
56 u32 length; /* length of data below */
57 u32 num_tlvs; /* number of tlvs */
58 struct vic_provinfo_tlv {
59 u16 type;
60 u16 length;
61 u8 value[0];
62 } tlv[0];
63} __packed;
64
65#define VIC_PROVINFO_ADD_TLV(vp, tlvtype, tlvlen, data) \
66 do { \
67 err = vic_provinfo_add_tlv(vp, tlvtype, tlvlen, data); \
68 if (err) \
69 goto add_tlv_failure; \
70 } while (0)
71
72#define VIC_PROVINFO_MAX_DATA 1385
73#define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \
74 sizeof(struct vic_provinfo))
75
76struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
77 const u8 type);
78void vic_provinfo_free(struct vic_provinfo *vp);
79int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
80 const void *value);
81size_t vic_provinfo_size(struct vic_provinfo *vp);
82
83#endif /* _VNIC_VIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c
new file mode 100644
index 000000000000..df61bd932ea6
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c
@@ -0,0 +1,200 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26
27#include "vnic_dev.h"
28#include "vnic_wq.h"
29
30static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
31{
32 struct vnic_wq_buf *buf;
33 struct vnic_dev *vdev;
34 unsigned int i, j, count = wq->ring.desc_count;
35 unsigned int blks = VNIC_WQ_BUF_BLKS_NEEDED(count);
36
37 vdev = wq->vdev;
38
39 for (i = 0; i < blks; i++) {
40 wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC);
41 if (!wq->bufs[i]) {
42 pr_err("Failed to alloc wq_bufs\n");
43 return -ENOMEM;
44 }
45 }
46
47 for (i = 0; i < blks; i++) {
48 buf = wq->bufs[i];
49 for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES(count); j++) {
50 buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES(count) + j;
51 buf->desc = (u8 *)wq->ring.descs +
52 wq->ring.desc_size * buf->index;
53 if (buf->index + 1 == count) {
54 buf->next = wq->bufs[0];
55 break;
56 } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES(count)) {
57 buf->next = wq->bufs[i + 1];
58 } else {
59 buf->next = buf + 1;
60 buf++;
61 }
62 }
63 }
64
65 wq->to_use = wq->to_clean = wq->bufs[0];
66
67 return 0;
68}
69
70void vnic_wq_free(struct vnic_wq *wq)
71{
72 struct vnic_dev *vdev;
73 unsigned int i;
74
75 vdev = wq->vdev;
76
77 vnic_dev_free_desc_ring(vdev, &wq->ring);
78
79 for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) {
80 if (wq->bufs[i]) {
81 kfree(wq->bufs[i]);
82 wq->bufs[i] = NULL;
83 }
84 }
85
86 wq->ctrl = NULL;
87}
88
89int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
90 unsigned int desc_count, unsigned int desc_size)
91{
92 int err;
93
94 wq->index = index;
95 wq->vdev = vdev;
96
97 wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index);
98 if (!wq->ctrl) {
99 pr_err("Failed to hook WQ[%d] resource\n", index);
100 return -EINVAL;
101 }
102
103 vnic_wq_disable(wq);
104
105 err = vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size);
106 if (err)
107 return err;
108
109 err = vnic_wq_alloc_bufs(wq);
110 if (err) {
111 vnic_wq_free(wq);
112 return err;
113 }
114
115 return 0;
116}
117
118static void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
119 unsigned int fetch_index, unsigned int posted_index,
120 unsigned int error_interrupt_enable,
121 unsigned int error_interrupt_offset)
122{
123 u64 paddr;
124 unsigned int count = wq->ring.desc_count;
125
126 paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET;
127 writeq(paddr, &wq->ctrl->ring_base);
128 iowrite32(count, &wq->ctrl->ring_size);
129 iowrite32(fetch_index, &wq->ctrl->fetch_index);
130 iowrite32(posted_index, &wq->ctrl->posted_index);
131 iowrite32(cq_index, &wq->ctrl->cq_index);
132 iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable);
133 iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset);
134 iowrite32(0, &wq->ctrl->error_status);
135
136 wq->to_use = wq->to_clean =
137 &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES(count)]
138 [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES(count)];
139}
140
141void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
142 unsigned int error_interrupt_enable,
143 unsigned int error_interrupt_offset)
144{
145 vnic_wq_init_start(wq, cq_index, 0, 0,
146 error_interrupt_enable,
147 error_interrupt_offset);
148}
149
150unsigned int vnic_wq_error_status(struct vnic_wq *wq)
151{
152 return ioread32(&wq->ctrl->error_status);
153}
154
155void vnic_wq_enable(struct vnic_wq *wq)
156{
157 iowrite32(1, &wq->ctrl->enable);
158}
159
160int vnic_wq_disable(struct vnic_wq *wq)
161{
162 unsigned int wait;
163
164 iowrite32(0, &wq->ctrl->enable);
165
166 /* Wait for HW to ACK disable request */
167 for (wait = 0; wait < 1000; wait++) {
168 if (!(ioread32(&wq->ctrl->running)))
169 return 0;
170 udelay(10);
171 }
172
173 pr_err("Failed to disable WQ[%d]\n", wq->index);
174
175 return -ETIMEDOUT;
176}
177
178void vnic_wq_clean(struct vnic_wq *wq,
179 void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf))
180{
181 struct vnic_wq_buf *buf;
182
183 buf = wq->to_clean;
184
185 while (vnic_wq_desc_used(wq) > 0) {
186
187 (*buf_clean)(wq, buf);
188
189 buf = wq->to_clean = buf->next;
190 wq->ring.desc_avail++;
191 }
192
193 wq->to_use = wq->to_clean = wq->bufs[0];
194
195 iowrite32(0, &wq->ctrl->fetch_index);
196 iowrite32(0, &wq->ctrl->posted_index);
197 iowrite32(0, &wq->ctrl->error_status);
198
199 vnic_dev_clear_desc_ring(&wq->ring);
200}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h
new file mode 100644
index 000000000000..7dd937ac11c2
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h
@@ -0,0 +1,165 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _VNIC_WQ_H_
21#define _VNIC_WQ_H_
22
23#include <linux/pci.h>
24
25#include "vnic_dev.h"
26#include "vnic_cq.h"
27
28/* Work queue control */
29struct vnic_wq_ctrl {
30 u64 ring_base; /* 0x00 */
31 u32 ring_size; /* 0x08 */
32 u32 pad0;
33 u32 posted_index; /* 0x10 */
34 u32 pad1;
35 u32 cq_index; /* 0x18 */
36 u32 pad2;
37 u32 enable; /* 0x20 */
38 u32 pad3;
39 u32 running; /* 0x28 */
40 u32 pad4;
41 u32 fetch_index; /* 0x30 */
42 u32 pad5;
43 u32 dca_value; /* 0x38 */
44 u32 pad6;
45 u32 error_interrupt_enable; /* 0x40 */
46 u32 pad7;
47 u32 error_interrupt_offset; /* 0x48 */
48 u32 pad8;
49 u32 error_status; /* 0x50 */
50 u32 pad9;
51};
52
53struct vnic_wq_buf {
54 struct vnic_wq_buf *next;
55 dma_addr_t dma_addr;
56 void *os_buf;
57 unsigned int len;
58 unsigned int index;
59 int sop;
60 void *desc;
61};
62
63/* Break the vnic_wq_buf allocations into blocks of 32/64 entries */
64#define VNIC_WQ_BUF_MIN_BLK_ENTRIES 32
65#define VNIC_WQ_BUF_DFLT_BLK_ENTRIES 64
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))
71#define VNIC_WQ_BUF_BLKS_NEEDED(entries) \
72 DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES(entries))
73#define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096)
74
75struct vnic_wq {
76 unsigned int index;
77 struct vnic_dev *vdev;
78 struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */
79 struct vnic_dev_ring ring;
80 struct vnic_wq_buf *bufs[VNIC_WQ_BUF_BLKS_MAX];
81 struct vnic_wq_buf *to_use;
82 struct vnic_wq_buf *to_clean;
83 unsigned int pkts_outstanding;
84};
85
86static inline unsigned int vnic_wq_desc_avail(struct vnic_wq *wq)
87{
88 /* how many does SW own? */
89 return wq->ring.desc_avail;
90}
91
92static inline unsigned int vnic_wq_desc_used(struct vnic_wq *wq)
93{
94 /* how many does HW own? */
95 return wq->ring.desc_count - wq->ring.desc_avail - 1;
96}
97
98static inline void *vnic_wq_next_desc(struct vnic_wq *wq)
99{
100 return wq->to_use->desc;
101}
102
103static inline void vnic_wq_post(struct vnic_wq *wq,
104 void *os_buf, dma_addr_t dma_addr,
105 unsigned int len, int sop, int eop)
106{
107 struct vnic_wq_buf *buf = wq->to_use;
108
109 buf->sop = sop;
110 buf->os_buf = eop ? os_buf : NULL;
111 buf->dma_addr = dma_addr;
112 buf->len = len;
113
114 buf = buf->next;
115 if (eop) {
116 /* Adding write memory barrier prevents compiler and/or CPU
117 * reordering, thus avoiding descriptor posting before
118 * descriptor is initialized. Otherwise, hardware can read
119 * stale descriptor fields.
120 */
121 wmb();
122 iowrite32(buf->index, &wq->ctrl->posted_index);
123 }
124 wq->to_use = buf;
125
126 wq->ring.desc_avail--;
127}
128
129static inline void vnic_wq_service(struct vnic_wq *wq,
130 struct cq_desc *cq_desc, u16 completed_index,
131 void (*buf_service)(struct vnic_wq *wq,
132 struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque),
133 void *opaque)
134{
135 struct vnic_wq_buf *buf;
136
137 buf = wq->to_clean;
138 while (1) {
139
140 (*buf_service)(wq, cq_desc, buf, opaque);
141
142 wq->ring.desc_avail++;
143
144 wq->to_clean = buf->next;
145
146 if (buf->index == completed_index)
147 break;
148
149 buf = wq->to_clean;
150 }
151}
152
153void vnic_wq_free(struct vnic_wq *wq);
154int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
155 unsigned int desc_count, unsigned int desc_size);
156void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
157 unsigned int error_interrupt_enable,
158 unsigned int error_interrupt_offset);
159unsigned int vnic_wq_error_status(struct vnic_wq *wq);
160void vnic_wq_enable(struct vnic_wq *wq);
161int vnic_wq_disable(struct vnic_wq *wq);
162void vnic_wq_clean(struct vnic_wq *wq,
163 void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf));
164
165#endif /* _VNIC_WQ_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/wq_enet_desc.h b/drivers/net/ethernet/cisco/enic/wq_enet_desc.h
new file mode 100644
index 000000000000..c7021e3a631f
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/wq_enet_desc.h
@@ -0,0 +1,98 @@
1/*
2 * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 *
18 */
19
20#ifndef _WQ_ENET_DESC_H_
21#define _WQ_ENET_DESC_H_
22
23/* Ethernet work queue descriptor: 16B */
24struct wq_enet_desc {
25 __le64 address;
26 __le16 length;
27 __le16 mss_loopback;
28 __le16 header_length_flags;
29 __le16 vlan_tag;
30};
31
32#define WQ_ENET_ADDR_BITS 64
33#define WQ_ENET_LEN_BITS 14
34#define WQ_ENET_LEN_MASK ((1 << WQ_ENET_LEN_BITS) - 1)
35#define WQ_ENET_MSS_BITS 14
36#define WQ_ENET_MSS_MASK ((1 << WQ_ENET_MSS_BITS) - 1)
37#define WQ_ENET_MSS_SHIFT 2
38#define WQ_ENET_LOOPBACK_SHIFT 1
39#define WQ_ENET_HDRLEN_BITS 10
40#define WQ_ENET_HDRLEN_MASK ((1 << WQ_ENET_HDRLEN_BITS) - 1)
41#define WQ_ENET_FLAGS_OM_BITS 2
42#define WQ_ENET_FLAGS_OM_MASK ((1 << WQ_ENET_FLAGS_OM_BITS) - 1)
43#define WQ_ENET_FLAGS_EOP_SHIFT 12
44#define WQ_ENET_FLAGS_CQ_ENTRY_SHIFT 13
45#define WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT 14
46#define WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT 15
47
48#define WQ_ENET_OFFLOAD_MODE_CSUM 0
49#define WQ_ENET_OFFLOAD_MODE_RESERVED 1
50#define WQ_ENET_OFFLOAD_MODE_CSUM_L4 2
51#define WQ_ENET_OFFLOAD_MODE_TSO 3
52
53static inline void wq_enet_desc_enc(struct wq_enet_desc *desc,
54 u64 address, u16 length, u16 mss, u16 header_length,
55 u8 offload_mode, u8 eop, u8 cq_entry, u8 fcoe_encap,
56 u8 vlan_tag_insert, u16 vlan_tag, u8 loopback)
57{
58 desc->address = cpu_to_le64(address);
59 desc->length = cpu_to_le16(length & WQ_ENET_LEN_MASK);
60 desc->mss_loopback = cpu_to_le16((mss & WQ_ENET_MSS_MASK) <<
61 WQ_ENET_MSS_SHIFT | (loopback & 1) << WQ_ENET_LOOPBACK_SHIFT);
62 desc->header_length_flags = cpu_to_le16(
63 (header_length & WQ_ENET_HDRLEN_MASK) |
64 (offload_mode & WQ_ENET_FLAGS_OM_MASK) << WQ_ENET_HDRLEN_BITS |
65 (eop & 1) << WQ_ENET_FLAGS_EOP_SHIFT |
66 (cq_entry & 1) << WQ_ENET_FLAGS_CQ_ENTRY_SHIFT |
67 (fcoe_encap & 1) << WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT |
68 (vlan_tag_insert & 1) << WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT);
69 desc->vlan_tag = cpu_to_le16(vlan_tag);
70}
71
72static inline void wq_enet_desc_dec(struct wq_enet_desc *desc,
73 u64 *address, u16 *length, u16 *mss, u16 *header_length,
74 u8 *offload_mode, u8 *eop, u8 *cq_entry, u8 *fcoe_encap,
75 u8 *vlan_tag_insert, u16 *vlan_tag, u8 *loopback)
76{
77 *address = le64_to_cpu(desc->address);
78 *length = le16_to_cpu(desc->length) & WQ_ENET_LEN_MASK;
79 *mss = (le16_to_cpu(desc->mss_loopback) >> WQ_ENET_MSS_SHIFT) &
80 WQ_ENET_MSS_MASK;
81 *loopback = (u8)((le16_to_cpu(desc->mss_loopback) >>
82 WQ_ENET_LOOPBACK_SHIFT) & 1);
83 *header_length = le16_to_cpu(desc->header_length_flags) &
84 WQ_ENET_HDRLEN_MASK;
85 *offload_mode = (u8)((le16_to_cpu(desc->header_length_flags) >>
86 WQ_ENET_HDRLEN_BITS) & WQ_ENET_FLAGS_OM_MASK);
87 *eop = (u8)((le16_to_cpu(desc->header_length_flags) >>
88 WQ_ENET_FLAGS_EOP_SHIFT) & 1);
89 *cq_entry = (u8)((le16_to_cpu(desc->header_length_flags) >>
90 WQ_ENET_FLAGS_CQ_ENTRY_SHIFT) & 1);
91 *fcoe_encap = (u8)((le16_to_cpu(desc->header_length_flags) >>
92 WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT) & 1);
93 *vlan_tag_insert = (u8)((le16_to_cpu(desc->header_length_flags) >>
94 WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT) & 1);
95 *vlan_tag = le16_to_cpu(desc->vlan_tag);
96}
97
98#endif /* _WQ_ENET_DESC_H_ */