diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 230 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 776 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 658 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 443 | ||||
-rw-r--r-- | drivers/net/benet/be_hw.h | 153 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 1897 |
6 files changed, 3101 insertions, 1056 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 53306bf3f401..a7db870d1641 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,11 +8,11 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #ifndef BE_H | 18 | #ifndef BE_H |
@@ -33,19 +33,23 @@ | |||
33 | 33 | ||
34 | #include "be_hw.h" | 34 | #include "be_hw.h" |
35 | 35 | ||
36 | #define DRV_VER "2.103.175u" | 36 | #define DRV_VER "4.0.100u" |
37 | #define DRV_NAME "be2net" | 37 | #define DRV_NAME "be2net" |
38 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" | 38 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" |
39 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" | 39 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" |
40 | #define OC_NAME "Emulex OneConnect 10Gbps NIC" | 40 | #define OC_NAME "Emulex OneConnect 10Gbps NIC" |
41 | #define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)" | 41 | #define OC_NAME_BE OC_NAME "(be3)" |
42 | #define OC_NAME_LANCER OC_NAME "(Lancer)" | ||
42 | #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" | 43 | #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" |
43 | 44 | ||
44 | #define BE_VENDOR_ID 0x19a2 | 45 | #define BE_VENDOR_ID 0x19a2 |
46 | #define EMULEX_VENDOR_ID 0x10df | ||
45 | #define BE_DEVICE_ID1 0x211 | 47 | #define BE_DEVICE_ID1 0x211 |
46 | #define BE_DEVICE_ID2 0x221 | 48 | #define BE_DEVICE_ID2 0x221 |
47 | #define OC_DEVICE_ID1 0x700 | 49 | #define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */ |
48 | #define OC_DEVICE_ID2 0x710 | 50 | #define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */ |
51 | #define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ | ||
52 | #define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */ | ||
49 | 53 | ||
50 | static inline char *nic_name(struct pci_dev *pdev) | 54 | static inline char *nic_name(struct pci_dev *pdev) |
51 | { | 55 | { |
@@ -53,7 +57,10 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
53 | case OC_DEVICE_ID1: | 57 | case OC_DEVICE_ID1: |
54 | return OC_NAME; | 58 | return OC_NAME; |
55 | case OC_DEVICE_ID2: | 59 | case OC_DEVICE_ID2: |
56 | return OC_NAME1; | 60 | return OC_NAME_BE; |
61 | case OC_DEVICE_ID3: | ||
62 | case OC_DEVICE_ID4: | ||
63 | return OC_NAME_LANCER; | ||
57 | case BE_DEVICE_ID2: | 64 | case BE_DEVICE_ID2: |
58 | return BE3_NAME; | 65 | return BE3_NAME; |
59 | default: | 66 | default: |
@@ -62,7 +69,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
62 | } | 69 | } |
63 | 70 | ||
64 | /* Number of bytes of an RX frame that are copied to skb->data */ | 71 | /* Number of bytes of an RX frame that are copied to skb->data */ |
65 | #define BE_HDR_LEN 64 | 72 | #define BE_HDR_LEN ((u16) 64) |
66 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 | 73 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 |
67 | #define BE_MIN_MTU 256 | 74 | #define BE_MIN_MTU 256 |
68 | 75 | ||
@@ -78,14 +85,15 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
78 | #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ | 85 | #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ |
79 | #define MCC_CQ_LEN 256 | 86 | #define MCC_CQ_LEN 256 |
80 | 87 | ||
88 | #define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ | ||
89 | #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ | ||
90 | #define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */ | ||
81 | #define BE_NAPI_WEIGHT 64 | 91 | #define BE_NAPI_WEIGHT 64 |
82 | #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ | 92 | #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ |
83 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) | 93 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) |
84 | 94 | ||
85 | #define FW_VER_LEN 32 | 95 | #define FW_VER_LEN 32 |
86 | 96 | ||
87 | #define BE_MAX_VF 32 | ||
88 | |||
89 | struct be_dma_mem { | 97 | struct be_dma_mem { |
90 | void *va; | 98 | void *va; |
91 | dma_addr_t dma; | 99 | dma_addr_t dma; |
@@ -147,6 +155,7 @@ struct be_eq_obj { | |||
147 | u16 min_eqd; /* in usecs */ | 155 | u16 min_eqd; /* in usecs */ |
148 | u16 max_eqd; /* in usecs */ | 156 | u16 max_eqd; /* in usecs */ |
149 | u16 cur_eqd; /* in usecs */ | 157 | u16 cur_eqd; /* in usecs */ |
158 | u8 eq_idx; | ||
150 | 159 | ||
151 | struct napi_struct napi; | 160 | struct napi_struct napi; |
152 | }; | 161 | }; |
@@ -157,10 +166,9 @@ struct be_mcc_obj { | |||
157 | bool rearm_cq; | 166 | bool rearm_cq; |
158 | }; | 167 | }; |
159 | 168 | ||
160 | struct be_drvr_stats { | 169 | struct be_tx_stats { |
161 | u32 be_tx_reqs; /* number of TX requests initiated */ | 170 | u32 be_tx_reqs; /* number of TX requests initiated */ |
162 | u32 be_tx_stops; /* number of times TX Q was stopped */ | 171 | u32 be_tx_stops; /* number of times TX Q was stopped */ |
163 | u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */ | ||
164 | u32 be_tx_wrbs; /* number of tx WRBs used */ | 172 | u32 be_tx_wrbs; /* number of tx WRBs used */ |
165 | u32 be_tx_events; /* number of tx completion events */ | 173 | u32 be_tx_events; /* number of tx completion events */ |
166 | u32 be_tx_compl; /* number of tx completion entries processed */ | 174 | u32 be_tx_compl; /* number of tx completion entries processed */ |
@@ -169,35 +177,6 @@ struct be_drvr_stats { | |||
169 | u64 be_tx_bytes_prev; | 177 | u64 be_tx_bytes_prev; |
170 | u64 be_tx_pkts; | 178 | u64 be_tx_pkts; |
171 | u32 be_tx_rate; | 179 | u32 be_tx_rate; |
172 | |||
173 | u32 cache_barrier[16]; | ||
174 | |||
175 | u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */ | ||
176 | u32 be_rx_polls; /* number of times NAPI called poll function */ | ||
177 | u32 be_rx_events; /* number of ucast rx completion events */ | ||
178 | u32 be_rx_compl; /* number of rx completion entries processed */ | ||
179 | ulong be_rx_jiffies; | ||
180 | u64 be_rx_bytes; | ||
181 | u64 be_rx_bytes_prev; | ||
182 | u64 be_rx_pkts; | ||
183 | u32 be_rx_rate; | ||
184 | u32 be_rx_mcast_pkt; | ||
185 | /* number of non ether type II frames dropped where | ||
186 | * frame len > length field of Mac Hdr */ | ||
187 | u32 be_802_3_dropped_frames; | ||
188 | /* number of non ether type II frames malformed where | ||
189 | * in frame len < length field of Mac Hdr */ | ||
190 | u32 be_802_3_malformed_frames; | ||
191 | u32 be_rxcp_err; /* Num rx completion entries w/ err set. */ | ||
192 | ulong rx_fps_jiffies; /* jiffies at last FPS calc */ | ||
193 | u32 be_rx_frags; | ||
194 | u32 be_prev_rx_frags; | ||
195 | u32 be_rx_fps; /* Rx frags per second */ | ||
196 | }; | ||
197 | |||
198 | struct be_stats_obj { | ||
199 | struct be_drvr_stats drvr_stats; | ||
200 | struct be_dma_mem cmd; | ||
201 | }; | 180 | }; |
202 | 181 | ||
203 | struct be_tx_obj { | 182 | struct be_tx_obj { |
@@ -215,10 +194,95 @@ struct be_rx_page_info { | |||
215 | bool last_page_user; | 194 | bool last_page_user; |
216 | }; | 195 | }; |
217 | 196 | ||
197 | struct be_rx_stats { | ||
198 | u32 rx_post_fail;/* number of ethrx buffer alloc failures */ | ||
199 | u32 rx_polls; /* number of times NAPI called poll function */ | ||
200 | u32 rx_events; /* number of ucast rx completion events */ | ||
201 | u32 rx_compl; /* number of rx completion entries processed */ | ||
202 | ulong rx_jiffies; | ||
203 | u64 rx_bytes; | ||
204 | u64 rx_bytes_prev; | ||
205 | u64 rx_pkts; | ||
206 | u32 rx_rate; | ||
207 | u32 rx_mcast_pkts; | ||
208 | u32 rxcp_err; /* Num rx completion entries w/ err set. */ | ||
209 | ulong rx_fps_jiffies; /* jiffies at last FPS calc */ | ||
210 | u32 rx_frags; | ||
211 | u32 prev_rx_frags; | ||
212 | u32 rx_fps; /* Rx frags per second */ | ||
213 | }; | ||
214 | |||
215 | struct be_rx_compl_info { | ||
216 | u32 rss_hash; | ||
217 | u16 vlan_tag; | ||
218 | u16 pkt_size; | ||
219 | u16 rxq_idx; | ||
220 | u16 mac_id; | ||
221 | u8 vlanf; | ||
222 | u8 num_rcvd; | ||
223 | u8 err; | ||
224 | u8 ipf; | ||
225 | u8 tcpf; | ||
226 | u8 udpf; | ||
227 | u8 ip_csum; | ||
228 | u8 l4_csum; | ||
229 | u8 ipv6; | ||
230 | u8 vtm; | ||
231 | u8 pkt_type; | ||
232 | }; | ||
233 | |||
218 | struct be_rx_obj { | 234 | struct be_rx_obj { |
235 | struct be_adapter *adapter; | ||
219 | struct be_queue_info q; | 236 | struct be_queue_info q; |
220 | struct be_queue_info cq; | 237 | struct be_queue_info cq; |
238 | struct be_rx_compl_info rxcp; | ||
221 | struct be_rx_page_info page_info_tbl[RX_Q_LEN]; | 239 | struct be_rx_page_info page_info_tbl[RX_Q_LEN]; |
240 | struct be_eq_obj rx_eq; | ||
241 | struct be_rx_stats stats; | ||
242 | u8 rss_id; | ||
243 | bool rx_post_starved; /* Zero rx frags have been posted to BE */ | ||
244 | u32 cache_line_barrier[16]; | ||
245 | }; | ||
246 | |||
247 | struct be_drv_stats { | ||
248 | u8 be_on_die_temperature; | ||
249 | u64 be_tx_events; | ||
250 | u64 eth_red_drops; | ||
251 | u64 rx_drops_no_pbuf; | ||
252 | u64 rx_drops_no_txpb; | ||
253 | u64 rx_drops_no_erx_descr; | ||
254 | u64 rx_drops_no_tpre_descr; | ||
255 | u64 rx_drops_too_many_frags; | ||
256 | u64 rx_drops_invalid_ring; | ||
257 | u64 forwarded_packets; | ||
258 | u64 rx_drops_mtu; | ||
259 | u64 rx_crc_errors; | ||
260 | u64 rx_alignment_symbol_errors; | ||
261 | u64 rx_pause_frames; | ||
262 | u64 rx_priority_pause_frames; | ||
263 | u64 rx_control_frames; | ||
264 | u64 rx_in_range_errors; | ||
265 | u64 rx_out_range_errors; | ||
266 | u64 rx_frame_too_long; | ||
267 | u64 rx_address_match_errors; | ||
268 | u64 rx_dropped_too_small; | ||
269 | u64 rx_dropped_too_short; | ||
270 | u64 rx_dropped_header_too_small; | ||
271 | u64 rx_dropped_tcp_length; | ||
272 | u64 rx_dropped_runt; | ||
273 | u64 rx_ip_checksum_errs; | ||
274 | u64 rx_tcp_checksum_errs; | ||
275 | u64 rx_udp_checksum_errs; | ||
276 | u64 rx_switched_unicast_packets; | ||
277 | u64 rx_switched_multicast_packets; | ||
278 | u64 rx_switched_broadcast_packets; | ||
279 | u64 tx_pauseframes; | ||
280 | u64 tx_priority_pauseframes; | ||
281 | u64 tx_controlframes; | ||
282 | u64 rxpp_fifo_overflow_drop; | ||
283 | u64 rx_input_fifo_overflow_drop; | ||
284 | u64 pmem_fifo_overflow_drop; | ||
285 | u64 jabber_events; | ||
222 | }; | 286 | }; |
223 | 287 | ||
224 | struct be_vf_cfg { | 288 | struct be_vf_cfg { |
@@ -229,8 +293,8 @@ struct be_vf_cfg { | |||
229 | u32 vf_tx_rate; | 293 | u32 vf_tx_rate; |
230 | }; | 294 | }; |
231 | 295 | ||
232 | #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ | ||
233 | #define BE_INVALID_PMAC_ID 0xffffffff | 296 | #define BE_INVALID_PMAC_ID 0xffffffff |
297 | |||
234 | struct be_adapter { | 298 | struct be_adapter { |
235 | struct pci_dev *pdev; | 299 | struct pci_dev *pdev; |
236 | struct net_device *netdev; | 300 | struct net_device *netdev; |
@@ -239,7 +303,7 @@ struct be_adapter { | |||
239 | u8 __iomem *db; /* Door Bell */ | 303 | u8 __iomem *db; /* Door Bell */ |
240 | u8 __iomem *pcicfg; /* PCI config space */ | 304 | u8 __iomem *pcicfg; /* PCI config space */ |
241 | 305 | ||
242 | spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */ | 306 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ |
243 | struct be_dma_mem mbox_mem; | 307 | struct be_dma_mem mbox_mem; |
244 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr | 308 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr |
245 | * is stored for freeing purpose */ | 309 | * is stored for freeing purpose */ |
@@ -249,37 +313,43 @@ struct be_adapter { | |||
249 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ | 313 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ |
250 | spinlock_t mcc_cq_lock; | 314 | spinlock_t mcc_cq_lock; |
251 | 315 | ||
252 | struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS]; | 316 | struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; |
253 | bool msix_enabled; | 317 | u32 num_msix_vec; |
254 | bool isr_registered; | 318 | bool isr_registered; |
255 | 319 | ||
256 | /* TX Rings */ | 320 | /* TX Rings */ |
257 | struct be_eq_obj tx_eq; | 321 | struct be_eq_obj tx_eq; |
258 | struct be_tx_obj tx_obj; | 322 | struct be_tx_obj tx_obj; |
323 | struct be_tx_stats tx_stats; | ||
259 | 324 | ||
260 | u32 cache_line_break[8]; | 325 | u32 cache_line_break[8]; |
261 | 326 | ||
262 | /* Rx rings */ | 327 | /* Rx rings */ |
263 | struct be_eq_obj rx_eq; | 328 | struct be_rx_obj rx_obj[MAX_RX_QS]; |
264 | struct be_rx_obj rx_obj; | 329 | u32 num_rx_qs; |
265 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ | 330 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ |
266 | bool rx_post_starved; /* Zero rx frags have been posted to BE */ | 331 | |
332 | u8 eq_next_idx; | ||
333 | struct be_drv_stats drv_stats; | ||
267 | 334 | ||
268 | struct vlan_group *vlan_grp; | 335 | struct vlan_group *vlan_grp; |
269 | u16 vlans_added; | 336 | u16 vlans_added; |
270 | u16 max_vlans; /* Number of vlans supported */ | 337 | u16 max_vlans; /* Number of vlans supported */ |
271 | u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; | 338 | u8 vlan_tag[VLAN_N_VID]; |
339 | u8 vlan_prio_bmap; /* Available Priority BitMap */ | ||
340 | u16 recommended_prio; /* Recommended Priority */ | ||
272 | struct be_dma_mem mc_cmd_mem; | 341 | struct be_dma_mem mc_cmd_mem; |
273 | 342 | ||
274 | struct be_stats_obj stats; | 343 | struct be_dma_mem stats_cmd; |
275 | /* Work queue used to perform periodic tasks like getting statistics */ | 344 | /* Work queue used to perform periodic tasks like getting statistics */ |
276 | struct delayed_work work; | 345 | struct delayed_work work; |
346 | u16 work_counter; | ||
277 | 347 | ||
278 | /* Ethtool knobs and info */ | 348 | /* Ethtool knobs and info */ |
279 | bool rx_csum; /* BE card must perform rx-checksumming */ | ||
280 | char fw_ver[FW_VER_LEN]; | 349 | char fw_ver[FW_VER_LEN]; |
281 | u32 if_handle; /* Used to configure filtering */ | 350 | u32 if_handle; /* Used to configure filtering */ |
282 | u32 pmac_id; /* MAC addr handle used by BE card */ | 351 | u32 pmac_id; /* MAC addr handle used by BE card */ |
352 | u32 beacon_state; /* for set_phys_id */ | ||
283 | 353 | ||
284 | bool eeh_err; | 354 | bool eeh_err; |
285 | bool link_up; | 355 | bool link_up; |
@@ -287,10 +357,11 @@ struct be_adapter { | |||
287 | bool promiscuous; | 357 | bool promiscuous; |
288 | bool wol; | 358 | bool wol; |
289 | u32 function_mode; | 359 | u32 function_mode; |
360 | u32 function_caps; | ||
290 | u32 rx_fc; /* Rx flow control */ | 361 | u32 rx_fc; /* Rx flow control */ |
291 | u32 tx_fc; /* Tx flow control */ | 362 | u32 tx_fc; /* Tx flow control */ |
292 | bool ue_detected; | 363 | bool ue_detected; |
293 | bool stats_ioctl_sent; | 364 | bool stats_cmd_sent; |
294 | int link_speed; | 365 | int link_speed; |
295 | u8 port_type; | 366 | u8 port_type; |
296 | u8 transceiver; | 367 | u8 transceiver; |
@@ -299,10 +370,13 @@ struct be_adapter { | |||
299 | u32 flash_status; | 370 | u32 flash_status; |
300 | struct completion flash_compl; | 371 | struct completion flash_compl; |
301 | 372 | ||
373 | bool be3_native; | ||
302 | bool sriov_enabled; | 374 | bool sriov_enabled; |
303 | struct be_vf_cfg vf_cfg[BE_MAX_VF]; | 375 | struct be_vf_cfg *vf_cfg; |
304 | u8 base_eq_id; | ||
305 | u8 is_virtfn; | 376 | u8 is_virtfn; |
377 | u32 sli_family; | ||
378 | u8 hba_port_num; | ||
379 | u16 pvid; | ||
306 | }; | 380 | }; |
307 | 381 | ||
308 | #define be_physfn(adapter) (!adapter->is_virtfn) | 382 | #define be_physfn(adapter) (!adapter->is_virtfn) |
@@ -311,12 +385,26 @@ struct be_adapter { | |||
311 | #define BE_GEN2 2 | 385 | #define BE_GEN2 2 |
312 | #define BE_GEN3 3 | 386 | #define BE_GEN3 3 |
313 | 387 | ||
388 | #define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ | ||
389 | (adapter->pdev->device == OC_DEVICE_ID4)) | ||
390 | |||
314 | extern const struct ethtool_ops be_ethtool_ops; | 391 | extern const struct ethtool_ops be_ethtool_ops; |
315 | 392 | ||
316 | #define drvr_stats(adapter) (&adapter->stats.drvr_stats) | 393 | #define msix_enabled(adapter) (adapter->num_msix_vec > 0) |
394 | #define tx_stats(adapter) (&adapter->tx_stats) | ||
395 | #define rx_stats(rxo) (&rxo->stats) | ||
317 | 396 | ||
318 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) | 397 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) |
319 | 398 | ||
399 | #define for_all_rx_queues(adapter, rxo, i) \ | ||
400 | for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ | ||
401 | i++, rxo++) | ||
402 | |||
403 | /* Just skip the first default non-rss queue */ | ||
404 | #define for_all_rss_queues(adapter, rxo, i) \ | ||
405 | for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\ | ||
406 | i++, rxo++) | ||
407 | |||
320 | #define PAGE_SHIFT_4K 12 | 408 | #define PAGE_SHIFT_4K 12 |
321 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 409 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
322 | 410 | ||
@@ -407,16 +495,34 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) | |||
407 | 495 | ||
408 | static inline void be_check_sriov_fn_type(struct be_adapter *adapter) | 496 | static inline void be_check_sriov_fn_type(struct be_adapter *adapter) |
409 | { | 497 | { |
410 | u8 data; | 498 | u32 sli_intf; |
499 | |||
500 | pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
501 | adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; | ||
502 | } | ||
503 | |||
504 | static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) | ||
505 | { | ||
506 | u32 addr; | ||
507 | |||
508 | addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0); | ||
411 | 509 | ||
412 | pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); | 510 | mac[5] = (u8)(addr & 0xFF); |
413 | pci_read_config_byte(adapter->pdev, 0xFE, &data); | 511 | mac[4] = (u8)((addr >> 8) & 0xFF); |
414 | adapter->is_virtfn = (data != 0xAA); | 512 | mac[3] = (u8)((addr >> 16) & 0xFF); |
513 | /* Use the OUI from the current MAC address */ | ||
514 | memcpy(mac, adapter->netdev->dev_addr, 3); | ||
515 | } | ||
516 | |||
517 | static inline bool be_multi_rxq(const struct be_adapter *adapter) | ||
518 | { | ||
519 | return adapter->num_rx_qs > 1; | ||
415 | } | 520 | } |
416 | 521 | ||
417 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 522 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
418 | u16 num_popped); | 523 | u16 num_popped); |
419 | extern void be_link_status_update(struct be_adapter *adapter, bool link_up); | 524 | extern void be_link_status_update(struct be_adapter *adapter, bool link_up); |
420 | extern void netdev_stats_update(struct be_adapter *adapter); | 525 | extern void netdev_stats_update(struct be_adapter *adapter); |
526 | extern void be_parse_stats(struct be_adapter *adapter); | ||
421 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); | 527 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); |
422 | #endif /* BE_H */ | 528 | #endif /* BE_H */ |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 34abcc9403d6..81654ae16c63 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,21 +8,30 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "be.h" | 18 | #include "be.h" |
19 | #include "be_cmds.h" | 19 | #include "be_cmds.h" |
20 | 20 | ||
21 | /* Must be a power of 2 or else MODULO will BUG_ON */ | ||
22 | static int be_get_temp_freq = 32; | ||
23 | |||
21 | static void be_mcc_notify(struct be_adapter *adapter) | 24 | static void be_mcc_notify(struct be_adapter *adapter) |
22 | { | 25 | { |
23 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 26 | struct be_queue_info *mccq = &adapter->mcc_obj.q; |
24 | u32 val = 0; | 27 | u32 val = 0; |
25 | 28 | ||
29 | if (adapter->eeh_err) { | ||
30 | dev_info(&adapter->pdev->dev, | ||
31 | "Error in Card Detected! Cannot issue commands\n"); | ||
32 | return; | ||
33 | } | ||
34 | |||
26 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; | 35 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; |
27 | val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT; | 36 | val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT; |
28 | 37 | ||
@@ -62,20 +71,40 @@ static int be_mcc_compl_process(struct be_adapter *adapter, | |||
62 | compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & | 71 | compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & |
63 | CQE_STATUS_COMPL_MASK; | 72 | CQE_STATUS_COMPL_MASK; |
64 | 73 | ||
65 | if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && | 74 | if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) || |
75 | (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) && | ||
66 | (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { | 76 | (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { |
67 | adapter->flash_status = compl_status; | 77 | adapter->flash_status = compl_status; |
68 | complete(&adapter->flash_compl); | 78 | complete(&adapter->flash_compl); |
69 | } | 79 | } |
70 | 80 | ||
71 | if (compl_status == MCC_STATUS_SUCCESS) { | 81 | if (compl_status == MCC_STATUS_SUCCESS) { |
72 | if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { | 82 | if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) || |
73 | struct be_cmd_resp_get_stats *resp = | 83 | (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) && |
74 | adapter->stats.cmd.va; | 84 | (compl->tag1 == CMD_SUBSYSTEM_ETH)) { |
75 | be_dws_le_to_cpu(&resp->hw_stats, | 85 | if (adapter->generation == BE_GEN3) { |
76 | sizeof(resp->hw_stats)); | 86 | if (lancer_chip(adapter)) { |
87 | struct lancer_cmd_resp_pport_stats | ||
88 | *resp = adapter->stats_cmd.va; | ||
89 | be_dws_le_to_cpu(&resp->pport_stats, | ||
90 | sizeof(resp->pport_stats)); | ||
91 | } else { | ||
92 | struct be_cmd_resp_get_stats_v1 *resp = | ||
93 | adapter->stats_cmd.va; | ||
94 | |||
95 | be_dws_le_to_cpu(&resp->hw_stats, | ||
96 | sizeof(resp->hw_stats)); | ||
97 | } | ||
98 | } else { | ||
99 | struct be_cmd_resp_get_stats_v0 *resp = | ||
100 | adapter->stats_cmd.va; | ||
101 | |||
102 | be_dws_le_to_cpu(&resp->hw_stats, | ||
103 | sizeof(resp->hw_stats)); | ||
104 | } | ||
105 | be_parse_stats(adapter); | ||
77 | netdev_stats_update(adapter); | 106 | netdev_stats_update(adapter); |
78 | adapter->stats_ioctl_sent = false; | 107 | adapter->stats_cmd_sent = false; |
79 | } | 108 | } |
80 | } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && | 109 | } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && |
81 | (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { | 110 | (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { |
@@ -96,11 +125,77 @@ static void be_async_link_state_process(struct be_adapter *adapter, | |||
96 | evt->port_link_status == ASYNC_EVENT_LINK_UP); | 125 | evt->port_link_status == ASYNC_EVENT_LINK_UP); |
97 | } | 126 | } |
98 | 127 | ||
128 | /* Grp5 CoS Priority evt */ | ||
129 | static void be_async_grp5_cos_priority_process(struct be_adapter *adapter, | ||
130 | struct be_async_event_grp5_cos_priority *evt) | ||
131 | { | ||
132 | if (evt->valid) { | ||
133 | adapter->vlan_prio_bmap = evt->available_priority_bmap; | ||
134 | adapter->recommended_prio &= ~VLAN_PRIO_MASK; | ||
135 | adapter->recommended_prio = | ||
136 | evt->reco_default_priority << VLAN_PRIO_SHIFT; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* Grp5 QOS Speed evt */ | ||
141 | static void be_async_grp5_qos_speed_process(struct be_adapter *adapter, | ||
142 | struct be_async_event_grp5_qos_link_speed *evt) | ||
143 | { | ||
144 | if (evt->physical_port == adapter->port_num) { | ||
145 | /* qos_link_speed is in units of 10 Mbps */ | ||
146 | adapter->link_speed = evt->qos_link_speed * 10; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | /*Grp5 PVID evt*/ | ||
151 | static void be_async_grp5_pvid_state_process(struct be_adapter *adapter, | ||
152 | struct be_async_event_grp5_pvid_state *evt) | ||
153 | { | ||
154 | if (evt->enabled) | ||
155 | adapter->pvid = le16_to_cpu(evt->tag); | ||
156 | else | ||
157 | adapter->pvid = 0; | ||
158 | } | ||
159 | |||
160 | static void be_async_grp5_evt_process(struct be_adapter *adapter, | ||
161 | u32 trailer, struct be_mcc_compl *evt) | ||
162 | { | ||
163 | u8 event_type = 0; | ||
164 | |||
165 | event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) & | ||
166 | ASYNC_TRAILER_EVENT_TYPE_MASK; | ||
167 | |||
168 | switch (event_type) { | ||
169 | case ASYNC_EVENT_COS_PRIORITY: | ||
170 | be_async_grp5_cos_priority_process(adapter, | ||
171 | (struct be_async_event_grp5_cos_priority *)evt); | ||
172 | break; | ||
173 | case ASYNC_EVENT_QOS_SPEED: | ||
174 | be_async_grp5_qos_speed_process(adapter, | ||
175 | (struct be_async_event_grp5_qos_link_speed *)evt); | ||
176 | break; | ||
177 | case ASYNC_EVENT_PVID_STATE: | ||
178 | be_async_grp5_pvid_state_process(adapter, | ||
179 | (struct be_async_event_grp5_pvid_state *)evt); | ||
180 | break; | ||
181 | default: | ||
182 | dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n"); | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | |||
99 | static inline bool is_link_state_evt(u32 trailer) | 187 | static inline bool is_link_state_evt(u32 trailer) |
100 | { | 188 | { |
189 | return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | ||
190 | ASYNC_TRAILER_EVENT_CODE_MASK) == | ||
191 | ASYNC_EVENT_CODE_LINK_STATE; | ||
192 | } | ||
193 | |||
194 | static inline bool is_grp5_evt(u32 trailer) | ||
195 | { | ||
101 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | 196 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & |
102 | ASYNC_TRAILER_EVENT_CODE_MASK) == | 197 | ASYNC_TRAILER_EVENT_CODE_MASK) == |
103 | ASYNC_EVENT_CODE_LINK_STATE); | 198 | ASYNC_EVENT_CODE_GRP_5); |
104 | } | 199 | } |
105 | 200 | ||
106 | static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) | 201 | static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) |
@@ -143,6 +238,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status) | |||
143 | if (is_link_state_evt(compl->flags)) | 238 | if (is_link_state_evt(compl->flags)) |
144 | be_async_link_state_process(adapter, | 239 | be_async_link_state_process(adapter, |
145 | (struct be_async_event_link_state *) compl); | 240 | (struct be_async_event_link_state *) compl); |
241 | else if (is_grp5_evt(compl->flags)) | ||
242 | be_async_grp5_evt_process(adapter, | ||
243 | compl->flags, compl); | ||
146 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 244 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
147 | *status = be_mcc_compl_process(adapter, compl); | 245 | *status = be_mcc_compl_process(adapter, compl); |
148 | atomic_dec(&mcc_obj->q.used); | 246 | atomic_dec(&mcc_obj->q.used); |
@@ -162,6 +260,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
162 | int i, num, status = 0; | 260 | int i, num, status = 0; |
163 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 261 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
164 | 262 | ||
263 | if (adapter->eeh_err) | ||
264 | return -EIO; | ||
265 | |||
165 | for (i = 0; i < mcc_timeout; i++) { | 266 | for (i = 0; i < mcc_timeout; i++) { |
166 | num = be_process_mcc(adapter, &status); | 267 | num = be_process_mcc(adapter, &status); |
167 | if (num) | 268 | if (num) |
@@ -191,6 +292,12 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
191 | int msecs = 0; | 292 | int msecs = 0; |
192 | u32 ready; | 293 | u32 ready; |
193 | 294 | ||
295 | if (adapter->eeh_err) { | ||
296 | dev_err(&adapter->pdev->dev, | ||
297 | "Error detected in card.Cannot issue commands\n"); | ||
298 | return -EIO; | ||
299 | } | ||
300 | |||
194 | do { | 301 | do { |
195 | ready = ioread32(db); | 302 | ready = ioread32(db); |
196 | if (ready == 0xffffffff) { | 303 | if (ready == 0xffffffff) { |
@@ -205,12 +312,12 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
205 | 312 | ||
206 | if (msecs > 4000) { | 313 | if (msecs > 4000) { |
207 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); | 314 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); |
208 | be_detect_dump_ue(adapter); | 315 | if (!lancer_chip(adapter)) |
316 | be_detect_dump_ue(adapter); | ||
209 | return -1; | 317 | return -1; |
210 | } | 318 | } |
211 | 319 | ||
212 | set_current_state(TASK_INTERRUPTIBLE); | 320 | msleep(1); |
213 | schedule_timeout(msecs_to_jiffies(1)); | ||
214 | msecs++; | 321 | msecs++; |
215 | } while (true); | 322 | } while (true); |
216 | 323 | ||
@@ -269,7 +376,12 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) | |||
269 | 376 | ||
270 | static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) | 377 | static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) |
271 | { | 378 | { |
272 | u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); | 379 | u32 sem; |
380 | |||
381 | if (lancer_chip(adapter)) | ||
382 | sem = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET); | ||
383 | else | ||
384 | sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); | ||
273 | 385 | ||
274 | *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; | 386 | *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; |
275 | if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) | 387 | if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) |
@@ -282,23 +394,25 @@ int be_cmd_POST(struct be_adapter *adapter) | |||
282 | { | 394 | { |
283 | u16 stage; | 395 | u16 stage; |
284 | int status, timeout = 0; | 396 | int status, timeout = 0; |
397 | struct device *dev = &adapter->pdev->dev; | ||
285 | 398 | ||
286 | do { | 399 | do { |
287 | status = be_POST_stage_get(adapter, &stage); | 400 | status = be_POST_stage_get(adapter, &stage); |
288 | if (status) { | 401 | if (status) { |
289 | dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n", | 402 | dev_err(dev, "POST error; stage=0x%x\n", stage); |
290 | stage); | ||
291 | return -1; | 403 | return -1; |
292 | } else if (stage != POST_STAGE_ARMFW_RDY) { | 404 | } else if (stage != POST_STAGE_ARMFW_RDY) { |
293 | set_current_state(TASK_INTERRUPTIBLE); | 405 | if (msleep_interruptible(2000)) { |
294 | schedule_timeout(2 * HZ); | 406 | dev_err(dev, "Waiting for POST aborted\n"); |
407 | return -EINTR; | ||
408 | } | ||
295 | timeout += 2; | 409 | timeout += 2; |
296 | } else { | 410 | } else { |
297 | return 0; | 411 | return 0; |
298 | } | 412 | } |
299 | } while (timeout < 40); | 413 | } while (timeout < 40); |
300 | 414 | ||
301 | dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); | 415 | dev_err(dev, "POST timeout; stage=0x%x\n", stage); |
302 | return -1; | 416 | return -1; |
303 | } | 417 | } |
304 | 418 | ||
@@ -408,7 +522,8 @@ int be_cmd_fw_init(struct be_adapter *adapter) | |||
408 | u8 *wrb; | 522 | u8 *wrb; |
409 | int status; | 523 | int status; |
410 | 524 | ||
411 | spin_lock(&adapter->mbox_lock); | 525 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
526 | return -1; | ||
412 | 527 | ||
413 | wrb = (u8 *)wrb_from_mbox(adapter); | 528 | wrb = (u8 *)wrb_from_mbox(adapter); |
414 | *wrb++ = 0xFF; | 529 | *wrb++ = 0xFF; |
@@ -422,7 +537,7 @@ int be_cmd_fw_init(struct be_adapter *adapter) | |||
422 | 537 | ||
423 | status = be_mbox_notify_wait(adapter); | 538 | status = be_mbox_notify_wait(adapter); |
424 | 539 | ||
425 | spin_unlock(&adapter->mbox_lock); | 540 | mutex_unlock(&adapter->mbox_lock); |
426 | return status; | 541 | return status; |
427 | } | 542 | } |
428 | 543 | ||
@@ -437,7 +552,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
437 | if (adapter->eeh_err) | 552 | if (adapter->eeh_err) |
438 | return -EIO; | 553 | return -EIO; |
439 | 554 | ||
440 | spin_lock(&adapter->mbox_lock); | 555 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
556 | return -1; | ||
441 | 557 | ||
442 | wrb = (u8 *)wrb_from_mbox(adapter); | 558 | wrb = (u8 *)wrb_from_mbox(adapter); |
443 | *wrb++ = 0xFF; | 559 | *wrb++ = 0xFF; |
@@ -451,7 +567,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
451 | 567 | ||
452 | status = be_mbox_notify_wait(adapter); | 568 | status = be_mbox_notify_wait(adapter); |
453 | 569 | ||
454 | spin_unlock(&adapter->mbox_lock); | 570 | mutex_unlock(&adapter->mbox_lock); |
455 | return status; | 571 | return status; |
456 | } | 572 | } |
457 | int be_cmd_eq_create(struct be_adapter *adapter, | 573 | int be_cmd_eq_create(struct be_adapter *adapter, |
@@ -462,7 +578,8 @@ int be_cmd_eq_create(struct be_adapter *adapter, | |||
462 | struct be_dma_mem *q_mem = &eq->dma_mem; | 578 | struct be_dma_mem *q_mem = &eq->dma_mem; |
463 | int status; | 579 | int status; |
464 | 580 | ||
465 | spin_lock(&adapter->mbox_lock); | 581 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
582 | return -1; | ||
466 | 583 | ||
467 | wrb = wrb_from_mbox(adapter); | 584 | wrb = wrb_from_mbox(adapter); |
468 | req = embedded_payload(wrb); | 585 | req = embedded_payload(wrb); |
@@ -492,7 +609,7 @@ int be_cmd_eq_create(struct be_adapter *adapter, | |||
492 | eq->created = true; | 609 | eq->created = true; |
493 | } | 610 | } |
494 | 611 | ||
495 | spin_unlock(&adapter->mbox_lock); | 612 | mutex_unlock(&adapter->mbox_lock); |
496 | return status; | 613 | return status; |
497 | } | 614 | } |
498 | 615 | ||
@@ -504,7 +621,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | |||
504 | struct be_cmd_req_mac_query *req; | 621 | struct be_cmd_req_mac_query *req; |
505 | int status; | 622 | int status; |
506 | 623 | ||
507 | spin_lock(&adapter->mbox_lock); | 624 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
625 | return -1; | ||
508 | 626 | ||
509 | wrb = wrb_from_mbox(adapter); | 627 | wrb = wrb_from_mbox(adapter); |
510 | req = embedded_payload(wrb); | 628 | req = embedded_payload(wrb); |
@@ -529,13 +647,13 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | |||
529 | memcpy(mac_addr, resp->mac.addr, ETH_ALEN); | 647 | memcpy(mac_addr, resp->mac.addr, ETH_ALEN); |
530 | } | 648 | } |
531 | 649 | ||
532 | spin_unlock(&adapter->mbox_lock); | 650 | mutex_unlock(&adapter->mbox_lock); |
533 | return status; | 651 | return status; |
534 | } | 652 | } |
535 | 653 | ||
536 | /* Uses synchronous MCCQ */ | 654 | /* Uses synchronous MCCQ */ |
537 | int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | 655 | int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, |
538 | u32 if_id, u32 *pmac_id) | 656 | u32 if_id, u32 *pmac_id, u32 domain) |
539 | { | 657 | { |
540 | struct be_mcc_wrb *wrb; | 658 | struct be_mcc_wrb *wrb; |
541 | struct be_cmd_req_pmac_add *req; | 659 | struct be_cmd_req_pmac_add *req; |
@@ -556,6 +674,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
556 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 674 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
557 | OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req)); | 675 | OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req)); |
558 | 676 | ||
677 | req->hdr.domain = domain; | ||
559 | req->if_id = cpu_to_le32(if_id); | 678 | req->if_id = cpu_to_le32(if_id); |
560 | memcpy(req->mac_address, mac_addr, ETH_ALEN); | 679 | memcpy(req->mac_address, mac_addr, ETH_ALEN); |
561 | 680 | ||
@@ -571,7 +690,7 @@ err: | |||
571 | } | 690 | } |
572 | 691 | ||
573 | /* Uses synchronous MCCQ */ | 692 | /* Uses synchronous MCCQ */ |
574 | int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) | 693 | int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom) |
575 | { | 694 | { |
576 | struct be_mcc_wrb *wrb; | 695 | struct be_mcc_wrb *wrb; |
577 | struct be_cmd_req_pmac_del *req; | 696 | struct be_cmd_req_pmac_del *req; |
@@ -592,6 +711,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) | |||
592 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 711 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
593 | OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req)); | 712 | OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req)); |
594 | 713 | ||
714 | req->hdr.domain = dom; | ||
595 | req->if_id = cpu_to_le32(if_id); | 715 | req->if_id = cpu_to_le32(if_id); |
596 | req->pmac_id = cpu_to_le32(pmac_id); | 716 | req->pmac_id = cpu_to_le32(pmac_id); |
597 | 717 | ||
@@ -613,7 +733,8 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
613 | void *ctxt; | 733 | void *ctxt; |
614 | int status; | 734 | int status; |
615 | 735 | ||
616 | spin_lock(&adapter->mbox_lock); | 736 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
737 | return -1; | ||
617 | 738 | ||
618 | wrb = wrb_from_mbox(adapter); | 739 | wrb = wrb_from_mbox(adapter); |
619 | req = embedded_payload(wrb); | 740 | req = embedded_payload(wrb); |
@@ -626,16 +747,34 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
626 | OPCODE_COMMON_CQ_CREATE, sizeof(*req)); | 747 | OPCODE_COMMON_CQ_CREATE, sizeof(*req)); |
627 | 748 | ||
628 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); | 749 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); |
750 | if (lancer_chip(adapter)) { | ||
751 | req->hdr.version = 2; | ||
752 | req->page_size = 1; /* 1 for 4K */ | ||
753 | AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt, | ||
754 | no_delay); | ||
755 | AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt, | ||
756 | __ilog2_u32(cq->len/256)); | ||
757 | AMAP_SET_BITS(struct amap_cq_context_lancer, valid, ctxt, 1); | ||
758 | AMAP_SET_BITS(struct amap_cq_context_lancer, eventable, | ||
759 | ctxt, 1); | ||
760 | AMAP_SET_BITS(struct amap_cq_context_lancer, eqid, | ||
761 | ctxt, eq->id); | ||
762 | AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1); | ||
763 | } else { | ||
764 | AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt, | ||
765 | coalesce_wm); | ||
766 | AMAP_SET_BITS(struct amap_cq_context_be, nodelay, | ||
767 | ctxt, no_delay); | ||
768 | AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt, | ||
769 | __ilog2_u32(cq->len/256)); | ||
770 | AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1); | ||
771 | AMAP_SET_BITS(struct amap_cq_context_be, solevent, | ||
772 | ctxt, sol_evts); | ||
773 | AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1); | ||
774 | AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id); | ||
775 | AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1); | ||
776 | } | ||
629 | 777 | ||
630 | AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm); | ||
631 | AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); | ||
632 | AMAP_SET_BITS(struct amap_cq_context, count, ctxt, | ||
633 | __ilog2_u32(cq->len/256)); | ||
634 | AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); | ||
635 | AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); | ||
636 | AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); | ||
637 | AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); | ||
638 | AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); | ||
639 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); | 778 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); |
640 | 779 | ||
641 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | 780 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
@@ -647,7 +786,7 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
647 | cq->created = true; | 786 | cq->created = true; |
648 | } | 787 | } |
649 | 788 | ||
650 | spin_unlock(&adapter->mbox_lock); | 789 | mutex_unlock(&adapter->mbox_lock); |
651 | 790 | ||
652 | return status; | 791 | return status; |
653 | } | 792 | } |
@@ -670,25 +809,41 @@ int be_cmd_mccq_create(struct be_adapter *adapter, | |||
670 | void *ctxt; | 809 | void *ctxt; |
671 | int status; | 810 | int status; |
672 | 811 | ||
673 | spin_lock(&adapter->mbox_lock); | 812 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
813 | return -1; | ||
674 | 814 | ||
675 | wrb = wrb_from_mbox(adapter); | 815 | wrb = wrb_from_mbox(adapter); |
676 | req = embedded_payload(wrb); | 816 | req = embedded_payload(wrb); |
677 | ctxt = &req->context; | 817 | ctxt = &req->context; |
678 | 818 | ||
679 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | 819 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, |
680 | OPCODE_COMMON_MCC_CREATE); | 820 | OPCODE_COMMON_MCC_CREATE_EXT); |
681 | 821 | ||
682 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 822 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
683 | OPCODE_COMMON_MCC_CREATE, sizeof(*req)); | 823 | OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); |
684 | 824 | ||
685 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); | 825 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); |
826 | if (lancer_chip(adapter)) { | ||
827 | req->hdr.version = 1; | ||
828 | req->cq_id = cpu_to_le16(cq->id); | ||
829 | |||
830 | AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt, | ||
831 | be_encoded_q_len(mccq->len)); | ||
832 | AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1); | ||
833 | AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id, | ||
834 | ctxt, cq->id); | ||
835 | AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid, | ||
836 | ctxt, 1); | ||
686 | 837 | ||
687 | AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); | 838 | } else { |
688 | AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, | 839 | AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1); |
689 | be_encoded_q_len(mccq->len)); | 840 | AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt, |
690 | AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); | 841 | be_encoded_q_len(mccq->len)); |
842 | AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id); | ||
843 | } | ||
691 | 844 | ||
845 | /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ | ||
846 | req->async_event_bitmap[0] = cpu_to_le32(0x00000022); | ||
692 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); | 847 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); |
693 | 848 | ||
694 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | 849 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
@@ -699,7 +854,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, | |||
699 | mccq->id = le16_to_cpu(resp->id); | 854 | mccq->id = le16_to_cpu(resp->id); |
700 | mccq->created = true; | 855 | mccq->created = true; |
701 | } | 856 | } |
702 | spin_unlock(&adapter->mbox_lock); | 857 | mutex_unlock(&adapter->mbox_lock); |
703 | 858 | ||
704 | return status; | 859 | return status; |
705 | } | 860 | } |
@@ -714,7 +869,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
714 | void *ctxt; | 869 | void *ctxt; |
715 | int status; | 870 | int status; |
716 | 871 | ||
717 | spin_lock(&adapter->mbox_lock); | 872 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
873 | return -1; | ||
718 | 874 | ||
719 | wrb = wrb_from_mbox(adapter); | 875 | wrb = wrb_from_mbox(adapter); |
720 | req = embedded_payload(wrb); | 876 | req = embedded_payload(wrb); |
@@ -726,6 +882,12 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
726 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, | 882 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, |
727 | sizeof(*req)); | 883 | sizeof(*req)); |
728 | 884 | ||
885 | if (lancer_chip(adapter)) { | ||
886 | req->hdr.version = 1; | ||
887 | AMAP_SET_BITS(struct amap_tx_context, if_id, ctxt, | ||
888 | adapter->if_handle); | ||
889 | } | ||
890 | |||
729 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | 891 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); |
730 | req->ulp_num = BE_ULP1_NUM; | 892 | req->ulp_num = BE_ULP1_NUM; |
731 | req->type = BE_ETH_TX_RING_TYPE_STANDARD; | 893 | req->type = BE_ETH_TX_RING_TYPE_STANDARD; |
@@ -746,7 +908,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
746 | txq->created = true; | 908 | txq->created = true; |
747 | } | 909 | } |
748 | 910 | ||
749 | spin_unlock(&adapter->mbox_lock); | 911 | mutex_unlock(&adapter->mbox_lock); |
750 | 912 | ||
751 | return status; | 913 | return status; |
752 | } | 914 | } |
@@ -754,14 +916,15 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
754 | /* Uses mbox */ | 916 | /* Uses mbox */ |
755 | int be_cmd_rxq_create(struct be_adapter *adapter, | 917 | int be_cmd_rxq_create(struct be_adapter *adapter, |
756 | struct be_queue_info *rxq, u16 cq_id, u16 frag_size, | 918 | struct be_queue_info *rxq, u16 cq_id, u16 frag_size, |
757 | u16 max_frame_size, u32 if_id, u32 rss) | 919 | u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id) |
758 | { | 920 | { |
759 | struct be_mcc_wrb *wrb; | 921 | struct be_mcc_wrb *wrb; |
760 | struct be_cmd_req_eth_rx_create *req; | 922 | struct be_cmd_req_eth_rx_create *req; |
761 | struct be_dma_mem *q_mem = &rxq->dma_mem; | 923 | struct be_dma_mem *q_mem = &rxq->dma_mem; |
762 | int status; | 924 | int status; |
763 | 925 | ||
764 | spin_lock(&adapter->mbox_lock); | 926 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
927 | return -1; | ||
765 | 928 | ||
766 | wrb = wrb_from_mbox(adapter); | 929 | wrb = wrb_from_mbox(adapter); |
767 | req = embedded_payload(wrb); | 930 | req = embedded_payload(wrb); |
@@ -785,9 +948,10 @@ int be_cmd_rxq_create(struct be_adapter *adapter, | |||
785 | struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); | 948 | struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); |
786 | rxq->id = le16_to_cpu(resp->id); | 949 | rxq->id = le16_to_cpu(resp->id); |
787 | rxq->created = true; | 950 | rxq->created = true; |
951 | *rss_id = resp->rss_id; | ||
788 | } | 952 | } |
789 | 953 | ||
790 | spin_unlock(&adapter->mbox_lock); | 954 | mutex_unlock(&adapter->mbox_lock); |
791 | 955 | ||
792 | return status; | 956 | return status; |
793 | } | 957 | } |
@@ -806,7 +970,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
806 | if (adapter->eeh_err) | 970 | if (adapter->eeh_err) |
807 | return -EIO; | 971 | return -EIO; |
808 | 972 | ||
809 | spin_lock(&adapter->mbox_lock); | 973 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
974 | return -1; | ||
810 | 975 | ||
811 | wrb = wrb_from_mbox(adapter); | 976 | wrb = wrb_from_mbox(adapter); |
812 | req = embedded_payload(wrb); | 977 | req = embedded_payload(wrb); |
@@ -843,7 +1008,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
843 | 1008 | ||
844 | status = be_mbox_notify_wait(adapter); | 1009 | status = be_mbox_notify_wait(adapter); |
845 | 1010 | ||
846 | spin_unlock(&adapter->mbox_lock); | 1011 | mutex_unlock(&adapter->mbox_lock); |
847 | 1012 | ||
848 | return status; | 1013 | return status; |
849 | } | 1014 | } |
@@ -859,7 +1024,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
859 | struct be_cmd_req_if_create *req; | 1024 | struct be_cmd_req_if_create *req; |
860 | int status; | 1025 | int status; |
861 | 1026 | ||
862 | spin_lock(&adapter->mbox_lock); | 1027 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1028 | return -1; | ||
863 | 1029 | ||
864 | wrb = wrb_from_mbox(adapter); | 1030 | wrb = wrb_from_mbox(adapter); |
865 | req = embedded_payload(wrb); | 1031 | req = embedded_payload(wrb); |
@@ -885,12 +1051,12 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
885 | *pmac_id = le32_to_cpu(resp->pmac_id); | 1051 | *pmac_id = le32_to_cpu(resp->pmac_id); |
886 | } | 1052 | } |
887 | 1053 | ||
888 | spin_unlock(&adapter->mbox_lock); | 1054 | mutex_unlock(&adapter->mbox_lock); |
889 | return status; | 1055 | return status; |
890 | } | 1056 | } |
891 | 1057 | ||
892 | /* Uses mbox */ | 1058 | /* Uses mbox */ |
893 | int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | 1059 | int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain) |
894 | { | 1060 | { |
895 | struct be_mcc_wrb *wrb; | 1061 | struct be_mcc_wrb *wrb; |
896 | struct be_cmd_req_if_destroy *req; | 1062 | struct be_cmd_req_if_destroy *req; |
@@ -899,7 +1065,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | |||
899 | if (adapter->eeh_err) | 1065 | if (adapter->eeh_err) |
900 | return -EIO; | 1066 | return -EIO; |
901 | 1067 | ||
902 | spin_lock(&adapter->mbox_lock); | 1068 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1069 | return -1; | ||
903 | 1070 | ||
904 | wrb = wrb_from_mbox(adapter); | 1071 | wrb = wrb_from_mbox(adapter); |
905 | req = embedded_payload(wrb); | 1072 | req = embedded_payload(wrb); |
@@ -910,11 +1077,12 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | |||
910 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1077 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
911 | OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); | 1078 | OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); |
912 | 1079 | ||
1080 | req->hdr.domain = domain; | ||
913 | req->interface_id = cpu_to_le32(interface_id); | 1081 | req->interface_id = cpu_to_le32(interface_id); |
914 | 1082 | ||
915 | status = be_mbox_notify_wait(adapter); | 1083 | status = be_mbox_notify_wait(adapter); |
916 | 1084 | ||
917 | spin_unlock(&adapter->mbox_lock); | 1085 | mutex_unlock(&adapter->mbox_lock); |
918 | 1086 | ||
919 | return status; | 1087 | return status; |
920 | } | 1088 | } |
@@ -926,10 +1094,13 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | |||
926 | int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) | 1094 | int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) |
927 | { | 1095 | { |
928 | struct be_mcc_wrb *wrb; | 1096 | struct be_mcc_wrb *wrb; |
929 | struct be_cmd_req_get_stats *req; | 1097 | struct be_cmd_req_hdr *hdr; |
930 | struct be_sge *sge; | 1098 | struct be_sge *sge; |
931 | int status = 0; | 1099 | int status = 0; |
932 | 1100 | ||
1101 | if (MODULO(adapter->work_counter, be_get_temp_freq) == 0) | ||
1102 | be_cmd_get_die_temperature(adapter); | ||
1103 | |||
933 | spin_lock_bh(&adapter->mcc_lock); | 1104 | spin_lock_bh(&adapter->mcc_lock); |
934 | 1105 | ||
935 | wrb = wrb_from_mccq(adapter); | 1106 | wrb = wrb_from_mccq(adapter); |
@@ -937,20 +1108,68 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) | |||
937 | status = -EBUSY; | 1108 | status = -EBUSY; |
938 | goto err; | 1109 | goto err; |
939 | } | 1110 | } |
940 | req = nonemb_cmd->va; | 1111 | hdr = nonemb_cmd->va; |
941 | sge = nonembedded_sgl(wrb); | 1112 | sge = nonembedded_sgl(wrb); |
942 | 1113 | ||
943 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, | 1114 | be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1, |
944 | OPCODE_ETH_GET_STATISTICS); | 1115 | OPCODE_ETH_GET_STATISTICS); |
945 | 1116 | ||
1117 | be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH, | ||
1118 | OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size); | ||
1119 | |||
1120 | if (adapter->generation == BE_GEN3) | ||
1121 | hdr->version = 1; | ||
1122 | |||
1123 | wrb->tag1 = CMD_SUBSYSTEM_ETH; | ||
1124 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); | ||
1125 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); | ||
1126 | sge->len = cpu_to_le32(nonemb_cmd->size); | ||
1127 | |||
1128 | be_mcc_notify(adapter); | ||
1129 | adapter->stats_cmd_sent = true; | ||
1130 | |||
1131 | err: | ||
1132 | spin_unlock_bh(&adapter->mcc_lock); | ||
1133 | return status; | ||
1134 | } | ||
1135 | |||
1136 | /* Lancer Stats */ | ||
1137 | int lancer_cmd_get_pport_stats(struct be_adapter *adapter, | ||
1138 | struct be_dma_mem *nonemb_cmd) | ||
1139 | { | ||
1140 | |||
1141 | struct be_mcc_wrb *wrb; | ||
1142 | struct lancer_cmd_req_pport_stats *req; | ||
1143 | struct be_sge *sge; | ||
1144 | int status = 0; | ||
1145 | |||
1146 | spin_lock_bh(&adapter->mcc_lock); | ||
1147 | |||
1148 | wrb = wrb_from_mccq(adapter); | ||
1149 | if (!wrb) { | ||
1150 | status = -EBUSY; | ||
1151 | goto err; | ||
1152 | } | ||
1153 | req = nonemb_cmd->va; | ||
1154 | sge = nonembedded_sgl(wrb); | ||
1155 | |||
1156 | be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1, | ||
1157 | OPCODE_ETH_GET_PPORT_STATS); | ||
1158 | |||
946 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, | 1159 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, |
947 | OPCODE_ETH_GET_STATISTICS, sizeof(*req)); | 1160 | OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size); |
1161 | |||
1162 | |||
1163 | req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num); | ||
1164 | req->cmd_params.params.reset_stats = 0; | ||
1165 | |||
1166 | wrb->tag1 = CMD_SUBSYSTEM_ETH; | ||
948 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); | 1167 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); |
949 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); | 1168 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); |
950 | sge->len = cpu_to_le32(nonemb_cmd->size); | 1169 | sge->len = cpu_to_le32(nonemb_cmd->size); |
951 | 1170 | ||
952 | be_mcc_notify(adapter); | 1171 | be_mcc_notify(adapter); |
953 | adapter->stats_ioctl_sent = true; | 1172 | adapter->stats_cmd_sent = true; |
954 | 1173 | ||
955 | err: | 1174 | err: |
956 | spin_unlock_bh(&adapter->mcc_lock); | 1175 | spin_unlock_bh(&adapter->mcc_lock); |
@@ -959,7 +1178,7 @@ err: | |||
959 | 1178 | ||
960 | /* Uses synchronous mcc */ | 1179 | /* Uses synchronous mcc */ |
961 | int be_cmd_link_status_query(struct be_adapter *adapter, | 1180 | int be_cmd_link_status_query(struct be_adapter *adapter, |
962 | bool *link_up, u8 *mac_speed, u16 *link_speed) | 1181 | bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom) |
963 | { | 1182 | { |
964 | struct be_mcc_wrb *wrb; | 1183 | struct be_mcc_wrb *wrb; |
965 | struct be_cmd_req_link_status *req; | 1184 | struct be_cmd_req_link_status *req; |
@@ -997,6 +1216,154 @@ err: | |||
997 | return status; | 1216 | return status; |
998 | } | 1217 | } |
999 | 1218 | ||
1219 | /* Uses synchronous mcc */ | ||
1220 | int be_cmd_get_die_temperature(struct be_adapter *adapter) | ||
1221 | { | ||
1222 | struct be_mcc_wrb *wrb; | ||
1223 | struct be_cmd_req_get_cntl_addnl_attribs *req; | ||
1224 | int status; | ||
1225 | |||
1226 | spin_lock_bh(&adapter->mcc_lock); | ||
1227 | |||
1228 | wrb = wrb_from_mccq(adapter); | ||
1229 | if (!wrb) { | ||
1230 | status = -EBUSY; | ||
1231 | goto err; | ||
1232 | } | ||
1233 | req = embedded_payload(wrb); | ||
1234 | |||
1235 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
1236 | OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES); | ||
1237 | |||
1238 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1239 | OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req)); | ||
1240 | |||
1241 | status = be_mcc_notify_wait(adapter); | ||
1242 | if (!status) { | ||
1243 | struct be_cmd_resp_get_cntl_addnl_attribs *resp = | ||
1244 | embedded_payload(wrb); | ||
1245 | adapter->drv_stats.be_on_die_temperature = | ||
1246 | resp->on_die_temperature; | ||
1247 | } | ||
1248 | /* If IOCTL fails once, do not bother issuing it again */ | ||
1249 | else | ||
1250 | be_get_temp_freq = 0; | ||
1251 | |||
1252 | err: | ||
1253 | spin_unlock_bh(&adapter->mcc_lock); | ||
1254 | return status; | ||
1255 | } | ||
1256 | |||
1257 | /* Uses synchronous mcc */ | ||
1258 | int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size) | ||
1259 | { | ||
1260 | struct be_mcc_wrb *wrb; | ||
1261 | struct be_cmd_req_get_fat *req; | ||
1262 | int status; | ||
1263 | |||
1264 | spin_lock_bh(&adapter->mcc_lock); | ||
1265 | |||
1266 | wrb = wrb_from_mccq(adapter); | ||
1267 | if (!wrb) { | ||
1268 | status = -EBUSY; | ||
1269 | goto err; | ||
1270 | } | ||
1271 | req = embedded_payload(wrb); | ||
1272 | |||
1273 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
1274 | OPCODE_COMMON_MANAGE_FAT); | ||
1275 | |||
1276 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1277 | OPCODE_COMMON_MANAGE_FAT, sizeof(*req)); | ||
1278 | req->fat_operation = cpu_to_le32(QUERY_FAT); | ||
1279 | status = be_mcc_notify_wait(adapter); | ||
1280 | if (!status) { | ||
1281 | struct be_cmd_resp_get_fat *resp = embedded_payload(wrb); | ||
1282 | if (log_size && resp->log_size) | ||
1283 | *log_size = le32_to_cpu(resp->log_size) - | ||
1284 | sizeof(u32); | ||
1285 | } | ||
1286 | err: | ||
1287 | spin_unlock_bh(&adapter->mcc_lock); | ||
1288 | return status; | ||
1289 | } | ||
1290 | |||
1291 | void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | ||
1292 | { | ||
1293 | struct be_dma_mem get_fat_cmd; | ||
1294 | struct be_mcc_wrb *wrb; | ||
1295 | struct be_cmd_req_get_fat *req; | ||
1296 | struct be_sge *sge; | ||
1297 | u32 offset = 0, total_size, buf_size, | ||
1298 | log_offset = sizeof(u32), payload_len; | ||
1299 | int status; | ||
1300 | |||
1301 | if (buf_len == 0) | ||
1302 | return; | ||
1303 | |||
1304 | total_size = buf_len; | ||
1305 | |||
1306 | get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024; | ||
1307 | get_fat_cmd.va = pci_alloc_consistent(adapter->pdev, | ||
1308 | get_fat_cmd.size, | ||
1309 | &get_fat_cmd.dma); | ||
1310 | if (!get_fat_cmd.va) { | ||
1311 | status = -ENOMEM; | ||
1312 | dev_err(&adapter->pdev->dev, | ||
1313 | "Memory allocation failure while retrieving FAT data\n"); | ||
1314 | return; | ||
1315 | } | ||
1316 | |||
1317 | spin_lock_bh(&adapter->mcc_lock); | ||
1318 | |||
1319 | while (total_size) { | ||
1320 | buf_size = min(total_size, (u32)60*1024); | ||
1321 | total_size -= buf_size; | ||
1322 | |||
1323 | wrb = wrb_from_mccq(adapter); | ||
1324 | if (!wrb) { | ||
1325 | status = -EBUSY; | ||
1326 | goto err; | ||
1327 | } | ||
1328 | req = get_fat_cmd.va; | ||
1329 | sge = nonembedded_sgl(wrb); | ||
1330 | |||
1331 | payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size; | ||
1332 | be_wrb_hdr_prepare(wrb, payload_len, false, 1, | ||
1333 | OPCODE_COMMON_MANAGE_FAT); | ||
1334 | |||
1335 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1336 | OPCODE_COMMON_MANAGE_FAT, payload_len); | ||
1337 | |||
1338 | sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.dma)); | ||
1339 | sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF); | ||
1340 | sge->len = cpu_to_le32(get_fat_cmd.size); | ||
1341 | |||
1342 | req->fat_operation = cpu_to_le32(RETRIEVE_FAT); | ||
1343 | req->read_log_offset = cpu_to_le32(log_offset); | ||
1344 | req->read_log_length = cpu_to_le32(buf_size); | ||
1345 | req->data_buffer_size = cpu_to_le32(buf_size); | ||
1346 | |||
1347 | status = be_mcc_notify_wait(adapter); | ||
1348 | if (!status) { | ||
1349 | struct be_cmd_resp_get_fat *resp = get_fat_cmd.va; | ||
1350 | memcpy(buf + offset, | ||
1351 | resp->data_buffer, | ||
1352 | resp->read_log_length); | ||
1353 | } else { | ||
1354 | dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n"); | ||
1355 | goto err; | ||
1356 | } | ||
1357 | offset += buf_size; | ||
1358 | log_offset += buf_size; | ||
1359 | } | ||
1360 | err: | ||
1361 | pci_free_consistent(adapter->pdev, get_fat_cmd.size, | ||
1362 | get_fat_cmd.va, | ||
1363 | get_fat_cmd.dma); | ||
1364 | spin_unlock_bh(&adapter->mcc_lock); | ||
1365 | } | ||
1366 | |||
1000 | /* Uses Mbox */ | 1367 | /* Uses Mbox */ |
1001 | int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) | 1368 | int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) |
1002 | { | 1369 | { |
@@ -1004,7 +1371,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) | |||
1004 | struct be_cmd_req_get_fw_version *req; | 1371 | struct be_cmd_req_get_fw_version *req; |
1005 | int status; | 1372 | int status; |
1006 | 1373 | ||
1007 | spin_lock(&adapter->mbox_lock); | 1374 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1375 | return -1; | ||
1008 | 1376 | ||
1009 | wrb = wrb_from_mbox(adapter); | 1377 | wrb = wrb_from_mbox(adapter); |
1010 | req = embedded_payload(wrb); | 1378 | req = embedded_payload(wrb); |
@@ -1021,7 +1389,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) | |||
1021 | strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); | 1389 | strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); |
1022 | } | 1390 | } |
1023 | 1391 | ||
1024 | spin_unlock(&adapter->mbox_lock); | 1392 | mutex_unlock(&adapter->mbox_lock); |
1025 | return status; | 1393 | return status; |
1026 | } | 1394 | } |
1027 | 1395 | ||
@@ -1103,12 +1471,24 @@ err: | |||
1103 | /* Uses MCC for this command as it may be called in BH context | 1471 | /* Uses MCC for this command as it may be called in BH context |
1104 | * Uses synchronous mcc | 1472 | * Uses synchronous mcc |
1105 | */ | 1473 | */ |
1106 | int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) | 1474 | int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en) |
1107 | { | 1475 | { |
1108 | struct be_mcc_wrb *wrb; | 1476 | struct be_mcc_wrb *wrb; |
1109 | struct be_cmd_req_promiscuous_config *req; | 1477 | struct be_cmd_req_rx_filter *req; |
1478 | struct be_dma_mem promiscous_cmd; | ||
1479 | struct be_sge *sge; | ||
1110 | int status; | 1480 | int status; |
1111 | 1481 | ||
1482 | memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem)); | ||
1483 | promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter); | ||
1484 | promiscous_cmd.va = pci_alloc_consistent(adapter->pdev, | ||
1485 | promiscous_cmd.size, &promiscous_cmd.dma); | ||
1486 | if (!promiscous_cmd.va) { | ||
1487 | dev_err(&adapter->pdev->dev, | ||
1488 | "Memory allocation failure\n"); | ||
1489 | return -ENOMEM; | ||
1490 | } | ||
1491 | |||
1112 | spin_lock_bh(&adapter->mcc_lock); | 1492 | spin_lock_bh(&adapter->mcc_lock); |
1113 | 1493 | ||
1114 | wrb = wrb_from_mccq(adapter); | 1494 | wrb = wrb_from_mccq(adapter); |
@@ -1116,32 +1496,36 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) | |||
1116 | status = -EBUSY; | 1496 | status = -EBUSY; |
1117 | goto err; | 1497 | goto err; |
1118 | } | 1498 | } |
1119 | req = embedded_payload(wrb); | ||
1120 | 1499 | ||
1121 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_PROMISCUOUS); | 1500 | req = promiscous_cmd.va; |
1501 | sge = nonembedded_sgl(wrb); | ||
1122 | 1502 | ||
1123 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, | 1503 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, |
1124 | OPCODE_ETH_PROMISCUOUS, sizeof(*req)); | 1504 | OPCODE_COMMON_NTWK_RX_FILTER); |
1125 | 1505 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | |
1126 | /* In FW versions X.102.149/X.101.487 and later, | 1506 | OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req)); |
1127 | * the port setting associated only with the | 1507 | |
1128 | * issuing pci function will take effect | 1508 | req->if_id = cpu_to_le32(adapter->if_handle); |
1129 | */ | 1509 | req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS); |
1130 | if (port_num) | 1510 | if (en) |
1131 | req->port1_promiscuous = en; | 1511 | req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS); |
1132 | else | 1512 | |
1133 | req->port0_promiscuous = en; | 1513 | sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma)); |
1514 | sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF); | ||
1515 | sge->len = cpu_to_le32(promiscous_cmd.size); | ||
1134 | 1516 | ||
1135 | status = be_mcc_notify_wait(adapter); | 1517 | status = be_mcc_notify_wait(adapter); |
1136 | 1518 | ||
1137 | err: | 1519 | err: |
1138 | spin_unlock_bh(&adapter->mcc_lock); | 1520 | spin_unlock_bh(&adapter->mcc_lock); |
1521 | pci_free_consistent(adapter->pdev, promiscous_cmd.size, | ||
1522 | promiscous_cmd.va, promiscous_cmd.dma); | ||
1139 | return status; | 1523 | return status; |
1140 | } | 1524 | } |
1141 | 1525 | ||
1142 | /* | 1526 | /* |
1143 | * Uses MCC for this command as it may be called in BH context | 1527 | * Uses MCC for this command as it may be called in BH context |
1144 | * (mc == NULL) => multicast promiscous | 1528 | * (mc == NULL) => multicast promiscuous |
1145 | */ | 1529 | */ |
1146 | int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | 1530 | int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, |
1147 | struct net_device *netdev, struct be_dma_mem *mem) | 1531 | struct net_device *netdev, struct be_dma_mem *mem) |
@@ -1179,7 +1563,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1179 | 1563 | ||
1180 | i = 0; | 1564 | i = 0; |
1181 | netdev_for_each_mc_addr(ha, netdev) | 1565 | netdev_for_each_mc_addr(ha, netdev) |
1182 | memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); | 1566 | memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN); |
1183 | } else { | 1567 | } else { |
1184 | req->promiscuous = 1; | 1568 | req->promiscuous = 1; |
1185 | } | 1569 | } |
@@ -1259,13 +1643,15 @@ err: | |||
1259 | } | 1643 | } |
1260 | 1644 | ||
1261 | /* Uses mbox */ | 1645 | /* Uses mbox */ |
1262 | int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) | 1646 | int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, |
1647 | u32 *mode, u32 *caps) | ||
1263 | { | 1648 | { |
1264 | struct be_mcc_wrb *wrb; | 1649 | struct be_mcc_wrb *wrb; |
1265 | struct be_cmd_req_query_fw_cfg *req; | 1650 | struct be_cmd_req_query_fw_cfg *req; |
1266 | int status; | 1651 | int status; |
1267 | 1652 | ||
1268 | spin_lock(&adapter->mbox_lock); | 1653 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1654 | return -1; | ||
1269 | 1655 | ||
1270 | wrb = wrb_from_mbox(adapter); | 1656 | wrb = wrb_from_mbox(adapter); |
1271 | req = embedded_payload(wrb); | 1657 | req = embedded_payload(wrb); |
@@ -1281,9 +1667,10 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) | |||
1281 | struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); | 1667 | struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); |
1282 | *port_num = le32_to_cpu(resp->phys_port); | 1668 | *port_num = le32_to_cpu(resp->phys_port); |
1283 | *mode = le32_to_cpu(resp->function_mode); | 1669 | *mode = le32_to_cpu(resp->function_mode); |
1670 | *caps = le32_to_cpu(resp->function_caps); | ||
1284 | } | 1671 | } |
1285 | 1672 | ||
1286 | spin_unlock(&adapter->mbox_lock); | 1673 | mutex_unlock(&adapter->mbox_lock); |
1287 | return status; | 1674 | return status; |
1288 | } | 1675 | } |
1289 | 1676 | ||
@@ -1294,7 +1681,8 @@ int be_cmd_reset_function(struct be_adapter *adapter) | |||
1294 | struct be_cmd_req_hdr *req; | 1681 | struct be_cmd_req_hdr *req; |
1295 | int status; | 1682 | int status; |
1296 | 1683 | ||
1297 | spin_lock(&adapter->mbox_lock); | 1684 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1685 | return -1; | ||
1298 | 1686 | ||
1299 | wrb = wrb_from_mbox(adapter); | 1687 | wrb = wrb_from_mbox(adapter); |
1300 | req = embedded_payload(wrb); | 1688 | req = embedded_payload(wrb); |
@@ -1307,7 +1695,40 @@ int be_cmd_reset_function(struct be_adapter *adapter) | |||
1307 | 1695 | ||
1308 | status = be_mbox_notify_wait(adapter); | 1696 | status = be_mbox_notify_wait(adapter); |
1309 | 1697 | ||
1310 | spin_unlock(&adapter->mbox_lock); | 1698 | mutex_unlock(&adapter->mbox_lock); |
1699 | return status; | ||
1700 | } | ||
1701 | |||
1702 | int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) | ||
1703 | { | ||
1704 | struct be_mcc_wrb *wrb; | ||
1705 | struct be_cmd_req_rss_config *req; | ||
1706 | u32 myhash[10] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF, | ||
1707 | 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF}; | ||
1708 | int status; | ||
1709 | |||
1710 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
1711 | return -1; | ||
1712 | |||
1713 | wrb = wrb_from_mbox(adapter); | ||
1714 | req = embedded_payload(wrb); | ||
1715 | |||
1716 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
1717 | OPCODE_ETH_RSS_CONFIG); | ||
1718 | |||
1719 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, | ||
1720 | OPCODE_ETH_RSS_CONFIG, sizeof(*req)); | ||
1721 | |||
1722 | req->if_id = cpu_to_le32(adapter->if_handle); | ||
1723 | req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4); | ||
1724 | req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1); | ||
1725 | memcpy(req->cpu_table, rsstable, table_size); | ||
1726 | memcpy(req->hash, myhash, sizeof(myhash)); | ||
1727 | be_dws_cpu_to_le(req->hash, sizeof(req->hash)); | ||
1728 | |||
1729 | status = be_mbox_notify_wait(adapter); | ||
1730 | |||
1731 | mutex_unlock(&adapter->mbox_lock); | ||
1311 | return status; | 1732 | return status; |
1312 | } | 1733 | } |
1313 | 1734 | ||
@@ -1382,38 +1803,77 @@ err: | |||
1382 | return status; | 1803 | return status; |
1383 | } | 1804 | } |
1384 | 1805 | ||
1385 | /* Uses sync mcc */ | 1806 | int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, |
1386 | int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, | 1807 | u32 data_size, u32 data_offset, const char *obj_name, |
1387 | u8 *connector) | 1808 | u32 *data_written, u8 *addn_status) |
1388 | { | 1809 | { |
1389 | struct be_mcc_wrb *wrb; | 1810 | struct be_mcc_wrb *wrb; |
1390 | struct be_cmd_req_port_type *req; | 1811 | struct lancer_cmd_req_write_object *req; |
1812 | struct lancer_cmd_resp_write_object *resp; | ||
1813 | void *ctxt = NULL; | ||
1391 | int status; | 1814 | int status; |
1392 | 1815 | ||
1393 | spin_lock_bh(&adapter->mcc_lock); | 1816 | spin_lock_bh(&adapter->mcc_lock); |
1817 | adapter->flash_status = 0; | ||
1394 | 1818 | ||
1395 | wrb = wrb_from_mccq(adapter); | 1819 | wrb = wrb_from_mccq(adapter); |
1396 | if (!wrb) { | 1820 | if (!wrb) { |
1397 | status = -EBUSY; | 1821 | status = -EBUSY; |
1398 | goto err; | 1822 | goto err_unlock; |
1399 | } | 1823 | } |
1824 | |||
1400 | req = embedded_payload(wrb); | 1825 | req = embedded_payload(wrb); |
1401 | 1826 | ||
1402 | be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0, | 1827 | be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object), |
1403 | OPCODE_COMMON_READ_TRANSRECV_DATA); | 1828 | true, 1, OPCODE_COMMON_WRITE_OBJECT); |
1829 | wrb->tag1 = CMD_SUBSYSTEM_COMMON; | ||
1404 | 1830 | ||
1405 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1831 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
1406 | OPCODE_COMMON_READ_TRANSRECV_DATA, sizeof(*req)); | 1832 | OPCODE_COMMON_WRITE_OBJECT, |
1833 | sizeof(struct lancer_cmd_req_write_object)); | ||
1407 | 1834 | ||
1408 | req->port = cpu_to_le32(port); | 1835 | ctxt = &req->context; |
1409 | req->page_num = cpu_to_le32(TR_PAGE_A0); | 1836 | AMAP_SET_BITS(struct amap_lancer_write_obj_context, |
1410 | status = be_mcc_notify_wait(adapter); | 1837 | write_length, ctxt, data_size); |
1838 | |||
1839 | if (data_size == 0) | ||
1840 | AMAP_SET_BITS(struct amap_lancer_write_obj_context, | ||
1841 | eof, ctxt, 1); | ||
1842 | else | ||
1843 | AMAP_SET_BITS(struct amap_lancer_write_obj_context, | ||
1844 | eof, ctxt, 0); | ||
1845 | |||
1846 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); | ||
1847 | req->write_offset = cpu_to_le32(data_offset); | ||
1848 | strcpy(req->object_name, obj_name); | ||
1849 | req->descriptor_count = cpu_to_le32(1); | ||
1850 | req->buf_len = cpu_to_le32(data_size); | ||
1851 | req->addr_low = cpu_to_le32((cmd->dma + | ||
1852 | sizeof(struct lancer_cmd_req_write_object)) | ||
1853 | & 0xFFFFFFFF); | ||
1854 | req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma + | ||
1855 | sizeof(struct lancer_cmd_req_write_object))); | ||
1856 | |||
1857 | be_mcc_notify(adapter); | ||
1858 | spin_unlock_bh(&adapter->mcc_lock); | ||
1859 | |||
1860 | if (!wait_for_completion_timeout(&adapter->flash_compl, | ||
1861 | msecs_to_jiffies(12000))) | ||
1862 | status = -1; | ||
1863 | else | ||
1864 | status = adapter->flash_status; | ||
1865 | |||
1866 | resp = embedded_payload(wrb); | ||
1411 | if (!status) { | 1867 | if (!status) { |
1412 | struct be_cmd_resp_port_type *resp = embedded_payload(wrb); | 1868 | *data_written = le32_to_cpu(resp->actual_write_len); |
1413 | *connector = resp->data.connector; | 1869 | } else { |
1870 | *addn_status = resp->additional_status; | ||
1871 | status = resp->status; | ||
1414 | } | 1872 | } |
1415 | 1873 | ||
1416 | err: | 1874 | return status; |
1875 | |||
1876 | err_unlock: | ||
1417 | spin_unlock_bh(&adapter->mcc_lock); | 1877 | spin_unlock_bh(&adapter->mcc_lock); |
1418 | return status; | 1878 | return status; |
1419 | } | 1879 | } |
@@ -1679,6 +2139,10 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
1679 | spin_lock_bh(&adapter->mcc_lock); | 2139 | spin_lock_bh(&adapter->mcc_lock); |
1680 | 2140 | ||
1681 | wrb = wrb_from_mccq(adapter); | 2141 | wrb = wrb_from_mccq(adapter); |
2142 | if (!wrb) { | ||
2143 | status = -EBUSY; | ||
2144 | goto err; | ||
2145 | } | ||
1682 | req = nonemb_cmd->va; | 2146 | req = nonemb_cmd->va; |
1683 | sge = nonembedded_sgl(wrb); | 2147 | sge = nonembedded_sgl(wrb); |
1684 | 2148 | ||
@@ -1694,6 +2158,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
1694 | 2158 | ||
1695 | status = be_mcc_notify_wait(adapter); | 2159 | status = be_mcc_notify_wait(adapter); |
1696 | 2160 | ||
2161 | err: | ||
1697 | spin_unlock_bh(&adapter->mcc_lock); | 2162 | spin_unlock_bh(&adapter->mcc_lock); |
1698 | return status; | 2163 | return status; |
1699 | } | 2164 | } |
@@ -1756,8 +2221,8 @@ int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) | |||
1756 | OPCODE_COMMON_SET_QOS, sizeof(*req)); | 2221 | OPCODE_COMMON_SET_QOS, sizeof(*req)); |
1757 | 2222 | ||
1758 | req->hdr.domain = domain; | 2223 | req->hdr.domain = domain; |
1759 | req->valid_bits = BE_QOS_BITS_NIC; | 2224 | req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC); |
1760 | req->max_bps_nic = bps; | 2225 | req->max_bps_nic = cpu_to_le32(bps); |
1761 | 2226 | ||
1762 | status = be_mcc_notify_wait(adapter); | 2227 | status = be_mcc_notify_wait(adapter); |
1763 | 2228 | ||
@@ -1765,3 +2230,96 @@ err: | |||
1765 | spin_unlock_bh(&adapter->mcc_lock); | 2230 | spin_unlock_bh(&adapter->mcc_lock); |
1766 | return status; | 2231 | return status; |
1767 | } | 2232 | } |
2233 | |||
2234 | int be_cmd_get_cntl_attributes(struct be_adapter *adapter) | ||
2235 | { | ||
2236 | struct be_mcc_wrb *wrb; | ||
2237 | struct be_cmd_req_cntl_attribs *req; | ||
2238 | struct be_cmd_resp_cntl_attribs *resp; | ||
2239 | struct be_sge *sge; | ||
2240 | int status; | ||
2241 | int payload_len = max(sizeof(*req), sizeof(*resp)); | ||
2242 | struct mgmt_controller_attrib *attribs; | ||
2243 | struct be_dma_mem attribs_cmd; | ||
2244 | |||
2245 | memset(&attribs_cmd, 0, sizeof(struct be_dma_mem)); | ||
2246 | attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs); | ||
2247 | attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size, | ||
2248 | &attribs_cmd.dma); | ||
2249 | if (!attribs_cmd.va) { | ||
2250 | dev_err(&adapter->pdev->dev, | ||
2251 | "Memory allocation failure\n"); | ||
2252 | return -ENOMEM; | ||
2253 | } | ||
2254 | |||
2255 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
2256 | return -1; | ||
2257 | |||
2258 | wrb = wrb_from_mbox(adapter); | ||
2259 | if (!wrb) { | ||
2260 | status = -EBUSY; | ||
2261 | goto err; | ||
2262 | } | ||
2263 | req = attribs_cmd.va; | ||
2264 | sge = nonembedded_sgl(wrb); | ||
2265 | |||
2266 | be_wrb_hdr_prepare(wrb, payload_len, false, 1, | ||
2267 | OPCODE_COMMON_GET_CNTL_ATTRIBUTES); | ||
2268 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2269 | OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len); | ||
2270 | sge->pa_hi = cpu_to_le32(upper_32_bits(attribs_cmd.dma)); | ||
2271 | sge->pa_lo = cpu_to_le32(attribs_cmd.dma & 0xFFFFFFFF); | ||
2272 | sge->len = cpu_to_le32(attribs_cmd.size); | ||
2273 | |||
2274 | status = be_mbox_notify_wait(adapter); | ||
2275 | if (!status) { | ||
2276 | attribs = (struct mgmt_controller_attrib *)( attribs_cmd.va + | ||
2277 | sizeof(struct be_cmd_resp_hdr)); | ||
2278 | adapter->hba_port_num = attribs->hba_attribs.phy_port; | ||
2279 | } | ||
2280 | |||
2281 | err: | ||
2282 | mutex_unlock(&adapter->mbox_lock); | ||
2283 | pci_free_consistent(adapter->pdev, attribs_cmd.size, attribs_cmd.va, | ||
2284 | attribs_cmd.dma); | ||
2285 | return status; | ||
2286 | } | ||
2287 | |||
2288 | /* Uses mbox */ | ||
2289 | int be_cmd_check_native_mode(struct be_adapter *adapter) | ||
2290 | { | ||
2291 | struct be_mcc_wrb *wrb; | ||
2292 | struct be_cmd_req_set_func_cap *req; | ||
2293 | int status; | ||
2294 | |||
2295 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
2296 | return -1; | ||
2297 | |||
2298 | wrb = wrb_from_mbox(adapter); | ||
2299 | if (!wrb) { | ||
2300 | status = -EBUSY; | ||
2301 | goto err; | ||
2302 | } | ||
2303 | |||
2304 | req = embedded_payload(wrb); | ||
2305 | |||
2306 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
2307 | OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP); | ||
2308 | |||
2309 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2310 | OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP, sizeof(*req)); | ||
2311 | |||
2312 | req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS | | ||
2313 | CAPABILITY_BE3_NATIVE_ERX_API); | ||
2314 | req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API); | ||
2315 | |||
2316 | status = be_mbox_notify_wait(adapter); | ||
2317 | if (!status) { | ||
2318 | struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb); | ||
2319 | adapter->be3_native = le32_to_cpu(resp->cap_flags) & | ||
2320 | CAPABILITY_BE3_NATIVE_ERX_API; | ||
2321 | } | ||
2322 | err: | ||
2323 | mutex_unlock(&adapter->mbox_lock); | ||
2324 | return status; | ||
2325 | } | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index ad1e6fac60c5..8148cc66cbe9 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,11 +8,11 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | /* | 18 | /* |
@@ -82,7 +82,13 @@ struct be_mcc_compl { | |||
82 | */ | 82 | */ |
83 | #define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */ | 83 | #define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */ |
84 | #define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF | 84 | #define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF |
85 | #define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16 | ||
86 | #define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF | ||
85 | #define ASYNC_EVENT_CODE_LINK_STATE 0x1 | 87 | #define ASYNC_EVENT_CODE_LINK_STATE 0x1 |
88 | #define ASYNC_EVENT_CODE_GRP_5 0x5 | ||
89 | #define ASYNC_EVENT_QOS_SPEED 0x1 | ||
90 | #define ASYNC_EVENT_COS_PRIORITY 0x2 | ||
91 | #define ASYNC_EVENT_PVID_STATE 0x3 | ||
86 | struct be_async_event_trailer { | 92 | struct be_async_event_trailer { |
87 | u32 code; | 93 | u32 code; |
88 | }; | 94 | }; |
@@ -105,6 +111,42 @@ struct be_async_event_link_state { | |||
105 | struct be_async_event_trailer trailer; | 111 | struct be_async_event_trailer trailer; |
106 | } __packed; | 112 | } __packed; |
107 | 113 | ||
114 | /* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED | ||
115 | * the mcc_compl must be interpreted as follows | ||
116 | */ | ||
117 | struct be_async_event_grp5_qos_link_speed { | ||
118 | u8 physical_port; | ||
119 | u8 rsvd[5]; | ||
120 | u16 qos_link_speed; | ||
121 | u32 event_tag; | ||
122 | struct be_async_event_trailer trailer; | ||
123 | } __packed; | ||
124 | |||
125 | /* When the event code of an async trailer is GRP5 and event type is | ||
126 | * CoS-Priority, the mcc_compl must be interpreted as follows | ||
127 | */ | ||
128 | struct be_async_event_grp5_cos_priority { | ||
129 | u8 physical_port; | ||
130 | u8 available_priority_bmap; | ||
131 | u8 reco_default_priority; | ||
132 | u8 valid; | ||
133 | u8 rsvd0; | ||
134 | u8 event_tag; | ||
135 | struct be_async_event_trailer trailer; | ||
136 | } __packed; | ||
137 | |||
138 | /* When the event code of an async trailer is GRP5 and event type is | ||
139 | * PVID state, the mcc_compl must be interpreted as follows | ||
140 | */ | ||
141 | struct be_async_event_grp5_pvid_state { | ||
142 | u8 enabled; | ||
143 | u8 rsvd0; | ||
144 | u16 tag; | ||
145 | u32 event_tag; | ||
146 | u32 rsvd1; | ||
147 | struct be_async_event_trailer trailer; | ||
148 | } __packed; | ||
149 | |||
108 | struct be_mcc_mailbox { | 150 | struct be_mcc_mailbox { |
109 | struct be_mcc_wrb wrb; | 151 | struct be_mcc_wrb wrb; |
110 | struct be_mcc_compl compl; | 152 | struct be_mcc_compl compl; |
@@ -123,9 +165,11 @@ struct be_mcc_mailbox { | |||
123 | #define OPCODE_COMMON_WRITE_FLASHROM 7 | 165 | #define OPCODE_COMMON_WRITE_FLASHROM 7 |
124 | #define OPCODE_COMMON_CQ_CREATE 12 | 166 | #define OPCODE_COMMON_CQ_CREATE 12 |
125 | #define OPCODE_COMMON_EQ_CREATE 13 | 167 | #define OPCODE_COMMON_EQ_CREATE 13 |
126 | #define OPCODE_COMMON_MCC_CREATE 21 | 168 | #define OPCODE_COMMON_MCC_CREATE 21 |
127 | #define OPCODE_COMMON_SET_QOS 28 | 169 | #define OPCODE_COMMON_SET_QOS 28 |
170 | #define OPCODE_COMMON_MCC_CREATE_EXT 90 | ||
128 | #define OPCODE_COMMON_SEEPROM_READ 30 | 171 | #define OPCODE_COMMON_SEEPROM_READ 30 |
172 | #define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 | ||
129 | #define OPCODE_COMMON_NTWK_RX_FILTER 34 | 173 | #define OPCODE_COMMON_NTWK_RX_FILTER 34 |
130 | #define OPCODE_COMMON_GET_FW_VERSION 35 | 174 | #define OPCODE_COMMON_GET_FW_VERSION 35 |
131 | #define OPCODE_COMMON_SET_FLOW_CONTROL 36 | 175 | #define OPCODE_COMMON_SET_FLOW_CONTROL 36 |
@@ -142,11 +186,16 @@ struct be_mcc_mailbox { | |||
142 | #define OPCODE_COMMON_NTWK_PMAC_ADD 59 | 186 | #define OPCODE_COMMON_NTWK_PMAC_ADD 59 |
143 | #define OPCODE_COMMON_NTWK_PMAC_DEL 60 | 187 | #define OPCODE_COMMON_NTWK_PMAC_DEL 60 |
144 | #define OPCODE_COMMON_FUNCTION_RESET 61 | 188 | #define OPCODE_COMMON_FUNCTION_RESET 61 |
189 | #define OPCODE_COMMON_MANAGE_FAT 68 | ||
145 | #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 | 190 | #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 |
146 | #define OPCODE_COMMON_GET_BEACON_STATE 70 | 191 | #define OPCODE_COMMON_GET_BEACON_STATE 70 |
147 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 | 192 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 |
148 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 | 193 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 |
194 | #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 | ||
195 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 | ||
196 | #define OPCODE_COMMON_WRITE_OBJECT 172 | ||
149 | 197 | ||
198 | #define OPCODE_ETH_RSS_CONFIG 1 | ||
150 | #define OPCODE_ETH_ACPI_CONFIG 2 | 199 | #define OPCODE_ETH_ACPI_CONFIG 2 |
151 | #define OPCODE_ETH_PROMISCUOUS 3 | 200 | #define OPCODE_ETH_PROMISCUOUS 3 |
152 | #define OPCODE_ETH_GET_STATISTICS 4 | 201 | #define OPCODE_ETH_GET_STATISTICS 4 |
@@ -155,6 +204,7 @@ struct be_mcc_mailbox { | |||
155 | #define OPCODE_ETH_TX_DESTROY 9 | 204 | #define OPCODE_ETH_TX_DESTROY 9 |
156 | #define OPCODE_ETH_RX_DESTROY 10 | 205 | #define OPCODE_ETH_RX_DESTROY 10 |
157 | #define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12 | 206 | #define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12 |
207 | #define OPCODE_ETH_GET_PPORT_STATS 18 | ||
158 | 208 | ||
159 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 | 209 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 |
160 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 | 210 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 |
@@ -278,7 +328,7 @@ struct be_cmd_req_pmac_del { | |||
278 | /******************** Create CQ ***************************/ | 328 | /******************** Create CQ ***************************/ |
279 | /* Pseudo amap definition in which each bit of the actual structure is defined | 329 | /* Pseudo amap definition in which each bit of the actual structure is defined |
280 | * as a byte: used to calculate offset/shift/mask of each field */ | 330 | * as a byte: used to calculate offset/shift/mask of each field */ |
281 | struct amap_cq_context { | 331 | struct amap_cq_context_be { |
282 | u8 cidx[11]; /* dword 0*/ | 332 | u8 cidx[11]; /* dword 0*/ |
283 | u8 rsvd0; /* dword 0*/ | 333 | u8 rsvd0; /* dword 0*/ |
284 | u8 coalescwm[2]; /* dword 0*/ | 334 | u8 coalescwm[2]; /* dword 0*/ |
@@ -301,24 +351,60 @@ struct amap_cq_context { | |||
301 | u8 rsvd5[32]; /* dword 3*/ | 351 | u8 rsvd5[32]; /* dword 3*/ |
302 | } __packed; | 352 | } __packed; |
303 | 353 | ||
354 | struct amap_cq_context_lancer { | ||
355 | u8 rsvd0[12]; /* dword 0*/ | ||
356 | u8 coalescwm[2]; /* dword 0*/ | ||
357 | u8 nodelay; /* dword 0*/ | ||
358 | u8 rsvd1[12]; /* dword 0*/ | ||
359 | u8 count[2]; /* dword 0*/ | ||
360 | u8 valid; /* dword 0*/ | ||
361 | u8 rsvd2; /* dword 0*/ | ||
362 | u8 eventable; /* dword 0*/ | ||
363 | u8 eqid[16]; /* dword 1*/ | ||
364 | u8 rsvd3[15]; /* dword 1*/ | ||
365 | u8 armed; /* dword 1*/ | ||
366 | u8 rsvd4[32]; /* dword 2*/ | ||
367 | u8 rsvd5[32]; /* dword 3*/ | ||
368 | } __packed; | ||
369 | |||
304 | struct be_cmd_req_cq_create { | 370 | struct be_cmd_req_cq_create { |
305 | struct be_cmd_req_hdr hdr; | 371 | struct be_cmd_req_hdr hdr; |
306 | u16 num_pages; | 372 | u16 num_pages; |
307 | u16 rsvd0; | 373 | u8 page_size; |
308 | u8 context[sizeof(struct amap_cq_context) / 8]; | 374 | u8 rsvd0; |
375 | u8 context[sizeof(struct amap_cq_context_be) / 8]; | ||
309 | struct phys_addr pages[8]; | 376 | struct phys_addr pages[8]; |
310 | } __packed; | 377 | } __packed; |
311 | 378 | ||
379 | |||
312 | struct be_cmd_resp_cq_create { | 380 | struct be_cmd_resp_cq_create { |
313 | struct be_cmd_resp_hdr hdr; | 381 | struct be_cmd_resp_hdr hdr; |
314 | u16 cq_id; | 382 | u16 cq_id; |
315 | u16 rsvd0; | 383 | u16 rsvd0; |
316 | } __packed; | 384 | } __packed; |
317 | 385 | ||
386 | struct be_cmd_req_get_fat { | ||
387 | struct be_cmd_req_hdr hdr; | ||
388 | u32 fat_operation; | ||
389 | u32 read_log_offset; | ||
390 | u32 read_log_length; | ||
391 | u32 data_buffer_size; | ||
392 | u32 data_buffer[1]; | ||
393 | } __packed; | ||
394 | |||
395 | struct be_cmd_resp_get_fat { | ||
396 | struct be_cmd_resp_hdr hdr; | ||
397 | u32 log_size; | ||
398 | u32 read_log_length; | ||
399 | u32 rsvd[2]; | ||
400 | u32 data_buffer[1]; | ||
401 | } __packed; | ||
402 | |||
403 | |||
318 | /******************** Create MCCQ ***************************/ | 404 | /******************** Create MCCQ ***************************/ |
319 | /* Pseudo amap definition in which each bit of the actual structure is defined | 405 | /* Pseudo amap definition in which each bit of the actual structure is defined |
320 | * as a byte: used to calculate offset/shift/mask of each field */ | 406 | * as a byte: used to calculate offset/shift/mask of each field */ |
321 | struct amap_mcc_context { | 407 | struct amap_mcc_context_be { |
322 | u8 con_index[14]; | 408 | u8 con_index[14]; |
323 | u8 rsvd0[2]; | 409 | u8 rsvd0[2]; |
324 | u8 ring_size[4]; | 410 | u8 ring_size[4]; |
@@ -333,11 +419,23 @@ struct amap_mcc_context { | |||
333 | u8 rsvd2[32]; | 419 | u8 rsvd2[32]; |
334 | } __packed; | 420 | } __packed; |
335 | 421 | ||
422 | struct amap_mcc_context_lancer { | ||
423 | u8 async_cq_id[16]; | ||
424 | u8 ring_size[4]; | ||
425 | u8 rsvd0[12]; | ||
426 | u8 rsvd1[31]; | ||
427 | u8 valid; | ||
428 | u8 async_cq_valid[1]; | ||
429 | u8 rsvd2[31]; | ||
430 | u8 rsvd3[32]; | ||
431 | } __packed; | ||
432 | |||
336 | struct be_cmd_req_mcc_create { | 433 | struct be_cmd_req_mcc_create { |
337 | struct be_cmd_req_hdr hdr; | 434 | struct be_cmd_req_hdr hdr; |
338 | u16 num_pages; | 435 | u16 num_pages; |
339 | u16 rsvd0; | 436 | u16 cq_id; |
340 | u8 context[sizeof(struct amap_mcc_context) / 8]; | 437 | u32 async_event_bitmap[1]; |
438 | u8 context[sizeof(struct amap_mcc_context_be) / 8]; | ||
341 | struct phys_addr pages[8]; | 439 | struct phys_addr pages[8]; |
342 | } __packed; | 440 | } __packed; |
343 | 441 | ||
@@ -354,7 +452,7 @@ struct be_cmd_resp_mcc_create { | |||
354 | /* Pseudo amap definition in which each bit of the actual structure is defined | 452 | /* Pseudo amap definition in which each bit of the actual structure is defined |
355 | * as a byte: used to calculate offset/shift/mask of each field */ | 453 | * as a byte: used to calculate offset/shift/mask of each field */ |
356 | struct amap_tx_context { | 454 | struct amap_tx_context { |
357 | u8 rsvd0[16]; /* dword 0 */ | 455 | u8 if_id[16]; /* dword 0 */ |
358 | u8 tx_ring_size[4]; /* dword 0 */ | 456 | u8 tx_ring_size[4]; /* dword 0 */ |
359 | u8 rsvd1[26]; /* dword 0 */ | 457 | u8 rsvd1[26]; /* dword 0 */ |
360 | u8 pci_func_id[8]; /* dword 1 */ | 458 | u8 pci_func_id[8]; /* dword 1 */ |
@@ -409,7 +507,7 @@ struct be_cmd_req_eth_rx_create { | |||
409 | struct be_cmd_resp_eth_rx_create { | 507 | struct be_cmd_resp_eth_rx_create { |
410 | struct be_cmd_resp_hdr hdr; | 508 | struct be_cmd_resp_hdr hdr; |
411 | u16 id; | 509 | u16 id; |
412 | u8 cpu_id; | 510 | u8 rss_id; |
413 | u8 rsvd0; | 511 | u8 rsvd0; |
414 | } __packed; | 512 | } __packed; |
415 | 513 | ||
@@ -442,7 +540,8 @@ enum be_if_flags { | |||
442 | BE_IF_FLAGS_VLAN = 0x100, | 540 | BE_IF_FLAGS_VLAN = 0x100, |
443 | BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, | 541 | BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, |
444 | BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, | 542 | BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, |
445 | BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800 | 543 | BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, |
544 | BE_IF_FLAGS_MULTICAST = 0x1000 | ||
446 | }; | 545 | }; |
447 | 546 | ||
448 | /* An RX interface is an object with one or more MAC addresses and | 547 | /* An RX interface is an object with one or more MAC addresses and |
@@ -471,7 +570,7 @@ struct be_cmd_req_if_destroy { | |||
471 | }; | 570 | }; |
472 | 571 | ||
473 | /*************** HW Stats Get **********************************/ | 572 | /*************** HW Stats Get **********************************/ |
474 | struct be_port_rxf_stats { | 573 | struct be_port_rxf_stats_v0 { |
475 | u32 rx_bytes_lsd; /* dword 0*/ | 574 | u32 rx_bytes_lsd; /* dword 0*/ |
476 | u32 rx_bytes_msd; /* dword 1*/ | 575 | u32 rx_bytes_msd; /* dword 1*/ |
477 | u32 rx_total_frames; /* dword 2*/ | 576 | u32 rx_total_frames; /* dword 2*/ |
@@ -540,8 +639,8 @@ struct be_port_rxf_stats { | |||
540 | u32 rx_input_fifo_overflow; /* dword 65*/ | 639 | u32 rx_input_fifo_overflow; /* dword 65*/ |
541 | }; | 640 | }; |
542 | 641 | ||
543 | struct be_rxf_stats { | 642 | struct be_rxf_stats_v0 { |
544 | struct be_port_rxf_stats port[2]; | 643 | struct be_port_rxf_stats_v0 port[2]; |
545 | u32 rx_drops_no_pbuf; /* dword 132*/ | 644 | u32 rx_drops_no_pbuf; /* dword 132*/ |
546 | u32 rx_drops_no_txpb; /* dword 133*/ | 645 | u32 rx_drops_no_txpb; /* dword 133*/ |
547 | u32 rx_drops_no_erx_descr; /* dword 134*/ | 646 | u32 rx_drops_no_erx_descr; /* dword 134*/ |
@@ -558,31 +657,245 @@ struct be_rxf_stats { | |||
558 | u32 rx_drops_invalid_ring; /* dword 145*/ | 657 | u32 rx_drops_invalid_ring; /* dword 145*/ |
559 | u32 forwarded_packets; /* dword 146*/ | 658 | u32 forwarded_packets; /* dword 146*/ |
560 | u32 rx_drops_mtu; /* dword 147*/ | 659 | u32 rx_drops_mtu; /* dword 147*/ |
561 | u32 rsvd0[15]; | 660 | u32 rsvd0[7]; |
661 | u32 port0_jabber_events; | ||
662 | u32 port1_jabber_events; | ||
663 | u32 rsvd1[6]; | ||
562 | }; | 664 | }; |
563 | 665 | ||
564 | struct be_erx_stats { | 666 | struct be_erx_stats_v0 { |
565 | u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/ | 667 | u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/ |
566 | u32 debug_wdma_sent_hold; /* dword 44*/ | 668 | u32 rsvd[4]; |
567 | u32 debug_wdma_pbfree_sent_hold; /* dword 45*/ | 669 | }; |
568 | u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/ | 670 | |
569 | u32 debug_pmem_pbuf_dealloc; /* dword 47*/ | 671 | struct be_pmem_stats { |
672 | u32 eth_red_drops; | ||
673 | u32 rsvd[5]; | ||
570 | }; | 674 | }; |
571 | 675 | ||
572 | struct be_hw_stats { | 676 | struct be_hw_stats_v0 { |
573 | struct be_rxf_stats rxf; | 677 | struct be_rxf_stats_v0 rxf; |
574 | u32 rsvd[48]; | 678 | u32 rsvd[48]; |
575 | struct be_erx_stats erx; | 679 | struct be_erx_stats_v0 erx; |
680 | struct be_pmem_stats pmem; | ||
681 | }; | ||
682 | |||
683 | struct be_cmd_req_get_stats_v0 { | ||
684 | struct be_cmd_req_hdr hdr; | ||
685 | u8 rsvd[sizeof(struct be_hw_stats_v0)]; | ||
686 | }; | ||
687 | |||
688 | struct be_cmd_resp_get_stats_v0 { | ||
689 | struct be_cmd_resp_hdr hdr; | ||
690 | struct be_hw_stats_v0 hw_stats; | ||
691 | }; | ||
692 | |||
693 | #define make_64bit_val(hi_32, lo_32) (((u64)hi_32<<32) | lo_32) | ||
694 | struct lancer_cmd_pport_stats { | ||
695 | u32 tx_packets_lo; | ||
696 | u32 tx_packets_hi; | ||
697 | u32 tx_unicast_packets_lo; | ||
698 | u32 tx_unicast_packets_hi; | ||
699 | u32 tx_multicast_packets_lo; | ||
700 | u32 tx_multicast_packets_hi; | ||
701 | u32 tx_broadcast_packets_lo; | ||
702 | u32 tx_broadcast_packets_hi; | ||
703 | u32 tx_bytes_lo; | ||
704 | u32 tx_bytes_hi; | ||
705 | u32 tx_unicast_bytes_lo; | ||
706 | u32 tx_unicast_bytes_hi; | ||
707 | u32 tx_multicast_bytes_lo; | ||
708 | u32 tx_multicast_bytes_hi; | ||
709 | u32 tx_broadcast_bytes_lo; | ||
710 | u32 tx_broadcast_bytes_hi; | ||
711 | u32 tx_discards_lo; | ||
712 | u32 tx_discards_hi; | ||
713 | u32 tx_errors_lo; | ||
714 | u32 tx_errors_hi; | ||
715 | u32 tx_pause_frames_lo; | ||
716 | u32 tx_pause_frames_hi; | ||
717 | u32 tx_pause_on_frames_lo; | ||
718 | u32 tx_pause_on_frames_hi; | ||
719 | u32 tx_pause_off_frames_lo; | ||
720 | u32 tx_pause_off_frames_hi; | ||
721 | u32 tx_internal_mac_errors_lo; | ||
722 | u32 tx_internal_mac_errors_hi; | ||
723 | u32 tx_control_frames_lo; | ||
724 | u32 tx_control_frames_hi; | ||
725 | u32 tx_packets_64_bytes_lo; | ||
726 | u32 tx_packets_64_bytes_hi; | ||
727 | u32 tx_packets_65_to_127_bytes_lo; | ||
728 | u32 tx_packets_65_to_127_bytes_hi; | ||
729 | u32 tx_packets_128_to_255_bytes_lo; | ||
730 | u32 tx_packets_128_to_255_bytes_hi; | ||
731 | u32 tx_packets_256_to_511_bytes_lo; | ||
732 | u32 tx_packets_256_to_511_bytes_hi; | ||
733 | u32 tx_packets_512_to_1023_bytes_lo; | ||
734 | u32 tx_packets_512_to_1023_bytes_hi; | ||
735 | u32 tx_packets_1024_to_1518_bytes_lo; | ||
736 | u32 tx_packets_1024_to_1518_bytes_hi; | ||
737 | u32 tx_packets_1519_to_2047_bytes_lo; | ||
738 | u32 tx_packets_1519_to_2047_bytes_hi; | ||
739 | u32 tx_packets_2048_to_4095_bytes_lo; | ||
740 | u32 tx_packets_2048_to_4095_bytes_hi; | ||
741 | u32 tx_packets_4096_to_8191_bytes_lo; | ||
742 | u32 tx_packets_4096_to_8191_bytes_hi; | ||
743 | u32 tx_packets_8192_to_9216_bytes_lo; | ||
744 | u32 tx_packets_8192_to_9216_bytes_hi; | ||
745 | u32 tx_lso_packets_lo; | ||
746 | u32 tx_lso_packets_hi; | ||
747 | u32 rx_packets_lo; | ||
748 | u32 rx_packets_hi; | ||
749 | u32 rx_unicast_packets_lo; | ||
750 | u32 rx_unicast_packets_hi; | ||
751 | u32 rx_multicast_packets_lo; | ||
752 | u32 rx_multicast_packets_hi; | ||
753 | u32 rx_broadcast_packets_lo; | ||
754 | u32 rx_broadcast_packets_hi; | ||
755 | u32 rx_bytes_lo; | ||
756 | u32 rx_bytes_hi; | ||
757 | u32 rx_unicast_bytes_lo; | ||
758 | u32 rx_unicast_bytes_hi; | ||
759 | u32 rx_multicast_bytes_lo; | ||
760 | u32 rx_multicast_bytes_hi; | ||
761 | u32 rx_broadcast_bytes_lo; | ||
762 | u32 rx_broadcast_bytes_hi; | ||
763 | u32 rx_unknown_protos; | ||
764 | u32 rsvd_69; /* Word 69 is reserved */ | ||
765 | u32 rx_discards_lo; | ||
766 | u32 rx_discards_hi; | ||
767 | u32 rx_errors_lo; | ||
768 | u32 rx_errors_hi; | ||
769 | u32 rx_crc_errors_lo; | ||
770 | u32 rx_crc_errors_hi; | ||
771 | u32 rx_alignment_errors_lo; | ||
772 | u32 rx_alignment_errors_hi; | ||
773 | u32 rx_symbol_errors_lo; | ||
774 | u32 rx_symbol_errors_hi; | ||
775 | u32 rx_pause_frames_lo; | ||
776 | u32 rx_pause_frames_hi; | ||
777 | u32 rx_pause_on_frames_lo; | ||
778 | u32 rx_pause_on_frames_hi; | ||
779 | u32 rx_pause_off_frames_lo; | ||
780 | u32 rx_pause_off_frames_hi; | ||
781 | u32 rx_frames_too_long_lo; | ||
782 | u32 rx_frames_too_long_hi; | ||
783 | u32 rx_internal_mac_errors_lo; | ||
784 | u32 rx_internal_mac_errors_hi; | ||
785 | u32 rx_undersize_packets; | ||
786 | u32 rx_oversize_packets; | ||
787 | u32 rx_fragment_packets; | ||
788 | u32 rx_jabbers; | ||
789 | u32 rx_control_frames_lo; | ||
790 | u32 rx_control_frames_hi; | ||
791 | u32 rx_control_frames_unknown_opcode_lo; | ||
792 | u32 rx_control_frames_unknown_opcode_hi; | ||
793 | u32 rx_in_range_errors; | ||
794 | u32 rx_out_of_range_errors; | ||
795 | u32 rx_address_match_errors; | ||
796 | u32 rx_vlan_mismatch_errors; | ||
797 | u32 rx_dropped_too_small; | ||
798 | u32 rx_dropped_too_short; | ||
799 | u32 rx_dropped_header_too_small; | ||
800 | u32 rx_dropped_invalid_tcp_length; | ||
801 | u32 rx_dropped_runt; | ||
802 | u32 rx_ip_checksum_errors; | ||
803 | u32 rx_tcp_checksum_errors; | ||
804 | u32 rx_udp_checksum_errors; | ||
805 | u32 rx_non_rss_packets; | ||
806 | u32 rsvd_111; | ||
807 | u32 rx_ipv4_packets_lo; | ||
808 | u32 rx_ipv4_packets_hi; | ||
809 | u32 rx_ipv6_packets_lo; | ||
810 | u32 rx_ipv6_packets_hi; | ||
811 | u32 rx_ipv4_bytes_lo; | ||
812 | u32 rx_ipv4_bytes_hi; | ||
813 | u32 rx_ipv6_bytes_lo; | ||
814 | u32 rx_ipv6_bytes_hi; | ||
815 | u32 rx_nic_packets_lo; | ||
816 | u32 rx_nic_packets_hi; | ||
817 | u32 rx_tcp_packets_lo; | ||
818 | u32 rx_tcp_packets_hi; | ||
819 | u32 rx_iscsi_packets_lo; | ||
820 | u32 rx_iscsi_packets_hi; | ||
821 | u32 rx_management_packets_lo; | ||
822 | u32 rx_management_packets_hi; | ||
823 | u32 rx_switched_unicast_packets_lo; | ||
824 | u32 rx_switched_unicast_packets_hi; | ||
825 | u32 rx_switched_multicast_packets_lo; | ||
826 | u32 rx_switched_multicast_packets_hi; | ||
827 | u32 rx_switched_broadcast_packets_lo; | ||
828 | u32 rx_switched_broadcast_packets_hi; | ||
829 | u32 num_forwards_lo; | ||
830 | u32 num_forwards_hi; | ||
831 | u32 rx_fifo_overflow; | ||
832 | u32 rx_input_fifo_overflow; | ||
833 | u32 rx_drops_too_many_frags_lo; | ||
834 | u32 rx_drops_too_many_frags_hi; | ||
835 | u32 rx_drops_invalid_queue; | ||
836 | u32 rsvd_141; | ||
837 | u32 rx_drops_mtu_lo; | ||
838 | u32 rx_drops_mtu_hi; | ||
839 | u32 rx_packets_64_bytes_lo; | ||
840 | u32 rx_packets_64_bytes_hi; | ||
841 | u32 rx_packets_65_to_127_bytes_lo; | ||
842 | u32 rx_packets_65_to_127_bytes_hi; | ||
843 | u32 rx_packets_128_to_255_bytes_lo; | ||
844 | u32 rx_packets_128_to_255_bytes_hi; | ||
845 | u32 rx_packets_256_to_511_bytes_lo; | ||
846 | u32 rx_packets_256_to_511_bytes_hi; | ||
847 | u32 rx_packets_512_to_1023_bytes_lo; | ||
848 | u32 rx_packets_512_to_1023_bytes_hi; | ||
849 | u32 rx_packets_1024_to_1518_bytes_lo; | ||
850 | u32 rx_packets_1024_to_1518_bytes_hi; | ||
851 | u32 rx_packets_1519_to_2047_bytes_lo; | ||
852 | u32 rx_packets_1519_to_2047_bytes_hi; | ||
853 | u32 rx_packets_2048_to_4095_bytes_lo; | ||
854 | u32 rx_packets_2048_to_4095_bytes_hi; | ||
855 | u32 rx_packets_4096_to_8191_bytes_lo; | ||
856 | u32 rx_packets_4096_to_8191_bytes_hi; | ||
857 | u32 rx_packets_8192_to_9216_bytes_lo; | ||
858 | u32 rx_packets_8192_to_9216_bytes_hi; | ||
859 | }; | ||
860 | |||
861 | struct pport_stats_params { | ||
862 | u16 pport_num; | ||
863 | u8 rsvd; | ||
864 | u8 reset_stats; | ||
576 | }; | 865 | }; |
577 | 866 | ||
578 | struct be_cmd_req_get_stats { | 867 | struct lancer_cmd_req_pport_stats { |
579 | struct be_cmd_req_hdr hdr; | 868 | struct be_cmd_req_hdr hdr; |
580 | u8 rsvd[sizeof(struct be_hw_stats)]; | 869 | union { |
870 | struct pport_stats_params params; | ||
871 | u8 rsvd[sizeof(struct lancer_cmd_pport_stats)]; | ||
872 | } cmd_params; | ||
873 | }; | ||
874 | |||
875 | struct lancer_cmd_resp_pport_stats { | ||
876 | struct be_cmd_resp_hdr hdr; | ||
877 | struct lancer_cmd_pport_stats pport_stats; | ||
878 | }; | ||
879 | |||
880 | static inline struct lancer_cmd_pport_stats* | ||
881 | pport_stats_from_cmd(struct be_adapter *adapter) | ||
882 | { | ||
883 | struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va; | ||
884 | return &cmd->pport_stats; | ||
885 | } | ||
886 | |||
887 | struct be_cmd_req_get_cntl_addnl_attribs { | ||
888 | struct be_cmd_req_hdr hdr; | ||
889 | u8 rsvd[8]; | ||
581 | }; | 890 | }; |
582 | 891 | ||
583 | struct be_cmd_resp_get_stats { | 892 | struct be_cmd_resp_get_cntl_addnl_attribs { |
584 | struct be_cmd_resp_hdr hdr; | 893 | struct be_cmd_resp_hdr hdr; |
585 | struct be_hw_stats hw_stats; | 894 | u16 ipl_file_number; |
895 | u8 ipl_file_version; | ||
896 | u8 rsvd0; | ||
897 | u8 on_die_temperature; /* in degrees centigrade*/ | ||
898 | u8 rsvd1[3]; | ||
586 | }; | 899 | }; |
587 | 900 | ||
588 | struct be_cmd_req_vlan_config { | 901 | struct be_cmd_req_vlan_config { |
@@ -594,13 +907,6 @@ struct be_cmd_req_vlan_config { | |||
594 | u16 normal_vlan[64]; | 907 | u16 normal_vlan[64]; |
595 | } __packed; | 908 | } __packed; |
596 | 909 | ||
597 | struct be_cmd_req_promiscuous_config { | ||
598 | struct be_cmd_req_hdr hdr; | ||
599 | u8 port0_promiscuous; | ||
600 | u8 port1_promiscuous; | ||
601 | u16 rsvd0; | ||
602 | } __packed; | ||
603 | |||
604 | /******************** Multicast MAC Config *******************/ | 910 | /******************** Multicast MAC Config *******************/ |
605 | #define BE_MAX_MC 64 /* set mcast promisc if > 64 */ | 911 | #define BE_MAX_MC 64 /* set mcast promisc if > 64 */ |
606 | struct macaddr { | 912 | struct macaddr { |
@@ -615,11 +921,18 @@ struct be_cmd_req_mcast_mac_config { | |||
615 | struct macaddr mac[BE_MAX_MC]; | 921 | struct macaddr mac[BE_MAX_MC]; |
616 | } __packed; | 922 | } __packed; |
617 | 923 | ||
618 | static inline struct be_hw_stats * | 924 | /******************* RX FILTER ******************************/ |
619 | hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd) | 925 | struct be_cmd_req_rx_filter { |
620 | { | 926 | struct be_cmd_req_hdr hdr; |
621 | return &cmd->hw_stats; | 927 | u32 global_flags_mask; |
622 | } | 928 | u32 global_flags; |
929 | u32 if_flags_mask; | ||
930 | u32 if_flags; | ||
931 | u32 if_id; | ||
932 | u32 multicast_num; | ||
933 | struct macaddr mac[BE_MAX_MC]; | ||
934 | }; | ||
935 | |||
623 | 936 | ||
624 | /******************** Link Status Query *******************/ | 937 | /******************** Link Status Query *******************/ |
625 | struct be_cmd_req_link_status { | 938 | struct be_cmd_req_link_status { |
@@ -739,9 +1052,10 @@ struct be_cmd_resp_modify_eq_delay { | |||
739 | } __packed; | 1052 | } __packed; |
740 | 1053 | ||
741 | /******************** Get FW Config *******************/ | 1054 | /******************** Get FW Config *******************/ |
1055 | #define BE_FUNCTION_CAPS_RSS 0x2 | ||
742 | struct be_cmd_req_query_fw_cfg { | 1056 | struct be_cmd_req_query_fw_cfg { |
743 | struct be_cmd_req_hdr hdr; | 1057 | struct be_cmd_req_hdr hdr; |
744 | u32 rsvd[30]; | 1058 | u32 rsvd[31]; |
745 | }; | 1059 | }; |
746 | 1060 | ||
747 | struct be_cmd_resp_query_fw_cfg { | 1061 | struct be_cmd_resp_query_fw_cfg { |
@@ -751,6 +1065,26 @@ struct be_cmd_resp_query_fw_cfg { | |||
751 | u32 phys_port; | 1065 | u32 phys_port; |
752 | u32 function_mode; | 1066 | u32 function_mode; |
753 | u32 rsvd[26]; | 1067 | u32 rsvd[26]; |
1068 | u32 function_caps; | ||
1069 | }; | ||
1070 | |||
1071 | /******************** RSS Config *******************/ | ||
1072 | /* RSS types */ | ||
1073 | #define RSS_ENABLE_NONE 0x0 | ||
1074 | #define RSS_ENABLE_IPV4 0x1 | ||
1075 | #define RSS_ENABLE_TCP_IPV4 0x2 | ||
1076 | #define RSS_ENABLE_IPV6 0x4 | ||
1077 | #define RSS_ENABLE_TCP_IPV6 0x8 | ||
1078 | |||
1079 | struct be_cmd_req_rss_config { | ||
1080 | struct be_cmd_req_hdr hdr; | ||
1081 | u32 if_id; | ||
1082 | u16 enable_rss; | ||
1083 | u16 cpu_table_size_log2; | ||
1084 | u32 hash[10]; | ||
1085 | u8 cpu_table[128]; | ||
1086 | u8 flush; | ||
1087 | u8 rsvd0[3]; | ||
754 | }; | 1088 | }; |
755 | 1089 | ||
756 | /******************** Port Beacon ***************************/ | 1090 | /******************** Port Beacon ***************************/ |
@@ -798,6 +1132,36 @@ struct be_cmd_write_flashrom { | |||
798 | struct flashrom_params params; | 1132 | struct flashrom_params params; |
799 | }; | 1133 | }; |
800 | 1134 | ||
1135 | /**************** Lancer Firmware Flash ************/ | ||
1136 | struct amap_lancer_write_obj_context { | ||
1137 | u8 write_length[24]; | ||
1138 | u8 reserved1[7]; | ||
1139 | u8 eof; | ||
1140 | } __packed; | ||
1141 | |||
1142 | struct lancer_cmd_req_write_object { | ||
1143 | struct be_cmd_req_hdr hdr; | ||
1144 | u8 context[sizeof(struct amap_lancer_write_obj_context) / 8]; | ||
1145 | u32 write_offset; | ||
1146 | u8 object_name[104]; | ||
1147 | u32 descriptor_count; | ||
1148 | u32 buf_len; | ||
1149 | u32 addr_low; | ||
1150 | u32 addr_high; | ||
1151 | }; | ||
1152 | |||
1153 | struct lancer_cmd_resp_write_object { | ||
1154 | u8 opcode; | ||
1155 | u8 subsystem; | ||
1156 | u8 rsvd1[2]; | ||
1157 | u8 status; | ||
1158 | u8 additional_status; | ||
1159 | u8 rsvd2[2]; | ||
1160 | u32 resp_len; | ||
1161 | u32 actual_resp_len; | ||
1162 | u32 actual_write_len; | ||
1163 | }; | ||
1164 | |||
801 | /************************ WOL *******************************/ | 1165 | /************************ WOL *******************************/ |
802 | struct be_cmd_req_acpi_wol_magic_config{ | 1166 | struct be_cmd_req_acpi_wol_magic_config{ |
803 | struct be_cmd_req_hdr hdr; | 1167 | struct be_cmd_req_hdr hdr; |
@@ -911,17 +1275,192 @@ struct be_cmd_resp_set_qos { | |||
911 | u32 rsvd; | 1275 | u32 rsvd; |
912 | }; | 1276 | }; |
913 | 1277 | ||
1278 | /*********************** Controller Attributes ***********************/ | ||
1279 | struct be_cmd_req_cntl_attribs { | ||
1280 | struct be_cmd_req_hdr hdr; | ||
1281 | }; | ||
1282 | |||
1283 | struct be_cmd_resp_cntl_attribs { | ||
1284 | struct be_cmd_resp_hdr hdr; | ||
1285 | struct mgmt_controller_attrib attribs; | ||
1286 | }; | ||
1287 | |||
1288 | /*********************** Set driver function ***********************/ | ||
1289 | #define CAPABILITY_SW_TIMESTAMPS 2 | ||
1290 | #define CAPABILITY_BE3_NATIVE_ERX_API 4 | ||
1291 | |||
1292 | struct be_cmd_req_set_func_cap { | ||
1293 | struct be_cmd_req_hdr hdr; | ||
1294 | u32 valid_cap_flags; | ||
1295 | u32 cap_flags; | ||
1296 | u8 rsvd[212]; | ||
1297 | }; | ||
1298 | |||
1299 | struct be_cmd_resp_set_func_cap { | ||
1300 | struct be_cmd_resp_hdr hdr; | ||
1301 | u32 valid_cap_flags; | ||
1302 | u32 cap_flags; | ||
1303 | u8 rsvd[212]; | ||
1304 | }; | ||
1305 | |||
1306 | /*************** HW Stats Get v1 **********************************/ | ||
1307 | #define BE_TXP_SW_SZ 48 | ||
1308 | struct be_port_rxf_stats_v1 { | ||
1309 | u32 rsvd0[12]; | ||
1310 | u32 rx_crc_errors; | ||
1311 | u32 rx_alignment_symbol_errors; | ||
1312 | u32 rx_pause_frames; | ||
1313 | u32 rx_priority_pause_frames; | ||
1314 | u32 rx_control_frames; | ||
1315 | u32 rx_in_range_errors; | ||
1316 | u32 rx_out_range_errors; | ||
1317 | u32 rx_frame_too_long; | ||
1318 | u32 rx_address_match_errors; | ||
1319 | u32 rx_dropped_too_small; | ||
1320 | u32 rx_dropped_too_short; | ||
1321 | u32 rx_dropped_header_too_small; | ||
1322 | u32 rx_dropped_tcp_length; | ||
1323 | u32 rx_dropped_runt; | ||
1324 | u32 rsvd1[10]; | ||
1325 | u32 rx_ip_checksum_errs; | ||
1326 | u32 rx_tcp_checksum_errs; | ||
1327 | u32 rx_udp_checksum_errs; | ||
1328 | u32 rsvd2[7]; | ||
1329 | u32 rx_switched_unicast_packets; | ||
1330 | u32 rx_switched_multicast_packets; | ||
1331 | u32 rx_switched_broadcast_packets; | ||
1332 | u32 rsvd3[3]; | ||
1333 | u32 tx_pauseframes; | ||
1334 | u32 tx_priority_pauseframes; | ||
1335 | u32 tx_controlframes; | ||
1336 | u32 rsvd4[10]; | ||
1337 | u32 rxpp_fifo_overflow_drop; | ||
1338 | u32 rx_input_fifo_overflow_drop; | ||
1339 | u32 pmem_fifo_overflow_drop; | ||
1340 | u32 jabber_events; | ||
1341 | u32 rsvd5[3]; | ||
1342 | }; | ||
1343 | |||
1344 | |||
1345 | struct be_rxf_stats_v1 { | ||
1346 | struct be_port_rxf_stats_v1 port[4]; | ||
1347 | u32 rsvd0[2]; | ||
1348 | u32 rx_drops_no_pbuf; | ||
1349 | u32 rx_drops_no_txpb; | ||
1350 | u32 rx_drops_no_erx_descr; | ||
1351 | u32 rx_drops_no_tpre_descr; | ||
1352 | u32 rsvd1[6]; | ||
1353 | u32 rx_drops_too_many_frags; | ||
1354 | u32 rx_drops_invalid_ring; | ||
1355 | u32 forwarded_packets; | ||
1356 | u32 rx_drops_mtu; | ||
1357 | u32 rsvd2[14]; | ||
1358 | }; | ||
1359 | |||
1360 | struct be_erx_stats_v1 { | ||
1361 | u32 rx_drops_no_fragments[68]; /* dwordS 0 to 67*/ | ||
1362 | u32 rsvd[4]; | ||
1363 | }; | ||
1364 | |||
1365 | struct be_hw_stats_v1 { | ||
1366 | struct be_rxf_stats_v1 rxf; | ||
1367 | u32 rsvd0[BE_TXP_SW_SZ]; | ||
1368 | struct be_erx_stats_v1 erx; | ||
1369 | struct be_pmem_stats pmem; | ||
1370 | u32 rsvd1[3]; | ||
1371 | }; | ||
1372 | |||
1373 | struct be_cmd_req_get_stats_v1 { | ||
1374 | struct be_cmd_req_hdr hdr; | ||
1375 | u8 rsvd[sizeof(struct be_hw_stats_v1)]; | ||
1376 | }; | ||
1377 | |||
1378 | struct be_cmd_resp_get_stats_v1 { | ||
1379 | struct be_cmd_resp_hdr hdr; | ||
1380 | struct be_hw_stats_v1 hw_stats; | ||
1381 | }; | ||
1382 | |||
1383 | static inline void * | ||
1384 | hw_stats_from_cmd(struct be_adapter *adapter) | ||
1385 | { | ||
1386 | if (adapter->generation == BE_GEN3) { | ||
1387 | struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va; | ||
1388 | |||
1389 | return &cmd->hw_stats; | ||
1390 | } else { | ||
1391 | struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va; | ||
1392 | |||
1393 | return &cmd->hw_stats; | ||
1394 | } | ||
1395 | } | ||
1396 | |||
1397 | static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter) | ||
1398 | { | ||
1399 | if (adapter->generation == BE_GEN3) { | ||
1400 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
1401 | struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf; | ||
1402 | |||
1403 | return &rxf_stats->port[adapter->port_num]; | ||
1404 | } else { | ||
1405 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
1406 | struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf; | ||
1407 | |||
1408 | return &rxf_stats->port[adapter->port_num]; | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1412 | static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter) | ||
1413 | { | ||
1414 | if (adapter->generation == BE_GEN3) { | ||
1415 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
1416 | |||
1417 | return &hw_stats->rxf; | ||
1418 | } else { | ||
1419 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
1420 | |||
1421 | return &hw_stats->rxf; | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1425 | static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) | ||
1426 | { | ||
1427 | if (adapter->generation == BE_GEN3) { | ||
1428 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
1429 | |||
1430 | return &hw_stats->erx; | ||
1431 | } else { | ||
1432 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
1433 | |||
1434 | return &hw_stats->erx; | ||
1435 | } | ||
1436 | } | ||
1437 | |||
1438 | static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter) | ||
1439 | { | ||
1440 | if (adapter->generation == BE_GEN3) { | ||
1441 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
1442 | |||
1443 | return &hw_stats->pmem; | ||
1444 | } else { | ||
1445 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
1446 | |||
1447 | return &hw_stats->pmem; | ||
1448 | } | ||
1449 | } | ||
1450 | |||
914 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 1451 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
915 | extern int be_cmd_POST(struct be_adapter *adapter); | 1452 | extern int be_cmd_POST(struct be_adapter *adapter); |
916 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 1453 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
917 | u8 type, bool permanent, u32 if_handle); | 1454 | u8 type, bool permanent, u32 if_handle); |
918 | extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | 1455 | extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, |
919 | u32 if_id, u32 *pmac_id); | 1456 | u32 if_id, u32 *pmac_id, u32 domain); |
920 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); | 1457 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, |
1458 | u32 pmac_id, u32 domain); | ||
921 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, | 1459 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, |
922 | u32 en_flags, u8 *mac, bool pmac_invalid, | 1460 | u32 en_flags, u8 *mac, bool pmac_invalid, |
923 | u32 *if_handle, u32 *pmac_id, u32 domain); | 1461 | u32 *if_handle, u32 *pmac_id, u32 domain); |
924 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); | 1462 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle, |
1463 | u32 domain); | ||
925 | extern int be_cmd_eq_create(struct be_adapter *adapter, | 1464 | extern int be_cmd_eq_create(struct be_adapter *adapter, |
926 | struct be_queue_info *eq, int eq_delay); | 1465 | struct be_queue_info *eq, int eq_delay); |
927 | extern int be_cmd_cq_create(struct be_adapter *adapter, | 1466 | extern int be_cmd_cq_create(struct be_adapter *adapter, |
@@ -937,22 +1476,23 @@ extern int be_cmd_txq_create(struct be_adapter *adapter, | |||
937 | extern int be_cmd_rxq_create(struct be_adapter *adapter, | 1476 | extern int be_cmd_rxq_create(struct be_adapter *adapter, |
938 | struct be_queue_info *rxq, u16 cq_id, | 1477 | struct be_queue_info *rxq, u16 cq_id, |
939 | u16 frag_size, u16 max_frame_size, u32 if_id, | 1478 | u16 frag_size, u16 max_frame_size, u32 if_id, |
940 | u32 rss); | 1479 | u32 rss, u8 *rss_id); |
941 | extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | 1480 | extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, |
942 | int type); | 1481 | int type); |
943 | extern int be_cmd_link_status_query(struct be_adapter *adapter, | 1482 | extern int be_cmd_link_status_query(struct be_adapter *adapter, |
944 | bool *link_up, u8 *mac_speed, u16 *link_speed); | 1483 | bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom); |
945 | extern int be_cmd_reset(struct be_adapter *adapter); | 1484 | extern int be_cmd_reset(struct be_adapter *adapter); |
946 | extern int be_cmd_get_stats(struct be_adapter *adapter, | 1485 | extern int be_cmd_get_stats(struct be_adapter *adapter, |
947 | struct be_dma_mem *nonemb_cmd); | 1486 | struct be_dma_mem *nonemb_cmd); |
1487 | extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter, | ||
1488 | struct be_dma_mem *nonemb_cmd); | ||
948 | extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver); | 1489 | extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver); |
949 | 1490 | ||
950 | extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd); | 1491 | extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd); |
951 | extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, | 1492 | extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, |
952 | u16 *vtag_array, u32 num, bool untagged, | 1493 | u16 *vtag_array, u32 num, bool untagged, |
953 | bool promiscuous); | 1494 | bool promiscuous); |
954 | extern int be_cmd_promiscuous_config(struct be_adapter *adapter, | 1495 | extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en); |
955 | u8 port_num, bool en); | ||
956 | extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | 1496 | extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, |
957 | struct net_device *netdev, struct be_dma_mem *mem); | 1497 | struct net_device *netdev, struct be_dma_mem *mem); |
958 | extern int be_cmd_set_flow_control(struct be_adapter *adapter, | 1498 | extern int be_cmd_set_flow_control(struct be_adapter *adapter, |
@@ -960,18 +1500,23 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter, | |||
960 | extern int be_cmd_get_flow_control(struct be_adapter *adapter, | 1500 | extern int be_cmd_get_flow_control(struct be_adapter *adapter, |
961 | u32 *tx_fc, u32 *rx_fc); | 1501 | u32 *tx_fc, u32 *rx_fc); |
962 | extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, | 1502 | extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, |
963 | u32 *port_num, u32 *cap); | 1503 | u32 *port_num, u32 *function_mode, u32 *function_caps); |
964 | extern int be_cmd_reset_function(struct be_adapter *adapter); | 1504 | extern int be_cmd_reset_function(struct be_adapter *adapter); |
1505 | extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, | ||
1506 | u16 table_size); | ||
965 | extern int be_process_mcc(struct be_adapter *adapter, int *status); | 1507 | extern int be_process_mcc(struct be_adapter *adapter, int *status); |
966 | extern int be_cmd_set_beacon_state(struct be_adapter *adapter, | 1508 | extern int be_cmd_set_beacon_state(struct be_adapter *adapter, |
967 | u8 port_num, u8 beacon, u8 status, u8 state); | 1509 | u8 port_num, u8 beacon, u8 status, u8 state); |
968 | extern int be_cmd_get_beacon_state(struct be_adapter *adapter, | 1510 | extern int be_cmd_get_beacon_state(struct be_adapter *adapter, |
969 | u8 port_num, u32 *state); | 1511 | u8 port_num, u32 *state); |
970 | extern int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, | ||
971 | u8 *connector); | ||
972 | extern int be_cmd_write_flashrom(struct be_adapter *adapter, | 1512 | extern int be_cmd_write_flashrom(struct be_adapter *adapter, |
973 | struct be_dma_mem *cmd, u32 flash_oper, | 1513 | struct be_dma_mem *cmd, u32 flash_oper, |
974 | u32 flash_opcode, u32 buf_size); | 1514 | u32 flash_opcode, u32 buf_size); |
1515 | extern int lancer_cmd_write_object(struct be_adapter *adapter, | ||
1516 | struct be_dma_mem *cmd, | ||
1517 | u32 data_size, u32 data_offset, | ||
1518 | const char *obj_name, | ||
1519 | u32 *data_written, u8 *addn_status); | ||
975 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | 1520 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, |
976 | int offset); | 1521 | int offset); |
977 | extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, | 1522 | extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, |
@@ -993,4 +1538,9 @@ extern int be_cmd_get_phy_info(struct be_adapter *adapter, | |||
993 | struct be_dma_mem *cmd); | 1538 | struct be_dma_mem *cmd); |
994 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); | 1539 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); |
995 | extern void be_detect_dump_ue(struct be_adapter *adapter); | 1540 | extern void be_detect_dump_ue(struct be_adapter *adapter); |
1541 | extern int be_cmd_get_die_temperature(struct be_adapter *adapter); | ||
1542 | extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); | ||
1543 | extern int be_cmd_check_native_mode(struct be_adapter *adapter); | ||
1544 | extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); | ||
1545 | extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); | ||
996 | 1546 | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 13f0abbc5205..facfe3ca5c40 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,11 +8,11 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "be.h" | 18 | #include "be.h" |
@@ -26,21 +26,22 @@ struct be_ethtool_stat { | |||
26 | int offset; | 26 | int offset; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT}; | 29 | enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, |
30 | DRVSTAT}; | ||
30 | #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ | 31 | #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ |
31 | offsetof(_struct, field) | 32 | offsetof(_struct, field) |
32 | #define NETSTAT_INFO(field) #field, NETSTAT,\ | 33 | #define NETSTAT_INFO(field) #field, NETSTAT,\ |
33 | FIELDINFO(struct net_device_stats,\ | 34 | FIELDINFO(struct net_device_stats,\ |
34 | field) | 35 | field) |
35 | #define DRVSTAT_INFO(field) #field, DRVSTAT,\ | 36 | #define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\ |
36 | FIELDINFO(struct be_drvr_stats, field) | 37 | FIELDINFO(struct be_tx_stats, field) |
37 | #define MISCSTAT_INFO(field) #field, MISCSTAT,\ | 38 | #define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\ |
38 | FIELDINFO(struct be_rxf_stats, field) | 39 | FIELDINFO(struct be_rx_stats, field) |
39 | #define PORTSTAT_INFO(field) #field, PORTSTAT,\ | 40 | #define ERXSTAT_INFO(field) #field, ERXSTAT,\ |
40 | FIELDINFO(struct be_port_rxf_stats, \ | 41 | FIELDINFO(struct be_erx_stats_v1, field) |
42 | #define DRVSTAT_INFO(field) #field, DRVSTAT,\ | ||
43 | FIELDINFO(struct be_drv_stats, \ | ||
41 | field) | 44 | field) |
42 | #define ERXSTAT_INFO(field) #field, ERXSTAT,\ | ||
43 | FIELDINFO(struct be_erx_stats, field) | ||
44 | 45 | ||
45 | static const struct be_ethtool_stat et_stats[] = { | 46 | static const struct be_ethtool_stat et_stats[] = { |
46 | {NETSTAT_INFO(rx_packets)}, | 47 | {NETSTAT_INFO(rx_packets)}, |
@@ -51,68 +52,70 @@ static const struct be_ethtool_stat et_stats[] = { | |||
51 | {NETSTAT_INFO(tx_errors)}, | 52 | {NETSTAT_INFO(tx_errors)}, |
52 | {NETSTAT_INFO(rx_dropped)}, | 53 | {NETSTAT_INFO(rx_dropped)}, |
53 | {NETSTAT_INFO(tx_dropped)}, | 54 | {NETSTAT_INFO(tx_dropped)}, |
54 | {DRVSTAT_INFO(be_tx_reqs)}, | 55 | {DRVSTAT_TX_INFO(be_tx_rate)}, |
55 | {DRVSTAT_INFO(be_tx_stops)}, | 56 | {DRVSTAT_TX_INFO(be_tx_reqs)}, |
56 | {DRVSTAT_INFO(be_fwd_reqs)}, | 57 | {DRVSTAT_TX_INFO(be_tx_wrbs)}, |
57 | {DRVSTAT_INFO(be_tx_wrbs)}, | 58 | {DRVSTAT_TX_INFO(be_tx_stops)}, |
58 | {DRVSTAT_INFO(be_rx_polls)}, | 59 | {DRVSTAT_TX_INFO(be_tx_events)}, |
59 | {DRVSTAT_INFO(be_tx_events)}, | 60 | {DRVSTAT_TX_INFO(be_tx_compl)}, |
60 | {DRVSTAT_INFO(be_rx_events)}, | 61 | {DRVSTAT_INFO(rx_crc_errors)}, |
61 | {DRVSTAT_INFO(be_tx_compl)}, | 62 | {DRVSTAT_INFO(rx_alignment_symbol_errors)}, |
62 | {DRVSTAT_INFO(be_rx_compl)}, | 63 | {DRVSTAT_INFO(rx_pause_frames)}, |
63 | {DRVSTAT_INFO(be_rx_mcast_pkt)}, | 64 | {DRVSTAT_INFO(rx_control_frames)}, |
64 | {DRVSTAT_INFO(be_ethrx_post_fail)}, | 65 | {DRVSTAT_INFO(rx_in_range_errors)}, |
65 | {DRVSTAT_INFO(be_802_3_dropped_frames)}, | 66 | {DRVSTAT_INFO(rx_out_range_errors)}, |
66 | {DRVSTAT_INFO(be_802_3_malformed_frames)}, | 67 | {DRVSTAT_INFO(rx_frame_too_long)}, |
67 | {DRVSTAT_INFO(be_tx_rate)}, | 68 | {DRVSTAT_INFO(rx_address_match_errors)}, |
68 | {DRVSTAT_INFO(be_rx_rate)}, | 69 | {DRVSTAT_INFO(rx_dropped_too_small)}, |
69 | {PORTSTAT_INFO(rx_unicast_frames)}, | 70 | {DRVSTAT_INFO(rx_dropped_too_short)}, |
70 | {PORTSTAT_INFO(rx_multicast_frames)}, | 71 | {DRVSTAT_INFO(rx_dropped_header_too_small)}, |
71 | {PORTSTAT_INFO(rx_broadcast_frames)}, | 72 | {DRVSTAT_INFO(rx_dropped_tcp_length)}, |
72 | {PORTSTAT_INFO(rx_crc_errors)}, | 73 | {DRVSTAT_INFO(rx_dropped_runt)}, |
73 | {PORTSTAT_INFO(rx_alignment_symbol_errors)}, | 74 | {DRVSTAT_INFO(rxpp_fifo_overflow_drop)}, |
74 | {PORTSTAT_INFO(rx_pause_frames)}, | 75 | {DRVSTAT_INFO(rx_input_fifo_overflow_drop)}, |
75 | {PORTSTAT_INFO(rx_control_frames)}, | 76 | {DRVSTAT_INFO(rx_ip_checksum_errs)}, |
76 | {PORTSTAT_INFO(rx_in_range_errors)}, | 77 | {DRVSTAT_INFO(rx_tcp_checksum_errs)}, |
77 | {PORTSTAT_INFO(rx_out_range_errors)}, | 78 | {DRVSTAT_INFO(rx_udp_checksum_errs)}, |
78 | {PORTSTAT_INFO(rx_frame_too_long)}, | 79 | {DRVSTAT_INFO(rx_switched_unicast_packets)}, |
79 | {PORTSTAT_INFO(rx_address_match_errors)}, | 80 | {DRVSTAT_INFO(rx_switched_multicast_packets)}, |
80 | {PORTSTAT_INFO(rx_vlan_mismatch)}, | 81 | {DRVSTAT_INFO(rx_switched_broadcast_packets)}, |
81 | {PORTSTAT_INFO(rx_dropped_too_small)}, | 82 | {DRVSTAT_INFO(tx_pauseframes)}, |
82 | {PORTSTAT_INFO(rx_dropped_too_short)}, | 83 | {DRVSTAT_INFO(tx_controlframes)}, |
83 | {PORTSTAT_INFO(rx_dropped_header_too_small)}, | 84 | {DRVSTAT_INFO(rx_priority_pause_frames)}, |
84 | {PORTSTAT_INFO(rx_dropped_tcp_length)}, | 85 | {DRVSTAT_INFO(pmem_fifo_overflow_drop)}, |
85 | {PORTSTAT_INFO(rx_dropped_runt)}, | 86 | {DRVSTAT_INFO(jabber_events)}, |
86 | {PORTSTAT_INFO(rx_fifo_overflow)}, | 87 | {DRVSTAT_INFO(rx_drops_no_pbuf)}, |
87 | {PORTSTAT_INFO(rx_input_fifo_overflow)}, | 88 | {DRVSTAT_INFO(rx_drops_no_txpb)}, |
88 | {PORTSTAT_INFO(rx_ip_checksum_errs)}, | 89 | {DRVSTAT_INFO(rx_drops_no_erx_descr)}, |
89 | {PORTSTAT_INFO(rx_tcp_checksum_errs)}, | 90 | {DRVSTAT_INFO(rx_drops_no_tpre_descr)}, |
90 | {PORTSTAT_INFO(rx_udp_checksum_errs)}, | 91 | {DRVSTAT_INFO(rx_drops_too_many_frags)}, |
91 | {PORTSTAT_INFO(rx_non_rss_packets)}, | 92 | {DRVSTAT_INFO(rx_drops_invalid_ring)}, |
92 | {PORTSTAT_INFO(rx_ipv4_packets)}, | 93 | {DRVSTAT_INFO(forwarded_packets)}, |
93 | {PORTSTAT_INFO(rx_ipv6_packets)}, | 94 | {DRVSTAT_INFO(rx_drops_mtu)}, |
94 | {PORTSTAT_INFO(tx_unicastframes)}, | 95 | {DRVSTAT_INFO(eth_red_drops)}, |
95 | {PORTSTAT_INFO(tx_multicastframes)}, | 96 | {DRVSTAT_INFO(be_on_die_temperature)} |
96 | {PORTSTAT_INFO(tx_broadcastframes)}, | ||
97 | {PORTSTAT_INFO(tx_pauseframes)}, | ||
98 | {PORTSTAT_INFO(tx_controlframes)}, | ||
99 | {MISCSTAT_INFO(rx_drops_no_pbuf)}, | ||
100 | {MISCSTAT_INFO(rx_drops_no_txpb)}, | ||
101 | {MISCSTAT_INFO(rx_drops_no_erx_descr)}, | ||
102 | {MISCSTAT_INFO(rx_drops_no_tpre_descr)}, | ||
103 | {MISCSTAT_INFO(rx_drops_too_many_frags)}, | ||
104 | {MISCSTAT_INFO(rx_drops_invalid_ring)}, | ||
105 | {MISCSTAT_INFO(forwarded_packets)}, | ||
106 | {MISCSTAT_INFO(rx_drops_mtu)}, | ||
107 | {ERXSTAT_INFO(rx_drops_no_fragments)}, | ||
108 | }; | 97 | }; |
109 | #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) | 98 | #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) |
110 | 99 | ||
100 | /* Stats related to multi RX queues */ | ||
101 | static const struct be_ethtool_stat et_rx_stats[] = { | ||
102 | {DRVSTAT_RX_INFO(rx_bytes)}, | ||
103 | {DRVSTAT_RX_INFO(rx_pkts)}, | ||
104 | {DRVSTAT_RX_INFO(rx_rate)}, | ||
105 | {DRVSTAT_RX_INFO(rx_polls)}, | ||
106 | {DRVSTAT_RX_INFO(rx_events)}, | ||
107 | {DRVSTAT_RX_INFO(rx_compl)}, | ||
108 | {DRVSTAT_RX_INFO(rx_mcast_pkts)}, | ||
109 | {DRVSTAT_RX_INFO(rx_post_fail)}, | ||
110 | {ERXSTAT_INFO(rx_drops_no_fragments)} | ||
111 | }; | ||
112 | #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) | ||
113 | |||
111 | static const char et_self_tests[][ETH_GSTRING_LEN] = { | 114 | static const char et_self_tests[][ETH_GSTRING_LEN] = { |
112 | "MAC Loopback test", | 115 | "MAC Loopback test", |
113 | "PHY Loopback test", | 116 | "PHY Loopback test", |
114 | "External Loopback test", | 117 | "External Loopback test", |
115 | "DDR DMA test" | 118 | "DDR DMA test", |
116 | "Link test" | 119 | "Link test" |
117 | }; | 120 | }; |
118 | 121 | ||
@@ -137,10 +140,33 @@ be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | |||
137 | } | 140 | } |
138 | 141 | ||
139 | static int | 142 | static int |
143 | be_get_reg_len(struct net_device *netdev) | ||
144 | { | ||
145 | struct be_adapter *adapter = netdev_priv(netdev); | ||
146 | u32 log_size = 0; | ||
147 | |||
148 | if (be_physfn(adapter)) | ||
149 | be_cmd_get_reg_len(adapter, &log_size); | ||
150 | |||
151 | return log_size; | ||
152 | } | ||
153 | |||
154 | static void | ||
155 | be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) | ||
156 | { | ||
157 | struct be_adapter *adapter = netdev_priv(netdev); | ||
158 | |||
159 | if (be_physfn(adapter)) { | ||
160 | memset(buf, 0, regs->len); | ||
161 | be_cmd_get_regs(adapter, regs->len, buf); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static int | ||
140 | be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) | 166 | be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) |
141 | { | 167 | { |
142 | struct be_adapter *adapter = netdev_priv(netdev); | 168 | struct be_adapter *adapter = netdev_priv(netdev); |
143 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | 169 | struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq; |
144 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 170 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
145 | 171 | ||
146 | coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; | 172 | coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; |
@@ -164,28 +190,50 @@ static int | |||
164 | be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) | 190 | be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) |
165 | { | 191 | { |
166 | struct be_adapter *adapter = netdev_priv(netdev); | 192 | struct be_adapter *adapter = netdev_priv(netdev); |
167 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | 193 | struct be_rx_obj *rxo; |
194 | struct be_eq_obj *rx_eq; | ||
168 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 195 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
169 | u32 tx_max, tx_min, tx_cur; | ||
170 | u32 rx_max, rx_min, rx_cur; | 196 | u32 rx_max, rx_min, rx_cur; |
171 | int status = 0; | 197 | int status = 0, i; |
198 | u32 tx_cur; | ||
172 | 199 | ||
173 | if (coalesce->use_adaptive_tx_coalesce == 1) | 200 | if (coalesce->use_adaptive_tx_coalesce == 1) |
174 | return -EINVAL; | 201 | return -EINVAL; |
175 | 202 | ||
176 | /* if AIC is being turned on now, start with an EQD of 0 */ | 203 | for_all_rx_queues(adapter, rxo, i) { |
177 | if (rx_eq->enable_aic == 0 && | 204 | rx_eq = &rxo->rx_eq; |
178 | coalesce->use_adaptive_rx_coalesce == 1) { | 205 | |
179 | rx_eq->cur_eqd = 0; | 206 | if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce) |
207 | rx_eq->cur_eqd = 0; | ||
208 | rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; | ||
209 | |||
210 | rx_max = coalesce->rx_coalesce_usecs_high; | ||
211 | rx_min = coalesce->rx_coalesce_usecs_low; | ||
212 | rx_cur = coalesce->rx_coalesce_usecs; | ||
213 | |||
214 | if (rx_eq->enable_aic) { | ||
215 | if (rx_max > BE_MAX_EQD) | ||
216 | rx_max = BE_MAX_EQD; | ||
217 | if (rx_min > rx_max) | ||
218 | rx_min = rx_max; | ||
219 | rx_eq->max_eqd = rx_max; | ||
220 | rx_eq->min_eqd = rx_min; | ||
221 | if (rx_eq->cur_eqd > rx_max) | ||
222 | rx_eq->cur_eqd = rx_max; | ||
223 | if (rx_eq->cur_eqd < rx_min) | ||
224 | rx_eq->cur_eqd = rx_min; | ||
225 | } else { | ||
226 | if (rx_cur > BE_MAX_EQD) | ||
227 | rx_cur = BE_MAX_EQD; | ||
228 | if (rx_eq->cur_eqd != rx_cur) { | ||
229 | status = be_cmd_modify_eqd(adapter, rx_eq->q.id, | ||
230 | rx_cur); | ||
231 | if (!status) | ||
232 | rx_eq->cur_eqd = rx_cur; | ||
233 | } | ||
234 | } | ||
180 | } | 235 | } |
181 | rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; | ||
182 | 236 | ||
183 | rx_max = coalesce->rx_coalesce_usecs_high; | ||
184 | rx_min = coalesce->rx_coalesce_usecs_low; | ||
185 | rx_cur = coalesce->rx_coalesce_usecs; | ||
186 | |||
187 | tx_max = coalesce->tx_coalesce_usecs_high; | ||
188 | tx_min = coalesce->tx_coalesce_usecs_low; | ||
189 | tx_cur = coalesce->tx_coalesce_usecs; | 237 | tx_cur = coalesce->tx_coalesce_usecs; |
190 | 238 | ||
191 | if (tx_cur > BE_MAX_EQD) | 239 | if (tx_cur > BE_MAX_EQD) |
@@ -196,46 +244,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) | |||
196 | tx_eq->cur_eqd = tx_cur; | 244 | tx_eq->cur_eqd = tx_cur; |
197 | } | 245 | } |
198 | 246 | ||
199 | if (rx_eq->enable_aic) { | ||
200 | if (rx_max > BE_MAX_EQD) | ||
201 | rx_max = BE_MAX_EQD; | ||
202 | if (rx_min > rx_max) | ||
203 | rx_min = rx_max; | ||
204 | rx_eq->max_eqd = rx_max; | ||
205 | rx_eq->min_eqd = rx_min; | ||
206 | if (rx_eq->cur_eqd > rx_max) | ||
207 | rx_eq->cur_eqd = rx_max; | ||
208 | if (rx_eq->cur_eqd < rx_min) | ||
209 | rx_eq->cur_eqd = rx_min; | ||
210 | } else { | ||
211 | if (rx_cur > BE_MAX_EQD) | ||
212 | rx_cur = BE_MAX_EQD; | ||
213 | if (rx_eq->cur_eqd != rx_cur) { | ||
214 | status = be_cmd_modify_eqd(adapter, rx_eq->q.id, | ||
215 | rx_cur); | ||
216 | if (!status) | ||
217 | rx_eq->cur_eqd = rx_cur; | ||
218 | } | ||
219 | } | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static u32 be_get_rx_csum(struct net_device *netdev) | ||
224 | { | ||
225 | struct be_adapter *adapter = netdev_priv(netdev); | ||
226 | |||
227 | return adapter->rx_csum; | ||
228 | } | ||
229 | |||
230 | static int be_set_rx_csum(struct net_device *netdev, uint32_t data) | ||
231 | { | ||
232 | struct be_adapter *adapter = netdev_priv(netdev); | ||
233 | |||
234 | if (data) | ||
235 | adapter->rx_csum = true; | ||
236 | else | ||
237 | adapter->rx_csum = false; | ||
238 | |||
239 | return 0; | 247 | return 0; |
240 | } | 248 | } |
241 | 249 | ||
@@ -244,32 +252,20 @@ be_get_ethtool_stats(struct net_device *netdev, | |||
244 | struct ethtool_stats *stats, uint64_t *data) | 252 | struct ethtool_stats *stats, uint64_t *data) |
245 | { | 253 | { |
246 | struct be_adapter *adapter = netdev_priv(netdev); | 254 | struct be_adapter *adapter = netdev_priv(netdev); |
247 | struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; | 255 | struct be_rx_obj *rxo; |
248 | struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); | ||
249 | struct be_rxf_stats *rxf_stats = &hw_stats->rxf; | ||
250 | struct be_port_rxf_stats *port_stats = | ||
251 | &rxf_stats->port[adapter->port_num]; | ||
252 | struct net_device_stats *net_stats = &netdev->stats; | ||
253 | struct be_erx_stats *erx_stats = &hw_stats->erx; | ||
254 | void *p = NULL; | 256 | void *p = NULL; |
255 | int i; | 257 | int i, j; |
256 | 258 | ||
257 | for (i = 0; i < ETHTOOL_STATS_NUM; i++) { | 259 | for (i = 0; i < ETHTOOL_STATS_NUM; i++) { |
258 | switch (et_stats[i].type) { | 260 | switch (et_stats[i].type) { |
259 | case NETSTAT: | 261 | case NETSTAT: |
260 | p = net_stats; | 262 | p = &netdev->stats; |
261 | break; | ||
262 | case DRVSTAT: | ||
263 | p = drvr_stats; | ||
264 | break; | 263 | break; |
265 | case PORTSTAT: | 264 | case DRVSTAT_TX: |
266 | p = port_stats; | 265 | p = &adapter->tx_stats; |
267 | break; | 266 | break; |
268 | case MISCSTAT: | 267 | case DRVSTAT: |
269 | p = rxf_stats; | 268 | p = &adapter->drv_stats; |
270 | break; | ||
271 | case ERXSTAT: /* Currently only one ERX stat is provided */ | ||
272 | p = (u32 *)erx_stats + adapter->rx_obj.q.id; | ||
273 | break; | 269 | break; |
274 | } | 270 | } |
275 | 271 | ||
@@ -277,19 +273,45 @@ be_get_ethtool_stats(struct net_device *netdev, | |||
277 | data[i] = (et_stats[i].size == sizeof(u64)) ? | 273 | data[i] = (et_stats[i].size == sizeof(u64)) ? |
278 | *(u64 *)p: *(u32 *)p; | 274 | *(u64 *)p: *(u32 *)p; |
279 | } | 275 | } |
276 | |||
277 | for_all_rx_queues(adapter, rxo, j) { | ||
278 | for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { | ||
279 | switch (et_rx_stats[i].type) { | ||
280 | case DRVSTAT_RX: | ||
281 | p = (u8 *)&rxo->stats + et_rx_stats[i].offset; | ||
282 | break; | ||
283 | case ERXSTAT: | ||
284 | p = (u32 *)be_erx_stats_from_cmd(adapter) + | ||
285 | rxo->q.id; | ||
286 | break; | ||
287 | } | ||
288 | data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = | ||
289 | (et_rx_stats[i].size == sizeof(u64)) ? | ||
290 | *(u64 *)p: *(u32 *)p; | ||
291 | } | ||
292 | } | ||
280 | } | 293 | } |
281 | 294 | ||
282 | static void | 295 | static void |
283 | be_get_stat_strings(struct net_device *netdev, uint32_t stringset, | 296 | be_get_stat_strings(struct net_device *netdev, uint32_t stringset, |
284 | uint8_t *data) | 297 | uint8_t *data) |
285 | { | 298 | { |
286 | int i; | 299 | struct be_adapter *adapter = netdev_priv(netdev); |
300 | int i, j; | ||
301 | |||
287 | switch (stringset) { | 302 | switch (stringset) { |
288 | case ETH_SS_STATS: | 303 | case ETH_SS_STATS: |
289 | for (i = 0; i < ETHTOOL_STATS_NUM; i++) { | 304 | for (i = 0; i < ETHTOOL_STATS_NUM; i++) { |
290 | memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); | 305 | memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); |
291 | data += ETH_GSTRING_LEN; | 306 | data += ETH_GSTRING_LEN; |
292 | } | 307 | } |
308 | for (i = 0; i < adapter->num_rx_qs; i++) { | ||
309 | for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) { | ||
310 | sprintf(data, "rxq%d: %s", i, | ||
311 | et_rx_stats[j].desc); | ||
312 | data += ETH_GSTRING_LEN; | ||
313 | } | ||
314 | } | ||
293 | break; | 315 | break; |
294 | case ETH_SS_TEST: | 316 | case ETH_SS_TEST: |
295 | for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { | 317 | for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { |
@@ -302,11 +324,14 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, | |||
302 | 324 | ||
303 | static int be_get_sset_count(struct net_device *netdev, int stringset) | 325 | static int be_get_sset_count(struct net_device *netdev, int stringset) |
304 | { | 326 | { |
327 | struct be_adapter *adapter = netdev_priv(netdev); | ||
328 | |||
305 | switch (stringset) { | 329 | switch (stringset) { |
306 | case ETH_SS_TEST: | 330 | case ETH_SS_TEST: |
307 | return ETHTOOL_TESTS_NUM; | 331 | return ETHTOOL_TESTS_NUM; |
308 | case ETH_SS_STATS: | 332 | case ETH_SS_STATS: |
309 | return ETHTOOL_STATS_NUM; | 333 | return ETHTOOL_STATS_NUM + |
334 | adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; | ||
310 | default: | 335 | default: |
311 | return -EINVAL; | 336 | return -EINVAL; |
312 | } | 337 | } |
@@ -325,26 +350,36 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
325 | 350 | ||
326 | if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { | 351 | if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { |
327 | status = be_cmd_link_status_query(adapter, &link_up, | 352 | status = be_cmd_link_status_query(adapter, &link_up, |
328 | &mac_speed, &link_speed); | 353 | &mac_speed, &link_speed, 0); |
329 | 354 | ||
330 | be_link_status_update(adapter, link_up); | 355 | be_link_status_update(adapter, link_up); |
331 | /* link_speed is in units of 10 Mbps */ | 356 | /* link_speed is in units of 10 Mbps */ |
332 | if (link_speed) { | 357 | if (link_speed) { |
333 | ecmd->speed = link_speed*10; | 358 | ethtool_cmd_speed_set(ecmd, link_speed*10); |
334 | } else { | 359 | } else { |
335 | switch (mac_speed) { | 360 | switch (mac_speed) { |
361 | case PHY_LINK_SPEED_10MBPS: | ||
362 | ethtool_cmd_speed_set(ecmd, SPEED_10); | ||
363 | break; | ||
364 | case PHY_LINK_SPEED_100MBPS: | ||
365 | ethtool_cmd_speed_set(ecmd, SPEED_100); | ||
366 | break; | ||
336 | case PHY_LINK_SPEED_1GBPS: | 367 | case PHY_LINK_SPEED_1GBPS: |
337 | ecmd->speed = SPEED_1000; | 368 | ethtool_cmd_speed_set(ecmd, SPEED_1000); |
338 | break; | 369 | break; |
339 | case PHY_LINK_SPEED_10GBPS: | 370 | case PHY_LINK_SPEED_10GBPS: |
340 | ecmd->speed = SPEED_10000; | 371 | ethtool_cmd_speed_set(ecmd, SPEED_10000); |
372 | break; | ||
373 | case PHY_LINK_SPEED_ZERO: | ||
374 | ethtool_cmd_speed_set(ecmd, 0); | ||
341 | break; | 375 | break; |
342 | } | 376 | } |
343 | } | 377 | } |
344 | 378 | ||
345 | phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info); | 379 | phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info); |
346 | phy_cmd.va = pci_alloc_consistent(adapter->pdev, phy_cmd.size, | 380 | phy_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, |
347 | &phy_cmd.dma); | 381 | phy_cmd.size, &phy_cmd.dma, |
382 | GFP_KERNEL); | ||
348 | if (!phy_cmd.va) { | 383 | if (!phy_cmd.va) { |
349 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | 384 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); |
350 | return -ENOMEM; | 385 | return -ENOMEM; |
@@ -379,14 +414,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
379 | } | 414 | } |
380 | 415 | ||
381 | /* Save for future use */ | 416 | /* Save for future use */ |
382 | adapter->link_speed = ecmd->speed; | 417 | adapter->link_speed = ethtool_cmd_speed(ecmd); |
383 | adapter->port_type = ecmd->port; | 418 | adapter->port_type = ecmd->port; |
384 | adapter->transceiver = ecmd->transceiver; | 419 | adapter->transceiver = ecmd->transceiver; |
385 | adapter->autoneg = ecmd->autoneg; | 420 | adapter->autoneg = ecmd->autoneg; |
386 | pci_free_consistent(adapter->pdev, phy_cmd.size, | 421 | dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va, |
387 | phy_cmd.va, phy_cmd.dma); | 422 | phy_cmd.dma); |
388 | } else { | 423 | } else { |
389 | ecmd->speed = adapter->link_speed; | 424 | ethtool_cmd_speed_set(ecmd, adapter->link_speed); |
390 | ecmd->port = adapter->port_type; | 425 | ecmd->port = adapter->port_type; |
391 | ecmd->transceiver = adapter->transceiver; | 426 | ecmd->transceiver = adapter->transceiver; |
392 | ecmd->autoneg = adapter->autoneg; | 427 | ecmd->autoneg = adapter->autoneg; |
@@ -421,10 +456,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) | |||
421 | { | 456 | { |
422 | struct be_adapter *adapter = netdev_priv(netdev); | 457 | struct be_adapter *adapter = netdev_priv(netdev); |
423 | 458 | ||
424 | ring->rx_max_pending = adapter->rx_obj.q.len; | 459 | ring->rx_max_pending = adapter->rx_obj[0].q.len; |
425 | ring->tx_max_pending = adapter->tx_obj.q.len; | 460 | ring->tx_max_pending = adapter->tx_obj.q.len; |
426 | 461 | ||
427 | ring->rx_pending = atomic_read(&adapter->rx_obj.q.used); | 462 | ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used); |
428 | ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); | 463 | ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); |
429 | } | 464 | } |
430 | 465 | ||
@@ -457,29 +492,42 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) | |||
457 | } | 492 | } |
458 | 493 | ||
459 | static int | 494 | static int |
460 | be_phys_id(struct net_device *netdev, u32 data) | 495 | be_set_phys_id(struct net_device *netdev, |
496 | enum ethtool_phys_id_state state) | ||
461 | { | 497 | { |
462 | struct be_adapter *adapter = netdev_priv(netdev); | 498 | struct be_adapter *adapter = netdev_priv(netdev); |
463 | int status; | ||
464 | u32 cur; | ||
465 | 499 | ||
466 | be_cmd_get_beacon_state(adapter, adapter->port_num, &cur); | 500 | switch (state) { |
501 | case ETHTOOL_ID_ACTIVE: | ||
502 | be_cmd_get_beacon_state(adapter, adapter->hba_port_num, | ||
503 | &adapter->beacon_state); | ||
504 | return 1; /* cycle on/off once per second */ | ||
467 | 505 | ||
468 | if (cur == BEACON_STATE_ENABLED) | 506 | case ETHTOOL_ID_ON: |
469 | return 0; | 507 | be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, |
508 | BEACON_STATE_ENABLED); | ||
509 | break; | ||
470 | 510 | ||
471 | if (data < 2) | 511 | case ETHTOOL_ID_OFF: |
472 | data = 2; | 512 | be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, |
513 | BEACON_STATE_DISABLED); | ||
514 | break; | ||
473 | 515 | ||
474 | status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, | 516 | case ETHTOOL_ID_INACTIVE: |
475 | BEACON_STATE_ENABLED); | 517 | be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, |
476 | set_current_state(TASK_INTERRUPTIBLE); | 518 | adapter->beacon_state); |
477 | schedule_timeout(data*HZ); | 519 | } |
478 | 520 | ||
479 | status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, | 521 | return 0; |
480 | BEACON_STATE_DISABLED); | 522 | } |
481 | 523 | ||
482 | return status; | 524 | static bool |
525 | be_is_wol_supported(struct be_adapter *adapter) | ||
526 | { | ||
527 | if (!be_physfn(adapter)) | ||
528 | return false; | ||
529 | else | ||
530 | return true; | ||
483 | } | 531 | } |
484 | 532 | ||
485 | static void | 533 | static void |
@@ -487,7 +535,9 @@ be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
487 | { | 535 | { |
488 | struct be_adapter *adapter = netdev_priv(netdev); | 536 | struct be_adapter *adapter = netdev_priv(netdev); |
489 | 537 | ||
490 | wol->supported = WAKE_MAGIC; | 538 | if (be_is_wol_supported(adapter)) |
539 | wol->supported = WAKE_MAGIC; | ||
540 | |||
491 | if (adapter->wol) | 541 | if (adapter->wol) |
492 | wol->wolopts = WAKE_MAGIC; | 542 | wol->wolopts = WAKE_MAGIC; |
493 | else | 543 | else |
@@ -503,7 +553,7 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
503 | if (wol->wolopts & ~WAKE_MAGIC) | 553 | if (wol->wolopts & ~WAKE_MAGIC) |
504 | return -EINVAL; | 554 | return -EINVAL; |
505 | 555 | ||
506 | if (wol->wolopts & WAKE_MAGIC) | 556 | if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter)) |
507 | adapter->wol = true; | 557 | adapter->wol = true; |
508 | else | 558 | else |
509 | adapter->wol = false; | 559 | adapter->wol = false; |
@@ -516,11 +566,13 @@ be_test_ddr_dma(struct be_adapter *adapter) | |||
516 | { | 566 | { |
517 | int ret, i; | 567 | int ret, i; |
518 | struct be_dma_mem ddrdma_cmd; | 568 | struct be_dma_mem ddrdma_cmd; |
519 | u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL}; | 569 | static const u64 pattern[2] = { |
570 | 0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL | ||
571 | }; | ||
520 | 572 | ||
521 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); | 573 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); |
522 | ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, | 574 | ddrdma_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, ddrdma_cmd.size, |
523 | &ddrdma_cmd.dma); | 575 | &ddrdma_cmd.dma, GFP_KERNEL); |
524 | if (!ddrdma_cmd.va) { | 576 | if (!ddrdma_cmd.va) { |
525 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); | 577 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); |
526 | return -ENOMEM; | 578 | return -ENOMEM; |
@@ -534,20 +586,20 @@ be_test_ddr_dma(struct be_adapter *adapter) | |||
534 | } | 586 | } |
535 | 587 | ||
536 | err: | 588 | err: |
537 | pci_free_consistent(adapter->pdev, ddrdma_cmd.size, | 589 | dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va, |
538 | ddrdma_cmd.va, ddrdma_cmd.dma); | 590 | ddrdma_cmd.dma); |
539 | return ret; | 591 | return ret; |
540 | } | 592 | } |
541 | 593 | ||
542 | static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, | 594 | static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, |
543 | u64 *status) | 595 | u64 *status) |
544 | { | 596 | { |
545 | be_cmd_set_loopback(adapter, adapter->port_num, | 597 | be_cmd_set_loopback(adapter, adapter->hba_port_num, |
546 | loopback_type, 1); | 598 | loopback_type, 1); |
547 | *status = be_cmd_loopback_test(adapter, adapter->port_num, | 599 | *status = be_cmd_loopback_test(adapter, adapter->hba_port_num, |
548 | loopback_type, 1500, | 600 | loopback_type, 1500, |
549 | 2, 0xabc); | 601 | 2, 0xabc); |
550 | be_cmd_set_loopback(adapter, adapter->port_num, | 602 | be_cmd_set_loopback(adapter, adapter->hba_port_num, |
551 | BE_NO_LOOPBACK, 1); | 603 | BE_NO_LOOPBACK, 1); |
552 | return *status; | 604 | return *status; |
553 | } | 605 | } |
@@ -583,10 +635,11 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | |||
583 | } | 635 | } |
584 | 636 | ||
585 | if (be_cmd_link_status_query(adapter, &link_up, &mac_speed, | 637 | if (be_cmd_link_status_query(adapter, &link_up, &mac_speed, |
586 | &qos_link_speed) != 0) { | 638 | &qos_link_speed, 0) != 0) { |
587 | test->flags |= ETH_TEST_FL_FAILED; | 639 | test->flags |= ETH_TEST_FL_FAILED; |
588 | data[4] = -1; | 640 | data[4] = -1; |
589 | } else if (mac_speed) { | 641 | } else if (!mac_speed) { |
642 | test->flags |= ETH_TEST_FL_FAILED; | ||
590 | data[4] = 1; | 643 | data[4] = 1; |
591 | } | 644 | } |
592 | } | 645 | } |
@@ -596,11 +649,9 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) | |||
596 | { | 649 | { |
597 | struct be_adapter *adapter = netdev_priv(netdev); | 650 | struct be_adapter *adapter = netdev_priv(netdev); |
598 | char file_name[ETHTOOL_FLASH_MAX_FILENAME]; | 651 | char file_name[ETHTOOL_FLASH_MAX_FILENAME]; |
599 | u32 region; | ||
600 | 652 | ||
601 | file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0; | 653 | file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0; |
602 | strcpy(file_name, efl->data); | 654 | strcpy(file_name, efl->data); |
603 | region = efl->region; | ||
604 | 655 | ||
605 | return be_load_fw(adapter, file_name); | 656 | return be_load_fw(adapter, file_name); |
606 | } | 657 | } |
@@ -627,8 +678,8 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | |||
627 | 678 | ||
628 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); | 679 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); |
629 | eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); | 680 | eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); |
630 | eeprom_cmd.va = pci_alloc_consistent(adapter->pdev, eeprom_cmd.size, | 681 | eeprom_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, eeprom_cmd.size, |
631 | &eeprom_cmd.dma); | 682 | &eeprom_cmd.dma, GFP_KERNEL); |
632 | 683 | ||
633 | if (!eeprom_cmd.va) { | 684 | if (!eeprom_cmd.va) { |
634 | dev_err(&adapter->pdev->dev, | 685 | dev_err(&adapter->pdev->dev, |
@@ -642,8 +693,8 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | |||
642 | resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va; | 693 | resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va; |
643 | memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len); | 694 | memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len); |
644 | } | 695 | } |
645 | pci_free_consistent(adapter->pdev, eeprom_cmd.size, eeprom_cmd.va, | 696 | dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va, |
646 | eeprom_cmd.dma); | 697 | eeprom_cmd.dma); |
647 | 698 | ||
648 | return status; | 699 | return status; |
649 | } | 700 | } |
@@ -661,18 +712,12 @@ const struct ethtool_ops be_ethtool_ops = { | |||
661 | .get_ringparam = be_get_ringparam, | 712 | .get_ringparam = be_get_ringparam, |
662 | .get_pauseparam = be_get_pauseparam, | 713 | .get_pauseparam = be_get_pauseparam, |
663 | .set_pauseparam = be_set_pauseparam, | 714 | .set_pauseparam = be_set_pauseparam, |
664 | .get_rx_csum = be_get_rx_csum, | ||
665 | .set_rx_csum = be_set_rx_csum, | ||
666 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
667 | .set_tx_csum = ethtool_op_set_tx_hw_csum, | ||
668 | .get_sg = ethtool_op_get_sg, | ||
669 | .set_sg = ethtool_op_set_sg, | ||
670 | .get_tso = ethtool_op_get_tso, | ||
671 | .set_tso = ethtool_op_set_tso, | ||
672 | .get_strings = be_get_stat_strings, | 715 | .get_strings = be_get_stat_strings, |
673 | .phys_id = be_phys_id, | 716 | .set_phys_id = be_set_phys_id, |
674 | .get_sset_count = be_get_sset_count, | 717 | .get_sset_count = be_get_sset_count, |
675 | .get_ethtool_stats = be_get_ethtool_stats, | 718 | .get_ethtool_stats = be_get_ethtool_stats, |
719 | .get_regs_len = be_get_reg_len, | ||
720 | .get_regs = be_get_regs, | ||
676 | .flash_device = be_do_flash, | 721 | .flash_device = be_do_flash, |
677 | .self_test = be_self_test, | 722 | .self_test = be_self_test, |
678 | }; | 723 | }; |
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index a2ec5df0d733..53d658afea2a 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,11 +8,11 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | /********* Mailbox door bell *************/ | 18 | /********* Mailbox door bell *************/ |
@@ -32,16 +32,30 @@ | |||
32 | #define MPU_EP_CONTROL 0 | 32 | #define MPU_EP_CONTROL 0 |
33 | 33 | ||
34 | /********** MPU semphore ******************/ | 34 | /********** MPU semphore ******************/ |
35 | #define MPU_EP_SEMAPHORE_OFFSET 0xac | 35 | #define MPU_EP_SEMAPHORE_OFFSET 0xac |
36 | #define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF | 36 | #define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400 |
37 | #define EP_SEMAPHORE_POST_ERR_MASK 0x1 | 37 | #define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF |
38 | #define EP_SEMAPHORE_POST_ERR_SHIFT 31 | 38 | #define EP_SEMAPHORE_POST_ERR_MASK 0x1 |
39 | #define EP_SEMAPHORE_POST_ERR_SHIFT 31 | ||
40 | |||
39 | /* MPU semphore POST stage values */ | 41 | /* MPU semphore POST stage values */ |
40 | #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ | 42 | #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ |
41 | #define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ | 43 | #define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ |
42 | #define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ | 44 | #define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ |
43 | #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ | 45 | #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ |
44 | 46 | ||
47 | |||
48 | /* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */ | ||
49 | #define SLIPORT_STATUS_OFFSET 0x404 | ||
50 | #define SLIPORT_CONTROL_OFFSET 0x408 | ||
51 | |||
52 | #define SLIPORT_STATUS_ERR_MASK 0x80000000 | ||
53 | #define SLIPORT_STATUS_RN_MASK 0x01000000 | ||
54 | #define SLIPORT_STATUS_RDY_MASK 0x00800000 | ||
55 | |||
56 | |||
57 | #define SLI_PORT_CONTROL_IP_MASK 0x08000000 | ||
58 | |||
45 | /********* Memory BAR register ************/ | 59 | /********* Memory BAR register ************/ |
46 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 60 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
47 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt | 61 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt |
@@ -66,6 +80,28 @@ | |||
66 | #define PCICFG_UE_STATUS_LOW_MASK 0xA8 | 80 | #define PCICFG_UE_STATUS_LOW_MASK 0xA8 |
67 | #define PCICFG_UE_STATUS_HI_MASK 0xAC | 81 | #define PCICFG_UE_STATUS_HI_MASK 0xAC |
68 | 82 | ||
83 | /******** SLI_INTF ***********************/ | ||
84 | #define SLI_INTF_REG_OFFSET 0x58 | ||
85 | #define SLI_INTF_VALID_MASK 0xE0000000 | ||
86 | #define SLI_INTF_VALID 0xC0000000 | ||
87 | #define SLI_INTF_HINT2_MASK 0x1F000000 | ||
88 | #define SLI_INTF_HINT2_SHIFT 24 | ||
89 | #define SLI_INTF_HINT1_MASK 0x00FF0000 | ||
90 | #define SLI_INTF_HINT1_SHIFT 16 | ||
91 | #define SLI_INTF_FAMILY_MASK 0x00000F00 | ||
92 | #define SLI_INTF_FAMILY_SHIFT 8 | ||
93 | #define SLI_INTF_IF_TYPE_MASK 0x0000F000 | ||
94 | #define SLI_INTF_IF_TYPE_SHIFT 12 | ||
95 | #define SLI_INTF_REV_MASK 0x000000F0 | ||
96 | #define SLI_INTF_REV_SHIFT 4 | ||
97 | #define SLI_INTF_FT_MASK 0x00000001 | ||
98 | |||
99 | |||
100 | /* SLI family */ | ||
101 | #define BE_SLI_FAMILY 0x0 | ||
102 | #define LANCER_A0_SLI_FAMILY 0xA | ||
103 | |||
104 | |||
69 | /********* ISR0 Register offset **********/ | 105 | /********* ISR0 Register offset **********/ |
70 | #define CEV_ISR0_OFFSET 0xC18 | 106 | #define CEV_ISR0_OFFSET 0xC18 |
71 | #define CEV_ISR_SIZE 4 | 107 | #define CEV_ISR_SIZE 4 |
@@ -73,6 +109,9 @@ | |||
73 | /********* Event Q door bell *************/ | 109 | /********* Event Q door bell *************/ |
74 | #define DB_EQ_OFFSET DB_CQ_OFFSET | 110 | #define DB_EQ_OFFSET DB_CQ_OFFSET |
75 | #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ | 111 | #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ |
112 | #define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */ | ||
113 | #define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */ | ||
114 | |||
76 | /* Clear the interrupt for this eq */ | 115 | /* Clear the interrupt for this eq */ |
77 | #define DB_EQ_CLR_SHIFT (9) /* bit 9 */ | 116 | #define DB_EQ_CLR_SHIFT (9) /* bit 9 */ |
78 | /* Must be 1 */ | 117 | /* Must be 1 */ |
@@ -85,6 +124,10 @@ | |||
85 | /********* Compl Q door bell *************/ | 124 | /********* Compl Q door bell *************/ |
86 | #define DB_CQ_OFFSET 0x120 | 125 | #define DB_CQ_OFFSET 0x120 |
87 | #define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ | 126 | #define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ |
127 | #define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */ | ||
128 | #define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14 | ||
129 | placing at 11-15 */ | ||
130 | |||
88 | /* Number of event entries processed */ | 131 | /* Number of event entries processed */ |
89 | #define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ | 132 | #define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ |
90 | /* Rearm bit */ | 133 | /* Rearm bit */ |
@@ -112,6 +155,10 @@ | |||
112 | /********** SRIOV VF PCICFG OFFSET ********/ | 155 | /********** SRIOV VF PCICFG OFFSET ********/ |
113 | #define SRIOV_VF_PCICFG_OFFSET (4096) | 156 | #define SRIOV_VF_PCICFG_OFFSET (4096) |
114 | 157 | ||
158 | /********** FAT TABLE ********/ | ||
159 | #define RETRIEVE_FAT 0 | ||
160 | #define QUERY_FAT 1 | ||
161 | |||
115 | /* Flashrom related descriptors */ | 162 | /* Flashrom related descriptors */ |
116 | #define IMAGE_TYPE_FIRMWARE 160 | 163 | #define IMAGE_TYPE_FIRMWARE 160 |
117 | #define IMAGE_TYPE_BOOTCODE 224 | 164 | #define IMAGE_TYPE_BOOTCODE 224 |
@@ -258,10 +305,10 @@ struct be_eth_rx_d { | |||
258 | 305 | ||
259 | /* RX Compl Queue Descriptor */ | 306 | /* RX Compl Queue Descriptor */ |
260 | 307 | ||
261 | /* Pseudo amap definition for eth_rx_compl in which each bit of the | 308 | /* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which |
262 | * actual structure is defined as a byte: used to calculate | 309 | * each bit of the actual structure is defined as a byte: used to calculate |
263 | * offset/shift/mask of each field */ | 310 | * offset/shift/mask of each field */ |
264 | struct amap_eth_rx_compl { | 311 | struct amap_eth_rx_compl_v0 { |
265 | u8 vlan_tag[16]; /* dword 0 */ | 312 | u8 vlan_tag[16]; /* dword 0 */ |
266 | u8 pktsize[14]; /* dword 0 */ | 313 | u8 pktsize[14]; /* dword 0 */ |
267 | u8 port; /* dword 0 */ | 314 | u8 port; /* dword 0 */ |
@@ -292,10 +339,92 @@ struct amap_eth_rx_compl { | |||
292 | u8 rsshash[32]; /* dword 3 */ | 339 | u8 rsshash[32]; /* dword 3 */ |
293 | } __packed; | 340 | } __packed; |
294 | 341 | ||
342 | /* Pseudo amap definition for BE3 native mode eth_rx_compl in which | ||
343 | * each bit of the actual structure is defined as a byte: used to calculate | ||
344 | * offset/shift/mask of each field */ | ||
345 | struct amap_eth_rx_compl_v1 { | ||
346 | u8 vlan_tag[16]; /* dword 0 */ | ||
347 | u8 pktsize[14]; /* dword 0 */ | ||
348 | u8 vtp; /* dword 0 */ | ||
349 | u8 ip_opt; /* dword 0 */ | ||
350 | u8 err; /* dword 1 */ | ||
351 | u8 rsshp; /* dword 1 */ | ||
352 | u8 ipf; /* dword 1 */ | ||
353 | u8 tcpf; /* dword 1 */ | ||
354 | u8 udpf; /* dword 1 */ | ||
355 | u8 ipcksm; /* dword 1 */ | ||
356 | u8 l4_cksm; /* dword 1 */ | ||
357 | u8 ip_version; /* dword 1 */ | ||
358 | u8 macdst[7]; /* dword 1 */ | ||
359 | u8 rsvd0; /* dword 1 */ | ||
360 | u8 fragndx[10]; /* dword 1 */ | ||
361 | u8 ct[2]; /* dword 1 */ | ||
362 | u8 sw; /* dword 1 */ | ||
363 | u8 numfrags[3]; /* dword 1 */ | ||
364 | u8 rss_flush; /* dword 2 */ | ||
365 | u8 cast_enc[2]; /* dword 2 */ | ||
366 | u8 vtm; /* dword 2 */ | ||
367 | u8 rss_bank; /* dword 2 */ | ||
368 | u8 port[2]; /* dword 2 */ | ||
369 | u8 vntagp; /* dword 2 */ | ||
370 | u8 header_len[8]; /* dword 2 */ | ||
371 | u8 header_split[2]; /* dword 2 */ | ||
372 | u8 rsvd1[13]; /* dword 2 */ | ||
373 | u8 valid; /* dword 2 */ | ||
374 | u8 rsshash[32]; /* dword 3 */ | ||
375 | } __packed; | ||
376 | |||
295 | struct be_eth_rx_compl { | 377 | struct be_eth_rx_compl { |
296 | u32 dw[4]; | 378 | u32 dw[4]; |
297 | }; | 379 | }; |
298 | 380 | ||
381 | struct mgmt_hba_attribs { | ||
382 | u8 flashrom_version_string[32]; | ||
383 | u8 manufacturer_name[32]; | ||
384 | u32 supported_modes; | ||
385 | u32 rsvd0[3]; | ||
386 | u8 ncsi_ver_string[12]; | ||
387 | u32 default_extended_timeout; | ||
388 | u8 controller_model_number[32]; | ||
389 | u8 controller_description[64]; | ||
390 | u8 controller_serial_number[32]; | ||
391 | u8 ip_version_string[32]; | ||
392 | u8 firmware_version_string[32]; | ||
393 | u8 bios_version_string[32]; | ||
394 | u8 redboot_version_string[32]; | ||
395 | u8 driver_version_string[32]; | ||
396 | u8 fw_on_flash_version_string[32]; | ||
397 | u32 functionalities_supported; | ||
398 | u16 max_cdblength; | ||
399 | u8 asic_revision; | ||
400 | u8 generational_guid[16]; | ||
401 | u8 hba_port_count; | ||
402 | u16 default_link_down_timeout; | ||
403 | u8 iscsi_ver_min_max; | ||
404 | u8 multifunction_device; | ||
405 | u8 cache_valid; | ||
406 | u8 hba_status; | ||
407 | u8 max_domains_supported; | ||
408 | u8 phy_port; | ||
409 | u32 firmware_post_status; | ||
410 | u32 hba_mtu[8]; | ||
411 | u32 rsvd1[4]; | ||
412 | }; | ||
413 | |||
414 | struct mgmt_controller_attrib { | ||
415 | struct mgmt_hba_attribs hba_attribs; | ||
416 | u16 pci_vendor_id; | ||
417 | u16 pci_device_id; | ||
418 | u16 pci_sub_vendor_id; | ||
419 | u16 pci_sub_system_id; | ||
420 | u8 pci_bus_number; | ||
421 | u8 pci_device_number; | ||
422 | u8 pci_function_number; | ||
423 | u8 interface_type; | ||
424 | u64 unique_identifier; | ||
425 | u32 rsvd0[5]; | ||
426 | }; | ||
427 | |||
299 | struct controller_id { | 428 | struct controller_id { |
300 | u32 vendor; | 429 | u32 vendor; |
301 | u32 device; | 430 | u32 device; |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6eda7a022256..a485f7fdaf37 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005 - 2010 ServerEngines | 2 | * Copyright (C) 2005 - 2011 Emulex |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -8,13 +8,14 @@ | |||
8 | * Public License is included in this distribution in the file called COPYING. | 8 | * Public License is included in this distribution in the file called COPYING. |
9 | * | 9 | * |
10 | * Contact Information: | 10 | * Contact Information: |
11 | * linux-drivers@serverengines.com | 11 | * linux-drivers@emulex.com |
12 | * | 12 | * |
13 | * ServerEngines | 13 | * Emulex |
14 | * 209 N. Fair Oaks Ave | 14 | * 3333 Susan Street |
15 | * Sunnyvale, CA 94085 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/prefetch.h> | ||
18 | #include "be.h" | 19 | #include "be.h" |
19 | #include "be_cmds.h" | 20 | #include "be_cmds.h" |
20 | #include <asm/div64.h> | 21 | #include <asm/div64.h> |
@@ -25,18 +26,24 @@ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); | |||
25 | MODULE_AUTHOR("ServerEngines Corporation"); | 26 | MODULE_AUTHOR("ServerEngines Corporation"); |
26 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
27 | 28 | ||
28 | static unsigned int rx_frag_size = 2048; | 29 | static ushort rx_frag_size = 2048; |
29 | static unsigned int num_vfs; | 30 | static unsigned int num_vfs; |
30 | module_param(rx_frag_size, uint, S_IRUGO); | 31 | module_param(rx_frag_size, ushort, S_IRUGO); |
31 | module_param(num_vfs, uint, S_IRUGO); | 32 | module_param(num_vfs, uint, S_IRUGO); |
32 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); | 33 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); |
33 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); | 34 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); |
34 | 35 | ||
36 | static bool multi_rxq = true; | ||
37 | module_param(multi_rxq, bool, S_IRUGO | S_IWUSR); | ||
38 | MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default"); | ||
39 | |||
35 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | 40 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { |
36 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 41 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
37 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, | 42 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, |
38 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, | 43 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, |
39 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, | 44 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, |
45 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, | ||
46 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)}, | ||
40 | { 0 } | 47 | { 0 } |
41 | }; | 48 | }; |
42 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 49 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
@@ -115,8 +122,8 @@ static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) | |||
115 | { | 122 | { |
116 | struct be_dma_mem *mem = &q->dma_mem; | 123 | struct be_dma_mem *mem = &q->dma_mem; |
117 | if (mem->va) | 124 | if (mem->va) |
118 | pci_free_consistent(adapter->pdev, mem->size, | 125 | dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, |
119 | mem->va, mem->dma); | 126 | mem->dma); |
120 | } | 127 | } |
121 | 128 | ||
122 | static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, | 129 | static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, |
@@ -128,7 +135,8 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, | |||
128 | q->len = len; | 135 | q->len = len; |
129 | q->entry_size = entry_size; | 136 | q->entry_size = entry_size; |
130 | mem->size = len * entry_size; | 137 | mem->size = len * entry_size; |
131 | mem->va = pci_alloc_consistent(adapter->pdev, mem->size, &mem->dma); | 138 | mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma, |
139 | GFP_KERNEL); | ||
132 | if (!mem->va) | 140 | if (!mem->va) |
133 | return -1; | 141 | return -1; |
134 | memset(mem->va, 0, mem->size); | 142 | memset(mem->va, 0, mem->size); |
@@ -179,6 +187,8 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid, | |||
179 | { | 187 | { |
180 | u32 val = 0; | 188 | u32 val = 0; |
181 | val |= qid & DB_EQ_RING_ID_MASK; | 189 | val |= qid & DB_EQ_RING_ID_MASK; |
190 | val |= ((qid & DB_EQ_RING_ID_EXT_MASK) << | ||
191 | DB_EQ_RING_ID_EXT_MASK_SHIFT); | ||
182 | 192 | ||
183 | if (adapter->eeh_err) | 193 | if (adapter->eeh_err) |
184 | return; | 194 | return; |
@@ -196,6 +206,8 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped) | |||
196 | { | 206 | { |
197 | u32 val = 0; | 207 | u32 val = 0; |
198 | val |= qid & DB_CQ_RING_ID_MASK; | 208 | val |= qid & DB_CQ_RING_ID_MASK; |
209 | val |= ((qid & DB_CQ_RING_ID_EXT_MASK) << | ||
210 | DB_CQ_RING_ID_EXT_MASK_SHIFT); | ||
199 | 211 | ||
200 | if (adapter->eeh_err) | 212 | if (adapter->eeh_err) |
201 | return; | 213 | return; |
@@ -221,12 +233,13 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) | |||
221 | if (!be_physfn(adapter)) | 233 | if (!be_physfn(adapter)) |
222 | goto netdev_addr; | 234 | goto netdev_addr; |
223 | 235 | ||
224 | status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); | 236 | status = be_cmd_pmac_del(adapter, adapter->if_handle, |
237 | adapter->pmac_id, 0); | ||
225 | if (status) | 238 | if (status) |
226 | return status; | 239 | return status; |
227 | 240 | ||
228 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, | 241 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, |
229 | adapter->if_handle, &adapter->pmac_id); | 242 | adapter->if_handle, &adapter->pmac_id, 0); |
230 | netdev_addr: | 243 | netdev_addr: |
231 | if (!status) | 244 | if (!status) |
232 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 245 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
@@ -234,75 +247,242 @@ netdev_addr: | |||
234 | return status; | 247 | return status; |
235 | } | 248 | } |
236 | 249 | ||
250 | static void populate_be2_stats(struct be_adapter *adapter) | ||
251 | { | ||
252 | |||
253 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
254 | struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); | ||
255 | struct be_port_rxf_stats_v0 *port_stats = | ||
256 | be_port_rxf_stats_from_cmd(adapter); | ||
257 | struct be_rxf_stats_v0 *rxf_stats = | ||
258 | be_rxf_stats_from_cmd(adapter); | ||
259 | |||
260 | drvs->rx_pause_frames = port_stats->rx_pause_frames; | ||
261 | drvs->rx_crc_errors = port_stats->rx_crc_errors; | ||
262 | drvs->rx_control_frames = port_stats->rx_control_frames; | ||
263 | drvs->rx_in_range_errors = port_stats->rx_in_range_errors; | ||
264 | drvs->rx_frame_too_long = port_stats->rx_frame_too_long; | ||
265 | drvs->rx_dropped_runt = port_stats->rx_dropped_runt; | ||
266 | drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; | ||
267 | drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; | ||
268 | drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; | ||
269 | drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow; | ||
270 | drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; | ||
271 | drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; | ||
272 | drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; | ||
273 | drvs->rx_out_range_errors = port_stats->rx_out_range_errors; | ||
274 | drvs->rx_input_fifo_overflow_drop = | ||
275 | port_stats->rx_input_fifo_overflow; | ||
276 | drvs->rx_dropped_header_too_small = | ||
277 | port_stats->rx_dropped_header_too_small; | ||
278 | drvs->rx_address_match_errors = | ||
279 | port_stats->rx_address_match_errors; | ||
280 | drvs->rx_alignment_symbol_errors = | ||
281 | port_stats->rx_alignment_symbol_errors; | ||
282 | |||
283 | drvs->tx_pauseframes = port_stats->tx_pauseframes; | ||
284 | drvs->tx_controlframes = port_stats->tx_controlframes; | ||
285 | |||
286 | if (adapter->port_num) | ||
287 | drvs->jabber_events = | ||
288 | rxf_stats->port1_jabber_events; | ||
289 | else | ||
290 | drvs->jabber_events = | ||
291 | rxf_stats->port0_jabber_events; | ||
292 | drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; | ||
293 | drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; | ||
294 | drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; | ||
295 | drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; | ||
296 | drvs->forwarded_packets = rxf_stats->forwarded_packets; | ||
297 | drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; | ||
298 | drvs->rx_drops_no_tpre_descr = | ||
299 | rxf_stats->rx_drops_no_tpre_descr; | ||
300 | drvs->rx_drops_too_many_frags = | ||
301 | rxf_stats->rx_drops_too_many_frags; | ||
302 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; | ||
303 | } | ||
304 | |||
305 | static void populate_be3_stats(struct be_adapter *adapter) | ||
306 | { | ||
307 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
308 | struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); | ||
309 | |||
310 | struct be_rxf_stats_v1 *rxf_stats = | ||
311 | be_rxf_stats_from_cmd(adapter); | ||
312 | struct be_port_rxf_stats_v1 *port_stats = | ||
313 | be_port_rxf_stats_from_cmd(adapter); | ||
314 | |||
315 | drvs->rx_priority_pause_frames = 0; | ||
316 | drvs->pmem_fifo_overflow_drop = 0; | ||
317 | drvs->rx_pause_frames = port_stats->rx_pause_frames; | ||
318 | drvs->rx_crc_errors = port_stats->rx_crc_errors; | ||
319 | drvs->rx_control_frames = port_stats->rx_control_frames; | ||
320 | drvs->rx_in_range_errors = port_stats->rx_in_range_errors; | ||
321 | drvs->rx_frame_too_long = port_stats->rx_frame_too_long; | ||
322 | drvs->rx_dropped_runt = port_stats->rx_dropped_runt; | ||
323 | drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; | ||
324 | drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; | ||
325 | drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; | ||
326 | drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; | ||
327 | drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; | ||
328 | drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; | ||
329 | drvs->rx_out_range_errors = port_stats->rx_out_range_errors; | ||
330 | drvs->rx_dropped_header_too_small = | ||
331 | port_stats->rx_dropped_header_too_small; | ||
332 | drvs->rx_input_fifo_overflow_drop = | ||
333 | port_stats->rx_input_fifo_overflow_drop; | ||
334 | drvs->rx_address_match_errors = | ||
335 | port_stats->rx_address_match_errors; | ||
336 | drvs->rx_alignment_symbol_errors = | ||
337 | port_stats->rx_alignment_symbol_errors; | ||
338 | drvs->rxpp_fifo_overflow_drop = | ||
339 | port_stats->rxpp_fifo_overflow_drop; | ||
340 | drvs->tx_pauseframes = port_stats->tx_pauseframes; | ||
341 | drvs->tx_controlframes = port_stats->tx_controlframes; | ||
342 | drvs->jabber_events = port_stats->jabber_events; | ||
343 | drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; | ||
344 | drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; | ||
345 | drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; | ||
346 | drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; | ||
347 | drvs->forwarded_packets = rxf_stats->forwarded_packets; | ||
348 | drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; | ||
349 | drvs->rx_drops_no_tpre_descr = | ||
350 | rxf_stats->rx_drops_no_tpre_descr; | ||
351 | drvs->rx_drops_too_many_frags = | ||
352 | rxf_stats->rx_drops_too_many_frags; | ||
353 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; | ||
354 | } | ||
355 | |||
356 | static void populate_lancer_stats(struct be_adapter *adapter) | ||
357 | { | ||
358 | |||
359 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
360 | struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd | ||
361 | (adapter); | ||
362 | drvs->rx_priority_pause_frames = 0; | ||
363 | drvs->pmem_fifo_overflow_drop = 0; | ||
364 | drvs->rx_pause_frames = | ||
365 | make_64bit_val(pport_stats->rx_pause_frames_lo, | ||
366 | pport_stats->rx_pause_frames_hi); | ||
367 | drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi, | ||
368 | pport_stats->rx_crc_errors_lo); | ||
369 | drvs->rx_control_frames = | ||
370 | make_64bit_val(pport_stats->rx_control_frames_hi, | ||
371 | pport_stats->rx_control_frames_lo); | ||
372 | drvs->rx_in_range_errors = pport_stats->rx_in_range_errors; | ||
373 | drvs->rx_frame_too_long = | ||
374 | make_64bit_val(pport_stats->rx_internal_mac_errors_hi, | ||
375 | pport_stats->rx_frames_too_long_lo); | ||
376 | drvs->rx_dropped_runt = pport_stats->rx_dropped_runt; | ||
377 | drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors; | ||
378 | drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors; | ||
379 | drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors; | ||
380 | drvs->rx_dropped_tcp_length = | ||
381 | pport_stats->rx_dropped_invalid_tcp_length; | ||
382 | drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small; | ||
383 | drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short; | ||
384 | drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors; | ||
385 | drvs->rx_dropped_header_too_small = | ||
386 | pport_stats->rx_dropped_header_too_small; | ||
387 | drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; | ||
388 | drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; | ||
389 | drvs->rx_alignment_symbol_errors = | ||
390 | make_64bit_val(pport_stats->rx_symbol_errors_hi, | ||
391 | pport_stats->rx_symbol_errors_lo); | ||
392 | drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; | ||
393 | drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi, | ||
394 | pport_stats->tx_pause_frames_lo); | ||
395 | drvs->tx_controlframes = | ||
396 | make_64bit_val(pport_stats->tx_control_frames_hi, | ||
397 | pport_stats->tx_control_frames_lo); | ||
398 | drvs->jabber_events = pport_stats->rx_jabbers; | ||
399 | drvs->rx_drops_no_pbuf = 0; | ||
400 | drvs->rx_drops_no_txpb = 0; | ||
401 | drvs->rx_drops_no_erx_descr = 0; | ||
402 | drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; | ||
403 | drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi, | ||
404 | pport_stats->num_forwards_lo); | ||
405 | drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi, | ||
406 | pport_stats->rx_drops_mtu_lo); | ||
407 | drvs->rx_drops_no_tpre_descr = 0; | ||
408 | drvs->rx_drops_too_many_frags = | ||
409 | make_64bit_val(pport_stats->rx_drops_too_many_frags_hi, | ||
410 | pport_stats->rx_drops_too_many_frags_lo); | ||
411 | } | ||
412 | |||
413 | void be_parse_stats(struct be_adapter *adapter) | ||
414 | { | ||
415 | if (adapter->generation == BE_GEN3) { | ||
416 | if (lancer_chip(adapter)) | ||
417 | populate_lancer_stats(adapter); | ||
418 | else | ||
419 | populate_be3_stats(adapter); | ||
420 | } else { | ||
421 | populate_be2_stats(adapter); | ||
422 | } | ||
423 | } | ||
424 | |||
237 | void netdev_stats_update(struct be_adapter *adapter) | 425 | void netdev_stats_update(struct be_adapter *adapter) |
238 | { | 426 | { |
239 | struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); | 427 | struct be_drv_stats *drvs = &adapter->drv_stats; |
240 | struct be_rxf_stats *rxf_stats = &hw_stats->rxf; | ||
241 | struct be_port_rxf_stats *port_stats = | ||
242 | &rxf_stats->port[adapter->port_num]; | ||
243 | struct net_device_stats *dev_stats = &adapter->netdev->stats; | 428 | struct net_device_stats *dev_stats = &adapter->netdev->stats; |
244 | struct be_erx_stats *erx_stats = &hw_stats->erx; | 429 | struct be_rx_obj *rxo; |
430 | int i; | ||
431 | |||
432 | memset(dev_stats, 0, sizeof(*dev_stats)); | ||
433 | for_all_rx_queues(adapter, rxo, i) { | ||
434 | dev_stats->rx_packets += rx_stats(rxo)->rx_pkts; | ||
435 | dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; | ||
436 | dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; | ||
437 | /* no space in linux buffers: best possible approximation */ | ||
438 | if (adapter->generation == BE_GEN3) { | ||
439 | if (!(lancer_chip(adapter))) { | ||
440 | struct be_erx_stats_v1 *erx_stats = | ||
441 | be_erx_stats_from_cmd(adapter); | ||
442 | dev_stats->rx_dropped += | ||
443 | erx_stats->rx_drops_no_fragments[rxo->q.id]; | ||
444 | } | ||
445 | } else { | ||
446 | struct be_erx_stats_v0 *erx_stats = | ||
447 | be_erx_stats_from_cmd(adapter); | ||
448 | dev_stats->rx_dropped += | ||
449 | erx_stats->rx_drops_no_fragments[rxo->q.id]; | ||
450 | } | ||
451 | } | ||
245 | 452 | ||
246 | dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts; | 453 | dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; |
247 | dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; | 454 | dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; |
248 | dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; | ||
249 | dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; | ||
250 | dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt; | ||
251 | 455 | ||
252 | /* bad pkts received */ | 456 | /* bad pkts received */ |
253 | dev_stats->rx_errors = port_stats->rx_crc_errors + | 457 | dev_stats->rx_errors = drvs->rx_crc_errors + |
254 | port_stats->rx_alignment_symbol_errors + | 458 | drvs->rx_alignment_symbol_errors + |
255 | port_stats->rx_in_range_errors + | 459 | drvs->rx_in_range_errors + |
256 | port_stats->rx_out_range_errors + | 460 | drvs->rx_out_range_errors + |
257 | port_stats->rx_frame_too_long + | 461 | drvs->rx_frame_too_long + |
258 | port_stats->rx_dropped_too_small + | 462 | drvs->rx_dropped_too_small + |
259 | port_stats->rx_dropped_too_short + | 463 | drvs->rx_dropped_too_short + |
260 | port_stats->rx_dropped_header_too_small + | 464 | drvs->rx_dropped_header_too_small + |
261 | port_stats->rx_dropped_tcp_length + | 465 | drvs->rx_dropped_tcp_length + |
262 | port_stats->rx_dropped_runt + | 466 | drvs->rx_dropped_runt + |
263 | port_stats->rx_tcp_checksum_errs + | 467 | drvs->rx_tcp_checksum_errs + |
264 | port_stats->rx_ip_checksum_errs + | 468 | drvs->rx_ip_checksum_errs + |
265 | port_stats->rx_udp_checksum_errs; | 469 | drvs->rx_udp_checksum_errs; |
266 | |||
267 | /* no space in linux buffers: best possible approximation */ | ||
268 | dev_stats->rx_dropped = | ||
269 | erx_stats->rx_drops_no_fragments[adapter->rx_obj.q.id]; | ||
270 | 470 | ||
271 | /* detailed rx errors */ | 471 | /* detailed rx errors */ |
272 | dev_stats->rx_length_errors = port_stats->rx_in_range_errors + | 472 | dev_stats->rx_length_errors = drvs->rx_in_range_errors + |
273 | port_stats->rx_out_range_errors + | 473 | drvs->rx_out_range_errors + |
274 | port_stats->rx_frame_too_long; | 474 | drvs->rx_frame_too_long; |
275 | |||
276 | /* receive ring buffer overflow */ | ||
277 | dev_stats->rx_over_errors = 0; | ||
278 | 475 | ||
279 | dev_stats->rx_crc_errors = port_stats->rx_crc_errors; | 476 | dev_stats->rx_crc_errors = drvs->rx_crc_errors; |
280 | 477 | ||
281 | /* frame alignment errors */ | 478 | /* frame alignment errors */ |
282 | dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; | 479 | dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; |
283 | 480 | ||
284 | /* receiver fifo overrun */ | 481 | /* receiver fifo overrun */ |
285 | /* drops_no_pbuf is no per i/f, it's per BE card */ | 482 | /* drops_no_pbuf is no per i/f, it's per BE card */ |
286 | dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + | 483 | dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + |
287 | port_stats->rx_input_fifo_overflow + | 484 | drvs->rx_input_fifo_overflow_drop + |
288 | rxf_stats->rx_drops_no_pbuf; | 485 | drvs->rx_drops_no_pbuf; |
289 | /* receiver missed packetd */ | ||
290 | dev_stats->rx_missed_errors = 0; | ||
291 | |||
292 | /* packet transmit problems */ | ||
293 | dev_stats->tx_errors = 0; | ||
294 | |||
295 | /* no space available in linux */ | ||
296 | dev_stats->tx_dropped = 0; | ||
297 | |||
298 | dev_stats->collisions = 0; | ||
299 | |||
300 | /* detailed tx_errors */ | ||
301 | dev_stats->tx_aborted_errors = 0; | ||
302 | dev_stats->tx_carrier_errors = 0; | ||
303 | dev_stats->tx_fifo_errors = 0; | ||
304 | dev_stats->tx_heartbeat_errors = 0; | ||
305 | dev_stats->tx_window_errors = 0; | ||
306 | } | 486 | } |
307 | 487 | ||
308 | void be_link_status_update(struct be_adapter *adapter, bool link_up) | 488 | void be_link_status_update(struct be_adapter *adapter, bool link_up) |
@@ -313,11 +493,9 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) | |||
313 | if (adapter->link_up != link_up) { | 493 | if (adapter->link_up != link_up) { |
314 | adapter->link_speed = -1; | 494 | adapter->link_speed = -1; |
315 | if (link_up) { | 495 | if (link_up) { |
316 | netif_start_queue(netdev); | ||
317 | netif_carrier_on(netdev); | 496 | netif_carrier_on(netdev); |
318 | printk(KERN_INFO "%s: Link up\n", netdev->name); | 497 | printk(KERN_INFO "%s: Link up\n", netdev->name); |
319 | } else { | 498 | } else { |
320 | netif_stop_queue(netdev); | ||
321 | netif_carrier_off(netdev); | 499 | netif_carrier_off(netdev); |
322 | printk(KERN_INFO "%s: Link down\n", netdev->name); | 500 | printk(KERN_INFO "%s: Link down\n", netdev->name); |
323 | } | 501 | } |
@@ -326,10 +504,10 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) | |||
326 | } | 504 | } |
327 | 505 | ||
328 | /* Update the EQ delay n BE based on the RX frags consumed / sec */ | 506 | /* Update the EQ delay n BE based on the RX frags consumed / sec */ |
329 | static void be_rx_eqd_update(struct be_adapter *adapter) | 507 | static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) |
330 | { | 508 | { |
331 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | 509 | struct be_eq_obj *rx_eq = &rxo->rx_eq; |
332 | struct be_drvr_stats *stats = &adapter->stats.drvr_stats; | 510 | struct be_rx_stats *stats = &rxo->stats; |
333 | ulong now = jiffies; | 511 | ulong now = jiffies; |
334 | u32 eqd; | 512 | u32 eqd; |
335 | 513 | ||
@@ -346,12 +524,12 @@ static void be_rx_eqd_update(struct be_adapter *adapter) | |||
346 | if ((now - stats->rx_fps_jiffies) < HZ) | 524 | if ((now - stats->rx_fps_jiffies) < HZ) |
347 | return; | 525 | return; |
348 | 526 | ||
349 | stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) / | 527 | stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) / |
350 | ((now - stats->rx_fps_jiffies) / HZ); | 528 | ((now - stats->rx_fps_jiffies) / HZ); |
351 | 529 | ||
352 | stats->rx_fps_jiffies = now; | 530 | stats->rx_fps_jiffies = now; |
353 | stats->be_prev_rx_frags = stats->be_rx_frags; | 531 | stats->prev_rx_frags = stats->rx_frags; |
354 | eqd = stats->be_rx_fps / 110000; | 532 | eqd = stats->rx_fps / 110000; |
355 | eqd = eqd << 3; | 533 | eqd = eqd << 3; |
356 | if (eqd > rx_eq->max_eqd) | 534 | if (eqd > rx_eq->max_eqd) |
357 | eqd = rx_eq->max_eqd; | 535 | eqd = rx_eq->max_eqd; |
@@ -365,11 +543,6 @@ static void be_rx_eqd_update(struct be_adapter *adapter) | |||
365 | rx_eq->cur_eqd = eqd; | 543 | rx_eq->cur_eqd = eqd; |
366 | } | 544 | } |
367 | 545 | ||
368 | static struct net_device_stats *be_get_stats(struct net_device *dev) | ||
369 | { | ||
370 | return &dev->stats; | ||
371 | } | ||
372 | |||
373 | static u32 be_calc_rate(u64 bytes, unsigned long ticks) | 546 | static u32 be_calc_rate(u64 bytes, unsigned long ticks) |
374 | { | 547 | { |
375 | u64 rate = bytes; | 548 | u64 rate = bytes; |
@@ -383,7 +556,7 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks) | |||
383 | 556 | ||
384 | static void be_tx_rate_update(struct be_adapter *adapter) | 557 | static void be_tx_rate_update(struct be_adapter *adapter) |
385 | { | 558 | { |
386 | struct be_drvr_stats *stats = drvr_stats(adapter); | 559 | struct be_tx_stats *stats = tx_stats(adapter); |
387 | ulong now = jiffies; | 560 | ulong now = jiffies; |
388 | 561 | ||
389 | /* Wrapped around? */ | 562 | /* Wrapped around? */ |
@@ -405,7 +578,7 @@ static void be_tx_rate_update(struct be_adapter *adapter) | |||
405 | static void be_tx_stats_update(struct be_adapter *adapter, | 578 | static void be_tx_stats_update(struct be_adapter *adapter, |
406 | u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) | 579 | u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) |
407 | { | 580 | { |
408 | struct be_drvr_stats *stats = drvr_stats(adapter); | 581 | struct be_tx_stats *stats = tx_stats(adapter); |
409 | stats->be_tx_reqs++; | 582 | stats->be_tx_reqs++; |
410 | stats->be_tx_wrbs += wrb_cnt; | 583 | stats->be_tx_wrbs += wrb_cnt; |
411 | stats->be_tx_bytes += copied; | 584 | stats->be_tx_bytes += copied; |
@@ -415,7 +588,8 @@ static void be_tx_stats_update(struct be_adapter *adapter, | |||
415 | } | 588 | } |
416 | 589 | ||
417 | /* Determine number of WRB entries needed to xmit data in an skb */ | 590 | /* Determine number of WRB entries needed to xmit data in an skb */ |
418 | static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) | 591 | static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb, |
592 | bool *dummy) | ||
419 | { | 593 | { |
420 | int cnt = (skb->len > skb->data_len); | 594 | int cnt = (skb->len > skb->data_len); |
421 | 595 | ||
@@ -423,12 +597,13 @@ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) | |||
423 | 597 | ||
424 | /* to account for hdr wrb */ | 598 | /* to account for hdr wrb */ |
425 | cnt++; | 599 | cnt++; |
426 | if (cnt & 1) { | 600 | if (lancer_chip(adapter) || !(cnt & 1)) { |
601 | *dummy = false; | ||
602 | } else { | ||
427 | /* add a dummy to make it an even num */ | 603 | /* add a dummy to make it an even num */ |
428 | cnt++; | 604 | cnt++; |
429 | *dummy = true; | 605 | *dummy = true; |
430 | } else | 606 | } |
431 | *dummy = false; | ||
432 | BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); | 607 | BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); |
433 | return cnt; | 608 | return cnt; |
434 | } | 609 | } |
@@ -440,9 +615,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) | |||
440 | wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; | 615 | wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; |
441 | } | 616 | } |
442 | 617 | ||
443 | static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, | 618 | static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, |
444 | bool vlan, u32 wrb_cnt, u32 len) | 619 | struct sk_buff *skb, u32 wrb_cnt, u32 len) |
445 | { | 620 | { |
621 | u8 vlan_prio = 0; | ||
622 | u16 vlan_tag = 0; | ||
623 | |||
446 | memset(hdr, 0, sizeof(*hdr)); | 624 | memset(hdr, 0, sizeof(*hdr)); |
447 | 625 | ||
448 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); | 626 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); |
@@ -451,8 +629,18 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, | |||
451 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); | 629 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); |
452 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, | 630 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, |
453 | hdr, skb_shinfo(skb)->gso_size); | 631 | hdr, skb_shinfo(skb)->gso_size); |
454 | if (skb_is_gso_v6(skb)) | 632 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) |
455 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); | 633 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); |
634 | if (lancer_chip(adapter) && adapter->sli_family == | ||
635 | LANCER_A0_SLI_FAMILY) { | ||
636 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1); | ||
637 | if (is_tcp_pkt(skb)) | ||
638 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, | ||
639 | tcpcs, hdr, 1); | ||
640 | else if (is_udp_pkt(skb)) | ||
641 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, | ||
642 | udpcs, hdr, 1); | ||
643 | } | ||
456 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 644 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
457 | if (is_tcp_pkt(skb)) | 645 | if (is_tcp_pkt(skb)) |
458 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); | 646 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); |
@@ -460,10 +648,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, | |||
460 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); | 648 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); |
461 | } | 649 | } |
462 | 650 | ||
463 | if (vlan && vlan_tx_tag_present(skb)) { | 651 | if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { |
464 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); | 652 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); |
465 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, | 653 | vlan_tag = vlan_tx_tag_get(skb); |
466 | hdr, vlan_tx_tag_get(skb)); | 654 | vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; |
655 | /* If vlan priority provided by OS is NOT in available bmap */ | ||
656 | if (!(adapter->vlan_prio_bmap & (1 << vlan_prio))) | ||
657 | vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) | | ||
658 | adapter->recommended_prio; | ||
659 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag); | ||
467 | } | 660 | } |
468 | 661 | ||
469 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); | 662 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); |
@@ -472,7 +665,7 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, | |||
472 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); | 665 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); |
473 | } | 666 | } |
474 | 667 | ||
475 | static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb, | 668 | static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, |
476 | bool unmap_single) | 669 | bool unmap_single) |
477 | { | 670 | { |
478 | dma_addr_t dma; | 671 | dma_addr_t dma; |
@@ -482,11 +675,10 @@ static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb, | |||
482 | dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo; | 675 | dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo; |
483 | if (wrb->frag_len) { | 676 | if (wrb->frag_len) { |
484 | if (unmap_single) | 677 | if (unmap_single) |
485 | pci_unmap_single(pdev, dma, wrb->frag_len, | 678 | dma_unmap_single(dev, dma, wrb->frag_len, |
486 | PCI_DMA_TODEVICE); | 679 | DMA_TO_DEVICE); |
487 | else | 680 | else |
488 | pci_unmap_page(pdev, dma, wrb->frag_len, | 681 | dma_unmap_page(dev, dma, wrb->frag_len, DMA_TO_DEVICE); |
489 | PCI_DMA_TODEVICE); | ||
490 | } | 682 | } |
491 | } | 683 | } |
492 | 684 | ||
@@ -495,7 +687,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
495 | { | 687 | { |
496 | dma_addr_t busaddr; | 688 | dma_addr_t busaddr; |
497 | int i, copied = 0; | 689 | int i, copied = 0; |
498 | struct pci_dev *pdev = adapter->pdev; | 690 | struct device *dev = &adapter->pdev->dev; |
499 | struct sk_buff *first_skb = skb; | 691 | struct sk_buff *first_skb = skb; |
500 | struct be_queue_info *txq = &adapter->tx_obj.q; | 692 | struct be_queue_info *txq = &adapter->tx_obj.q; |
501 | struct be_eth_wrb *wrb; | 693 | struct be_eth_wrb *wrb; |
@@ -509,9 +701,8 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
509 | 701 | ||
510 | if (skb->len > skb->data_len) { | 702 | if (skb->len > skb->data_len) { |
511 | int len = skb_headlen(skb); | 703 | int len = skb_headlen(skb); |
512 | busaddr = pci_map_single(pdev, skb->data, len, | 704 | busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE); |
513 | PCI_DMA_TODEVICE); | 705 | if (dma_mapping_error(dev, busaddr)) |
514 | if (pci_dma_mapping_error(pdev, busaddr)) | ||
515 | goto dma_err; | 706 | goto dma_err; |
516 | map_single = true; | 707 | map_single = true; |
517 | wrb = queue_head_node(txq); | 708 | wrb = queue_head_node(txq); |
@@ -524,10 +715,9 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
524 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 715 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
525 | struct skb_frag_struct *frag = | 716 | struct skb_frag_struct *frag = |
526 | &skb_shinfo(skb)->frags[i]; | 717 | &skb_shinfo(skb)->frags[i]; |
527 | busaddr = pci_map_page(pdev, frag->page, | 718 | busaddr = dma_map_page(dev, frag->page, frag->page_offset, |
528 | frag->page_offset, | 719 | frag->size, DMA_TO_DEVICE); |
529 | frag->size, PCI_DMA_TODEVICE); | 720 | if (dma_mapping_error(dev, busaddr)) |
530 | if (pci_dma_mapping_error(pdev, busaddr)) | ||
531 | goto dma_err; | 721 | goto dma_err; |
532 | wrb = queue_head_node(txq); | 722 | wrb = queue_head_node(txq); |
533 | wrb_fill(wrb, busaddr, frag->size); | 723 | wrb_fill(wrb, busaddr, frag->size); |
@@ -543,8 +733,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
543 | queue_head_inc(txq); | 733 | queue_head_inc(txq); |
544 | } | 734 | } |
545 | 735 | ||
546 | wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, | 736 | wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied); |
547 | wrb_cnt, copied); | ||
548 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); | 737 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); |
549 | 738 | ||
550 | return copied; | 739 | return copied; |
@@ -552,7 +741,7 @@ dma_err: | |||
552 | txq->head = map_head; | 741 | txq->head = map_head; |
553 | while (copied) { | 742 | while (copied) { |
554 | wrb = queue_head_node(txq); | 743 | wrb = queue_head_node(txq); |
555 | unmap_tx_frag(pdev, wrb, map_single); | 744 | unmap_tx_frag(dev, wrb, map_single); |
556 | map_single = false; | 745 | map_single = false; |
557 | copied -= wrb->frag_len; | 746 | copied -= wrb->frag_len; |
558 | queue_head_inc(txq); | 747 | queue_head_inc(txq); |
@@ -570,7 +759,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, | |||
570 | u32 start = txq->head; | 759 | u32 start = txq->head; |
571 | bool dummy_wrb, stopped = false; | 760 | bool dummy_wrb, stopped = false; |
572 | 761 | ||
573 | wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb); | 762 | wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); |
574 | 763 | ||
575 | copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); | 764 | copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); |
576 | if (copied) { | 765 | if (copied) { |
@@ -637,7 +826,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) | |||
637 | 826 | ||
638 | if (adapter->vlans_added <= adapter->max_vlans) { | 827 | if (adapter->vlans_added <= adapter->max_vlans) { |
639 | /* Construct VLAN Table to give to HW */ | 828 | /* Construct VLAN Table to give to HW */ |
640 | for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { | 829 | for (i = 0; i < VLAN_N_VID; i++) { |
641 | if (adapter->vlan_tag[i]) { | 830 | if (adapter->vlan_tag[i]) { |
642 | vtag[ntags] = cpu_to_le16(i); | 831 | vtag[ntags] = cpu_to_le16(i); |
643 | ntags++; | 832 | ntags++; |
@@ -656,14 +845,8 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) | |||
656 | static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) | 845 | static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) |
657 | { | 846 | { |
658 | struct be_adapter *adapter = netdev_priv(netdev); | 847 | struct be_adapter *adapter = netdev_priv(netdev); |
659 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | ||
660 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | ||
661 | 848 | ||
662 | be_eq_notify(adapter, rx_eq->q.id, false, false, 0); | ||
663 | be_eq_notify(adapter, tx_eq->q.id, false, false, 0); | ||
664 | adapter->vlan_grp = grp; | 849 | adapter->vlan_grp = grp; |
665 | be_eq_notify(adapter, rx_eq->q.id, true, false, 0); | ||
666 | be_eq_notify(adapter, tx_eq->q.id, true, false, 0); | ||
667 | } | 850 | } |
668 | 851 | ||
669 | static void be_vlan_add_vid(struct net_device *netdev, u16 vid) | 852 | static void be_vlan_add_vid(struct net_device *netdev, u16 vid) |
@@ -699,15 +882,15 @@ static void be_set_multicast_list(struct net_device *netdev) | |||
699 | struct be_adapter *adapter = netdev_priv(netdev); | 882 | struct be_adapter *adapter = netdev_priv(netdev); |
700 | 883 | ||
701 | if (netdev->flags & IFF_PROMISC) { | 884 | if (netdev->flags & IFF_PROMISC) { |
702 | be_cmd_promiscuous_config(adapter, adapter->port_num, 1); | 885 | be_cmd_promiscuous_config(adapter, true); |
703 | adapter->promiscuous = true; | 886 | adapter->promiscuous = true; |
704 | goto done; | 887 | goto done; |
705 | } | 888 | } |
706 | 889 | ||
707 | /* BE was previously in promiscous mode; disable it */ | 890 | /* BE was previously in promiscuous mode; disable it */ |
708 | if (adapter->promiscuous) { | 891 | if (adapter->promiscuous) { |
709 | adapter->promiscuous = false; | 892 | adapter->promiscuous = false; |
710 | be_cmd_promiscuous_config(adapter, adapter->port_num, 0); | 893 | be_cmd_promiscuous_config(adapter, false); |
711 | } | 894 | } |
712 | 895 | ||
713 | /* Enable multicast promisc if num configured exceeds what we support */ | 896 | /* Enable multicast promisc if num configured exceeds what we support */ |
@@ -738,11 +921,11 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | |||
738 | if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) | 921 | if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) |
739 | status = be_cmd_pmac_del(adapter, | 922 | status = be_cmd_pmac_del(adapter, |
740 | adapter->vf_cfg[vf].vf_if_handle, | 923 | adapter->vf_cfg[vf].vf_if_handle, |
741 | adapter->vf_cfg[vf].vf_pmac_id); | 924 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
742 | 925 | ||
743 | status = be_cmd_pmac_add(adapter, mac, | 926 | status = be_cmd_pmac_add(adapter, mac, |
744 | adapter->vf_cfg[vf].vf_if_handle, | 927 | adapter->vf_cfg[vf].vf_if_handle, |
745 | &adapter->vf_cfg[vf].vf_pmac_id); | 928 | &adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
746 | 929 | ||
747 | if (status) | 930 | if (status) |
748 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", | 931 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", |
@@ -817,7 +1000,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
817 | rate = 10000; | 1000 | rate = 10000; |
818 | 1001 | ||
819 | adapter->vf_cfg[vf].vf_tx_rate = rate; | 1002 | adapter->vf_cfg[vf].vf_tx_rate = rate; |
820 | status = be_cmd_set_qos(adapter, rate / 10, vf); | 1003 | status = be_cmd_set_qos(adapter, rate / 10, vf + 1); |
821 | 1004 | ||
822 | if (status) | 1005 | if (status) |
823 | dev_info(&adapter->pdev->dev, | 1006 | dev_info(&adapter->pdev->dev, |
@@ -825,70 +1008,65 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
825 | return status; | 1008 | return status; |
826 | } | 1009 | } |
827 | 1010 | ||
828 | static void be_rx_rate_update(struct be_adapter *adapter) | 1011 | static void be_rx_rate_update(struct be_rx_obj *rxo) |
829 | { | 1012 | { |
830 | struct be_drvr_stats *stats = drvr_stats(adapter); | 1013 | struct be_rx_stats *stats = &rxo->stats; |
831 | ulong now = jiffies; | 1014 | ulong now = jiffies; |
832 | 1015 | ||
833 | /* Wrapped around */ | 1016 | /* Wrapped around */ |
834 | if (time_before(now, stats->be_rx_jiffies)) { | 1017 | if (time_before(now, stats->rx_jiffies)) { |
835 | stats->be_rx_jiffies = now; | 1018 | stats->rx_jiffies = now; |
836 | return; | 1019 | return; |
837 | } | 1020 | } |
838 | 1021 | ||
839 | /* Update the rate once in two seconds */ | 1022 | /* Update the rate once in two seconds */ |
840 | if ((now - stats->be_rx_jiffies) < 2 * HZ) | 1023 | if ((now - stats->rx_jiffies) < 2 * HZ) |
841 | return; | 1024 | return; |
842 | 1025 | ||
843 | stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes | 1026 | stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev, |
844 | - stats->be_rx_bytes_prev, | 1027 | now - stats->rx_jiffies); |
845 | now - stats->be_rx_jiffies); | 1028 | stats->rx_jiffies = now; |
846 | stats->be_rx_jiffies = now; | 1029 | stats->rx_bytes_prev = stats->rx_bytes; |
847 | stats->be_rx_bytes_prev = stats->be_rx_bytes; | ||
848 | } | 1030 | } |
849 | 1031 | ||
850 | static void be_rx_stats_update(struct be_adapter *adapter, | 1032 | static void be_rx_stats_update(struct be_rx_obj *rxo, |
851 | u32 pktsize, u16 numfrags, u8 pkt_type) | 1033 | struct be_rx_compl_info *rxcp) |
852 | { | 1034 | { |
853 | struct be_drvr_stats *stats = drvr_stats(adapter); | 1035 | struct be_rx_stats *stats = &rxo->stats; |
854 | 1036 | ||
855 | stats->be_rx_compl++; | 1037 | stats->rx_compl++; |
856 | stats->be_rx_frags += numfrags; | 1038 | stats->rx_frags += rxcp->num_rcvd; |
857 | stats->be_rx_bytes += pktsize; | 1039 | stats->rx_bytes += rxcp->pkt_size; |
858 | stats->be_rx_pkts++; | 1040 | stats->rx_pkts++; |
859 | 1041 | if (rxcp->pkt_type == BE_MULTICAST_PACKET) | |
860 | if (pkt_type == BE_MULTICAST_PACKET) | 1042 | stats->rx_mcast_pkts++; |
861 | stats->be_rx_mcast_pkt++; | 1043 | if (rxcp->err) |
1044 | stats->rxcp_err++; | ||
862 | } | 1045 | } |
863 | 1046 | ||
864 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) | 1047 | static inline bool csum_passed(struct be_rx_compl_info *rxcp) |
865 | { | 1048 | { |
866 | u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk; | 1049 | /* L4 checksum is not reliable for non TCP/UDP packets. |
867 | 1050 | * Also ignore ipcksm for ipv6 pkts */ | |
868 | l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); | 1051 | return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum && |
869 | ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); | 1052 | (rxcp->ip_csum || rxcp->ipv6); |
870 | ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); | ||
871 | if (ip_version) { | ||
872 | tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); | ||
873 | udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); | ||
874 | } | ||
875 | ipv6_chk = (ip_version && (tcpf || udpf)); | ||
876 | |||
877 | return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true; | ||
878 | } | 1053 | } |
879 | 1054 | ||
880 | static struct be_rx_page_info * | 1055 | static struct be_rx_page_info * |
881 | get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) | 1056 | get_rx_page_info(struct be_adapter *adapter, |
1057 | struct be_rx_obj *rxo, | ||
1058 | u16 frag_idx) | ||
882 | { | 1059 | { |
883 | struct be_rx_page_info *rx_page_info; | 1060 | struct be_rx_page_info *rx_page_info; |
884 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1061 | struct be_queue_info *rxq = &rxo->q; |
885 | 1062 | ||
886 | rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx]; | 1063 | rx_page_info = &rxo->page_info_tbl[frag_idx]; |
887 | BUG_ON(!rx_page_info->page); | 1064 | BUG_ON(!rx_page_info->page); |
888 | 1065 | ||
889 | if (rx_page_info->last_page_user) { | 1066 | if (rx_page_info->last_page_user) { |
890 | pci_unmap_page(adapter->pdev, dma_unmap_addr(rx_page_info, bus), | 1067 | dma_unmap_page(&adapter->pdev->dev, |
891 | adapter->big_page_size, PCI_DMA_FROMDEVICE); | 1068 | dma_unmap_addr(rx_page_info, bus), |
1069 | adapter->big_page_size, DMA_FROM_DEVICE); | ||
892 | rx_page_info->last_page_user = false; | 1070 | rx_page_info->last_page_user = false; |
893 | } | 1071 | } |
894 | 1072 | ||
@@ -898,20 +1076,18 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) | |||
898 | 1076 | ||
899 | /* Throwaway the data in the Rx completion */ | 1077 | /* Throwaway the data in the Rx completion */ |
900 | static void be_rx_compl_discard(struct be_adapter *adapter, | 1078 | static void be_rx_compl_discard(struct be_adapter *adapter, |
901 | struct be_eth_rx_compl *rxcp) | 1079 | struct be_rx_obj *rxo, |
1080 | struct be_rx_compl_info *rxcp) | ||
902 | { | 1081 | { |
903 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1082 | struct be_queue_info *rxq = &rxo->q; |
904 | struct be_rx_page_info *page_info; | 1083 | struct be_rx_page_info *page_info; |
905 | u16 rxq_idx, i, num_rcvd; | 1084 | u16 i, num_rcvd = rxcp->num_rcvd; |
906 | |||
907 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
908 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | ||
909 | 1085 | ||
910 | for (i = 0; i < num_rcvd; i++) { | 1086 | for (i = 0; i < num_rcvd; i++) { |
911 | page_info = get_rx_page_info(adapter, rxq_idx); | 1087 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
912 | put_page(page_info->page); | 1088 | put_page(page_info->page); |
913 | memset(page_info, 0, sizeof(*page_info)); | 1089 | memset(page_info, 0, sizeof(*page_info)); |
914 | index_inc(&rxq_idx, rxq->len); | 1090 | index_inc(&rxcp->rxq_idx, rxq->len); |
915 | } | 1091 | } |
916 | } | 1092 | } |
917 | 1093 | ||
@@ -919,31 +1095,24 @@ static void be_rx_compl_discard(struct be_adapter *adapter, | |||
919 | * skb_fill_rx_data forms a complete skb for an ether frame | 1095 | * skb_fill_rx_data forms a complete skb for an ether frame |
920 | * indicated by rxcp. | 1096 | * indicated by rxcp. |
921 | */ | 1097 | */ |
922 | static void skb_fill_rx_data(struct be_adapter *adapter, | 1098 | static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, |
923 | struct sk_buff *skb, struct be_eth_rx_compl *rxcp, | 1099 | struct sk_buff *skb, struct be_rx_compl_info *rxcp) |
924 | u16 num_rcvd) | ||
925 | { | 1100 | { |
926 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1101 | struct be_queue_info *rxq = &rxo->q; |
927 | struct be_rx_page_info *page_info; | 1102 | struct be_rx_page_info *page_info; |
928 | u16 rxq_idx, i, j; | 1103 | u16 i, j; |
929 | u32 pktsize, hdr_len, curr_frag_len, size; | 1104 | u16 hdr_len, curr_frag_len, remaining; |
930 | u8 *start; | 1105 | u8 *start; |
931 | u8 pkt_type; | ||
932 | |||
933 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
934 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | ||
935 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
936 | |||
937 | page_info = get_rx_page_info(adapter, rxq_idx); | ||
938 | 1106 | ||
1107 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); | ||
939 | start = page_address(page_info->page) + page_info->page_offset; | 1108 | start = page_address(page_info->page) + page_info->page_offset; |
940 | prefetch(start); | 1109 | prefetch(start); |
941 | 1110 | ||
942 | /* Copy data in the first descriptor of this completion */ | 1111 | /* Copy data in the first descriptor of this completion */ |
943 | curr_frag_len = min(pktsize, rx_frag_size); | 1112 | curr_frag_len = min(rxcp->pkt_size, rx_frag_size); |
944 | 1113 | ||
945 | /* Copy the header portion into skb_data */ | 1114 | /* Copy the header portion into skb_data */ |
946 | hdr_len = min((u32)BE_HDR_LEN, curr_frag_len); | 1115 | hdr_len = min(BE_HDR_LEN, curr_frag_len); |
947 | memcpy(skb->data, start, hdr_len); | 1116 | memcpy(skb->data, start, hdr_len); |
948 | skb->len = curr_frag_len; | 1117 | skb->len = curr_frag_len; |
949 | if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ | 1118 | if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ |
@@ -962,19 +1131,17 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
962 | } | 1131 | } |
963 | page_info->page = NULL; | 1132 | page_info->page = NULL; |
964 | 1133 | ||
965 | if (pktsize <= rx_frag_size) { | 1134 | if (rxcp->pkt_size <= rx_frag_size) { |
966 | BUG_ON(num_rcvd != 1); | 1135 | BUG_ON(rxcp->num_rcvd != 1); |
967 | goto done; | 1136 | return; |
968 | } | 1137 | } |
969 | 1138 | ||
970 | /* More frags present for this completion */ | 1139 | /* More frags present for this completion */ |
971 | size = pktsize; | 1140 | index_inc(&rxcp->rxq_idx, rxq->len); |
972 | for (i = 1, j = 0; i < num_rcvd; i++) { | 1141 | remaining = rxcp->pkt_size - curr_frag_len; |
973 | size -= curr_frag_len; | 1142 | for (i = 1, j = 0; i < rxcp->num_rcvd; i++) { |
974 | index_inc(&rxq_idx, rxq->len); | 1143 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
975 | page_info = get_rx_page_info(adapter, rxq_idx); | 1144 | curr_frag_len = min(remaining, rx_frag_size); |
976 | |||
977 | curr_frag_len = min(size, rx_frag_size); | ||
978 | 1145 | ||
979 | /* Coalesce all frags from the same physical page in one slot */ | 1146 | /* Coalesce all frags from the same physical page in one slot */ |
980 | if (page_info->page_offset == 0) { | 1147 | if (page_info->page_offset == 0) { |
@@ -993,62 +1160,49 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
993 | skb->len += curr_frag_len; | 1160 | skb->len += curr_frag_len; |
994 | skb->data_len += curr_frag_len; | 1161 | skb->data_len += curr_frag_len; |
995 | 1162 | ||
1163 | remaining -= curr_frag_len; | ||
1164 | index_inc(&rxcp->rxq_idx, rxq->len); | ||
996 | page_info->page = NULL; | 1165 | page_info->page = NULL; |
997 | } | 1166 | } |
998 | BUG_ON(j > MAX_SKB_FRAGS); | 1167 | BUG_ON(j > MAX_SKB_FRAGS); |
999 | |||
1000 | done: | ||
1001 | be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type); | ||
1002 | } | 1168 | } |
1003 | 1169 | ||
1004 | /* Process the RX completion indicated by rxcp when GRO is disabled */ | 1170 | /* Process the RX completion indicated by rxcp when GRO is disabled */ |
1005 | static void be_rx_compl_process(struct be_adapter *adapter, | 1171 | static void be_rx_compl_process(struct be_adapter *adapter, |
1006 | struct be_eth_rx_compl *rxcp) | 1172 | struct be_rx_obj *rxo, |
1173 | struct be_rx_compl_info *rxcp) | ||
1007 | { | 1174 | { |
1175 | struct net_device *netdev = adapter->netdev; | ||
1008 | struct sk_buff *skb; | 1176 | struct sk_buff *skb; |
1009 | u32 vlanf, vid; | ||
1010 | u16 num_rcvd; | ||
1011 | u8 vtm; | ||
1012 | 1177 | ||
1013 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | 1178 | skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); |
1014 | /* Is it a flush compl that has no data */ | ||
1015 | if (unlikely(num_rcvd == 0)) | ||
1016 | return; | ||
1017 | |||
1018 | skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); | ||
1019 | if (unlikely(!skb)) { | 1179 | if (unlikely(!skb)) { |
1020 | if (net_ratelimit()) | 1180 | if (net_ratelimit()) |
1021 | dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); | 1181 | dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); |
1022 | be_rx_compl_discard(adapter, rxcp); | 1182 | be_rx_compl_discard(adapter, rxo, rxcp); |
1023 | return; | 1183 | return; |
1024 | } | 1184 | } |
1025 | 1185 | ||
1026 | skb_fill_rx_data(adapter, skb, rxcp, num_rcvd); | 1186 | skb_fill_rx_data(adapter, rxo, skb, rxcp); |
1027 | 1187 | ||
1028 | if (do_pkt_csum(rxcp, adapter->rx_csum)) | 1188 | if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp))) |
1029 | skb->ip_summed = CHECKSUM_NONE; | ||
1030 | else | ||
1031 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1189 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1190 | else | ||
1191 | skb_checksum_none_assert(skb); | ||
1032 | 1192 | ||
1033 | skb->truesize = skb->len + sizeof(struct sk_buff); | 1193 | skb->truesize = skb->len + sizeof(struct sk_buff); |
1034 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 1194 | skb->protocol = eth_type_trans(skb, netdev); |
1195 | if (adapter->netdev->features & NETIF_F_RXHASH) | ||
1196 | skb->rxhash = rxcp->rss_hash; | ||
1035 | 1197 | ||
1036 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | ||
1037 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | ||
1038 | 1198 | ||
1039 | /* vlanf could be wrongly set in some cards. | 1199 | if (unlikely(rxcp->vlanf)) { |
1040 | * ignore if vtm is not set */ | ||
1041 | if ((adapter->function_mode & 0x400) && !vtm) | ||
1042 | vlanf = 0; | ||
1043 | |||
1044 | if (unlikely(vlanf)) { | ||
1045 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { | 1200 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { |
1046 | kfree_skb(skb); | 1201 | kfree_skb(skb); |
1047 | return; | 1202 | return; |
1048 | } | 1203 | } |
1049 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 1204 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, |
1050 | vid = swab16(vid); | 1205 | rxcp->vlan_tag); |
1051 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); | ||
1052 | } else { | 1206 | } else { |
1053 | netif_receive_skb(skb); | 1207 | netif_receive_skb(skb); |
1054 | } | 1208 | } |
@@ -1056,42 +1210,25 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
1056 | 1210 | ||
1057 | /* Process the RX completion indicated by rxcp when GRO is enabled */ | 1211 | /* Process the RX completion indicated by rxcp when GRO is enabled */ |
1058 | static void be_rx_compl_process_gro(struct be_adapter *adapter, | 1212 | static void be_rx_compl_process_gro(struct be_adapter *adapter, |
1059 | struct be_eth_rx_compl *rxcp) | 1213 | struct be_rx_obj *rxo, |
1214 | struct be_rx_compl_info *rxcp) | ||
1060 | { | 1215 | { |
1061 | struct be_rx_page_info *page_info; | 1216 | struct be_rx_page_info *page_info; |
1062 | struct sk_buff *skb = NULL; | 1217 | struct sk_buff *skb = NULL; |
1063 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1218 | struct be_queue_info *rxq = &rxo->q; |
1064 | struct be_eq_obj *eq_obj = &adapter->rx_eq; | 1219 | struct be_eq_obj *eq_obj = &rxo->rx_eq; |
1065 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 1220 | u16 remaining, curr_frag_len; |
1066 | u16 i, rxq_idx = 0, vid, j; | 1221 | u16 i, j; |
1067 | u8 vtm; | ||
1068 | u8 pkt_type; | ||
1069 | |||
1070 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | ||
1071 | /* Is it a flush compl that has no data */ | ||
1072 | if (unlikely(num_rcvd == 0)) | ||
1073 | return; | ||
1074 | |||
1075 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | ||
1076 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | ||
1077 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
1078 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | ||
1079 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
1080 | |||
1081 | /* vlanf could be wrongly set in some cards. | ||
1082 | * ignore if vtm is not set */ | ||
1083 | if ((adapter->function_mode & 0x400) && !vtm) | ||
1084 | vlanf = 0; | ||
1085 | 1222 | ||
1086 | skb = napi_get_frags(&eq_obj->napi); | 1223 | skb = napi_get_frags(&eq_obj->napi); |
1087 | if (!skb) { | 1224 | if (!skb) { |
1088 | be_rx_compl_discard(adapter, rxcp); | 1225 | be_rx_compl_discard(adapter, rxo, rxcp); |
1089 | return; | 1226 | return; |
1090 | } | 1227 | } |
1091 | 1228 | ||
1092 | remaining = pkt_size; | 1229 | remaining = rxcp->pkt_size; |
1093 | for (i = 0, j = -1; i < num_rcvd; i++) { | 1230 | for (i = 0, j = -1; i < rxcp->num_rcvd; i++) { |
1094 | page_info = get_rx_page_info(adapter, rxq_idx); | 1231 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
1095 | 1232 | ||
1096 | curr_frag_len = min(remaining, rx_frag_size); | 1233 | curr_frag_len = min(remaining, rx_frag_size); |
1097 | 1234 | ||
@@ -1109,89 +1246,166 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1109 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | 1246 | skb_shinfo(skb)->frags[j].size += curr_frag_len; |
1110 | 1247 | ||
1111 | remaining -= curr_frag_len; | 1248 | remaining -= curr_frag_len; |
1112 | index_inc(&rxq_idx, rxq->len); | 1249 | index_inc(&rxcp->rxq_idx, rxq->len); |
1113 | memset(page_info, 0, sizeof(*page_info)); | 1250 | memset(page_info, 0, sizeof(*page_info)); |
1114 | } | 1251 | } |
1115 | BUG_ON(j > MAX_SKB_FRAGS); | 1252 | BUG_ON(j > MAX_SKB_FRAGS); |
1116 | 1253 | ||
1117 | skb_shinfo(skb)->nr_frags = j + 1; | 1254 | skb_shinfo(skb)->nr_frags = j + 1; |
1118 | skb->len = pkt_size; | 1255 | skb->len = rxcp->pkt_size; |
1119 | skb->data_len = pkt_size; | 1256 | skb->data_len = rxcp->pkt_size; |
1120 | skb->truesize += pkt_size; | 1257 | skb->truesize += rxcp->pkt_size; |
1121 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1258 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1259 | if (adapter->netdev->features & NETIF_F_RXHASH) | ||
1260 | skb->rxhash = rxcp->rss_hash; | ||
1122 | 1261 | ||
1123 | if (likely(!vlanf)) { | 1262 | if (likely(!rxcp->vlanf)) |
1124 | napi_gro_frags(&eq_obj->napi); | 1263 | napi_gro_frags(&eq_obj->napi); |
1125 | } else { | 1264 | else |
1126 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 1265 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, |
1127 | vid = swab16(vid); | 1266 | rxcp->vlan_tag); |
1267 | } | ||
1268 | |||
1269 | static void be_parse_rx_compl_v1(struct be_adapter *adapter, | ||
1270 | struct be_eth_rx_compl *compl, | ||
1271 | struct be_rx_compl_info *rxcp) | ||
1272 | { | ||
1273 | rxcp->pkt_size = | ||
1274 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl); | ||
1275 | rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl); | ||
1276 | rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl); | ||
1277 | rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl); | ||
1278 | rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl); | ||
1279 | rxcp->ip_csum = | ||
1280 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl); | ||
1281 | rxcp->l4_csum = | ||
1282 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl); | ||
1283 | rxcp->ipv6 = | ||
1284 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl); | ||
1285 | rxcp->rxq_idx = | ||
1286 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl); | ||
1287 | rxcp->num_rcvd = | ||
1288 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); | ||
1289 | rxcp->pkt_type = | ||
1290 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); | ||
1291 | rxcp->rss_hash = | ||
1292 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp); | ||
1293 | if (rxcp->vlanf) { | ||
1294 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, | ||
1295 | compl); | ||
1296 | rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, | ||
1297 | compl); | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1301 | static void be_parse_rx_compl_v0(struct be_adapter *adapter, | ||
1302 | struct be_eth_rx_compl *compl, | ||
1303 | struct be_rx_compl_info *rxcp) | ||
1304 | { | ||
1305 | rxcp->pkt_size = | ||
1306 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl); | ||
1307 | rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl); | ||
1308 | rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl); | ||
1309 | rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl); | ||
1310 | rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl); | ||
1311 | rxcp->ip_csum = | ||
1312 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl); | ||
1313 | rxcp->l4_csum = | ||
1314 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl); | ||
1315 | rxcp->ipv6 = | ||
1316 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl); | ||
1317 | rxcp->rxq_idx = | ||
1318 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl); | ||
1319 | rxcp->num_rcvd = | ||
1320 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); | ||
1321 | rxcp->pkt_type = | ||
1322 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); | ||
1323 | rxcp->rss_hash = | ||
1324 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp); | ||
1325 | if (rxcp->vlanf) { | ||
1326 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, | ||
1327 | compl); | ||
1328 | rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, | ||
1329 | compl); | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | ||
1334 | { | ||
1335 | struct be_eth_rx_compl *compl = queue_tail_node(&rxo->cq); | ||
1336 | struct be_rx_compl_info *rxcp = &rxo->rxcp; | ||
1337 | struct be_adapter *adapter = rxo->adapter; | ||
1338 | |||
1339 | /* For checking the valid bit it is Ok to use either definition as the | ||
1340 | * valid bit is at the same position in both v0 and v1 Rx compl */ | ||
1341 | if (compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] == 0) | ||
1342 | return NULL; | ||
1128 | 1343 | ||
1129 | if (!adapter->vlan_grp || adapter->vlans_added == 0) | 1344 | rmb(); |
1130 | return; | 1345 | be_dws_le_to_cpu(compl, sizeof(*compl)); |
1131 | 1346 | ||
1132 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); | 1347 | if (adapter->be3_native) |
1133 | } | 1348 | be_parse_rx_compl_v1(adapter, compl, rxcp); |
1349 | else | ||
1350 | be_parse_rx_compl_v0(adapter, compl, rxcp); | ||
1134 | 1351 | ||
1135 | be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type); | 1352 | if (rxcp->vlanf) { |
1136 | } | 1353 | /* vlanf could be wrongly set in some cards. |
1354 | * ignore if vtm is not set */ | ||
1355 | if ((adapter->function_mode & 0x400) && !rxcp->vtm) | ||
1356 | rxcp->vlanf = 0; | ||
1137 | 1357 | ||
1138 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) | 1358 | if (!lancer_chip(adapter)) |
1139 | { | 1359 | rxcp->vlan_tag = swab16(rxcp->vlan_tag); |
1140 | struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq); | ||
1141 | 1360 | ||
1142 | if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) | 1361 | if (((adapter->pvid & VLAN_VID_MASK) == |
1143 | return NULL; | 1362 | (rxcp->vlan_tag & VLAN_VID_MASK)) && |
1363 | !adapter->vlan_tag[rxcp->vlan_tag]) | ||
1364 | rxcp->vlanf = 0; | ||
1365 | } | ||
1144 | 1366 | ||
1145 | rmb(); | 1367 | /* As the compl has been parsed, reset it; we wont touch it again */ |
1146 | be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); | 1368 | compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; |
1147 | 1369 | ||
1148 | queue_tail_inc(&adapter->rx_obj.cq); | 1370 | queue_tail_inc(&rxo->cq); |
1149 | return rxcp; | 1371 | return rxcp; |
1150 | } | 1372 | } |
1151 | 1373 | ||
1152 | /* To reset the valid bit, we need to reset the whole word as | 1374 | static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) |
1153 | * when walking the queue the valid entries are little-endian | ||
1154 | * and invalid entries are host endian | ||
1155 | */ | ||
1156 | static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) | ||
1157 | { | ||
1158 | rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; | ||
1159 | } | ||
1160 | |||
1161 | static inline struct page *be_alloc_pages(u32 size) | ||
1162 | { | 1375 | { |
1163 | gfp_t alloc_flags = GFP_ATOMIC; | ||
1164 | u32 order = get_order(size); | 1376 | u32 order = get_order(size); |
1377 | |||
1165 | if (order > 0) | 1378 | if (order > 0) |
1166 | alloc_flags |= __GFP_COMP; | 1379 | gfp |= __GFP_COMP; |
1167 | return alloc_pages(alloc_flags, order); | 1380 | return alloc_pages(gfp, order); |
1168 | } | 1381 | } |
1169 | 1382 | ||
1170 | /* | 1383 | /* |
1171 | * Allocate a page, split it to fragments of size rx_frag_size and post as | 1384 | * Allocate a page, split it to fragments of size rx_frag_size and post as |
1172 | * receive buffers to BE | 1385 | * receive buffers to BE |
1173 | */ | 1386 | */ |
1174 | static void be_post_rx_frags(struct be_adapter *adapter) | 1387 | static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) |
1175 | { | 1388 | { |
1176 | struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; | 1389 | struct be_adapter *adapter = rxo->adapter; |
1390 | struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl; | ||
1177 | struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; | 1391 | struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; |
1178 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1392 | struct be_queue_info *rxq = &rxo->q; |
1179 | struct page *pagep = NULL; | 1393 | struct page *pagep = NULL; |
1180 | struct be_eth_rx_d *rxd; | 1394 | struct be_eth_rx_d *rxd; |
1181 | u64 page_dmaaddr = 0, frag_dmaaddr; | 1395 | u64 page_dmaaddr = 0, frag_dmaaddr; |
1182 | u32 posted, page_offset = 0; | 1396 | u32 posted, page_offset = 0; |
1183 | 1397 | ||
1184 | page_info = &page_info_tbl[rxq->head]; | 1398 | page_info = &rxo->page_info_tbl[rxq->head]; |
1185 | for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { | 1399 | for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { |
1186 | if (!pagep) { | 1400 | if (!pagep) { |
1187 | pagep = be_alloc_pages(adapter->big_page_size); | 1401 | pagep = be_alloc_pages(adapter->big_page_size, gfp); |
1188 | if (unlikely(!pagep)) { | 1402 | if (unlikely(!pagep)) { |
1189 | drvr_stats(adapter)->be_ethrx_post_fail++; | 1403 | rxo->stats.rx_post_fail++; |
1190 | break; | 1404 | break; |
1191 | } | 1405 | } |
1192 | page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, | 1406 | page_dmaaddr = dma_map_page(&adapter->pdev->dev, pagep, |
1193 | adapter->big_page_size, | 1407 | 0, adapter->big_page_size, |
1194 | PCI_DMA_FROMDEVICE); | 1408 | DMA_FROM_DEVICE); |
1195 | page_info->page_offset = 0; | 1409 | page_info->page_offset = 0; |
1196 | } else { | 1410 | } else { |
1197 | get_page(pagep); | 1411 | get_page(pagep); |
@@ -1225,7 +1439,7 @@ static void be_post_rx_frags(struct be_adapter *adapter) | |||
1225 | be_rxq_notify(adapter, rxq->id, posted); | 1439 | be_rxq_notify(adapter, rxq->id, posted); |
1226 | } else if (atomic_read(&rxq->used) == 0) { | 1440 | } else if (atomic_read(&rxq->used) == 0) { |
1227 | /* Let be_worker replenish when memory is available */ | 1441 | /* Let be_worker replenish when memory is available */ |
1228 | adapter->rx_post_starved = true; | 1442 | rxo->rx_post_starved = true; |
1229 | } | 1443 | } |
1230 | } | 1444 | } |
1231 | 1445 | ||
@@ -1245,7 +1459,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq) | |||
1245 | return txcp; | 1459 | return txcp; |
1246 | } | 1460 | } |
1247 | 1461 | ||
1248 | static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | 1462 | static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index) |
1249 | { | 1463 | { |
1250 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1464 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1251 | struct be_eth_wrb *wrb; | 1465 | struct be_eth_wrb *wrb; |
@@ -1264,17 +1478,16 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | |||
1264 | do { | 1478 | do { |
1265 | cur_index = txq->tail; | 1479 | cur_index = txq->tail; |
1266 | wrb = queue_tail_node(txq); | 1480 | wrb = queue_tail_node(txq); |
1267 | unmap_tx_frag(adapter->pdev, wrb, (unmap_skb_hdr && | 1481 | unmap_tx_frag(&adapter->pdev->dev, wrb, |
1268 | skb_headlen(sent_skb))); | 1482 | (unmap_skb_hdr && skb_headlen(sent_skb))); |
1269 | unmap_skb_hdr = false; | 1483 | unmap_skb_hdr = false; |
1270 | 1484 | ||
1271 | num_wrbs++; | 1485 | num_wrbs++; |
1272 | queue_tail_inc(txq); | 1486 | queue_tail_inc(txq); |
1273 | } while (cur_index != last_index); | 1487 | } while (cur_index != last_index); |
1274 | 1488 | ||
1275 | atomic_sub(num_wrbs, &txq->used); | ||
1276 | |||
1277 | kfree_skb(sent_skb); | 1489 | kfree_skb(sent_skb); |
1490 | return num_wrbs; | ||
1278 | } | 1491 | } |
1279 | 1492 | ||
1280 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) | 1493 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) |
@@ -1328,25 +1541,24 @@ static void be_eq_clean(struct be_adapter *adapter, | |||
1328 | be_eq_notify(adapter, eq_obj->q.id, false, true, num); | 1541 | be_eq_notify(adapter, eq_obj->q.id, false, true, num); |
1329 | } | 1542 | } |
1330 | 1543 | ||
1331 | static void be_rx_q_clean(struct be_adapter *adapter) | 1544 | static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) |
1332 | { | 1545 | { |
1333 | struct be_rx_page_info *page_info; | 1546 | struct be_rx_page_info *page_info; |
1334 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 1547 | struct be_queue_info *rxq = &rxo->q; |
1335 | struct be_queue_info *rx_cq = &adapter->rx_obj.cq; | 1548 | struct be_queue_info *rx_cq = &rxo->cq; |
1336 | struct be_eth_rx_compl *rxcp; | 1549 | struct be_rx_compl_info *rxcp; |
1337 | u16 tail; | 1550 | u16 tail; |
1338 | 1551 | ||
1339 | /* First cleanup pending rx completions */ | 1552 | /* First cleanup pending rx completions */ |
1340 | while ((rxcp = be_rx_compl_get(adapter)) != NULL) { | 1553 | while ((rxcp = be_rx_compl_get(rxo)) != NULL) { |
1341 | be_rx_compl_discard(adapter, rxcp); | 1554 | be_rx_compl_discard(adapter, rxo, rxcp); |
1342 | be_rx_compl_reset(rxcp); | 1555 | be_cq_notify(adapter, rx_cq->id, false, 1); |
1343 | be_cq_notify(adapter, rx_cq->id, true, 1); | ||
1344 | } | 1556 | } |
1345 | 1557 | ||
1346 | /* Then free posted rx buffer that were not used */ | 1558 | /* Then free posted rx buffer that were not used */ |
1347 | tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; | 1559 | tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; |
1348 | for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) { | 1560 | for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) { |
1349 | page_info = get_rx_page_info(adapter, tail); | 1561 | page_info = get_rx_page_info(adapter, rxo, tail); |
1350 | put_page(page_info->page); | 1562 | put_page(page_info->page); |
1351 | memset(page_info, 0, sizeof(*page_info)); | 1563 | memset(page_info, 0, sizeof(*page_info)); |
1352 | } | 1564 | } |
@@ -1358,7 +1570,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1358 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1570 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1359 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1571 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1360 | struct be_eth_tx_compl *txcp; | 1572 | struct be_eth_tx_compl *txcp; |
1361 | u16 end_idx, cmpl = 0, timeo = 0; | 1573 | u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0; |
1362 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; | 1574 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; |
1363 | struct sk_buff *sent_skb; | 1575 | struct sk_buff *sent_skb; |
1364 | bool dummy_wrb; | 1576 | bool dummy_wrb; |
@@ -1368,12 +1580,14 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1368 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1580 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1369 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1581 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1370 | wrb_index, txcp); | 1582 | wrb_index, txcp); |
1371 | be_tx_compl_process(adapter, end_idx); | 1583 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1372 | cmpl++; | 1584 | cmpl++; |
1373 | } | 1585 | } |
1374 | if (cmpl) { | 1586 | if (cmpl) { |
1375 | be_cq_notify(adapter, tx_cq->id, false, cmpl); | 1587 | be_cq_notify(adapter, tx_cq->id, false, cmpl); |
1588 | atomic_sub(num_wrbs, &txq->used); | ||
1376 | cmpl = 0; | 1589 | cmpl = 0; |
1590 | num_wrbs = 0; | ||
1377 | } | 1591 | } |
1378 | 1592 | ||
1379 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) | 1593 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) |
@@ -1391,8 +1605,10 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1391 | sent_skb = sent_skbs[txq->tail]; | 1605 | sent_skb = sent_skbs[txq->tail]; |
1392 | end_idx = txq->tail; | 1606 | end_idx = txq->tail; |
1393 | index_adv(&end_idx, | 1607 | index_adv(&end_idx, |
1394 | wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); | 1608 | wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, |
1395 | be_tx_compl_process(adapter, end_idx); | 1609 | txq->len); |
1610 | num_wrbs = be_tx_compl_process(adapter, end_idx); | ||
1611 | atomic_sub(num_wrbs, &txq->used); | ||
1396 | } | 1612 | } |
1397 | } | 1613 | } |
1398 | 1614 | ||
@@ -1486,7 +1702,9 @@ static int be_tx_queues_create(struct be_adapter *adapter) | |||
1486 | /* Ask BE to create Tx Event queue */ | 1702 | /* Ask BE to create Tx Event queue */ |
1487 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) | 1703 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) |
1488 | goto tx_eq_free; | 1704 | goto tx_eq_free; |
1489 | adapter->base_eq_id = adapter->tx_eq.q.id; | 1705 | |
1706 | adapter->tx_eq.eq_idx = adapter->eq_next_idx++; | ||
1707 | |||
1490 | 1708 | ||
1491 | /* Alloc TX eth compl queue */ | 1709 | /* Alloc TX eth compl queue */ |
1492 | cq = &adapter->tx_obj.cq; | 1710 | cq = &adapter->tx_obj.cq; |
@@ -1524,121 +1742,173 @@ tx_eq_free: | |||
1524 | static void be_rx_queues_destroy(struct be_adapter *adapter) | 1742 | static void be_rx_queues_destroy(struct be_adapter *adapter) |
1525 | { | 1743 | { |
1526 | struct be_queue_info *q; | 1744 | struct be_queue_info *q; |
1527 | 1745 | struct be_rx_obj *rxo; | |
1528 | q = &adapter->rx_obj.q; | 1746 | int i; |
1529 | if (q->created) { | 1747 | |
1530 | be_cmd_q_destroy(adapter, q, QTYPE_RXQ); | 1748 | for_all_rx_queues(adapter, rxo, i) { |
1531 | 1749 | q = &rxo->q; | |
1532 | /* After the rxq is invalidated, wait for a grace time | 1750 | if (q->created) { |
1533 | * of 1ms for all dma to end and the flush compl to arrive | 1751 | be_cmd_q_destroy(adapter, q, QTYPE_RXQ); |
1534 | */ | 1752 | /* After the rxq is invalidated, wait for a grace time |
1535 | mdelay(1); | 1753 | * of 1ms for all dma to end and the flush compl to |
1536 | be_rx_q_clean(adapter); | 1754 | * arrive |
1755 | */ | ||
1756 | mdelay(1); | ||
1757 | be_rx_q_clean(adapter, rxo); | ||
1758 | } | ||
1759 | be_queue_free(adapter, q); | ||
1760 | |||
1761 | q = &rxo->cq; | ||
1762 | if (q->created) | ||
1763 | be_cmd_q_destroy(adapter, q, QTYPE_CQ); | ||
1764 | be_queue_free(adapter, q); | ||
1765 | |||
1766 | /* Clear any residual events */ | ||
1767 | q = &rxo->rx_eq.q; | ||
1768 | if (q->created) { | ||
1769 | be_eq_clean(adapter, &rxo->rx_eq); | ||
1770 | be_cmd_q_destroy(adapter, q, QTYPE_EQ); | ||
1771 | } | ||
1772 | be_queue_free(adapter, q); | ||
1537 | } | 1773 | } |
1538 | be_queue_free(adapter, q); | 1774 | } |
1539 | |||
1540 | q = &adapter->rx_obj.cq; | ||
1541 | if (q->created) | ||
1542 | be_cmd_q_destroy(adapter, q, QTYPE_CQ); | ||
1543 | be_queue_free(adapter, q); | ||
1544 | |||
1545 | /* Clear any residual events */ | ||
1546 | be_eq_clean(adapter, &adapter->rx_eq); | ||
1547 | 1775 | ||
1548 | q = &adapter->rx_eq.q; | 1776 | static u32 be_num_rxqs_want(struct be_adapter *adapter) |
1549 | if (q->created) | 1777 | { |
1550 | be_cmd_q_destroy(adapter, q, QTYPE_EQ); | 1778 | if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && |
1551 | be_queue_free(adapter, q); | 1779 | !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { |
1780 | return 1 + MAX_RSS_QS; /* one default non-RSS queue */ | ||
1781 | } else { | ||
1782 | dev_warn(&adapter->pdev->dev, | ||
1783 | "No support for multiple RX queues\n"); | ||
1784 | return 1; | ||
1785 | } | ||
1552 | } | 1786 | } |
1553 | 1787 | ||
1554 | static int be_rx_queues_create(struct be_adapter *adapter) | 1788 | static int be_rx_queues_create(struct be_adapter *adapter) |
1555 | { | 1789 | { |
1556 | struct be_queue_info *eq, *q, *cq; | 1790 | struct be_queue_info *eq, *q, *cq; |
1557 | int rc; | 1791 | struct be_rx_obj *rxo; |
1792 | int rc, i; | ||
1793 | |||
1794 | adapter->num_rx_qs = min(be_num_rxqs_want(adapter), | ||
1795 | msix_enabled(adapter) ? | ||
1796 | adapter->num_msix_vec - 1 : 1); | ||
1797 | if (adapter->num_rx_qs != MAX_RX_QS) | ||
1798 | dev_warn(&adapter->pdev->dev, | ||
1799 | "Can create only %d RX queues", adapter->num_rx_qs); | ||
1558 | 1800 | ||
1559 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; | 1801 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; |
1560 | adapter->rx_eq.max_eqd = BE_MAX_EQD; | 1802 | for_all_rx_queues(adapter, rxo, i) { |
1561 | adapter->rx_eq.min_eqd = 0; | 1803 | rxo->adapter = adapter; |
1562 | adapter->rx_eq.cur_eqd = 0; | 1804 | rxo->rx_eq.max_eqd = BE_MAX_EQD; |
1563 | adapter->rx_eq.enable_aic = true; | 1805 | rxo->rx_eq.enable_aic = true; |
1564 | 1806 | ||
1565 | /* Alloc Rx Event queue */ | 1807 | /* EQ */ |
1566 | eq = &adapter->rx_eq.q; | 1808 | eq = &rxo->rx_eq.q; |
1567 | rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, | 1809 | rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, |
1568 | sizeof(struct be_eq_entry)); | 1810 | sizeof(struct be_eq_entry)); |
1569 | if (rc) | 1811 | if (rc) |
1570 | return rc; | 1812 | goto err; |
1571 | 1813 | ||
1572 | /* Ask BE to create Rx Event queue */ | 1814 | rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd); |
1573 | rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd); | 1815 | if (rc) |
1574 | if (rc) | 1816 | goto err; |
1575 | goto rx_eq_free; | 1817 | |
1576 | 1818 | rxo->rx_eq.eq_idx = adapter->eq_next_idx++; | |
1577 | /* Alloc RX eth compl queue */ | 1819 | |
1578 | cq = &adapter->rx_obj.cq; | 1820 | /* CQ */ |
1579 | rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, | 1821 | cq = &rxo->cq; |
1580 | sizeof(struct be_eth_rx_compl)); | 1822 | rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, |
1581 | if (rc) | 1823 | sizeof(struct be_eth_rx_compl)); |
1582 | goto rx_eq_destroy; | 1824 | if (rc) |
1583 | 1825 | goto err; | |
1584 | /* Ask BE to create Rx eth compl queue */ | 1826 | |
1585 | rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); | 1827 | rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); |
1586 | if (rc) | 1828 | if (rc) |
1587 | goto rx_cq_free; | 1829 | goto err; |
1588 | 1830 | /* Rx Q */ | |
1589 | /* Alloc RX eth queue */ | 1831 | q = &rxo->q; |
1590 | q = &adapter->rx_obj.q; | 1832 | rc = be_queue_alloc(adapter, q, RX_Q_LEN, |
1591 | rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); | 1833 | sizeof(struct be_eth_rx_d)); |
1592 | if (rc) | 1834 | if (rc) |
1593 | goto rx_cq_destroy; | 1835 | goto err; |
1594 | 1836 | ||
1595 | /* Ask BE to create Rx eth queue */ | 1837 | rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, |
1596 | rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, | 1838 | BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, |
1597 | BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false); | 1839 | (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id); |
1598 | if (rc) | 1840 | if (rc) |
1599 | goto rx_q_free; | 1841 | goto err; |
1842 | } | ||
1843 | |||
1844 | if (be_multi_rxq(adapter)) { | ||
1845 | u8 rsstable[MAX_RSS_QS]; | ||
1846 | |||
1847 | for_all_rss_queues(adapter, rxo, i) | ||
1848 | rsstable[i] = rxo->rss_id; | ||
1849 | |||
1850 | rc = be_cmd_rss_config(adapter, rsstable, | ||
1851 | adapter->num_rx_qs - 1); | ||
1852 | if (rc) | ||
1853 | goto err; | ||
1854 | } | ||
1600 | 1855 | ||
1601 | return 0; | 1856 | return 0; |
1602 | rx_q_free: | 1857 | err: |
1603 | be_queue_free(adapter, q); | 1858 | be_rx_queues_destroy(adapter); |
1604 | rx_cq_destroy: | 1859 | return -1; |
1605 | be_cmd_q_destroy(adapter, cq, QTYPE_CQ); | ||
1606 | rx_cq_free: | ||
1607 | be_queue_free(adapter, cq); | ||
1608 | rx_eq_destroy: | ||
1609 | be_cmd_q_destroy(adapter, eq, QTYPE_EQ); | ||
1610 | rx_eq_free: | ||
1611 | be_queue_free(adapter, eq); | ||
1612 | return rc; | ||
1613 | } | 1860 | } |
1614 | 1861 | ||
1615 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ | 1862 | static bool event_peek(struct be_eq_obj *eq_obj) |
1616 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) | ||
1617 | { | 1863 | { |
1618 | return eq_id - adapter->base_eq_id; | 1864 | struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q); |
1865 | if (!eqe->evt) | ||
1866 | return false; | ||
1867 | else | ||
1868 | return true; | ||
1619 | } | 1869 | } |
1620 | 1870 | ||
1621 | static irqreturn_t be_intx(int irq, void *dev) | 1871 | static irqreturn_t be_intx(int irq, void *dev) |
1622 | { | 1872 | { |
1623 | struct be_adapter *adapter = dev; | 1873 | struct be_adapter *adapter = dev; |
1624 | int isr; | 1874 | struct be_rx_obj *rxo; |
1875 | int isr, i, tx = 0 , rx = 0; | ||
1876 | |||
1877 | if (lancer_chip(adapter)) { | ||
1878 | if (event_peek(&adapter->tx_eq)) | ||
1879 | tx = event_handle(adapter, &adapter->tx_eq); | ||
1880 | for_all_rx_queues(adapter, rxo, i) { | ||
1881 | if (event_peek(&rxo->rx_eq)) | ||
1882 | rx |= event_handle(adapter, &rxo->rx_eq); | ||
1883 | } | ||
1625 | 1884 | ||
1626 | isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + | 1885 | if (!(tx || rx)) |
1627 | (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); | 1886 | return IRQ_NONE; |
1628 | if (!isr) | ||
1629 | return IRQ_NONE; | ||
1630 | 1887 | ||
1631 | event_handle(adapter, &adapter->tx_eq); | 1888 | } else { |
1632 | event_handle(adapter, &adapter->rx_eq); | 1889 | isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + |
1890 | (adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE); | ||
1891 | if (!isr) | ||
1892 | return IRQ_NONE; | ||
1893 | |||
1894 | if ((1 << adapter->tx_eq.eq_idx & isr)) | ||
1895 | event_handle(adapter, &adapter->tx_eq); | ||
1896 | |||
1897 | for_all_rx_queues(adapter, rxo, i) { | ||
1898 | if ((1 << rxo->rx_eq.eq_idx & isr)) | ||
1899 | event_handle(adapter, &rxo->rx_eq); | ||
1900 | } | ||
1901 | } | ||
1633 | 1902 | ||
1634 | return IRQ_HANDLED; | 1903 | return IRQ_HANDLED; |
1635 | } | 1904 | } |
1636 | 1905 | ||
1637 | static irqreturn_t be_msix_rx(int irq, void *dev) | 1906 | static irqreturn_t be_msix_rx(int irq, void *dev) |
1638 | { | 1907 | { |
1639 | struct be_adapter *adapter = dev; | 1908 | struct be_rx_obj *rxo = dev; |
1909 | struct be_adapter *adapter = rxo->adapter; | ||
1640 | 1910 | ||
1641 | event_handle(adapter, &adapter->rx_eq); | 1911 | event_handle(adapter, &rxo->rx_eq); |
1642 | 1912 | ||
1643 | return IRQ_HANDLED; | 1913 | return IRQ_HANDLED; |
1644 | } | 1914 | } |
@@ -1652,44 +1922,42 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) | |||
1652 | return IRQ_HANDLED; | 1922 | return IRQ_HANDLED; |
1653 | } | 1923 | } |
1654 | 1924 | ||
1655 | static inline bool do_gro(struct be_adapter *adapter, | 1925 | static inline bool do_gro(struct be_rx_compl_info *rxcp) |
1656 | struct be_eth_rx_compl *rxcp) | ||
1657 | { | 1926 | { |
1658 | int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); | 1927 | return (rxcp->tcpf && !rxcp->err) ? true : false; |
1659 | int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); | ||
1660 | |||
1661 | if (err) | ||
1662 | drvr_stats(adapter)->be_rxcp_err++; | ||
1663 | |||
1664 | return (tcp_frame && !err) ? true : false; | ||
1665 | } | 1928 | } |
1666 | 1929 | ||
1667 | int be_poll_rx(struct napi_struct *napi, int budget) | 1930 | static int be_poll_rx(struct napi_struct *napi, int budget) |
1668 | { | 1931 | { |
1669 | struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); | 1932 | struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); |
1670 | struct be_adapter *adapter = | 1933 | struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); |
1671 | container_of(rx_eq, struct be_adapter, rx_eq); | 1934 | struct be_adapter *adapter = rxo->adapter; |
1672 | struct be_queue_info *rx_cq = &adapter->rx_obj.cq; | 1935 | struct be_queue_info *rx_cq = &rxo->cq; |
1673 | struct be_eth_rx_compl *rxcp; | 1936 | struct be_rx_compl_info *rxcp; |
1674 | u32 work_done; | 1937 | u32 work_done; |
1675 | 1938 | ||
1676 | adapter->stats.drvr_stats.be_rx_polls++; | 1939 | rxo->stats.rx_polls++; |
1677 | for (work_done = 0; work_done < budget; work_done++) { | 1940 | for (work_done = 0; work_done < budget; work_done++) { |
1678 | rxcp = be_rx_compl_get(adapter); | 1941 | rxcp = be_rx_compl_get(rxo); |
1679 | if (!rxcp) | 1942 | if (!rxcp) |
1680 | break; | 1943 | break; |
1681 | 1944 | ||
1682 | if (do_gro(adapter, rxcp)) | 1945 | /* Ignore flush completions */ |
1683 | be_rx_compl_process_gro(adapter, rxcp); | 1946 | if (rxcp->num_rcvd && rxcp->pkt_size) { |
1684 | else | 1947 | if (do_gro(rxcp)) |
1685 | be_rx_compl_process(adapter, rxcp); | 1948 | be_rx_compl_process_gro(adapter, rxo, rxcp); |
1949 | else | ||
1950 | be_rx_compl_process(adapter, rxo, rxcp); | ||
1951 | } else if (rxcp->pkt_size == 0) { | ||
1952 | be_rx_compl_discard(adapter, rxo, rxcp); | ||
1953 | } | ||
1686 | 1954 | ||
1687 | be_rx_compl_reset(rxcp); | 1955 | be_rx_stats_update(rxo, rxcp); |
1688 | } | 1956 | } |
1689 | 1957 | ||
1690 | /* Refill the queue */ | 1958 | /* Refill the queue */ |
1691 | if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM) | 1959 | if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM) |
1692 | be_post_rx_frags(adapter); | 1960 | be_post_rx_frags(rxo, GFP_ATOMIC); |
1693 | 1961 | ||
1694 | /* All consumed */ | 1962 | /* All consumed */ |
1695 | if (work_done < budget) { | 1963 | if (work_done < budget) { |
@@ -1714,12 +1982,12 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1714 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1982 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1715 | struct be_eth_tx_compl *txcp; | 1983 | struct be_eth_tx_compl *txcp; |
1716 | int tx_compl = 0, mcc_compl, status = 0; | 1984 | int tx_compl = 0, mcc_compl, status = 0; |
1717 | u16 end_idx; | 1985 | u16 end_idx, num_wrbs = 0; |
1718 | 1986 | ||
1719 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1987 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1720 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1988 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1721 | wrb_index, txcp); | 1989 | wrb_index, txcp); |
1722 | be_tx_compl_process(adapter, end_idx); | 1990 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1723 | tx_compl++; | 1991 | tx_compl++; |
1724 | } | 1992 | } |
1725 | 1993 | ||
@@ -1735,6 +2003,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1735 | if (tx_compl) { | 2003 | if (tx_compl) { |
1736 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); | 2004 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); |
1737 | 2005 | ||
2006 | atomic_sub(num_wrbs, &txq->used); | ||
2007 | |||
1738 | /* As Tx wrbs have been freed up, wake up netdev queue if | 2008 | /* As Tx wrbs have been freed up, wake up netdev queue if |
1739 | * it was stopped due to lack of tx wrbs. | 2009 | * it was stopped due to lack of tx wrbs. |
1740 | */ | 2010 | */ |
@@ -1743,8 +2013,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1743 | netif_wake_queue(adapter->netdev); | 2013 | netif_wake_queue(adapter->netdev); |
1744 | } | 2014 | } |
1745 | 2015 | ||
1746 | drvr_stats(adapter)->be_tx_events++; | 2016 | tx_stats(adapter)->be_tx_events++; |
1747 | drvr_stats(adapter)->be_tx_compl += tx_compl; | 2017 | tx_stats(adapter)->be_tx_compl += tx_compl; |
1748 | } | 2018 | } |
1749 | 2019 | ||
1750 | return 1; | 2020 | return 1; |
@@ -1769,6 +2039,7 @@ void be_detect_dump_ue(struct be_adapter *adapter) | |||
1769 | 2039 | ||
1770 | if (ue_status_lo || ue_status_hi) { | 2040 | if (ue_status_lo || ue_status_hi) { |
1771 | adapter->ue_detected = true; | 2041 | adapter->ue_detected = true; |
2042 | adapter->eeh_err = true; | ||
1772 | dev_err(&adapter->pdev->dev, "UE Detected!!\n"); | 2043 | dev_err(&adapter->pdev->dev, "UE Detected!!\n"); |
1773 | } | 2044 | } |
1774 | 2045 | ||
@@ -1793,45 +2064,82 @@ static void be_worker(struct work_struct *work) | |||
1793 | { | 2064 | { |
1794 | struct be_adapter *adapter = | 2065 | struct be_adapter *adapter = |
1795 | container_of(work, struct be_adapter, work.work); | 2066 | container_of(work, struct be_adapter, work.work); |
2067 | struct be_rx_obj *rxo; | ||
2068 | int i; | ||
2069 | |||
2070 | if (!adapter->ue_detected && !lancer_chip(adapter)) | ||
2071 | be_detect_dump_ue(adapter); | ||
2072 | |||
2073 | /* when interrupts are not yet enabled, just reap any pending | ||
2074 | * mcc completions */ | ||
2075 | if (!netif_running(adapter->netdev)) { | ||
2076 | int mcc_compl, status = 0; | ||
2077 | |||
2078 | mcc_compl = be_process_mcc(adapter, &status); | ||
1796 | 2079 | ||
1797 | if (!adapter->stats_ioctl_sent) | 2080 | if (mcc_compl) { |
1798 | be_cmd_get_stats(adapter, &adapter->stats.cmd); | 2081 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
2082 | be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl); | ||
2083 | } | ||
1799 | 2084 | ||
1800 | /* Set EQ delay */ | 2085 | goto reschedule; |
1801 | be_rx_eqd_update(adapter); | 2086 | } |
1802 | 2087 | ||
2088 | if (!adapter->stats_cmd_sent) { | ||
2089 | if (lancer_chip(adapter)) | ||
2090 | lancer_cmd_get_pport_stats(adapter, | ||
2091 | &adapter->stats_cmd); | ||
2092 | else | ||
2093 | be_cmd_get_stats(adapter, &adapter->stats_cmd); | ||
2094 | } | ||
1803 | be_tx_rate_update(adapter); | 2095 | be_tx_rate_update(adapter); |
1804 | be_rx_rate_update(adapter); | ||
1805 | 2096 | ||
1806 | if (adapter->rx_post_starved) { | 2097 | for_all_rx_queues(adapter, rxo, i) { |
1807 | adapter->rx_post_starved = false; | 2098 | be_rx_rate_update(rxo); |
1808 | be_post_rx_frags(adapter); | 2099 | be_rx_eqd_update(adapter, rxo); |
2100 | |||
2101 | if (rxo->rx_post_starved) { | ||
2102 | rxo->rx_post_starved = false; | ||
2103 | be_post_rx_frags(rxo, GFP_KERNEL); | ||
2104 | } | ||
1809 | } | 2105 | } |
1810 | if (!adapter->ue_detected) | ||
1811 | be_detect_dump_ue(adapter); | ||
1812 | 2106 | ||
2107 | reschedule: | ||
2108 | adapter->work_counter++; | ||
1813 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); | 2109 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
1814 | } | 2110 | } |
1815 | 2111 | ||
1816 | static void be_msix_disable(struct be_adapter *adapter) | 2112 | static void be_msix_disable(struct be_adapter *adapter) |
1817 | { | 2113 | { |
1818 | if (adapter->msix_enabled) { | 2114 | if (msix_enabled(adapter)) { |
1819 | pci_disable_msix(adapter->pdev); | 2115 | pci_disable_msix(adapter->pdev); |
1820 | adapter->msix_enabled = false; | 2116 | adapter->num_msix_vec = 0; |
1821 | } | 2117 | } |
1822 | } | 2118 | } |
1823 | 2119 | ||
1824 | static void be_msix_enable(struct be_adapter *adapter) | 2120 | static void be_msix_enable(struct be_adapter *adapter) |
1825 | { | 2121 | { |
1826 | int i, status; | 2122 | #define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ |
2123 | int i, status, num_vec; | ||
1827 | 2124 | ||
1828 | for (i = 0; i < BE_NUM_MSIX_VECTORS; i++) | 2125 | num_vec = be_num_rxqs_want(adapter) + 1; |
2126 | |||
2127 | for (i = 0; i < num_vec; i++) | ||
1829 | adapter->msix_entries[i].entry = i; | 2128 | adapter->msix_entries[i].entry = i; |
1830 | 2129 | ||
1831 | status = pci_enable_msix(adapter->pdev, adapter->msix_entries, | 2130 | status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); |
1832 | BE_NUM_MSIX_VECTORS); | 2131 | if (status == 0) { |
1833 | if (status == 0) | 2132 | goto done; |
1834 | adapter->msix_enabled = true; | 2133 | } else if (status >= BE_MIN_MSIX_VECTORS) { |
2134 | num_vec = status; | ||
2135 | if (pci_enable_msix(adapter->pdev, adapter->msix_entries, | ||
2136 | num_vec) == 0) | ||
2137 | goto done; | ||
2138 | } | ||
2139 | return; | ||
2140 | done: | ||
2141 | adapter->num_msix_vec = num_vec; | ||
2142 | return; | ||
1835 | } | 2143 | } |
1836 | 2144 | ||
1837 | static void be_sriov_enable(struct be_adapter *adapter) | 2145 | static void be_sriov_enable(struct be_adapter *adapter) |
@@ -1839,7 +2147,20 @@ static void be_sriov_enable(struct be_adapter *adapter) | |||
1839 | be_check_sriov_fn_type(adapter); | 2147 | be_check_sriov_fn_type(adapter); |
1840 | #ifdef CONFIG_PCI_IOV | 2148 | #ifdef CONFIG_PCI_IOV |
1841 | if (be_physfn(adapter) && num_vfs) { | 2149 | if (be_physfn(adapter) && num_vfs) { |
1842 | int status; | 2150 | int status, pos; |
2151 | u16 nvfs; | ||
2152 | |||
2153 | pos = pci_find_ext_capability(adapter->pdev, | ||
2154 | PCI_EXT_CAP_ID_SRIOV); | ||
2155 | pci_read_config_word(adapter->pdev, | ||
2156 | pos + PCI_SRIOV_TOTAL_VF, &nvfs); | ||
2157 | |||
2158 | if (num_vfs > nvfs) { | ||
2159 | dev_info(&adapter->pdev->dev, | ||
2160 | "Device supports %d VFs and not %d\n", | ||
2161 | nvfs, num_vfs); | ||
2162 | num_vfs = nvfs; | ||
2163 | } | ||
1843 | 2164 | ||
1844 | status = pci_enable_sriov(adapter->pdev, num_vfs); | 2165 | status = pci_enable_sriov(adapter->pdev, num_vfs); |
1845 | adapter->sriov_enabled = status ? false : true; | 2166 | adapter->sriov_enabled = status ? false : true; |
@@ -1857,51 +2178,62 @@ static void be_sriov_disable(struct be_adapter *adapter) | |||
1857 | #endif | 2178 | #endif |
1858 | } | 2179 | } |
1859 | 2180 | ||
1860 | static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) | 2181 | static inline int be_msix_vec_get(struct be_adapter *adapter, |
2182 | struct be_eq_obj *eq_obj) | ||
1861 | { | 2183 | { |
1862 | return adapter->msix_entries[ | 2184 | return adapter->msix_entries[eq_obj->eq_idx].vector; |
1863 | be_evt_bit_get(adapter, eq_id)].vector; | ||
1864 | } | 2185 | } |
1865 | 2186 | ||
1866 | static int be_request_irq(struct be_adapter *adapter, | 2187 | static int be_request_irq(struct be_adapter *adapter, |
1867 | struct be_eq_obj *eq_obj, | 2188 | struct be_eq_obj *eq_obj, |
1868 | void *handler, char *desc) | 2189 | void *handler, char *desc, void *context) |
1869 | { | 2190 | { |
1870 | struct net_device *netdev = adapter->netdev; | 2191 | struct net_device *netdev = adapter->netdev; |
1871 | int vec; | 2192 | int vec; |
1872 | 2193 | ||
1873 | sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); | 2194 | sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); |
1874 | vec = be_msix_vec_get(adapter, eq_obj->q.id); | 2195 | vec = be_msix_vec_get(adapter, eq_obj); |
1875 | return request_irq(vec, handler, 0, eq_obj->desc, adapter); | 2196 | return request_irq(vec, handler, 0, eq_obj->desc, context); |
1876 | } | 2197 | } |
1877 | 2198 | ||
1878 | static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj) | 2199 | static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, |
2200 | void *context) | ||
1879 | { | 2201 | { |
1880 | int vec = be_msix_vec_get(adapter, eq_obj->q.id); | 2202 | int vec = be_msix_vec_get(adapter, eq_obj); |
1881 | free_irq(vec, adapter); | 2203 | free_irq(vec, context); |
1882 | } | 2204 | } |
1883 | 2205 | ||
1884 | static int be_msix_register(struct be_adapter *adapter) | 2206 | static int be_msix_register(struct be_adapter *adapter) |
1885 | { | 2207 | { |
1886 | int status; | 2208 | struct be_rx_obj *rxo; |
2209 | int status, i; | ||
2210 | char qname[10]; | ||
1887 | 2211 | ||
1888 | status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx"); | 2212 | status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx", |
2213 | adapter); | ||
1889 | if (status) | 2214 | if (status) |
1890 | goto err; | 2215 | goto err; |
1891 | 2216 | ||
1892 | status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx"); | 2217 | for_all_rx_queues(adapter, rxo, i) { |
1893 | if (status) | 2218 | sprintf(qname, "rxq%d", i); |
1894 | goto free_tx_irq; | 2219 | status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx, |
2220 | qname, rxo); | ||
2221 | if (status) | ||
2222 | goto err_msix; | ||
2223 | } | ||
1895 | 2224 | ||
1896 | return 0; | 2225 | return 0; |
1897 | 2226 | ||
1898 | free_tx_irq: | 2227 | err_msix: |
1899 | be_free_irq(adapter, &adapter->tx_eq); | 2228 | be_free_irq(adapter, &adapter->tx_eq, adapter); |
2229 | |||
2230 | for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--) | ||
2231 | be_free_irq(adapter, &rxo->rx_eq, rxo); | ||
2232 | |||
1900 | err: | 2233 | err: |
1901 | dev_warn(&adapter->pdev->dev, | 2234 | dev_warn(&adapter->pdev->dev, |
1902 | "MSIX Request IRQ failed - err %d\n", status); | 2235 | "MSIX Request IRQ failed - err %d\n", status); |
1903 | pci_disable_msix(adapter->pdev); | 2236 | be_msix_disable(adapter); |
1904 | adapter->msix_enabled = false; | ||
1905 | return status; | 2237 | return status; |
1906 | } | 2238 | } |
1907 | 2239 | ||
@@ -1910,7 +2242,7 @@ static int be_irq_register(struct be_adapter *adapter) | |||
1910 | struct net_device *netdev = adapter->netdev; | 2242 | struct net_device *netdev = adapter->netdev; |
1911 | int status; | 2243 | int status; |
1912 | 2244 | ||
1913 | if (adapter->msix_enabled) { | 2245 | if (msix_enabled(adapter)) { |
1914 | status = be_msix_register(adapter); | 2246 | status = be_msix_register(adapter); |
1915 | if (status == 0) | 2247 | if (status == 0) |
1916 | goto done; | 2248 | goto done; |
@@ -1936,19 +2268,24 @@ done: | |||
1936 | static void be_irq_unregister(struct be_adapter *adapter) | 2268 | static void be_irq_unregister(struct be_adapter *adapter) |
1937 | { | 2269 | { |
1938 | struct net_device *netdev = adapter->netdev; | 2270 | struct net_device *netdev = adapter->netdev; |
2271 | struct be_rx_obj *rxo; | ||
2272 | int i; | ||
1939 | 2273 | ||
1940 | if (!adapter->isr_registered) | 2274 | if (!adapter->isr_registered) |
1941 | return; | 2275 | return; |
1942 | 2276 | ||
1943 | /* INTx */ | 2277 | /* INTx */ |
1944 | if (!adapter->msix_enabled) { | 2278 | if (!msix_enabled(adapter)) { |
1945 | free_irq(netdev->irq, adapter); | 2279 | free_irq(netdev->irq, adapter); |
1946 | goto done; | 2280 | goto done; |
1947 | } | 2281 | } |
1948 | 2282 | ||
1949 | /* MSIx */ | 2283 | /* MSIx */ |
1950 | be_free_irq(adapter, &adapter->tx_eq); | 2284 | be_free_irq(adapter, &adapter->tx_eq, adapter); |
1951 | be_free_irq(adapter, &adapter->rx_eq); | 2285 | |
2286 | for_all_rx_queues(adapter, rxo, i) | ||
2287 | be_free_irq(adapter, &rxo->rx_eq, rxo); | ||
2288 | |||
1952 | done: | 2289 | done: |
1953 | adapter->isr_registered = false; | 2290 | adapter->isr_registered = false; |
1954 | } | 2291 | } |
@@ -1956,33 +2293,43 @@ done: | |||
1956 | static int be_close(struct net_device *netdev) | 2293 | static int be_close(struct net_device *netdev) |
1957 | { | 2294 | { |
1958 | struct be_adapter *adapter = netdev_priv(netdev); | 2295 | struct be_adapter *adapter = netdev_priv(netdev); |
1959 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | 2296 | struct be_rx_obj *rxo; |
1960 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 2297 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
1961 | int vec; | 2298 | int vec, i; |
1962 | |||
1963 | cancel_delayed_work_sync(&adapter->work); | ||
1964 | 2299 | ||
1965 | be_async_mcc_disable(adapter); | 2300 | be_async_mcc_disable(adapter); |
1966 | 2301 | ||
1967 | netif_stop_queue(netdev); | ||
1968 | netif_carrier_off(netdev); | 2302 | netif_carrier_off(netdev); |
1969 | adapter->link_up = false; | 2303 | adapter->link_up = false; |
1970 | 2304 | ||
1971 | be_intr_set(adapter, false); | 2305 | if (!lancer_chip(adapter)) |
2306 | be_intr_set(adapter, false); | ||
1972 | 2307 | ||
1973 | if (adapter->msix_enabled) { | 2308 | for_all_rx_queues(adapter, rxo, i) |
1974 | vec = be_msix_vec_get(adapter, tx_eq->q.id); | 2309 | napi_disable(&rxo->rx_eq.napi); |
1975 | synchronize_irq(vec); | 2310 | |
1976 | vec = be_msix_vec_get(adapter, rx_eq->q.id); | 2311 | napi_disable(&tx_eq->napi); |
2312 | |||
2313 | if (lancer_chip(adapter)) { | ||
2314 | be_cq_notify(adapter, adapter->tx_obj.cq.id, false, 0); | ||
2315 | be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0); | ||
2316 | for_all_rx_queues(adapter, rxo, i) | ||
2317 | be_cq_notify(adapter, rxo->cq.id, false, 0); | ||
2318 | } | ||
2319 | |||
2320 | if (msix_enabled(adapter)) { | ||
2321 | vec = be_msix_vec_get(adapter, tx_eq); | ||
1977 | synchronize_irq(vec); | 2322 | synchronize_irq(vec); |
2323 | |||
2324 | for_all_rx_queues(adapter, rxo, i) { | ||
2325 | vec = be_msix_vec_get(adapter, &rxo->rx_eq); | ||
2326 | synchronize_irq(vec); | ||
2327 | } | ||
1978 | } else { | 2328 | } else { |
1979 | synchronize_irq(netdev->irq); | 2329 | synchronize_irq(netdev->irq); |
1980 | } | 2330 | } |
1981 | be_irq_unregister(adapter); | 2331 | be_irq_unregister(adapter); |
1982 | 2332 | ||
1983 | napi_disable(&rx_eq->napi); | ||
1984 | napi_disable(&tx_eq->napi); | ||
1985 | |||
1986 | /* Wait for all pending tx completions to arrive so that | 2333 | /* Wait for all pending tx completions to arrive so that |
1987 | * all tx skbs are freed. | 2334 | * all tx skbs are freed. |
1988 | */ | 2335 | */ |
@@ -1994,37 +2341,36 @@ static int be_close(struct net_device *netdev) | |||
1994 | static int be_open(struct net_device *netdev) | 2341 | static int be_open(struct net_device *netdev) |
1995 | { | 2342 | { |
1996 | struct be_adapter *adapter = netdev_priv(netdev); | 2343 | struct be_adapter *adapter = netdev_priv(netdev); |
1997 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | ||
1998 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 2344 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
2345 | struct be_rx_obj *rxo; | ||
1999 | bool link_up; | 2346 | bool link_up; |
2000 | int status; | 2347 | int status, i; |
2001 | u8 mac_speed; | 2348 | u8 mac_speed; |
2002 | u16 link_speed; | 2349 | u16 link_speed; |
2003 | 2350 | ||
2004 | /* First time posting */ | 2351 | for_all_rx_queues(adapter, rxo, i) { |
2005 | be_post_rx_frags(adapter); | 2352 | be_post_rx_frags(rxo, GFP_KERNEL); |
2006 | 2353 | napi_enable(&rxo->rx_eq.napi); | |
2007 | napi_enable(&rx_eq->napi); | 2354 | } |
2008 | napi_enable(&tx_eq->napi); | 2355 | napi_enable(&tx_eq->napi); |
2009 | 2356 | ||
2010 | be_irq_register(adapter); | 2357 | be_irq_register(adapter); |
2011 | 2358 | ||
2012 | be_intr_set(adapter, true); | 2359 | if (!lancer_chip(adapter)) |
2360 | be_intr_set(adapter, true); | ||
2013 | 2361 | ||
2014 | /* The evt queues are created in unarmed state; arm them */ | 2362 | /* The evt queues are created in unarmed state; arm them */ |
2015 | be_eq_notify(adapter, rx_eq->q.id, true, false, 0); | 2363 | for_all_rx_queues(adapter, rxo, i) { |
2364 | be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0); | ||
2365 | be_cq_notify(adapter, rxo->cq.id, true, 0); | ||
2366 | } | ||
2016 | be_eq_notify(adapter, tx_eq->q.id, true, false, 0); | 2367 | be_eq_notify(adapter, tx_eq->q.id, true, false, 0); |
2017 | 2368 | ||
2018 | /* Rx compl queue may be in unarmed state; rearm it */ | ||
2019 | be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); | ||
2020 | |||
2021 | /* Now that interrupts are on we can process async mcc */ | 2369 | /* Now that interrupts are on we can process async mcc */ |
2022 | be_async_mcc_enable(adapter); | 2370 | be_async_mcc_enable(adapter); |
2023 | 2371 | ||
2024 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | ||
2025 | |||
2026 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, | 2372 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, |
2027 | &link_speed); | 2373 | &link_speed, 0); |
2028 | if (status) | 2374 | if (status) |
2029 | goto err; | 2375 | goto err; |
2030 | be_link_status_update(adapter, link_up); | 2376 | be_link_status_update(adapter, link_up); |
@@ -2055,7 +2401,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
2055 | memset(mac, 0, ETH_ALEN); | 2401 | memset(mac, 0, ETH_ALEN); |
2056 | 2402 | ||
2057 | cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); | 2403 | cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); |
2058 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 2404 | cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
2405 | GFP_KERNEL); | ||
2059 | if (cmd.va == NULL) | 2406 | if (cmd.va == NULL) |
2060 | return -1; | 2407 | return -1; |
2061 | memset(cmd.va, 0, cmd.size); | 2408 | memset(cmd.va, 0, cmd.size); |
@@ -2066,8 +2413,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
2066 | if (status) { | 2413 | if (status) { |
2067 | dev_err(&adapter->pdev->dev, | 2414 | dev_err(&adapter->pdev->dev, |
2068 | "Could not enable Wake-on-lan\n"); | 2415 | "Could not enable Wake-on-lan\n"); |
2069 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, | 2416 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, |
2070 | cmd.dma); | 2417 | cmd.dma); |
2071 | return status; | 2418 | return status; |
2072 | } | 2419 | } |
2073 | status = be_cmd_enable_magic_wol(adapter, | 2420 | status = be_cmd_enable_magic_wol(adapter, |
@@ -2080,10 +2427,52 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
2080 | pci_enable_wake(adapter->pdev, PCI_D3cold, 0); | 2427 | pci_enable_wake(adapter->pdev, PCI_D3cold, 0); |
2081 | } | 2428 | } |
2082 | 2429 | ||
2083 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 2430 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); |
2431 | return status; | ||
2432 | } | ||
2433 | |||
2434 | /* | ||
2435 | * Generate a seed MAC address from the PF MAC Address using jhash. | ||
2436 | * MAC Address for VFs are assigned incrementally starting from the seed. | ||
2437 | * These addresses are programmed in the ASIC by the PF and the VF driver | ||
2438 | * queries for the MAC address during its probe. | ||
2439 | */ | ||
2440 | static inline int be_vf_eth_addr_config(struct be_adapter *adapter) | ||
2441 | { | ||
2442 | u32 vf = 0; | ||
2443 | int status = 0; | ||
2444 | u8 mac[ETH_ALEN]; | ||
2445 | |||
2446 | be_vf_eth_addr_generate(adapter, mac); | ||
2447 | |||
2448 | for (vf = 0; vf < num_vfs; vf++) { | ||
2449 | status = be_cmd_pmac_add(adapter, mac, | ||
2450 | adapter->vf_cfg[vf].vf_if_handle, | ||
2451 | &adapter->vf_cfg[vf].vf_pmac_id, | ||
2452 | vf + 1); | ||
2453 | if (status) | ||
2454 | dev_err(&adapter->pdev->dev, | ||
2455 | "Mac address add failed for VF %d\n", vf); | ||
2456 | else | ||
2457 | memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); | ||
2458 | |||
2459 | mac[5] += 1; | ||
2460 | } | ||
2084 | return status; | 2461 | return status; |
2085 | } | 2462 | } |
2086 | 2463 | ||
2464 | static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) | ||
2465 | { | ||
2466 | u32 vf; | ||
2467 | |||
2468 | for (vf = 0; vf < num_vfs; vf++) { | ||
2469 | if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) | ||
2470 | be_cmd_pmac_del(adapter, | ||
2471 | adapter->vf_cfg[vf].vf_if_handle, | ||
2472 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); | ||
2473 | } | ||
2474 | } | ||
2475 | |||
2087 | static int be_setup(struct be_adapter *adapter) | 2476 | static int be_setup(struct be_adapter *adapter) |
2088 | { | 2477 | { |
2089 | struct net_device *netdev = adapter->netdev; | 2478 | struct net_device *netdev = adapter->netdev; |
@@ -2091,13 +2480,20 @@ static int be_setup(struct be_adapter *adapter) | |||
2091 | int status; | 2480 | int status; |
2092 | u8 mac[ETH_ALEN]; | 2481 | u8 mac[ETH_ALEN]; |
2093 | 2482 | ||
2094 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; | 2483 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | |
2484 | BE_IF_FLAGS_BROADCAST | | ||
2485 | BE_IF_FLAGS_MULTICAST; | ||
2095 | 2486 | ||
2096 | if (be_physfn(adapter)) { | 2487 | if (be_physfn(adapter)) { |
2097 | cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | | 2488 | cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | |
2098 | BE_IF_FLAGS_PROMISCUOUS | | 2489 | BE_IF_FLAGS_PROMISCUOUS | |
2099 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2490 | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2100 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2491 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2492 | |||
2493 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { | ||
2494 | cap_flags |= BE_IF_FLAGS_RSS; | ||
2495 | en_flags |= BE_IF_FLAGS_RSS; | ||
2496 | } | ||
2101 | } | 2497 | } |
2102 | 2498 | ||
2103 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2499 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
@@ -2107,22 +2503,26 @@ static int be_setup(struct be_adapter *adapter) | |||
2107 | goto do_none; | 2503 | goto do_none; |
2108 | 2504 | ||
2109 | if (be_physfn(adapter)) { | 2505 | if (be_physfn(adapter)) { |
2110 | while (vf < num_vfs) { | 2506 | if (adapter->sriov_enabled) { |
2111 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | 2507 | while (vf < num_vfs) { |
2112 | | BE_IF_FLAGS_BROADCAST; | 2508 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | |
2113 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2509 | BE_IF_FLAGS_BROADCAST; |
2114 | mac, true, | 2510 | status = be_cmd_if_create(adapter, cap_flags, |
2511 | en_flags, mac, true, | ||
2115 | &adapter->vf_cfg[vf].vf_if_handle, | 2512 | &adapter->vf_cfg[vf].vf_if_handle, |
2116 | NULL, vf+1); | 2513 | NULL, vf+1); |
2117 | if (status) { | 2514 | if (status) { |
2118 | dev_err(&adapter->pdev->dev, | 2515 | dev_err(&adapter->pdev->dev, |
2119 | "Interface Create failed for VF %d\n", vf); | 2516 | "Interface Create failed for VF %d\n", |
2120 | goto if_destroy; | 2517 | vf); |
2518 | goto if_destroy; | ||
2519 | } | ||
2520 | adapter->vf_cfg[vf].vf_pmac_id = | ||
2521 | BE_INVALID_PMAC_ID; | ||
2522 | vf++; | ||
2121 | } | 2523 | } |
2122 | adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; | ||
2123 | vf++; | ||
2124 | } | 2524 | } |
2125 | } else if (!be_physfn(adapter)) { | 2525 | } else { |
2126 | status = be_cmd_mac_addr_query(adapter, mac, | 2526 | status = be_cmd_mac_addr_query(adapter, mac, |
2127 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | 2527 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); |
2128 | if (!status) { | 2528 | if (!status) { |
@@ -2152,22 +2552,37 @@ rx_qs_destroy: | |||
2152 | tx_qs_destroy: | 2552 | tx_qs_destroy: |
2153 | be_tx_queues_destroy(adapter); | 2553 | be_tx_queues_destroy(adapter); |
2154 | if_destroy: | 2554 | if_destroy: |
2155 | for (vf = 0; vf < num_vfs; vf++) | 2555 | if (be_physfn(adapter) && adapter->sriov_enabled) |
2156 | if (adapter->vf_cfg[vf].vf_if_handle) | 2556 | for (vf = 0; vf < num_vfs; vf++) |
2157 | be_cmd_if_destroy(adapter, | 2557 | if (adapter->vf_cfg[vf].vf_if_handle) |
2158 | adapter->vf_cfg[vf].vf_if_handle); | 2558 | be_cmd_if_destroy(adapter, |
2159 | be_cmd_if_destroy(adapter, adapter->if_handle); | 2559 | adapter->vf_cfg[vf].vf_if_handle, |
2560 | vf + 1); | ||
2561 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); | ||
2160 | do_none: | 2562 | do_none: |
2161 | return status; | 2563 | return status; |
2162 | } | 2564 | } |
2163 | 2565 | ||
2164 | static int be_clear(struct be_adapter *adapter) | 2566 | static int be_clear(struct be_adapter *adapter) |
2165 | { | 2567 | { |
2568 | int vf; | ||
2569 | |||
2570 | if (be_physfn(adapter) && adapter->sriov_enabled) | ||
2571 | be_vf_eth_addr_rem(adapter); | ||
2572 | |||
2166 | be_mcc_queues_destroy(adapter); | 2573 | be_mcc_queues_destroy(adapter); |
2167 | be_rx_queues_destroy(adapter); | 2574 | be_rx_queues_destroy(adapter); |
2168 | be_tx_queues_destroy(adapter); | 2575 | be_tx_queues_destroy(adapter); |
2576 | adapter->eq_next_idx = 0; | ||
2577 | |||
2578 | if (be_physfn(adapter) && adapter->sriov_enabled) | ||
2579 | for (vf = 0; vf < num_vfs; vf++) | ||
2580 | if (adapter->vf_cfg[vf].vf_if_handle) | ||
2581 | be_cmd_if_destroy(adapter, | ||
2582 | adapter->vf_cfg[vf].vf_if_handle, | ||
2583 | vf + 1); | ||
2169 | 2584 | ||
2170 | be_cmd_if_destroy(adapter, adapter->if_handle); | 2585 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); |
2171 | 2586 | ||
2172 | /* tell fw we're done with firing cmds */ | 2587 | /* tell fw we're done with firing cmds */ |
2173 | be_cmd_fw_clean(adapter); | 2588 | be_cmd_fw_clean(adapter); |
@@ -2176,9 +2591,6 @@ static int be_clear(struct be_adapter *adapter) | |||
2176 | 2591 | ||
2177 | 2592 | ||
2178 | #define FW_FILE_HDR_SIGN "ServerEngines Corp. " | 2593 | #define FW_FILE_HDR_SIGN "ServerEngines Corp. " |
2179 | char flash_cookie[2][16] = {"*** SE FLAS", | ||
2180 | "H DIRECTORY *** "}; | ||
2181 | |||
2182 | static bool be_flash_redboot(struct be_adapter *adapter, | 2594 | static bool be_flash_redboot(struct be_adapter *adapter, |
2183 | const u8 *p, u32 img_start, int image_size, | 2595 | const u8 *p, u32 img_start, int image_size, |
2184 | int hdr_size) | 2596 | int hdr_size) |
@@ -2216,10 +2628,10 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2216 | int num_bytes; | 2628 | int num_bytes; |
2217 | const u8 *p = fw->data; | 2629 | const u8 *p = fw->data; |
2218 | struct be_cmd_write_flashrom *req = flash_cmd->va; | 2630 | struct be_cmd_write_flashrom *req = flash_cmd->va; |
2219 | struct flash_comp *pflashcomp; | 2631 | const struct flash_comp *pflashcomp; |
2220 | int num_comp; | 2632 | int num_comp; |
2221 | 2633 | ||
2222 | struct flash_comp gen3_flash_types[9] = { | 2634 | static const struct flash_comp gen3_flash_types[9] = { |
2223 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, | 2635 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, |
2224 | FLASH_IMAGE_MAX_SIZE_g3}, | 2636 | FLASH_IMAGE_MAX_SIZE_g3}, |
2225 | { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, | 2637 | { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, |
@@ -2239,7 +2651,7 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2239 | { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, | 2651 | { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, |
2240 | FLASH_NCSI_IMAGE_MAX_SIZE_g3} | 2652 | FLASH_NCSI_IMAGE_MAX_SIZE_g3} |
2241 | }; | 2653 | }; |
2242 | struct flash_comp gen2_flash_types[8] = { | 2654 | static const struct flash_comp gen2_flash_types[8] = { |
2243 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, | 2655 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, |
2244 | FLASH_IMAGE_MAX_SIZE_g2}, | 2656 | FLASH_IMAGE_MAX_SIZE_g2}, |
2245 | { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT, | 2657 | { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT, |
@@ -2261,11 +2673,11 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2261 | if (adapter->generation == BE_GEN3) { | 2673 | if (adapter->generation == BE_GEN3) { |
2262 | pflashcomp = gen3_flash_types; | 2674 | pflashcomp = gen3_flash_types; |
2263 | filehdr_size = sizeof(struct flash_file_hdr_g3); | 2675 | filehdr_size = sizeof(struct flash_file_hdr_g3); |
2264 | num_comp = 9; | 2676 | num_comp = ARRAY_SIZE(gen3_flash_types); |
2265 | } else { | 2677 | } else { |
2266 | pflashcomp = gen2_flash_types; | 2678 | pflashcomp = gen2_flash_types; |
2267 | filehdr_size = sizeof(struct flash_file_hdr_g2); | 2679 | filehdr_size = sizeof(struct flash_file_hdr_g2); |
2268 | num_comp = 8; | 2680 | num_comp = ARRAY_SIZE(gen2_flash_types); |
2269 | } | 2681 | } |
2270 | for (i = 0; i < num_comp; i++) { | 2682 | for (i = 0; i < num_comp; i++) { |
2271 | if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && | 2683 | if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && |
@@ -2273,8 +2685,8 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2273 | continue; | 2685 | continue; |
2274 | if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && | 2686 | if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && |
2275 | (!be_flash_redboot(adapter, fw->data, | 2687 | (!be_flash_redboot(adapter, fw->data, |
2276 | pflashcomp[i].offset, pflashcomp[i].size, | 2688 | pflashcomp[i].offset, pflashcomp[i].size, filehdr_size + |
2277 | filehdr_size))) | 2689 | (num_of_images * sizeof(struct image_hdr))))) |
2278 | continue; | 2690 | continue; |
2279 | p = fw->data; | 2691 | p = fw->data; |
2280 | p += filehdr_size + pflashcomp[i].offset | 2692 | p += filehdr_size + pflashcomp[i].offset |
@@ -2302,7 +2714,6 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2302 | "cmd to write to flash rom failed.\n"); | 2714 | "cmd to write to flash rom failed.\n"); |
2303 | return -1; | 2715 | return -1; |
2304 | } | 2716 | } |
2305 | yield(); | ||
2306 | } | 2717 | } |
2307 | } | 2718 | } |
2308 | return 0; | 2719 | return 0; |
@@ -2320,35 +2731,105 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) | |||
2320 | return 0; | 2731 | return 0; |
2321 | } | 2732 | } |
2322 | 2733 | ||
2323 | int be_load_fw(struct be_adapter *adapter, u8 *func) | 2734 | static int lancer_fw_download(struct be_adapter *adapter, |
2735 | const struct firmware *fw) | ||
2736 | { | ||
2737 | #define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024) | ||
2738 | #define LANCER_FW_DOWNLOAD_LOCATION "/prg" | ||
2739 | struct be_dma_mem flash_cmd; | ||
2740 | const u8 *data_ptr = NULL; | ||
2741 | u8 *dest_image_ptr = NULL; | ||
2742 | size_t image_size = 0; | ||
2743 | u32 chunk_size = 0; | ||
2744 | u32 data_written = 0; | ||
2745 | u32 offset = 0; | ||
2746 | int status = 0; | ||
2747 | u8 add_status = 0; | ||
2748 | |||
2749 | if (!IS_ALIGNED(fw->size, sizeof(u32))) { | ||
2750 | dev_err(&adapter->pdev->dev, | ||
2751 | "FW Image not properly aligned. " | ||
2752 | "Length must be 4 byte aligned.\n"); | ||
2753 | status = -EINVAL; | ||
2754 | goto lancer_fw_exit; | ||
2755 | } | ||
2756 | |||
2757 | flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) | ||
2758 | + LANCER_FW_DOWNLOAD_CHUNK; | ||
2759 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, | ||
2760 | &flash_cmd.dma, GFP_KERNEL); | ||
2761 | if (!flash_cmd.va) { | ||
2762 | status = -ENOMEM; | ||
2763 | dev_err(&adapter->pdev->dev, | ||
2764 | "Memory allocation failure while flashing\n"); | ||
2765 | goto lancer_fw_exit; | ||
2766 | } | ||
2767 | |||
2768 | dest_image_ptr = flash_cmd.va + | ||
2769 | sizeof(struct lancer_cmd_req_write_object); | ||
2770 | image_size = fw->size; | ||
2771 | data_ptr = fw->data; | ||
2772 | |||
2773 | while (image_size) { | ||
2774 | chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK); | ||
2775 | |||
2776 | /* Copy the image chunk content. */ | ||
2777 | memcpy(dest_image_ptr, data_ptr, chunk_size); | ||
2778 | |||
2779 | status = lancer_cmd_write_object(adapter, &flash_cmd, | ||
2780 | chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION, | ||
2781 | &data_written, &add_status); | ||
2782 | |||
2783 | if (status) | ||
2784 | break; | ||
2785 | |||
2786 | offset += data_written; | ||
2787 | data_ptr += data_written; | ||
2788 | image_size -= data_written; | ||
2789 | } | ||
2790 | |||
2791 | if (!status) { | ||
2792 | /* Commit the FW written */ | ||
2793 | status = lancer_cmd_write_object(adapter, &flash_cmd, | ||
2794 | 0, offset, LANCER_FW_DOWNLOAD_LOCATION, | ||
2795 | &data_written, &add_status); | ||
2796 | } | ||
2797 | |||
2798 | dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, | ||
2799 | flash_cmd.dma); | ||
2800 | if (status) { | ||
2801 | dev_err(&adapter->pdev->dev, | ||
2802 | "Firmware load error. " | ||
2803 | "Status code: 0x%x Additional Status: 0x%x\n", | ||
2804 | status, add_status); | ||
2805 | goto lancer_fw_exit; | ||
2806 | } | ||
2807 | |||
2808 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); | ||
2809 | lancer_fw_exit: | ||
2810 | return status; | ||
2811 | } | ||
2812 | |||
2813 | static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | ||
2324 | { | 2814 | { |
2325 | char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; | ||
2326 | const struct firmware *fw; | ||
2327 | struct flash_file_hdr_g2 *fhdr; | 2815 | struct flash_file_hdr_g2 *fhdr; |
2328 | struct flash_file_hdr_g3 *fhdr3; | 2816 | struct flash_file_hdr_g3 *fhdr3; |
2329 | struct image_hdr *img_hdr_ptr = NULL; | 2817 | struct image_hdr *img_hdr_ptr = NULL; |
2330 | struct be_dma_mem flash_cmd; | 2818 | struct be_dma_mem flash_cmd; |
2331 | int status, i = 0, num_imgs = 0; | ||
2332 | const u8 *p; | 2819 | const u8 *p; |
2333 | 2820 | int status = 0, i = 0, num_imgs = 0; | |
2334 | strcpy(fw_file, func); | ||
2335 | |||
2336 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); | ||
2337 | if (status) | ||
2338 | goto fw_exit; | ||
2339 | 2821 | ||
2340 | p = fw->data; | 2822 | p = fw->data; |
2341 | fhdr = (struct flash_file_hdr_g2 *) p; | 2823 | fhdr = (struct flash_file_hdr_g2 *) p; |
2342 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); | ||
2343 | 2824 | ||
2344 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; | 2825 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; |
2345 | flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size, | 2826 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, |
2346 | &flash_cmd.dma); | 2827 | &flash_cmd.dma, GFP_KERNEL); |
2347 | if (!flash_cmd.va) { | 2828 | if (!flash_cmd.va) { |
2348 | status = -ENOMEM; | 2829 | status = -ENOMEM; |
2349 | dev_err(&adapter->pdev->dev, | 2830 | dev_err(&adapter->pdev->dev, |
2350 | "Memory allocation failure while flashing\n"); | 2831 | "Memory allocation failure while flashing\n"); |
2351 | goto fw_exit; | 2832 | goto be_fw_exit; |
2352 | } | 2833 | } |
2353 | 2834 | ||
2354 | if ((adapter->generation == BE_GEN3) && | 2835 | if ((adapter->generation == BE_GEN3) && |
@@ -2372,15 +2853,41 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
2372 | status = -1; | 2853 | status = -1; |
2373 | } | 2854 | } |
2374 | 2855 | ||
2375 | pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va, | 2856 | dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, |
2376 | flash_cmd.dma); | 2857 | flash_cmd.dma); |
2377 | if (status) { | 2858 | if (status) { |
2378 | dev_err(&adapter->pdev->dev, "Firmware load error\n"); | 2859 | dev_err(&adapter->pdev->dev, "Firmware load error\n"); |
2379 | goto fw_exit; | 2860 | goto be_fw_exit; |
2380 | } | 2861 | } |
2381 | 2862 | ||
2382 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); | 2863 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); |
2383 | 2864 | ||
2865 | be_fw_exit: | ||
2866 | return status; | ||
2867 | } | ||
2868 | |||
2869 | int be_load_fw(struct be_adapter *adapter, u8 *fw_file) | ||
2870 | { | ||
2871 | const struct firmware *fw; | ||
2872 | int status; | ||
2873 | |||
2874 | if (!netif_running(adapter->netdev)) { | ||
2875 | dev_err(&adapter->pdev->dev, | ||
2876 | "Firmware load not allowed (interface is down)\n"); | ||
2877 | return -1; | ||
2878 | } | ||
2879 | |||
2880 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); | ||
2881 | if (status) | ||
2882 | goto fw_exit; | ||
2883 | |||
2884 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); | ||
2885 | |||
2886 | if (lancer_chip(adapter)) | ||
2887 | status = lancer_fw_download(adapter, fw); | ||
2888 | else | ||
2889 | status = be_fw_download(adapter, fw); | ||
2890 | |||
2384 | fw_exit: | 2891 | fw_exit: |
2385 | release_firmware(fw); | 2892 | release_firmware(fw); |
2386 | return status; | 2893 | return status; |
@@ -2390,7 +2897,6 @@ static struct net_device_ops be_netdev_ops = { | |||
2390 | .ndo_open = be_open, | 2897 | .ndo_open = be_open, |
2391 | .ndo_stop = be_close, | 2898 | .ndo_stop = be_close, |
2392 | .ndo_start_xmit = be_xmit, | 2899 | .ndo_start_xmit = be_xmit, |
2393 | .ndo_get_stats = be_get_stats, | ||
2394 | .ndo_set_rx_mode = be_set_multicast_list, | 2900 | .ndo_set_rx_mode = be_set_multicast_list, |
2395 | .ndo_set_mac_address = be_mac_addr_set, | 2901 | .ndo_set_mac_address = be_mac_addr_set, |
2396 | .ndo_change_mtu = be_change_mtu, | 2902 | .ndo_change_mtu = be_change_mtu, |
@@ -2407,16 +2913,25 @@ static struct net_device_ops be_netdev_ops = { | |||
2407 | static void be_netdev_init(struct net_device *netdev) | 2913 | static void be_netdev_init(struct net_device *netdev) |
2408 | { | 2914 | { |
2409 | struct be_adapter *adapter = netdev_priv(netdev); | 2915 | struct be_adapter *adapter = netdev_priv(netdev); |
2916 | struct be_rx_obj *rxo; | ||
2917 | int i; | ||
2410 | 2918 | ||
2411 | netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | | 2919 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
2412 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM | | 2920 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | |
2413 | NETIF_F_GRO | NETIF_F_TSO6; | 2921 | NETIF_F_HW_VLAN_TX; |
2922 | if (be_multi_rxq(adapter)) | ||
2923 | netdev->hw_features |= NETIF_F_RXHASH; | ||
2414 | 2924 | ||
2415 | netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM; | 2925 | netdev->features |= netdev->hw_features | |
2926 | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; | ||
2416 | 2927 | ||
2417 | netdev->flags |= IFF_MULTICAST; | 2928 | netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | |
2929 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | ||
2930 | |||
2931 | if (lancer_chip(adapter)) | ||
2932 | netdev->vlan_features |= NETIF_F_TSO6; | ||
2418 | 2933 | ||
2419 | adapter->rx_csum = true; | 2934 | netdev->flags |= IFF_MULTICAST; |
2420 | 2935 | ||
2421 | /* Default settings for Rx and Tx flow control */ | 2936 | /* Default settings for Rx and Tx flow control */ |
2422 | adapter->rx_fc = true; | 2937 | adapter->rx_fc = true; |
@@ -2428,13 +2943,12 @@ static void be_netdev_init(struct net_device *netdev) | |||
2428 | 2943 | ||
2429 | SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); | 2944 | SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); |
2430 | 2945 | ||
2431 | netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, | 2946 | for_all_rx_queues(adapter, rxo, i) |
2432 | BE_NAPI_WEIGHT); | 2947 | netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx, |
2948 | BE_NAPI_WEIGHT); | ||
2949 | |||
2433 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, | 2950 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, |
2434 | BE_NAPI_WEIGHT); | 2951 | BE_NAPI_WEIGHT); |
2435 | |||
2436 | netif_carrier_off(netdev); | ||
2437 | netif_stop_queue(netdev); | ||
2438 | } | 2952 | } |
2439 | 2953 | ||
2440 | static void be_unmap_pci_bars(struct be_adapter *adapter) | 2954 | static void be_unmap_pci_bars(struct be_adapter *adapter) |
@@ -2452,6 +2966,15 @@ static int be_map_pci_bars(struct be_adapter *adapter) | |||
2452 | u8 __iomem *addr; | 2966 | u8 __iomem *addr; |
2453 | int pcicfg_reg, db_reg; | 2967 | int pcicfg_reg, db_reg; |
2454 | 2968 | ||
2969 | if (lancer_chip(adapter)) { | ||
2970 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0), | ||
2971 | pci_resource_len(adapter->pdev, 0)); | ||
2972 | if (addr == NULL) | ||
2973 | return -ENOMEM; | ||
2974 | adapter->db = addr; | ||
2975 | return 0; | ||
2976 | } | ||
2977 | |||
2455 | if (be_physfn(adapter)) { | 2978 | if (be_physfn(adapter)) { |
2456 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), | 2979 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), |
2457 | pci_resource_len(adapter->pdev, 2)); | 2980 | pci_resource_len(adapter->pdev, 2)); |
@@ -2500,13 +3023,13 @@ static void be_ctrl_cleanup(struct be_adapter *adapter) | |||
2500 | be_unmap_pci_bars(adapter); | 3023 | be_unmap_pci_bars(adapter); |
2501 | 3024 | ||
2502 | if (mem->va) | 3025 | if (mem->va) |
2503 | pci_free_consistent(adapter->pdev, mem->size, | 3026 | dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, |
2504 | mem->va, mem->dma); | 3027 | mem->dma); |
2505 | 3028 | ||
2506 | mem = &adapter->mc_cmd_mem; | 3029 | mem = &adapter->mc_cmd_mem; |
2507 | if (mem->va) | 3030 | if (mem->va) |
2508 | pci_free_consistent(adapter->pdev, mem->size, | 3031 | dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, |
2509 | mem->va, mem->dma); | 3032 | mem->dma); |
2510 | } | 3033 | } |
2511 | 3034 | ||
2512 | static int be_ctrl_init(struct be_adapter *adapter) | 3035 | static int be_ctrl_init(struct be_adapter *adapter) |
@@ -2521,8 +3044,10 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
2521 | goto done; | 3044 | goto done; |
2522 | 3045 | ||
2523 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; | 3046 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; |
2524 | mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, | 3047 | mbox_mem_alloc->va = dma_alloc_coherent(&adapter->pdev->dev, |
2525 | mbox_mem_alloc->size, &mbox_mem_alloc->dma); | 3048 | mbox_mem_alloc->size, |
3049 | &mbox_mem_alloc->dma, | ||
3050 | GFP_KERNEL); | ||
2526 | if (!mbox_mem_alloc->va) { | 3051 | if (!mbox_mem_alloc->va) { |
2527 | status = -ENOMEM; | 3052 | status = -ENOMEM; |
2528 | goto unmap_pci_bars; | 3053 | goto unmap_pci_bars; |
@@ -2534,15 +3059,16 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
2534 | memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); | 3059 | memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); |
2535 | 3060 | ||
2536 | mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config); | 3061 | mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config); |
2537 | mc_cmd_mem->va = pci_alloc_consistent(adapter->pdev, mc_cmd_mem->size, | 3062 | mc_cmd_mem->va = dma_alloc_coherent(&adapter->pdev->dev, |
2538 | &mc_cmd_mem->dma); | 3063 | mc_cmd_mem->size, &mc_cmd_mem->dma, |
3064 | GFP_KERNEL); | ||
2539 | if (mc_cmd_mem->va == NULL) { | 3065 | if (mc_cmd_mem->va == NULL) { |
2540 | status = -ENOMEM; | 3066 | status = -ENOMEM; |
2541 | goto free_mbox; | 3067 | goto free_mbox; |
2542 | } | 3068 | } |
2543 | memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); | 3069 | memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); |
2544 | 3070 | ||
2545 | spin_lock_init(&adapter->mbox_lock); | 3071 | mutex_init(&adapter->mbox_lock); |
2546 | spin_lock_init(&adapter->mcc_lock); | 3072 | spin_lock_init(&adapter->mcc_lock); |
2547 | spin_lock_init(&adapter->mcc_cq_lock); | 3073 | spin_lock_init(&adapter->mcc_cq_lock); |
2548 | 3074 | ||
@@ -2551,8 +3077,8 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
2551 | return 0; | 3077 | return 0; |
2552 | 3078 | ||
2553 | free_mbox: | 3079 | free_mbox: |
2554 | pci_free_consistent(adapter->pdev, mbox_mem_alloc->size, | 3080 | dma_free_coherent(&adapter->pdev->dev, mbox_mem_alloc->size, |
2555 | mbox_mem_alloc->va, mbox_mem_alloc->dma); | 3081 | mbox_mem_alloc->va, mbox_mem_alloc->dma); |
2556 | 3082 | ||
2557 | unmap_pci_bars: | 3083 | unmap_pci_bars: |
2558 | be_unmap_pci_bars(adapter); | 3084 | be_unmap_pci_bars(adapter); |
@@ -2563,21 +3089,27 @@ done: | |||
2563 | 3089 | ||
2564 | static void be_stats_cleanup(struct be_adapter *adapter) | 3090 | static void be_stats_cleanup(struct be_adapter *adapter) |
2565 | { | 3091 | { |
2566 | struct be_stats_obj *stats = &adapter->stats; | 3092 | struct be_dma_mem *cmd = &adapter->stats_cmd; |
2567 | struct be_dma_mem *cmd = &stats->cmd; | ||
2568 | 3093 | ||
2569 | if (cmd->va) | 3094 | if (cmd->va) |
2570 | pci_free_consistent(adapter->pdev, cmd->size, | 3095 | dma_free_coherent(&adapter->pdev->dev, cmd->size, |
2571 | cmd->va, cmd->dma); | 3096 | cmd->va, cmd->dma); |
2572 | } | 3097 | } |
2573 | 3098 | ||
2574 | static int be_stats_init(struct be_adapter *adapter) | 3099 | static int be_stats_init(struct be_adapter *adapter) |
2575 | { | 3100 | { |
2576 | struct be_stats_obj *stats = &adapter->stats; | 3101 | struct be_dma_mem *cmd = &adapter->stats_cmd; |
2577 | struct be_dma_mem *cmd = &stats->cmd; | ||
2578 | 3102 | ||
2579 | cmd->size = sizeof(struct be_cmd_req_get_stats); | 3103 | if (adapter->generation == BE_GEN2) { |
2580 | cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); | 3104 | cmd->size = sizeof(struct be_cmd_req_get_stats_v0); |
3105 | } else { | ||
3106 | if (lancer_chip(adapter)) | ||
3107 | cmd->size = sizeof(struct lancer_cmd_req_pport_stats); | ||
3108 | else | ||
3109 | cmd->size = sizeof(struct be_cmd_req_get_stats_v1); | ||
3110 | } | ||
3111 | cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, | ||
3112 | GFP_KERNEL); | ||
2581 | if (cmd->va == NULL) | 3113 | if (cmd->va == NULL) |
2582 | return -1; | 3114 | return -1; |
2583 | memset(cmd->va, 0, cmd->size); | 3115 | memset(cmd->va, 0, cmd->size); |
@@ -2591,6 +3123,8 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
2591 | if (!adapter) | 3123 | if (!adapter) |
2592 | return; | 3124 | return; |
2593 | 3125 | ||
3126 | cancel_delayed_work_sync(&adapter->work); | ||
3127 | |||
2594 | unregister_netdev(adapter->netdev); | 3128 | unregister_netdev(adapter->netdev); |
2595 | 3129 | ||
2596 | be_clear(adapter); | 3130 | be_clear(adapter); |
@@ -2599,6 +3133,7 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
2599 | 3133 | ||
2600 | be_ctrl_cleanup(adapter); | 3134 | be_ctrl_cleanup(adapter); |
2601 | 3135 | ||
3136 | kfree(adapter->vf_cfg); | ||
2602 | be_sriov_disable(adapter); | 3137 | be_sriov_disable(adapter); |
2603 | 3138 | ||
2604 | be_msix_disable(adapter); | 3139 | be_msix_disable(adapter); |
@@ -2619,14 +3154,15 @@ static int be_get_config(struct be_adapter *adapter) | |||
2619 | if (status) | 3154 | if (status) |
2620 | return status; | 3155 | return status; |
2621 | 3156 | ||
2622 | status = be_cmd_query_fw_cfg(adapter, | 3157 | status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, |
2623 | &adapter->port_num, &adapter->function_mode); | 3158 | &adapter->function_mode, &adapter->function_caps); |
2624 | if (status) | 3159 | if (status) |
2625 | return status; | 3160 | return status; |
2626 | 3161 | ||
2627 | memset(mac, 0, ETH_ALEN); | 3162 | memset(mac, 0, ETH_ALEN); |
2628 | 3163 | ||
2629 | if (be_physfn(adapter)) { | 3164 | /* A default permanent address is given to each VF for Lancer*/ |
3165 | if (be_physfn(adapter) || lancer_chip(adapter)) { | ||
2630 | status = be_cmd_mac_addr_query(adapter, mac, | 3166 | status = be_cmd_mac_addr_query(adapter, mac, |
2631 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); | 3167 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); |
2632 | 3168 | ||
@@ -2645,9 +3181,97 @@ static int be_get_config(struct be_adapter *adapter) | |||
2645 | else | 3181 | else |
2646 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; | 3182 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; |
2647 | 3183 | ||
3184 | status = be_cmd_get_cntl_attributes(adapter); | ||
3185 | if (status) | ||
3186 | return status; | ||
3187 | |||
3188 | be_cmd_check_native_mode(adapter); | ||
3189 | return 0; | ||
3190 | } | ||
3191 | |||
3192 | static int be_dev_family_check(struct be_adapter *adapter) | ||
3193 | { | ||
3194 | struct pci_dev *pdev = adapter->pdev; | ||
3195 | u32 sli_intf = 0, if_type; | ||
3196 | |||
3197 | switch (pdev->device) { | ||
3198 | case BE_DEVICE_ID1: | ||
3199 | case OC_DEVICE_ID1: | ||
3200 | adapter->generation = BE_GEN2; | ||
3201 | break; | ||
3202 | case BE_DEVICE_ID2: | ||
3203 | case OC_DEVICE_ID2: | ||
3204 | adapter->generation = BE_GEN3; | ||
3205 | break; | ||
3206 | case OC_DEVICE_ID3: | ||
3207 | case OC_DEVICE_ID4: | ||
3208 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3209 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | ||
3210 | SLI_INTF_IF_TYPE_SHIFT; | ||
3211 | |||
3212 | if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || | ||
3213 | if_type != 0x02) { | ||
3214 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | ||
3215 | return -EINVAL; | ||
3216 | } | ||
3217 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> | ||
3218 | SLI_INTF_FAMILY_SHIFT); | ||
3219 | adapter->generation = BE_GEN3; | ||
3220 | break; | ||
3221 | default: | ||
3222 | adapter->generation = 0; | ||
3223 | } | ||
2648 | return 0; | 3224 | return 0; |
2649 | } | 3225 | } |
2650 | 3226 | ||
3227 | static int lancer_wait_ready(struct be_adapter *adapter) | ||
3228 | { | ||
3229 | #define SLIPORT_READY_TIMEOUT 500 | ||
3230 | u32 sliport_status; | ||
3231 | int status = 0, i; | ||
3232 | |||
3233 | for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) { | ||
3234 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | ||
3235 | if (sliport_status & SLIPORT_STATUS_RDY_MASK) | ||
3236 | break; | ||
3237 | |||
3238 | msleep(20); | ||
3239 | } | ||
3240 | |||
3241 | if (i == SLIPORT_READY_TIMEOUT) | ||
3242 | status = -1; | ||
3243 | |||
3244 | return status; | ||
3245 | } | ||
3246 | |||
3247 | static int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | ||
3248 | { | ||
3249 | int status; | ||
3250 | u32 sliport_status, err, reset_needed; | ||
3251 | status = lancer_wait_ready(adapter); | ||
3252 | if (!status) { | ||
3253 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | ||
3254 | err = sliport_status & SLIPORT_STATUS_ERR_MASK; | ||
3255 | reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK; | ||
3256 | if (err && reset_needed) { | ||
3257 | iowrite32(SLI_PORT_CONTROL_IP_MASK, | ||
3258 | adapter->db + SLIPORT_CONTROL_OFFSET); | ||
3259 | |||
3260 | /* check adapter has corrected the error */ | ||
3261 | status = lancer_wait_ready(adapter); | ||
3262 | sliport_status = ioread32(adapter->db + | ||
3263 | SLIPORT_STATUS_OFFSET); | ||
3264 | sliport_status &= (SLIPORT_STATUS_ERR_MASK | | ||
3265 | SLIPORT_STATUS_RN_MASK); | ||
3266 | if (status || sliport_status) | ||
3267 | status = -1; | ||
3268 | } else if (err || reset_needed) { | ||
3269 | status = -1; | ||
3270 | } | ||
3271 | } | ||
3272 | return status; | ||
3273 | } | ||
3274 | |||
2651 | static int __devinit be_probe(struct pci_dev *pdev, | 3275 | static int __devinit be_probe(struct pci_dev *pdev, |
2652 | const struct pci_device_id *pdev_id) | 3276 | const struct pci_device_id *pdev_id) |
2653 | { | 3277 | { |
@@ -2655,7 +3279,6 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2655 | struct be_adapter *adapter; | 3279 | struct be_adapter *adapter; |
2656 | struct net_device *netdev; | 3280 | struct net_device *netdev; |
2657 | 3281 | ||
2658 | |||
2659 | status = pci_enable_device(pdev); | 3282 | status = pci_enable_device(pdev); |
2660 | if (status) | 3283 | if (status) |
2661 | goto do_none; | 3284 | goto do_none; |
@@ -2671,33 +3294,21 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2671 | goto rel_reg; | 3294 | goto rel_reg; |
2672 | } | 3295 | } |
2673 | adapter = netdev_priv(netdev); | 3296 | adapter = netdev_priv(netdev); |
2674 | |||
2675 | switch (pdev->device) { | ||
2676 | case BE_DEVICE_ID1: | ||
2677 | case OC_DEVICE_ID1: | ||
2678 | adapter->generation = BE_GEN2; | ||
2679 | break; | ||
2680 | case BE_DEVICE_ID2: | ||
2681 | case OC_DEVICE_ID2: | ||
2682 | adapter->generation = BE_GEN3; | ||
2683 | break; | ||
2684 | default: | ||
2685 | adapter->generation = 0; | ||
2686 | } | ||
2687 | |||
2688 | adapter->pdev = pdev; | 3297 | adapter->pdev = pdev; |
2689 | pci_set_drvdata(pdev, adapter); | 3298 | pci_set_drvdata(pdev, adapter); |
3299 | |||
3300 | status = be_dev_family_check(adapter); | ||
3301 | if (status) | ||
3302 | goto free_netdev; | ||
3303 | |||
2690 | adapter->netdev = netdev; | 3304 | adapter->netdev = netdev; |
2691 | be_netdev_init(netdev); | ||
2692 | SET_NETDEV_DEV(netdev, &pdev->dev); | 3305 | SET_NETDEV_DEV(netdev, &pdev->dev); |
2693 | 3306 | ||
2694 | be_msix_enable(adapter); | 3307 | status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); |
2695 | |||
2696 | status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
2697 | if (!status) { | 3308 | if (!status) { |
2698 | netdev->features |= NETIF_F_HIGHDMA; | 3309 | netdev->features |= NETIF_F_HIGHDMA; |
2699 | } else { | 3310 | } else { |
2700 | status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 3311 | status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); |
2701 | if (status) { | 3312 | if (status) { |
2702 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); | 3313 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); |
2703 | goto free_netdev; | 3314 | goto free_netdev; |
@@ -2705,10 +3316,25 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2705 | } | 3316 | } |
2706 | 3317 | ||
2707 | be_sriov_enable(adapter); | 3318 | be_sriov_enable(adapter); |
3319 | if (adapter->sriov_enabled) { | ||
3320 | adapter->vf_cfg = kcalloc(num_vfs, | ||
3321 | sizeof(struct be_vf_cfg), GFP_KERNEL); | ||
3322 | |||
3323 | if (!adapter->vf_cfg) | ||
3324 | goto free_netdev; | ||
3325 | } | ||
2708 | 3326 | ||
2709 | status = be_ctrl_init(adapter); | 3327 | status = be_ctrl_init(adapter); |
2710 | if (status) | 3328 | if (status) |
2711 | goto free_netdev; | 3329 | goto free_vf_cfg; |
3330 | |||
3331 | if (lancer_chip(adapter)) { | ||
3332 | status = lancer_test_and_set_rdy_state(adapter); | ||
3333 | if (status) { | ||
3334 | dev_err(&pdev->dev, "Adapter in non recoverable error\n"); | ||
3335 | goto ctrl_clean; | ||
3336 | } | ||
3337 | } | ||
2712 | 3338 | ||
2713 | /* sync up with fw's ready state */ | 3339 | /* sync up with fw's ready state */ |
2714 | if (be_physfn(adapter)) { | 3340 | if (be_physfn(adapter)) { |
@@ -2722,11 +3348,9 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2722 | if (status) | 3348 | if (status) |
2723 | goto ctrl_clean; | 3349 | goto ctrl_clean; |
2724 | 3350 | ||
2725 | if (be_physfn(adapter)) { | 3351 | status = be_cmd_reset_function(adapter); |
2726 | status = be_cmd_reset_function(adapter); | 3352 | if (status) |
2727 | if (status) | 3353 | goto ctrl_clean; |
2728 | goto ctrl_clean; | ||
2729 | } | ||
2730 | 3354 | ||
2731 | status = be_stats_init(adapter); | 3355 | status = be_stats_init(adapter); |
2732 | if (status) | 3356 | if (status) |
@@ -2736,29 +3360,60 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2736 | if (status) | 3360 | if (status) |
2737 | goto stats_clean; | 3361 | goto stats_clean; |
2738 | 3362 | ||
3363 | be_msix_enable(adapter); | ||
3364 | |||
2739 | INIT_DELAYED_WORK(&adapter->work, be_worker); | 3365 | INIT_DELAYED_WORK(&adapter->work, be_worker); |
2740 | 3366 | ||
2741 | status = be_setup(adapter); | 3367 | status = be_setup(adapter); |
2742 | if (status) | 3368 | if (status) |
2743 | goto stats_clean; | 3369 | goto msix_disable; |
2744 | 3370 | ||
3371 | be_netdev_init(netdev); | ||
2745 | status = register_netdev(netdev); | 3372 | status = register_netdev(netdev); |
2746 | if (status != 0) | 3373 | if (status != 0) |
2747 | goto unsetup; | 3374 | goto unsetup; |
3375 | netif_carrier_off(netdev); | ||
3376 | |||
3377 | if (be_physfn(adapter) && adapter->sriov_enabled) { | ||
3378 | u8 mac_speed; | ||
3379 | bool link_up; | ||
3380 | u16 vf, lnk_speed; | ||
3381 | |||
3382 | if (!lancer_chip(adapter)) { | ||
3383 | status = be_vf_eth_addr_config(adapter); | ||
3384 | if (status) | ||
3385 | goto unreg_netdev; | ||
3386 | } | ||
3387 | |||
3388 | for (vf = 0; vf < num_vfs; vf++) { | ||
3389 | status = be_cmd_link_status_query(adapter, &link_up, | ||
3390 | &mac_speed, &lnk_speed, vf + 1); | ||
3391 | if (!status) | ||
3392 | adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10; | ||
3393 | else | ||
3394 | goto unreg_netdev; | ||
3395 | } | ||
3396 | } | ||
2748 | 3397 | ||
2749 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); | 3398 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); |
3399 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | ||
2750 | return 0; | 3400 | return 0; |
2751 | 3401 | ||
3402 | unreg_netdev: | ||
3403 | unregister_netdev(netdev); | ||
2752 | unsetup: | 3404 | unsetup: |
2753 | be_clear(adapter); | 3405 | be_clear(adapter); |
3406 | msix_disable: | ||
3407 | be_msix_disable(adapter); | ||
2754 | stats_clean: | 3408 | stats_clean: |
2755 | be_stats_cleanup(adapter); | 3409 | be_stats_cleanup(adapter); |
2756 | ctrl_clean: | 3410 | ctrl_clean: |
2757 | be_ctrl_cleanup(adapter); | 3411 | be_ctrl_cleanup(adapter); |
3412 | free_vf_cfg: | ||
3413 | kfree(adapter->vf_cfg); | ||
2758 | free_netdev: | 3414 | free_netdev: |
2759 | be_msix_disable(adapter); | ||
2760 | be_sriov_disable(adapter); | 3415 | be_sriov_disable(adapter); |
2761 | free_netdev(adapter->netdev); | 3416 | free_netdev(netdev); |
2762 | pci_set_drvdata(pdev, NULL); | 3417 | pci_set_drvdata(pdev, NULL); |
2763 | rel_reg: | 3418 | rel_reg: |
2764 | pci_release_regions(pdev); | 3419 | pci_release_regions(pdev); |
@@ -2774,6 +3429,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2774 | struct be_adapter *adapter = pci_get_drvdata(pdev); | 3429 | struct be_adapter *adapter = pci_get_drvdata(pdev); |
2775 | struct net_device *netdev = adapter->netdev; | 3430 | struct net_device *netdev = adapter->netdev; |
2776 | 3431 | ||
3432 | cancel_delayed_work_sync(&adapter->work); | ||
2777 | if (adapter->wol) | 3433 | if (adapter->wol) |
2778 | be_setup_wol(adapter, true); | 3434 | be_setup_wol(adapter, true); |
2779 | 3435 | ||
@@ -2786,6 +3442,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2786 | be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc); | 3442 | be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc); |
2787 | be_clear(adapter); | 3443 | be_clear(adapter); |
2788 | 3444 | ||
3445 | be_msix_disable(adapter); | ||
2789 | pci_save_state(pdev); | 3446 | pci_save_state(pdev); |
2790 | pci_disable_device(pdev); | 3447 | pci_disable_device(pdev); |
2791 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3448 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
@@ -2807,6 +3464,7 @@ static int be_resume(struct pci_dev *pdev) | |||
2807 | pci_set_power_state(pdev, 0); | 3464 | pci_set_power_state(pdev, 0); |
2808 | pci_restore_state(pdev); | 3465 | pci_restore_state(pdev); |
2809 | 3466 | ||
3467 | be_msix_enable(adapter); | ||
2810 | /* tell fw we're ready to fire cmds */ | 3468 | /* tell fw we're ready to fire cmds */ |
2811 | status = be_cmd_fw_init(adapter); | 3469 | status = be_cmd_fw_init(adapter); |
2812 | if (status) | 3470 | if (status) |
@@ -2822,6 +3480,8 @@ static int be_resume(struct pci_dev *pdev) | |||
2822 | 3480 | ||
2823 | if (adapter->wol) | 3481 | if (adapter->wol) |
2824 | be_setup_wol(adapter, false); | 3482 | be_setup_wol(adapter, false); |
3483 | |||
3484 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | ||
2825 | return 0; | 3485 | return 0; |
2826 | } | 3486 | } |
2827 | 3487 | ||
@@ -2831,15 +3491,19 @@ static int be_resume(struct pci_dev *pdev) | |||
2831 | static void be_shutdown(struct pci_dev *pdev) | 3491 | static void be_shutdown(struct pci_dev *pdev) |
2832 | { | 3492 | { |
2833 | struct be_adapter *adapter = pci_get_drvdata(pdev); | 3493 | struct be_adapter *adapter = pci_get_drvdata(pdev); |
2834 | struct net_device *netdev = adapter->netdev; | ||
2835 | 3494 | ||
2836 | netif_device_detach(netdev); | 3495 | if (!adapter) |
3496 | return; | ||
2837 | 3497 | ||
2838 | be_cmd_reset_function(adapter); | 3498 | cancel_delayed_work_sync(&adapter->work); |
3499 | |||
3500 | netif_device_detach(adapter->netdev); | ||
2839 | 3501 | ||
2840 | if (adapter->wol) | 3502 | if (adapter->wol) |
2841 | be_setup_wol(adapter, true); | 3503 | be_setup_wol(adapter, true); |
2842 | 3504 | ||
3505 | be_cmd_reset_function(adapter); | ||
3506 | |||
2843 | pci_disable_device(pdev); | 3507 | pci_disable_device(pdev); |
2844 | } | 3508 | } |
2845 | 3509 | ||
@@ -2951,13 +3615,6 @@ static int __init be_init_module(void) | |||
2951 | rx_frag_size = 2048; | 3615 | rx_frag_size = 2048; |
2952 | } | 3616 | } |
2953 | 3617 | ||
2954 | if (num_vfs > 32) { | ||
2955 | printk(KERN_WARNING DRV_NAME | ||
2956 | " : Module param num_vfs must not be greater than 32." | ||
2957 | "Using 32\n"); | ||
2958 | num_vfs = 32; | ||
2959 | } | ||
2960 | |||
2961 | return pci_register_driver(&be_driver); | 3618 | return pci_register_driver(&be_driver); |
2962 | } | 3619 | } |
2963 | module_init(be_init_module); | 3620 | module_init(be_init_module); |