]>
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" |
3f255dcc | 36 | #define DRV_VERSION "2.1.1.83" |
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; | |
53 | }; | |
54 | ||
7c2ce6e6 SS |
55 | /* Store only the lower range. Higher range is given by fw. */ |
56 | struct enic_intr_mod_range { | |
57 | u32 small_pkt_range_start; | |
58 | u32 large_pkt_range_start; | |
59 | }; | |
60 | ||
61 | struct enic_intr_mod_table { | |
62 | u32 rx_rate; | |
63 | u32 range_percent; | |
64 | }; | |
65 | ||
66 | #define ENIC_MAX_LINK_SPEEDS 3 | |
67 | #define ENIC_LINK_SPEED_10G 10000 | |
68 | #define ENIC_LINK_SPEED_4G 4000 | |
69 | #define ENIC_LINK_40G_INDEX 2 | |
70 | #define ENIC_LINK_10G_INDEX 1 | |
71 | #define ENIC_LINK_4G_INDEX 0 | |
72 | #define ENIC_RX_COALESCE_RANGE_END 125 | |
73 | #define ENIC_AIC_TS_BREAK 100 | |
74 | ||
75 | struct enic_rx_coal { | |
76 | u32 small_pkt_range_start; | |
77 | u32 large_pkt_range_start; | |
78 | u32 range_end; | |
79 | u32 use_adaptive_rx_coalesce; | |
80 | }; | |
81 | ||
8749b427 RP |
82 | /* priv_flags */ |
83 | #define ENIC_SRIOV_ENABLED (1 << 0) | |
84 | ||
85 | /* enic port profile set flags */ | |
4dce2396 | 86 | #define ENIC_PORT_REQUEST_APPLIED (1 << 0) |
08f382eb SF |
87 | #define ENIC_SET_REQUEST (1 << 1) |
88 | #define ENIC_SET_NAME (1 << 2) | |
89 | #define ENIC_SET_INSTANCE (1 << 3) | |
90 | #define ENIC_SET_HOST (1 << 4) | |
91 | ||
f8bd9091 | 92 | struct enic_port_profile { |
08f382eb | 93 | u32 set; |
f8bd9091 SF |
94 | u8 request; |
95 | char name[PORT_PROFILE_MAX]; | |
96 | u8 instance_uuid[PORT_UUID_MAX]; | |
97 | u8 host_uuid[PORT_UUID_MAX]; | |
0b1c00fc | 98 | u8 vf_mac[ETH_ALEN]; |
29639059 | 99 | u8 mac_addr[ETH_ALEN]; |
f8bd9091 SF |
100 | }; |
101 | ||
a145df23 GV |
102 | /* enic_rfs_fltr_node - rfs filter node in hash table |
103 | * @@keys: IPv4 5 tuple | |
104 | * @flow_id: flow_id of clsf filter provided by kernel | |
105 | * @fltr_id: filter id of clsf filter returned by adaptor | |
106 | * @rq_id: desired rq index | |
107 | * @node: hlist_node | |
108 | */ | |
109 | struct enic_rfs_fltr_node { | |
110 | struct flow_keys keys; | |
111 | u32 flow_id; | |
112 | u16 fltr_id; | |
113 | u16 rq_id; | |
114 | struct hlist_node node; | |
115 | }; | |
116 | ||
117 | /* enic_rfs_flw_tbl - rfs flow table | |
118 | * @max: Maximum number of filters vNIC supports | |
119 | * @free: Number of free filters available | |
120 | * @toclean: hash table index to clean next | |
121 | * @ht_head: hash table list head | |
122 | * @lock: spin lock | |
123 | * @rfs_may_expire: timer function for enic_rps_may_expire_flow | |
124 | */ | |
125 | struct enic_rfs_flw_tbl { | |
126 | u16 max; | |
127 | int free; | |
128 | ||
129 | #define ENIC_RFS_FLW_BITSHIFT (10) | |
130 | #define ENIC_RFS_FLW_MASK ((1 << ENIC_RFS_FLW_BITSHIFT) - 1) | |
131 | u16 toclean:ENIC_RFS_FLW_BITSHIFT; | |
132 | struct hlist_head ht_head[1 << ENIC_RFS_FLW_BITSHIFT]; | |
133 | spinlock_t lock; | |
134 | struct timer_list rfs_may_expire; | |
135 | }; | |
136 | ||
01f2e4ea SF |
137 | /* Per-instance private data structure */ |
138 | struct enic { | |
139 | struct net_device *netdev; | |
140 | struct pci_dev *pdev; | |
141 | struct vnic_enet_config config; | |
27e6c7d3 | 142 | struct vnic_dev_bar bar[ENIC_BARS_MAX]; |
01f2e4ea | 143 | struct vnic_dev *vdev; |
01f2e4ea SF |
144 | struct timer_list notify_timer; |
145 | struct work_struct reset; | |
c97c894d | 146 | struct work_struct change_mtu_work; |
717258ba VK |
147 | struct msix_entry msix_entry[ENIC_INTR_MAX]; |
148 | struct enic_msix_entry msix[ENIC_INTR_MAX]; | |
01f2e4ea SF |
149 | u32 msg_enable; |
150 | spinlock_t devcmd_lock; | |
151 | u8 mac_addr[ETH_ALEN]; | |
9959a185 | 152 | unsigned int flags; |
8749b427 | 153 | unsigned int priv_flags; |
01f2e4ea | 154 | unsigned int mc_count; |
319d7e84 | 155 | unsigned int uc_count; |
01f2e4ea | 156 | u32 port_mtu; |
7c2ce6e6 | 157 | struct enic_rx_coal rx_coalesce_setting; |
7c844599 SF |
158 | u32 rx_coalesce_usecs; |
159 | u32 tx_coalesce_usecs; | |
8749b427 | 160 | #ifdef CONFIG_PCI_IOV |
413708bb | 161 | u16 num_vfs; |
8749b427 | 162 | #endif |
0b038566 | 163 | spinlock_t enic_api_lock; |
3f192795 | 164 | struct enic_port_profile *pp; |
01f2e4ea SF |
165 | |
166 | /* work queue cache line section */ | |
6ba9cdc0 SF |
167 | ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; |
168 | spinlock_t wq_lock[ENIC_WQ_MAX]; | |
01f2e4ea | 169 | unsigned int wq_count; |
1825aca6 VK |
170 | u16 loop_enable; |
171 | u16 loop_tag; | |
01f2e4ea SF |
172 | |
173 | /* receive queue cache line section */ | |
6ba9cdc0 | 174 | ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; |
01f2e4ea | 175 | unsigned int rq_count; |
350991e1 | 176 | u64 rq_truncated_pkts; |
bd9fb1a4 | 177 | u64 rq_bad_fcs; |
4cfe8785 | 178 | struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX]; |
01f2e4ea SF |
179 | |
180 | /* interrupt resource cache line section */ | |
6ba9cdc0 | 181 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; |
01f2e4ea SF |
182 | unsigned int intr_count; |
183 | u32 __iomem *legacy_pba; /* memory-mapped */ | |
184 | ||
185 | /* completion queue cache line section */ | |
186 | ____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX]; | |
187 | unsigned int cq_count; | |
a145df23 | 188 | struct enic_rfs_flw_tbl rfs_h; |
a03bb56e | 189 | u32 rx_copybreak; |
4f675eb2 | 190 | u8 rss_key[ENIC_RSS_LEN]; |
58feff07 | 191 | struct vnic_gen_stats gen_stats; |
01f2e4ea SF |
192 | }; |
193 | ||
a7a79deb VK |
194 | static inline struct device *enic_get_dev(struct enic *enic) |
195 | { | |
196 | return &(enic->pdev->dev); | |
197 | } | |
198 | ||
f13bbc2f NP |
199 | static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) |
200 | { | |
201 | return rq; | |
202 | } | |
203 | ||
204 | static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq) | |
205 | { | |
206 | return enic->rq_count + wq; | |
207 | } | |
208 | ||
209 | static inline unsigned int enic_legacy_io_intr(void) | |
210 | { | |
211 | return 0; | |
212 | } | |
213 | ||
214 | static inline unsigned int enic_legacy_err_intr(void) | |
215 | { | |
216 | return 1; | |
217 | } | |
218 | ||
219 | static inline unsigned int enic_legacy_notify_intr(void) | |
220 | { | |
221 | return 2; | |
222 | } | |
223 | ||
224 | static inline unsigned int enic_msix_rq_intr(struct enic *enic, | |
225 | unsigned int rq) | |
226 | { | |
227 | return enic->cq[enic_cq_rq(enic, rq)].interrupt_offset; | |
228 | } | |
229 | ||
230 | static inline unsigned int enic_msix_wq_intr(struct enic *enic, | |
231 | unsigned int wq) | |
232 | { | |
233 | return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset; | |
234 | } | |
235 | ||
236 | static inline unsigned int enic_msix_err_intr(struct enic *enic) | |
237 | { | |
238 | return enic->rq_count + enic->wq_count; | |
239 | } | |
240 | ||
241 | static inline unsigned int enic_msix_notify_intr(struct enic *enic) | |
242 | { | |
243 | return enic->rq_count + enic->wq_count + 1; | |
244 | } | |
245 | ||
065df159 GV |
246 | static inline int enic_dma_map_check(struct enic *enic, dma_addr_t dma_addr) |
247 | { | |
248 | if (unlikely(pci_dma_mapping_error(enic->pdev, dma_addr))) { | |
249 | net_warn_ratelimited("%s: PCI dma mapping failed!\n", | |
250 | enic->netdev->name); | |
58feff07 | 251 | enic->gen_stats.dma_map_error++; |
065df159 GV |
252 | |
253 | return -ENOMEM; | |
254 | } | |
255 | ||
256 | return 0; | |
257 | } | |
258 | ||
b3abfbd2 | 259 | void enic_reset_addr_lists(struct enic *enic); |
8749b427 | 260 | int enic_sriov_enabled(struct enic *enic); |
889d13f5 | 261 | int enic_is_valid_vf(struct enic *enic, int vf); |
3f192795 | 262 | int enic_is_dynamic(struct enic *enic); |
f13bbc2f | 263 | void enic_set_ethtool_ops(struct net_device *netdev); |
4f675eb2 | 264 | int __enic_set_rsskey(struct enic *enic); |
b3abfbd2 | 265 | |
01f2e4ea | 266 | #endif /* _ENIC_H_ */ |