]>
Commit | Line | Data |
---|---|---|
01f2e4ea | 1 | /* |
29046f9b | 2 | * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. |
01f2e4ea SF |
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 | ||
01f2e4ea SF |
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" | |
6ba9cdc0 | 30 | #include "vnic_nic.h" |
717258ba | 31 | #include "vnic_rss.h" |
fef1f07c | 32 | #include <linux/irq.h> |
01f2e4ea SF |
33 | |
34 | #define DRV_NAME "enic" | |
641cb85e | 35 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" |
ca7f41a4 | 36 | #define DRV_VERSION "2.3.0.20" |
92e2b469 | 37 | #define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc" |
01f2e4ea | 38 | |
27e6c7d3 SF |
39 | #define ENIC_BARS_MAX 6 |
40 | ||
822473b6 | 41 | #define ENIC_WQ_MAX 8 |
63da93d9 | 42 | #define ENIC_RQ_MAX 8 |
6ba9cdc0 SF |
43 | #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) |
44 | #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) | |
45 | ||
7c2ce6e6 SS |
46 | #define ENIC_AIC_LARGE_PKT_DIFF 3 |
47 | ||
01f2e4ea SF |
48 | struct enic_msix_entry { |
49 | int requested; | |
50 | char devname[IFNAMSIZ]; | |
51 | irqreturn_t (*isr)(int, void *); | |
52 | void *devid; | |
322cf7e3 | 53 | cpumask_var_t affinity_mask; |
01f2e4ea SF |
54 | }; |
55 | ||
7c2ce6e6 SS |
56 | /* Store only the lower range. Higher range is given by fw. */ |
57 | struct enic_intr_mod_range { | |
58 | u32 small_pkt_range_start; | |
59 | u32 large_pkt_range_start; | |
60 | }; | |
61 | ||
62 | struct enic_intr_mod_table { | |
63 | u32 rx_rate; | |
64 | u32 range_percent; | |
65 | }; | |
66 | ||
67 | #define ENIC_MAX_LINK_SPEEDS 3 | |
68 | #define ENIC_LINK_SPEED_10G 10000 | |
69 | #define ENIC_LINK_SPEED_4G 4000 | |
70 | #define ENIC_LINK_40G_INDEX 2 | |
71 | #define ENIC_LINK_10G_INDEX 1 | |
72 | #define ENIC_LINK_4G_INDEX 0 | |
73 | #define ENIC_RX_COALESCE_RANGE_END 125 | |
74 | #define ENIC_AIC_TS_BREAK 100 | |
75 | ||
76 | struct enic_rx_coal { | |
77 | u32 small_pkt_range_start; | |
78 | u32 large_pkt_range_start; | |
79 | u32 range_end; | |
80 | u32 use_adaptive_rx_coalesce; | |
81 | }; | |
82 | ||
8749b427 RP |
83 | /* priv_flags */ |
84 | #define ENIC_SRIOV_ENABLED (1 << 0) | |
85 | ||
86 | /* enic port profile set flags */ | |
4dce2396 | 87 | #define ENIC_PORT_REQUEST_APPLIED (1 << 0) |
08f382eb SF |
88 | #define ENIC_SET_REQUEST (1 << 1) |
89 | #define ENIC_SET_NAME (1 << 2) | |
90 | #define ENIC_SET_INSTANCE (1 << 3) | |
91 | #define ENIC_SET_HOST (1 << 4) | |
92 | ||
f8bd9091 | 93 | struct enic_port_profile { |
08f382eb | 94 | u32 set; |
f8bd9091 SF |
95 | u8 request; |
96 | char name[PORT_PROFILE_MAX]; | |
97 | u8 instance_uuid[PORT_UUID_MAX]; | |
98 | u8 host_uuid[PORT_UUID_MAX]; | |
0b1c00fc | 99 | u8 vf_mac[ETH_ALEN]; |
29639059 | 100 | u8 mac_addr[ETH_ALEN]; |
f8bd9091 SF |
101 | }; |
102 | ||
a145df23 GV |
103 | /* enic_rfs_fltr_node - rfs filter node in hash table |
104 | * @@keys: IPv4 5 tuple | |
105 | * @flow_id: flow_id of clsf filter provided by kernel | |
106 | * @fltr_id: filter id of clsf filter returned by adaptor | |
107 | * @rq_id: desired rq index | |
108 | * @node: hlist_node | |
109 | */ | |
110 | struct enic_rfs_fltr_node { | |
111 | struct flow_keys keys; | |
112 | u32 flow_id; | |
113 | u16 fltr_id; | |
114 | u16 rq_id; | |
115 | struct hlist_node node; | |
116 | }; | |
117 | ||
118 | /* enic_rfs_flw_tbl - rfs flow table | |
119 | * @max: Maximum number of filters vNIC supports | |
120 | * @free: Number of free filters available | |
121 | * @toclean: hash table index to clean next | |
122 | * @ht_head: hash table list head | |
123 | * @lock: spin lock | |
124 | * @rfs_may_expire: timer function for enic_rps_may_expire_flow | |
125 | */ | |
126 | struct enic_rfs_flw_tbl { | |
127 | u16 max; | |
128 | int free; | |
129 | ||
130 | #define ENIC_RFS_FLW_BITSHIFT (10) | |
131 | #define ENIC_RFS_FLW_MASK ((1 << ENIC_RFS_FLW_BITSHIFT) - 1) | |
132 | u16 toclean:ENIC_RFS_FLW_BITSHIFT; | |
133 | struct hlist_head ht_head[1 << ENIC_RFS_FLW_BITSHIFT]; | |
134 | spinlock_t lock; | |
135 | struct timer_list rfs_may_expire; | |
136 | }; | |
137 | ||
01f2e4ea SF |
138 | /* Per-instance private data structure */ |
139 | struct enic { | |
140 | struct net_device *netdev; | |
141 | struct pci_dev *pdev; | |
142 | struct vnic_enet_config config; | |
27e6c7d3 | 143 | struct vnic_dev_bar bar[ENIC_BARS_MAX]; |
01f2e4ea | 144 | struct vnic_dev *vdev; |
01f2e4ea SF |
145 | struct timer_list notify_timer; |
146 | struct work_struct reset; | |
937317c7 | 147 | struct work_struct tx_hang_reset; |
c97c894d | 148 | struct work_struct change_mtu_work; |
717258ba VK |
149 | struct msix_entry msix_entry[ENIC_INTR_MAX]; |
150 | struct enic_msix_entry msix[ENIC_INTR_MAX]; | |
01f2e4ea SF |
151 | u32 msg_enable; |
152 | spinlock_t devcmd_lock; | |
153 | u8 mac_addr[ETH_ALEN]; | |
9959a185 | 154 | unsigned int flags; |
8749b427 | 155 | unsigned int priv_flags; |
01f2e4ea | 156 | unsigned int mc_count; |
319d7e84 | 157 | unsigned int uc_count; |
01f2e4ea | 158 | u32 port_mtu; |
7c2ce6e6 | 159 | struct enic_rx_coal rx_coalesce_setting; |
7c844599 SF |
160 | u32 rx_coalesce_usecs; |
161 | u32 tx_coalesce_usecs; | |
8749b427 | 162 | #ifdef CONFIG_PCI_IOV |
413708bb | 163 | u16 num_vfs; |
8749b427 | 164 | #endif |
0b038566 | 165 | spinlock_t enic_api_lock; |
3f192795 | 166 | struct enic_port_profile *pp; |
01f2e4ea SF |
167 | |
168 | /* work queue cache line section */ | |
6ba9cdc0 SF |
169 | ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; |
170 | spinlock_t wq_lock[ENIC_WQ_MAX]; | |
01f2e4ea | 171 | unsigned int wq_count; |
1825aca6 VK |
172 | u16 loop_enable; |
173 | u16 loop_tag; | |
01f2e4ea SF |
174 | |
175 | /* receive queue cache line section */ | |
6ba9cdc0 | 176 | ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; |
01f2e4ea | 177 | unsigned int rq_count; |
350991e1 | 178 | u64 rq_truncated_pkts; |
bd9fb1a4 | 179 | u64 rq_bad_fcs; |
4cfe8785 | 180 | struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX]; |
01f2e4ea SF |
181 | |
182 | /* interrupt resource cache line section */ | |
6ba9cdc0 | 183 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; |
01f2e4ea SF |
184 | unsigned int intr_count; |
185 | u32 __iomem *legacy_pba; /* memory-mapped */ | |
186 | ||
187 | /* completion queue cache line section */ | |
188 | ____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX]; | |
189 | unsigned int cq_count; | |
a145df23 | 190 | struct enic_rfs_flw_tbl rfs_h; |
a03bb56e | 191 | u32 rx_copybreak; |
4f675eb2 | 192 | u8 rss_key[ENIC_RSS_LEN]; |
58feff07 | 193 | struct vnic_gen_stats gen_stats; |
01f2e4ea SF |
194 | }; |
195 | ||
6a3c2f83 GV |
196 | static inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev) |
197 | { | |
198 | struct enic *enic = vdev->priv; | |
199 | ||
200 | return enic->netdev; | |
201 | } | |
202 | ||
203 | /* wrappers function for kernel log | |
204 | * Make sure variable vdev of struct vnic_dev is available in the block where | |
205 | * these macros are used | |
206 | */ | |
207 | #define vdev_info(args...) dev_info(&vdev->pdev->dev, args) | |
208 | #define vdev_warn(args...) dev_warn(&vdev->pdev->dev, args) | |
209 | #define vdev_err(args...) dev_err(&vdev->pdev->dev, args) | |
210 | ||
211 | #define vdev_netinfo(args...) netdev_info(vnic_get_netdev(vdev), args) | |
212 | #define vdev_netwarn(args...) netdev_warn(vnic_get_netdev(vdev), args) | |
213 | #define vdev_neterr(args...) netdev_err(vnic_get_netdev(vdev), args) | |
214 | ||
a7a79deb VK |
215 | static inline struct device *enic_get_dev(struct enic *enic) |
216 | { | |
217 | return &(enic->pdev->dev); | |
218 | } | |
219 | ||
f13bbc2f NP |
220 | static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) |
221 | { | |
222 | return rq; | |
223 | } | |
224 | ||
225 | static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq) | |
226 | { | |
227 | return enic->rq_count + wq; | |
228 | } | |
229 | ||
230 | static inline unsigned int enic_legacy_io_intr(void) | |
231 | { | |
232 | return 0; | |
233 | } | |
234 | ||
235 | static inline unsigned int enic_legacy_err_intr(void) | |
236 | { | |
237 | return 1; | |
238 | } | |
239 | ||
240 | static inline unsigned int enic_legacy_notify_intr(void) | |
241 | { | |
242 | return 2; | |
243 | } | |
244 | ||
245 | static inline unsigned int enic_msix_rq_intr(struct enic *enic, | |
246 | unsigned int rq) | |
247 | { | |
248 | return enic->cq[enic_cq_rq(enic, rq)].interrupt_offset; | |
249 | } | |
250 | ||
251 | static inline unsigned int enic_msix_wq_intr(struct enic *enic, | |
252 | unsigned int wq) | |
253 | { | |
254 | return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset; | |
255 | } | |
256 | ||
257 | static inline unsigned int enic_msix_err_intr(struct enic *enic) | |
258 | { | |
259 | return enic->rq_count + enic->wq_count; | |
260 | } | |
261 | ||
262 | static inline unsigned int enic_msix_notify_intr(struct enic *enic) | |
263 | { | |
264 | return enic->rq_count + enic->wq_count + 1; | |
265 | } | |
266 | ||
322cf7e3 GV |
267 | static inline bool enic_is_err_intr(struct enic *enic, int intr) |
268 | { | |
269 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | |
270 | case VNIC_DEV_INTR_MODE_INTX: | |
271 | return intr == enic_legacy_err_intr(); | |
272 | case VNIC_DEV_INTR_MODE_MSIX: | |
273 | return intr == enic_msix_err_intr(enic); | |
274 | case VNIC_DEV_INTR_MODE_MSI: | |
275 | default: | |
276 | return false; | |
277 | } | |
278 | } | |
279 | ||
280 | static inline bool enic_is_notify_intr(struct enic *enic, int intr) | |
281 | { | |
282 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | |
283 | case VNIC_DEV_INTR_MODE_INTX: | |
284 | return intr == enic_legacy_notify_intr(); | |
285 | case VNIC_DEV_INTR_MODE_MSIX: | |
286 | return intr == enic_msix_notify_intr(enic); | |
287 | case VNIC_DEV_INTR_MODE_MSI: | |
288 | default: | |
289 | return false; | |
290 | } | |
291 | } | |
292 | ||
065df159 GV |
293 | static inline int enic_dma_map_check(struct enic *enic, dma_addr_t dma_addr) |
294 | { | |
295 | if (unlikely(pci_dma_mapping_error(enic->pdev, dma_addr))) { | |
296 | net_warn_ratelimited("%s: PCI dma mapping failed!\n", | |
297 | enic->netdev->name); | |
58feff07 | 298 | enic->gen_stats.dma_map_error++; |
065df159 GV |
299 | |
300 | return -ENOMEM; | |
301 | } | |
302 | ||
303 | return 0; | |
304 | } | |
305 | ||
b3abfbd2 | 306 | void enic_reset_addr_lists(struct enic *enic); |
8749b427 | 307 | int enic_sriov_enabled(struct enic *enic); |
889d13f5 | 308 | int enic_is_valid_vf(struct enic *enic, int vf); |
3f192795 | 309 | int enic_is_dynamic(struct enic *enic); |
f13bbc2f | 310 | void enic_set_ethtool_ops(struct net_device *netdev); |
4f675eb2 | 311 | int __enic_set_rsskey(struct enic *enic); |
b3abfbd2 | 312 | |
01f2e4ea | 313 | #endif /* _ENIC_H_ */ |