Commit | Line | Data |
---|---|---|
51b35a45 EC |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /**************************************************************************** | |
3 | * Driver for Solarflare network controllers and boards | |
4 | * Copyright 2018 Solarflare Communications Inc. | |
5 | * Copyright 2019-2020 Xilinx Inc. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License version 2 as published | |
9 | * by the Free Software Foundation, incorporated herein by reference. | |
10 | */ | |
11 | ||
12 | #include "ef100_nic.h" | |
13 | #include "efx_common.h" | |
14 | #include "efx_channels.h" | |
15 | #include "io.h" | |
16 | #include "selftest.h" | |
17 | #include "ef100_regs.h" | |
18 | #include "mcdi.h" | |
19 | #include "mcdi_pcol.h" | |
20 | #include "mcdi_port_common.h" | |
21 | #include "mcdi_functions.h" | |
22 | #include "mcdi_filters.h" | |
23 | #include "ef100_rx.h" | |
24 | #include "ef100_tx.h" | |
25 | #include "ef100_netdev.h" | |
000fe940 | 26 | #include "rx_common.h" |
51b35a45 EC |
27 | |
28 | #define EF100_MAX_VIS 4096 | |
2200e6d9 EC |
29 | #define EF100_NUM_MCDI_BUFFERS 1 |
30 | #define MCDI_BUF_LEN (8 + MCDI_CTL_SDU_LEN_MAX) | |
51b35a45 | 31 | |
c027f2a7 EC |
32 | #define EF100_RESET_PORT ((ETH_RESET_MAC | ETH_RESET_PHY) << ETH_RESET_SHARED_SHIFT) |
33 | ||
51b35a45 EC |
34 | /* MCDI |
35 | */ | |
2200e6d9 EC |
36 | static u8 *ef100_mcdi_buf(struct efx_nic *efx, u8 bufid, dma_addr_t *dma_addr) |
37 | { | |
38 | struct ef100_nic_data *nic_data = efx->nic_data; | |
39 | ||
40 | if (dma_addr) | |
41 | *dma_addr = nic_data->mcdi_buf.dma_addr + | |
42 | bufid * ALIGN(MCDI_BUF_LEN, 256); | |
43 | return nic_data->mcdi_buf.addr + bufid * ALIGN(MCDI_BUF_LEN, 256); | |
44 | } | |
45 | ||
51b35a45 EC |
46 | static int ef100_get_warm_boot_count(struct efx_nic *efx) |
47 | { | |
48 | efx_dword_t reg; | |
49 | ||
50 | efx_readd(efx, ®, efx_reg(efx, ER_GZ_MC_SFT_STATUS)); | |
51 | ||
52 | if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) == 0xffffffff) { | |
53 | netif_err(efx, hw, efx->net_dev, "Hardware unavailable\n"); | |
54 | efx->state = STATE_DISABLED; | |
55 | return -ENETDOWN; | |
56 | } else { | |
57 | return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ? | |
58 | EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO; | |
59 | } | |
60 | } | |
61 | ||
2200e6d9 EC |
62 | static void ef100_mcdi_request(struct efx_nic *efx, |
63 | const efx_dword_t *hdr, size_t hdr_len, | |
64 | const efx_dword_t *sdu, size_t sdu_len) | |
65 | { | |
66 | dma_addr_t dma_addr; | |
67 | u8 *pdu = ef100_mcdi_buf(efx, 0, &dma_addr); | |
68 | ||
69 | memcpy(pdu, hdr, hdr_len); | |
70 | memcpy(pdu + hdr_len, sdu, sdu_len); | |
71 | wmb(); | |
72 | ||
73 | /* The hardware provides 'low' and 'high' (doorbell) registers | |
74 | * for passing the 64-bit address of an MCDI request to | |
75 | * firmware. However the dwords are swapped by firmware. The | |
76 | * least significant bits of the doorbell are then 0 for all | |
77 | * MCDI requests due to alignment. | |
78 | */ | |
79 | _efx_writed(efx, cpu_to_le32((u64)dma_addr >> 32), efx_reg(efx, ER_GZ_MC_DB_LWRD)); | |
80 | _efx_writed(efx, cpu_to_le32((u32)dma_addr), efx_reg(efx, ER_GZ_MC_DB_HWRD)); | |
81 | } | |
82 | ||
83 | static bool ef100_mcdi_poll_response(struct efx_nic *efx) | |
84 | { | |
85 | const efx_dword_t hdr = | |
86 | *(const efx_dword_t *)(ef100_mcdi_buf(efx, 0, NULL)); | |
87 | ||
88 | rmb(); | |
89 | return EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE); | |
90 | } | |
91 | ||
92 | static void ef100_mcdi_read_response(struct efx_nic *efx, | |
93 | efx_dword_t *outbuf, size_t offset, | |
94 | size_t outlen) | |
95 | { | |
96 | const u8 *pdu = ef100_mcdi_buf(efx, 0, NULL); | |
97 | ||
98 | memcpy(outbuf, pdu + offset, outlen); | |
99 | } | |
100 | ||
101 | static int ef100_mcdi_poll_reboot(struct efx_nic *efx) | |
102 | { | |
103 | struct ef100_nic_data *nic_data = efx->nic_data; | |
104 | int rc; | |
105 | ||
106 | rc = ef100_get_warm_boot_count(efx); | |
107 | if (rc < 0) { | |
108 | /* The firmware is presumably in the process of | |
109 | * rebooting. However, we are supposed to report each | |
110 | * reboot just once, so we must only do that once we | |
111 | * can read and store the updated warm boot count. | |
112 | */ | |
113 | return 0; | |
114 | } | |
115 | ||
116 | if (rc == nic_data->warm_boot_count) | |
117 | return 0; | |
118 | ||
119 | nic_data->warm_boot_count = rc; | |
120 | ||
121 | return -EIO; | |
122 | } | |
123 | ||
124 | static void ef100_mcdi_reboot_detected(struct efx_nic *efx) | |
125 | { | |
126 | } | |
127 | ||
f6573120 EC |
128 | /* MCDI calls |
129 | */ | |
29ec1b27 EC |
130 | static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address) |
131 | { | |
132 | MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN); | |
133 | size_t outlen; | |
134 | int rc; | |
135 | ||
136 | BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0); | |
137 | ||
138 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0, | |
139 | outbuf, sizeof(outbuf), &outlen); | |
140 | if (rc) | |
141 | return rc; | |
142 | if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) | |
143 | return -EIO; | |
144 | ||
145 | ether_addr_copy(mac_address, | |
146 | MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE)); | |
147 | return 0; | |
148 | } | |
149 | ||
f6573120 EC |
150 | static int efx_ef100_init_datapath_caps(struct efx_nic *efx) |
151 | { | |
d802b0ae | 152 | MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN); |
f6573120 EC |
153 | struct ef100_nic_data *nic_data = efx->nic_data; |
154 | u8 vi_window_mode; | |
155 | size_t outlen; | |
156 | int rc; | |
157 | ||
158 | BUILD_BUG_ON(MC_CMD_GET_CAPABILITIES_IN_LEN != 0); | |
159 | ||
160 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_CAPABILITIES, NULL, 0, | |
161 | outbuf, sizeof(outbuf), &outlen); | |
162 | if (rc) | |
163 | return rc; | |
164 | if (outlen < MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) { | |
165 | netif_err(efx, drv, efx->net_dev, | |
166 | "unable to read datapath firmware capabilities\n"); | |
167 | return -EIO; | |
168 | } | |
169 | ||
170 | nic_data->datapath_caps = MCDI_DWORD(outbuf, | |
171 | GET_CAPABILITIES_OUT_FLAGS1); | |
172 | nic_data->datapath_caps2 = MCDI_DWORD(outbuf, | |
173 | GET_CAPABILITIES_V2_OUT_FLAGS2); | |
d802b0ae EC |
174 | if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN) |
175 | nic_data->datapath_caps3 = 0; | |
176 | else | |
177 | nic_data->datapath_caps3 = MCDI_DWORD(outbuf, | |
178 | GET_CAPABILITIES_V7_OUT_FLAGS3); | |
f6573120 EC |
179 | |
180 | vi_window_mode = MCDI_BYTE(outbuf, | |
181 | GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); | |
182 | rc = efx_mcdi_window_mode_to_stride(efx, vi_window_mode); | |
183 | if (rc) | |
184 | return rc; | |
185 | ||
806f9f23 EC |
186 | if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3)) { |
187 | struct net_device *net_dev = efx->net_dev; | |
188 | netdev_features_t tso = NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_PARTIAL | | |
c5122cf5 EC |
189 | NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM | |
190 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM; | |
806f9f23 EC |
191 | |
192 | net_dev->features |= tso; | |
193 | net_dev->hw_features |= tso; | |
194 | net_dev->hw_enc_features |= tso; | |
c5122cf5 EC |
195 | /* EF100 HW can only offload outer checksums if they are UDP, |
196 | * so for GRE_CSUM we have to use GSO_PARTIAL. | |
197 | */ | |
198 | net_dev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; | |
806f9f23 | 199 | } |
f6573120 EC |
200 | efx->num_mac_stats = MCDI_WORD(outbuf, |
201 | GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); | |
202 | netif_dbg(efx, probe, efx->net_dev, | |
203 | "firmware reports num_mac_stats = %u\n", | |
204 | efx->num_mac_stats); | |
205 | return 0; | |
206 | } | |
207 | ||
51b35a45 EC |
208 | /* Event handling |
209 | */ | |
210 | static int ef100_ev_probe(struct efx_channel *channel) | |
211 | { | |
212 | /* Allocate an extra descriptor for the QMDA status completion entry */ | |
213 | return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf, | |
214 | (channel->eventq_mask + 2) * | |
215 | sizeof(efx_qword_t), | |
216 | GFP_KERNEL); | |
217 | } | |
218 | ||
965b549f EC |
219 | static int ef100_ev_init(struct efx_channel *channel) |
220 | { | |
221 | struct ef100_nic_data *nic_data = channel->efx->nic_data; | |
222 | ||
223 | /* initial phase is 0 */ | |
224 | clear_bit(channel->channel, nic_data->evq_phases); | |
225 | ||
226 | return efx_mcdi_ev_init(channel, false, false); | |
227 | } | |
228 | ||
229 | static void ef100_ev_read_ack(struct efx_channel *channel) | |
230 | { | |
231 | efx_dword_t evq_prime; | |
232 | ||
233 | EFX_POPULATE_DWORD_2(evq_prime, | |
234 | ERF_GZ_EVQ_ID, channel->channel, | |
235 | ERF_GZ_IDX, channel->eventq_read_ptr & | |
236 | channel->eventq_mask); | |
237 | ||
238 | efx_writed(channel->efx, &evq_prime, | |
239 | efx_reg(channel->efx, ER_GZ_EVQ_INT_PRIME)); | |
240 | } | |
241 | ||
242 | static int ef100_ev_process(struct efx_channel *channel, int quota) | |
243 | { | |
5e4ef673 EC |
244 | struct efx_nic *efx = channel->efx; |
245 | struct ef100_nic_data *nic_data; | |
246 | bool evq_phase, old_evq_phase; | |
247 | unsigned int read_ptr; | |
248 | efx_qword_t *p_event; | |
249 | int spent = 0; | |
250 | bool ev_phase; | |
251 | int ev_type; | |
252 | ||
253 | if (unlikely(!channel->enabled)) | |
254 | return 0; | |
255 | ||
256 | nic_data = efx->nic_data; | |
257 | evq_phase = test_bit(channel->channel, nic_data->evq_phases); | |
258 | old_evq_phase = evq_phase; | |
259 | read_ptr = channel->eventq_read_ptr; | |
260 | BUILD_BUG_ON(ESF_GZ_EV_RXPKTS_PHASE_LBN != ESF_GZ_EV_TXCMPL_PHASE_LBN); | |
261 | ||
262 | while (spent < quota) { | |
263 | p_event = efx_event(channel, read_ptr); | |
264 | ||
265 | ev_phase = !!EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_PHASE); | |
266 | if (ev_phase != evq_phase) | |
267 | break; | |
268 | ||
269 | netif_vdbg(efx, drv, efx->net_dev, | |
270 | "processing event on %d " EFX_QWORD_FMT "\n", | |
271 | channel->channel, EFX_QWORD_VAL(*p_event)); | |
272 | ||
273 | ev_type = EFX_QWORD_FIELD(*p_event, ESF_GZ_E_TYPE); | |
274 | ||
275 | switch (ev_type) { | |
8e57daf7 EC |
276 | case ESE_GZ_EF100_EV_RX_PKTS: |
277 | efx_ef100_ev_rx(channel, p_event); | |
278 | ++spent; | |
279 | break; | |
5e4ef673 EC |
280 | case ESE_GZ_EF100_EV_MCDI: |
281 | efx_mcdi_process_event(channel, p_event); | |
282 | break; | |
d19a5372 EC |
283 | case ESE_GZ_EF100_EV_TX_COMPLETION: |
284 | ef100_ev_tx(channel, p_event); | |
285 | break; | |
5e4ef673 EC |
286 | case ESE_GZ_EF100_EV_DRIVER: |
287 | netif_info(efx, drv, efx->net_dev, | |
288 | "Driver initiated event " EFX_QWORD_FMT "\n", | |
289 | EFX_QWORD_VAL(*p_event)); | |
290 | break; | |
291 | default: | |
292 | netif_info(efx, drv, efx->net_dev, | |
293 | "Unhandled event " EFX_QWORD_FMT "\n", | |
294 | EFX_QWORD_VAL(*p_event)); | |
295 | } | |
296 | ||
297 | ++read_ptr; | |
298 | if ((read_ptr & channel->eventq_mask) == 0) | |
299 | evq_phase = !evq_phase; | |
300 | } | |
301 | ||
302 | channel->eventq_read_ptr = read_ptr; | |
303 | if (evq_phase != old_evq_phase) | |
304 | change_bit(channel->channel, nic_data->evq_phases); | |
305 | ||
306 | return spent; | |
965b549f EC |
307 | } |
308 | ||
51b35a45 EC |
309 | static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id) |
310 | { | |
311 | struct efx_msi_context *context = dev_id; | |
312 | struct efx_nic *efx = context->efx; | |
313 | ||
314 | netif_vdbg(efx, intr, efx->net_dev, | |
315 | "IRQ %d on CPU %d\n", irq, raw_smp_processor_id()); | |
316 | ||
317 | if (likely(READ_ONCE(efx->irq_soft_enabled))) { | |
318 | /* Note test interrupts */ | |
319 | if (context->index == efx->irq_level) | |
320 | efx->last_irq_cpu = raw_smp_processor_id(); | |
321 | ||
322 | /* Schedule processing of the channel */ | |
323 | efx_schedule_channel_irq(efx->channel[context->index]); | |
324 | } | |
325 | ||
326 | return IRQ_HANDLED; | |
327 | } | |
328 | ||
aa86a75f EC |
329 | static int ef100_phy_probe(struct efx_nic *efx) |
330 | { | |
99a23c11 EC |
331 | struct efx_mcdi_phy_data *phy_data; |
332 | int rc; | |
333 | ||
334 | /* Probe for the PHY */ | |
aa86a75f EC |
335 | efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL); |
336 | if (!efx->phy_data) | |
337 | return -ENOMEM; | |
338 | ||
99a23c11 EC |
339 | rc = efx_mcdi_get_phy_cfg(efx, efx->phy_data); |
340 | if (rc) | |
341 | return rc; | |
342 | ||
343 | /* Populate driver and ethtool settings */ | |
344 | phy_data = efx->phy_data; | |
345 | mcdi_to_ethtool_linkset(phy_data->media, phy_data->supported_cap, | |
346 | efx->link_advertising); | |
347 | efx->fec_config = mcdi_fec_caps_to_ethtool(phy_data->supported_cap, | |
348 | false); | |
349 | ||
350 | /* Default to Autonegotiated flow control if the PHY supports it */ | |
351 | efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; | |
352 | if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) | |
353 | efx->wanted_fc |= EFX_FC_AUTO; | |
354 | efx_link_set_wanted_fc(efx, efx->wanted_fc); | |
355 | ||
356 | /* Push settings to the PHY. Failure is not fatal, the user can try to | |
357 | * fix it using ethtool. | |
358 | */ | |
359 | rc = efx_mcdi_port_reconfigure(efx); | |
360 | if (rc && rc != -EPERM) | |
361 | netif_warn(efx, drv, efx->net_dev, | |
362 | "could not initialise PHY settings\n"); | |
363 | ||
aa86a75f EC |
364 | return 0; |
365 | } | |
366 | ||
a9dc3d56 EC |
367 | static int ef100_filter_table_probe(struct efx_nic *efx) |
368 | { | |
369 | return efx_mcdi_filter_table_probe(efx, true); | |
370 | } | |
371 | ||
372 | static int ef100_filter_table_up(struct efx_nic *efx) | |
373 | { | |
374 | int rc; | |
375 | ||
376 | rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC); | |
377 | if (rc) { | |
378 | efx_mcdi_filter_table_down(efx); | |
379 | return rc; | |
380 | } | |
381 | ||
382 | rc = efx_mcdi_filter_add_vlan(efx, 0); | |
383 | if (rc) { | |
384 | efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC); | |
385 | efx_mcdi_filter_table_down(efx); | |
386 | } | |
387 | ||
388 | return rc; | |
389 | } | |
390 | ||
391 | static void ef100_filter_table_down(struct efx_nic *efx) | |
392 | { | |
393 | efx_mcdi_filter_del_vlan(efx, 0); | |
394 | efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC); | |
395 | efx_mcdi_filter_table_down(efx); | |
396 | } | |
397 | ||
c027f2a7 EC |
398 | /* Other |
399 | */ | |
99a23c11 EC |
400 | static int ef100_reconfigure_mac(struct efx_nic *efx, bool mtu_only) |
401 | { | |
402 | WARN_ON(!mutex_is_locked(&efx->mac_lock)); | |
403 | ||
404 | efx_mcdi_filter_sync_rx_mode(efx); | |
405 | ||
406 | if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED)) | |
407 | return efx_mcdi_set_mtu(efx); | |
408 | return efx_mcdi_set_mac(efx); | |
409 | } | |
c027f2a7 EC |
410 | |
411 | static enum reset_type ef100_map_reset_reason(enum reset_type reason) | |
412 | { | |
413 | if (reason == RESET_TYPE_TX_WATCHDOG) | |
414 | return reason; | |
415 | return RESET_TYPE_DISABLE; | |
416 | } | |
417 | ||
418 | static int ef100_map_reset_flags(u32 *flags) | |
419 | { | |
420 | /* Only perform a RESET_TYPE_ALL because we don't support MC_REBOOTs */ | |
421 | if ((*flags & EF100_RESET_PORT)) { | |
422 | *flags &= ~EF100_RESET_PORT; | |
423 | return RESET_TYPE_ALL; | |
424 | } | |
425 | if (*flags & ETH_RESET_MGMT) { | |
426 | *flags &= ~ETH_RESET_MGMT; | |
427 | return RESET_TYPE_DISABLE; | |
428 | } | |
429 | ||
430 | return -EINVAL; | |
431 | } | |
432 | ||
433 | static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type) | |
434 | { | |
435 | int rc; | |
436 | ||
437 | dev_close(efx->net_dev); | |
438 | ||
439 | if (reset_type == RESET_TYPE_TX_WATCHDOG) { | |
440 | netif_device_attach(efx->net_dev); | |
441 | __clear_bit(reset_type, &efx->reset_pending); | |
442 | rc = dev_open(efx->net_dev, NULL); | |
443 | } else if (reset_type == RESET_TYPE_ALL) { | |
4e5675bb EC |
444 | rc = efx_mcdi_reset(efx, reset_type); |
445 | if (rc) | |
446 | return rc; | |
447 | ||
c027f2a7 EC |
448 | netif_device_attach(efx->net_dev); |
449 | ||
450 | rc = dev_open(efx->net_dev, NULL); | |
451 | } else { | |
452 | rc = 1; /* Leave the device closed */ | |
453 | } | |
454 | return rc; | |
455 | } | |
456 | ||
b593b6f1 EC |
457 | static void ef100_common_stat_mask(unsigned long *mask) |
458 | { | |
459 | __set_bit(EF100_STAT_port_rx_packets, mask); | |
460 | __set_bit(EF100_STAT_port_tx_packets, mask); | |
461 | __set_bit(EF100_STAT_port_rx_bytes, mask); | |
462 | __set_bit(EF100_STAT_port_tx_bytes, mask); | |
463 | __set_bit(EF100_STAT_port_rx_multicast, mask); | |
464 | __set_bit(EF100_STAT_port_rx_bad, mask); | |
465 | __set_bit(EF100_STAT_port_rx_align_error, mask); | |
466 | __set_bit(EF100_STAT_port_rx_overflow, mask); | |
467 | } | |
468 | ||
469 | static void ef100_ethtool_stat_mask(unsigned long *mask) | |
470 | { | |
471 | __set_bit(EF100_STAT_port_tx_pause, mask); | |
472 | __set_bit(EF100_STAT_port_tx_unicast, mask); | |
473 | __set_bit(EF100_STAT_port_tx_multicast, mask); | |
474 | __set_bit(EF100_STAT_port_tx_broadcast, mask); | |
475 | __set_bit(EF100_STAT_port_tx_lt64, mask); | |
476 | __set_bit(EF100_STAT_port_tx_64, mask); | |
477 | __set_bit(EF100_STAT_port_tx_65_to_127, mask); | |
478 | __set_bit(EF100_STAT_port_tx_128_to_255, mask); | |
479 | __set_bit(EF100_STAT_port_tx_256_to_511, mask); | |
480 | __set_bit(EF100_STAT_port_tx_512_to_1023, mask); | |
481 | __set_bit(EF100_STAT_port_tx_1024_to_15xx, mask); | |
482 | __set_bit(EF100_STAT_port_tx_15xx_to_jumbo, mask); | |
483 | __set_bit(EF100_STAT_port_rx_good, mask); | |
484 | __set_bit(EF100_STAT_port_rx_pause, mask); | |
485 | __set_bit(EF100_STAT_port_rx_unicast, mask); | |
486 | __set_bit(EF100_STAT_port_rx_broadcast, mask); | |
487 | __set_bit(EF100_STAT_port_rx_lt64, mask); | |
488 | __set_bit(EF100_STAT_port_rx_64, mask); | |
489 | __set_bit(EF100_STAT_port_rx_65_to_127, mask); | |
490 | __set_bit(EF100_STAT_port_rx_128_to_255, mask); | |
491 | __set_bit(EF100_STAT_port_rx_256_to_511, mask); | |
492 | __set_bit(EF100_STAT_port_rx_512_to_1023, mask); | |
493 | __set_bit(EF100_STAT_port_rx_1024_to_15xx, mask); | |
494 | __set_bit(EF100_STAT_port_rx_15xx_to_jumbo, mask); | |
495 | __set_bit(EF100_STAT_port_rx_gtjumbo, mask); | |
496 | __set_bit(EF100_STAT_port_rx_bad_gtjumbo, mask); | |
497 | __set_bit(EF100_STAT_port_rx_length_error, mask); | |
498 | __set_bit(EF100_STAT_port_rx_nodesc_drops, mask); | |
499 | __set_bit(GENERIC_STAT_rx_nodesc_trunc, mask); | |
500 | __set_bit(GENERIC_STAT_rx_noskb_drops, mask); | |
501 | } | |
502 | ||
503 | #define EF100_DMA_STAT(ext_name, mcdi_name) \ | |
504 | [EF100_STAT_ ## ext_name] = \ | |
505 | { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name } | |
506 | ||
507 | static const struct efx_hw_stat_desc ef100_stat_desc[EF100_STAT_COUNT] = { | |
508 | EF100_DMA_STAT(port_tx_bytes, TX_BYTES), | |
509 | EF100_DMA_STAT(port_tx_packets, TX_PKTS), | |
510 | EF100_DMA_STAT(port_tx_pause, TX_PAUSE_PKTS), | |
511 | EF100_DMA_STAT(port_tx_unicast, TX_UNICAST_PKTS), | |
512 | EF100_DMA_STAT(port_tx_multicast, TX_MULTICAST_PKTS), | |
513 | EF100_DMA_STAT(port_tx_broadcast, TX_BROADCAST_PKTS), | |
514 | EF100_DMA_STAT(port_tx_lt64, TX_LT64_PKTS), | |
515 | EF100_DMA_STAT(port_tx_64, TX_64_PKTS), | |
516 | EF100_DMA_STAT(port_tx_65_to_127, TX_65_TO_127_PKTS), | |
517 | EF100_DMA_STAT(port_tx_128_to_255, TX_128_TO_255_PKTS), | |
518 | EF100_DMA_STAT(port_tx_256_to_511, TX_256_TO_511_PKTS), | |
519 | EF100_DMA_STAT(port_tx_512_to_1023, TX_512_TO_1023_PKTS), | |
520 | EF100_DMA_STAT(port_tx_1024_to_15xx, TX_1024_TO_15XX_PKTS), | |
521 | EF100_DMA_STAT(port_tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS), | |
522 | EF100_DMA_STAT(port_rx_bytes, RX_BYTES), | |
523 | EF100_DMA_STAT(port_rx_packets, RX_PKTS), | |
524 | EF100_DMA_STAT(port_rx_good, RX_GOOD_PKTS), | |
525 | EF100_DMA_STAT(port_rx_bad, RX_BAD_FCS_PKTS), | |
526 | EF100_DMA_STAT(port_rx_pause, RX_PAUSE_PKTS), | |
527 | EF100_DMA_STAT(port_rx_unicast, RX_UNICAST_PKTS), | |
528 | EF100_DMA_STAT(port_rx_multicast, RX_MULTICAST_PKTS), | |
529 | EF100_DMA_STAT(port_rx_broadcast, RX_BROADCAST_PKTS), | |
530 | EF100_DMA_STAT(port_rx_lt64, RX_UNDERSIZE_PKTS), | |
531 | EF100_DMA_STAT(port_rx_64, RX_64_PKTS), | |
532 | EF100_DMA_STAT(port_rx_65_to_127, RX_65_TO_127_PKTS), | |
533 | EF100_DMA_STAT(port_rx_128_to_255, RX_128_TO_255_PKTS), | |
534 | EF100_DMA_STAT(port_rx_256_to_511, RX_256_TO_511_PKTS), | |
535 | EF100_DMA_STAT(port_rx_512_to_1023, RX_512_TO_1023_PKTS), | |
536 | EF100_DMA_STAT(port_rx_1024_to_15xx, RX_1024_TO_15XX_PKTS), | |
537 | EF100_DMA_STAT(port_rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS), | |
538 | EF100_DMA_STAT(port_rx_gtjumbo, RX_GTJUMBO_PKTS), | |
539 | EF100_DMA_STAT(port_rx_bad_gtjumbo, RX_JABBER_PKTS), | |
540 | EF100_DMA_STAT(port_rx_align_error, RX_ALIGN_ERROR_PKTS), | |
541 | EF100_DMA_STAT(port_rx_length_error, RX_LENGTH_ERROR_PKTS), | |
542 | EF100_DMA_STAT(port_rx_overflow, RX_OVERFLOW_PKTS), | |
543 | EF100_DMA_STAT(port_rx_nodesc_drops, RX_NODESC_DROPS), | |
544 | EFX_GENERIC_SW_STAT(rx_nodesc_trunc), | |
545 | EFX_GENERIC_SW_STAT(rx_noskb_drops), | |
546 | }; | |
547 | ||
548 | static size_t ef100_describe_stats(struct efx_nic *efx, u8 *names) | |
549 | { | |
550 | DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {}; | |
551 | ||
552 | ef100_ethtool_stat_mask(mask); | |
553 | return efx_nic_describe_stats(ef100_stat_desc, EF100_STAT_COUNT, | |
554 | mask, names); | |
555 | } | |
556 | ||
557 | static size_t ef100_update_stats_common(struct efx_nic *efx, u64 *full_stats, | |
558 | struct rtnl_link_stats64 *core_stats) | |
559 | { | |
560 | struct ef100_nic_data *nic_data = efx->nic_data; | |
561 | DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {}; | |
562 | size_t stats_count = 0, index; | |
563 | u64 *stats = nic_data->stats; | |
564 | ||
565 | ef100_ethtool_stat_mask(mask); | |
566 | ||
567 | if (full_stats) { | |
568 | for_each_set_bit(index, mask, EF100_STAT_COUNT) { | |
569 | if (ef100_stat_desc[index].name) { | |
570 | *full_stats++ = stats[index]; | |
571 | ++stats_count; | |
572 | } | |
573 | } | |
574 | } | |
575 | ||
576 | if (!core_stats) | |
577 | return stats_count; | |
578 | ||
579 | core_stats->rx_packets = stats[EF100_STAT_port_rx_packets]; | |
580 | core_stats->tx_packets = stats[EF100_STAT_port_tx_packets]; | |
581 | core_stats->rx_bytes = stats[EF100_STAT_port_rx_bytes]; | |
582 | core_stats->tx_bytes = stats[EF100_STAT_port_tx_bytes]; | |
583 | core_stats->rx_dropped = stats[EF100_STAT_port_rx_nodesc_drops] + | |
584 | stats[GENERIC_STAT_rx_nodesc_trunc] + | |
585 | stats[GENERIC_STAT_rx_noskb_drops]; | |
586 | core_stats->multicast = stats[EF100_STAT_port_rx_multicast]; | |
587 | core_stats->rx_length_errors = | |
588 | stats[EF100_STAT_port_rx_gtjumbo] + | |
589 | stats[EF100_STAT_port_rx_length_error]; | |
590 | core_stats->rx_crc_errors = stats[EF100_STAT_port_rx_bad]; | |
591 | core_stats->rx_frame_errors = | |
592 | stats[EF100_STAT_port_rx_align_error]; | |
593 | core_stats->rx_fifo_errors = stats[EF100_STAT_port_rx_overflow]; | |
594 | core_stats->rx_errors = (core_stats->rx_length_errors + | |
595 | core_stats->rx_crc_errors + | |
596 | core_stats->rx_frame_errors); | |
597 | ||
598 | return stats_count; | |
599 | } | |
600 | ||
601 | static size_t ef100_update_stats(struct efx_nic *efx, | |
602 | u64 *full_stats, | |
603 | struct rtnl_link_stats64 *core_stats) | |
604 | { | |
605 | __le64 *mc_stats = kmalloc(array_size(efx->num_mac_stats, sizeof(__le64)), GFP_ATOMIC); | |
606 | struct ef100_nic_data *nic_data = efx->nic_data; | |
607 | DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {}; | |
608 | u64 *stats = nic_data->stats; | |
609 | ||
610 | ef100_common_stat_mask(mask); | |
611 | ef100_ethtool_stat_mask(mask); | |
612 | ||
407ecd1b JJ |
613 | if (!mc_stats) |
614 | return 0; | |
615 | ||
b593b6f1 EC |
616 | efx_nic_copy_stats(efx, mc_stats); |
617 | efx_nic_update_stats(ef100_stat_desc, EF100_STAT_COUNT, mask, | |
618 | stats, mc_stats, false); | |
619 | ||
620 | kfree(mc_stats); | |
621 | ||
622 | return ef100_update_stats_common(efx, full_stats, core_stats); | |
623 | } | |
624 | ||
1c748843 EC |
625 | static int efx_ef100_get_phys_port_id(struct efx_nic *efx, |
626 | struct netdev_phys_item_id *ppid) | |
627 | { | |
628 | struct ef100_nic_data *nic_data = efx->nic_data; | |
629 | ||
630 | if (!is_valid_ether_addr(nic_data->port_id)) | |
631 | return -EOPNOTSUPP; | |
632 | ||
633 | ppid->id_len = ETH_ALEN; | |
634 | memcpy(ppid->id, nic_data->port_id, ppid->id_len); | |
635 | ||
636 | return 0; | |
637 | } | |
638 | ||
43c3df0d EC |
639 | static int efx_ef100_irq_test_generate(struct efx_nic *efx) |
640 | { | |
641 | MCDI_DECLARE_BUF(inbuf, MC_CMD_TRIGGER_INTERRUPT_IN_LEN); | |
642 | ||
643 | BUILD_BUG_ON(MC_CMD_TRIGGER_INTERRUPT_OUT_LEN != 0); | |
644 | ||
645 | MCDI_SET_DWORD(inbuf, TRIGGER_INTERRUPT_IN_INTR_LEVEL, efx->irq_level); | |
646 | return efx_mcdi_rpc_quiet(efx, MC_CMD_TRIGGER_INTERRUPT, | |
647 | inbuf, sizeof(inbuf), NULL, 0, NULL); | |
648 | } | |
649 | ||
650 | #define EFX_EF100_TEST 1 | |
651 | ||
652 | static void efx_ef100_ev_test_generate(struct efx_channel *channel) | |
653 | { | |
654 | MCDI_DECLARE_BUF(inbuf, MC_CMD_DRIVER_EVENT_IN_LEN); | |
655 | struct efx_nic *efx = channel->efx; | |
656 | efx_qword_t event; | |
657 | int rc; | |
658 | ||
659 | EFX_POPULATE_QWORD_2(event, | |
660 | ESF_GZ_E_TYPE, ESE_GZ_EF100_EV_DRIVER, | |
661 | ESF_GZ_DRIVER_DATA, EFX_EF100_TEST); | |
662 | ||
663 | MCDI_SET_DWORD(inbuf, DRIVER_EVENT_IN_EVQ, channel->channel); | |
664 | ||
665 | /* MCDI_SET_QWORD is not appropriate here since EFX_POPULATE_* has | |
666 | * already swapped the data to little-endian order. | |
667 | */ | |
668 | memcpy(MCDI_PTR(inbuf, DRIVER_EVENT_IN_DATA), &event.u64[0], | |
669 | sizeof(efx_qword_t)); | |
670 | ||
671 | rc = efx_mcdi_rpc(efx, MC_CMD_DRIVER_EVENT, inbuf, sizeof(inbuf), | |
672 | NULL, 0, NULL); | |
673 | if (rc && (rc != -ENETDOWN)) | |
674 | goto fail; | |
675 | ||
676 | return; | |
677 | ||
678 | fail: | |
679 | WARN_ON(true); | |
680 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | |
681 | } | |
682 | ||
965b549f EC |
683 | static unsigned int ef100_check_caps(const struct efx_nic *efx, |
684 | u8 flag, u32 offset) | |
685 | { | |
f6573120 EC |
686 | const struct ef100_nic_data *nic_data = efx->nic_data; |
687 | ||
688 | switch (offset) { | |
689 | case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_OFST: | |
690 | return nic_data->datapath_caps & BIT_ULL(flag); | |
691 | case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST: | |
692 | return nic_data->datapath_caps2 & BIT_ULL(flag); | |
d802b0ae EC |
693 | case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_OFST: |
694 | return nic_data->datapath_caps3 & BIT_ULL(flag); | |
f6573120 EC |
695 | default: |
696 | return 0; | |
697 | } | |
965b549f EC |
698 | } |
699 | ||
000fe940 MH |
700 | static unsigned int efx_ef100_recycle_ring_size(const struct efx_nic *efx) |
701 | { | |
702 | /* Maximum link speed for Riverhead is 100G */ | |
703 | return 10 * EFX_RECYCLE_RING_SIZE_10G; | |
704 | } | |
705 | ||
51b35a45 EC |
706 | /* NIC level access functions |
707 | */ | |
8e57daf7 | 708 | #define EF100_OFFLOAD_FEATURES (NETIF_F_HW_CSUM | NETIF_F_RXCSUM | \ |
4404c089 | 709 | NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_NTUPLE | \ |
8e57daf7 | 710 | NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \ |
dbe2f251 | 711 | NETIF_F_HW_VLAN_CTAG_TX) |
d19a5372 | 712 | |
51b35a45 EC |
713 | const struct efx_nic_type ef100_pf_nic_type = { |
714 | .revision = EFX_REV_EF100, | |
715 | .is_vf = false, | |
716 | .probe = ef100_probe_pf, | |
d19a5372 | 717 | .offload_features = EF100_OFFLOAD_FEATURES, |
51b35a45 | 718 | .mcdi_max_ver = 2, |
2200e6d9 EC |
719 | .mcdi_request = ef100_mcdi_request, |
720 | .mcdi_poll_response = ef100_mcdi_poll_response, | |
721 | .mcdi_read_response = ef100_mcdi_read_response, | |
722 | .mcdi_poll_reboot = ef100_mcdi_poll_reboot, | |
723 | .mcdi_reboot_detected = ef100_mcdi_reboot_detected, | |
51b35a45 | 724 | .irq_enable_master = efx_port_dummy_op_void, |
43c3df0d | 725 | .irq_test_generate = efx_ef100_irq_test_generate, |
51b35a45 EC |
726 | .irq_disable_non_ev = efx_port_dummy_op_void, |
727 | .push_irq_moderation = efx_channel_dummy_op_void, | |
728 | .min_interrupt_mode = EFX_INT_MODE_MSIX, | |
c027f2a7 EC |
729 | .map_reset_reason = ef100_map_reset_reason, |
730 | .map_reset_flags = ef100_map_reset_flags, | |
731 | .reset = ef100_reset, | |
51b35a45 | 732 | |
965b549f EC |
733 | .check_caps = ef100_check_caps, |
734 | ||
51b35a45 | 735 | .ev_probe = ef100_ev_probe, |
965b549f EC |
736 | .ev_init = ef100_ev_init, |
737 | .ev_fini = efx_mcdi_ev_fini, | |
738 | .ev_remove = efx_mcdi_ev_remove, | |
51b35a45 | 739 | .irq_handle_msi = ef100_msi_interrupt, |
965b549f EC |
740 | .ev_process = ef100_ev_process, |
741 | .ev_read_ack = ef100_ev_read_ack, | |
43c3df0d | 742 | .ev_test_generate = efx_ef100_ev_test_generate, |
965b549f EC |
743 | .tx_probe = ef100_tx_probe, |
744 | .tx_init = ef100_tx_init, | |
745 | .tx_write = ef100_tx_write, | |
746 | .tx_enqueue = ef100_enqueue_skb, | |
747 | .rx_probe = efx_mcdi_rx_probe, | |
748 | .rx_init = efx_mcdi_rx_init, | |
749 | .rx_remove = efx_mcdi_rx_remove, | |
750 | .rx_write = ef100_rx_write, | |
751 | .rx_packet = __ef100_rx_packet, | |
db06ea34 | 752 | .rx_buf_hash_valid = ef100_rx_buf_hash_valid, |
b780feac | 753 | .fini_dmaq = efx_fini_dmaq, |
a9dc3d56 EC |
754 | .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, |
755 | .filter_table_probe = ef100_filter_table_up, | |
756 | .filter_table_restore = efx_mcdi_filter_table_restore, | |
757 | .filter_table_remove = ef100_filter_table_down, | |
758 | .filter_insert = efx_mcdi_filter_insert, | |
759 | .filter_remove_safe = efx_mcdi_filter_remove_safe, | |
760 | .filter_get_safe = efx_mcdi_filter_get_safe, | |
761 | .filter_clear_rx = efx_mcdi_filter_clear_rx, | |
762 | .filter_count_rx_used = efx_mcdi_filter_count_rx_used, | |
763 | .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, | |
764 | .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, | |
765 | #ifdef CONFIG_RFS_ACCEL | |
766 | .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, | |
767 | #endif | |
51b35a45 | 768 | |
1c748843 EC |
769 | .get_phys_port_id = efx_ef100_get_phys_port_id, |
770 | ||
8e57daf7 EC |
771 | .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, |
772 | .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, | |
773 | .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, | |
774 | .rx_hash_key_size = 40, | |
775 | .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, | |
776 | .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, | |
777 | .rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config, | |
778 | .rx_pull_rss_context_config = efx_mcdi_rx_pull_rss_context_config, | |
779 | .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, | |
000fe940 | 780 | .rx_recycle_ring_size = efx_ef100_recycle_ring_size, |
8e57daf7 | 781 | |
99a23c11 | 782 | .reconfigure_mac = ef100_reconfigure_mac, |
4404c089 | 783 | .reconfigure_port = efx_mcdi_port_reconfigure, |
43c3df0d | 784 | .test_nvram = efx_new_mcdi_nvram_test_all, |
b593b6f1 EC |
785 | .describe_stats = ef100_describe_stats, |
786 | .start_stats = efx_mcdi_mac_start_stats, | |
787 | .update_stats = ef100_update_stats, | |
788 | .pull_stats = efx_mcdi_mac_pull_stats, | |
789 | .stop_stats = efx_mcdi_mac_stop_stats, | |
99a23c11 | 790 | |
51b35a45 EC |
791 | /* Per-type bar/size configuration not used on ef100. Location of |
792 | * registers is defined by extended capabilities. | |
793 | */ | |
794 | .mem_bar = NULL, | |
795 | .mem_map_size = NULL, | |
796 | ||
797 | }; | |
798 | ||
d61592a1 EC |
799 | const struct efx_nic_type ef100_vf_nic_type = { |
800 | .revision = EFX_REV_EF100, | |
801 | .is_vf = true, | |
802 | .probe = ef100_probe_vf, | |
803 | .offload_features = EF100_OFFLOAD_FEATURES, | |
804 | .mcdi_max_ver = 2, | |
805 | .mcdi_request = ef100_mcdi_request, | |
806 | .mcdi_poll_response = ef100_mcdi_poll_response, | |
807 | .mcdi_read_response = ef100_mcdi_read_response, | |
808 | .mcdi_poll_reboot = ef100_mcdi_poll_reboot, | |
809 | .mcdi_reboot_detected = ef100_mcdi_reboot_detected, | |
810 | .irq_enable_master = efx_port_dummy_op_void, | |
811 | .irq_test_generate = efx_ef100_irq_test_generate, | |
812 | .irq_disable_non_ev = efx_port_dummy_op_void, | |
813 | .push_irq_moderation = efx_channel_dummy_op_void, | |
814 | .min_interrupt_mode = EFX_INT_MODE_MSIX, | |
815 | .map_reset_reason = ef100_map_reset_reason, | |
816 | .map_reset_flags = ef100_map_reset_flags, | |
817 | .reset = ef100_reset, | |
818 | .check_caps = ef100_check_caps, | |
819 | .ev_probe = ef100_ev_probe, | |
820 | .ev_init = ef100_ev_init, | |
821 | .ev_fini = efx_mcdi_ev_fini, | |
822 | .ev_remove = efx_mcdi_ev_remove, | |
823 | .irq_handle_msi = ef100_msi_interrupt, | |
824 | .ev_process = ef100_ev_process, | |
825 | .ev_read_ack = ef100_ev_read_ack, | |
826 | .ev_test_generate = efx_ef100_ev_test_generate, | |
827 | .tx_probe = ef100_tx_probe, | |
828 | .tx_init = ef100_tx_init, | |
829 | .tx_write = ef100_tx_write, | |
830 | .tx_enqueue = ef100_enqueue_skb, | |
831 | .rx_probe = efx_mcdi_rx_probe, | |
832 | .rx_init = efx_mcdi_rx_init, | |
833 | .rx_remove = efx_mcdi_rx_remove, | |
834 | .rx_write = ef100_rx_write, | |
835 | .rx_packet = __ef100_rx_packet, | |
db06ea34 | 836 | .rx_buf_hash_valid = ef100_rx_buf_hash_valid, |
d61592a1 EC |
837 | .fini_dmaq = efx_fini_dmaq, |
838 | .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, | |
839 | .filter_table_probe = ef100_filter_table_up, | |
840 | .filter_table_restore = efx_mcdi_filter_table_restore, | |
841 | .filter_table_remove = ef100_filter_table_down, | |
842 | .filter_insert = efx_mcdi_filter_insert, | |
843 | .filter_remove_safe = efx_mcdi_filter_remove_safe, | |
844 | .filter_get_safe = efx_mcdi_filter_get_safe, | |
845 | .filter_clear_rx = efx_mcdi_filter_clear_rx, | |
846 | .filter_count_rx_used = efx_mcdi_filter_count_rx_used, | |
847 | .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, | |
848 | .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, | |
da795540 | 849 | #ifdef CONFIG_RFS_ACCEL |
d61592a1 | 850 | .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, |
da795540 | 851 | #endif |
d61592a1 EC |
852 | |
853 | .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, | |
854 | .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, | |
855 | .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, | |
856 | .rx_hash_key_size = 40, | |
857 | .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, | |
858 | .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, | |
859 | .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, | |
000fe940 | 860 | .rx_recycle_ring_size = efx_ef100_recycle_ring_size, |
d61592a1 EC |
861 | |
862 | .reconfigure_mac = ef100_reconfigure_mac, | |
863 | .test_nvram = efx_new_mcdi_nvram_test_all, | |
864 | .describe_stats = ef100_describe_stats, | |
865 | .start_stats = efx_mcdi_mac_start_stats, | |
866 | .update_stats = ef100_update_stats, | |
867 | .pull_stats = efx_mcdi_mac_pull_stats, | |
868 | .stop_stats = efx_mcdi_mac_stop_stats, | |
869 | ||
870 | .mem_bar = NULL, | |
871 | .mem_map_size = NULL, | |
872 | ||
873 | }; | |
874 | ||
8e737145 EC |
875 | static int compare_versions(const char *a, const char *b) |
876 | { | |
877 | int a_major, a_minor, a_point, a_patch; | |
878 | int b_major, b_minor, b_point, b_patch; | |
879 | int a_matched, b_matched; | |
880 | ||
881 | a_matched = sscanf(a, "%d.%d.%d.%d", &a_major, &a_minor, &a_point, &a_patch); | |
882 | b_matched = sscanf(b, "%d.%d.%d.%d", &b_major, &b_minor, &b_point, &b_patch); | |
883 | ||
884 | if (a_matched == 4 && b_matched != 4) | |
885 | return +1; | |
886 | ||
887 | if (a_matched != 4 && b_matched == 4) | |
888 | return -1; | |
889 | ||
890 | if (a_matched != 4 && b_matched != 4) | |
891 | return 0; | |
892 | ||
893 | if (a_major != b_major) | |
894 | return a_major - b_major; | |
895 | ||
896 | if (a_minor != b_minor) | |
897 | return a_minor - b_minor; | |
898 | ||
899 | if (a_point != b_point) | |
900 | return a_point - b_point; | |
901 | ||
902 | return a_patch - b_patch; | |
903 | } | |
904 | ||
adcfc348 EC |
905 | enum ef100_tlv_state_machine { |
906 | EF100_TLV_TYPE, | |
907 | EF100_TLV_TYPE_CONT, | |
908 | EF100_TLV_LENGTH, | |
909 | EF100_TLV_VALUE | |
910 | }; | |
911 | ||
912 | struct ef100_tlv_state { | |
913 | enum ef100_tlv_state_machine state; | |
914 | u64 value; | |
915 | u32 value_offset; | |
916 | u16 type; | |
917 | u8 len; | |
918 | }; | |
919 | ||
920 | static int ef100_tlv_feed(struct ef100_tlv_state *state, u8 byte) | |
921 | { | |
922 | switch (state->state) { | |
923 | case EF100_TLV_TYPE: | |
924 | state->type = byte & 0x7f; | |
925 | state->state = (byte & 0x80) ? EF100_TLV_TYPE_CONT | |
926 | : EF100_TLV_LENGTH; | |
927 | /* Clear ready to read in a new entry */ | |
928 | state->value = 0; | |
929 | state->value_offset = 0; | |
930 | return 0; | |
931 | case EF100_TLV_TYPE_CONT: | |
932 | state->type |= byte << 7; | |
933 | state->state = EF100_TLV_LENGTH; | |
934 | return 0; | |
935 | case EF100_TLV_LENGTH: | |
936 | state->len = byte; | |
937 | /* We only handle TLVs that fit in a u64 */ | |
938 | if (state->len > sizeof(state->value)) | |
939 | return -EOPNOTSUPP; | |
940 | /* len may be zero, implying a value of zero */ | |
941 | state->state = state->len ? EF100_TLV_VALUE : EF100_TLV_TYPE; | |
942 | return 0; | |
943 | case EF100_TLV_VALUE: | |
944 | state->value |= ((u64)byte) << (state->value_offset * 8); | |
945 | state->value_offset++; | |
946 | if (state->value_offset >= state->len) | |
947 | state->state = EF100_TLV_TYPE; | |
948 | return 0; | |
949 | default: /* state machine error, can't happen */ | |
950 | WARN_ON_ONCE(1); | |
951 | return -EIO; | |
952 | } | |
953 | } | |
954 | ||
955 | static int ef100_process_design_param(struct efx_nic *efx, | |
956 | const struct ef100_tlv_state *reader) | |
957 | { | |
958 | struct ef100_nic_data *nic_data = efx->nic_data; | |
959 | ||
960 | switch (reader->type) { | |
961 | case ESE_EF100_DP_GZ_PAD: /* padding, skip it */ | |
962 | return 0; | |
963 | case ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS: | |
964 | /* Driver doesn't support timestamping yet, so we don't care */ | |
965 | return 0; | |
966 | case ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS: | |
967 | /* Driver doesn't support unsolicited-event credits yet, so | |
968 | * we don't care | |
969 | */ | |
970 | return 0; | |
971 | case ESE_EF100_DP_GZ_NMMU_GROUP_SIZE: | |
972 | /* Driver doesn't manage the NMMU (so we don't care) */ | |
973 | return 0; | |
974 | case ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS: | |
975 | /* Driver uses CHECKSUM_COMPLETE, so we don't care about | |
976 | * protocol checksum validation | |
977 | */ | |
978 | return 0; | |
979 | case ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN: | |
980 | nic_data->tso_max_hdr_len = min_t(u64, reader->value, 0xffff); | |
981 | return 0; | |
982 | case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS: | |
983 | /* We always put HDR_NUM_SEGS=1 in our TSO descriptors */ | |
984 | if (!reader->value) { | |
985 | netif_err(efx, probe, efx->net_dev, | |
986 | "TSO_MAX_HDR_NUM_SEGS < 1\n"); | |
987 | return -EOPNOTSUPP; | |
988 | } | |
989 | return 0; | |
990 | case ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY: | |
991 | case ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY: | |
992 | /* Our TXQ and RXQ sizes are always power-of-two and thus divisible by | |
993 | * EFX_MIN_DMAQ_SIZE, so we just need to check that | |
994 | * EFX_MIN_DMAQ_SIZE is divisible by GRANULARITY. | |
995 | * This is very unlikely to fail. | |
996 | */ | |
41077c99 EC |
997 | if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE || |
998 | EFX_MIN_DMAQ_SIZE % (u32)reader->value) { | |
adcfc348 EC |
999 | netif_err(efx, probe, efx->net_dev, |
1000 | "%s size granularity is %llu, can't guarantee safety\n", | |
1001 | reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ", | |
1002 | reader->value); | |
1003 | return -EOPNOTSUPP; | |
1004 | } | |
1005 | return 0; | |
1006 | case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN: | |
1007 | nic_data->tso_max_payload_len = min_t(u64, reader->value, GSO_MAX_SIZE); | |
4b66d216 | 1008 | netif_set_gso_max_size(efx->net_dev, nic_data->tso_max_payload_len); |
adcfc348 EC |
1009 | return 0; |
1010 | case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS: | |
1011 | nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff); | |
6d872df3 | 1012 | netif_set_gso_max_segs(efx->net_dev, nic_data->tso_max_payload_num_segs); |
adcfc348 EC |
1013 | return 0; |
1014 | case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES: | |
1015 | nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff); | |
1016 | return 0; | |
1017 | case ESE_EF100_DP_GZ_COMPAT: | |
1018 | if (reader->value) { | |
1019 | netif_err(efx, probe, efx->net_dev, | |
1020 | "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n", | |
1021 | reader->value); | |
1022 | return -EOPNOTSUPP; | |
1023 | } | |
1024 | return 0; | |
1025 | case ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN: | |
1026 | /* Driver doesn't use mem2mem transfers */ | |
1027 | return 0; | |
1028 | case ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS: | |
1029 | /* Driver doesn't currently use EVQ_TIMER */ | |
1030 | return 0; | |
1031 | case ESE_EF100_DP_GZ_NMMU_PAGE_SIZES: | |
1032 | /* Driver doesn't manage the NMMU (so we don't care) */ | |
1033 | return 0; | |
1034 | case ESE_EF100_DP_GZ_VI_STRIDES: | |
1035 | /* We never try to set the VI stride, and we don't rely on | |
1036 | * being able to find VIs past VI 0 until after we've learned | |
1037 | * the current stride from MC_CMD_GET_CAPABILITIES. | |
1038 | * So the value of this shouldn't matter. | |
1039 | */ | |
1040 | if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT) | |
1041 | netif_dbg(efx, probe, efx->net_dev, | |
1042 | "NIC has other than default VI_STRIDES (mask " | |
1043 | "%#llx), early probing might use wrong one\n", | |
1044 | reader->value); | |
1045 | return 0; | |
1046 | case ESE_EF100_DP_GZ_RX_MAX_RUNT: | |
1047 | /* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't | |
1048 | * care whether it indicates runt or overlength for any given | |
1049 | * packet, so we don't care about this parameter. | |
1050 | */ | |
1051 | return 0; | |
1052 | default: | |
1053 | /* Host interface says "Drivers should ignore design parameters | |
1054 | * that they do not recognise." | |
1055 | */ | |
1056 | netif_dbg(efx, probe, efx->net_dev, | |
1057 | "Ignoring unrecognised design parameter %u\n", | |
1058 | reader->type); | |
1059 | return 0; | |
1060 | } | |
1061 | } | |
1062 | ||
1063 | static int ef100_check_design_params(struct efx_nic *efx) | |
1064 | { | |
1065 | struct ef100_tlv_state reader = {}; | |
1066 | u32 total_len, offset = 0; | |
1067 | efx_dword_t reg; | |
1068 | int rc = 0, i; | |
1069 | u32 data; | |
1070 | ||
1071 | efx_readd(efx, ®, ER_GZ_PARAMS_TLV_LEN); | |
1072 | total_len = EFX_DWORD_FIELD(reg, EFX_DWORD_0); | |
1073 | netif_dbg(efx, probe, efx->net_dev, "%u bytes of design parameters\n", | |
1074 | total_len); | |
1075 | while (offset < total_len) { | |
1076 | efx_readd(efx, ®, ER_GZ_PARAMS_TLV + offset); | |
1077 | data = EFX_DWORD_FIELD(reg, EFX_DWORD_0); | |
1078 | for (i = 0; i < sizeof(data); i++) { | |
1079 | rc = ef100_tlv_feed(&reader, data); | |
1080 | /* Got a complete value? */ | |
1081 | if (!rc && reader.state == EF100_TLV_TYPE) | |
1082 | rc = ef100_process_design_param(efx, &reader); | |
1083 | if (rc) | |
1084 | goto out; | |
1085 | data >>= 8; | |
1086 | offset++; | |
1087 | } | |
1088 | } | |
1089 | /* Check we didn't end halfway through a TLV entry, which could either | |
1090 | * mean that the TLV stream is truncated or just that it's corrupted | |
1091 | * and our state machine is out of sync. | |
1092 | */ | |
1093 | if (reader.state != EF100_TLV_TYPE) { | |
1094 | if (reader.state == EF100_TLV_TYPE_CONT) | |
1095 | netif_err(efx, probe, efx->net_dev, | |
1096 | "truncated design parameter (incomplete type %u)\n", | |
1097 | reader.type); | |
1098 | else | |
1099 | netif_err(efx, probe, efx->net_dev, | |
1100 | "truncated design parameter %u\n", | |
1101 | reader.type); | |
1102 | rc = -EIO; | |
1103 | } | |
1104 | out: | |
1105 | return rc; | |
1106 | } | |
1107 | ||
51b35a45 EC |
1108 | /* NIC probe and remove |
1109 | */ | |
1110 | static int ef100_probe_main(struct efx_nic *efx) | |
1111 | { | |
1112 | unsigned int bar_size = resource_size(&efx->pci_dev->resource[efx->mem_bar]); | |
1113 | struct net_device *net_dev = efx->net_dev; | |
1114 | struct ef100_nic_data *nic_data; | |
8e737145 | 1115 | char fw_version[32]; |
51b35a45 EC |
1116 | int i, rc; |
1117 | ||
1118 | if (WARN_ON(bar_size == 0)) | |
1119 | return -EIO; | |
1120 | ||
1121 | nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); | |
1122 | if (!nic_data) | |
1123 | return -ENOMEM; | |
1124 | efx->nic_data = nic_data; | |
1125 | nic_data->efx = efx; | |
1126 | net_dev->features |= efx->type->offload_features; | |
1127 | net_dev->hw_features |= efx->type->offload_features; | |
806f9f23 | 1128 | net_dev->hw_enc_features |= efx->type->offload_features; |
b61e8100 EC |
1129 | net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG | |
1130 | NETIF_F_HIGHDMA | NETIF_F_ALL_TSO; | |
51b35a45 | 1131 | |
adcfc348 EC |
1132 | /* Populate design-parameter defaults */ |
1133 | nic_data->tso_max_hdr_len = ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT; | |
1134 | nic_data->tso_max_frames = ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT; | |
1135 | nic_data->tso_max_payload_num_segs = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT; | |
1136 | nic_data->tso_max_payload_len = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT; | |
6d872df3 | 1137 | netif_set_gso_max_segs(net_dev, ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT); |
adcfc348 EC |
1138 | /* Read design parameters */ |
1139 | rc = ef100_check_design_params(efx); | |
1140 | if (rc) { | |
1141 | netif_err(efx, probe, efx->net_dev, | |
1142 | "Unsupported design parameters\n"); | |
1143 | goto fail; | |
1144 | } | |
1145 | ||
2200e6d9 EC |
1146 | /* we assume later that we can copy from this buffer in dwords */ |
1147 | BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4); | |
1148 | ||
1149 | /* MCDI buffers must be 256 byte aligned. */ | |
1150 | rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf, MCDI_BUF_LEN, | |
1151 | GFP_KERNEL); | |
1152 | if (rc) | |
1153 | goto fail; | |
1154 | ||
51b35a45 EC |
1155 | /* Get the MC's warm boot count. In case it's rebooting right |
1156 | * now, be prepared to retry. | |
1157 | */ | |
1158 | i = 0; | |
1159 | for (;;) { | |
1160 | rc = ef100_get_warm_boot_count(efx); | |
1161 | if (rc >= 0) | |
1162 | break; | |
1163 | if (++i == 5) | |
1164 | goto fail; | |
1165 | ssleep(1); | |
1166 | } | |
1167 | nic_data->warm_boot_count = rc; | |
1168 | ||
1169 | /* In case we're recovering from a crash (kexec), we want to | |
1170 | * cancel any outstanding request by the previous user of this | |
1171 | * function. We send a special message using the least | |
1172 | * significant bits of the 'high' (doorbell) register. | |
1173 | */ | |
1174 | _efx_writed(efx, cpu_to_le32(1), efx_reg(efx, ER_GZ_MC_DB_HWRD)); | |
1175 | ||
1176 | /* Post-IO section. */ | |
1177 | ||
2200e6d9 EC |
1178 | rc = efx_mcdi_init(efx); |
1179 | if (!rc && efx->mcdi->fn_flags & | |
1180 | (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT)) { | |
1181 | netif_info(efx, probe, efx->net_dev, | |
1182 | "No network port on this PCI function"); | |
1183 | rc = -ENODEV; | |
1184 | } | |
1185 | if (rc) | |
1186 | goto fail; | |
4e5675bb EC |
1187 | /* Reset (most) configuration for this function */ |
1188 | rc = efx_mcdi_reset(efx, RESET_TYPE_ALL); | |
4404c089 EC |
1189 | if (rc) |
1190 | goto fail; | |
1191 | /* Enable event logging */ | |
1192 | rc = efx_mcdi_log_ctrl(efx, true, false, 0); | |
4e5675bb EC |
1193 | if (rc) |
1194 | goto fail; | |
1195 | ||
ef2c57b9 EC |
1196 | rc = efx_get_pf_index(efx, &nic_data->pf_index); |
1197 | if (rc) | |
1198 | goto fail; | |
1199 | ||
f6573120 EC |
1200 | rc = efx_ef100_init_datapath_caps(efx); |
1201 | if (rc < 0) | |
1202 | goto fail; | |
2200e6d9 | 1203 | |
51b35a45 EC |
1204 | efx->max_vis = EF100_MAX_VIS; |
1205 | ||
1c748843 EC |
1206 | rc = efx_mcdi_port_get_number(efx); |
1207 | if (rc < 0) | |
1208 | goto fail; | |
1209 | efx->port_num = rc; | |
1210 | ||
8e737145 EC |
1211 | efx_mcdi_print_fwver(efx, fw_version, sizeof(fw_version)); |
1212 | netif_dbg(efx, drv, efx->net_dev, "Firmware version %s\n", fw_version); | |
1213 | ||
1214 | if (compare_versions(fw_version, "1.1.0.1000") < 0) { | |
1215 | netif_info(efx, drv, efx->net_dev, "Firmware uses old event descriptors\n"); | |
1216 | rc = -EINVAL; | |
4496363b EC |
1217 | goto fail; |
1218 | } | |
1219 | ||
1220 | if (efx_has_cap(efx, UNSOL_EV_CREDIT_SUPPORTED)) { | |
1221 | netif_info(efx, drv, efx->net_dev, "Firmware uses unsolicited-event credits\n"); | |
1222 | rc = -EINVAL; | |
8e737145 EC |
1223 | goto fail; |
1224 | } | |
1225 | ||
aa86a75f EC |
1226 | rc = ef100_phy_probe(efx); |
1227 | if (rc) | |
1228 | goto fail; | |
1229 | ||
a9dc3d56 EC |
1230 | down_write(&efx->filter_sem); |
1231 | rc = ef100_filter_table_probe(efx); | |
1232 | up_write(&efx->filter_sem); | |
1233 | if (rc) | |
1234 | goto fail; | |
1235 | ||
8e57daf7 EC |
1236 | netdev_rss_key_fill(efx->rss_context.rx_hash_key, |
1237 | sizeof(efx->rss_context.rx_hash_key)); | |
1238 | ||
1239 | /* Don't fail init if RSS setup doesn't work. */ | |
1240 | efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels); | |
1241 | ||
51b35a45 EC |
1242 | rc = ef100_register_netdev(efx); |
1243 | if (rc) | |
1244 | goto fail; | |
1245 | ||
1246 | return 0; | |
1247 | fail: | |
1248 | return rc; | |
1249 | } | |
1250 | ||
1251 | int ef100_probe_pf(struct efx_nic *efx) | |
1252 | { | |
29ec1b27 EC |
1253 | struct net_device *net_dev = efx->net_dev; |
1254 | struct ef100_nic_data *nic_data; | |
1255 | int rc = ef100_probe_main(efx); | |
1256 | ||
1257 | if (rc) | |
1258 | goto fail; | |
1259 | ||
1260 | nic_data = efx->nic_data; | |
1261 | rc = ef100_get_mac_address(efx, net_dev->perm_addr); | |
1262 | if (rc) | |
1263 | goto fail; | |
1264 | /* Assign MAC address */ | |
a96d317f | 1265 | eth_hw_addr_set(net_dev, net_dev->perm_addr); |
29ec1b27 EC |
1266 | memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN); |
1267 | ||
1268 | return 0; | |
1269 | ||
1270 | fail: | |
1271 | return rc; | |
51b35a45 EC |
1272 | } |
1273 | ||
d61592a1 EC |
1274 | int ef100_probe_vf(struct efx_nic *efx) |
1275 | { | |
1276 | return ef100_probe_main(efx); | |
1277 | } | |
1278 | ||
51b35a45 EC |
1279 | void ef100_remove(struct efx_nic *efx) |
1280 | { | |
1281 | struct ef100_nic_data *nic_data = efx->nic_data; | |
1282 | ||
1283 | ef100_unregister_netdev(efx); | |
a9dc3d56 EC |
1284 | |
1285 | down_write(&efx->filter_sem); | |
1286 | efx_mcdi_filter_table_remove(efx); | |
1287 | up_write(&efx->filter_sem); | |
51b35a45 EC |
1288 | efx_fini_channels(efx); |
1289 | kfree(efx->phy_data); | |
1290 | efx->phy_data = NULL; | |
2200e6d9 EC |
1291 | efx_mcdi_detach(efx); |
1292 | efx_mcdi_fini(efx); | |
1293 | if (nic_data) | |
1294 | efx_nic_free_buffer(efx, &nic_data->mcdi_buf); | |
51b35a45 EC |
1295 | kfree(nic_data); |
1296 | efx->nic_data = NULL; | |
1297 | } |