1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /**************************************************************************** |
3 | * Driver for Solarflare network controllers and boards |
4 | * Copyright 2005-2006 Fen Systems Ltd. |
5 | * Copyright 2006-2013 Solarflare Communications Inc. |
6 | */ |
7 | |
8 | #include <linux/bitops.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/pci.h> |
11 | #include <linux/module.h> |
12 | #include <linux/slab.h> |
13 | #include <linux/random.h> |
14 | #include "net_driver.h" |
15 | #include "bitfield.h" |
16 | #include "efx.h" |
17 | #include "efx_common.h" |
18 | #include "nic.h" |
19 | #include "farch_regs.h" |
20 | #include "io.h" |
21 | #include "workarounds.h" |
22 | #include "mcdi.h" |
23 | #include "mcdi_pcol.h" |
24 | #include "mcdi_port.h" |
25 | #include "mcdi_port_common.h" |
26 | #include "selftest.h" |
27 | #include "siena_sriov.h" |
28 | #include "rx_common.h" |
29 | |
30 | /* Hardware control for SFC9000 family including SFL9021 (aka Siena). */ |
31 | |
32 | static void siena_init_wol(struct efx_nic *efx); |
33 | |
34 | |
35 | static void siena_push_irq_moderation(struct efx_channel *channel) |
36 | { |
37 | struct efx_nic *efx = channel->efx; |
38 | efx_dword_t timer_cmd; |
39 | |
40 | if (channel->irq_moderation_us) { |
41 | unsigned int ticks; |
42 | |
43 | ticks = efx_siena_usecs_to_ticks(efx, usecs: channel->irq_moderation_us); |
44 | EFX_POPULATE_DWORD_2(timer_cmd, |
45 | FRF_CZ_TC_TIMER_MODE, |
46 | FFE_CZ_TIMER_MODE_INT_HLDOFF, |
47 | FRF_CZ_TC_TIMER_VAL, |
48 | ticks - 1); |
49 | } else { |
50 | EFX_POPULATE_DWORD_2(timer_cmd, |
51 | FRF_CZ_TC_TIMER_MODE, |
52 | FFE_CZ_TIMER_MODE_DIS, |
53 | FRF_CZ_TC_TIMER_VAL, 0); |
54 | } |
55 | efx_writed_page_locked(channel->efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0, |
56 | channel->channel); |
57 | } |
58 | |
59 | void efx_siena_prepare_flush(struct efx_nic *efx) |
60 | { |
61 | if (efx->fc_disable++ == 0) |
62 | efx_siena_mcdi_set_mac(efx); |
63 | } |
64 | |
65 | void siena_finish_flush(struct efx_nic *efx) |
66 | { |
67 | if (--efx->fc_disable == 0) |
68 | efx_siena_mcdi_set_mac(efx); |
69 | } |
70 | |
71 | static const struct efx_farch_register_test siena_register_tests[] = { |
72 | { FR_AZ_ADR_REGION, |
73 | EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) }, |
74 | { FR_CZ_USR_EV_CFG, |
75 | EFX_OWORD32(0x000103FF, 0x00000000, 0x00000000, 0x00000000) }, |
76 | { FR_AZ_RX_CFG, |
77 | EFX_OWORD32(0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000) }, |
78 | { FR_AZ_TX_CFG, |
79 | EFX_OWORD32(0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF) }, |
80 | { FR_AZ_TX_RESERVED, |
81 | EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) }, |
82 | { FR_AZ_SRM_TX_DC_CFG, |
83 | EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) }, |
84 | { FR_AZ_RX_DC_CFG, |
85 | EFX_OWORD32(0x00000003, 0x00000000, 0x00000000, 0x00000000) }, |
86 | { FR_AZ_RX_DC_PF_WM, |
87 | EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, |
88 | { FR_BZ_DP_CTRL, |
89 | EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, |
90 | { FR_BZ_RX_RSS_TKEY, |
91 | EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) }, |
92 | { FR_CZ_RX_RSS_IPV6_REG1, |
93 | EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) }, |
94 | { FR_CZ_RX_RSS_IPV6_REG2, |
95 | EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) }, |
96 | { FR_CZ_RX_RSS_IPV6_REG3, |
97 | EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000) }, |
98 | }; |
99 | |
100 | static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) |
101 | { |
102 | enum reset_type reset_method = RESET_TYPE_ALL; |
103 | int rc, rc2; |
104 | |
105 | efx_siena_reset_down(efx, method: reset_method); |
106 | |
107 | /* Reset the chip immediately so that it is completely |
108 | * quiescent regardless of what any VF driver does. |
109 | */ |
110 | rc = efx_siena_mcdi_reset(efx, method: reset_method); |
111 | if (rc) |
112 | goto out; |
113 | |
114 | tests->registers = |
115 | efx_farch_test_registers(efx, regs: siena_register_tests, |
116 | ARRAY_SIZE(siena_register_tests)) |
117 | ? -1 : 1; |
118 | |
119 | rc = efx_siena_mcdi_reset(efx, method: reset_method); |
120 | out: |
121 | rc2 = efx_siena_reset_up(efx, method: reset_method, ok: rc == 0); |
122 | return rc ? rc : rc2; |
123 | } |
124 | |
125 | /************************************************************************** |
126 | * |
127 | * PTP |
128 | * |
129 | ************************************************************************** |
130 | */ |
131 | |
132 | static void siena_ptp_write_host_time(struct efx_nic *efx, u32 host_time) |
133 | { |
134 | _efx_writed(efx, cpu_to_le32(host_time), |
135 | FR_CZ_MC_TREG_SMEM + MC_SMEM_P0_PTP_TIME_OFST); |
136 | } |
137 | |
138 | static int siena_ptp_set_ts_config(struct efx_nic *efx, |
139 | struct kernel_hwtstamp_config *init) |
140 | { |
141 | int rc; |
142 | |
143 | switch (init->rx_filter) { |
144 | case HWTSTAMP_FILTER_NONE: |
145 | /* if TX timestamping is still requested then leave PTP on */ |
146 | return efx_siena_ptp_change_mode(efx, |
147 | enable_wanted: init->tx_type != HWTSTAMP_TX_OFF, |
148 | new_mode: efx_siena_ptp_get_mode(efx)); |
149 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
150 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
151 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
152 | init->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; |
153 | return efx_siena_ptp_change_mode(efx, enable_wanted: true, MC_CMD_PTP_MODE_V1); |
154 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
155 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
156 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
157 | init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; |
158 | rc = efx_siena_ptp_change_mode(efx, enable_wanted: true, |
159 | MC_CMD_PTP_MODE_V2_ENHANCED); |
160 | /* bug 33070 - old versions of the firmware do not support the |
161 | * improved UUID filtering option. Similarly old versions of the |
162 | * application do not expect it to be enabled. If the firmware |
163 | * does not accept the enhanced mode, fall back to the standard |
164 | * PTP v2 UUID filtering. */ |
165 | if (rc != 0) |
166 | rc = efx_siena_ptp_change_mode(efx, enable_wanted: true, |
167 | MC_CMD_PTP_MODE_V2); |
168 | return rc; |
169 | default: |
170 | return -ERANGE; |
171 | } |
172 | } |
173 | |
174 | /************************************************************************** |
175 | * |
176 | * Device reset |
177 | * |
178 | ************************************************************************** |
179 | */ |
180 | |
181 | static int siena_map_reset_flags(u32 *flags) |
182 | { |
183 | enum { |
184 | SIENA_RESET_PORT = (ETH_RESET_DMA | ETH_RESET_FILTER | |
185 | ETH_RESET_OFFLOAD | ETH_RESET_MAC | |
186 | ETH_RESET_PHY), |
187 | SIENA_RESET_MC = (SIENA_RESET_PORT | |
188 | ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT), |
189 | }; |
190 | |
191 | if ((*flags & SIENA_RESET_MC) == SIENA_RESET_MC) { |
192 | *flags &= ~SIENA_RESET_MC; |
193 | return RESET_TYPE_WORLD; |
194 | } |
195 | |
196 | if ((*flags & SIENA_RESET_PORT) == SIENA_RESET_PORT) { |
197 | *flags &= ~SIENA_RESET_PORT; |
198 | return RESET_TYPE_ALL; |
199 | } |
200 | |
201 | /* no invisible reset implemented */ |
202 | |
203 | return -EINVAL; |
204 | } |
205 | |
206 | #ifdef CONFIG_EEH |
207 | /* When a PCI device is isolated from the bus, a subsequent MMIO read is |
208 | * required for the kernel EEH mechanisms to notice. As the Solarflare driver |
209 | * was written to minimise MMIO read (for latency) then a periodic call to check |
210 | * the EEH status of the device is required so that device recovery can happen |
211 | * in a timely fashion. |
212 | */ |
213 | static void siena_monitor(struct efx_nic *efx) |
214 | { |
215 | struct eeh_dev *eehdev = pci_dev_to_eeh_dev(efx->pci_dev); |
216 | |
217 | eeh_dev_check_failure(eehdev); |
218 | } |
219 | #endif |
220 | |
221 | static int siena_probe_nvconfig(struct efx_nic *efx) |
222 | { |
223 | u32 caps = 0; |
224 | int rc; |
225 | |
226 | rc = efx_siena_mcdi_get_board_cfg(efx, mac_address: efx->net_dev->perm_addr, NULL, |
227 | capabilities: &caps); |
228 | |
229 | efx->timer_quantum_ns = |
230 | (caps & (1 << MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN)) ? |
231 | 3072 : 6144; /* 768 cycles */ |
232 | efx->timer_max_ns = efx->type->timer_period_max * |
233 | efx->timer_quantum_ns; |
234 | |
235 | return rc; |
236 | } |
237 | |
238 | static int siena_dimension_resources(struct efx_nic *efx) |
239 | { |
240 | /* Each port has a small block of internal SRAM dedicated to |
241 | * the buffer table and descriptor caches. In theory we can |
242 | * map both blocks to one port, but we don't. |
243 | */ |
244 | efx_farch_dimension_resources(efx, FR_CZ_BUF_FULL_TBL_ROWS / 2); |
245 | return 0; |
246 | } |
247 | |
248 | /* On all Falcon-architecture NICs, PFs use BAR 0 for I/O space and BAR 2(&3) |
249 | * for memory. |
250 | */ |
251 | static unsigned int siena_mem_bar(struct efx_nic *efx) |
252 | { |
253 | return 2; |
254 | } |
255 | |
256 | static unsigned int siena_mem_map_size(struct efx_nic *efx) |
257 | { |
258 | return FR_CZ_MC_TREG_SMEM + |
259 | FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS; |
260 | } |
261 | |
262 | static int siena_probe_nic(struct efx_nic *efx) |
263 | { |
264 | struct siena_nic_data *nic_data; |
265 | efx_oword_t reg; |
266 | int rc; |
267 | |
268 | /* Allocate storage for hardware specific data */ |
269 | nic_data = kzalloc(size: sizeof(struct siena_nic_data), GFP_KERNEL); |
270 | if (!nic_data) |
271 | return -ENOMEM; |
272 | nic_data->efx = efx; |
273 | efx->nic_data = nic_data; |
274 | |
275 | if (efx_farch_fpga_ver(efx) != 0) { |
276 | netif_err(efx, probe, efx->net_dev, |
277 | "Siena FPGA not supported\n" ); |
278 | rc = -ENODEV; |
279 | goto fail1; |
280 | } |
281 | |
282 | efx->max_channels = EFX_MAX_CHANNELS; |
283 | efx->max_vis = EFX_MAX_CHANNELS; |
284 | efx->max_tx_channels = EFX_MAX_CHANNELS; |
285 | efx->tx_queues_per_channel = 4; |
286 | |
287 | efx_reado(efx, value: ®, FR_AZ_CS_DEBUG); |
288 | efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; |
289 | |
290 | rc = efx_siena_mcdi_init(efx); |
291 | if (rc) |
292 | goto fail1; |
293 | |
294 | /* Now we can reset the NIC */ |
295 | rc = efx_siena_mcdi_reset(efx, method: RESET_TYPE_ALL); |
296 | if (rc) { |
297 | netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n" ); |
298 | goto fail3; |
299 | } |
300 | |
301 | siena_init_wol(efx); |
302 | |
303 | /* Allocate memory for INT_KER */ |
304 | rc = efx_siena_alloc_buffer(efx, buffer: &efx->irq_status, len: sizeof(efx_oword_t), |
305 | GFP_KERNEL); |
306 | if (rc) |
307 | goto fail4; |
308 | BUG_ON(efx->irq_status.dma_addr & 0x0f); |
309 | |
310 | netif_dbg(efx, probe, efx->net_dev, |
311 | "INT_KER at %llx (virt %p phys %llx)\n" , |
312 | (unsigned long long)efx->irq_status.dma_addr, |
313 | efx->irq_status.addr, |
314 | (unsigned long long)virt_to_phys(efx->irq_status.addr)); |
315 | |
316 | /* Read in the non-volatile configuration */ |
317 | rc = siena_probe_nvconfig(efx); |
318 | if (rc == -EINVAL) { |
319 | netif_err(efx, probe, efx->net_dev, |
320 | "NVRAM is invalid therefore using defaults\n" ); |
321 | efx->phy_type = PHY_TYPE_NONE; |
322 | efx->mdio.prtad = MDIO_PRTAD_NONE; |
323 | } else if (rc) { |
324 | goto fail5; |
325 | } |
326 | |
327 | rc = efx_siena_mcdi_mon_probe(efx); |
328 | if (rc) |
329 | goto fail5; |
330 | |
331 | #ifdef CONFIG_SFC_SIENA_SRIOV |
332 | efx_siena_sriov_probe(efx); |
333 | #endif |
334 | efx_siena_ptp_defer_probe_with_channel(efx); |
335 | |
336 | return 0; |
337 | |
338 | fail5: |
339 | efx_siena_free_buffer(efx, buffer: &efx->irq_status); |
340 | fail4: |
341 | fail3: |
342 | efx_siena_mcdi_detach(efx); |
343 | efx_siena_mcdi_fini(efx); |
344 | fail1: |
345 | kfree(objp: efx->nic_data); |
346 | return rc; |
347 | } |
348 | |
349 | static int (struct efx_nic *efx) |
350 | { |
351 | efx_oword_t temp; |
352 | |
353 | /* Read from IPv6 RSS key as that's longer (the IPv4 key is just the |
354 | * first 128 bits of the same key, assuming it's been set by |
355 | * siena_rx_push_rss_config, below) |
356 | */ |
357 | efx_reado(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG1); |
358 | memcpy(efx->rss_context.rx_hash_key, &temp, sizeof(temp)); |
359 | efx_reado(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG2); |
360 | memcpy(efx->rss_context.rx_hash_key + sizeof(temp), &temp, sizeof(temp)); |
361 | efx_reado(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG3); |
362 | memcpy(efx->rss_context.rx_hash_key + 2 * sizeof(temp), &temp, |
363 | FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); |
364 | efx_farch_rx_pull_indir_table(efx); |
365 | return 0; |
366 | } |
367 | |
368 | static int (struct efx_nic *efx, bool user, |
369 | const u32 *rx_indir_table, const u8 *key) |
370 | { |
371 | efx_oword_t temp; |
372 | |
373 | /* Set hash key for IPv4 */ |
374 | if (key) |
375 | memcpy(efx->rss_context.rx_hash_key, key, sizeof(temp)); |
376 | memcpy(&temp, efx->rss_context.rx_hash_key, sizeof(temp)); |
377 | efx_writeo(efx, value: &temp, FR_BZ_RX_RSS_TKEY); |
378 | |
379 | /* Enable IPv6 RSS */ |
380 | BUILD_BUG_ON(sizeof(efx->rss_context.rx_hash_key) < |
381 | 2 * sizeof(temp) + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8 || |
382 | FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN != 0); |
383 | memcpy(&temp, efx->rss_context.rx_hash_key, sizeof(temp)); |
384 | efx_writeo(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG1); |
385 | memcpy(&temp, efx->rss_context.rx_hash_key + sizeof(temp), sizeof(temp)); |
386 | efx_writeo(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG2); |
387 | EFX_POPULATE_OWORD_2(temp, FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1, |
388 | FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, 1); |
389 | memcpy(&temp, efx->rss_context.rx_hash_key + 2 * sizeof(temp), |
390 | FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); |
391 | efx_writeo(efx, value: &temp, FR_CZ_RX_RSS_IPV6_REG3); |
392 | |
393 | memcpy(efx->rss_context.rx_indir_table, rx_indir_table, |
394 | sizeof(efx->rss_context.rx_indir_table)); |
395 | efx_farch_rx_push_indir_table(efx); |
396 | |
397 | return 0; |
398 | } |
399 | |
400 | /* This call performs hardware-specific global initialisation, such as |
401 | * defining the descriptor cache sizes and number of RSS channels. |
402 | * It does not set up any buffers, descriptor rings or event queues. |
403 | */ |
404 | static int siena_init_nic(struct efx_nic *efx) |
405 | { |
406 | efx_oword_t temp; |
407 | int rc; |
408 | |
409 | /* Recover from a failed assertion post-reset */ |
410 | rc = efx_siena_mcdi_handle_assertion(efx); |
411 | if (rc) |
412 | return rc; |
413 | |
414 | /* Squash TX of packets of 16 bytes or less */ |
415 | efx_reado(efx, value: &temp, FR_AZ_TX_RESERVED); |
416 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); |
417 | efx_writeo(efx, value: &temp, FR_AZ_TX_RESERVED); |
418 | |
419 | /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 |
420 | * descriptors (which is bad). |
421 | */ |
422 | efx_reado(efx, value: &temp, FR_AZ_TX_CFG); |
423 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0); |
424 | EFX_SET_OWORD_FIELD(temp, FRF_CZ_TX_FILTER_EN_BIT, 1); |
425 | efx_writeo(efx, value: &temp, FR_AZ_TX_CFG); |
426 | |
427 | efx_reado(efx, value: &temp, FR_AZ_RX_CFG); |
428 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_DESC_PUSH_EN, 0); |
429 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1); |
430 | /* Enable hash insertion. This is broken for the 'Falcon' hash |
431 | * if IPv6 hashing is also enabled, so also select Toeplitz |
432 | * TCP/IPv4 and IPv4 hashes. */ |
433 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_INSRT_HDR, 1); |
434 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_ALG, 1); |
435 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_IP_HASH, 1); |
436 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_USR_BUF_SIZE, |
437 | EFX_RX_USR_BUF_SIZE >> 5); |
438 | efx_writeo(efx, value: &temp, FR_AZ_RX_CFG); |
439 | |
440 | siena_rx_push_rss_config(efx, user: false, rx_indir_table: efx->rss_context.rx_indir_table, NULL); |
441 | efx->rss_context.context_id = 0; /* indicates RSS is active */ |
442 | |
443 | /* Enable event logging */ |
444 | rc = efx_siena_mcdi_log_ctrl(efx, evq: true, uart: false, dest_evq: 0); |
445 | if (rc) |
446 | return rc; |
447 | |
448 | /* Set destination of both TX and RX Flush events */ |
449 | EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); |
450 | efx_writeo(efx, value: &temp, FR_BZ_DP_CTRL); |
451 | |
452 | EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1); |
453 | efx_writeo(efx, value: &temp, FR_CZ_USR_EV_CFG); |
454 | |
455 | efx_farch_init_common(efx); |
456 | return 0; |
457 | } |
458 | |
459 | static void siena_remove_nic(struct efx_nic *efx) |
460 | { |
461 | efx_siena_mcdi_mon_remove(efx); |
462 | |
463 | efx_siena_free_buffer(efx, buffer: &efx->irq_status); |
464 | |
465 | efx_siena_mcdi_reset(efx, method: RESET_TYPE_ALL); |
466 | |
467 | efx_siena_mcdi_detach(efx); |
468 | efx_siena_mcdi_fini(efx); |
469 | |
470 | /* Tear down the private nic state */ |
471 | kfree(objp: efx->nic_data); |
472 | efx->nic_data = NULL; |
473 | } |
474 | |
475 | #define SIENA_DMA_STAT(ext_name, mcdi_name) \ |
476 | [SIENA_STAT_ ## ext_name] = \ |
477 | { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name } |
478 | #define SIENA_OTHER_STAT(ext_name) \ |
479 | [SIENA_STAT_ ## ext_name] = { #ext_name, 0, 0 } |
480 | #define GENERIC_SW_STAT(ext_name) \ |
481 | [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 } |
482 | |
483 | static const struct efx_hw_stat_desc siena_stat_desc[SIENA_STAT_COUNT] = { |
484 | SIENA_DMA_STAT(tx_bytes, TX_BYTES), |
485 | SIENA_OTHER_STAT(tx_good_bytes), |
486 | SIENA_DMA_STAT(tx_bad_bytes, TX_BAD_BYTES), |
487 | SIENA_DMA_STAT(tx_packets, TX_PKTS), |
488 | SIENA_DMA_STAT(tx_bad, TX_BAD_FCS_PKTS), |
489 | SIENA_DMA_STAT(tx_pause, TX_PAUSE_PKTS), |
490 | SIENA_DMA_STAT(tx_control, TX_CONTROL_PKTS), |
491 | SIENA_DMA_STAT(tx_unicast, TX_UNICAST_PKTS), |
492 | SIENA_DMA_STAT(tx_multicast, TX_MULTICAST_PKTS), |
493 | SIENA_DMA_STAT(tx_broadcast, TX_BROADCAST_PKTS), |
494 | SIENA_DMA_STAT(tx_lt64, TX_LT64_PKTS), |
495 | SIENA_DMA_STAT(tx_64, TX_64_PKTS), |
496 | SIENA_DMA_STAT(tx_65_to_127, TX_65_TO_127_PKTS), |
497 | SIENA_DMA_STAT(tx_128_to_255, TX_128_TO_255_PKTS), |
498 | SIENA_DMA_STAT(tx_256_to_511, TX_256_TO_511_PKTS), |
499 | SIENA_DMA_STAT(tx_512_to_1023, TX_512_TO_1023_PKTS), |
500 | SIENA_DMA_STAT(tx_1024_to_15xx, TX_1024_TO_15XX_PKTS), |
501 | SIENA_DMA_STAT(tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS), |
502 | SIENA_DMA_STAT(tx_gtjumbo, TX_GTJUMBO_PKTS), |
503 | SIENA_OTHER_STAT(tx_collision), |
504 | SIENA_DMA_STAT(tx_single_collision, TX_SINGLE_COLLISION_PKTS), |
505 | SIENA_DMA_STAT(tx_multiple_collision, TX_MULTIPLE_COLLISION_PKTS), |
506 | SIENA_DMA_STAT(tx_excessive_collision, TX_EXCESSIVE_COLLISION_PKTS), |
507 | SIENA_DMA_STAT(tx_deferred, TX_DEFERRED_PKTS), |
508 | SIENA_DMA_STAT(tx_late_collision, TX_LATE_COLLISION_PKTS), |
509 | SIENA_DMA_STAT(tx_excessive_deferred, TX_EXCESSIVE_DEFERRED_PKTS), |
510 | SIENA_DMA_STAT(tx_non_tcpudp, TX_NON_TCPUDP_PKTS), |
511 | SIENA_DMA_STAT(tx_mac_src_error, TX_MAC_SRC_ERR_PKTS), |
512 | SIENA_DMA_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS), |
513 | SIENA_DMA_STAT(rx_bytes, RX_BYTES), |
514 | SIENA_OTHER_STAT(rx_good_bytes), |
515 | SIENA_DMA_STAT(rx_bad_bytes, RX_BAD_BYTES), |
516 | SIENA_DMA_STAT(rx_packets, RX_PKTS), |
517 | SIENA_DMA_STAT(rx_good, RX_GOOD_PKTS), |
518 | SIENA_DMA_STAT(rx_bad, RX_BAD_FCS_PKTS), |
519 | SIENA_DMA_STAT(rx_pause, RX_PAUSE_PKTS), |
520 | SIENA_DMA_STAT(rx_control, RX_CONTROL_PKTS), |
521 | SIENA_DMA_STAT(rx_unicast, RX_UNICAST_PKTS), |
522 | SIENA_DMA_STAT(rx_multicast, RX_MULTICAST_PKTS), |
523 | SIENA_DMA_STAT(rx_broadcast, RX_BROADCAST_PKTS), |
524 | SIENA_DMA_STAT(rx_lt64, RX_UNDERSIZE_PKTS), |
525 | SIENA_DMA_STAT(rx_64, RX_64_PKTS), |
526 | SIENA_DMA_STAT(rx_65_to_127, RX_65_TO_127_PKTS), |
527 | SIENA_DMA_STAT(rx_128_to_255, RX_128_TO_255_PKTS), |
528 | SIENA_DMA_STAT(rx_256_to_511, RX_256_TO_511_PKTS), |
529 | SIENA_DMA_STAT(rx_512_to_1023, RX_512_TO_1023_PKTS), |
530 | SIENA_DMA_STAT(rx_1024_to_15xx, RX_1024_TO_15XX_PKTS), |
531 | SIENA_DMA_STAT(rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS), |
532 | SIENA_DMA_STAT(rx_gtjumbo, RX_GTJUMBO_PKTS), |
533 | SIENA_DMA_STAT(rx_bad_gtjumbo, RX_JABBER_PKTS), |
534 | SIENA_DMA_STAT(rx_overflow, RX_OVERFLOW_PKTS), |
535 | SIENA_DMA_STAT(rx_false_carrier, RX_FALSE_CARRIER_PKTS), |
536 | SIENA_DMA_STAT(rx_symbol_error, RX_SYMBOL_ERROR_PKTS), |
537 | SIENA_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS), |
538 | SIENA_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS), |
539 | SIENA_DMA_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS), |
540 | SIENA_DMA_STAT(rx_nodesc_drop_cnt, RX_NODESC_DROPS), |
541 | GENERIC_SW_STAT(rx_nodesc_trunc), |
542 | GENERIC_SW_STAT(rx_noskb_drops), |
543 | }; |
544 | static const unsigned long siena_stat_mask[] = { |
545 | [0 ... BITS_TO_LONGS(SIENA_STAT_COUNT) - 1] = ~0UL, |
546 | }; |
547 | |
548 | static size_t siena_describe_nic_stats(struct efx_nic *efx, u8 *names) |
549 | { |
550 | return efx_siena_describe_stats(desc: siena_stat_desc, count: SIENA_STAT_COUNT, |
551 | mask: siena_stat_mask, names); |
552 | } |
553 | |
554 | static int siena_try_update_nic_stats(struct efx_nic *efx) |
555 | { |
556 | struct siena_nic_data *nic_data = efx->nic_data; |
557 | u64 *stats = nic_data->stats; |
558 | __le64 *dma_stats; |
559 | __le64 generation_start, generation_end; |
560 | |
561 | dma_stats = efx->stats_buffer.addr; |
562 | |
563 | generation_end = dma_stats[efx->num_mac_stats - 1]; |
564 | if (generation_end == EFX_MC_STATS_GENERATION_INVALID) |
565 | return 0; |
566 | rmb(); |
567 | efx_siena_update_stats(desc: siena_stat_desc, count: SIENA_STAT_COUNT, mask: siena_stat_mask, |
568 | stats, dma_buf: efx->stats_buffer.addr, accumulate: false); |
569 | rmb(); |
570 | generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; |
571 | if (generation_end != generation_start) |
572 | return -EAGAIN; |
573 | |
574 | /* Update derived statistics */ |
575 | efx_siena_fix_nodesc_drop_stat(efx, |
576 | stat: &stats[SIENA_STAT_rx_nodesc_drop_cnt]); |
577 | efx_update_diff_stat(stat: &stats[SIENA_STAT_tx_good_bytes], |
578 | diff: stats[SIENA_STAT_tx_bytes] - |
579 | stats[SIENA_STAT_tx_bad_bytes]); |
580 | stats[SIENA_STAT_tx_collision] = |
581 | stats[SIENA_STAT_tx_single_collision] + |
582 | stats[SIENA_STAT_tx_multiple_collision] + |
583 | stats[SIENA_STAT_tx_excessive_collision] + |
584 | stats[SIENA_STAT_tx_late_collision]; |
585 | efx_update_diff_stat(stat: &stats[SIENA_STAT_rx_good_bytes], |
586 | diff: stats[SIENA_STAT_rx_bytes] - |
587 | stats[SIENA_STAT_rx_bad_bytes]); |
588 | efx_siena_update_sw_stats(efx, stats); |
589 | return 0; |
590 | } |
591 | |
592 | static size_t siena_update_nic_stats(struct efx_nic *efx, u64 *full_stats, |
593 | struct rtnl_link_stats64 *core_stats) |
594 | { |
595 | struct siena_nic_data *nic_data = efx->nic_data; |
596 | u64 *stats = nic_data->stats; |
597 | int retry; |
598 | |
599 | /* If we're unlucky enough to read statistics wduring the DMA, wait |
600 | * up to 10ms for it to finish (typically takes <500us) */ |
601 | for (retry = 0; retry < 100; ++retry) { |
602 | if (siena_try_update_nic_stats(efx) == 0) |
603 | break; |
604 | udelay(100); |
605 | } |
606 | |
607 | if (full_stats) |
608 | memcpy(full_stats, stats, sizeof(u64) * SIENA_STAT_COUNT); |
609 | |
610 | if (core_stats) { |
611 | core_stats->rx_packets = stats[SIENA_STAT_rx_packets]; |
612 | core_stats->tx_packets = stats[SIENA_STAT_tx_packets]; |
613 | core_stats->rx_bytes = stats[SIENA_STAT_rx_bytes]; |
614 | core_stats->tx_bytes = stats[SIENA_STAT_tx_bytes]; |
615 | core_stats->rx_dropped = stats[SIENA_STAT_rx_nodesc_drop_cnt] + |
616 | stats[GENERIC_STAT_rx_nodesc_trunc] + |
617 | stats[GENERIC_STAT_rx_noskb_drops]; |
618 | core_stats->multicast = stats[SIENA_STAT_rx_multicast]; |
619 | core_stats->collisions = stats[SIENA_STAT_tx_collision]; |
620 | core_stats->rx_length_errors = |
621 | stats[SIENA_STAT_rx_gtjumbo] + |
622 | stats[SIENA_STAT_rx_length_error]; |
623 | core_stats->rx_crc_errors = stats[SIENA_STAT_rx_bad]; |
624 | core_stats->rx_frame_errors = stats[SIENA_STAT_rx_align_error]; |
625 | core_stats->rx_fifo_errors = stats[SIENA_STAT_rx_overflow]; |
626 | core_stats->tx_window_errors = |
627 | stats[SIENA_STAT_tx_late_collision]; |
628 | |
629 | core_stats->rx_errors = (core_stats->rx_length_errors + |
630 | core_stats->rx_crc_errors + |
631 | core_stats->rx_frame_errors + |
632 | stats[SIENA_STAT_rx_symbol_error]); |
633 | core_stats->tx_errors = (core_stats->tx_window_errors + |
634 | stats[SIENA_STAT_tx_bad]); |
635 | } |
636 | |
637 | return SIENA_STAT_COUNT; |
638 | } |
639 | |
640 | static int siena_mac_reconfigure(struct efx_nic *efx, bool mtu_only __always_unused) |
641 | { |
642 | MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MCAST_HASH_IN_LEN); |
643 | int rc; |
644 | |
645 | BUILD_BUG_ON(MC_CMD_SET_MCAST_HASH_IN_LEN != |
646 | MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST + |
647 | sizeof(efx->multicast_hash)); |
648 | |
649 | efx_farch_filter_sync_rx_mode(efx); |
650 | |
651 | WARN_ON(!mutex_is_locked(&efx->mac_lock)); |
652 | |
653 | rc = efx_siena_mcdi_set_mac(efx); |
654 | if (rc != 0) |
655 | return rc; |
656 | |
657 | memcpy(MCDI_PTR(inbuf, SET_MCAST_HASH_IN_HASH0), |
658 | efx->multicast_hash.byte, sizeof(efx->multicast_hash)); |
659 | return efx_siena_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, |
660 | inbuf, inlen: sizeof(inbuf), NULL, outlen: 0, NULL); |
661 | } |
662 | |
663 | /************************************************************************** |
664 | * |
665 | * Wake on LAN |
666 | * |
667 | ************************************************************************** |
668 | */ |
669 | |
670 | static void siena_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol) |
671 | { |
672 | struct siena_nic_data *nic_data = efx->nic_data; |
673 | |
674 | wol->supported = WAKE_MAGIC; |
675 | if (nic_data->wol_filter_id != -1) |
676 | wol->wolopts = WAKE_MAGIC; |
677 | else |
678 | wol->wolopts = 0; |
679 | memset(&wol->sopass, 0, sizeof(wol->sopass)); |
680 | } |
681 | |
682 | |
683 | static int siena_set_wol(struct efx_nic *efx, u32 type) |
684 | { |
685 | struct siena_nic_data *nic_data = efx->nic_data; |
686 | int rc; |
687 | |
688 | if (type & ~WAKE_MAGIC) |
689 | return -EINVAL; |
690 | |
691 | if (type & WAKE_MAGIC) { |
692 | if (nic_data->wol_filter_id != -1) |
693 | efx_siena_mcdi_wol_filter_remove(efx, |
694 | id: nic_data->wol_filter_id); |
695 | rc = efx_siena_mcdi_wol_filter_set_magic(efx, |
696 | mac: efx->net_dev->dev_addr, |
697 | id_out: &nic_data->wol_filter_id); |
698 | if (rc) |
699 | goto fail; |
700 | |
701 | pci_wake_from_d3(dev: efx->pci_dev, enable: true); |
702 | } else { |
703 | rc = efx_siena_mcdi_wol_filter_reset(efx); |
704 | nic_data->wol_filter_id = -1; |
705 | pci_wake_from_d3(dev: efx->pci_dev, enable: false); |
706 | if (rc) |
707 | goto fail; |
708 | } |
709 | |
710 | return 0; |
711 | fail: |
712 | netif_err(efx, hw, efx->net_dev, "%s failed: type=%d rc=%d\n" , |
713 | __func__, type, rc); |
714 | return rc; |
715 | } |
716 | |
717 | |
718 | static void siena_init_wol(struct efx_nic *efx) |
719 | { |
720 | struct siena_nic_data *nic_data = efx->nic_data; |
721 | int rc; |
722 | |
723 | rc = efx_siena_mcdi_wol_filter_get_magic(efx, id_out: &nic_data->wol_filter_id); |
724 | |
725 | if (rc != 0) { |
726 | /* If it failed, attempt to get into a synchronised |
727 | * state with MC by resetting any set WoL filters */ |
728 | efx_siena_mcdi_wol_filter_reset(efx); |
729 | nic_data->wol_filter_id = -1; |
730 | } else if (nic_data->wol_filter_id != -1) { |
731 | pci_wake_from_d3(dev: efx->pci_dev, enable: true); |
732 | } |
733 | } |
734 | |
735 | /************************************************************************** |
736 | * |
737 | * MCDI |
738 | * |
739 | ************************************************************************** |
740 | */ |
741 | |
742 | #define MCDI_PDU(efx) \ |
743 | (efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST) |
744 | #define MCDI_DOORBELL(efx) \ |
745 | (efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST) |
746 | #define MCDI_STATUS(efx) \ |
747 | (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST) |
748 | |
749 | static void siena_mcdi_request(struct efx_nic *efx, |
750 | const efx_dword_t *hdr, size_t hdr_len, |
751 | const efx_dword_t *sdu, size_t sdu_len) |
752 | { |
753 | unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); |
754 | unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx); |
755 | unsigned int i; |
756 | unsigned int inlen_dw = DIV_ROUND_UP(sdu_len, 4); |
757 | |
758 | EFX_WARN_ON_PARANOID(hdr_len != 4); |
759 | |
760 | efx_writed(efx, value: hdr, reg: pdu); |
761 | |
762 | for (i = 0; i < inlen_dw; i++) |
763 | efx_writed(efx, value: &sdu[i], reg: pdu + hdr_len + 4 * i); |
764 | |
765 | /* Ensure the request is written out before the doorbell */ |
766 | wmb(); |
767 | |
768 | /* ring the doorbell with a distinctive value */ |
769 | _efx_writed(efx, value: (__force __le32) 0x45789abc, reg: doorbell); |
770 | } |
771 | |
772 | static bool siena_mcdi_poll_response(struct efx_nic *efx) |
773 | { |
774 | unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); |
775 | efx_dword_t hdr; |
776 | |
777 | efx_readd(efx, value: &hdr, reg: pdu); |
778 | |
779 | /* All 1's indicates that shared memory is in reset (and is |
780 | * not a valid hdr). Wait for it to come out reset before |
781 | * completing the command |
782 | */ |
783 | return EFX_DWORD_FIELD(hdr, EFX_DWORD_0) != 0xffffffff && |
784 | EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE); |
785 | } |
786 | |
787 | static void siena_mcdi_read_response(struct efx_nic *efx, efx_dword_t *outbuf, |
788 | size_t offset, size_t outlen) |
789 | { |
790 | unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); |
791 | unsigned int outlen_dw = DIV_ROUND_UP(outlen, 4); |
792 | int i; |
793 | |
794 | for (i = 0; i < outlen_dw; i++) |
795 | efx_readd(efx, value: &outbuf[i], reg: pdu + offset + 4 * i); |
796 | } |
797 | |
798 | static int siena_mcdi_poll_reboot(struct efx_nic *efx) |
799 | { |
800 | struct siena_nic_data *nic_data = efx->nic_data; |
801 | unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx); |
802 | efx_dword_t reg; |
803 | u32 value; |
804 | |
805 | efx_readd(efx, value: ®, reg: addr); |
806 | value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); |
807 | |
808 | if (value == 0) |
809 | return 0; |
810 | |
811 | EFX_ZERO_DWORD(reg); |
812 | efx_writed(efx, value: ®, reg: addr); |
813 | |
814 | /* MAC statistics have been cleared on the NIC; clear the local |
815 | * copies that we update with efx_update_diff_stat(). |
816 | */ |
817 | nic_data->stats[SIENA_STAT_tx_good_bytes] = 0; |
818 | nic_data->stats[SIENA_STAT_rx_good_bytes] = 0; |
819 | |
820 | if (value == MC_STATUS_DWORD_ASSERT) |
821 | return -EINTR; |
822 | else |
823 | return -EIO; |
824 | } |
825 | |
826 | /************************************************************************** |
827 | * |
828 | * MTD |
829 | * |
830 | ************************************************************************** |
831 | */ |
832 | |
833 | #ifdef CONFIG_SFC_SIENA_MTD |
834 | |
835 | struct siena_nvram_type_info { |
836 | int port; |
837 | const char *name; |
838 | }; |
839 | |
840 | static const struct siena_nvram_type_info siena_nvram_types[] = { |
841 | [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO] = { 0, "sfc_dummy_phy" }, |
842 | [MC_CMD_NVRAM_TYPE_MC_FW] = { 0, "sfc_mcfw" }, |
843 | [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP] = { 0, "sfc_mcfw_backup" }, |
844 | [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0] = { 0, "sfc_static_cfg" }, |
845 | [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1] = { 1, "sfc_static_cfg" }, |
846 | [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0] = { 0, "sfc_dynamic_cfg" }, |
847 | [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1] = { 1, "sfc_dynamic_cfg" }, |
848 | [MC_CMD_NVRAM_TYPE_EXP_ROM] = { 0, "sfc_exp_rom" }, |
849 | [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0] = { 0, "sfc_exp_rom_cfg" }, |
850 | [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1] = { 1, "sfc_exp_rom_cfg" }, |
851 | [MC_CMD_NVRAM_TYPE_PHY_PORT0] = { 0, "sfc_phy_fw" }, |
852 | [MC_CMD_NVRAM_TYPE_PHY_PORT1] = { 1, "sfc_phy_fw" }, |
853 | [MC_CMD_NVRAM_TYPE_FPGA] = { 0, "sfc_fpga" }, |
854 | }; |
855 | |
856 | static int siena_mtd_probe_partition(struct efx_nic *efx, |
857 | struct efx_mcdi_mtd_partition *part, |
858 | unsigned int type) |
859 | { |
860 | const struct siena_nvram_type_info *info; |
861 | size_t size, erase_size; |
862 | bool protected; |
863 | int rc; |
864 | |
865 | if (type >= ARRAY_SIZE(siena_nvram_types) || |
866 | siena_nvram_types[type].name == NULL) |
867 | return -ENODEV; |
868 | |
869 | info = &siena_nvram_types[type]; |
870 | |
871 | if (info->port != efx_port_num(efx)) |
872 | return -ENODEV; |
873 | |
874 | rc = efx_siena_mcdi_nvram_info(efx, type, size_out: &size, erase_size_out: &erase_size, |
875 | protected_out: &protected); |
876 | if (rc) |
877 | return rc; |
878 | if (protected) |
879 | return -ENODEV; /* hide it */ |
880 | |
881 | part->nvram_type = type; |
882 | part->common.dev_type_name = "Siena NVRAM manager" ; |
883 | part->common.type_name = info->name; |
884 | |
885 | part->common.mtd.type = MTD_NORFLASH; |
886 | part->common.mtd.flags = MTD_CAP_NORFLASH; |
887 | part->common.mtd.size = size; |
888 | part->common.mtd.erasesize = erase_size; |
889 | |
890 | return 0; |
891 | } |
892 | |
893 | static int siena_mtd_get_fw_subtypes(struct efx_nic *efx, |
894 | struct efx_mcdi_mtd_partition *parts, |
895 | size_t n_parts) |
896 | { |
897 | uint16_t fw_subtype_list[ |
898 | MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM]; |
899 | size_t i; |
900 | int rc; |
901 | |
902 | rc = efx_siena_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL); |
903 | if (rc) |
904 | return rc; |
905 | |
906 | for (i = 0; i < n_parts; i++) |
907 | parts[i].fw_subtype = fw_subtype_list[parts[i].nvram_type]; |
908 | |
909 | return 0; |
910 | } |
911 | |
912 | static int siena_mtd_probe(struct efx_nic *efx) |
913 | { |
914 | struct efx_mcdi_mtd_partition *parts; |
915 | u32 nvram_types; |
916 | unsigned int type; |
917 | size_t n_parts; |
918 | int rc; |
919 | |
920 | ASSERT_RTNL(); |
921 | |
922 | rc = efx_siena_mcdi_nvram_types(efx, nvram_types_out: &nvram_types); |
923 | if (rc) |
924 | return rc; |
925 | |
926 | parts = kcalloc(hweight32(nvram_types), size: sizeof(*parts), GFP_KERNEL); |
927 | if (!parts) |
928 | return -ENOMEM; |
929 | |
930 | type = 0; |
931 | n_parts = 0; |
932 | |
933 | while (nvram_types != 0) { |
934 | if (nvram_types & 1) { |
935 | rc = siena_mtd_probe_partition(efx, part: &parts[n_parts], |
936 | type); |
937 | if (rc == 0) |
938 | n_parts++; |
939 | else if (rc != -ENODEV) |
940 | goto fail; |
941 | } |
942 | type++; |
943 | nvram_types >>= 1; |
944 | } |
945 | |
946 | rc = siena_mtd_get_fw_subtypes(efx, parts, n_parts); |
947 | if (rc) |
948 | goto fail; |
949 | |
950 | rc = efx_siena_mtd_add(efx, parts: &parts[0].common, n_parts, sizeof_part: sizeof(*parts)); |
951 | fail: |
952 | if (rc) |
953 | kfree(objp: parts); |
954 | return rc; |
955 | } |
956 | |
957 | #endif /* CONFIG_SFC_SIENA_MTD */ |
958 | |
959 | static unsigned int siena_check_caps(const struct efx_nic *efx, |
960 | u8 flag, u32 offset) |
961 | { |
962 | /* Siena did not support MC_CMD_GET_CAPABILITIES */ |
963 | return 0; |
964 | } |
965 | |
966 | static unsigned int efx_siena_recycle_ring_size(const struct efx_nic *efx) |
967 | { |
968 | /* Maximum link speed is 10G */ |
969 | return EFX_RECYCLE_RING_SIZE_10G; |
970 | } |
971 | |
972 | /************************************************************************** |
973 | * |
974 | * Revision-dependent attributes used by efx.c and nic.c |
975 | * |
976 | ************************************************************************** |
977 | */ |
978 | |
979 | const struct efx_nic_type siena_a0_nic_type = { |
980 | .is_vf = false, |
981 | .mem_bar = siena_mem_bar, |
982 | .mem_map_size = siena_mem_map_size, |
983 | .probe = siena_probe_nic, |
984 | .remove = siena_remove_nic, |
985 | .init = siena_init_nic, |
986 | .dimension_resources = siena_dimension_resources, |
987 | .fini = efx_siena_port_dummy_op_void, |
988 | #ifdef CONFIG_EEH |
989 | .monitor = siena_monitor, |
990 | #else |
991 | .monitor = NULL, |
992 | #endif |
993 | .map_reset_reason = efx_siena_mcdi_map_reset_reason, |
994 | .map_reset_flags = siena_map_reset_flags, |
995 | .reset = efx_siena_mcdi_reset, |
996 | .probe_port = efx_siena_mcdi_port_probe, |
997 | .remove_port = efx_siena_mcdi_port_remove, |
998 | .fini_dmaq = efx_farch_fini_dmaq, |
999 | .prepare_flush = efx_siena_prepare_flush, |
1000 | .finish_flush = siena_finish_flush, |
1001 | .prepare_flr = efx_siena_port_dummy_op_void, |
1002 | .finish_flr = efx_farch_finish_flr, |
1003 | .describe_stats = siena_describe_nic_stats, |
1004 | .update_stats = siena_update_nic_stats, |
1005 | .start_stats = efx_siena_mcdi_mac_start_stats, |
1006 | .pull_stats = efx_siena_mcdi_mac_pull_stats, |
1007 | .stop_stats = efx_siena_mcdi_mac_stop_stats, |
1008 | .push_irq_moderation = siena_push_irq_moderation, |
1009 | .reconfigure_mac = siena_mac_reconfigure, |
1010 | .check_mac_fault = efx_siena_mcdi_mac_check_fault, |
1011 | .reconfigure_port = efx_siena_mcdi_port_reconfigure, |
1012 | .get_wol = siena_get_wol, |
1013 | .set_wol = siena_set_wol, |
1014 | .resume_wol = siena_init_wol, |
1015 | .test_chip = siena_test_chip, |
1016 | .test_nvram = efx_siena_mcdi_nvram_test_all, |
1017 | .mcdi_request = siena_mcdi_request, |
1018 | .mcdi_poll_response = siena_mcdi_poll_response, |
1019 | .mcdi_read_response = siena_mcdi_read_response, |
1020 | .mcdi_poll_reboot = siena_mcdi_poll_reboot, |
1021 | .irq_enable_master = efx_farch_irq_enable_master, |
1022 | .irq_test_generate = efx_farch_irq_test_generate, |
1023 | .irq_disable_non_ev = efx_farch_irq_disable_master, |
1024 | .irq_handle_msi = efx_farch_msi_interrupt, |
1025 | .irq_handle_legacy = efx_farch_legacy_interrupt, |
1026 | .tx_probe = efx_farch_tx_probe, |
1027 | .tx_init = efx_farch_tx_init, |
1028 | .tx_remove = efx_farch_tx_remove, |
1029 | .tx_write = efx_farch_tx_write, |
1030 | .tx_limit_len = efx_farch_tx_limit_len, |
1031 | .tx_enqueue = __efx_siena_enqueue_skb, |
1032 | .rx_push_rss_config = siena_rx_push_rss_config, |
1033 | .rx_pull_rss_config = siena_rx_pull_rss_config, |
1034 | .rx_probe = efx_farch_rx_probe, |
1035 | .rx_init = efx_farch_rx_init, |
1036 | .rx_remove = efx_farch_rx_remove, |
1037 | .rx_write = efx_farch_rx_write, |
1038 | .rx_defer_refill = efx_farch_rx_defer_refill, |
1039 | .rx_packet = __efx_siena_rx_packet, |
1040 | .ev_probe = efx_farch_ev_probe, |
1041 | .ev_init = efx_farch_ev_init, |
1042 | .ev_fini = efx_farch_ev_fini, |
1043 | .ev_remove = efx_farch_ev_remove, |
1044 | .ev_process = efx_farch_ev_process, |
1045 | .ev_read_ack = efx_farch_ev_read_ack, |
1046 | .ev_test_generate = efx_farch_ev_test_generate, |
1047 | .filter_table_probe = efx_farch_filter_table_probe, |
1048 | .filter_table_restore = efx_farch_filter_table_restore, |
1049 | .filter_table_remove = efx_farch_filter_table_remove, |
1050 | .filter_update_rx_scatter = efx_farch_filter_update_rx_scatter, |
1051 | .filter_insert = efx_farch_filter_insert, |
1052 | .filter_remove_safe = efx_farch_filter_remove_safe, |
1053 | .filter_get_safe = efx_farch_filter_get_safe, |
1054 | .filter_clear_rx = efx_farch_filter_clear_rx, |
1055 | .filter_count_rx_used = efx_farch_filter_count_rx_used, |
1056 | .filter_get_rx_id_limit = efx_farch_filter_get_rx_id_limit, |
1057 | .filter_get_rx_ids = efx_farch_filter_get_rx_ids, |
1058 | #ifdef CONFIG_RFS_ACCEL |
1059 | .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one, |
1060 | #endif |
1061 | #ifdef CONFIG_SFC_SIENA_MTD |
1062 | .mtd_probe = siena_mtd_probe, |
1063 | .mtd_rename = efx_siena_mcdi_mtd_rename, |
1064 | .mtd_read = efx_siena_mcdi_mtd_read, |
1065 | .mtd_erase = efx_siena_mcdi_mtd_erase, |
1066 | .mtd_write = efx_siena_mcdi_mtd_write, |
1067 | .mtd_sync = efx_siena_mcdi_mtd_sync, |
1068 | #endif |
1069 | .ptp_write_host_time = siena_ptp_write_host_time, |
1070 | .ptp_set_ts_config = siena_ptp_set_ts_config, |
1071 | #ifdef CONFIG_SFC_SIENA_SRIOV |
1072 | .sriov_configure = efx_siena_sriov_configure, |
1073 | .sriov_init = efx_siena_sriov_init, |
1074 | .sriov_fini = efx_siena_sriov_fini, |
1075 | .sriov_wanted = efx_siena_sriov_wanted, |
1076 | .sriov_reset = efx_siena_sriov_reset, |
1077 | .sriov_flr = efx_siena_sriov_flr, |
1078 | .sriov_set_vf_mac = efx_siena_sriov_set_vf_mac, |
1079 | .sriov_set_vf_vlan = efx_siena_sriov_set_vf_vlan, |
1080 | .sriov_set_vf_spoofchk = efx_siena_sriov_set_vf_spoofchk, |
1081 | .sriov_get_vf_config = efx_siena_sriov_get_vf_config, |
1082 | .vswitching_probe = efx_siena_port_dummy_op_int, |
1083 | .vswitching_restore = efx_siena_port_dummy_op_int, |
1084 | .vswitching_remove = efx_siena_port_dummy_op_void, |
1085 | .set_mac_address = efx_siena_sriov_mac_address_changed, |
1086 | #endif |
1087 | |
1088 | .revision = EFX_REV_SIENA_A0, |
1089 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, |
1090 | .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, |
1091 | .buf_tbl_base = FR_BZ_BUF_FULL_TBL, |
1092 | .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, |
1093 | .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, |
1094 | .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), |
1095 | .rx_prefix_size = FS_BZ_RX_PREFIX_SIZE, |
1096 | .rx_hash_offset = FS_BZ_RX_PREFIX_HASH_OFST, |
1097 | .rx_buffer_padding = 0, |
1098 | .can_rx_scatter = true, |
1099 | .option_descriptors = false, |
1100 | .min_interrupt_mode = EFX_INT_MODE_LEGACY, |
1101 | .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, |
1102 | .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
1103 | NETIF_F_RXHASH | NETIF_F_NTUPLE), |
1104 | .mcdi_max_ver = 1, |
1105 | .max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS, |
1106 | .hwtstamp_filters = (1 << HWTSTAMP_FILTER_NONE | |
1107 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT | |
1108 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT), |
1109 | .rx_hash_key_size = 16, |
1110 | .check_caps = siena_check_caps, |
1111 | .sensor_event = efx_siena_mcdi_sensor_event, |
1112 | .rx_recycle_ring_size = efx_siena_recycle_ring_size, |
1113 | }; |
1114 | |