blob: 6deef607a914606bf781ebde2e0c89e18162a236 [file] [log] [blame]
Ben Hutchings8127d662013-08-29 19:19:29 +01001/****************************************************************************
2 * Driver for Solarflare network controllers and boards
3 * Copyright 2012-2013 Solarflare Communications Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation, incorporated herein by reference.
8 */
9
10#include "net_driver.h"
11#include "ef10_regs.h"
12#include "io.h"
13#include "mcdi.h"
14#include "mcdi_pcol.h"
15#include "nic.h"
16#include "workarounds.h"
Jon Cooper74cd60a2013-09-16 14:18:51 +010017#include "selftest.h"
Shradha Shah7fa8d542015-05-06 00:55:13 +010018#include "ef10_sriov.h"
Ben Hutchings8127d662013-08-29 19:19:29 +010019#include <linux/in.h>
20#include <linux/jhash.h>
21#include <linux/wait.h>
22#include <linux/workqueue.h>
23
24/* Hardware control for EF10 architecture including 'Huntington'. */
25
26#define EFX_EF10_DRVGEN_EV 7
27enum {
28 EFX_EF10_TEST = 1,
29 EFX_EF10_REFILL,
30};
31
32/* The reserved RSS context value */
33#define EFX_EF10_RSS_CONTEXT_INVALID 0xffffffff
Jon Cooper267c0152015-05-06 00:59:38 +010034/* The maximum size of a shared RSS context */
35/* TODO: this should really be from the mcdi protocol export */
36#define EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE 64UL
Ben Hutchings8127d662013-08-29 19:19:29 +010037
38/* The filter table(s) are managed by firmware and we have write-only
39 * access. When removing filters we must identify them to the
40 * firmware by a 64-bit handle, but this is too wide for Linux kernel
41 * interfaces (32-bit for RX NFC, 16-bit for RFS). Also, we need to
42 * be able to tell in advance whether a requested insertion will
43 * replace an existing filter. Therefore we maintain a software hash
44 * table, which should be at least as large as the hardware hash
45 * table.
46 *
47 * Huntington has a single 8K filter table shared between all filter
48 * types and both ports.
49 */
50#define HUNT_FILTER_TBL_ROWS 8192
51
Edward Cree12fb0da2015-07-21 15:11:00 +010052#define EFX_EF10_FILTER_ID_INVALID 0xffff
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +010053
54#define EFX_EF10_FILTER_DEV_UC_MAX 32
55#define EFX_EF10_FILTER_DEV_MC_MAX 256
56
Andrew Rybchenko34813fe2016-06-15 17:48:14 +010057/* VLAN list entry */
58struct efx_ef10_vlan {
59 struct list_head list;
60 u16 vid;
61};
62
Edward Cree9b410802017-01-27 15:02:52 +000063enum efx_ef10_default_filters {
64 EFX_EF10_BCAST,
65 EFX_EF10_UCDEF,
66 EFX_EF10_MCDEF,
67 EFX_EF10_VXLAN4_UCDEF,
68 EFX_EF10_VXLAN4_MCDEF,
69 EFX_EF10_VXLAN6_UCDEF,
70 EFX_EF10_VXLAN6_MCDEF,
71 EFX_EF10_NVGRE4_UCDEF,
72 EFX_EF10_NVGRE4_MCDEF,
73 EFX_EF10_NVGRE6_UCDEF,
74 EFX_EF10_NVGRE6_MCDEF,
75 EFX_EF10_GENEVE4_UCDEF,
76 EFX_EF10_GENEVE4_MCDEF,
77 EFX_EF10_GENEVE6_UCDEF,
78 EFX_EF10_GENEVE6_MCDEF,
79
80 EFX_EF10_NUM_DEFAULT_FILTERS
81};
82
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +010083/* Per-VLAN filters information */
84struct efx_ef10_filter_vlan {
Andrew Rybchenko34813fe2016-06-15 17:48:14 +010085 struct list_head list;
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +010086 u16 vid;
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +010087 u16 uc[EFX_EF10_FILTER_DEV_UC_MAX];
88 u16 mc[EFX_EF10_FILTER_DEV_MC_MAX];
Edward Cree9b410802017-01-27 15:02:52 +000089 u16 default_filters[EFX_EF10_NUM_DEFAULT_FILTERS];
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +010090};
91
Daniel Pieczko822b96f2015-07-21 15:10:27 +010092struct efx_ef10_dev_addr {
93 u8 addr[ETH_ALEN];
Daniel Pieczko822b96f2015-07-21 15:10:27 +010094};
95
Ben Hutchings8127d662013-08-29 19:19:29 +010096struct efx_ef10_filter_table {
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +010097/* The MCDI match masks supported by this fw & hw, in order of priority */
98 u32 rx_match_mcdi_flags[
Edward Cree9b410802017-01-27 15:02:52 +000099 MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM * 2];
Ben Hutchings8127d662013-08-29 19:19:29 +0100100 unsigned int rx_match_count;
101
102 struct {
103 unsigned long spec; /* pointer to spec plus flag bits */
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +0000104/* BUSY flag indicates that an update is in progress. AUTO_OLD is
105 * used to mark and sweep MAC filters for the device address lists.
Ben Hutchings8127d662013-08-29 19:19:29 +0100106 */
107#define EFX_EF10_FILTER_FLAG_BUSY 1UL
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +0000108#define EFX_EF10_FILTER_FLAG_AUTO_OLD 2UL
Ben Hutchings8127d662013-08-29 19:19:29 +0100109#define EFX_EF10_FILTER_FLAGS 3UL
110 u64 handle; /* firmware handle */
111 } *entry;
112 wait_queue_head_t waitq;
113/* Shadow of net_device address lists, guarded by mac_lock */
Daniel Pieczko822b96f2015-07-21 15:10:27 +0100114 struct efx_ef10_dev_addr dev_uc_list[EFX_EF10_FILTER_DEV_UC_MAX];
115 struct efx_ef10_dev_addr dev_mc_list[EFX_EF10_FILTER_DEV_MC_MAX];
Edward Cree12fb0da2015-07-21 15:11:00 +0100116 int dev_uc_count;
117 int dev_mc_count;
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +0100118 bool uc_promisc;
119 bool mc_promisc;
Andrew Rybchenkob071c3a2016-06-15 17:43:00 +0100120/* Whether in multicast promiscuous mode when last changed */
121 bool mc_promisc_last;
Edward Cree148cbab2017-04-04 17:02:49 +0100122 bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100123 bool vlan_filter;
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100124 struct list_head vlan_list;
Ben Hutchings8127d662013-08-29 19:19:29 +0100125};
126
127/* An arbitrary search limit for the software hash table */
128#define EFX_EF10_FILTER_SEARCH_LIMIT 200
129
Ben Hutchings8127d662013-08-29 19:19:29 +0100130static void efx_ef10_rx_free_indir_table(struct efx_nic *efx);
131static void efx_ef10_filter_table_remove(struct efx_nic *efx);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100132static int efx_ef10_filter_add_vlan(struct efx_nic *efx, u16 vid);
133static void efx_ef10_filter_del_vlan_internal(struct efx_nic *efx,
134 struct efx_ef10_filter_vlan *vlan);
135static void efx_ef10_filter_del_vlan(struct efx_nic *efx, u16 vid);
Jon Coopere5fbd972017-02-08 16:52:10 +0000136static int efx_ef10_set_udp_tnl_ports(struct efx_nic *efx, bool unloading);
Ben Hutchings8127d662013-08-29 19:19:29 +0100137
Jon Cooper0ccb9982017-02-17 15:49:13 +0000138static u32 efx_ef10_filter_get_unsafe_id(u32 filter_id)
139{
140 WARN_ON_ONCE(filter_id == EFX_EF10_FILTER_ID_INVALID);
141 return filter_id & (HUNT_FILTER_TBL_ROWS - 1);
142}
143
144static unsigned int efx_ef10_filter_get_unsafe_pri(u32 filter_id)
145{
146 return filter_id / (HUNT_FILTER_TBL_ROWS * 2);
147}
148
149static u32 efx_ef10_make_filter_id(unsigned int pri, u16 idx)
150{
151 return pri * HUNT_FILTER_TBL_ROWS * 2 + idx;
152}
153
Ben Hutchings8127d662013-08-29 19:19:29 +0100154static int efx_ef10_get_warm_boot_count(struct efx_nic *efx)
155{
156 efx_dword_t reg;
157
158 efx_readd(efx, &reg, ER_DZ_BIU_MC_SFT_STATUS);
159 return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ?
160 EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO;
161}
162
Edward Cree03714bb2017-12-18 16:55:50 +0000163/* On all EF10s up to and including SFC9220 (Medford1), all PFs use BAR 0 for
164 * I/O space and BAR 2(&3) for memory. On SFC9250 (Medford2), there is no I/O
165 * bar; PFs use BAR 0/1 for memory.
166 */
167static unsigned int efx_ef10_pf_mem_bar(struct efx_nic *efx)
168{
169 switch (efx->pci_dev->device) {
170 case 0x0b03: /* SFC9250 PF */
171 return 0;
172 default:
173 return 2;
174 }
175}
176
177/* All VFs use BAR 0/1 for memory */
178static unsigned int efx_ef10_vf_mem_bar(struct efx_nic *efx)
179{
180 return 0;
181}
182
Ben Hutchings8127d662013-08-29 19:19:29 +0100183static unsigned int efx_ef10_mem_map_size(struct efx_nic *efx)
184{
Shradha Shah02246a72015-05-06 00:58:14 +0100185 int bar;
186
Edward Cree03714bb2017-12-18 16:55:50 +0000187 bar = efx->type->mem_bar(efx);
Shradha Shah02246a72015-05-06 00:58:14 +0100188 return resource_size(&efx->pci_dev->resource[bar]);
Ben Hutchings8127d662013-08-29 19:19:29 +0100189}
190
Daniel Pieczko7a186f42015-07-07 11:37:19 +0100191static bool efx_ef10_is_vf(struct efx_nic *efx)
192{
193 return efx->type->is_vf;
194}
195
Daniel Pieczko1cd9ecb2015-05-06 00:57:53 +0100196static int efx_ef10_get_pf_index(struct efx_nic *efx)
197{
198 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_FUNCTION_INFO_OUT_LEN);
199 struct efx_ef10_nic_data *nic_data = efx->nic_data;
200 size_t outlen;
201 int rc;
202
203 rc = efx_mcdi_rpc(efx, MC_CMD_GET_FUNCTION_INFO, NULL, 0, outbuf,
204 sizeof(outbuf), &outlen);
205 if (rc)
206 return rc;
207 if (outlen < sizeof(outbuf))
208 return -EIO;
209
210 nic_data->pf_index = MCDI_DWORD(outbuf, GET_FUNCTION_INFO_OUT_PF);
211 return 0;
212}
213
Shradha Shah88a37de2015-05-20 11:09:15 +0100214#ifdef CONFIG_SFC_SRIOV
215static int efx_ef10_get_vf_index(struct efx_nic *efx)
216{
217 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_FUNCTION_INFO_OUT_LEN);
218 struct efx_ef10_nic_data *nic_data = efx->nic_data;
219 size_t outlen;
220 int rc;
221
222 rc = efx_mcdi_rpc(efx, MC_CMD_GET_FUNCTION_INFO, NULL, 0, outbuf,
223 sizeof(outbuf), &outlen);
224 if (rc)
225 return rc;
226 if (outlen < sizeof(outbuf))
227 return -EIO;
228
229 nic_data->vf_index = MCDI_DWORD(outbuf, GET_FUNCTION_INFO_OUT_VF);
230 return 0;
231}
232#endif
233
Ben Hutchingse5a25382013-09-05 22:50:59 +0100234static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
Ben Hutchings8127d662013-08-29 19:19:29 +0100235{
Edward Creec1be4822017-12-21 09:00:26 +0000236 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +0100237 struct efx_ef10_nic_data *nic_data = efx->nic_data;
238 size_t outlen;
239 int rc;
240
241 BUILD_BUG_ON(MC_CMD_GET_CAPABILITIES_IN_LEN != 0);
242
243 rc = efx_mcdi_rpc(efx, MC_CMD_GET_CAPABILITIES, NULL, 0,
244 outbuf, sizeof(outbuf), &outlen);
245 if (rc)
246 return rc;
Bert Kenwardca889a02016-08-11 13:01:35 +0100247 if (outlen < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
Ben Hutchingse5a25382013-09-05 22:50:59 +0100248 netif_err(efx, drv, efx->net_dev,
249 "unable to read datapath firmware capabilities\n");
250 return -EIO;
251 }
Ben Hutchings8127d662013-08-29 19:19:29 +0100252
Ben Hutchingse5a25382013-09-05 22:50:59 +0100253 nic_data->datapath_caps =
254 MCDI_DWORD(outbuf, GET_CAPABILITIES_OUT_FLAGS1);
255
Edward Creec6347002017-01-13 21:20:29 +0000256 if (outlen >= MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) {
Bert Kenwardca889a02016-08-11 13:01:35 +0100257 nic_data->datapath_caps2 = MCDI_DWORD(outbuf,
258 GET_CAPABILITIES_V2_OUT_FLAGS2);
Edward Creec6347002017-01-13 21:20:29 +0000259 nic_data->piobuf_size = MCDI_WORD(outbuf,
260 GET_CAPABILITIES_V2_OUT_SIZE_PIO_BUFF);
261 } else {
Bert Kenwardca889a02016-08-11 13:01:35 +0100262 nic_data->datapath_caps2 = 0;
Edward Creec6347002017-01-13 21:20:29 +0000263 nic_data->piobuf_size = ER_DZ_TX_PIOBUF_SIZE;
264 }
Bert Kenwardca889a02016-08-11 13:01:35 +0100265
Daniel Pieczko8d9f9dd2015-05-06 00:56:55 +0100266 /* record the DPCPU firmware IDs to determine VEB vswitching support.
267 */
268 nic_data->rx_dpcpu_fw_id =
269 MCDI_WORD(outbuf, GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID);
270 nic_data->tx_dpcpu_fw_id =
271 MCDI_WORD(outbuf, GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID);
272
Ben Hutchingse5a25382013-09-05 22:50:59 +0100273 if (!(nic_data->datapath_caps &
Ben Hutchingse5a25382013-09-05 22:50:59 +0100274 (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
275 netif_err(efx, probe, efx->net_dev,
276 "current firmware does not support an RX prefix\n");
277 return -ENODEV;
Ben Hutchings8127d662013-08-29 19:19:29 +0100278 }
279
Edward Cree71827442017-12-18 16:56:19 +0000280 if (outlen >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) {
281 u8 vi_window_mode = MCDI_BYTE(outbuf,
282 GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
283
284 switch (vi_window_mode) {
285 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K:
286 efx->vi_stride = 8192;
287 break;
288 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K:
289 efx->vi_stride = 16384;
290 break;
291 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K:
292 efx->vi_stride = 65536;
293 break;
294 default:
295 netif_err(efx, probe, efx->net_dev,
296 "Unrecognised VI window mode %d\n",
297 vi_window_mode);
298 return -EIO;
299 }
300 netif_dbg(efx, probe, efx->net_dev, "vi_stride = %u\n",
301 efx->vi_stride);
302 } else {
303 /* keep default VI stride */
304 netif_dbg(efx, probe, efx->net_dev,
305 "firmware did not report VI window mode, assuming vi_stride = %u\n",
306 efx->vi_stride);
307 }
308
Edward Creec1be4822017-12-21 09:00:26 +0000309 if (outlen >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) {
310 efx->num_mac_stats = MCDI_WORD(outbuf,
311 GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
312 netif_dbg(efx, probe, efx->net_dev,
313 "firmware reports num_mac_stats = %u\n",
314 efx->num_mac_stats);
315 } else {
316 /* leave num_mac_stats as the default value, MC_CMD_MAC_NSTATS */
317 netif_dbg(efx, probe, efx->net_dev,
318 "firmware did not report num_mac_stats, assuming %u\n",
319 efx->num_mac_stats);
320 }
321
Ben Hutchings8127d662013-08-29 19:19:29 +0100322 return 0;
323}
324
325static int efx_ef10_get_sysclk_freq(struct efx_nic *efx)
326{
327 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CLOCK_OUT_LEN);
328 int rc;
329
330 rc = efx_mcdi_rpc(efx, MC_CMD_GET_CLOCK, NULL, 0,
331 outbuf, sizeof(outbuf), NULL);
332 if (rc)
333 return rc;
334 rc = MCDI_DWORD(outbuf, GET_CLOCK_OUT_SYS_FREQ);
335 return rc > 0 ? rc : -ERANGE;
336}
337
Bert Kenwardd95e3292016-08-11 13:02:36 +0100338static int efx_ef10_get_timer_workarounds(struct efx_nic *efx)
339{
340 struct efx_ef10_nic_data *nic_data = efx->nic_data;
341 unsigned int implemented;
342 unsigned int enabled;
343 int rc;
344
345 nic_data->workaround_35388 = false;
346 nic_data->workaround_61265 = false;
347
348 rc = efx_mcdi_get_workarounds(efx, &implemented, &enabled);
349
350 if (rc == -ENOSYS) {
351 /* Firmware without GET_WORKAROUNDS - not a problem. */
352 rc = 0;
353 } else if (rc == 0) {
354 /* Bug61265 workaround is always enabled if implemented. */
355 if (enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG61265)
356 nic_data->workaround_61265 = true;
357
358 if (enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388) {
359 nic_data->workaround_35388 = true;
360 } else if (implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG35388) {
361 /* Workaround is implemented but not enabled.
362 * Try to enable it.
363 */
364 rc = efx_mcdi_set_workaround(efx,
365 MC_CMD_WORKAROUND_BUG35388,
366 true, NULL);
367 if (rc == 0)
368 nic_data->workaround_35388 = true;
369 /* If we failed to set the workaround just carry on. */
370 rc = 0;
371 }
372 }
373
374 netif_dbg(efx, probe, efx->net_dev,
375 "workaround for bug 35388 is %sabled\n",
376 nic_data->workaround_35388 ? "en" : "dis");
377 netif_dbg(efx, probe, efx->net_dev,
378 "workaround for bug 61265 is %sabled\n",
379 nic_data->workaround_61265 ? "en" : "dis");
380
381 return rc;
382}
383
384static void efx_ef10_process_timer_config(struct efx_nic *efx,
385 const efx_dword_t *data)
386{
387 unsigned int max_count;
388
389 if (EFX_EF10_WORKAROUND_61265(efx)) {
390 efx->timer_quantum_ns = MCDI_DWORD(data,
391 GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_STEP_NS);
392 efx->timer_max_ns = MCDI_DWORD(data,
393 GET_EVQ_TMR_PROPERTIES_OUT_MCDI_TMR_MAX_NS);
394 } else if (EFX_EF10_WORKAROUND_35388(efx)) {
395 efx->timer_quantum_ns = MCDI_DWORD(data,
396 GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_NS_PER_COUNT);
397 max_count = MCDI_DWORD(data,
398 GET_EVQ_TMR_PROPERTIES_OUT_BUG35388_TMR_MAX_COUNT);
399 efx->timer_max_ns = max_count * efx->timer_quantum_ns;
400 } else {
401 efx->timer_quantum_ns = MCDI_DWORD(data,
402 GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_NS_PER_COUNT);
403 max_count = MCDI_DWORD(data,
404 GET_EVQ_TMR_PROPERTIES_OUT_TMR_REG_MAX_COUNT);
405 efx->timer_max_ns = max_count * efx->timer_quantum_ns;
406 }
407
408 netif_dbg(efx, probe, efx->net_dev,
409 "got timer properties from MC: quantum %u ns; max %u ns\n",
410 efx->timer_quantum_ns, efx->timer_max_ns);
411}
412
413static int efx_ef10_get_timer_config(struct efx_nic *efx)
414{
415 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_LEN);
416 int rc;
417
418 rc = efx_ef10_get_timer_workarounds(efx);
419 if (rc)
420 return rc;
421
422 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_EVQ_TMR_PROPERTIES, NULL, 0,
423 outbuf, sizeof(outbuf), NULL);
424
425 if (rc == 0) {
426 efx_ef10_process_timer_config(efx, outbuf);
427 } else if (rc == -ENOSYS || rc == -EPERM) {
428 /* Not available - fall back to Huntington defaults. */
429 unsigned int quantum;
430
431 rc = efx_ef10_get_sysclk_freq(efx);
432 if (rc < 0)
433 return rc;
434
435 quantum = 1536000 / rc; /* 1536 cycles */
436 efx->timer_quantum_ns = quantum;
437 efx->timer_max_ns = efx->type->timer_period_max * quantum;
438 rc = 0;
439 } else {
440 efx_mcdi_display_error(efx, MC_CMD_GET_EVQ_TMR_PROPERTIES,
441 MC_CMD_GET_EVQ_TMR_PROPERTIES_OUT_LEN,
442 NULL, 0, rc);
443 }
444
445 return rc;
446}
447
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +0100448static int efx_ef10_get_mac_address_pf(struct efx_nic *efx, u8 *mac_address)
Ben Hutchings8127d662013-08-29 19:19:29 +0100449{
450 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
451 size_t outlen;
452 int rc;
453
454 BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0);
455
456 rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0,
457 outbuf, sizeof(outbuf), &outlen);
458 if (rc)
459 return rc;
460 if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
461 return -EIO;
462
Edward Creecd84ff42014-03-07 18:27:41 +0000463 ether_addr_copy(mac_address,
464 MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE));
Ben Hutchings8127d662013-08-29 19:19:29 +0100465 return 0;
466}
467
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +0100468static int efx_ef10_get_mac_address_vf(struct efx_nic *efx, u8 *mac_address)
469{
470 MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN);
471 MCDI_DECLARE_BUF(outbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
472 size_t outlen;
473 int num_addrs, rc;
474
475 MCDI_SET_DWORD(inbuf, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
476 EVB_PORT_ID_ASSIGNED);
477 rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_GET_MAC_ADDRESSES, inbuf,
478 sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
479
480 if (rc)
481 return rc;
482 if (outlen < MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN)
483 return -EIO;
484
485 num_addrs = MCDI_DWORD(outbuf,
486 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT);
487
488 WARN_ON(num_addrs != 1);
489
490 ether_addr_copy(mac_address,
491 MCDI_PTR(outbuf, VPORT_GET_MAC_ADDRESSES_OUT_MACADDR));
492
493 return 0;
494}
495
Shradha Shah0f5c0842015-06-02 11:37:58 +0100496static ssize_t efx_ef10_show_link_control_flag(struct device *dev,
497 struct device_attribute *attr,
498 char *buf)
499{
500 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
501
502 return sprintf(buf, "%d\n",
503 ((efx->mcdi->fn_flags) &
504 (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL))
505 ? 1 : 0);
506}
507
508static ssize_t efx_ef10_show_primary_flag(struct device *dev,
509 struct device_attribute *attr,
510 char *buf)
511{
512 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
513
514 return sprintf(buf, "%d\n",
515 ((efx->mcdi->fn_flags) &
516 (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY))
517 ? 1 : 0);
518}
519
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100520static struct efx_ef10_vlan *efx_ef10_find_vlan(struct efx_nic *efx, u16 vid)
521{
522 struct efx_ef10_nic_data *nic_data = efx->nic_data;
523 struct efx_ef10_vlan *vlan;
524
525 WARN_ON(!mutex_is_locked(&nic_data->vlan_lock));
526
527 list_for_each_entry(vlan, &nic_data->vlan_list, list) {
528 if (vlan->vid == vid)
529 return vlan;
530 }
531
532 return NULL;
533}
534
535static int efx_ef10_add_vlan(struct efx_nic *efx, u16 vid)
536{
537 struct efx_ef10_nic_data *nic_data = efx->nic_data;
538 struct efx_ef10_vlan *vlan;
539 int rc;
540
541 mutex_lock(&nic_data->vlan_lock);
542
543 vlan = efx_ef10_find_vlan(efx, vid);
544 if (vlan) {
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100545 /* We add VID 0 on init. 8021q adds it on module init
546 * for all interfaces with VLAN filtring feature.
547 */
548 if (vid == 0)
549 goto done_unlock;
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100550 netif_warn(efx, drv, efx->net_dev,
551 "VLAN %u already added\n", vid);
552 rc = -EALREADY;
553 goto fail_exist;
554 }
555
556 rc = -ENOMEM;
557 vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
558 if (!vlan)
559 goto fail_alloc;
560
561 vlan->vid = vid;
562
563 list_add_tail(&vlan->list, &nic_data->vlan_list);
564
565 if (efx->filter_state) {
566 mutex_lock(&efx->mac_lock);
567 down_write(&efx->filter_sem);
568 rc = efx_ef10_filter_add_vlan(efx, vlan->vid);
569 up_write(&efx->filter_sem);
570 mutex_unlock(&efx->mac_lock);
571 if (rc)
572 goto fail_filter_add_vlan;
573 }
574
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100575done_unlock:
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100576 mutex_unlock(&nic_data->vlan_lock);
577 return 0;
578
579fail_filter_add_vlan:
580 list_del(&vlan->list);
581 kfree(vlan);
582fail_alloc:
583fail_exist:
584 mutex_unlock(&nic_data->vlan_lock);
585 return rc;
586}
587
588static void efx_ef10_del_vlan_internal(struct efx_nic *efx,
589 struct efx_ef10_vlan *vlan)
590{
591 struct efx_ef10_nic_data *nic_data = efx->nic_data;
592
593 WARN_ON(!mutex_is_locked(&nic_data->vlan_lock));
594
595 if (efx->filter_state) {
596 down_write(&efx->filter_sem);
597 efx_ef10_filter_del_vlan(efx, vlan->vid);
598 up_write(&efx->filter_sem);
599 }
600
601 list_del(&vlan->list);
602 kfree(vlan);
603}
604
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100605static int efx_ef10_del_vlan(struct efx_nic *efx, u16 vid)
606{
607 struct efx_ef10_nic_data *nic_data = efx->nic_data;
608 struct efx_ef10_vlan *vlan;
609 int rc = 0;
610
611 /* 8021q removes VID 0 on module unload for all interfaces
612 * with VLAN filtering feature. We need to keep it to receive
613 * untagged traffic.
614 */
615 if (vid == 0)
616 return 0;
617
618 mutex_lock(&nic_data->vlan_lock);
619
620 vlan = efx_ef10_find_vlan(efx, vid);
621 if (!vlan) {
622 netif_err(efx, drv, efx->net_dev,
623 "VLAN %u to be deleted not found\n", vid);
624 rc = -ENOENT;
625 } else {
626 efx_ef10_del_vlan_internal(efx, vlan);
627 }
628
629 mutex_unlock(&nic_data->vlan_lock);
630
631 return rc;
632}
633
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100634static void efx_ef10_cleanup_vlans(struct efx_nic *efx)
635{
636 struct efx_ef10_nic_data *nic_data = efx->nic_data;
637 struct efx_ef10_vlan *vlan, *next_vlan;
638
639 mutex_lock(&nic_data->vlan_lock);
640 list_for_each_entry_safe(vlan, next_vlan, &nic_data->vlan_list, list)
641 efx_ef10_del_vlan_internal(efx, vlan);
642 mutex_unlock(&nic_data->vlan_lock);
643}
644
Shradha Shah0f5c0842015-06-02 11:37:58 +0100645static DEVICE_ATTR(link_control_flag, 0444, efx_ef10_show_link_control_flag,
646 NULL);
647static DEVICE_ATTR(primary_flag, 0444, efx_ef10_show_primary_flag, NULL);
648
Ben Hutchings8127d662013-08-29 19:19:29 +0100649static int efx_ef10_probe(struct efx_nic *efx)
650{
651 struct efx_ef10_nic_data *nic_data;
652 int i, rc;
653
Ben Hutchings8127d662013-08-29 19:19:29 +0100654 nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
655 if (!nic_data)
656 return -ENOMEM;
657 efx->nic_data = nic_data;
658
Edward Cree75aba2a2015-05-27 13:13:54 +0100659 /* we assume later that we can copy from this buffer in dwords */
660 BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4);
661
Ben Hutchings8127d662013-08-29 19:19:29 +0100662 rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf,
663 8 + MCDI_CTL_SDU_LEN_MAX_V2, GFP_KERNEL);
664 if (rc)
665 goto fail1;
666
667 /* Get the MC's warm boot count. In case it's rebooting right
668 * now, be prepared to retry.
669 */
670 i = 0;
671 for (;;) {
672 rc = efx_ef10_get_warm_boot_count(efx);
673 if (rc >= 0)
674 break;
675 if (++i == 5)
676 goto fail2;
677 ssleep(1);
678 }
679 nic_data->warm_boot_count = rc;
680
681 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
682
Daniel Pieczko45b24492015-05-06 00:57:14 +0100683 nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
684
Ben Hutchings8127d662013-08-29 19:19:29 +0100685 /* In case we're recovering from a crash (kexec), we want to
686 * cancel any outstanding request by the previous user of this
687 * function. We send a special message using the least
688 * significant bits of the 'high' (doorbell) register.
689 */
690 _efx_writed(efx, cpu_to_le32(1), ER_DZ_MC_DB_HWRD);
691
692 rc = efx_mcdi_init(efx);
693 if (rc)
694 goto fail2;
695
Jon Coopere5fbd972017-02-08 16:52:10 +0000696 mutex_init(&nic_data->udp_tunnels_lock);
697
Ben Hutchings8127d662013-08-29 19:19:29 +0100698 /* Reset (most) configuration for this function */
699 rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
700 if (rc)
701 goto fail3;
702
703 /* Enable event logging */
704 rc = efx_mcdi_log_ctrl(efx, true, false, 0);
705 if (rc)
706 goto fail3;
707
Shradha Shah0f5c0842015-06-02 11:37:58 +0100708 rc = device_create_file(&efx->pci_dev->dev,
709 &dev_attr_link_control_flag);
Daniel Pieczko1cd9ecb2015-05-06 00:57:53 +0100710 if (rc)
711 goto fail3;
712
Shradha Shah0f5c0842015-06-02 11:37:58 +0100713 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_primary_flag);
714 if (rc)
715 goto fail4;
716
717 rc = efx_ef10_get_pf_index(efx);
718 if (rc)
719 goto fail5;
720
Ben Hutchingse5a25382013-09-05 22:50:59 +0100721 rc = efx_ef10_init_datapath_caps(efx);
Ben Hutchings8127d662013-08-29 19:19:29 +0100722 if (rc < 0)
Shradha Shah0f5c0842015-06-02 11:37:58 +0100723 goto fail5;
Ben Hutchings8127d662013-08-29 19:19:29 +0100724
Edward Cree71827442017-12-18 16:56:19 +0000725 /* We can have one VI for each vi_stride-byte region.
726 * However, until we use TX option descriptors we need two TX queues
727 * per channel.
728 */
729 efx->max_channels = min_t(unsigned int,
730 EFX_MAX_CHANNELS,
731 efx_ef10_mem_map_size(efx) /
732 (efx->vi_stride * EFX_TXQ_TYPES));
733 efx->max_tx_channels = efx->max_channels;
734 if (WARN_ON(efx->max_channels == 0)) {
735 rc = -EIO;
736 goto fail5;
737 }
738
Ben Hutchings8127d662013-08-29 19:19:29 +0100739 efx->rx_packet_len_offset =
740 ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE;
741
Edward Cree69787292017-10-31 14:29:47 +0000742 if (nic_data->datapath_caps &
743 (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN))
744 efx->net_dev->hw_features |= NETIF_F_RXFCS;
745
Ben Hutchings8127d662013-08-29 19:19:29 +0100746 rc = efx_mcdi_port_get_number(efx);
747 if (rc < 0)
Shradha Shah0f5c0842015-06-02 11:37:58 +0100748 goto fail5;
Ben Hutchings8127d662013-08-29 19:19:29 +0100749 efx->port_num = rc;
750
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +0100751 rc = efx->type->get_mac_address(efx, efx->net_dev->perm_addr);
Ben Hutchings8127d662013-08-29 19:19:29 +0100752 if (rc)
Shradha Shah0f5c0842015-06-02 11:37:58 +0100753 goto fail5;
Ben Hutchings8127d662013-08-29 19:19:29 +0100754
Bert Kenwardd95e3292016-08-11 13:02:36 +0100755 rc = efx_ef10_get_timer_config(efx);
Ben Hutchings8127d662013-08-29 19:19:29 +0100756 if (rc < 0)
Shradha Shah0f5c0842015-06-02 11:37:58 +0100757 goto fail5;
Ben Hutchings8127d662013-08-29 19:19:29 +0100758
Ben Hutchings8127d662013-08-29 19:19:29 +0100759 rc = efx_mcdi_mon_probe(efx);
Edward Cree267d9d72015-05-06 00:59:18 +0100760 if (rc && rc != -EPERM)
Shradha Shah0f5c0842015-06-02 11:37:58 +0100761 goto fail5;
Ben Hutchings8127d662013-08-29 19:19:29 +0100762
Martin Habets23418dc2018-01-25 17:25:15 +0000763 efx_ptp_defer_probe_with_channel(efx);
Ben Hutchings9aecda92013-12-05 21:28:42 +0000764
Shradha Shah1d051e02015-06-02 11:38:16 +0100765#ifdef CONFIG_SFC_SRIOV
766 if ((efx->pci_dev->physfn) && (!efx->pci_dev->is_physfn)) {
767 struct pci_dev *pci_dev_pf = efx->pci_dev->physfn;
768 struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
769
770 efx_pf->type->get_mac_address(efx_pf, nic_data->port_id);
771 } else
772#endif
773 ether_addr_copy(nic_data->port_id, efx->net_dev->perm_addr);
774
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100775 INIT_LIST_HEAD(&nic_data->vlan_list);
776 mutex_init(&nic_data->vlan_lock);
777
778 /* Add unspecified VID to support VLAN filtering being disabled */
779 rc = efx_ef10_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
780 if (rc)
781 goto fail_add_vid_unspec;
782
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100783 /* If VLAN filtering is enabled, we need VID 0 to get untagged
784 * traffic. It is added automatically if 8021q module is loaded,
785 * but we can't rely on it since module may be not loaded.
786 */
787 rc = efx_ef10_add_vlan(efx, 0);
788 if (rc)
789 goto fail_add_vid_0;
790
Ben Hutchings8127d662013-08-29 19:19:29 +0100791 return 0;
792
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +0100793fail_add_vid_0:
794 efx_ef10_cleanup_vlans(efx);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +0100795fail_add_vid_unspec:
796 mutex_destroy(&nic_data->vlan_lock);
797 efx_ptp_remove(efx);
798 efx_mcdi_mon_remove(efx);
Shradha Shah0f5c0842015-06-02 11:37:58 +0100799fail5:
800 device_remove_file(&efx->pci_dev->dev, &dev_attr_primary_flag);
801fail4:
802 device_remove_file(&efx->pci_dev->dev, &dev_attr_link_control_flag);
Ben Hutchings8127d662013-08-29 19:19:29 +0100803fail3:
Jon Coopere5fbd972017-02-08 16:52:10 +0000804 efx_mcdi_detach(efx);
805
806 mutex_lock(&nic_data->udp_tunnels_lock);
807 memset(nic_data->udp_tunnels, 0, sizeof(nic_data->udp_tunnels));
808 (void)efx_ef10_set_udp_tnl_ports(efx, true);
809 mutex_unlock(&nic_data->udp_tunnels_lock);
810 mutex_destroy(&nic_data->udp_tunnels_lock);
811
Ben Hutchings8127d662013-08-29 19:19:29 +0100812 efx_mcdi_fini(efx);
813fail2:
814 efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
815fail1:
816 kfree(nic_data);
817 efx->nic_data = NULL;
818 return rc;
819}
820
821static int efx_ef10_free_vis(struct efx_nic *efx)
822{
Jon Cooperaa09a3d2015-05-20 11:10:41 +0100823 MCDI_DECLARE_BUF_ERR(outbuf);
Edward Cree1e0b8122013-05-31 18:36:12 +0100824 size_t outlen;
825 int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0,
826 outbuf, sizeof(outbuf), &outlen);
Ben Hutchings8127d662013-08-29 19:19:29 +0100827
828 /* -EALREADY means nothing to free, so ignore */
829 if (rc == -EALREADY)
830 rc = 0;
Edward Cree1e0b8122013-05-31 18:36:12 +0100831 if (rc)
832 efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen,
833 rc);
Ben Hutchings8127d662013-08-29 19:19:29 +0100834 return rc;
835}
836
Ben Hutchings183233b2013-06-28 21:47:12 +0100837#ifdef EFX_USE_PIO
838
839static void efx_ef10_free_piobufs(struct efx_nic *efx)
840{
841 struct efx_ef10_nic_data *nic_data = efx->nic_data;
842 MCDI_DECLARE_BUF(inbuf, MC_CMD_FREE_PIOBUF_IN_LEN);
843 unsigned int i;
844 int rc;
845
846 BUILD_BUG_ON(MC_CMD_FREE_PIOBUF_OUT_LEN != 0);
847
848 for (i = 0; i < nic_data->n_piobufs; i++) {
849 MCDI_SET_DWORD(inbuf, FREE_PIOBUF_IN_PIOBUF_HANDLE,
850 nic_data->piobuf_handle[i]);
851 rc = efx_mcdi_rpc(efx, MC_CMD_FREE_PIOBUF, inbuf, sizeof(inbuf),
852 NULL, 0, NULL);
853 WARN_ON(rc);
854 }
855
856 nic_data->n_piobufs = 0;
857}
858
859static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
860{
861 struct efx_ef10_nic_data *nic_data = efx->nic_data;
862 MCDI_DECLARE_BUF(outbuf, MC_CMD_ALLOC_PIOBUF_OUT_LEN);
863 unsigned int i;
864 size_t outlen;
865 int rc = 0;
866
867 BUILD_BUG_ON(MC_CMD_ALLOC_PIOBUF_IN_LEN != 0);
868
869 for (i = 0; i < n; i++) {
Bert Kenward09a04202015-12-23 08:58:15 +0000870 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_ALLOC_PIOBUF, NULL, 0,
871 outbuf, sizeof(outbuf), &outlen);
872 if (rc) {
873 /* Don't display the MC error if we didn't have space
874 * for a VF.
875 */
876 if (!(efx_ef10_is_vf(efx) && rc == -ENOSPC))
877 efx_mcdi_display_error(efx, MC_CMD_ALLOC_PIOBUF,
878 0, outbuf, outlen, rc);
Ben Hutchings183233b2013-06-28 21:47:12 +0100879 break;
Bert Kenward09a04202015-12-23 08:58:15 +0000880 }
Ben Hutchings183233b2013-06-28 21:47:12 +0100881 if (outlen < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
882 rc = -EIO;
883 break;
884 }
885 nic_data->piobuf_handle[i] =
886 MCDI_DWORD(outbuf, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
887 netif_dbg(efx, probe, efx->net_dev,
888 "allocated PIO buffer %u handle %x\n", i,
889 nic_data->piobuf_handle[i]);
890 }
891
892 nic_data->n_piobufs = i;
893 if (rc)
894 efx_ef10_free_piobufs(efx);
895 return rc;
896}
897
898static int efx_ef10_link_piobufs(struct efx_nic *efx)
899{
900 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Edward Creed0346b02017-03-03 15:22:09 +0000901 MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_PIOBUF_IN_LEN);
Ben Hutchings183233b2013-06-28 21:47:12 +0100902 struct efx_channel *channel;
903 struct efx_tx_queue *tx_queue;
904 unsigned int offset, index;
905 int rc;
906
907 BUILD_BUG_ON(MC_CMD_LINK_PIOBUF_OUT_LEN != 0);
908 BUILD_BUG_ON(MC_CMD_UNLINK_PIOBUF_OUT_LEN != 0);
909
910 /* Link a buffer to each VI in the write-combining mapping */
911 for (index = 0; index < nic_data->n_piobufs; ++index) {
912 MCDI_SET_DWORD(inbuf, LINK_PIOBUF_IN_PIOBUF_HANDLE,
913 nic_data->piobuf_handle[index]);
914 MCDI_SET_DWORD(inbuf, LINK_PIOBUF_IN_TXQ_INSTANCE,
915 nic_data->pio_write_vi_base + index);
916 rc = efx_mcdi_rpc(efx, MC_CMD_LINK_PIOBUF,
917 inbuf, MC_CMD_LINK_PIOBUF_IN_LEN,
918 NULL, 0, NULL);
919 if (rc) {
920 netif_err(efx, drv, efx->net_dev,
921 "failed to link VI %u to PIO buffer %u (%d)\n",
922 nic_data->pio_write_vi_base + index, index,
923 rc);
924 goto fail;
925 }
926 netif_dbg(efx, probe, efx->net_dev,
927 "linked VI %u to PIO buffer %u\n",
928 nic_data->pio_write_vi_base + index, index);
929 }
930
931 /* Link a buffer to each TX queue */
932 efx_for_each_channel(channel, efx) {
933 efx_for_each_channel_tx_queue(tx_queue, channel) {
934 /* We assign the PIO buffers to queues in
935 * reverse order to allow for the following
936 * special case.
937 */
938 offset = ((efx->tx_channel_offset + efx->n_tx_channels -
939 tx_queue->channel->channel - 1) *
940 efx_piobuf_size);
Edward Creec6347002017-01-13 21:20:29 +0000941 index = offset / nic_data->piobuf_size;
942 offset = offset % nic_data->piobuf_size;
Ben Hutchings183233b2013-06-28 21:47:12 +0100943
944 /* When the host page size is 4K, the first
945 * host page in the WC mapping may be within
946 * the same VI page as the last TX queue. We
947 * can only link one buffer to each VI.
948 */
949 if (tx_queue->queue == nic_data->pio_write_vi_base) {
950 BUG_ON(index != 0);
951 rc = 0;
952 } else {
953 MCDI_SET_DWORD(inbuf,
954 LINK_PIOBUF_IN_PIOBUF_HANDLE,
955 nic_data->piobuf_handle[index]);
956 MCDI_SET_DWORD(inbuf,
957 LINK_PIOBUF_IN_TXQ_INSTANCE,
958 tx_queue->queue);
959 rc = efx_mcdi_rpc(efx, MC_CMD_LINK_PIOBUF,
960 inbuf, MC_CMD_LINK_PIOBUF_IN_LEN,
961 NULL, 0, NULL);
962 }
963
964 if (rc) {
965 /* This is non-fatal; the TX path just
966 * won't use PIO for this queue
967 */
968 netif_err(efx, drv, efx->net_dev,
969 "failed to link VI %u to PIO buffer %u (%d)\n",
970 tx_queue->queue, index, rc);
971 tx_queue->piobuf = NULL;
972 } else {
973 tx_queue->piobuf =
974 nic_data->pio_write_base +
Edward Cree71827442017-12-18 16:56:19 +0000975 index * efx->vi_stride + offset;
Ben Hutchings183233b2013-06-28 21:47:12 +0100976 tx_queue->piobuf_offset = offset;
977 netif_dbg(efx, probe, efx->net_dev,
978 "linked VI %u to PIO buffer %u offset %x addr %p\n",
979 tx_queue->queue, index,
980 tx_queue->piobuf_offset,
981 tx_queue->piobuf);
982 }
983 }
984 }
985
986 return 0;
987
988fail:
Edward Creed0346b02017-03-03 15:22:09 +0000989 /* inbuf was defined for MC_CMD_LINK_PIOBUF. We can use the same
990 * buffer for MC_CMD_UNLINK_PIOBUF because it's shorter.
991 */
992 BUILD_BUG_ON(MC_CMD_LINK_PIOBUF_IN_LEN < MC_CMD_UNLINK_PIOBUF_IN_LEN);
Ben Hutchings183233b2013-06-28 21:47:12 +0100993 while (index--) {
994 MCDI_SET_DWORD(inbuf, UNLINK_PIOBUF_IN_TXQ_INSTANCE,
995 nic_data->pio_write_vi_base + index);
996 efx_mcdi_rpc(efx, MC_CMD_UNLINK_PIOBUF,
997 inbuf, MC_CMD_UNLINK_PIOBUF_IN_LEN,
998 NULL, 0, NULL);
999 }
1000 return rc;
1001}
1002
Edward Creec0795bf2016-05-24 18:53:36 +01001003static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
1004{
1005 struct efx_channel *channel;
1006 struct efx_tx_queue *tx_queue;
1007
1008 /* All our existing PIO buffers went away */
1009 efx_for_each_channel(channel, efx)
1010 efx_for_each_channel_tx_queue(tx_queue, channel)
1011 tx_queue->piobuf = NULL;
1012}
1013
Ben Hutchings183233b2013-06-28 21:47:12 +01001014#else /* !EFX_USE_PIO */
1015
1016static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
1017{
1018 return n == 0 ? 0 : -ENOBUFS;
1019}
1020
1021static int efx_ef10_link_piobufs(struct efx_nic *efx)
1022{
1023 return 0;
1024}
1025
1026static void efx_ef10_free_piobufs(struct efx_nic *efx)
1027{
1028}
1029
Edward Creec0795bf2016-05-24 18:53:36 +01001030static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
1031{
1032}
1033
Ben Hutchings183233b2013-06-28 21:47:12 +01001034#endif /* EFX_USE_PIO */
1035
Ben Hutchings8127d662013-08-29 19:19:29 +01001036static void efx_ef10_remove(struct efx_nic *efx)
1037{
1038 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1039 int rc;
1040
Shradha Shahf1122a32015-05-20 11:09:46 +01001041#ifdef CONFIG_SFC_SRIOV
1042 struct efx_ef10_nic_data *nic_data_pf;
1043 struct pci_dev *pci_dev_pf;
1044 struct efx_nic *efx_pf;
1045 struct ef10_vf *vf;
1046
1047 if (efx->pci_dev->is_virtfn) {
1048 pci_dev_pf = efx->pci_dev->physfn;
1049 if (pci_dev_pf) {
1050 efx_pf = pci_get_drvdata(pci_dev_pf);
1051 nic_data_pf = efx_pf->nic_data;
1052 vf = nic_data_pf->vf + nic_data->vf_index;
1053 vf->efx = NULL;
1054 } else
1055 netif_info(efx, drv, efx->net_dev,
1056 "Could not get the PF id from VF\n");
1057 }
1058#endif
1059
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01001060 efx_ef10_cleanup_vlans(efx);
1061 mutex_destroy(&nic_data->vlan_lock);
1062
Ben Hutchings9aecda92013-12-05 21:28:42 +00001063 efx_ptp_remove(efx);
1064
Ben Hutchings8127d662013-08-29 19:19:29 +01001065 efx_mcdi_mon_remove(efx);
1066
Ben Hutchings8127d662013-08-29 19:19:29 +01001067 efx_ef10_rx_free_indir_table(efx);
1068
Ben Hutchings183233b2013-06-28 21:47:12 +01001069 if (nic_data->wc_membase)
1070 iounmap(nic_data->wc_membase);
1071
Ben Hutchings8127d662013-08-29 19:19:29 +01001072 rc = efx_ef10_free_vis(efx);
1073 WARN_ON(rc != 0);
1074
Ben Hutchings183233b2013-06-28 21:47:12 +01001075 if (!nic_data->must_restore_piobufs)
1076 efx_ef10_free_piobufs(efx);
1077
Shradha Shah0f5c0842015-06-02 11:37:58 +01001078 device_remove_file(&efx->pci_dev->dev, &dev_attr_primary_flag);
1079 device_remove_file(&efx->pci_dev->dev, &dev_attr_link_control_flag);
1080
Jon Coopere5fbd972017-02-08 16:52:10 +00001081 efx_mcdi_detach(efx);
1082
1083 memset(nic_data->udp_tunnels, 0, sizeof(nic_data->udp_tunnels));
1084 mutex_lock(&nic_data->udp_tunnels_lock);
1085 (void)efx_ef10_set_udp_tnl_ports(efx, true);
1086 mutex_unlock(&nic_data->udp_tunnels_lock);
1087
1088 mutex_destroy(&nic_data->udp_tunnels_lock);
1089
Ben Hutchings8127d662013-08-29 19:19:29 +01001090 efx_mcdi_fini(efx);
1091 efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
1092 kfree(nic_data);
1093}
1094
Shradha Shah88a37de2015-05-20 11:09:15 +01001095static int efx_ef10_probe_pf(struct efx_nic *efx)
1096{
1097 return efx_ef10_probe(efx);
1098}
1099
Andrew Rybchenko38d27f32016-06-15 17:52:08 +01001100int efx_ef10_vadaptor_query(struct efx_nic *efx, unsigned int port_id,
1101 u32 *port_flags, u32 *vadaptor_flags,
1102 unsigned int *vlan_tags)
1103{
1104 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1105 MCDI_DECLARE_BUF(inbuf, MC_CMD_VADAPTOR_QUERY_IN_LEN);
1106 MCDI_DECLARE_BUF(outbuf, MC_CMD_VADAPTOR_QUERY_OUT_LEN);
1107 size_t outlen;
1108 int rc;
1109
1110 if (nic_data->datapath_caps &
1111 (1 << MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_QUERY_LBN)) {
1112 MCDI_SET_DWORD(inbuf, VADAPTOR_QUERY_IN_UPSTREAM_PORT_ID,
1113 port_id);
1114
1115 rc = efx_mcdi_rpc(efx, MC_CMD_VADAPTOR_QUERY, inbuf, sizeof(inbuf),
1116 outbuf, sizeof(outbuf), &outlen);
1117 if (rc)
1118 return rc;
1119
1120 if (outlen < sizeof(outbuf)) {
1121 rc = -EIO;
1122 return rc;
1123 }
1124 }
1125
1126 if (port_flags)
1127 *port_flags = MCDI_DWORD(outbuf, VADAPTOR_QUERY_OUT_PORT_FLAGS);
1128 if (vadaptor_flags)
1129 *vadaptor_flags =
1130 MCDI_DWORD(outbuf, VADAPTOR_QUERY_OUT_VADAPTOR_FLAGS);
1131 if (vlan_tags)
1132 *vlan_tags =
1133 MCDI_DWORD(outbuf,
1134 VADAPTOR_QUERY_OUT_NUM_AVAILABLE_VLAN_TAGS);
1135
1136 return 0;
1137}
1138
Daniel Pieczko7a186f42015-07-07 11:37:19 +01001139int efx_ef10_vadaptor_alloc(struct efx_nic *efx, unsigned int port_id)
1140{
1141 MCDI_DECLARE_BUF(inbuf, MC_CMD_VADAPTOR_ALLOC_IN_LEN);
1142
1143 MCDI_SET_DWORD(inbuf, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
1144 return efx_mcdi_rpc(efx, MC_CMD_VADAPTOR_ALLOC, inbuf, sizeof(inbuf),
1145 NULL, 0, NULL);
1146}
1147
1148int efx_ef10_vadaptor_free(struct efx_nic *efx, unsigned int port_id)
1149{
1150 MCDI_DECLARE_BUF(inbuf, MC_CMD_VADAPTOR_FREE_IN_LEN);
1151
1152 MCDI_SET_DWORD(inbuf, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
1153 return efx_mcdi_rpc(efx, MC_CMD_VADAPTOR_FREE, inbuf, sizeof(inbuf),
1154 NULL, 0, NULL);
1155}
1156
1157int efx_ef10_vport_add_mac(struct efx_nic *efx,
1158 unsigned int port_id, u8 *mac)
1159{
1160 MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN);
1161
1162 MCDI_SET_DWORD(inbuf, VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID, port_id);
1163 ether_addr_copy(MCDI_PTR(inbuf, VPORT_ADD_MAC_ADDRESS_IN_MACADDR), mac);
1164
1165 return efx_mcdi_rpc(efx, MC_CMD_VPORT_ADD_MAC_ADDRESS, inbuf,
1166 sizeof(inbuf), NULL, 0, NULL);
1167}
1168
1169int efx_ef10_vport_del_mac(struct efx_nic *efx,
1170 unsigned int port_id, u8 *mac)
1171{
1172 MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN);
1173
1174 MCDI_SET_DWORD(inbuf, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, port_id);
1175 ether_addr_copy(MCDI_PTR(inbuf, VPORT_DEL_MAC_ADDRESS_IN_MACADDR), mac);
1176
1177 return efx_mcdi_rpc(efx, MC_CMD_VPORT_DEL_MAC_ADDRESS, inbuf,
1178 sizeof(inbuf), NULL, 0, NULL);
1179}
1180
Shradha Shah88a37de2015-05-20 11:09:15 +01001181#ifdef CONFIG_SFC_SRIOV
1182static int efx_ef10_probe_vf(struct efx_nic *efx)
1183{
1184 int rc;
Daniel Pieczko6598dad2015-06-02 11:41:00 +01001185 struct pci_dev *pci_dev_pf;
1186
1187 /* If the parent PF has no VF data structure, it doesn't know about this
1188 * VF so fail probe. The VF needs to be re-created. This can happen
1189 * if the PF driver is unloaded while the VF is assigned to a guest.
1190 */
1191 pci_dev_pf = efx->pci_dev->physfn;
1192 if (pci_dev_pf) {
1193 struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
1194 struct efx_ef10_nic_data *nic_data_pf = efx_pf->nic_data;
1195
1196 if (!nic_data_pf->vf) {
1197 netif_info(efx, drv, efx->net_dev,
1198 "The VF cannot link to its parent PF; "
1199 "please destroy and re-create the VF\n");
1200 return -EBUSY;
1201 }
1202 }
Shradha Shah88a37de2015-05-20 11:09:15 +01001203
1204 rc = efx_ef10_probe(efx);
1205 if (rc)
1206 return rc;
1207
1208 rc = efx_ef10_get_vf_index(efx);
1209 if (rc)
1210 goto fail;
1211
Shradha Shahf1122a32015-05-20 11:09:46 +01001212 if (efx->pci_dev->is_virtfn) {
1213 if (efx->pci_dev->physfn) {
1214 struct efx_nic *efx_pf =
1215 pci_get_drvdata(efx->pci_dev->physfn);
1216 struct efx_ef10_nic_data *nic_data_p = efx_pf->nic_data;
1217 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1218
1219 nic_data_p->vf[nic_data->vf_index].efx = efx;
Daniel Pieczko6598dad2015-06-02 11:41:00 +01001220 nic_data_p->vf[nic_data->vf_index].pci_dev =
1221 efx->pci_dev;
Shradha Shahf1122a32015-05-20 11:09:46 +01001222 } else
1223 netif_info(efx, drv, efx->net_dev,
1224 "Could not get the PF id from VF\n");
1225 }
1226
Shradha Shah88a37de2015-05-20 11:09:15 +01001227 return 0;
1228
1229fail:
1230 efx_ef10_remove(efx);
1231 return rc;
1232}
1233#else
1234static int efx_ef10_probe_vf(struct efx_nic *efx __attribute__ ((unused)))
1235{
1236 return 0;
1237}
1238#endif
1239
Ben Hutchings8127d662013-08-29 19:19:29 +01001240static int efx_ef10_alloc_vis(struct efx_nic *efx,
1241 unsigned int min_vis, unsigned int max_vis)
1242{
1243 MCDI_DECLARE_BUF(inbuf, MC_CMD_ALLOC_VIS_IN_LEN);
1244 MCDI_DECLARE_BUF(outbuf, MC_CMD_ALLOC_VIS_OUT_LEN);
1245 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1246 size_t outlen;
1247 int rc;
1248
1249 MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MIN_VI_COUNT, min_vis);
1250 MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MAX_VI_COUNT, max_vis);
1251 rc = efx_mcdi_rpc(efx, MC_CMD_ALLOC_VIS, inbuf, sizeof(inbuf),
1252 outbuf, sizeof(outbuf), &outlen);
1253 if (rc != 0)
1254 return rc;
1255
1256 if (outlen < MC_CMD_ALLOC_VIS_OUT_LEN)
1257 return -EIO;
1258
1259 netif_dbg(efx, drv, efx->net_dev, "base VI is A0x%03x\n",
1260 MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE));
1261
1262 nic_data->vi_base = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE);
1263 nic_data->n_allocated_vis = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_COUNT);
1264 return 0;
1265}
1266
Ben Hutchings183233b2013-06-28 21:47:12 +01001267/* Note that the failure path of this function does not free
1268 * resources, as this will be done by efx_ef10_remove().
1269 */
Ben Hutchings8127d662013-08-29 19:19:29 +01001270static int efx_ef10_dimension_resources(struct efx_nic *efx)
1271{
Ben Hutchings183233b2013-06-28 21:47:12 +01001272 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1273 unsigned int uc_mem_map_size, wc_mem_map_size;
Shradha Shahb0fbdae2015-08-28 10:55:42 +01001274 unsigned int min_vis = max(EFX_TXQ_TYPES,
1275 efx_separate_tx_channels ? 2 : 1);
1276 unsigned int channel_vis, pio_write_vi_base, max_vis;
Ben Hutchings183233b2013-06-28 21:47:12 +01001277 void __iomem *membase;
1278 int rc;
Ben Hutchings8127d662013-08-29 19:19:29 +01001279
Shradha Shahb0fbdae2015-08-28 10:55:42 +01001280 channel_vis = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES);
Ben Hutchings183233b2013-06-28 21:47:12 +01001281
1282#ifdef EFX_USE_PIO
1283 /* Try to allocate PIO buffers if wanted and if the full
1284 * number of PIO buffers would be sufficient to allocate one
1285 * copy-buffer per TX channel. Failure is non-fatal, as there
1286 * are only a small number of PIO buffers shared between all
1287 * functions of the controller.
1288 */
1289 if (efx_piobuf_size != 0 &&
Edward Creec6347002017-01-13 21:20:29 +00001290 nic_data->piobuf_size / efx_piobuf_size * EF10_TX_PIOBUF_COUNT >=
Ben Hutchings183233b2013-06-28 21:47:12 +01001291 efx->n_tx_channels) {
1292 unsigned int n_piobufs =
1293 DIV_ROUND_UP(efx->n_tx_channels,
Edward Creec6347002017-01-13 21:20:29 +00001294 nic_data->piobuf_size / efx_piobuf_size);
Ben Hutchings183233b2013-06-28 21:47:12 +01001295
1296 rc = efx_ef10_alloc_piobufs(efx, n_piobufs);
Tomáš Pilař6eacfb52017-01-25 13:48:17 +00001297 if (rc == -ENOSPC)
1298 netif_dbg(efx, probe, efx->net_dev,
1299 "out of PIO buffers; cannot allocate more\n");
1300 else if (rc == -EPERM)
1301 netif_dbg(efx, probe, efx->net_dev,
1302 "not permitted to allocate PIO buffers\n");
1303 else if (rc)
Ben Hutchings183233b2013-06-28 21:47:12 +01001304 netif_err(efx, probe, efx->net_dev,
1305 "failed to allocate PIO buffers (%d)\n", rc);
1306 else
1307 netif_dbg(efx, probe, efx->net_dev,
1308 "allocated %u PIO buffers\n", n_piobufs);
1309 }
1310#else
1311 nic_data->n_piobufs = 0;
1312#endif
1313
1314 /* PIO buffers should be mapped with write-combining enabled,
1315 * and we want to make single UC and WC mappings rather than
1316 * several of each (in fact that's the only option if host
1317 * page size is >4K). So we may allocate some extra VIs just
1318 * for writing PIO buffers through.
Daniel Pieczko52ad7622014-04-01 13:10:34 +01001319 *
Shradha Shahb0fbdae2015-08-28 10:55:42 +01001320 * The UC mapping contains (channel_vis - 1) complete VIs and the
Edward Cree71827442017-12-18 16:56:19 +00001321 * first 4K of the next VI. Then the WC mapping begins with
1322 * the remainder of this last VI.
Ben Hutchings183233b2013-06-28 21:47:12 +01001323 */
Edward Cree71827442017-12-18 16:56:19 +00001324 uc_mem_map_size = PAGE_ALIGN((channel_vis - 1) * efx->vi_stride +
Ben Hutchings183233b2013-06-28 21:47:12 +01001325 ER_DZ_TX_PIOBUF);
1326 if (nic_data->n_piobufs) {
Daniel Pieczko52ad7622014-04-01 13:10:34 +01001327 /* pio_write_vi_base rounds down to give the number of complete
1328 * VIs inside the UC mapping.
1329 */
Edward Cree71827442017-12-18 16:56:19 +00001330 pio_write_vi_base = uc_mem_map_size / efx->vi_stride;
Ben Hutchings183233b2013-06-28 21:47:12 +01001331 wc_mem_map_size = (PAGE_ALIGN((pio_write_vi_base +
1332 nic_data->n_piobufs) *
Edward Cree71827442017-12-18 16:56:19 +00001333 efx->vi_stride) -
Ben Hutchings183233b2013-06-28 21:47:12 +01001334 uc_mem_map_size);
1335 max_vis = pio_write_vi_base + nic_data->n_piobufs;
1336 } else {
1337 pio_write_vi_base = 0;
1338 wc_mem_map_size = 0;
Shradha Shahb0fbdae2015-08-28 10:55:42 +01001339 max_vis = channel_vis;
Ben Hutchings183233b2013-06-28 21:47:12 +01001340 }
1341
1342 /* In case the last attached driver failed to free VIs, do it now */
1343 rc = efx_ef10_free_vis(efx);
1344 if (rc != 0)
1345 return rc;
1346
1347 rc = efx_ef10_alloc_vis(efx, min_vis, max_vis);
1348 if (rc != 0)
1349 return rc;
1350
Shradha Shahb0fbdae2015-08-28 10:55:42 +01001351 if (nic_data->n_allocated_vis < channel_vis) {
1352 netif_info(efx, drv, efx->net_dev,
1353 "Could not allocate enough VIs to satisfy RSS"
1354 " requirements. Performance may not be optimal.\n");
1355 /* We didn't get the VIs to populate our channels.
1356 * We could keep what we got but then we'd have more
1357 * interrupts than we need.
1358 * Instead calculate new max_channels and restart
1359 */
1360 efx->max_channels = nic_data->n_allocated_vis;
1361 efx->max_tx_channels =
1362 nic_data->n_allocated_vis / EFX_TXQ_TYPES;
1363
1364 efx_ef10_free_vis(efx);
1365 return -EAGAIN;
1366 }
1367
Ben Hutchings183233b2013-06-28 21:47:12 +01001368 /* If we didn't get enough VIs to map all the PIO buffers, free the
1369 * PIO buffers
1370 */
1371 if (nic_data->n_piobufs &&
1372 nic_data->n_allocated_vis <
1373 pio_write_vi_base + nic_data->n_piobufs) {
1374 netif_dbg(efx, probe, efx->net_dev,
1375 "%u VIs are not sufficient to map %u PIO buffers\n",
1376 nic_data->n_allocated_vis, nic_data->n_piobufs);
1377 efx_ef10_free_piobufs(efx);
1378 }
1379
1380 /* Shrink the original UC mapping of the memory BAR */
1381 membase = ioremap_nocache(efx->membase_phys, uc_mem_map_size);
1382 if (!membase) {
1383 netif_err(efx, probe, efx->net_dev,
1384 "could not shrink memory BAR to %x\n",
1385 uc_mem_map_size);
1386 return -ENOMEM;
1387 }
1388 iounmap(efx->membase);
1389 efx->membase = membase;
1390
1391 /* Set up the WC mapping if needed */
1392 if (wc_mem_map_size) {
1393 nic_data->wc_membase = ioremap_wc(efx->membase_phys +
1394 uc_mem_map_size,
1395 wc_mem_map_size);
1396 if (!nic_data->wc_membase) {
1397 netif_err(efx, probe, efx->net_dev,
1398 "could not allocate WC mapping of size %x\n",
1399 wc_mem_map_size);
1400 return -ENOMEM;
1401 }
1402 nic_data->pio_write_vi_base = pio_write_vi_base;
1403 nic_data->pio_write_base =
1404 nic_data->wc_membase +
Edward Cree71827442017-12-18 16:56:19 +00001405 (pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF -
Ben Hutchings183233b2013-06-28 21:47:12 +01001406 uc_mem_map_size);
1407
1408 rc = efx_ef10_link_piobufs(efx);
1409 if (rc)
1410 efx_ef10_free_piobufs(efx);
1411 }
1412
1413 netif_dbg(efx, probe, efx->net_dev,
1414 "memory BAR at %pa (virtual %p+%x UC, %p+%x WC)\n",
1415 &efx->membase_phys, efx->membase, uc_mem_map_size,
1416 nic_data->wc_membase, wc_mem_map_size);
1417
1418 return 0;
Ben Hutchings8127d662013-08-29 19:19:29 +01001419}
1420
1421static int efx_ef10_init_nic(struct efx_nic *efx)
1422{
1423 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1424 int rc;
1425
Ben Hutchingsa915ccc2013-09-05 22:51:55 +01001426 if (nic_data->must_check_datapath_caps) {
1427 rc = efx_ef10_init_datapath_caps(efx);
1428 if (rc)
1429 return rc;
1430 nic_data->must_check_datapath_caps = false;
1431 }
1432
Ben Hutchings8127d662013-08-29 19:19:29 +01001433 if (nic_data->must_realloc_vis) {
1434 /* We cannot let the number of VIs change now */
1435 rc = efx_ef10_alloc_vis(efx, nic_data->n_allocated_vis,
1436 nic_data->n_allocated_vis);
1437 if (rc)
1438 return rc;
1439 nic_data->must_realloc_vis = false;
1440 }
1441
Ben Hutchings183233b2013-06-28 21:47:12 +01001442 if (nic_data->must_restore_piobufs && nic_data->n_piobufs) {
1443 rc = efx_ef10_alloc_piobufs(efx, nic_data->n_piobufs);
1444 if (rc == 0) {
1445 rc = efx_ef10_link_piobufs(efx);
1446 if (rc)
1447 efx_ef10_free_piobufs(efx);
1448 }
1449
Tomáš Pilař6eacfb52017-01-25 13:48:17 +00001450 /* Log an error on failure, but this is non-fatal.
1451 * Permission errors are less important - we've presumably
1452 * had the PIO buffer licence removed.
1453 */
1454 if (rc == -EPERM)
1455 netif_dbg(efx, drv, efx->net_dev,
1456 "not permitted to restore PIO buffers\n");
1457 else if (rc)
Ben Hutchings183233b2013-06-28 21:47:12 +01001458 netif_err(efx, drv, efx->net_dev,
1459 "failed to restore PIO buffers (%d)\n", rc);
1460 nic_data->must_restore_piobufs = false;
1461 }
1462
Jon Cooper267c0152015-05-06 00:59:38 +01001463 /* don't fail init if RSS setup doesn't work */
Edward Creef74d1992017-01-17 12:01:53 +00001464 rc = efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table, NULL);
Edward Cree4fdda952017-01-04 15:10:56 +00001465 efx->rss_active = (rc == 0);
Jon Cooper267c0152015-05-06 00:59:38 +01001466
Ben Hutchings8127d662013-08-29 19:19:29 +01001467 return 0;
1468}
1469
Jon Cooper3e336262014-01-17 19:48:06 +00001470static void efx_ef10_reset_mc_allocations(struct efx_nic *efx)
1471{
1472 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Daniel Pieczko774ad032015-07-31 11:15:22 +01001473#ifdef CONFIG_SFC_SRIOV
1474 unsigned int i;
1475#endif
Jon Cooper3e336262014-01-17 19:48:06 +00001476
1477 /* All our allocations have been reset */
1478 nic_data->must_realloc_vis = true;
1479 nic_data->must_restore_filters = true;
1480 nic_data->must_restore_piobufs = true;
Edward Creec0795bf2016-05-24 18:53:36 +01001481 efx_ef10_forget_old_piobufs(efx);
Jon Cooper3e336262014-01-17 19:48:06 +00001482 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
Daniel Pieczko774ad032015-07-31 11:15:22 +01001483
1484 /* Driver-created vswitches and vports must be re-created */
1485 nic_data->must_probe_vswitching = true;
1486 nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
1487#ifdef CONFIG_SFC_SRIOV
1488 if (nic_data->vf)
1489 for (i = 0; i < efx->vf_count; i++)
1490 nic_data->vf[i].vport_id = 0;
1491#endif
Jon Cooper3e336262014-01-17 19:48:06 +00001492}
1493
Jon Cooper087e9022015-05-20 11:11:35 +01001494static enum reset_type efx_ef10_map_reset_reason(enum reset_type reason)
1495{
1496 if (reason == RESET_TYPE_MC_FAILURE)
1497 return RESET_TYPE_DATAPATH;
1498
1499 return efx_mcdi_map_reset_reason(reason);
1500}
1501
Ben Hutchings8127d662013-08-29 19:19:29 +01001502static int efx_ef10_map_reset_flags(u32 *flags)
1503{
1504 enum {
1505 EF10_RESET_PORT = ((ETH_RESET_MAC | ETH_RESET_PHY) <<
1506 ETH_RESET_SHARED_SHIFT),
1507 EF10_RESET_MC = ((ETH_RESET_DMA | ETH_RESET_FILTER |
1508 ETH_RESET_OFFLOAD | ETH_RESET_MAC |
1509 ETH_RESET_PHY | ETH_RESET_MGMT) <<
1510 ETH_RESET_SHARED_SHIFT)
1511 };
1512
1513 /* We assume for now that our PCI function is permitted to
1514 * reset everything.
1515 */
1516
1517 if ((*flags & EF10_RESET_MC) == EF10_RESET_MC) {
1518 *flags &= ~EF10_RESET_MC;
1519 return RESET_TYPE_WORLD;
1520 }
1521
1522 if ((*flags & EF10_RESET_PORT) == EF10_RESET_PORT) {
1523 *flags &= ~EF10_RESET_PORT;
1524 return RESET_TYPE_ALL;
1525 }
1526
1527 /* no invisible reset implemented */
1528
1529 return -EINVAL;
1530}
1531
Jon Cooper3e336262014-01-17 19:48:06 +00001532static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type)
1533{
1534 int rc = efx_mcdi_reset(efx, reset_type);
1535
Daniel Pieczko27324822015-07-31 11:14:54 +01001536 /* Unprivileged functions return -EPERM, but need to return success
1537 * here so that the datapath is brought back up.
1538 */
1539 if (reset_type == RESET_TYPE_WORLD && rc == -EPERM)
1540 rc = 0;
1541
Jon Cooper3e336262014-01-17 19:48:06 +00001542 /* If it was a port reset, trigger reallocation of MC resources.
1543 * Note that on an MC reset nothing needs to be done now because we'll
1544 * detect the MC reset later and handle it then.
Edward Creee2835462014-04-16 19:27:48 +01001545 * For an FLR, we never get an MC reset event, but the MC has reset all
1546 * resources assigned to us, so we have to trigger reallocation now.
Jon Cooper3e336262014-01-17 19:48:06 +00001547 */
Edward Creee2835462014-04-16 19:27:48 +01001548 if ((reset_type == RESET_TYPE_ALL ||
1549 reset_type == RESET_TYPE_MCDI_TIMEOUT) && !rc)
Jon Cooper3e336262014-01-17 19:48:06 +00001550 efx_ef10_reset_mc_allocations(efx);
1551 return rc;
1552}
1553
Ben Hutchings8127d662013-08-29 19:19:29 +01001554#define EF10_DMA_STAT(ext_name, mcdi_name) \
1555 [EF10_STAT_ ## ext_name] = \
1556 { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
1557#define EF10_DMA_INVIS_STAT(int_name, mcdi_name) \
1558 [EF10_STAT_ ## int_name] = \
1559 { NULL, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
1560#define EF10_OTHER_STAT(ext_name) \
1561 [EF10_STAT_ ## ext_name] = { #ext_name, 0, 0 }
Edward Creee4d112e2014-07-15 11:58:12 +01001562#define GENERIC_SW_STAT(ext_name) \
1563 [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
Ben Hutchings8127d662013-08-29 19:19:29 +01001564
1565static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001566 EF10_DMA_STAT(port_tx_bytes, TX_BYTES),
1567 EF10_DMA_STAT(port_tx_packets, TX_PKTS),
1568 EF10_DMA_STAT(port_tx_pause, TX_PAUSE_PKTS),
1569 EF10_DMA_STAT(port_tx_control, TX_CONTROL_PKTS),
1570 EF10_DMA_STAT(port_tx_unicast, TX_UNICAST_PKTS),
1571 EF10_DMA_STAT(port_tx_multicast, TX_MULTICAST_PKTS),
1572 EF10_DMA_STAT(port_tx_broadcast, TX_BROADCAST_PKTS),
1573 EF10_DMA_STAT(port_tx_lt64, TX_LT64_PKTS),
1574 EF10_DMA_STAT(port_tx_64, TX_64_PKTS),
1575 EF10_DMA_STAT(port_tx_65_to_127, TX_65_TO_127_PKTS),
1576 EF10_DMA_STAT(port_tx_128_to_255, TX_128_TO_255_PKTS),
1577 EF10_DMA_STAT(port_tx_256_to_511, TX_256_TO_511_PKTS),
1578 EF10_DMA_STAT(port_tx_512_to_1023, TX_512_TO_1023_PKTS),
1579 EF10_DMA_STAT(port_tx_1024_to_15xx, TX_1024_TO_15XX_PKTS),
1580 EF10_DMA_STAT(port_tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS),
1581 EF10_DMA_STAT(port_rx_bytes, RX_BYTES),
1582 EF10_DMA_INVIS_STAT(port_rx_bytes_minus_good_bytes, RX_BAD_BYTES),
1583 EF10_OTHER_STAT(port_rx_good_bytes),
1584 EF10_OTHER_STAT(port_rx_bad_bytes),
1585 EF10_DMA_STAT(port_rx_packets, RX_PKTS),
1586 EF10_DMA_STAT(port_rx_good, RX_GOOD_PKTS),
1587 EF10_DMA_STAT(port_rx_bad, RX_BAD_FCS_PKTS),
1588 EF10_DMA_STAT(port_rx_pause, RX_PAUSE_PKTS),
1589 EF10_DMA_STAT(port_rx_control, RX_CONTROL_PKTS),
1590 EF10_DMA_STAT(port_rx_unicast, RX_UNICAST_PKTS),
1591 EF10_DMA_STAT(port_rx_multicast, RX_MULTICAST_PKTS),
1592 EF10_DMA_STAT(port_rx_broadcast, RX_BROADCAST_PKTS),
1593 EF10_DMA_STAT(port_rx_lt64, RX_UNDERSIZE_PKTS),
1594 EF10_DMA_STAT(port_rx_64, RX_64_PKTS),
1595 EF10_DMA_STAT(port_rx_65_to_127, RX_65_TO_127_PKTS),
1596 EF10_DMA_STAT(port_rx_128_to_255, RX_128_TO_255_PKTS),
1597 EF10_DMA_STAT(port_rx_256_to_511, RX_256_TO_511_PKTS),
1598 EF10_DMA_STAT(port_rx_512_to_1023, RX_512_TO_1023_PKTS),
1599 EF10_DMA_STAT(port_rx_1024_to_15xx, RX_1024_TO_15XX_PKTS),
1600 EF10_DMA_STAT(port_rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS),
1601 EF10_DMA_STAT(port_rx_gtjumbo, RX_GTJUMBO_PKTS),
1602 EF10_DMA_STAT(port_rx_bad_gtjumbo, RX_JABBER_PKTS),
1603 EF10_DMA_STAT(port_rx_overflow, RX_OVERFLOW_PKTS),
1604 EF10_DMA_STAT(port_rx_align_error, RX_ALIGN_ERROR_PKTS),
1605 EF10_DMA_STAT(port_rx_length_error, RX_LENGTH_ERROR_PKTS),
1606 EF10_DMA_STAT(port_rx_nodesc_drops, RX_NODESC_DROPS),
Edward Creee4d112e2014-07-15 11:58:12 +01001607 GENERIC_SW_STAT(rx_nodesc_trunc),
1608 GENERIC_SW_STAT(rx_noskb_drops),
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001609 EF10_DMA_STAT(port_rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW),
1610 EF10_DMA_STAT(port_rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW),
1611 EF10_DMA_STAT(port_rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL),
1612 EF10_DMA_STAT(port_rx_pm_discard_vfifo_full, PM_DISCARD_VFIFO_FULL),
1613 EF10_DMA_STAT(port_rx_pm_trunc_qbb, PM_TRUNC_QBB),
1614 EF10_DMA_STAT(port_rx_pm_discard_qbb, PM_DISCARD_QBB),
1615 EF10_DMA_STAT(port_rx_pm_discard_mapping, PM_DISCARD_MAPPING),
1616 EF10_DMA_STAT(port_rx_dp_q_disabled_packets, RXDP_Q_DISABLED_PKTS),
1617 EF10_DMA_STAT(port_rx_dp_di_dropped_packets, RXDP_DI_DROPPED_PKTS),
1618 EF10_DMA_STAT(port_rx_dp_streaming_packets, RXDP_STREAMING_PKTS),
1619 EF10_DMA_STAT(port_rx_dp_hlb_fetch, RXDP_HLB_FETCH_CONDITIONS),
1620 EF10_DMA_STAT(port_rx_dp_hlb_wait, RXDP_HLB_WAIT_CONDITIONS),
Daniel Pieczko3c36a2a2015-06-02 11:39:06 +01001621 EF10_DMA_STAT(rx_unicast, VADAPTER_RX_UNICAST_PACKETS),
1622 EF10_DMA_STAT(rx_unicast_bytes, VADAPTER_RX_UNICAST_BYTES),
1623 EF10_DMA_STAT(rx_multicast, VADAPTER_RX_MULTICAST_PACKETS),
1624 EF10_DMA_STAT(rx_multicast_bytes, VADAPTER_RX_MULTICAST_BYTES),
1625 EF10_DMA_STAT(rx_broadcast, VADAPTER_RX_BROADCAST_PACKETS),
1626 EF10_DMA_STAT(rx_broadcast_bytes, VADAPTER_RX_BROADCAST_BYTES),
1627 EF10_DMA_STAT(rx_bad, VADAPTER_RX_BAD_PACKETS),
1628 EF10_DMA_STAT(rx_bad_bytes, VADAPTER_RX_BAD_BYTES),
1629 EF10_DMA_STAT(rx_overflow, VADAPTER_RX_OVERFLOW),
1630 EF10_DMA_STAT(tx_unicast, VADAPTER_TX_UNICAST_PACKETS),
1631 EF10_DMA_STAT(tx_unicast_bytes, VADAPTER_TX_UNICAST_BYTES),
1632 EF10_DMA_STAT(tx_multicast, VADAPTER_TX_MULTICAST_PACKETS),
1633 EF10_DMA_STAT(tx_multicast_bytes, VADAPTER_TX_MULTICAST_BYTES),
1634 EF10_DMA_STAT(tx_broadcast, VADAPTER_TX_BROADCAST_PACKETS),
1635 EF10_DMA_STAT(tx_broadcast_bytes, VADAPTER_TX_BROADCAST_BYTES),
1636 EF10_DMA_STAT(tx_bad, VADAPTER_TX_BAD_PACKETS),
1637 EF10_DMA_STAT(tx_bad_bytes, VADAPTER_TX_BAD_BYTES),
1638 EF10_DMA_STAT(tx_overflow, VADAPTER_TX_OVERFLOW),
Edward Creef411b542017-12-21 09:00:36 +00001639 EF10_DMA_STAT(fec_uncorrected_errors, FEC_UNCORRECTED_ERRORS),
1640 EF10_DMA_STAT(fec_corrected_errors, FEC_CORRECTED_ERRORS),
1641 EF10_DMA_STAT(fec_corrected_symbols_lane0, FEC_CORRECTED_SYMBOLS_LANE0),
1642 EF10_DMA_STAT(fec_corrected_symbols_lane1, FEC_CORRECTED_SYMBOLS_LANE1),
1643 EF10_DMA_STAT(fec_corrected_symbols_lane2, FEC_CORRECTED_SYMBOLS_LANE2),
1644 EF10_DMA_STAT(fec_corrected_symbols_lane3, FEC_CORRECTED_SYMBOLS_LANE3),
Bert Kenward2c0b6ee2017-12-21 09:00:41 +00001645 EF10_DMA_STAT(ctpio_dmabuf_start, CTPIO_DMABUF_START),
1646 EF10_DMA_STAT(ctpio_vi_busy_fallback, CTPIO_VI_BUSY_FALLBACK),
1647 EF10_DMA_STAT(ctpio_long_write_success, CTPIO_LONG_WRITE_SUCCESS),
1648 EF10_DMA_STAT(ctpio_missing_dbell_fail, CTPIO_MISSING_DBELL_FAIL),
1649 EF10_DMA_STAT(ctpio_overflow_fail, CTPIO_OVERFLOW_FAIL),
1650 EF10_DMA_STAT(ctpio_underflow_fail, CTPIO_UNDERFLOW_FAIL),
1651 EF10_DMA_STAT(ctpio_timeout_fail, CTPIO_TIMEOUT_FAIL),
1652 EF10_DMA_STAT(ctpio_noncontig_wr_fail, CTPIO_NONCONTIG_WR_FAIL),
1653 EF10_DMA_STAT(ctpio_frm_clobber_fail, CTPIO_FRM_CLOBBER_FAIL),
1654 EF10_DMA_STAT(ctpio_invalid_wr_fail, CTPIO_INVALID_WR_FAIL),
1655 EF10_DMA_STAT(ctpio_vi_clobber_fallback, CTPIO_VI_CLOBBER_FALLBACK),
1656 EF10_DMA_STAT(ctpio_unqualified_fallback, CTPIO_UNQUALIFIED_FALLBACK),
1657 EF10_DMA_STAT(ctpio_runt_fallback, CTPIO_RUNT_FALLBACK),
1658 EF10_DMA_STAT(ctpio_success, CTPIO_SUCCESS),
1659 EF10_DMA_STAT(ctpio_fallback, CTPIO_FALLBACK),
1660 EF10_DMA_STAT(ctpio_poison, CTPIO_POISON),
1661 EF10_DMA_STAT(ctpio_erase, CTPIO_ERASE),
Ben Hutchings8127d662013-08-29 19:19:29 +01001662};
1663
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001664#define HUNT_COMMON_STAT_MASK ((1ULL << EF10_STAT_port_tx_bytes) | \
1665 (1ULL << EF10_STAT_port_tx_packets) | \
1666 (1ULL << EF10_STAT_port_tx_pause) | \
1667 (1ULL << EF10_STAT_port_tx_unicast) | \
1668 (1ULL << EF10_STAT_port_tx_multicast) | \
1669 (1ULL << EF10_STAT_port_tx_broadcast) | \
1670 (1ULL << EF10_STAT_port_rx_bytes) | \
1671 (1ULL << \
1672 EF10_STAT_port_rx_bytes_minus_good_bytes) | \
1673 (1ULL << EF10_STAT_port_rx_good_bytes) | \
1674 (1ULL << EF10_STAT_port_rx_bad_bytes) | \
1675 (1ULL << EF10_STAT_port_rx_packets) | \
1676 (1ULL << EF10_STAT_port_rx_good) | \
1677 (1ULL << EF10_STAT_port_rx_bad) | \
1678 (1ULL << EF10_STAT_port_rx_pause) | \
1679 (1ULL << EF10_STAT_port_rx_control) | \
1680 (1ULL << EF10_STAT_port_rx_unicast) | \
1681 (1ULL << EF10_STAT_port_rx_multicast) | \
1682 (1ULL << EF10_STAT_port_rx_broadcast) | \
1683 (1ULL << EF10_STAT_port_rx_lt64) | \
1684 (1ULL << EF10_STAT_port_rx_64) | \
1685 (1ULL << EF10_STAT_port_rx_65_to_127) | \
1686 (1ULL << EF10_STAT_port_rx_128_to_255) | \
1687 (1ULL << EF10_STAT_port_rx_256_to_511) | \
1688 (1ULL << EF10_STAT_port_rx_512_to_1023) |\
1689 (1ULL << EF10_STAT_port_rx_1024_to_15xx) |\
1690 (1ULL << EF10_STAT_port_rx_15xx_to_jumbo) |\
1691 (1ULL << EF10_STAT_port_rx_gtjumbo) | \
1692 (1ULL << EF10_STAT_port_rx_bad_gtjumbo) |\
1693 (1ULL << EF10_STAT_port_rx_overflow) | \
1694 (1ULL << EF10_STAT_port_rx_nodesc_drops) |\
Edward Creee4d112e2014-07-15 11:58:12 +01001695 (1ULL << GENERIC_STAT_rx_nodesc_trunc) | \
1696 (1ULL << GENERIC_STAT_rx_noskb_drops))
Ben Hutchings8127d662013-08-29 19:19:29 +01001697
Edward Cree69b365c2016-08-26 15:12:41 +01001698/* On 7000 series NICs, these statistics are only provided by the 10G MAC.
1699 * For a 10G/40G switchable port we do not expose these because they might
1700 * not include all the packets they should.
1701 * On 8000 series NICs these statistics are always provided.
Ben Hutchings8127d662013-08-29 19:19:29 +01001702 */
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001703#define HUNT_10G_ONLY_STAT_MASK ((1ULL << EF10_STAT_port_tx_control) | \
1704 (1ULL << EF10_STAT_port_tx_lt64) | \
1705 (1ULL << EF10_STAT_port_tx_64) | \
1706 (1ULL << EF10_STAT_port_tx_65_to_127) |\
1707 (1ULL << EF10_STAT_port_tx_128_to_255) |\
1708 (1ULL << EF10_STAT_port_tx_256_to_511) |\
1709 (1ULL << EF10_STAT_port_tx_512_to_1023) |\
1710 (1ULL << EF10_STAT_port_tx_1024_to_15xx) |\
1711 (1ULL << EF10_STAT_port_tx_15xx_to_jumbo))
Ben Hutchings8127d662013-08-29 19:19:29 +01001712
1713/* These statistics are only provided by the 40G MAC. For a 10G/40G
1714 * switchable port we do expose these because the errors will otherwise
1715 * be silent.
1716 */
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001717#define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_port_rx_align_error) |\
1718 (1ULL << EF10_STAT_port_rx_length_error))
Ben Hutchings8127d662013-08-29 19:19:29 +01001719
Edward Cree568d7a02013-09-25 17:32:09 +01001720/* These statistics are only provided if the firmware supports the
1721 * capability PM_AND_RXDP_COUNTERS.
1722 */
1723#define HUNT_PM_AND_RXDP_STAT_MASK ( \
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001724 (1ULL << EF10_STAT_port_rx_pm_trunc_bb_overflow) | \
1725 (1ULL << EF10_STAT_port_rx_pm_discard_bb_overflow) | \
1726 (1ULL << EF10_STAT_port_rx_pm_trunc_vfifo_full) | \
1727 (1ULL << EF10_STAT_port_rx_pm_discard_vfifo_full) | \
1728 (1ULL << EF10_STAT_port_rx_pm_trunc_qbb) | \
1729 (1ULL << EF10_STAT_port_rx_pm_discard_qbb) | \
1730 (1ULL << EF10_STAT_port_rx_pm_discard_mapping) | \
1731 (1ULL << EF10_STAT_port_rx_dp_q_disabled_packets) | \
1732 (1ULL << EF10_STAT_port_rx_dp_di_dropped_packets) | \
1733 (1ULL << EF10_STAT_port_rx_dp_streaming_packets) | \
1734 (1ULL << EF10_STAT_port_rx_dp_hlb_fetch) | \
1735 (1ULL << EF10_STAT_port_rx_dp_hlb_wait))
Ben Hutchings8127d662013-08-29 19:19:29 +01001736
Edward Creef411b542017-12-21 09:00:36 +00001737/* These statistics are only provided if the NIC supports MC_CMD_MAC_STATS_V2,
1738 * indicated by returning a value >= MC_CMD_MAC_NSTATS_V2 in
1739 * MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS.
1740 * These bits are in the second u64 of the raw mask.
1741 */
1742#define EF10_FEC_STAT_MASK ( \
1743 (1ULL << (EF10_STAT_fec_uncorrected_errors - 64)) | \
1744 (1ULL << (EF10_STAT_fec_corrected_errors - 64)) | \
1745 (1ULL << (EF10_STAT_fec_corrected_symbols_lane0 - 64)) | \
1746 (1ULL << (EF10_STAT_fec_corrected_symbols_lane1 - 64)) | \
1747 (1ULL << (EF10_STAT_fec_corrected_symbols_lane2 - 64)) | \
1748 (1ULL << (EF10_STAT_fec_corrected_symbols_lane3 - 64)))
1749
Bert Kenward2c0b6ee2017-12-21 09:00:41 +00001750/* These statistics are only provided if the NIC supports MC_CMD_MAC_STATS_V3,
1751 * indicated by returning a value >= MC_CMD_MAC_NSTATS_V3 in
1752 * MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS.
1753 * These bits are in the second u64 of the raw mask.
1754 */
1755#define EF10_CTPIO_STAT_MASK ( \
1756 (1ULL << (EF10_STAT_ctpio_dmabuf_start - 64)) | \
1757 (1ULL << (EF10_STAT_ctpio_vi_busy_fallback - 64)) | \
1758 (1ULL << (EF10_STAT_ctpio_long_write_success - 64)) | \
1759 (1ULL << (EF10_STAT_ctpio_missing_dbell_fail - 64)) | \
1760 (1ULL << (EF10_STAT_ctpio_overflow_fail - 64)) | \
1761 (1ULL << (EF10_STAT_ctpio_underflow_fail - 64)) | \
1762 (1ULL << (EF10_STAT_ctpio_timeout_fail - 64)) | \
1763 (1ULL << (EF10_STAT_ctpio_noncontig_wr_fail - 64)) | \
1764 (1ULL << (EF10_STAT_ctpio_frm_clobber_fail - 64)) | \
1765 (1ULL << (EF10_STAT_ctpio_invalid_wr_fail - 64)) | \
1766 (1ULL << (EF10_STAT_ctpio_vi_clobber_fallback - 64)) | \
1767 (1ULL << (EF10_STAT_ctpio_unqualified_fallback - 64)) | \
1768 (1ULL << (EF10_STAT_ctpio_runt_fallback - 64)) | \
1769 (1ULL << (EF10_STAT_ctpio_success - 64)) | \
1770 (1ULL << (EF10_STAT_ctpio_fallback - 64)) | \
1771 (1ULL << (EF10_STAT_ctpio_poison - 64)) | \
1772 (1ULL << (EF10_STAT_ctpio_erase - 64)))
1773
Edward Cree4bae9132013-09-27 18:52:49 +01001774static u64 efx_ef10_raw_stat_mask(struct efx_nic *efx)
Ben Hutchings8127d662013-08-29 19:19:29 +01001775{
Edward Cree4bae9132013-09-27 18:52:49 +01001776 u64 raw_mask = HUNT_COMMON_STAT_MASK;
Ben Hutchings8127d662013-08-29 19:19:29 +01001777 u32 port_caps = efx_mcdi_phy_get_caps(efx);
Edward Cree568d7a02013-09-25 17:32:09 +01001778 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Ben Hutchings8127d662013-08-29 19:19:29 +01001779
Daniel Pieczko3c36a2a2015-06-02 11:39:06 +01001780 if (!(efx->mcdi->fn_flags &
1781 1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL))
1782 return 0;
1783
Edward Cree69b365c2016-08-26 15:12:41 +01001784 if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) {
Edward Cree4bae9132013-09-27 18:52:49 +01001785 raw_mask |= HUNT_40G_EXTRA_STAT_MASK;
Edward Cree69b365c2016-08-26 15:12:41 +01001786 /* 8000 series have everything even at 40G */
1787 if (nic_data->datapath_caps2 &
1788 (1 << MC_CMD_GET_CAPABILITIES_V2_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN))
1789 raw_mask |= HUNT_10G_ONLY_STAT_MASK;
1790 } else {
Edward Cree4bae9132013-09-27 18:52:49 +01001791 raw_mask |= HUNT_10G_ONLY_STAT_MASK;
Edward Cree69b365c2016-08-26 15:12:41 +01001792 }
Edward Cree568d7a02013-09-25 17:32:09 +01001793
1794 if (nic_data->datapath_caps &
1795 (1 << MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN))
1796 raw_mask |= HUNT_PM_AND_RXDP_STAT_MASK;
1797
Edward Cree4bae9132013-09-27 18:52:49 +01001798 return raw_mask;
1799}
1800
1801static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask)
1802{
Daniel Pieczkod94619c2015-06-02 11:40:05 +01001803 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Daniel Pieczko3c36a2a2015-06-02 11:39:06 +01001804 u64 raw_mask[2];
1805
1806 raw_mask[0] = efx_ef10_raw_stat_mask(efx);
1807
Daniel Pieczkod94619c2015-06-02 11:40:05 +01001808 /* Only show vadaptor stats when EVB capability is present */
1809 if (nic_data->datapath_caps &
1810 (1 << MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN)) {
1811 raw_mask[0] |= ~((1ULL << EF10_STAT_rx_unicast) - 1);
Edward Creef411b542017-12-21 09:00:36 +00001812 raw_mask[1] = (1ULL << (EF10_STAT_V1_COUNT - 64)) - 1;
Daniel Pieczkod94619c2015-06-02 11:40:05 +01001813 } else {
1814 raw_mask[1] = 0;
1815 }
Edward Creef411b542017-12-21 09:00:36 +00001816 /* Only show FEC stats when NIC supports MC_CMD_MAC_STATS_V2 */
1817 if (efx->num_mac_stats >= MC_CMD_MAC_NSTATS_V2)
1818 raw_mask[1] |= EF10_FEC_STAT_MASK;
Edward Cree4bae9132013-09-27 18:52:49 +01001819
Bert Kenward2c0b6ee2017-12-21 09:00:41 +00001820 /* CTPIO stats appear in V3. Only show them on devices that actually
1821 * support CTPIO. Although this driver doesn't use CTPIO others might,
1822 * and we may be reporting the stats for the underlying port.
1823 */
1824 if (efx->num_mac_stats >= MC_CMD_MAC_NSTATS_V3 &&
1825 (nic_data->datapath_caps2 &
1826 (1 << MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_LBN)))
1827 raw_mask[1] |= EF10_CTPIO_STAT_MASK;
1828
Edward Cree4bae9132013-09-27 18:52:49 +01001829#if BITS_PER_LONG == 64
Andrew Rybchenkoe70c70c32016-08-26 11:19:34 +01001830 BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 2);
Daniel Pieczko3c36a2a2015-06-02 11:39:06 +01001831 mask[0] = raw_mask[0];
1832 mask[1] = raw_mask[1];
Edward Cree4bae9132013-09-27 18:52:49 +01001833#else
Andrew Rybchenkoe70c70c32016-08-26 11:19:34 +01001834 BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 3);
Daniel Pieczko3c36a2a2015-06-02 11:39:06 +01001835 mask[0] = raw_mask[0] & 0xffffffff;
1836 mask[1] = raw_mask[0] >> 32;
1837 mask[2] = raw_mask[1] & 0xffffffff;
Edward Cree4bae9132013-09-27 18:52:49 +01001838#endif
Ben Hutchings8127d662013-08-29 19:19:29 +01001839}
1840
1841static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names)
1842{
Edward Cree4bae9132013-09-27 18:52:49 +01001843 DECLARE_BITMAP(mask, EF10_STAT_COUNT);
1844
1845 efx_ef10_get_stat_mask(efx, mask);
Ben Hutchings8127d662013-08-29 19:19:29 +01001846 return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
Edward Cree4bae9132013-09-27 18:52:49 +01001847 mask, names);
Ben Hutchings8127d662013-08-29 19:19:29 +01001848}
1849
Daniel Pieczkod7788192015-06-02 11:39:20 +01001850static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats,
1851 struct rtnl_link_stats64 *core_stats)
1852{
1853 DECLARE_BITMAP(mask, EF10_STAT_COUNT);
1854 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1855 u64 *stats = nic_data->stats;
1856 size_t stats_count = 0, index;
1857
1858 efx_ef10_get_stat_mask(efx, mask);
1859
1860 if (full_stats) {
1861 for_each_set_bit(index, mask, EF10_STAT_COUNT) {
1862 if (efx_ef10_stat_desc[index].name) {
1863 *full_stats++ = stats[index];
1864 ++stats_count;
1865 }
1866 }
1867 }
1868
Bert Kenwardfbe43072015-08-26 16:39:03 +01001869 if (!core_stats)
1870 return stats_count;
1871
1872 if (nic_data->datapath_caps &
1873 1 << MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN) {
1874 /* Use vadaptor stats. */
Daniel Pieczko0fc95fc2015-06-02 11:39:33 +01001875 core_stats->rx_packets = stats[EF10_STAT_rx_unicast] +
1876 stats[EF10_STAT_rx_multicast] +
1877 stats[EF10_STAT_rx_broadcast];
1878 core_stats->tx_packets = stats[EF10_STAT_tx_unicast] +
1879 stats[EF10_STAT_tx_multicast] +
1880 stats[EF10_STAT_tx_broadcast];
1881 core_stats->rx_bytes = stats[EF10_STAT_rx_unicast_bytes] +
1882 stats[EF10_STAT_rx_multicast_bytes] +
1883 stats[EF10_STAT_rx_broadcast_bytes];
1884 core_stats->tx_bytes = stats[EF10_STAT_tx_unicast_bytes] +
1885 stats[EF10_STAT_tx_multicast_bytes] +
1886 stats[EF10_STAT_tx_broadcast_bytes];
1887 core_stats->rx_dropped = stats[GENERIC_STAT_rx_nodesc_trunc] +
Daniel Pieczkod7788192015-06-02 11:39:20 +01001888 stats[GENERIC_STAT_rx_noskb_drops];
Daniel Pieczko0fc95fc2015-06-02 11:39:33 +01001889 core_stats->multicast = stats[EF10_STAT_rx_multicast];
1890 core_stats->rx_crc_errors = stats[EF10_STAT_rx_bad];
1891 core_stats->rx_fifo_errors = stats[EF10_STAT_rx_overflow];
1892 core_stats->rx_errors = core_stats->rx_crc_errors;
1893 core_stats->tx_errors = stats[EF10_STAT_tx_bad];
Bert Kenwardfbe43072015-08-26 16:39:03 +01001894 } else {
1895 /* Use port stats. */
1896 core_stats->rx_packets = stats[EF10_STAT_port_rx_packets];
1897 core_stats->tx_packets = stats[EF10_STAT_port_tx_packets];
1898 core_stats->rx_bytes = stats[EF10_STAT_port_rx_bytes];
1899 core_stats->tx_bytes = stats[EF10_STAT_port_tx_bytes];
1900 core_stats->rx_dropped = stats[EF10_STAT_port_rx_nodesc_drops] +
1901 stats[GENERIC_STAT_rx_nodesc_trunc] +
1902 stats[GENERIC_STAT_rx_noskb_drops];
1903 core_stats->multicast = stats[EF10_STAT_port_rx_multicast];
1904 core_stats->rx_length_errors =
1905 stats[EF10_STAT_port_rx_gtjumbo] +
1906 stats[EF10_STAT_port_rx_length_error];
1907 core_stats->rx_crc_errors = stats[EF10_STAT_port_rx_bad];
1908 core_stats->rx_frame_errors =
1909 stats[EF10_STAT_port_rx_align_error];
1910 core_stats->rx_fifo_errors = stats[EF10_STAT_port_rx_overflow];
1911 core_stats->rx_errors = (core_stats->rx_length_errors +
1912 core_stats->rx_crc_errors +
1913 core_stats->rx_frame_errors);
Daniel Pieczkod7788192015-06-02 11:39:20 +01001914 }
1915
1916 return stats_count;
1917}
1918
1919static int efx_ef10_try_update_nic_stats_pf(struct efx_nic *efx)
Ben Hutchings8127d662013-08-29 19:19:29 +01001920{
1921 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Edward Cree4bae9132013-09-27 18:52:49 +01001922 DECLARE_BITMAP(mask, EF10_STAT_COUNT);
Ben Hutchings8127d662013-08-29 19:19:29 +01001923 __le64 generation_start, generation_end;
1924 u64 *stats = nic_data->stats;
1925 __le64 *dma_stats;
1926
Edward Cree4bae9132013-09-27 18:52:49 +01001927 efx_ef10_get_stat_mask(efx, mask);
1928
Ben Hutchings8127d662013-08-29 19:19:29 +01001929 dma_stats = efx->stats_buffer.addr;
Ben Hutchings8127d662013-08-29 19:19:29 +01001930
Edward Creec1be4822017-12-21 09:00:26 +00001931 generation_end = dma_stats[efx->num_mac_stats - 1];
Ben Hutchings8127d662013-08-29 19:19:29 +01001932 if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
1933 return 0;
1934 rmb();
Edward Cree4bae9132013-09-27 18:52:49 +01001935 efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask,
Ben Hutchings8127d662013-08-29 19:19:29 +01001936 stats, efx->stats_buffer.addr, false);
Jon Cooperd546a892013-09-27 18:26:30 +01001937 rmb();
Ben Hutchings8127d662013-08-29 19:19:29 +01001938 generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
1939 if (generation_end != generation_start)
1940 return -EAGAIN;
1941
1942 /* Update derived statistics */
Daniel Pieczkoe80ca0132015-06-02 11:38:34 +01001943 efx_nic_fix_nodesc_drop_stat(efx,
1944 &stats[EF10_STAT_port_rx_nodesc_drops]);
1945 stats[EF10_STAT_port_rx_good_bytes] =
1946 stats[EF10_STAT_port_rx_bytes] -
1947 stats[EF10_STAT_port_rx_bytes_minus_good_bytes];
1948 efx_update_diff_stat(&stats[EF10_STAT_port_rx_bad_bytes],
1949 stats[EF10_STAT_port_rx_bytes_minus_good_bytes]);
Edward Creee4d112e2014-07-15 11:58:12 +01001950 efx_update_sw_stats(efx, stats);
Ben Hutchings8127d662013-08-29 19:19:29 +01001951 return 0;
1952}
1953
1954
Daniel Pieczkod7788192015-06-02 11:39:20 +01001955static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
1956 struct rtnl_link_stats64 *core_stats)
Ben Hutchings8127d662013-08-29 19:19:29 +01001957{
Ben Hutchings8127d662013-08-29 19:19:29 +01001958 int retry;
1959
1960 /* If we're unlucky enough to read statistics during the DMA, wait
1961 * up to 10ms for it to finish (typically takes <500us)
1962 */
1963 for (retry = 0; retry < 100; ++retry) {
Daniel Pieczkod7788192015-06-02 11:39:20 +01001964 if (efx_ef10_try_update_nic_stats_pf(efx) == 0)
Ben Hutchings8127d662013-08-29 19:19:29 +01001965 break;
1966 udelay(100);
1967 }
1968
Daniel Pieczkod7788192015-06-02 11:39:20 +01001969 return efx_ef10_update_stats_common(efx, full_stats, core_stats);
1970}
1971
1972static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx)
1973{
1974 MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
1975 struct efx_ef10_nic_data *nic_data = efx->nic_data;
1976 DECLARE_BITMAP(mask, EF10_STAT_COUNT);
1977 __le64 generation_start, generation_end;
1978 u64 *stats = nic_data->stats;
Edward Creec1be4822017-12-21 09:00:26 +00001979 u32 dma_len = efx->num_mac_stats * sizeof(u64);
Daniel Pieczkod7788192015-06-02 11:39:20 +01001980 struct efx_buffer stats_buf;
1981 __le64 *dma_stats;
1982 int rc;
1983
Daniel Pieczkof00bf232015-06-02 11:40:18 +01001984 spin_unlock_bh(&efx->stats_lock);
1985
1986 if (in_interrupt()) {
1987 /* If in atomic context, cannot update stats. Just update the
1988 * software stats and return so the caller can continue.
1989 */
1990 spin_lock_bh(&efx->stats_lock);
1991 efx_update_sw_stats(efx, stats);
1992 return 0;
1993 }
1994
Daniel Pieczkod7788192015-06-02 11:39:20 +01001995 efx_ef10_get_stat_mask(efx, mask);
1996
1997 rc = efx_nic_alloc_buffer(efx, &stats_buf, dma_len, GFP_ATOMIC);
Daniel Pieczkof00bf232015-06-02 11:40:18 +01001998 if (rc) {
1999 spin_lock_bh(&efx->stats_lock);
Daniel Pieczkod7788192015-06-02 11:39:20 +01002000 return rc;
Daniel Pieczkof00bf232015-06-02 11:40:18 +01002001 }
Daniel Pieczkod7788192015-06-02 11:39:20 +01002002
2003 dma_stats = stats_buf.addr;
Edward Creec1be4822017-12-21 09:00:26 +00002004 dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
Daniel Pieczkod7788192015-06-02 11:39:20 +01002005
2006 MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, stats_buf.dma_addr);
2007 MCDI_POPULATE_DWORD_1(inbuf, MAC_STATS_IN_CMD,
Daniel Pieczko0fc95fc2015-06-02 11:39:33 +01002008 MAC_STATS_IN_DMA, 1);
Daniel Pieczkod7788192015-06-02 11:39:20 +01002009 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
2010 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
2011
Daniel Pieczko6dd48592015-06-02 11:39:49 +01002012 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
2013 NULL, 0, NULL);
Daniel Pieczkod7788192015-06-02 11:39:20 +01002014 spin_lock_bh(&efx->stats_lock);
Daniel Pieczko6dd48592015-06-02 11:39:49 +01002015 if (rc) {
2016 /* Expect ENOENT if DMA queues have not been set up */
2017 if (rc != -ENOENT || atomic_read(&efx->active_queues))
2018 efx_mcdi_display_error(efx, MC_CMD_MAC_STATS,
2019 sizeof(inbuf), NULL, 0, rc);
Daniel Pieczkod7788192015-06-02 11:39:20 +01002020 goto out;
Daniel Pieczko6dd48592015-06-02 11:39:49 +01002021 }
Daniel Pieczkod7788192015-06-02 11:39:20 +01002022
Edward Creec1be4822017-12-21 09:00:26 +00002023 generation_end = dma_stats[efx->num_mac_stats - 1];
Daniel Pieczko0fc95fc2015-06-02 11:39:33 +01002024 if (generation_end == EFX_MC_STATS_GENERATION_INVALID) {
2025 WARN_ON_ONCE(1);
Daniel Pieczkod7788192015-06-02 11:39:20 +01002026 goto out;
Daniel Pieczko0fc95fc2015-06-02 11:39:33 +01002027 }
Daniel Pieczkod7788192015-06-02 11:39:20 +01002028 rmb();
2029 efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask,
2030 stats, stats_buf.addr, false);
2031 rmb();
2032 generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
2033 if (generation_end != generation_start) {
2034 rc = -EAGAIN;
2035 goto out;
Ben Hutchings8127d662013-08-29 19:19:29 +01002036 }
2037
Daniel Pieczkod7788192015-06-02 11:39:20 +01002038 efx_update_sw_stats(efx, stats);
2039out:
2040 efx_nic_free_buffer(efx, &stats_buf);
2041 return rc;
2042}
Ben Hutchings8127d662013-08-29 19:19:29 +01002043
Daniel Pieczkod7788192015-06-02 11:39:20 +01002044static size_t efx_ef10_update_stats_vf(struct efx_nic *efx, u64 *full_stats,
2045 struct rtnl_link_stats64 *core_stats)
2046{
2047 if (efx_ef10_try_update_nic_stats_vf(efx))
2048 return 0;
2049
2050 return efx_ef10_update_stats_common(efx, full_stats, core_stats);
Ben Hutchings8127d662013-08-29 19:19:29 +01002051}
2052
2053static void efx_ef10_push_irq_moderation(struct efx_channel *channel)
2054{
2055 struct efx_nic *efx = channel->efx;
Bert Kenward539de7c2016-08-11 13:02:09 +01002056 unsigned int mode, usecs;
Ben Hutchings8127d662013-08-29 19:19:29 +01002057 efx_dword_t timer_cmd;
2058
Bert Kenward539de7c2016-08-11 13:02:09 +01002059 if (channel->irq_moderation_us) {
Ben Hutchings8127d662013-08-29 19:19:29 +01002060 mode = 3;
Bert Kenward539de7c2016-08-11 13:02:09 +01002061 usecs = channel->irq_moderation_us;
Ben Hutchings8127d662013-08-29 19:19:29 +01002062 } else {
2063 mode = 0;
Bert Kenward539de7c2016-08-11 13:02:09 +01002064 usecs = 0;
Ben Hutchings8127d662013-08-29 19:19:29 +01002065 }
2066
Bert Kenward539de7c2016-08-11 13:02:09 +01002067 if (EFX_EF10_WORKAROUND_61265(efx)) {
2068 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_EVQ_TMR_IN_LEN);
2069 unsigned int ns = usecs * 1000;
2070
2071 MCDI_SET_DWORD(inbuf, SET_EVQ_TMR_IN_INSTANCE,
2072 channel->channel);
2073 MCDI_SET_DWORD(inbuf, SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS, ns);
2074 MCDI_SET_DWORD(inbuf, SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS, ns);
2075 MCDI_SET_DWORD(inbuf, SET_EVQ_TMR_IN_TMR_MODE, mode);
2076
2077 efx_mcdi_rpc_async(efx, MC_CMD_SET_EVQ_TMR,
2078 inbuf, sizeof(inbuf), 0, NULL, 0);
2079 } else if (EFX_EF10_WORKAROUND_35388(efx)) {
2080 unsigned int ticks = efx_usecs_to_ticks(efx, usecs);
2081
Ben Hutchings8127d662013-08-29 19:19:29 +01002082 EFX_POPULATE_DWORD_3(timer_cmd, ERF_DD_EVQ_IND_TIMER_FLAGS,
2083 EFE_DD_EVQ_IND_TIMER_FLAGS,
2084 ERF_DD_EVQ_IND_TIMER_MODE, mode,
Bert Kenward539de7c2016-08-11 13:02:09 +01002085 ERF_DD_EVQ_IND_TIMER_VAL, ticks);
Ben Hutchings8127d662013-08-29 19:19:29 +01002086 efx_writed_page(efx, &timer_cmd, ER_DD_EVQ_INDIRECT,
2087 channel->channel);
2088 } else {
Bert Kenward539de7c2016-08-11 13:02:09 +01002089 unsigned int ticks = efx_usecs_to_ticks(efx, usecs);
2090
Bert Kenward0bc959a2017-12-18 16:57:41 +00002091 EFX_POPULATE_DWORD_3(timer_cmd, ERF_DZ_TC_TIMER_MODE, mode,
2092 ERF_DZ_TC_TIMER_VAL, ticks,
2093 ERF_FZ_TC_TMR_REL_VAL, ticks);
Ben Hutchings8127d662013-08-29 19:19:29 +01002094 efx_writed_page(efx, &timer_cmd, ER_DZ_EVQ_TMR,
2095 channel->channel);
2096 }
2097}
2098
Shradha Shah02246a72015-05-06 00:58:14 +01002099static void efx_ef10_get_wol_vf(struct efx_nic *efx,
2100 struct ethtool_wolinfo *wol) {}
2101
2102static int efx_ef10_set_wol_vf(struct efx_nic *efx, u32 type)
2103{
2104 return -EOPNOTSUPP;
2105}
2106
Ben Hutchings8127d662013-08-29 19:19:29 +01002107static void efx_ef10_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol)
2108{
2109 wol->supported = 0;
2110 wol->wolopts = 0;
2111 memset(&wol->sopass, 0, sizeof(wol->sopass));
2112}
2113
2114static int efx_ef10_set_wol(struct efx_nic *efx, u32 type)
2115{
2116 if (type != 0)
2117 return -EINVAL;
2118 return 0;
2119}
2120
2121static void efx_ef10_mcdi_request(struct efx_nic *efx,
2122 const efx_dword_t *hdr, size_t hdr_len,
2123 const efx_dword_t *sdu, size_t sdu_len)
2124{
2125 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2126 u8 *pdu = nic_data->mcdi_buf.addr;
2127
2128 memcpy(pdu, hdr, hdr_len);
2129 memcpy(pdu + hdr_len, sdu, sdu_len);
2130 wmb();
2131
2132 /* The hardware provides 'low' and 'high' (doorbell) registers
2133 * for passing the 64-bit address of an MCDI request to
2134 * firmware. However the dwords are swapped by firmware. The
2135 * least significant bits of the doorbell are then 0 for all
2136 * MCDI requests due to alignment.
2137 */
2138 _efx_writed(efx, cpu_to_le32((u64)nic_data->mcdi_buf.dma_addr >> 32),
2139 ER_DZ_MC_DB_LWRD);
2140 _efx_writed(efx, cpu_to_le32((u32)nic_data->mcdi_buf.dma_addr),
2141 ER_DZ_MC_DB_HWRD);
2142}
2143
2144static bool efx_ef10_mcdi_poll_response(struct efx_nic *efx)
2145{
2146 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2147 const efx_dword_t hdr = *(const efx_dword_t *)nic_data->mcdi_buf.addr;
2148
2149 rmb();
2150 return EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE);
2151}
2152
2153static void
2154efx_ef10_mcdi_read_response(struct efx_nic *efx, efx_dword_t *outbuf,
2155 size_t offset, size_t outlen)
2156{
2157 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2158 const u8 *pdu = nic_data->mcdi_buf.addr;
2159
2160 memcpy(outbuf, pdu + offset, outlen);
2161}
2162
Daniel Pieczkoc577e592015-10-09 10:40:35 +01002163static void efx_ef10_mcdi_reboot_detected(struct efx_nic *efx)
2164{
2165 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2166
2167 /* All our allocations have been reset */
2168 efx_ef10_reset_mc_allocations(efx);
2169
2170 /* The datapath firmware might have been changed */
2171 nic_data->must_check_datapath_caps = true;
2172
2173 /* MAC statistics have been cleared on the NIC; clear the local
2174 * statistic that we update with efx_update_diff_stat().
2175 */
2176 nic_data->stats[EF10_STAT_port_rx_bad_bytes] = 0;
2177}
2178
Ben Hutchings8127d662013-08-29 19:19:29 +01002179static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx)
2180{
2181 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2182 int rc;
2183
2184 rc = efx_ef10_get_warm_boot_count(efx);
2185 if (rc < 0) {
2186 /* The firmware is presumably in the process of
2187 * rebooting. However, we are supposed to report each
2188 * reboot just once, so we must only do that once we
2189 * can read and store the updated warm boot count.
2190 */
2191 return 0;
2192 }
2193
2194 if (rc == nic_data->warm_boot_count)
2195 return 0;
2196
2197 nic_data->warm_boot_count = rc;
Daniel Pieczkoc577e592015-10-09 10:40:35 +01002198 efx_ef10_mcdi_reboot_detected(efx);
Ben Hutchings869070c2013-09-05 22:46:10 +01002199
Ben Hutchings8127d662013-08-29 19:19:29 +01002200 return -EIO;
2201}
2202
2203/* Handle an MSI interrupt
2204 *
2205 * Handle an MSI hardware interrupt. This routine schedules event
2206 * queue processing. No interrupt acknowledgement cycle is necessary.
2207 * Also, we never need to check that the interrupt is for us, since
2208 * MSI interrupts cannot be shared.
2209 */
2210static irqreturn_t efx_ef10_msi_interrupt(int irq, void *dev_id)
2211{
2212 struct efx_msi_context *context = dev_id;
2213 struct efx_nic *efx = context->efx;
2214
2215 netif_vdbg(efx, intr, efx->net_dev,
2216 "IRQ %d on CPU %d\n", irq, raw_smp_processor_id());
2217
Mark Rutland6aa7de02017-10-23 14:07:29 -07002218 if (likely(READ_ONCE(efx->irq_soft_enabled))) {
Ben Hutchings8127d662013-08-29 19:19:29 +01002219 /* Note test interrupts */
2220 if (context->index == efx->irq_level)
2221 efx->last_irq_cpu = raw_smp_processor_id();
2222
2223 /* Schedule processing of the channel */
2224 efx_schedule_channel_irq(efx->channel[context->index]);
2225 }
2226
2227 return IRQ_HANDLED;
2228}
2229
2230static irqreturn_t efx_ef10_legacy_interrupt(int irq, void *dev_id)
2231{
2232 struct efx_nic *efx = dev_id;
Mark Rutland6aa7de02017-10-23 14:07:29 -07002233 bool soft_enabled = READ_ONCE(efx->irq_soft_enabled);
Ben Hutchings8127d662013-08-29 19:19:29 +01002234 struct efx_channel *channel;
2235 efx_dword_t reg;
2236 u32 queues;
2237
2238 /* Read the ISR which also ACKs the interrupts */
2239 efx_readd(efx, &reg, ER_DZ_BIU_INT_ISR);
2240 queues = EFX_DWORD_FIELD(reg, ERF_DZ_ISR_REG);
2241
2242 if (queues == 0)
2243 return IRQ_NONE;
2244
2245 if (likely(soft_enabled)) {
2246 /* Note test interrupts */
2247 if (queues & (1U << efx->irq_level))
2248 efx->last_irq_cpu = raw_smp_processor_id();
2249
2250 efx_for_each_channel(channel, efx) {
2251 if (queues & 1)
2252 efx_schedule_channel_irq(channel);
2253 queues >>= 1;
2254 }
2255 }
2256
2257 netif_vdbg(efx, intr, efx->net_dev,
2258 "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
2259 irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
2260
2261 return IRQ_HANDLED;
2262}
2263
Jon Cooper942e2982016-08-26 15:13:30 +01002264static int efx_ef10_irq_test_generate(struct efx_nic *efx)
Ben Hutchings8127d662013-08-29 19:19:29 +01002265{
2266 MCDI_DECLARE_BUF(inbuf, MC_CMD_TRIGGER_INTERRUPT_IN_LEN);
2267
Jon Cooper942e2982016-08-26 15:13:30 +01002268 if (efx_mcdi_set_workaround(efx, MC_CMD_WORKAROUND_BUG41750, true,
2269 NULL) == 0)
2270 return -ENOTSUPP;
2271
Ben Hutchings8127d662013-08-29 19:19:29 +01002272 BUILD_BUG_ON(MC_CMD_TRIGGER_INTERRUPT_OUT_LEN != 0);
2273
2274 MCDI_SET_DWORD(inbuf, TRIGGER_INTERRUPT_IN_INTR_LEVEL, efx->irq_level);
Jon Cooper942e2982016-08-26 15:13:30 +01002275 return efx_mcdi_rpc(efx, MC_CMD_TRIGGER_INTERRUPT,
Ben Hutchings8127d662013-08-29 19:19:29 +01002276 inbuf, sizeof(inbuf), NULL, 0, NULL);
2277}
2278
2279static int efx_ef10_tx_probe(struct efx_tx_queue *tx_queue)
2280{
2281 return efx_nic_alloc_buffer(tx_queue->efx, &tx_queue->txd.buf,
2282 (tx_queue->ptr_mask + 1) *
2283 sizeof(efx_qword_t),
2284 GFP_KERNEL);
2285}
2286
2287/* This writes to the TX_DESC_WPTR and also pushes data */
2288static inline void efx_ef10_push_tx_desc(struct efx_tx_queue *tx_queue,
2289 const efx_qword_t *txd)
2290{
2291 unsigned int write_ptr;
2292 efx_oword_t reg;
2293
2294 write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
2295 EFX_POPULATE_OWORD_1(reg, ERF_DZ_TX_DESC_WPTR, write_ptr);
2296 reg.qword[0] = *txd;
2297 efx_writeo_page(tx_queue->efx, &reg,
2298 ER_DZ_TX_DESC_UPD, tx_queue->queue);
2299}
2300
Bert Kenwarde9117e52016-11-17 10:51:54 +00002301/* Add Firmware-Assisted TSO v2 option descriptors to a queue.
2302 */
2303static int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue,
2304 struct sk_buff *skb,
2305 bool *data_mapped)
2306{
2307 struct efx_tx_buffer *buffer;
2308 struct tcphdr *tcp;
2309 struct iphdr *ip;
2310
2311 u16 ipv4_id;
2312 u32 seqnum;
2313 u32 mss;
2314
Edward Creee01b16a2016-12-02 15:51:33 +00002315 EFX_WARN_ON_ONCE_PARANOID(tx_queue->tso_version != 2);
Bert Kenwarde9117e52016-11-17 10:51:54 +00002316
2317 mss = skb_shinfo(skb)->gso_size;
2318
2319 if (unlikely(mss < 4)) {
2320 WARN_ONCE(1, "MSS of %u is too small for TSO v2\n", mss);
2321 return -EINVAL;
2322 }
2323
2324 ip = ip_hdr(skb);
2325 if (ip->version == 4) {
2326 /* Modify IPv4 header if needed. */
2327 ip->tot_len = 0;
2328 ip->check = 0;
Edward Cree6d431312017-03-03 15:22:27 +00002329 ipv4_id = ntohs(ip->id);
Bert Kenwarde9117e52016-11-17 10:51:54 +00002330 } else {
2331 /* Modify IPv6 header if needed. */
2332 struct ipv6hdr *ipv6 = ipv6_hdr(skb);
2333
2334 ipv6->payload_len = 0;
2335 ipv4_id = 0;
2336 }
2337
2338 tcp = tcp_hdr(skb);
2339 seqnum = ntohl(tcp->seq);
2340
2341 buffer = efx_tx_queue_get_insert_buffer(tx_queue);
2342
2343 buffer->flags = EFX_TX_BUF_OPTION;
2344 buffer->len = 0;
2345 buffer->unmap_len = 0;
2346 EFX_POPULATE_QWORD_5(buffer->option,
2347 ESF_DZ_TX_DESC_IS_OPT, 1,
2348 ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_TSO,
2349 ESF_DZ_TX_TSO_OPTION_TYPE,
2350 ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A,
2351 ESF_DZ_TX_TSO_IP_ID, ipv4_id,
2352 ESF_DZ_TX_TSO_TCP_SEQNO, seqnum
2353 );
2354 ++tx_queue->insert_count;
2355
2356 buffer = efx_tx_queue_get_insert_buffer(tx_queue);
2357
2358 buffer->flags = EFX_TX_BUF_OPTION;
2359 buffer->len = 0;
2360 buffer->unmap_len = 0;
2361 EFX_POPULATE_QWORD_4(buffer->option,
2362 ESF_DZ_TX_DESC_IS_OPT, 1,
2363 ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_TSO,
2364 ESF_DZ_TX_TSO_OPTION_TYPE,
2365 ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B,
2366 ESF_DZ_TX_TSO_TCP_MSS, mss
2367 );
2368 ++tx_queue->insert_count;
2369
2370 return 0;
2371}
2372
Edward Cree46d1efd2016-11-17 10:52:36 +00002373static u32 efx_ef10_tso_versions(struct efx_nic *efx)
2374{
2375 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2376 u32 tso_versions = 0;
2377
2378 if (nic_data->datapath_caps &
2379 (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))
2380 tso_versions |= BIT(1);
2381 if (nic_data->datapath_caps2 &
2382 (1 << MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_LBN))
2383 tso_versions |= BIT(2);
2384 return tso_versions;
2385}
2386
Ben Hutchings8127d662013-08-29 19:19:29 +01002387static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
2388{
2389 MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
2390 EFX_BUF_SIZE));
Ben Hutchings8127d662013-08-29 19:19:29 +01002391 bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
2392 size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE;
2393 struct efx_channel *channel = tx_queue->channel;
2394 struct efx_nic *efx = tx_queue->efx;
Daniel Pieczko45b24492015-05-06 00:57:14 +01002395 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Bert Kenwarde9117e52016-11-17 10:51:54 +00002396 bool tso_v2 = false;
Jon Cooperaa09a3d2015-05-20 11:10:41 +01002397 size_t inlen;
Ben Hutchings8127d662013-08-29 19:19:29 +01002398 dma_addr_t dma_addr;
2399 efx_qword_t *txd;
2400 int rc;
2401 int i;
Jon Cooperaa09a3d2015-05-20 11:10:41 +01002402 BUILD_BUG_ON(MC_CMD_INIT_TXQ_OUT_LEN != 0);
Ben Hutchings8127d662013-08-29 19:19:29 +01002403
Bert Kenwarde9117e52016-11-17 10:51:54 +00002404 /* TSOv2 is a limited resource that can only be configured on a limited
2405 * number of queues. TSO without checksum offload is not really a thing,
2406 * so we only enable it for those queues.
Martin Habetsb9b603d42018-01-25 17:24:43 +00002407 * TSOv2 cannot be used with Hardware timestamping.
Bert Kenwarde9117e52016-11-17 10:51:54 +00002408 */
2409 if (csum_offload && (nic_data->datapath_caps2 &
Martin Habetsb9b603d42018-01-25 17:24:43 +00002410 (1 << MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_LBN)) &&
2411 !tx_queue->timestamping) {
Bert Kenwarde9117e52016-11-17 10:51:54 +00002412 tso_v2 = true;
2413 netif_dbg(efx, hw, efx->net_dev, "Using TSOv2 for channel %u\n",
2414 channel->channel);
2415 }
2416
Ben Hutchings8127d662013-08-29 19:19:29 +01002417 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1);
2418 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel);
2419 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue);
2420 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue);
Ben Hutchings8127d662013-08-29 19:19:29 +01002421 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0);
Daniel Pieczko45b24492015-05-06 00:57:14 +01002422 MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, nic_data->vport_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01002423
2424 dma_addr = tx_queue->txd.buf.dma_addr;
2425
2426 netif_dbg(efx, hw, efx->net_dev, "pushing TXQ %d. %zu entries (%llx)\n",
2427 tx_queue->queue, entries, (u64)dma_addr);
2428
2429 for (i = 0; i < entries; ++i) {
2430 MCDI_SET_ARRAY_QWORD(inbuf, INIT_TXQ_IN_DMA_ADDR, i, dma_addr);
2431 dma_addr += EFX_BUF_SIZE;
2432 }
2433
2434 inlen = MC_CMD_INIT_TXQ_IN_LEN(entries);
2435
Edward Creee638ee12016-11-17 10:52:07 +00002436 do {
Martin Habetsb9b603d42018-01-25 17:24:43 +00002437 MCDI_POPULATE_DWORD_4(inbuf, INIT_TXQ_IN_FLAGS,
Edward Creee638ee12016-11-17 10:52:07 +00002438 /* This flag was removed from mcdi_pcol.h for
2439 * the non-_EXT version of INIT_TXQ. However,
2440 * firmware still honours it.
2441 */
2442 INIT_TXQ_EXT_IN_FLAG_TSOV2_EN, tso_v2,
2443 INIT_TXQ_IN_FLAG_IP_CSUM_DIS, !csum_offload,
Martin Habetsb9b603d42018-01-25 17:24:43 +00002444 INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, !csum_offload,
2445 INIT_TXQ_EXT_IN_FLAG_TIMESTAMP,
2446 tx_queue->timestamping);
Edward Creee638ee12016-11-17 10:52:07 +00002447
2448 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_INIT_TXQ, inbuf, inlen,
2449 NULL, 0, NULL);
2450 if (rc == -ENOSPC && tso_v2) {
2451 /* Retry without TSOv2 if we're short on contexts. */
2452 tso_v2 = false;
2453 netif_warn(efx, probe, efx->net_dev,
2454 "TSOv2 context not available to segment in hardware. TCP performance may be reduced.\n");
2455 } else if (rc) {
2456 efx_mcdi_display_error(efx, MC_CMD_INIT_TXQ,
2457 MC_CMD_INIT_TXQ_EXT_IN_LEN,
2458 NULL, 0, rc);
2459 goto fail;
2460 }
2461 } while (rc);
Ben Hutchings8127d662013-08-29 19:19:29 +01002462
2463 /* A previous user of this TX queue might have set us up the
2464 * bomb by writing a descriptor to the TX push collector but
2465 * not the doorbell. (Each collector belongs to a port, not a
2466 * queue or function, so cannot easily be reset.) We must
2467 * attempt to push a no-op descriptor in its place.
2468 */
2469 tx_queue->buffer[0].flags = EFX_TX_BUF_OPTION;
2470 tx_queue->insert_count = 1;
2471 txd = efx_tx_desc(tx_queue, 0);
Martin Habetsb9b603d42018-01-25 17:24:43 +00002472 EFX_POPULATE_QWORD_5(*txd,
Ben Hutchings8127d662013-08-29 19:19:29 +01002473 ESF_DZ_TX_DESC_IS_OPT, true,
2474 ESF_DZ_TX_OPTION_TYPE,
2475 ESE_DZ_TX_OPTION_DESC_CRC_CSUM,
2476 ESF_DZ_TX_OPTION_UDP_TCP_CSUM, csum_offload,
Martin Habetsb9b603d42018-01-25 17:24:43 +00002477 ESF_DZ_TX_OPTION_IP_CSUM, csum_offload,
2478 ESF_DZ_TX_TIMESTAMP, tx_queue->timestamping);
Ben Hutchings8127d662013-08-29 19:19:29 +01002479 tx_queue->write_count = 1;
Bert Kenward93171b12015-11-30 09:05:35 +00002480
Bert Kenwarde9117e52016-11-17 10:51:54 +00002481 if (tso_v2) {
2482 tx_queue->handle_tso = efx_ef10_tx_tso_desc;
2483 tx_queue->tso_version = 2;
2484 } else if (nic_data->datapath_caps &
2485 (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN)) {
Bert Kenward93171b12015-11-30 09:05:35 +00002486 tx_queue->tso_version = 1;
2487 }
2488
Ben Hutchings8127d662013-08-29 19:19:29 +01002489 wmb();
2490 efx_ef10_push_tx_desc(tx_queue, txd);
2491
2492 return;
2493
2494fail:
Ben Hutchings48ce5632013-11-01 16:42:44 +00002495 netdev_WARN(efx->net_dev, "failed to initialise TXQ %d\n",
2496 tx_queue->queue);
Ben Hutchings8127d662013-08-29 19:19:29 +01002497}
2498
2499static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
2500{
2501 MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_TXQ_IN_LEN);
Jon Cooperaa09a3d2015-05-20 11:10:41 +01002502 MCDI_DECLARE_BUF_ERR(outbuf);
Ben Hutchings8127d662013-08-29 19:19:29 +01002503 struct efx_nic *efx = tx_queue->efx;
2504 size_t outlen;
2505 int rc;
2506
2507 MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE,
2508 tx_queue->queue);
2509
Edward Cree1e0b8122013-05-31 18:36:12 +01002510 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf),
Ben Hutchings8127d662013-08-29 19:19:29 +01002511 outbuf, sizeof(outbuf), &outlen);
2512
2513 if (rc && rc != -EALREADY)
2514 goto fail;
2515
2516 return;
2517
2518fail:
Edward Cree1e0b8122013-05-31 18:36:12 +01002519 efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN,
2520 outbuf, outlen, rc);
Ben Hutchings8127d662013-08-29 19:19:29 +01002521}
2522
2523static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue)
2524{
2525 efx_nic_free_buffer(tx_queue->efx, &tx_queue->txd.buf);
2526}
2527
2528/* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */
2529static inline void efx_ef10_notify_tx_desc(struct efx_tx_queue *tx_queue)
2530{
2531 unsigned int write_ptr;
2532 efx_dword_t reg;
2533
2534 write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
2535 EFX_POPULATE_DWORD_1(reg, ERF_DZ_TX_DESC_WPTR_DWORD, write_ptr);
2536 efx_writed_page(tx_queue->efx, &reg,
2537 ER_DZ_TX_DESC_UPD_DWORD, tx_queue->queue);
2538}
2539
Bert Kenwarde9117e52016-11-17 10:51:54 +00002540#define EFX_EF10_MAX_TX_DESCRIPTOR_LEN 0x3fff
2541
2542static unsigned int efx_ef10_tx_limit_len(struct efx_tx_queue *tx_queue,
2543 dma_addr_t dma_addr, unsigned int len)
2544{
2545 if (len > EFX_EF10_MAX_TX_DESCRIPTOR_LEN) {
2546 /* If we need to break across multiple descriptors we should
2547 * stop at a page boundary. This assumes the length limit is
2548 * greater than the page size.
2549 */
2550 dma_addr_t end = dma_addr + EFX_EF10_MAX_TX_DESCRIPTOR_LEN;
2551
2552 BUILD_BUG_ON(EFX_EF10_MAX_TX_DESCRIPTOR_LEN < EFX_PAGE_SIZE);
2553 len = (end & (~(EFX_PAGE_SIZE - 1))) - dma_addr;
2554 }
2555
2556 return len;
2557}
2558
Ben Hutchings8127d662013-08-29 19:19:29 +01002559static void efx_ef10_tx_write(struct efx_tx_queue *tx_queue)
2560{
2561 unsigned int old_write_count = tx_queue->write_count;
2562 struct efx_tx_buffer *buffer;
2563 unsigned int write_ptr;
2564 efx_qword_t *txd;
2565
Martin Habetsb2663a42015-11-02 12:51:31 +00002566 tx_queue->xmit_more_available = false;
2567 if (unlikely(tx_queue->write_count == tx_queue->insert_count))
2568 return;
Ben Hutchings8127d662013-08-29 19:19:29 +01002569
2570 do {
2571 write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
2572 buffer = &tx_queue->buffer[write_ptr];
2573 txd = efx_tx_desc(tx_queue, write_ptr);
2574 ++tx_queue->write_count;
2575
2576 /* Create TX descriptor ring entry */
2577 if (buffer->flags & EFX_TX_BUF_OPTION) {
2578 *txd = buffer->option;
Edward Creede1deff2017-01-13 21:20:14 +00002579 if (EFX_QWORD_FIELD(*txd, ESF_DZ_TX_OPTION_TYPE) == 1)
2580 /* PIO descriptor */
2581 tx_queue->packet_write_count = tx_queue->write_count;
Ben Hutchings8127d662013-08-29 19:19:29 +01002582 } else {
Edward Creede1deff2017-01-13 21:20:14 +00002583 tx_queue->packet_write_count = tx_queue->write_count;
Ben Hutchings8127d662013-08-29 19:19:29 +01002584 BUILD_BUG_ON(EFX_TX_BUF_CONT != 1);
2585 EFX_POPULATE_QWORD_3(
2586 *txd,
2587 ESF_DZ_TX_KER_CONT,
2588 buffer->flags & EFX_TX_BUF_CONT,
2589 ESF_DZ_TX_KER_BYTE_CNT, buffer->len,
2590 ESF_DZ_TX_KER_BUF_ADDR, buffer->dma_addr);
2591 }
2592 } while (tx_queue->write_count != tx_queue->insert_count);
2593
2594 wmb(); /* Ensure descriptors are written before they are fetched */
2595
2596 if (efx_nic_may_push_tx_desc(tx_queue, old_write_count)) {
2597 txd = efx_tx_desc(tx_queue,
2598 old_write_count & tx_queue->ptr_mask);
2599 efx_ef10_push_tx_desc(tx_queue, txd);
2600 ++tx_queue->pushes;
2601 } else {
2602 efx_ef10_notify_tx_desc(tx_queue);
2603 }
2604}
2605
Edward Creea33a4c72016-11-03 22:12:27 +00002606#define RSS_MODE_HASH_ADDRS (1 << RSS_MODE_HASH_SRC_ADDR_LBN |\
2607 1 << RSS_MODE_HASH_DST_ADDR_LBN)
2608#define RSS_MODE_HASH_PORTS (1 << RSS_MODE_HASH_SRC_PORT_LBN |\
2609 1 << RSS_MODE_HASH_DST_PORT_LBN)
2610#define RSS_CONTEXT_FLAGS_DEFAULT (1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN |\
2611 1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN |\
2612 1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_LBN |\
2613 1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_LBN |\
2614 (RSS_MODE_HASH_ADDRS | RSS_MODE_HASH_PORTS) << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_LBN |\
2615 RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN |\
2616 RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_LBN |\
2617 (RSS_MODE_HASH_ADDRS | RSS_MODE_HASH_PORTS) << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_LBN |\
2618 RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN |\
2619 RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_LBN)
2620
2621static int efx_ef10_get_rss_flags(struct efx_nic *efx, u32 context, u32 *flags)
2622{
2623 /* Firmware had a bug (sfc bug 61952) where it would not actually
2624 * fill in the flags field in the response to MC_CMD_RSS_CONTEXT_GET_FLAGS.
2625 * This meant that it would always contain whatever was previously
2626 * in the MCDI buffer. Fortunately, all firmware versions with
2627 * this bug have the same default flags value for a newly-allocated
2628 * RSS context, and the only time we want to get the flags is just
2629 * after allocating. Moreover, the response has a 32-bit hole
2630 * where the context ID would be in the request, so we can use an
2631 * overlength buffer in the request and pre-fill the flags field
2632 * with what we believe the default to be. Thus if the firmware
2633 * has the bug, it will leave our pre-filled value in the flags
2634 * field of the response, and we will get the right answer.
2635 *
2636 * However, this does mean that this function should NOT be used if
2637 * the RSS context flags might not be their defaults - it is ONLY
2638 * reliably correct for a newly-allocated RSS context.
2639 */
2640 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN);
2641 MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN);
2642 size_t outlen;
2643 int rc;
2644
2645 /* Check we have a hole for the context ID */
2646 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_LEN != MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST);
2647 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID, context);
2648 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_FLAGS_OUT_FLAGS,
2649 RSS_CONTEXT_FLAGS_DEFAULT);
2650 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_FLAGS, inbuf,
2651 sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
2652 if (rc == 0) {
2653 if (outlen < MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN)
2654 rc = -EIO;
2655 else
2656 *flags = MCDI_DWORD(outbuf, RSS_CONTEXT_GET_FLAGS_OUT_FLAGS);
2657 }
2658 return rc;
2659}
2660
2661/* Attempt to enable 4-tuple UDP hashing on the specified RSS context.
2662 * If we fail, we just leave the RSS context at its default hash settings,
2663 * which is safe but may slightly reduce performance.
2664 * Defaults are 4-tuple for TCP and 2-tuple for UDP and other-IP, so we
2665 * just need to set the UDP ports flags (for both IP versions).
2666 */
2667static void efx_ef10_set_rss_flags(struct efx_nic *efx, u32 context)
2668{
2669 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN);
2670 u32 flags;
2671
2672 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN != 0);
2673
2674 if (efx_ef10_get_rss_flags(efx, context, &flags) != 0)
2675 return;
2676 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, context);
2677 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN;
2678 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN;
2679 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, flags);
Edward Creeb718c882016-11-03 22:12:58 +00002680 if (!efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_FLAGS, inbuf, sizeof(inbuf),
2681 NULL, 0, NULL))
2682 /* Succeeded, so UDP 4-tuple is now enabled */
2683 efx->rx_hash_udp_4tuple = true;
Edward Creea33a4c72016-11-03 22:12:27 +00002684}
2685
Jon Cooper267c0152015-05-06 00:59:38 +01002686static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context,
2687 bool exclusive, unsigned *context_size)
Ben Hutchings8127d662013-08-29 19:19:29 +01002688{
2689 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN);
2690 MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
Daniel Pieczko45b24492015-05-06 00:57:14 +01002691 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Ben Hutchings8127d662013-08-29 19:19:29 +01002692 size_t outlen;
2693 int rc;
Jon Cooper267c0152015-05-06 00:59:38 +01002694 u32 alloc_type = exclusive ?
2695 MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE :
2696 MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED;
2697 unsigned rss_spread = exclusive ?
2698 efx->rss_spread :
2699 min(rounddown_pow_of_two(efx->rss_spread),
2700 EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE);
2701
2702 if (!exclusive && rss_spread == 1) {
2703 *context = EFX_EF10_RSS_CONTEXT_INVALID;
2704 if (context_size)
2705 *context_size = 1;
2706 return 0;
2707 }
Ben Hutchings8127d662013-08-29 19:19:29 +01002708
Jon Cooperdcb41232016-04-25 16:51:00 +01002709 if (nic_data->datapath_caps &
2710 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN)
2711 return -EOPNOTSUPP;
2712
Ben Hutchings8127d662013-08-29 19:19:29 +01002713 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
Daniel Pieczko45b24492015-05-06 00:57:14 +01002714 nic_data->vport_id);
Jon Cooper267c0152015-05-06 00:59:38 +01002715 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type);
2716 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, rss_spread);
Ben Hutchings8127d662013-08-29 19:19:29 +01002717
2718 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_ALLOC, inbuf, sizeof(inbuf),
2719 outbuf, sizeof(outbuf), &outlen);
2720 if (rc != 0)
2721 return rc;
2722
2723 if (outlen < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)
2724 return -EIO;
2725
2726 *context = MCDI_DWORD(outbuf, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
2727
Jon Cooper267c0152015-05-06 00:59:38 +01002728 if (context_size)
2729 *context_size = rss_spread;
2730
Edward Creea33a4c72016-11-03 22:12:27 +00002731 if (nic_data->datapath_caps &
2732 1 << MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN)
2733 efx_ef10_set_rss_flags(efx, *context);
2734
Ben Hutchings8127d662013-08-29 19:19:29 +01002735 return 0;
2736}
2737
2738static void efx_ef10_free_rss_context(struct efx_nic *efx, u32 context)
2739{
2740 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_FREE_IN_LEN);
2741 int rc;
2742
2743 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID,
2744 context);
2745
2746 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_FREE, inbuf, sizeof(inbuf),
2747 NULL, 0, NULL);
2748 WARN_ON(rc != 0);
2749}
2750
Jon Cooper267c0152015-05-06 00:59:38 +01002751static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context,
Edward Creef74d1992017-01-17 12:01:53 +00002752 const u32 *rx_indir_table, const u8 *key)
Ben Hutchings8127d662013-08-29 19:19:29 +01002753{
2754 MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN);
2755 MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN);
2756 int i, rc;
2757
2758 MCDI_SET_DWORD(tablebuf, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
2759 context);
2760 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) !=
2761 MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN);
2762
Edward Creef74d1992017-01-17 12:01:53 +00002763 /* This iterates over the length of efx->rx_indir_table, but copies
2764 * bytes from rx_indir_table. That's because the latter is a pointer
2765 * rather than an array, but should have the same length.
2766 * The efx->rx_hash_key loop below is similar.
2767 */
Ben Hutchings8127d662013-08-29 19:19:29 +01002768 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); ++i)
2769 MCDI_PTR(tablebuf,
2770 RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE)[i] =
Jon Cooper267c0152015-05-06 00:59:38 +01002771 (u8) rx_indir_table[i];
Ben Hutchings8127d662013-08-29 19:19:29 +01002772
2773 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_TABLE, tablebuf,
2774 sizeof(tablebuf), NULL, 0, NULL);
2775 if (rc != 0)
2776 return rc;
2777
2778 MCDI_SET_DWORD(keybuf, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
2779 context);
2780 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_hash_key) !=
2781 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2782 for (i = 0; i < ARRAY_SIZE(efx->rx_hash_key); ++i)
Edward Creef74d1992017-01-17 12:01:53 +00002783 MCDI_PTR(keybuf, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY)[i] = key[i];
Ben Hutchings8127d662013-08-29 19:19:29 +01002784
2785 return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_KEY, keybuf,
2786 sizeof(keybuf), NULL, 0, NULL);
2787}
2788
2789static void efx_ef10_rx_free_indir_table(struct efx_nic *efx)
2790{
2791 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2792
2793 if (nic_data->rx_rss_context != EFX_EF10_RSS_CONTEXT_INVALID)
2794 efx_ef10_free_rss_context(efx, nic_data->rx_rss_context);
2795 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
2796}
2797
Jon Cooper267c0152015-05-06 00:59:38 +01002798static int efx_ef10_rx_push_shared_rss_config(struct efx_nic *efx,
2799 unsigned *context_size)
2800{
2801 u32 new_rx_rss_context;
2802 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2803 int rc = efx_ef10_alloc_rss_context(efx, &new_rx_rss_context,
2804 false, context_size);
2805
2806 if (rc != 0)
2807 return rc;
2808
2809 nic_data->rx_rss_context = new_rx_rss_context;
2810 nic_data->rx_rss_context_exclusive = false;
2811 efx_set_default_rx_indir_table(efx);
2812 return 0;
2813}
2814
2815static int efx_ef10_rx_push_exclusive_rss_config(struct efx_nic *efx,
Edward Creef74d1992017-01-17 12:01:53 +00002816 const u32 *rx_indir_table,
2817 const u8 *key)
Ben Hutchings8127d662013-08-29 19:19:29 +01002818{
2819 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2820 int rc;
Jon Cooper267c0152015-05-06 00:59:38 +01002821 u32 new_rx_rss_context;
Ben Hutchings8127d662013-08-29 19:19:29 +01002822
Jon Cooper267c0152015-05-06 00:59:38 +01002823 if (nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID ||
2824 !nic_data->rx_rss_context_exclusive) {
2825 rc = efx_ef10_alloc_rss_context(efx, &new_rx_rss_context,
2826 true, NULL);
2827 if (rc == -EOPNOTSUPP)
2828 return rc;
2829 else if (rc != 0)
2830 goto fail1;
2831 } else {
2832 new_rx_rss_context = nic_data->rx_rss_context;
Ben Hutchings8127d662013-08-29 19:19:29 +01002833 }
2834
Jon Cooper267c0152015-05-06 00:59:38 +01002835 rc = efx_ef10_populate_rss_table(efx, new_rx_rss_context,
Edward Creef74d1992017-01-17 12:01:53 +00002836 rx_indir_table, key);
Ben Hutchings8127d662013-08-29 19:19:29 +01002837 if (rc != 0)
Jon Cooper267c0152015-05-06 00:59:38 +01002838 goto fail2;
Ben Hutchings8127d662013-08-29 19:19:29 +01002839
Jon Cooper267c0152015-05-06 00:59:38 +01002840 if (nic_data->rx_rss_context != new_rx_rss_context)
2841 efx_ef10_rx_free_indir_table(efx);
2842 nic_data->rx_rss_context = new_rx_rss_context;
2843 nic_data->rx_rss_context_exclusive = true;
2844 if (rx_indir_table != efx->rx_indir_table)
2845 memcpy(efx->rx_indir_table, rx_indir_table,
2846 sizeof(efx->rx_indir_table));
Edward Creef74d1992017-01-17 12:01:53 +00002847 if (key != efx->rx_hash_key)
2848 memcpy(efx->rx_hash_key, key, efx->type->rx_hash_key_size);
2849
Jon Cooper267c0152015-05-06 00:59:38 +01002850 return 0;
Ben Hutchings8127d662013-08-29 19:19:29 +01002851
Jon Cooper267c0152015-05-06 00:59:38 +01002852fail2:
2853 if (new_rx_rss_context != nic_data->rx_rss_context)
2854 efx_ef10_free_rss_context(efx, new_rx_rss_context);
2855fail1:
Ben Hutchings8127d662013-08-29 19:19:29 +01002856 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
Jon Cooper267c0152015-05-06 00:59:38 +01002857 return rc;
2858}
2859
Edward Creea707d182017-01-17 12:02:12 +00002860static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx)
2861{
2862 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2863 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN);
2864 MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN);
2865 MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN);
2866 size_t outlen;
2867 int rc, i;
2868
2869 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN !=
2870 MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN);
2871
2872 if (nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID)
2873 return -ENOENT;
2874
2875 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID,
2876 nic_data->rx_rss_context);
2877 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) !=
2878 MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN);
2879 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_TABLE, inbuf, sizeof(inbuf),
2880 tablebuf, sizeof(tablebuf), &outlen);
2881 if (rc != 0)
2882 return rc;
2883
2884 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN))
2885 return -EIO;
2886
2887 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
2888 efx->rx_indir_table[i] = MCDI_PTR(tablebuf,
2889 RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE)[i];
2890
2891 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID,
2892 nic_data->rx_rss_context);
2893 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_hash_key) !=
2894 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2895 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_KEY, inbuf, sizeof(inbuf),
2896 keybuf, sizeof(keybuf), &outlen);
2897 if (rc != 0)
2898 return rc;
2899
2900 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN))
2901 return -EIO;
2902
2903 for (i = 0; i < ARRAY_SIZE(efx->rx_hash_key); ++i)
2904 efx->rx_hash_key[i] = MCDI_PTR(
2905 keybuf, RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY)[i];
2906
2907 return 0;
2908}
2909
Jon Cooper267c0152015-05-06 00:59:38 +01002910static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
Edward Creef74d1992017-01-17 12:01:53 +00002911 const u32 *rx_indir_table,
2912 const u8 *key)
Jon Cooper267c0152015-05-06 00:59:38 +01002913{
2914 int rc;
2915
2916 if (efx->rss_spread == 1)
2917 return 0;
2918
Edward Creef74d1992017-01-17 12:01:53 +00002919 if (!key)
2920 key = efx->rx_hash_key;
2921
2922 rc = efx_ef10_rx_push_exclusive_rss_config(efx, rx_indir_table, key);
Jon Cooper267c0152015-05-06 00:59:38 +01002923
2924 if (rc == -ENOBUFS && !user) {
2925 unsigned context_size;
2926 bool mismatch = false;
2927 size_t i;
2928
2929 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table) && !mismatch;
2930 i++)
2931 mismatch = rx_indir_table[i] !=
2932 ethtool_rxfh_indir_default(i, efx->rss_spread);
2933
2934 rc = efx_ef10_rx_push_shared_rss_config(efx, &context_size);
2935 if (rc == 0) {
2936 if (context_size != efx->rss_spread)
2937 netif_warn(efx, probe, efx->net_dev,
2938 "Could not allocate an exclusive RSS"
2939 " context; allocated a shared one of"
2940 " different size."
2941 " Wanted %u, got %u.\n",
2942 efx->rss_spread, context_size);
2943 else if (mismatch)
2944 netif_warn(efx, probe, efx->net_dev,
2945 "Could not allocate an exclusive RSS"
2946 " context; allocated a shared one but"
2947 " could not apply custom"
2948 " indirection.\n");
2949 else
2950 netif_info(efx, probe, efx->net_dev,
2951 "Could not allocate an exclusive RSS"
2952 " context; allocated a shared one.\n");
2953 }
2954 }
2955 return rc;
2956}
2957
2958static int efx_ef10_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
2959 const u32 *rx_indir_table
Edward Creef74d1992017-01-17 12:01:53 +00002960 __attribute__ ((unused)),
2961 const u8 *key
Jon Cooper267c0152015-05-06 00:59:38 +01002962 __attribute__ ((unused)))
2963{
2964 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2965
2966 if (user)
2967 return -EOPNOTSUPP;
2968 if (nic_data->rx_rss_context != EFX_EF10_RSS_CONTEXT_INVALID)
2969 return 0;
2970 return efx_ef10_rx_push_shared_rss_config(efx, NULL);
Ben Hutchings8127d662013-08-29 19:19:29 +01002971}
2972
2973static int efx_ef10_rx_probe(struct efx_rx_queue *rx_queue)
2974{
2975 return efx_nic_alloc_buffer(rx_queue->efx, &rx_queue->rxd.buf,
2976 (rx_queue->ptr_mask + 1) *
2977 sizeof(efx_qword_t),
2978 GFP_KERNEL);
2979}
2980
2981static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
2982{
2983 MCDI_DECLARE_BUF(inbuf,
2984 MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
2985 EFX_BUF_SIZE));
Ben Hutchings8127d662013-08-29 19:19:29 +01002986 struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
2987 size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE;
2988 struct efx_nic *efx = rx_queue->efx;
Daniel Pieczko45b24492015-05-06 00:57:14 +01002989 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Jon Cooperaa09a3d2015-05-20 11:10:41 +01002990 size_t inlen;
Ben Hutchings8127d662013-08-29 19:19:29 +01002991 dma_addr_t dma_addr;
2992 int rc;
2993 int i;
Jon Cooperaa09a3d2015-05-20 11:10:41 +01002994 BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0);
Ben Hutchings8127d662013-08-29 19:19:29 +01002995
2996 rx_queue->scatter_n = 0;
2997 rx_queue->scatter_len = 0;
2998
2999 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_SIZE, rx_queue->ptr_mask + 1);
3000 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_TARGET_EVQ, channel->channel);
3001 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_LABEL, efx_rx_queue_index(rx_queue));
3002 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_INSTANCE,
3003 efx_rx_queue_index(rx_queue));
Jon Cooperbd9a2652013-11-18 12:54:41 +00003004 MCDI_POPULATE_DWORD_2(inbuf, INIT_RXQ_IN_FLAGS,
3005 INIT_RXQ_IN_FLAG_PREFIX, 1,
3006 INIT_RXQ_IN_FLAG_TIMESTAMP, 1);
Ben Hutchings8127d662013-08-29 19:19:29 +01003007 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0);
Daniel Pieczko45b24492015-05-06 00:57:14 +01003008 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, nic_data->vport_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01003009
3010 dma_addr = rx_queue->rxd.buf.dma_addr;
3011
3012 netif_dbg(efx, hw, efx->net_dev, "pushing RXQ %d. %zu entries (%llx)\n",
3013 efx_rx_queue_index(rx_queue), entries, (u64)dma_addr);
3014
3015 for (i = 0; i < entries; ++i) {
3016 MCDI_SET_ARRAY_QWORD(inbuf, INIT_RXQ_IN_DMA_ADDR, i, dma_addr);
3017 dma_addr += EFX_BUF_SIZE;
3018 }
3019
3020 inlen = MC_CMD_INIT_RXQ_IN_LEN(entries);
3021
3022 rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen,
Jon Cooperaa09a3d2015-05-20 11:10:41 +01003023 NULL, 0, NULL);
Ben Hutchings48ce5632013-11-01 16:42:44 +00003024 if (rc)
3025 netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n",
3026 efx_rx_queue_index(rx_queue));
Ben Hutchings8127d662013-08-29 19:19:29 +01003027}
3028
3029static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
3030{
3031 MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_RXQ_IN_LEN);
Jon Cooperaa09a3d2015-05-20 11:10:41 +01003032 MCDI_DECLARE_BUF_ERR(outbuf);
Ben Hutchings8127d662013-08-29 19:19:29 +01003033 struct efx_nic *efx = rx_queue->efx;
3034 size_t outlen;
3035 int rc;
3036
3037 MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE,
3038 efx_rx_queue_index(rx_queue));
3039
Edward Cree1e0b8122013-05-31 18:36:12 +01003040 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf),
Ben Hutchings8127d662013-08-29 19:19:29 +01003041 outbuf, sizeof(outbuf), &outlen);
3042
3043 if (rc && rc != -EALREADY)
3044 goto fail;
3045
3046 return;
3047
3048fail:
Edward Cree1e0b8122013-05-31 18:36:12 +01003049 efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN,
3050 outbuf, outlen, rc);
Ben Hutchings8127d662013-08-29 19:19:29 +01003051}
3052
3053static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue)
3054{
3055 efx_nic_free_buffer(rx_queue->efx, &rx_queue->rxd.buf);
3056}
3057
3058/* This creates an entry in the RX descriptor queue */
3059static inline void
3060efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
3061{
3062 struct efx_rx_buffer *rx_buf;
3063 efx_qword_t *rxd;
3064
3065 rxd = efx_rx_desc(rx_queue, index);
3066 rx_buf = efx_rx_buffer(rx_queue, index);
3067 EFX_POPULATE_QWORD_2(*rxd,
3068 ESF_DZ_RX_KER_BYTE_CNT, rx_buf->len,
3069 ESF_DZ_RX_KER_BUF_ADDR, rx_buf->dma_addr);
3070}
3071
3072static void efx_ef10_rx_write(struct efx_rx_queue *rx_queue)
3073{
3074 struct efx_nic *efx = rx_queue->efx;
3075 unsigned int write_count;
3076 efx_dword_t reg;
3077
3078 /* Firmware requires that RX_DESC_WPTR be a multiple of 8 */
3079 write_count = rx_queue->added_count & ~7;
3080 if (rx_queue->notified_count == write_count)
3081 return;
3082
3083 do
3084 efx_ef10_build_rx_desc(
3085 rx_queue,
3086 rx_queue->notified_count & rx_queue->ptr_mask);
3087 while (++rx_queue->notified_count != write_count);
3088
3089 wmb();
3090 EFX_POPULATE_DWORD_1(reg, ERF_DZ_RX_DESC_WPTR,
3091 write_count & rx_queue->ptr_mask);
3092 efx_writed_page(efx, &reg, ER_DZ_RX_DESC_UPD,
3093 efx_rx_queue_index(rx_queue));
3094}
3095
3096static efx_mcdi_async_completer efx_ef10_rx_defer_refill_complete;
3097
3098static void efx_ef10_rx_defer_refill(struct efx_rx_queue *rx_queue)
3099{
3100 struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
3101 MCDI_DECLARE_BUF(inbuf, MC_CMD_DRIVER_EVENT_IN_LEN);
3102 efx_qword_t event;
3103
3104 EFX_POPULATE_QWORD_2(event,
3105 ESF_DZ_EV_CODE, EFX_EF10_DRVGEN_EV,
3106 ESF_DZ_EV_DATA, EFX_EF10_REFILL);
3107
3108 MCDI_SET_DWORD(inbuf, DRIVER_EVENT_IN_EVQ, channel->channel);
3109
3110 /* MCDI_SET_QWORD is not appropriate here since EFX_POPULATE_* has
3111 * already swapped the data to little-endian order.
3112 */
3113 memcpy(MCDI_PTR(inbuf, DRIVER_EVENT_IN_DATA), &event.u64[0],
3114 sizeof(efx_qword_t));
3115
3116 efx_mcdi_rpc_async(channel->efx, MC_CMD_DRIVER_EVENT,
3117 inbuf, sizeof(inbuf), 0,
3118 efx_ef10_rx_defer_refill_complete, 0);
3119}
3120
3121static void
3122efx_ef10_rx_defer_refill_complete(struct efx_nic *efx, unsigned long cookie,
3123 int rc, efx_dword_t *outbuf,
3124 size_t outlen_actual)
3125{
3126 /* nothing to do */
3127}
3128
3129static int efx_ef10_ev_probe(struct efx_channel *channel)
3130{
3131 return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf,
3132 (channel->eventq_mask + 1) *
3133 sizeof(efx_qword_t),
3134 GFP_KERNEL);
3135}
3136
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003137static void efx_ef10_ev_fini(struct efx_channel *channel)
3138{
3139 MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_EVQ_IN_LEN);
3140 MCDI_DECLARE_BUF_ERR(outbuf);
3141 struct efx_nic *efx = channel->efx;
3142 size_t outlen;
3143 int rc;
3144
3145 MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel);
3146
3147 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf),
3148 outbuf, sizeof(outbuf), &outlen);
3149
3150 if (rc && rc != -EALREADY)
3151 goto fail;
3152
3153 return;
3154
3155fail:
3156 efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN,
3157 outbuf, outlen, rc);
3158}
3159
Ben Hutchings8127d662013-08-29 19:19:29 +01003160static int efx_ef10_ev_init(struct efx_channel *channel)
3161{
3162 MCDI_DECLARE_BUF(inbuf,
Bert Kenwarda9955602016-08-11 13:01:54 +01003163 MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_MAX_EVQ_SIZE * 8 /
3164 EFX_BUF_SIZE));
3165 MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_EVQ_V2_OUT_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01003166 size_t entries = channel->eventq.buf.len / EFX_BUF_SIZE;
3167 struct efx_nic *efx = channel->efx;
3168 struct efx_ef10_nic_data *nic_data;
Ben Hutchings8127d662013-08-29 19:19:29 +01003169 size_t inlen, outlen;
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003170 unsigned int enabled, implemented;
Ben Hutchings8127d662013-08-29 19:19:29 +01003171 dma_addr_t dma_addr;
3172 int rc;
3173 int i;
3174
3175 nic_data = efx->nic_data;
Ben Hutchings8127d662013-08-29 19:19:29 +01003176
3177 /* Fill event queue with all ones (i.e. empty events) */
3178 memset(channel->eventq.buf.addr, 0xff, channel->eventq.buf.len);
3179
3180 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_SIZE, channel->eventq_mask + 1);
3181 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_INSTANCE, channel->channel);
3182 /* INIT_EVQ expects index in vector table, not absolute */
3183 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_IRQ_NUM, channel->channel);
Ben Hutchings8127d662013-08-29 19:19:29 +01003184 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_MODE,
3185 MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
3186 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_LOAD, 0);
3187 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_RELOAD, 0);
3188 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_MODE,
3189 MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
3190 MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_THRSHLD, 0);
3191
Bert Kenwarda9955602016-08-11 13:01:54 +01003192 if (nic_data->datapath_caps2 &
3193 1 << MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_LBN) {
3194 /* Use the new generic approach to specifying event queue
3195 * configuration, requesting lower latency or higher throughput.
3196 * The options that actually get used appear in the output.
3197 */
3198 MCDI_POPULATE_DWORD_2(inbuf, INIT_EVQ_V2_IN_FLAGS,
3199 INIT_EVQ_V2_IN_FLAG_INTERRUPTING, 1,
3200 INIT_EVQ_V2_IN_FLAG_TYPE,
3201 MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO);
3202 } else {
3203 bool cut_thru = !(nic_data->datapath_caps &
3204 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN);
3205
3206 MCDI_POPULATE_DWORD_4(inbuf, INIT_EVQ_IN_FLAGS,
3207 INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
3208 INIT_EVQ_IN_FLAG_RX_MERGE, 1,
3209 INIT_EVQ_IN_FLAG_TX_MERGE, 1,
3210 INIT_EVQ_IN_FLAG_CUT_THRU, cut_thru);
3211 }
3212
Ben Hutchings8127d662013-08-29 19:19:29 +01003213 dma_addr = channel->eventq.buf.dma_addr;
3214 for (i = 0; i < entries; ++i) {
3215 MCDI_SET_ARRAY_QWORD(inbuf, INIT_EVQ_IN_DMA_ADDR, i, dma_addr);
3216 dma_addr += EFX_BUF_SIZE;
3217 }
3218
3219 inlen = MC_CMD_INIT_EVQ_IN_LEN(entries);
3220
3221 rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen,
3222 outbuf, sizeof(outbuf), &outlen);
Bert Kenwarda9955602016-08-11 13:01:54 +01003223
3224 if (outlen >= MC_CMD_INIT_EVQ_V2_OUT_LEN)
3225 netif_dbg(efx, drv, efx->net_dev,
3226 "Channel %d using event queue flags %08x\n",
3227 channel->channel,
3228 MCDI_DWORD(outbuf, INIT_EVQ_V2_OUT_FLAGS));
3229
Ben Hutchings8127d662013-08-29 19:19:29 +01003230 /* IRQ return is ignored */
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003231 if (channel->channel || rc)
3232 return rc;
Ben Hutchings8127d662013-08-29 19:19:29 +01003233
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003234 /* Successfully created event queue on channel 0 */
3235 rc = efx_mcdi_get_workarounds(efx, &implemented, &enabled);
Edward Cree832dc9e2015-07-21 15:09:31 +01003236 if (rc == -ENOSYS) {
Bert Kenwardd95e3292016-08-11 13:02:36 +01003237 /* GET_WORKAROUNDS was implemented before this workaround,
3238 * thus it must be unavailable in this firmware.
Edward Cree832dc9e2015-07-21 15:09:31 +01003239 */
3240 nic_data->workaround_26807 = false;
3241 rc = 0;
3242 } else if (rc) {
Ben Hutchings8127d662013-08-29 19:19:29 +01003243 goto fail;
Edward Cree832dc9e2015-07-21 15:09:31 +01003244 } else {
3245 nic_data->workaround_26807 =
3246 !!(enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807);
Ben Hutchings8127d662013-08-29 19:19:29 +01003247
Edward Cree832dc9e2015-07-21 15:09:31 +01003248 if (implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807 &&
3249 !nic_data->workaround_26807) {
Daniel Pieczko5a55a722015-07-21 15:10:02 +01003250 unsigned int flags;
3251
Daniel Pieczko34ccfe62015-07-21 15:09:43 +01003252 rc = efx_mcdi_set_workaround(efx,
3253 MC_CMD_WORKAROUND_BUG26807,
Daniel Pieczko5a55a722015-07-21 15:10:02 +01003254 true, &flags);
3255
3256 if (!rc) {
3257 if (flags &
3258 1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN) {
3259 netif_info(efx, drv, efx->net_dev,
3260 "other functions on NIC have been reset\n");
Daniel Pieczkoabd86a52015-12-04 08:48:39 +00003261
3262 /* With MCFW v4.6.x and earlier, the
3263 * boot count will have incremented,
3264 * so re-read the warm_boot_count
3265 * value now to ensure this function
3266 * doesn't think it has changed next
3267 * time it checks.
3268 */
3269 rc = efx_ef10_get_warm_boot_count(efx);
3270 if (rc >= 0) {
3271 nic_data->warm_boot_count = rc;
3272 rc = 0;
3273 }
Daniel Pieczko5a55a722015-07-21 15:10:02 +01003274 }
Edward Cree832dc9e2015-07-21 15:09:31 +01003275 nic_data->workaround_26807 = true;
Daniel Pieczko5a55a722015-07-21 15:10:02 +01003276 } else if (rc == -EPERM) {
Edward Cree832dc9e2015-07-21 15:09:31 +01003277 rc = 0;
Daniel Pieczko5a55a722015-07-21 15:10:02 +01003278 }
Edward Cree832dc9e2015-07-21 15:09:31 +01003279 }
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003280 }
3281
3282 if (!rc)
3283 return 0;
Ben Hutchings8127d662013-08-29 19:19:29 +01003284
3285fail:
Daniel Pieczko46e612b2015-07-21 15:09:18 +01003286 efx_ef10_ev_fini(channel);
3287 return rc;
Ben Hutchings8127d662013-08-29 19:19:29 +01003288}
3289
3290static void efx_ef10_ev_remove(struct efx_channel *channel)
3291{
3292 efx_nic_free_buffer(channel->efx, &channel->eventq.buf);
3293}
3294
3295static void efx_ef10_handle_rx_wrong_queue(struct efx_rx_queue *rx_queue,
3296 unsigned int rx_queue_label)
3297{
3298 struct efx_nic *efx = rx_queue->efx;
3299
3300 netif_info(efx, hw, efx->net_dev,
3301 "rx event arrived on queue %d labeled as queue %u\n",
3302 efx_rx_queue_index(rx_queue), rx_queue_label);
3303
3304 efx_schedule_reset(efx, RESET_TYPE_DISABLE);
3305}
3306
3307static void
3308efx_ef10_handle_rx_bad_lbits(struct efx_rx_queue *rx_queue,
3309 unsigned int actual, unsigned int expected)
3310{
3311 unsigned int dropped = (actual - expected) & rx_queue->ptr_mask;
3312 struct efx_nic *efx = rx_queue->efx;
3313
3314 netif_info(efx, hw, efx->net_dev,
3315 "dropped %d events (index=%d expected=%d)\n",
3316 dropped, actual, expected);
3317
3318 efx_schedule_reset(efx, RESET_TYPE_DISABLE);
3319}
3320
3321/* partially received RX was aborted. clean up. */
3322static void efx_ef10_handle_rx_abort(struct efx_rx_queue *rx_queue)
3323{
3324 unsigned int rx_desc_ptr;
3325
Ben Hutchings8127d662013-08-29 19:19:29 +01003326 netif_dbg(rx_queue->efx, hw, rx_queue->efx->net_dev,
3327 "scattered RX aborted (dropping %u buffers)\n",
3328 rx_queue->scatter_n);
3329
3330 rx_desc_ptr = rx_queue->removed_count & rx_queue->ptr_mask;
3331
3332 efx_rx_packet(rx_queue, rx_desc_ptr, rx_queue->scatter_n,
3333 0, EFX_RX_PKT_DISCARD);
3334
3335 rx_queue->removed_count += rx_queue->scatter_n;
3336 rx_queue->scatter_n = 0;
3337 rx_queue->scatter_len = 0;
3338 ++efx_rx_queue_channel(rx_queue)->n_rx_nodesc_trunc;
3339}
3340
Jon Coopera0ee3542017-02-08 16:50:40 +00003341static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel,
3342 unsigned int n_packets,
3343 unsigned int rx_encap_hdr,
3344 unsigned int rx_l3_class,
3345 unsigned int rx_l4_class,
3346 const efx_qword_t *event)
3347{
3348 struct efx_nic *efx = channel->efx;
Edward Cree69787292017-10-31 14:29:47 +00003349 bool handled = false;
Jon Coopera0ee3542017-02-08 16:50:40 +00003350
3351 if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_ECRC_ERR)) {
Edward Cree69787292017-10-31 14:29:47 +00003352 if (!(efx->net_dev->features & NETIF_F_RXALL)) {
3353 if (!efx->loopback_selftest)
3354 channel->n_rx_eth_crc_err += n_packets;
3355 return EFX_RX_PKT_DISCARD;
3356 }
3357 handled = true;
Jon Coopera0ee3542017-02-08 16:50:40 +00003358 }
3359 if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_IPCKSUM_ERR)) {
3360 if (unlikely(rx_encap_hdr != ESE_EZ_ENCAP_HDR_VXLAN &&
3361 rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
3362 rx_l3_class != ESE_DZ_L3_CLASS_IP4_FRAG &&
3363 rx_l3_class != ESE_DZ_L3_CLASS_IP6 &&
3364 rx_l3_class != ESE_DZ_L3_CLASS_IP6_FRAG))
3365 netdev_WARN(efx->net_dev,
3366 "invalid class for RX_IPCKSUM_ERR: event="
3367 EFX_QWORD_FMT "\n",
3368 EFX_QWORD_VAL(*event));
3369 if (!efx->loopback_selftest)
3370 *(rx_encap_hdr ?
3371 &channel->n_rx_outer_ip_hdr_chksum_err :
3372 &channel->n_rx_ip_hdr_chksum_err) += n_packets;
3373 return 0;
3374 }
3375 if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_TCPUDP_CKSUM_ERR)) {
3376 if (unlikely(rx_encap_hdr != ESE_EZ_ENCAP_HDR_VXLAN &&
3377 ((rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
3378 rx_l3_class != ESE_DZ_L3_CLASS_IP6) ||
Bert Kenwardd8d8ccf2017-12-18 16:57:18 +00003379 (rx_l4_class != ESE_FZ_L4_CLASS_TCP &&
3380 rx_l4_class != ESE_FZ_L4_CLASS_UDP))))
Jon Coopera0ee3542017-02-08 16:50:40 +00003381 netdev_WARN(efx->net_dev,
3382 "invalid class for RX_TCPUDP_CKSUM_ERR: event="
3383 EFX_QWORD_FMT "\n",
3384 EFX_QWORD_VAL(*event));
3385 if (!efx->loopback_selftest)
3386 *(rx_encap_hdr ?
3387 &channel->n_rx_outer_tcp_udp_chksum_err :
3388 &channel->n_rx_tcp_udp_chksum_err) += n_packets;
3389 return 0;
3390 }
3391 if (EFX_QWORD_FIELD(*event, ESF_EZ_RX_IP_INNER_CHKSUM_ERR)) {
3392 if (unlikely(!rx_encap_hdr))
3393 netdev_WARN(efx->net_dev,
3394 "invalid encapsulation type for RX_IP_INNER_CHKSUM_ERR: event="
3395 EFX_QWORD_FMT "\n",
3396 EFX_QWORD_VAL(*event));
3397 else if (unlikely(rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
3398 rx_l3_class != ESE_DZ_L3_CLASS_IP4_FRAG &&
3399 rx_l3_class != ESE_DZ_L3_CLASS_IP6 &&
3400 rx_l3_class != ESE_DZ_L3_CLASS_IP6_FRAG))
3401 netdev_WARN(efx->net_dev,
3402 "invalid class for RX_IP_INNER_CHKSUM_ERR: event="
3403 EFX_QWORD_FMT "\n",
3404 EFX_QWORD_VAL(*event));
3405 if (!efx->loopback_selftest)
3406 channel->n_rx_inner_ip_hdr_chksum_err += n_packets;
3407 return 0;
3408 }
3409 if (EFX_QWORD_FIELD(*event, ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR)) {
3410 if (unlikely(!rx_encap_hdr))
3411 netdev_WARN(efx->net_dev,
3412 "invalid encapsulation type for RX_TCP_UDP_INNER_CHKSUM_ERR: event="
3413 EFX_QWORD_FMT "\n",
3414 EFX_QWORD_VAL(*event));
3415 else if (unlikely((rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
3416 rx_l3_class != ESE_DZ_L3_CLASS_IP6) ||
Bert Kenwardd8d8ccf2017-12-18 16:57:18 +00003417 (rx_l4_class != ESE_FZ_L4_CLASS_TCP &&
3418 rx_l4_class != ESE_FZ_L4_CLASS_UDP)))
Jon Coopera0ee3542017-02-08 16:50:40 +00003419 netdev_WARN(efx->net_dev,
3420 "invalid class for RX_TCP_UDP_INNER_CHKSUM_ERR: event="
3421 EFX_QWORD_FMT "\n",
3422 EFX_QWORD_VAL(*event));
3423 if (!efx->loopback_selftest)
3424 channel->n_rx_inner_tcp_udp_chksum_err += n_packets;
3425 return 0;
3426 }
3427
Edward Cree69787292017-10-31 14:29:47 +00003428 WARN_ON(!handled); /* No error bits were recognised */
Jon Coopera0ee3542017-02-08 16:50:40 +00003429 return 0;
3430}
3431
Ben Hutchings8127d662013-08-29 19:19:29 +01003432static int efx_ef10_handle_rx_event(struct efx_channel *channel,
3433 const efx_qword_t *event)
3434{
Jon Coopera0ee3542017-02-08 16:50:40 +00003435 unsigned int rx_bytes, next_ptr_lbits, rx_queue_label;
3436 unsigned int rx_l3_class, rx_l4_class, rx_encap_hdr;
Ben Hutchings8127d662013-08-29 19:19:29 +01003437 unsigned int n_descs, n_packets, i;
3438 struct efx_nic *efx = channel->efx;
Jon Coopera0ee3542017-02-08 16:50:40 +00003439 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Ben Hutchings8127d662013-08-29 19:19:29 +01003440 struct efx_rx_queue *rx_queue;
Jon Coopera0ee3542017-02-08 16:50:40 +00003441 efx_qword_t errors;
Ben Hutchings8127d662013-08-29 19:19:29 +01003442 bool rx_cont;
3443 u16 flags = 0;
3444
Mark Rutland6aa7de02017-10-23 14:07:29 -07003445 if (unlikely(READ_ONCE(efx->reset_pending)))
Ben Hutchings8127d662013-08-29 19:19:29 +01003446 return 0;
3447
3448 /* Basic packet information */
3449 rx_bytes = EFX_QWORD_FIELD(*event, ESF_DZ_RX_BYTES);
3450 next_ptr_lbits = EFX_QWORD_FIELD(*event, ESF_DZ_RX_DSC_PTR_LBITS);
3451 rx_queue_label = EFX_QWORD_FIELD(*event, ESF_DZ_RX_QLABEL);
Jon Coopera0ee3542017-02-08 16:50:40 +00003452 rx_l3_class = EFX_QWORD_FIELD(*event, ESF_DZ_RX_L3_CLASS);
Bert Kenwardd8d8ccf2017-12-18 16:57:18 +00003453 rx_l4_class = EFX_QWORD_FIELD(*event, ESF_FZ_RX_L4_CLASS);
Ben Hutchings8127d662013-08-29 19:19:29 +01003454 rx_cont = EFX_QWORD_FIELD(*event, ESF_DZ_RX_CONT);
Jon Coopera0ee3542017-02-08 16:50:40 +00003455 rx_encap_hdr =
3456 nic_data->datapath_caps &
3457 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN) ?
3458 EFX_QWORD_FIELD(*event, ESF_EZ_RX_ENCAP_HDR) :
3459 ESE_EZ_ENCAP_HDR_NONE;
Ben Hutchings8127d662013-08-29 19:19:29 +01003460
Ben Hutchings48ce5632013-11-01 16:42:44 +00003461 if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_DROP_EVENT))
3462 netdev_WARN(efx->net_dev, "saw RX_DROP_EVENT: event="
3463 EFX_QWORD_FMT "\n",
3464 EFX_QWORD_VAL(*event));
Ben Hutchings8127d662013-08-29 19:19:29 +01003465
3466 rx_queue = efx_channel_get_rx_queue(channel);
3467
3468 if (unlikely(rx_queue_label != efx_rx_queue_index(rx_queue)))
3469 efx_ef10_handle_rx_wrong_queue(rx_queue, rx_queue_label);
3470
3471 n_descs = ((next_ptr_lbits - rx_queue->removed_count) &
3472 ((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1));
3473
3474 if (n_descs != rx_queue->scatter_n + 1) {
Ben Hutchings92a04162013-09-24 23:21:57 +01003475 struct efx_ef10_nic_data *nic_data = efx->nic_data;
3476
Ben Hutchings8127d662013-08-29 19:19:29 +01003477 /* detect rx abort */
3478 if (unlikely(n_descs == rx_queue->scatter_n)) {
Ben Hutchings48ce5632013-11-01 16:42:44 +00003479 if (rx_queue->scatter_n == 0 || rx_bytes != 0)
3480 netdev_WARN(efx->net_dev,
3481 "invalid RX abort: scatter_n=%u event="
3482 EFX_QWORD_FMT "\n",
3483 rx_queue->scatter_n,
3484 EFX_QWORD_VAL(*event));
Ben Hutchings8127d662013-08-29 19:19:29 +01003485 efx_ef10_handle_rx_abort(rx_queue);
3486 return 0;
3487 }
3488
Ben Hutchings92a04162013-09-24 23:21:57 +01003489 /* Check that RX completion merging is valid, i.e.
3490 * the current firmware supports it and this is a
3491 * non-scattered packet.
3492 */
3493 if (!(nic_data->datapath_caps &
3494 (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN)) ||
3495 rx_queue->scatter_n != 0 || rx_cont) {
Ben Hutchings8127d662013-08-29 19:19:29 +01003496 efx_ef10_handle_rx_bad_lbits(
3497 rx_queue, next_ptr_lbits,
3498 (rx_queue->removed_count +
3499 rx_queue->scatter_n + 1) &
3500 ((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1));
3501 return 0;
3502 }
3503
3504 /* Merged completion for multiple non-scattered packets */
3505 rx_queue->scatter_n = 1;
3506 rx_queue->scatter_len = 0;
3507 n_packets = n_descs;
3508 ++channel->n_rx_merge_events;
3509 channel->n_rx_merge_packets += n_packets;
3510 flags |= EFX_RX_PKT_PREFIX_LEN;
3511 } else {
3512 ++rx_queue->scatter_n;
3513 rx_queue->scatter_len += rx_bytes;
3514 if (rx_cont)
3515 return 0;
3516 n_packets = 1;
3517 }
3518
Jon Coopera0ee3542017-02-08 16:50:40 +00003519 EFX_POPULATE_QWORD_5(errors, ESF_DZ_RX_ECRC_ERR, 1,
3520 ESF_DZ_RX_IPCKSUM_ERR, 1,
3521 ESF_DZ_RX_TCPUDP_CKSUM_ERR, 1,
3522 ESF_EZ_RX_IP_INNER_CHKSUM_ERR, 1,
3523 ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR, 1);
3524 EFX_AND_QWORD(errors, *event, errors);
3525 if (unlikely(!EFX_QWORD_IS_ZERO(errors))) {
3526 flags |= efx_ef10_handle_rx_event_errors(channel, n_packets,
Edward Cree90d2ea92017-02-10 17:34:59 +00003527 rx_encap_hdr,
Jon Coopera0ee3542017-02-08 16:50:40 +00003528 rx_l3_class, rx_l4_class,
Edward Cree90d2ea92017-02-10 17:34:59 +00003529 event);
Jon Coopera0ee3542017-02-08 16:50:40 +00003530 } else {
Bert Kenwardd8d8ccf2017-12-18 16:57:18 +00003531 bool tcpudp = rx_l4_class == ESE_FZ_L4_CLASS_TCP ||
3532 rx_l4_class == ESE_FZ_L4_CLASS_UDP;
Jon Cooperda50ae22017-02-08 16:51:02 +00003533
3534 switch (rx_encap_hdr) {
3535 case ESE_EZ_ENCAP_HDR_VXLAN: /* VxLAN or GENEVE */
3536 flags |= EFX_RX_PKT_CSUMMED; /* outer UDP csum */
3537 if (tcpudp)
3538 flags |= EFX_RX_PKT_CSUM_LEVEL; /* inner L4 */
3539 break;
3540 case ESE_EZ_ENCAP_HDR_GRE:
3541 case ESE_EZ_ENCAP_HDR_NONE:
3542 if (tcpudp)
3543 flags |= EFX_RX_PKT_CSUMMED;
3544 break;
3545 default:
3546 netdev_WARN(efx->net_dev,
3547 "unknown encapsulation type: event="
3548 EFX_QWORD_FMT "\n",
3549 EFX_QWORD_VAL(*event));
3550 }
Ben Hutchings8127d662013-08-29 19:19:29 +01003551 }
3552
Bert Kenwardd8d8ccf2017-12-18 16:57:18 +00003553 if (rx_l4_class == ESE_FZ_L4_CLASS_TCP)
Ben Hutchings8127d662013-08-29 19:19:29 +01003554 flags |= EFX_RX_PKT_TCP;
3555
3556 channel->irq_mod_score += 2 * n_packets;
3557
3558 /* Handle received packet(s) */
3559 for (i = 0; i < n_packets; i++) {
3560 efx_rx_packet(rx_queue,
3561 rx_queue->removed_count & rx_queue->ptr_mask,
3562 rx_queue->scatter_n, rx_queue->scatter_len,
3563 flags);
3564 rx_queue->removed_count += rx_queue->scatter_n;
3565 }
3566
3567 rx_queue->scatter_n = 0;
3568 rx_queue->scatter_len = 0;
3569
3570 return n_packets;
3571}
3572
Martin Habetsb9b603d42018-01-25 17:24:43 +00003573static u32 efx_ef10_extract_event_ts(efx_qword_t *event)
3574{
3575 u32 tstamp;
3576
3577 tstamp = EFX_QWORD_FIELD(*event, TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI);
3578 tstamp <<= 16;
3579 tstamp |= EFX_QWORD_FIELD(*event, TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO);
3580
3581 return tstamp;
3582}
3583
Bert Kenward5227ecc2018-01-25 17:24:20 +00003584static void
Ben Hutchings8127d662013-08-29 19:19:29 +01003585efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
3586{
3587 struct efx_nic *efx = channel->efx;
3588 struct efx_tx_queue *tx_queue;
3589 unsigned int tx_ev_desc_ptr;
3590 unsigned int tx_ev_q_label;
Martin Habetsb9b603d42018-01-25 17:24:43 +00003591 unsigned int tx_ev_type;
3592 u64 ts_part;
Ben Hutchings8127d662013-08-29 19:19:29 +01003593
Mark Rutland6aa7de02017-10-23 14:07:29 -07003594 if (unlikely(READ_ONCE(efx->reset_pending)))
Bert Kenward5227ecc2018-01-25 17:24:20 +00003595 return;
Ben Hutchings8127d662013-08-29 19:19:29 +01003596
3597 if (unlikely(EFX_QWORD_FIELD(*event, ESF_DZ_TX_DROP_EVENT)))
Bert Kenward5227ecc2018-01-25 17:24:20 +00003598 return;
Ben Hutchings8127d662013-08-29 19:19:29 +01003599
Martin Habetsb9b603d42018-01-25 17:24:43 +00003600 /* Get the transmit queue */
Ben Hutchings8127d662013-08-29 19:19:29 +01003601 tx_ev_q_label = EFX_QWORD_FIELD(*event, ESF_DZ_TX_QLABEL);
3602 tx_queue = efx_channel_get_tx_queue(channel,
3603 tx_ev_q_label % EFX_TXQ_TYPES);
Martin Habetsb9b603d42018-01-25 17:24:43 +00003604
3605 if (!tx_queue->timestamping) {
3606 /* Transmit completion */
3607 tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, ESF_DZ_TX_DESCR_INDX);
3608 efx_xmit_done(tx_queue, tx_ev_desc_ptr & tx_queue->ptr_mask);
3609 return;
3610 }
3611
3612 /* Transmit timestamps are only available for 8XXX series. They result
3613 * in three events per packet. These occur in order, and are:
3614 * - the normal completion event
3615 * - the low part of the timestamp
3616 * - the high part of the timestamp
3617 *
3618 * Each part of the timestamp is itself split across two 16 bit
3619 * fields in the event.
3620 */
3621 tx_ev_type = EFX_QWORD_FIELD(*event, ESF_EZ_TX_SOFT1);
3622
3623 switch (tx_ev_type) {
3624 case TX_TIMESTAMP_EVENT_TX_EV_COMPLETION:
3625 /* In case of Queue flush or FLR, we might have received
3626 * the previous TX completion event but not the Timestamp
3627 * events.
3628 */
3629 if (tx_queue->completed_desc_ptr != tx_queue->ptr_mask)
3630 efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr);
3631
3632 tx_ev_desc_ptr = EFX_QWORD_FIELD(*event,
3633 ESF_DZ_TX_DESCR_INDX);
3634 tx_queue->completed_desc_ptr =
3635 tx_ev_desc_ptr & tx_queue->ptr_mask;
3636 break;
3637
3638 case TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO:
3639 ts_part = efx_ef10_extract_event_ts(event);
3640 tx_queue->completed_timestamp_minor = ts_part;
3641 break;
3642
3643 case TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_HI:
3644 ts_part = efx_ef10_extract_event_ts(event);
3645 tx_queue->completed_timestamp_major = ts_part;
3646
3647 efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr);
3648 tx_queue->completed_desc_ptr = tx_queue->ptr_mask;
3649 break;
3650
3651 default:
3652 netif_err(efx, hw, efx->net_dev,
3653 "channel %d unknown tx event type %d (data "
3654 EFX_QWORD_FMT ")\n",
3655 channel->channel, tx_ev_type,
3656 EFX_QWORD_VAL(*event));
3657 break;
3658 }
Ben Hutchings8127d662013-08-29 19:19:29 +01003659}
3660
3661static void
3662efx_ef10_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
3663{
3664 struct efx_nic *efx = channel->efx;
3665 int subcode;
3666
3667 subcode = EFX_QWORD_FIELD(*event, ESF_DZ_DRV_SUB_CODE);
3668
3669 switch (subcode) {
3670 case ESE_DZ_DRV_TIMER_EV:
3671 case ESE_DZ_DRV_WAKE_UP_EV:
3672 break;
3673 case ESE_DZ_DRV_START_UP_EV:
3674 /* event queue init complete. ok. */
3675 break;
3676 default:
3677 netif_err(efx, hw, efx->net_dev,
3678 "channel %d unknown driver event type %d"
3679 " (data " EFX_QWORD_FMT ")\n",
3680 channel->channel, subcode,
3681 EFX_QWORD_VAL(*event));
3682
3683 }
3684}
3685
3686static void efx_ef10_handle_driver_generated_event(struct efx_channel *channel,
3687 efx_qword_t *event)
3688{
3689 struct efx_nic *efx = channel->efx;
3690 u32 subcode;
3691
3692 subcode = EFX_QWORD_FIELD(*event, EFX_DWORD_0);
3693
3694 switch (subcode) {
3695 case EFX_EF10_TEST:
3696 channel->event_test_cpu = raw_smp_processor_id();
3697 break;
3698 case EFX_EF10_REFILL:
3699 /* The queue must be empty, so we won't receive any rx
3700 * events, so efx_process_channel() won't refill the
3701 * queue. Refill it here
3702 */
Jon Coopercce28792013-10-02 11:04:14 +01003703 efx_fast_push_rx_descriptors(&channel->rx_queue, true);
Ben Hutchings8127d662013-08-29 19:19:29 +01003704 break;
3705 default:
3706 netif_err(efx, hw, efx->net_dev,
3707 "channel %d unknown driver event type %u"
3708 " (data " EFX_QWORD_FMT ")\n",
3709 channel->channel, (unsigned) subcode,
3710 EFX_QWORD_VAL(*event));
3711 }
3712}
3713
3714static int efx_ef10_ev_process(struct efx_channel *channel, int quota)
3715{
3716 struct efx_nic *efx = channel->efx;
3717 efx_qword_t event, *p_event;
3718 unsigned int read_ptr;
3719 int ev_code;
Ben Hutchings8127d662013-08-29 19:19:29 +01003720 int spent = 0;
3721
Eric W. Biederman75363a42014-03-14 18:11:22 -07003722 if (quota <= 0)
3723 return spent;
3724
Ben Hutchings8127d662013-08-29 19:19:29 +01003725 read_ptr = channel->eventq_read_ptr;
3726
3727 for (;;) {
3728 p_event = efx_event(channel, read_ptr);
3729 event = *p_event;
3730
3731 if (!efx_event_present(&event))
3732 break;
3733
3734 EFX_SET_QWORD(*p_event);
3735
3736 ++read_ptr;
3737
3738 ev_code = EFX_QWORD_FIELD(event, ESF_DZ_EV_CODE);
3739
3740 netif_vdbg(efx, drv, efx->net_dev,
3741 "processing event on %d " EFX_QWORD_FMT "\n",
3742 channel->channel, EFX_QWORD_VAL(event));
3743
3744 switch (ev_code) {
3745 case ESE_DZ_EV_CODE_MCDI_EV:
3746 efx_mcdi_process_event(channel, &event);
3747 break;
3748 case ESE_DZ_EV_CODE_RX_EV:
3749 spent += efx_ef10_handle_rx_event(channel, &event);
3750 if (spent >= quota) {
3751 /* XXX can we split a merged event to
3752 * avoid going over-quota?
3753 */
3754 spent = quota;
3755 goto out;
3756 }
3757 break;
3758 case ESE_DZ_EV_CODE_TX_EV:
Bert Kenward5227ecc2018-01-25 17:24:20 +00003759 efx_ef10_handle_tx_event(channel, &event);
Ben Hutchings8127d662013-08-29 19:19:29 +01003760 break;
3761 case ESE_DZ_EV_CODE_DRIVER_EV:
3762 efx_ef10_handle_driver_event(channel, &event);
3763 if (++spent == quota)
3764 goto out;
3765 break;
3766 case EFX_EF10_DRVGEN_EV:
3767 efx_ef10_handle_driver_generated_event(channel, &event);
3768 break;
3769 default:
3770 netif_err(efx, hw, efx->net_dev,
3771 "channel %d unknown event type %d"
3772 " (data " EFX_QWORD_FMT ")\n",
3773 channel->channel, ev_code,
3774 EFX_QWORD_VAL(event));
3775 }
3776 }
3777
3778out:
3779 channel->eventq_read_ptr = read_ptr;
3780 return spent;
3781}
3782
3783static void efx_ef10_ev_read_ack(struct efx_channel *channel)
3784{
3785 struct efx_nic *efx = channel->efx;
3786 efx_dword_t rptr;
3787
3788 if (EFX_EF10_WORKAROUND_35388(efx)) {
3789 BUILD_BUG_ON(EFX_MIN_EVQ_SIZE <
3790 (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
3791 BUILD_BUG_ON(EFX_MAX_EVQ_SIZE >
3792 (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
3793
3794 EFX_POPULATE_DWORD_2(rptr, ERF_DD_EVQ_IND_RPTR_FLAGS,
3795 EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
3796 ERF_DD_EVQ_IND_RPTR,
3797 (channel->eventq_read_ptr &
3798 channel->eventq_mask) >>
3799 ERF_DD_EVQ_IND_RPTR_WIDTH);
3800 efx_writed_page(efx, &rptr, ER_DD_EVQ_INDIRECT,
3801 channel->channel);
3802 EFX_POPULATE_DWORD_2(rptr, ERF_DD_EVQ_IND_RPTR_FLAGS,
3803 EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
3804 ERF_DD_EVQ_IND_RPTR,
3805 channel->eventq_read_ptr &
3806 ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
3807 efx_writed_page(efx, &rptr, ER_DD_EVQ_INDIRECT,
3808 channel->channel);
3809 } else {
3810 EFX_POPULATE_DWORD_1(rptr, ERF_DZ_EVQ_RPTR,
3811 channel->eventq_read_ptr &
3812 channel->eventq_mask);
3813 efx_writed_page(efx, &rptr, ER_DZ_EVQ_RPTR, channel->channel);
3814 }
3815}
3816
3817static void efx_ef10_ev_test_generate(struct efx_channel *channel)
3818{
3819 MCDI_DECLARE_BUF(inbuf, MC_CMD_DRIVER_EVENT_IN_LEN);
3820 struct efx_nic *efx = channel->efx;
3821 efx_qword_t event;
3822 int rc;
3823
3824 EFX_POPULATE_QWORD_2(event,
3825 ESF_DZ_EV_CODE, EFX_EF10_DRVGEN_EV,
3826 ESF_DZ_EV_DATA, EFX_EF10_TEST);
3827
3828 MCDI_SET_DWORD(inbuf, DRIVER_EVENT_IN_EVQ, channel->channel);
3829
3830 /* MCDI_SET_QWORD is not appropriate here since EFX_POPULATE_* has
3831 * already swapped the data to little-endian order.
3832 */
3833 memcpy(MCDI_PTR(inbuf, DRIVER_EVENT_IN_DATA), &event.u64[0],
3834 sizeof(efx_qword_t));
3835
3836 rc = efx_mcdi_rpc(efx, MC_CMD_DRIVER_EVENT, inbuf, sizeof(inbuf),
3837 NULL, 0, NULL);
3838 if (rc != 0)
3839 goto fail;
3840
3841 return;
3842
3843fail:
3844 WARN_ON(true);
3845 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
3846}
3847
3848void efx_ef10_handle_drain_event(struct efx_nic *efx)
3849{
3850 if (atomic_dec_and_test(&efx->active_queues))
3851 wake_up(&efx->flush_wq);
3852
3853 WARN_ON(atomic_read(&efx->active_queues) < 0);
3854}
3855
3856static int efx_ef10_fini_dmaq(struct efx_nic *efx)
3857{
3858 struct efx_ef10_nic_data *nic_data = efx->nic_data;
3859 struct efx_channel *channel;
3860 struct efx_tx_queue *tx_queue;
3861 struct efx_rx_queue *rx_queue;
3862 int pending;
3863
3864 /* If the MC has just rebooted, the TX/RX queues will have already been
3865 * torn down, but efx->active_queues needs to be set to zero.
3866 */
3867 if (nic_data->must_realloc_vis) {
3868 atomic_set(&efx->active_queues, 0);
3869 return 0;
3870 }
3871
3872 /* Do not attempt to write to the NIC during EEH recovery */
3873 if (efx->state != STATE_RECOVERY) {
3874 efx_for_each_channel(channel, efx) {
3875 efx_for_each_channel_rx_queue(rx_queue, channel)
3876 efx_ef10_rx_fini(rx_queue);
3877 efx_for_each_channel_tx_queue(tx_queue, channel)
3878 efx_ef10_tx_fini(tx_queue);
3879 }
3880
3881 wait_event_timeout(efx->flush_wq,
3882 atomic_read(&efx->active_queues) == 0,
3883 msecs_to_jiffies(EFX_MAX_FLUSH_TIME));
3884 pending = atomic_read(&efx->active_queues);
3885 if (pending) {
3886 netif_err(efx, hw, efx->net_dev, "failed to flush %d queues\n",
3887 pending);
3888 return -ETIMEDOUT;
3889 }
3890 }
3891
3892 return 0;
3893}
3894
Edward Creee2835462014-04-16 19:27:48 +01003895static void efx_ef10_prepare_flr(struct efx_nic *efx)
3896{
3897 atomic_set(&efx->active_queues, 0);
3898}
3899
Ben Hutchings8127d662013-08-29 19:19:29 +01003900static bool efx_ef10_filter_equal(const struct efx_filter_spec *left,
3901 const struct efx_filter_spec *right)
3902{
3903 if ((left->match_flags ^ right->match_flags) |
3904 ((left->flags ^ right->flags) &
3905 (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
3906 return false;
3907
3908 return memcmp(&left->outer_vid, &right->outer_vid,
3909 sizeof(struct efx_filter_spec) -
3910 offsetof(struct efx_filter_spec, outer_vid)) == 0;
3911}
3912
3913static unsigned int efx_ef10_filter_hash(const struct efx_filter_spec *spec)
3914{
3915 BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
3916 return jhash2((const u32 *)&spec->outer_vid,
3917 (sizeof(struct efx_filter_spec) -
3918 offsetof(struct efx_filter_spec, outer_vid)) / 4,
3919 0);
3920 /* XXX should we randomise the initval? */
3921}
3922
3923/* Decide whether a filter should be exclusive or else should allow
3924 * delivery to additional recipients. Currently we decide that
3925 * filters for specific local unicast MAC and IP addresses are
3926 * exclusive.
3927 */
3928static bool efx_ef10_filter_is_exclusive(const struct efx_filter_spec *spec)
3929{
3930 if (spec->match_flags & EFX_FILTER_MATCH_LOC_MAC &&
3931 !is_multicast_ether_addr(spec->loc_mac))
3932 return true;
3933
3934 if ((spec->match_flags &
3935 (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) ==
3936 (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) {
3937 if (spec->ether_type == htons(ETH_P_IP) &&
3938 !ipv4_is_multicast(spec->loc_host[0]))
3939 return true;
3940 if (spec->ether_type == htons(ETH_P_IPV6) &&
3941 ((const u8 *)spec->loc_host)[0] != 0xff)
3942 return true;
3943 }
3944
3945 return false;
3946}
3947
3948static struct efx_filter_spec *
3949efx_ef10_filter_entry_spec(const struct efx_ef10_filter_table *table,
3950 unsigned int filter_idx)
3951{
3952 return (struct efx_filter_spec *)(table->entry[filter_idx].spec &
3953 ~EFX_EF10_FILTER_FLAGS);
3954}
3955
3956static unsigned int
3957efx_ef10_filter_entry_flags(const struct efx_ef10_filter_table *table,
3958 unsigned int filter_idx)
3959{
3960 return table->entry[filter_idx].spec & EFX_EF10_FILTER_FLAGS;
3961}
3962
3963static void
3964efx_ef10_filter_set_entry(struct efx_ef10_filter_table *table,
3965 unsigned int filter_idx,
3966 const struct efx_filter_spec *spec,
3967 unsigned int flags)
3968{
3969 table->entry[filter_idx].spec = (unsigned long)spec | flags;
3970}
3971
Edward Cree9b410802017-01-27 15:02:52 +00003972static void
3973efx_ef10_filter_push_prep_set_match_fields(struct efx_nic *efx,
3974 const struct efx_filter_spec *spec,
3975 efx_dword_t *inbuf)
3976{
3977 enum efx_encap_type encap_type = efx_filter_get_encap_type(spec);
3978 u32 match_fields = 0, uc_match, mc_match;
3979
3980 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
3981 efx_ef10_filter_is_exclusive(spec) ?
3982 MC_CMD_FILTER_OP_IN_OP_INSERT :
3983 MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE);
3984
3985 /* Convert match flags and values. Unlike almost
3986 * everything else in MCDI, these fields are in
3987 * network byte order.
3988 */
3989#define COPY_VALUE(value, mcdi_field) \
3990 do { \
3991 match_fields |= \
3992 1 << MC_CMD_FILTER_OP_IN_MATCH_ ## \
3993 mcdi_field ## _LBN; \
3994 BUILD_BUG_ON( \
3995 MC_CMD_FILTER_OP_IN_ ## mcdi_field ## _LEN < \
3996 sizeof(value)); \
3997 memcpy(MCDI_PTR(inbuf, FILTER_OP_IN_ ## mcdi_field), \
3998 &value, sizeof(value)); \
3999 } while (0)
4000#define COPY_FIELD(gen_flag, gen_field, mcdi_field) \
4001 if (spec->match_flags & EFX_FILTER_MATCH_ ## gen_flag) { \
4002 COPY_VALUE(spec->gen_field, mcdi_field); \
4003 }
4004 /* Handle encap filters first. They will always be mismatch
4005 * (unknown UC or MC) filters
4006 */
4007 if (encap_type) {
4008 /* ether_type and outer_ip_proto need to be variables
4009 * because COPY_VALUE wants to memcpy them
4010 */
4011 __be16 ether_type =
4012 htons(encap_type & EFX_ENCAP_FLAG_IPV6 ?
4013 ETH_P_IPV6 : ETH_P_IP);
4014 u8 vni_type = MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE;
4015 u8 outer_ip_proto;
4016
4017 switch (encap_type & EFX_ENCAP_TYPES_MASK) {
4018 case EFX_ENCAP_TYPE_VXLAN:
4019 vni_type = MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN;
4020 /* fallthrough */
4021 case EFX_ENCAP_TYPE_GENEVE:
4022 COPY_VALUE(ether_type, ETHER_TYPE);
4023 outer_ip_proto = IPPROTO_UDP;
4024 COPY_VALUE(outer_ip_proto, IP_PROTO);
4025 /* We always need to set the type field, even
4026 * though we're not matching on the TNI.
4027 */
4028 MCDI_POPULATE_DWORD_1(inbuf,
4029 FILTER_OP_EXT_IN_VNI_OR_VSID,
4030 FILTER_OP_EXT_IN_VNI_TYPE,
4031 vni_type);
4032 break;
4033 case EFX_ENCAP_TYPE_NVGRE:
4034 COPY_VALUE(ether_type, ETHER_TYPE);
4035 outer_ip_proto = IPPROTO_GRE;
4036 COPY_VALUE(outer_ip_proto, IP_PROTO);
4037 break;
4038 default:
4039 WARN_ON(1);
4040 }
4041
4042 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN;
4043 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN;
4044 } else {
4045 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
4046 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
4047 }
4048
4049 if (spec->match_flags & EFX_FILTER_MATCH_LOC_MAC_IG)
4050 match_fields |=
4051 is_multicast_ether_addr(spec->loc_mac) ?
4052 1 << mc_match :
4053 1 << uc_match;
4054 COPY_FIELD(REM_HOST, rem_host, SRC_IP);
4055 COPY_FIELD(LOC_HOST, loc_host, DST_IP);
4056 COPY_FIELD(REM_MAC, rem_mac, SRC_MAC);
4057 COPY_FIELD(REM_PORT, rem_port, SRC_PORT);
4058 COPY_FIELD(LOC_MAC, loc_mac, DST_MAC);
4059 COPY_FIELD(LOC_PORT, loc_port, DST_PORT);
4060 COPY_FIELD(ETHER_TYPE, ether_type, ETHER_TYPE);
4061 COPY_FIELD(INNER_VID, inner_vid, INNER_VLAN);
4062 COPY_FIELD(OUTER_VID, outer_vid, OUTER_VLAN);
4063 COPY_FIELD(IP_PROTO, ip_proto, IP_PROTO);
4064#undef COPY_FIELD
4065#undef COPY_VALUE
4066 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_MATCH_FIELDS,
4067 match_fields);
4068}
4069
Ben Hutchings8127d662013-08-29 19:19:29 +01004070static void efx_ef10_filter_push_prep(struct efx_nic *efx,
4071 const struct efx_filter_spec *spec,
4072 efx_dword_t *inbuf, u64 handle,
4073 bool replacing)
4074{
4075 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Jon Cooperdcb41232016-04-25 16:51:00 +01004076 u32 flags = spec->flags;
Ben Hutchings8127d662013-08-29 19:19:29 +01004077
Edward Cree9b410802017-01-27 15:02:52 +00004078 memset(inbuf, 0, MC_CMD_FILTER_OP_EXT_IN_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01004079
Jon Cooperdcb41232016-04-25 16:51:00 +01004080 /* Remove RSS flag if we don't have an RSS context. */
4081 if (flags & EFX_FILTER_FLAG_RX_RSS &&
4082 spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT &&
4083 nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID)
4084 flags &= ~EFX_FILTER_FLAG_RX_RSS;
4085
Ben Hutchings8127d662013-08-29 19:19:29 +01004086 if (replacing) {
4087 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
4088 MC_CMD_FILTER_OP_IN_OP_REPLACE);
4089 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE, handle);
4090 } else {
Edward Cree9b410802017-01-27 15:02:52 +00004091 efx_ef10_filter_push_prep_set_match_fields(efx, spec, inbuf);
Ben Hutchings8127d662013-08-29 19:19:29 +01004092 }
4093
Daniel Pieczko45b24492015-05-06 00:57:14 +01004094 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_PORT_ID, nic_data->vport_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01004095 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_DEST,
4096 spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ?
4097 MC_CMD_FILTER_OP_IN_RX_DEST_DROP :
4098 MC_CMD_FILTER_OP_IN_RX_DEST_HOST);
Shradha Shahe3d36292015-05-06 00:56:24 +01004099 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_TX_DOMAIN, 0);
Ben Hutchings8127d662013-08-29 19:19:29 +01004100 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_TX_DEST,
4101 MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT);
Ben Hutchingsa0bc3482013-12-16 18:56:24 +00004102 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_QUEUE,
4103 spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ?
4104 0 : spec->dmaq_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01004105 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE,
Jon Cooperdcb41232016-04-25 16:51:00 +01004106 (flags & EFX_FILTER_FLAG_RX_RSS) ?
Ben Hutchings8127d662013-08-29 19:19:29 +01004107 MC_CMD_FILTER_OP_IN_RX_MODE_RSS :
4108 MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE);
Jon Cooperdcb41232016-04-25 16:51:00 +01004109 if (flags & EFX_FILTER_FLAG_RX_RSS)
Ben Hutchings8127d662013-08-29 19:19:29 +01004110 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT,
4111 spec->rss_context !=
4112 EFX_FILTER_RSS_CONTEXT_DEFAULT ?
4113 spec->rss_context : nic_data->rx_rss_context);
4114}
4115
4116static int efx_ef10_filter_push(struct efx_nic *efx,
4117 const struct efx_filter_spec *spec,
4118 u64 *handle, bool replacing)
4119{
Edward Cree9b410802017-01-27 15:02:52 +00004120 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
4121 MCDI_DECLARE_BUF(outbuf, MC_CMD_FILTER_OP_EXT_OUT_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01004122 int rc;
4123
4124 efx_ef10_filter_push_prep(efx, spec, inbuf, *handle, replacing);
4125 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf),
4126 outbuf, sizeof(outbuf), NULL);
4127 if (rc == 0)
4128 *handle = MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE);
Ben Hutchings065e64c2013-10-09 14:17:27 +01004129 if (rc == -ENOSPC)
4130 rc = -EBUSY; /* to match efx_farch_filter_insert() */
Ben Hutchings8127d662013-08-29 19:19:29 +01004131 return rc;
4132}
4133
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004134static u32 efx_ef10_filter_mcdi_flags_from_spec(const struct efx_filter_spec *spec)
Ben Hutchings8127d662013-08-29 19:19:29 +01004135{
Edward Cree9b410802017-01-27 15:02:52 +00004136 enum efx_encap_type encap_type = efx_filter_get_encap_type(spec);
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004137 unsigned int match_flags = spec->match_flags;
Edward Cree9b410802017-01-27 15:02:52 +00004138 unsigned int uc_match, mc_match;
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004139 u32 mcdi_flags = 0;
4140
Edward Cree9b410802017-01-27 15:02:52 +00004141#define MAP_FILTER_TO_MCDI_FLAG(gen_flag, mcdi_field, encap) { \
4142 unsigned int old_match_flags = match_flags; \
4143 match_flags &= ~EFX_FILTER_MATCH_ ## gen_flag; \
4144 if (match_flags != old_match_flags) \
4145 mcdi_flags |= \
4146 (1 << ((encap) ? \
4147 MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ ## \
4148 mcdi_field ## _LBN : \
4149 MC_CMD_FILTER_OP_EXT_IN_MATCH_ ##\
4150 mcdi_field ## _LBN)); \
4151 }
4152 /* inner or outer based on encap type */
4153 MAP_FILTER_TO_MCDI_FLAG(REM_HOST, SRC_IP, encap_type);
4154 MAP_FILTER_TO_MCDI_FLAG(LOC_HOST, DST_IP, encap_type);
4155 MAP_FILTER_TO_MCDI_FLAG(REM_MAC, SRC_MAC, encap_type);
4156 MAP_FILTER_TO_MCDI_FLAG(REM_PORT, SRC_PORT, encap_type);
4157 MAP_FILTER_TO_MCDI_FLAG(LOC_MAC, DST_MAC, encap_type);
4158 MAP_FILTER_TO_MCDI_FLAG(LOC_PORT, DST_PORT, encap_type);
4159 MAP_FILTER_TO_MCDI_FLAG(ETHER_TYPE, ETHER_TYPE, encap_type);
4160 MAP_FILTER_TO_MCDI_FLAG(IP_PROTO, IP_PROTO, encap_type);
4161 /* always outer */
4162 MAP_FILTER_TO_MCDI_FLAG(INNER_VID, INNER_VLAN, false);
4163 MAP_FILTER_TO_MCDI_FLAG(OUTER_VID, OUTER_VLAN, false);
4164#undef MAP_FILTER_TO_MCDI_FLAG
4165
4166 /* special handling for encap type, and mismatch */
4167 if (encap_type) {
4168 match_flags &= ~EFX_FILTER_MATCH_ENCAP_TYPE;
4169 mcdi_flags |=
4170 (1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN);
4171 mcdi_flags |= (1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN);
4172
4173 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN;
4174 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN;
4175 } else {
4176 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
4177 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
4178 }
4179
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004180 if (match_flags & EFX_FILTER_MATCH_LOC_MAC_IG) {
4181 match_flags &= ~EFX_FILTER_MATCH_LOC_MAC_IG;
4182 mcdi_flags |=
4183 is_multicast_ether_addr(spec->loc_mac) ?
Edward Cree9b410802017-01-27 15:02:52 +00004184 1 << mc_match :
4185 1 << uc_match;
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004186 }
4187
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004188 /* Did we map them all? */
4189 WARN_ON_ONCE(match_flags);
4190
4191 return mcdi_flags;
4192}
4193
4194static int efx_ef10_filter_pri(struct efx_ef10_filter_table *table,
4195 const struct efx_filter_spec *spec)
4196{
4197 u32 mcdi_flags = efx_ef10_filter_mcdi_flags_from_spec(spec);
Ben Hutchings8127d662013-08-29 19:19:29 +01004198 unsigned int match_pri;
4199
4200 for (match_pri = 0;
4201 match_pri < table->rx_match_count;
4202 match_pri++)
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004203 if (table->rx_match_mcdi_flags[match_pri] == mcdi_flags)
Ben Hutchings8127d662013-08-29 19:19:29 +01004204 return match_pri;
4205
4206 return -EPROTONOSUPPORT;
4207}
4208
4209static s32 efx_ef10_filter_insert(struct efx_nic *efx,
4210 struct efx_filter_spec *spec,
4211 bool replace_equal)
4212{
4213 struct efx_ef10_filter_table *table = efx->filter_state;
4214 DECLARE_BITMAP(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
4215 struct efx_filter_spec *saved_spec;
4216 unsigned int match_pri, hash;
4217 unsigned int priv_flags;
4218 bool replacing = false;
4219 int ins_index = -1;
4220 DEFINE_WAIT(wait);
4221 bool is_mc_recip;
4222 s32 rc;
4223
4224 /* For now, only support RX filters */
4225 if ((spec->flags & (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)) !=
4226 EFX_FILTER_FLAG_RX)
4227 return -EINVAL;
4228
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004229 rc = efx_ef10_filter_pri(table, spec);
Ben Hutchings8127d662013-08-29 19:19:29 +01004230 if (rc < 0)
4231 return rc;
4232 match_pri = rc;
4233
4234 hash = efx_ef10_filter_hash(spec);
4235 is_mc_recip = efx_filter_is_mc_recipient(spec);
4236 if (is_mc_recip)
4237 bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
4238
4239 /* Find any existing filters with the same match tuple or
4240 * else a free slot to insert at. If any of them are busy,
4241 * we have to wait and retry.
4242 */
4243 for (;;) {
4244 unsigned int depth = 1;
4245 unsigned int i;
4246
4247 spin_lock_bh(&efx->filter_lock);
4248
4249 for (;;) {
4250 i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1);
4251 saved_spec = efx_ef10_filter_entry_spec(table, i);
4252
4253 if (!saved_spec) {
4254 if (ins_index < 0)
4255 ins_index = i;
4256 } else if (efx_ef10_filter_equal(spec, saved_spec)) {
4257 if (table->entry[i].spec &
4258 EFX_EF10_FILTER_FLAG_BUSY)
4259 break;
4260 if (spec->priority < saved_spec->priority &&
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004261 spec->priority != EFX_FILTER_PRI_AUTO) {
Ben Hutchings8127d662013-08-29 19:19:29 +01004262 rc = -EPERM;
4263 goto out_unlock;
4264 }
4265 if (!is_mc_recip) {
4266 /* This is the only one */
4267 if (spec->priority ==
4268 saved_spec->priority &&
4269 !replace_equal) {
4270 rc = -EEXIST;
4271 goto out_unlock;
4272 }
4273 ins_index = i;
4274 goto found;
4275 } else if (spec->priority >
4276 saved_spec->priority ||
4277 (spec->priority ==
4278 saved_spec->priority &&
4279 replace_equal)) {
4280 if (ins_index < 0)
4281 ins_index = i;
4282 else
4283 __set_bit(depth, mc_rem_map);
4284 }
4285 }
4286
4287 /* Once we reach the maximum search depth, use
4288 * the first suitable slot or return -EBUSY if
4289 * there was none
4290 */
4291 if (depth == EFX_EF10_FILTER_SEARCH_LIMIT) {
4292 if (ins_index < 0) {
4293 rc = -EBUSY;
4294 goto out_unlock;
4295 }
4296 goto found;
4297 }
4298
4299 ++depth;
4300 }
4301
4302 prepare_to_wait(&table->waitq, &wait, TASK_UNINTERRUPTIBLE);
4303 spin_unlock_bh(&efx->filter_lock);
4304 schedule();
4305 }
4306
4307found:
4308 /* Create a software table entry if necessary, and mark it
4309 * busy. We might yet fail to insert, but any attempt to
4310 * insert a conflicting filter while we're waiting for the
4311 * firmware must find the busy entry.
4312 */
4313 saved_spec = efx_ef10_filter_entry_spec(table, ins_index);
4314 if (saved_spec) {
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004315 if (spec->priority == EFX_FILTER_PRI_AUTO &&
4316 saved_spec->priority >= EFX_FILTER_PRI_AUTO) {
Ben Hutchings8127d662013-08-29 19:19:29 +01004317 /* Just make sure it won't be removed */
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004318 if (saved_spec->priority > EFX_FILTER_PRI_AUTO)
4319 saved_spec->flags |= EFX_FILTER_FLAG_RX_OVER_AUTO;
Ben Hutchings8127d662013-08-29 19:19:29 +01004320 table->entry[ins_index].spec &=
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004321 ~EFX_EF10_FILTER_FLAG_AUTO_OLD;
Ben Hutchings8127d662013-08-29 19:19:29 +01004322 rc = ins_index;
4323 goto out_unlock;
4324 }
4325 replacing = true;
4326 priv_flags = efx_ef10_filter_entry_flags(table, ins_index);
4327 } else {
4328 saved_spec = kmalloc(sizeof(*spec), GFP_ATOMIC);
4329 if (!saved_spec) {
4330 rc = -ENOMEM;
4331 goto out_unlock;
4332 }
4333 *saved_spec = *spec;
4334 priv_flags = 0;
4335 }
4336 efx_ef10_filter_set_entry(table, ins_index, saved_spec,
4337 priv_flags | EFX_EF10_FILTER_FLAG_BUSY);
4338
4339 /* Mark lower-priority multicast recipients busy prior to removal */
4340 if (is_mc_recip) {
4341 unsigned int depth, i;
4342
4343 for (depth = 0; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) {
4344 i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1);
4345 if (test_bit(depth, mc_rem_map))
4346 table->entry[i].spec |=
4347 EFX_EF10_FILTER_FLAG_BUSY;
4348 }
4349 }
4350
4351 spin_unlock_bh(&efx->filter_lock);
4352
4353 rc = efx_ef10_filter_push(efx, spec, &table->entry[ins_index].handle,
4354 replacing);
4355
4356 /* Finalise the software table entry */
4357 spin_lock_bh(&efx->filter_lock);
4358 if (rc == 0) {
4359 if (replacing) {
4360 /* Update the fields that may differ */
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004361 if (saved_spec->priority == EFX_FILTER_PRI_AUTO)
4362 saved_spec->flags |=
4363 EFX_FILTER_FLAG_RX_OVER_AUTO;
Ben Hutchings8127d662013-08-29 19:19:29 +01004364 saved_spec->priority = spec->priority;
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004365 saved_spec->flags &= EFX_FILTER_FLAG_RX_OVER_AUTO;
Ben Hutchings8127d662013-08-29 19:19:29 +01004366 saved_spec->flags |= spec->flags;
4367 saved_spec->rss_context = spec->rss_context;
4368 saved_spec->dmaq_id = spec->dmaq_id;
4369 }
4370 } else if (!replacing) {
4371 kfree(saved_spec);
4372 saved_spec = NULL;
4373 }
4374 efx_ef10_filter_set_entry(table, ins_index, saved_spec, priv_flags);
4375
4376 /* Remove and finalise entries for lower-priority multicast
4377 * recipients
4378 */
4379 if (is_mc_recip) {
Martin Habetsbb53f4d2017-06-22 10:50:41 +01004380 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01004381 unsigned int depth, i;
4382
4383 memset(inbuf, 0, sizeof(inbuf));
4384
4385 for (depth = 0; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) {
4386 if (!test_bit(depth, mc_rem_map))
4387 continue;
4388
4389 i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1);
4390 saved_spec = efx_ef10_filter_entry_spec(table, i);
4391 priv_flags = efx_ef10_filter_entry_flags(table, i);
4392
4393 if (rc == 0) {
4394 spin_unlock_bh(&efx->filter_lock);
4395 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
4396 MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
4397 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
4398 table->entry[i].handle);
4399 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP,
4400 inbuf, sizeof(inbuf),
4401 NULL, 0, NULL);
4402 spin_lock_bh(&efx->filter_lock);
4403 }
4404
4405 if (rc == 0) {
4406 kfree(saved_spec);
4407 saved_spec = NULL;
4408 priv_flags = 0;
4409 } else {
4410 priv_flags &= ~EFX_EF10_FILTER_FLAG_BUSY;
4411 }
4412 efx_ef10_filter_set_entry(table, i, saved_spec,
4413 priv_flags);
4414 }
4415 }
4416
4417 /* If successful, return the inserted filter ID */
4418 if (rc == 0)
Jon Cooper0ccb9982017-02-17 15:49:13 +00004419 rc = efx_ef10_make_filter_id(match_pri, ins_index);
Ben Hutchings8127d662013-08-29 19:19:29 +01004420
4421 wake_up_all(&table->waitq);
4422out_unlock:
4423 spin_unlock_bh(&efx->filter_lock);
4424 finish_wait(&table->waitq, &wait);
4425 return rc;
4426}
4427
Fengguang Wu9fd8095d2013-08-31 06:54:05 +08004428static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx)
Ben Hutchings8127d662013-08-29 19:19:29 +01004429{
4430 /* no need to do anything here on EF10 */
4431}
4432
4433/* Remove a filter.
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004434 * If !by_index, remove by ID
4435 * If by_index, remove by index
Ben Hutchings8127d662013-08-29 19:19:29 +01004436 * Filter ID may come from userland and must be range-checked.
4437 */
4438static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004439 unsigned int priority_mask,
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004440 u32 filter_id, bool by_index)
Ben Hutchings8127d662013-08-29 19:19:29 +01004441{
Jon Cooper0ccb9982017-02-17 15:49:13 +00004442 unsigned int filter_idx = efx_ef10_filter_get_unsafe_id(filter_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01004443 struct efx_ef10_filter_table *table = efx->filter_state;
4444 MCDI_DECLARE_BUF(inbuf,
4445 MC_CMD_FILTER_OP_IN_HANDLE_OFST +
4446 MC_CMD_FILTER_OP_IN_HANDLE_LEN);
4447 struct efx_filter_spec *spec;
4448 DEFINE_WAIT(wait);
4449 int rc;
4450
4451 /* Find the software table entry and mark it busy. Don't
4452 * remove it yet; any attempt to update while we're waiting
4453 * for the firmware must find the busy entry.
4454 */
4455 for (;;) {
4456 spin_lock_bh(&efx->filter_lock);
4457 if (!(table->entry[filter_idx].spec &
4458 EFX_EF10_FILTER_FLAG_BUSY))
4459 break;
4460 prepare_to_wait(&table->waitq, &wait, TASK_UNINTERRUPTIBLE);
4461 spin_unlock_bh(&efx->filter_lock);
4462 schedule();
4463 }
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004464
Ben Hutchings8127d662013-08-29 19:19:29 +01004465 spec = efx_ef10_filter_entry_spec(table, filter_idx);
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004466 if (!spec ||
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004467 (!by_index &&
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004468 efx_ef10_filter_pri(table, spec) !=
Jon Cooper0ccb9982017-02-17 15:49:13 +00004469 efx_ef10_filter_get_unsafe_pri(filter_id))) {
Ben Hutchings8127d662013-08-29 19:19:29 +01004470 rc = -ENOENT;
4471 goto out_unlock;
4472 }
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004473
4474 if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO &&
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004475 priority_mask == (1U << EFX_FILTER_PRI_AUTO)) {
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004476 /* Just remove flags */
4477 spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO;
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004478 table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD;
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004479 rc = 0;
4480 goto out_unlock;
4481 }
4482
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004483 if (!(priority_mask & (1U << spec->priority))) {
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004484 rc = -ENOENT;
4485 goto out_unlock;
4486 }
4487
Ben Hutchings8127d662013-08-29 19:19:29 +01004488 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY;
4489 spin_unlock_bh(&efx->filter_lock);
4490
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004491 if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) {
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00004492 /* Reset to an automatic filter */
Ben Hutchings8127d662013-08-29 19:19:29 +01004493
4494 struct efx_filter_spec new_spec = *spec;
4495
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004496 new_spec.priority = EFX_FILTER_PRI_AUTO;
Ben Hutchings8127d662013-08-29 19:19:29 +01004497 new_spec.flags = (EFX_FILTER_FLAG_RX |
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00004498 (efx_rss_enabled(efx) ?
4499 EFX_FILTER_FLAG_RX_RSS : 0));
Ben Hutchings8127d662013-08-29 19:19:29 +01004500 new_spec.dmaq_id = 0;
4501 new_spec.rss_context = EFX_FILTER_RSS_CONTEXT_DEFAULT;
4502 rc = efx_ef10_filter_push(efx, &new_spec,
4503 &table->entry[filter_idx].handle,
4504 true);
4505
4506 spin_lock_bh(&efx->filter_lock);
4507 if (rc == 0)
4508 *spec = new_spec;
4509 } else {
4510 /* Really remove the filter */
4511
4512 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
4513 efx_ef10_filter_is_exclusive(spec) ?
4514 MC_CMD_FILTER_OP_IN_OP_REMOVE :
4515 MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
4516 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
4517 table->entry[filter_idx].handle);
Bert Kenward105eac62017-02-17 15:50:12 +00004518 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP,
4519 inbuf, sizeof(inbuf), NULL, 0, NULL);
Ben Hutchings8127d662013-08-29 19:19:29 +01004520
4521 spin_lock_bh(&efx->filter_lock);
Bert Kenward105eac62017-02-17 15:50:12 +00004522 if ((rc == 0) || (rc == -ENOENT)) {
4523 /* Filter removed OK or didn't actually exist */
Ben Hutchings8127d662013-08-29 19:19:29 +01004524 kfree(spec);
4525 efx_ef10_filter_set_entry(table, filter_idx, NULL, 0);
Bert Kenward105eac62017-02-17 15:50:12 +00004526 } else {
4527 efx_mcdi_display_error(efx, MC_CMD_FILTER_OP,
Martin Habetsbb53f4d2017-06-22 10:50:41 +01004528 MC_CMD_FILTER_OP_EXT_IN_LEN,
Bert Kenward105eac62017-02-17 15:50:12 +00004529 NULL, 0, rc);
Ben Hutchings8127d662013-08-29 19:19:29 +01004530 }
4531 }
Ben Hutchings7665d1a2013-11-21 19:02:18 +00004532
Ben Hutchings8127d662013-08-29 19:19:29 +01004533 table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_BUSY;
4534 wake_up_all(&table->waitq);
4535out_unlock:
4536 spin_unlock_bh(&efx->filter_lock);
4537 finish_wait(&table->waitq, &wait);
4538 return rc;
4539}
4540
4541static int efx_ef10_filter_remove_safe(struct efx_nic *efx,
4542 enum efx_filter_priority priority,
4543 u32 filter_id)
4544{
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004545 return efx_ef10_filter_remove_internal(efx, 1U << priority,
4546 filter_id, false);
Ben Hutchings8127d662013-08-29 19:19:29 +01004547}
4548
Edward Cree8c915622016-06-15 17:49:05 +01004549static void efx_ef10_filter_remove_unsafe(struct efx_nic *efx,
4550 enum efx_filter_priority priority,
4551 u32 filter_id)
Edward Cree12fb0da2015-07-21 15:11:00 +01004552{
Edward Cree8c915622016-06-15 17:49:05 +01004553 if (filter_id == EFX_EF10_FILTER_ID_INVALID)
4554 return;
4555 efx_ef10_filter_remove_internal(efx, 1U << priority, filter_id, true);
Edward Cree12fb0da2015-07-21 15:11:00 +01004556}
4557
Ben Hutchings8127d662013-08-29 19:19:29 +01004558static int efx_ef10_filter_get_safe(struct efx_nic *efx,
4559 enum efx_filter_priority priority,
4560 u32 filter_id, struct efx_filter_spec *spec)
4561{
Jon Cooper0ccb9982017-02-17 15:49:13 +00004562 unsigned int filter_idx = efx_ef10_filter_get_unsafe_id(filter_id);
Ben Hutchings8127d662013-08-29 19:19:29 +01004563 struct efx_ef10_filter_table *table = efx->filter_state;
4564 const struct efx_filter_spec *saved_spec;
4565 int rc;
4566
4567 spin_lock_bh(&efx->filter_lock);
4568 saved_spec = efx_ef10_filter_entry_spec(table, filter_idx);
4569 if (saved_spec && saved_spec->priority == priority &&
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004570 efx_ef10_filter_pri(table, saved_spec) ==
Jon Cooper0ccb9982017-02-17 15:49:13 +00004571 efx_ef10_filter_get_unsafe_pri(filter_id)) {
Ben Hutchings8127d662013-08-29 19:19:29 +01004572 *spec = *saved_spec;
4573 rc = 0;
4574 } else {
4575 rc = -ENOENT;
4576 }
4577 spin_unlock_bh(&efx->filter_lock);
4578 return rc;
4579}
4580
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004581static int efx_ef10_filter_clear_rx(struct efx_nic *efx,
Ben Hutchings8127d662013-08-29 19:19:29 +01004582 enum efx_filter_priority priority)
4583{
Ben Hutchingsfbd79122013-11-21 19:15:03 +00004584 unsigned int priority_mask;
4585 unsigned int i;
4586 int rc;
4587
4588 priority_mask = (((1U << (priority + 1)) - 1) &
4589 ~(1U << EFX_FILTER_PRI_AUTO));
4590
4591 for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) {
4592 rc = efx_ef10_filter_remove_internal(efx, priority_mask,
4593 i, true);
4594 if (rc && rc != -ENOENT)
4595 return rc;
4596 }
4597
4598 return 0;
Ben Hutchings8127d662013-08-29 19:19:29 +01004599}
4600
4601static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx,
4602 enum efx_filter_priority priority)
4603{
4604 struct efx_ef10_filter_table *table = efx->filter_state;
4605 unsigned int filter_idx;
4606 s32 count = 0;
4607
4608 spin_lock_bh(&efx->filter_lock);
4609 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) {
4610 if (table->entry[filter_idx].spec &&
4611 efx_ef10_filter_entry_spec(table, filter_idx)->priority ==
4612 priority)
4613 ++count;
4614 }
4615 spin_unlock_bh(&efx->filter_lock);
4616 return count;
4617}
4618
4619static u32 efx_ef10_filter_get_rx_id_limit(struct efx_nic *efx)
4620{
4621 struct efx_ef10_filter_table *table = efx->filter_state;
4622
Jon Cooper0ccb9982017-02-17 15:49:13 +00004623 return table->rx_match_count * HUNT_FILTER_TBL_ROWS * 2;
Ben Hutchings8127d662013-08-29 19:19:29 +01004624}
4625
4626static s32 efx_ef10_filter_get_rx_ids(struct efx_nic *efx,
4627 enum efx_filter_priority priority,
4628 u32 *buf, u32 size)
4629{
4630 struct efx_ef10_filter_table *table = efx->filter_state;
4631 struct efx_filter_spec *spec;
4632 unsigned int filter_idx;
4633 s32 count = 0;
4634
4635 spin_lock_bh(&efx->filter_lock);
4636 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) {
4637 spec = efx_ef10_filter_entry_spec(table, filter_idx);
4638 if (spec && spec->priority == priority) {
4639 if (count == size) {
4640 count = -EMSGSIZE;
4641 break;
4642 }
Jon Cooper0ccb9982017-02-17 15:49:13 +00004643 buf[count++] =
4644 efx_ef10_make_filter_id(
4645 efx_ef10_filter_pri(table, spec),
Ben Hutchings8127d662013-08-29 19:19:29 +01004646 filter_idx);
4647 }
4648 }
4649 spin_unlock_bh(&efx->filter_lock);
4650 return count;
4651}
4652
4653#ifdef CONFIG_RFS_ACCEL
4654
4655static efx_mcdi_async_completer efx_ef10_filter_rfs_insert_complete;
4656
4657static s32 efx_ef10_filter_rfs_insert(struct efx_nic *efx,
4658 struct efx_filter_spec *spec)
4659{
4660 struct efx_ef10_filter_table *table = efx->filter_state;
Martin Habetsbb53f4d2017-06-22 10:50:41 +01004661 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01004662 struct efx_filter_spec *saved_spec;
4663 unsigned int hash, i, depth = 1;
4664 bool replacing = false;
4665 int ins_index = -1;
4666 u64 cookie;
4667 s32 rc;
4668
4669 /* Must be an RX filter without RSS and not for a multicast
4670 * destination address (RFS only works for connected sockets).
4671 * These restrictions allow us to pass only a tiny amount of
4672 * data through to the completion function.
4673 */
4674 EFX_WARN_ON_PARANOID(spec->flags !=
4675 (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_SCATTER));
4676 EFX_WARN_ON_PARANOID(spec->priority != EFX_FILTER_PRI_HINT);
4677 EFX_WARN_ON_PARANOID(efx_filter_is_mc_recipient(spec));
4678
4679 hash = efx_ef10_filter_hash(spec);
4680
4681 spin_lock_bh(&efx->filter_lock);
4682
4683 /* Find any existing filter with the same match tuple or else
4684 * a free slot to insert at. If an existing filter is busy,
4685 * we have to give up.
4686 */
4687 for (;;) {
4688 i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1);
4689 saved_spec = efx_ef10_filter_entry_spec(table, i);
4690
4691 if (!saved_spec) {
4692 if (ins_index < 0)
4693 ins_index = i;
4694 } else if (efx_ef10_filter_equal(spec, saved_spec)) {
4695 if (table->entry[i].spec & EFX_EF10_FILTER_FLAG_BUSY) {
4696 rc = -EBUSY;
4697 goto fail_unlock;
4698 }
Ben Hutchings8127d662013-08-29 19:19:29 +01004699 if (spec->priority < saved_spec->priority) {
4700 rc = -EPERM;
4701 goto fail_unlock;
4702 }
4703 ins_index = i;
4704 break;
4705 }
4706
4707 /* Once we reach the maximum search depth, use the
4708 * first suitable slot or return -EBUSY if there was
4709 * none
4710 */
4711 if (depth == EFX_EF10_FILTER_SEARCH_LIMIT) {
4712 if (ins_index < 0) {
4713 rc = -EBUSY;
4714 goto fail_unlock;
4715 }
4716 break;
4717 }
4718
4719 ++depth;
4720 }
4721
4722 /* Create a software table entry if necessary, and mark it
4723 * busy. We might yet fail to insert, but any attempt to
4724 * insert a conflicting filter while we're waiting for the
4725 * firmware must find the busy entry.
4726 */
4727 saved_spec = efx_ef10_filter_entry_spec(table, ins_index);
4728 if (saved_spec) {
4729 replacing = true;
4730 } else {
4731 saved_spec = kmalloc(sizeof(*spec), GFP_ATOMIC);
4732 if (!saved_spec) {
4733 rc = -ENOMEM;
4734 goto fail_unlock;
4735 }
4736 *saved_spec = *spec;
4737 }
4738 efx_ef10_filter_set_entry(table, ins_index, saved_spec,
4739 EFX_EF10_FILTER_FLAG_BUSY);
4740
4741 spin_unlock_bh(&efx->filter_lock);
4742
4743 /* Pack up the variables needed on completion */
4744 cookie = replacing << 31 | ins_index << 16 | spec->dmaq_id;
4745
4746 efx_ef10_filter_push_prep(efx, spec, inbuf,
4747 table->entry[ins_index].handle, replacing);
4748 efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf),
4749 MC_CMD_FILTER_OP_OUT_LEN,
4750 efx_ef10_filter_rfs_insert_complete, cookie);
4751
4752 return ins_index;
4753
4754fail_unlock:
4755 spin_unlock_bh(&efx->filter_lock);
4756 return rc;
4757}
4758
4759static void
4760efx_ef10_filter_rfs_insert_complete(struct efx_nic *efx, unsigned long cookie,
4761 int rc, efx_dword_t *outbuf,
4762 size_t outlen_actual)
4763{
4764 struct efx_ef10_filter_table *table = efx->filter_state;
4765 unsigned int ins_index, dmaq_id;
4766 struct efx_filter_spec *spec;
4767 bool replacing;
4768
4769 /* Unpack the cookie */
4770 replacing = cookie >> 31;
4771 ins_index = (cookie >> 16) & (HUNT_FILTER_TBL_ROWS - 1);
4772 dmaq_id = cookie & 0xffff;
4773
4774 spin_lock_bh(&efx->filter_lock);
4775 spec = efx_ef10_filter_entry_spec(table, ins_index);
4776 if (rc == 0) {
4777 table->entry[ins_index].handle =
4778 MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE);
4779 if (replacing)
4780 spec->dmaq_id = dmaq_id;
4781 } else if (!replacing) {
4782 kfree(spec);
4783 spec = NULL;
4784 }
4785 efx_ef10_filter_set_entry(table, ins_index, spec, 0);
4786 spin_unlock_bh(&efx->filter_lock);
4787
4788 wake_up_all(&table->waitq);
4789}
4790
4791static void
4792efx_ef10_filter_rfs_expire_complete(struct efx_nic *efx,
4793 unsigned long filter_idx,
4794 int rc, efx_dword_t *outbuf,
4795 size_t outlen_actual);
4796
4797static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
4798 unsigned int filter_idx)
4799{
4800 struct efx_ef10_filter_table *table = efx->filter_state;
4801 struct efx_filter_spec *spec =
4802 efx_ef10_filter_entry_spec(table, filter_idx);
4803 MCDI_DECLARE_BUF(inbuf,
4804 MC_CMD_FILTER_OP_IN_HANDLE_OFST +
4805 MC_CMD_FILTER_OP_IN_HANDLE_LEN);
4806
4807 if (!spec ||
4808 (table->entry[filter_idx].spec & EFX_EF10_FILTER_FLAG_BUSY) ||
4809 spec->priority != EFX_FILTER_PRI_HINT ||
4810 !rps_may_expire_flow(efx->net_dev, spec->dmaq_id,
4811 flow_id, filter_idx))
4812 return false;
4813
4814 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
4815 MC_CMD_FILTER_OP_IN_OP_REMOVE);
4816 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
4817 table->entry[filter_idx].handle);
4818 if (efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf), 0,
4819 efx_ef10_filter_rfs_expire_complete, filter_idx))
4820 return false;
4821
4822 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY;
4823 return true;
4824}
4825
4826static void
4827efx_ef10_filter_rfs_expire_complete(struct efx_nic *efx,
4828 unsigned long filter_idx,
4829 int rc, efx_dword_t *outbuf,
4830 size_t outlen_actual)
4831{
4832 struct efx_ef10_filter_table *table = efx->filter_state;
4833 struct efx_filter_spec *spec =
4834 efx_ef10_filter_entry_spec(table, filter_idx);
4835
4836 spin_lock_bh(&efx->filter_lock);
4837 if (rc == 0) {
4838 kfree(spec);
4839 efx_ef10_filter_set_entry(table, filter_idx, NULL, 0);
4840 }
4841 table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_BUSY;
4842 wake_up_all(&table->waitq);
4843 spin_unlock_bh(&efx->filter_lock);
4844}
4845
4846#endif /* CONFIG_RFS_ACCEL */
4847
Edward Cree9b410802017-01-27 15:02:52 +00004848static int efx_ef10_filter_match_flags_from_mcdi(bool encap, u32 mcdi_flags)
Ben Hutchings8127d662013-08-29 19:19:29 +01004849{
4850 int match_flags = 0;
4851
Edward Cree9b410802017-01-27 15:02:52 +00004852#define MAP_FLAG(gen_flag, mcdi_field) do { \
Ben Hutchings8127d662013-08-29 19:19:29 +01004853 u32 old_mcdi_flags = mcdi_flags; \
Edward Cree9b410802017-01-27 15:02:52 +00004854 mcdi_flags &= ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ ## \
4855 mcdi_field ## _LBN); \
Ben Hutchings8127d662013-08-29 19:19:29 +01004856 if (mcdi_flags != old_mcdi_flags) \
4857 match_flags |= EFX_FILTER_MATCH_ ## gen_flag; \
Edward Cree9b410802017-01-27 15:02:52 +00004858 } while (0)
4859
4860 if (encap) {
4861 /* encap filters must specify encap type */
4862 match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
4863 /* and imply ethertype and ip proto */
4864 mcdi_flags &=
4865 ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN);
4866 mcdi_flags &=
4867 ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN);
4868 /* VLAN tags refer to the outer packet */
4869 MAP_FLAG(INNER_VID, INNER_VLAN);
4870 MAP_FLAG(OUTER_VID, OUTER_VLAN);
4871 /* everything else refers to the inner packet */
4872 MAP_FLAG(LOC_MAC_IG, IFRM_UNKNOWN_UCAST_DST);
4873 MAP_FLAG(LOC_MAC_IG, IFRM_UNKNOWN_MCAST_DST);
4874 MAP_FLAG(REM_HOST, IFRM_SRC_IP);
4875 MAP_FLAG(LOC_HOST, IFRM_DST_IP);
4876 MAP_FLAG(REM_MAC, IFRM_SRC_MAC);
4877 MAP_FLAG(REM_PORT, IFRM_SRC_PORT);
4878 MAP_FLAG(LOC_MAC, IFRM_DST_MAC);
4879 MAP_FLAG(LOC_PORT, IFRM_DST_PORT);
4880 MAP_FLAG(ETHER_TYPE, IFRM_ETHER_TYPE);
4881 MAP_FLAG(IP_PROTO, IFRM_IP_PROTO);
4882 } else {
4883 MAP_FLAG(LOC_MAC_IG, UNKNOWN_UCAST_DST);
4884 MAP_FLAG(LOC_MAC_IG, UNKNOWN_MCAST_DST);
4885 MAP_FLAG(REM_HOST, SRC_IP);
4886 MAP_FLAG(LOC_HOST, DST_IP);
4887 MAP_FLAG(REM_MAC, SRC_MAC);
4888 MAP_FLAG(REM_PORT, SRC_PORT);
4889 MAP_FLAG(LOC_MAC, DST_MAC);
4890 MAP_FLAG(LOC_PORT, DST_PORT);
4891 MAP_FLAG(ETHER_TYPE, ETHER_TYPE);
4892 MAP_FLAG(INNER_VID, INNER_VLAN);
4893 MAP_FLAG(OUTER_VID, OUTER_VLAN);
4894 MAP_FLAG(IP_PROTO, IP_PROTO);
Ben Hutchings8127d662013-08-29 19:19:29 +01004895 }
Ben Hutchings8127d662013-08-29 19:19:29 +01004896#undef MAP_FLAG
4897
4898 /* Did we map them all? */
4899 if (mcdi_flags)
4900 return -EINVAL;
4901
4902 return match_flags;
4903}
4904
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01004905static void efx_ef10_filter_cleanup_vlans(struct efx_nic *efx)
4906{
4907 struct efx_ef10_filter_table *table = efx->filter_state;
4908 struct efx_ef10_filter_vlan *vlan, *next_vlan;
4909
4910 /* See comment in efx_ef10_filter_table_remove() */
4911 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
4912 return;
4913
4914 if (!table)
4915 return;
4916
4917 list_for_each_entry_safe(vlan, next_vlan, &table->vlan_list, list)
4918 efx_ef10_filter_del_vlan_internal(efx, vlan);
4919}
4920
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004921static bool efx_ef10_filter_match_supported(struct efx_ef10_filter_table *table,
Edward Cree9b410802017-01-27 15:02:52 +00004922 bool encap,
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004923 enum efx_filter_match_flags match_flags)
4924{
4925 unsigned int match_pri;
4926 int mf;
4927
4928 for (match_pri = 0;
4929 match_pri < table->rx_match_count;
4930 match_pri++) {
Edward Cree9b410802017-01-27 15:02:52 +00004931 mf = efx_ef10_filter_match_flags_from_mcdi(encap,
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004932 table->rx_match_mcdi_flags[match_pri]);
4933 if (mf == match_flags)
4934 return true;
4935 }
4936
4937 return false;
4938}
4939
Edward Cree9b410802017-01-27 15:02:52 +00004940static int
4941efx_ef10_filter_table_probe_matches(struct efx_nic *efx,
4942 struct efx_ef10_filter_table *table,
4943 bool encap)
Ben Hutchings8127d662013-08-29 19:19:29 +01004944{
4945 MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN);
4946 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX);
4947 unsigned int pd_match_pri, pd_match_count;
Ben Hutchings8127d662013-08-29 19:19:29 +01004948 size_t outlen;
4949 int rc;
4950
Ben Hutchings8127d662013-08-29 19:19:29 +01004951 /* Find out which RX filter types are supported, and their priorities */
4952 MCDI_SET_DWORD(inbuf, GET_PARSER_DISP_INFO_IN_OP,
Edward Cree9b410802017-01-27 15:02:52 +00004953 encap ?
4954 MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES :
Ben Hutchings8127d662013-08-29 19:19:29 +01004955 MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
4956 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PARSER_DISP_INFO,
4957 inbuf, sizeof(inbuf), outbuf, sizeof(outbuf),
4958 &outlen);
4959 if (rc)
Edward Cree9b410802017-01-27 15:02:52 +00004960 return rc;
4961
Ben Hutchings8127d662013-08-29 19:19:29 +01004962 pd_match_count = MCDI_VAR_ARRAY_LEN(
4963 outlen, GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES);
Ben Hutchings8127d662013-08-29 19:19:29 +01004964
4965 for (pd_match_pri = 0; pd_match_pri < pd_match_count; pd_match_pri++) {
4966 u32 mcdi_flags =
4967 MCDI_ARRAY_DWORD(
4968 outbuf,
4969 GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES,
4970 pd_match_pri);
Edward Cree9b410802017-01-27 15:02:52 +00004971 rc = efx_ef10_filter_match_flags_from_mcdi(encap, mcdi_flags);
Ben Hutchings8127d662013-08-29 19:19:29 +01004972 if (rc < 0) {
4973 netif_dbg(efx, probe, efx->net_dev,
4974 "%s: fw flags %#x pri %u not supported in driver\n",
4975 __func__, mcdi_flags, pd_match_pri);
4976 } else {
4977 netif_dbg(efx, probe, efx->net_dev,
4978 "%s: fw flags %#x pri %u supported as driver flags %#x pri %u\n",
4979 __func__, mcdi_flags, pd_match_pri,
4980 rc, table->rx_match_count);
Andrew Rybchenko7ac0dd92016-06-15 17:49:30 +01004981 table->rx_match_mcdi_flags[table->rx_match_count] = mcdi_flags;
4982 table->rx_match_count++;
Ben Hutchings8127d662013-08-29 19:19:29 +01004983 }
4984 }
4985
Edward Cree9b410802017-01-27 15:02:52 +00004986 return 0;
4987}
4988
4989static int efx_ef10_filter_table_probe(struct efx_nic *efx)
4990{
4991 struct efx_ef10_nic_data *nic_data = efx->nic_data;
4992 struct net_device *net_dev = efx->net_dev;
4993 struct efx_ef10_filter_table *table;
4994 struct efx_ef10_vlan *vlan;
4995 int rc;
4996
4997 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
4998 return -EINVAL;
4999
5000 if (efx->filter_state) /* already probed */
5001 return 0;
5002
5003 table = kzalloc(sizeof(*table), GFP_KERNEL);
5004 if (!table)
5005 return -ENOMEM;
5006
5007 table->rx_match_count = 0;
5008 rc = efx_ef10_filter_table_probe_matches(efx, table, false);
5009 if (rc)
5010 goto fail;
5011 if (nic_data->datapath_caps &
5012 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN))
5013 rc = efx_ef10_filter_table_probe_matches(efx, table, true);
5014 if (rc)
5015 goto fail;
Martin Habetse4478ad2016-06-15 17:51:07 +01005016 if ((efx_supported_features(efx) & NETIF_F_HW_VLAN_CTAG_FILTER) &&
Edward Cree9b410802017-01-27 15:02:52 +00005017 !(efx_ef10_filter_match_supported(table, false,
Martin Habetse4478ad2016-06-15 17:51:07 +01005018 (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC)) &&
Edward Cree9b410802017-01-27 15:02:52 +00005019 efx_ef10_filter_match_supported(table, false,
Martin Habetse4478ad2016-06-15 17:51:07 +01005020 (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC_IG)))) {
5021 netif_info(efx, probe, net_dev,
5022 "VLAN filters are not supported in this firmware variant\n");
5023 net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
5024 efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
5025 net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
5026 }
5027
Ben Hutchings8127d662013-08-29 19:19:29 +01005028 table->entry = vzalloc(HUNT_FILTER_TBL_ROWS * sizeof(*table->entry));
5029 if (!table->entry) {
5030 rc = -ENOMEM;
5031 goto fail;
5032 }
5033
Andrew Rybchenkob071c3a2016-06-15 17:43:00 +01005034 table->mc_promisc_last = false;
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01005035 table->vlan_filter =
5036 !!(efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005037 INIT_LIST_HEAD(&table->vlan_list);
Edward Cree12fb0da2015-07-21 15:11:00 +01005038
Ben Hutchings8127d662013-08-29 19:19:29 +01005039 efx->filter_state = table;
5040 init_waitqueue_head(&table->waitq);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005041
5042 list_for_each_entry(vlan, &nic_data->vlan_list, list) {
5043 rc = efx_ef10_filter_add_vlan(efx, vlan->vid);
5044 if (rc)
5045 goto fail_add_vlan;
5046 }
5047
Ben Hutchings8127d662013-08-29 19:19:29 +01005048 return 0;
5049
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005050fail_add_vlan:
5051 efx_ef10_filter_cleanup_vlans(efx);
5052 efx->filter_state = NULL;
Ben Hutchings8127d662013-08-29 19:19:29 +01005053fail:
5054 kfree(table);
5055 return rc;
5056}
5057
Edward Cree0d322412015-05-20 11:10:03 +01005058/* Caller must hold efx->filter_sem for read if race against
5059 * efx_ef10_filter_table_remove() is possible
5060 */
Ben Hutchings8127d662013-08-29 19:19:29 +01005061static void efx_ef10_filter_table_restore(struct efx_nic *efx)
5062{
5063 struct efx_ef10_filter_table *table = efx->filter_state;
5064 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005065 unsigned int invalid_filters = 0, failed = 0;
5066 struct efx_ef10_filter_vlan *vlan;
Ben Hutchings8127d662013-08-29 19:19:29 +01005067 struct efx_filter_spec *spec;
5068 unsigned int filter_idx;
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005069 u32 mcdi_flags;
5070 int match_pri;
Edward Cree9b410802017-01-27 15:02:52 +00005071 int rc, i;
Ben Hutchings8127d662013-08-29 19:19:29 +01005072
Edward Cree0d322412015-05-20 11:10:03 +01005073 WARN_ON(!rwsem_is_locked(&efx->filter_sem));
5074
Ben Hutchings8127d662013-08-29 19:19:29 +01005075 if (!nic_data->must_restore_filters)
5076 return;
5077
Edward Cree0d322412015-05-20 11:10:03 +01005078 if (!table)
5079 return;
5080
Ben Hutchings8127d662013-08-29 19:19:29 +01005081 spin_lock_bh(&efx->filter_lock);
5082
5083 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) {
5084 spec = efx_ef10_filter_entry_spec(table, filter_idx);
5085 if (!spec)
5086 continue;
5087
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005088 mcdi_flags = efx_ef10_filter_mcdi_flags_from_spec(spec);
5089 match_pri = 0;
5090 while (match_pri < table->rx_match_count &&
5091 table->rx_match_mcdi_flags[match_pri] != mcdi_flags)
5092 ++match_pri;
5093 if (match_pri >= table->rx_match_count) {
5094 invalid_filters++;
5095 goto not_restored;
5096 }
5097 if (spec->rss_context != EFX_FILTER_RSS_CONTEXT_DEFAULT &&
5098 spec->rss_context != nic_data->rx_rss_context)
5099 netif_warn(efx, drv, efx->net_dev,
5100 "Warning: unable to restore a filter with specific RSS context.\n");
5101
Ben Hutchings8127d662013-08-29 19:19:29 +01005102 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY;
5103 spin_unlock_bh(&efx->filter_lock);
5104
5105 rc = efx_ef10_filter_push(efx, spec,
5106 &table->entry[filter_idx].handle,
5107 false);
5108 if (rc)
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005109 failed++;
Ben Hutchings8127d662013-08-29 19:19:29 +01005110 spin_lock_bh(&efx->filter_lock);
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005111
Ben Hutchings8127d662013-08-29 19:19:29 +01005112 if (rc) {
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005113not_restored:
Edward Cree9b410802017-01-27 15:02:52 +00005114 list_for_each_entry(vlan, &table->vlan_list, list)
5115 for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; ++i)
5116 if (vlan->default_filters[i] == filter_idx)
5117 vlan->default_filters[i] =
5118 EFX_EF10_FILTER_ID_INVALID;
5119
Ben Hutchings8127d662013-08-29 19:19:29 +01005120 kfree(spec);
5121 efx_ef10_filter_set_entry(table, filter_idx, NULL, 0);
5122 } else {
5123 table->entry[filter_idx].spec &=
5124 ~EFX_EF10_FILTER_FLAG_BUSY;
5125 }
5126 }
5127
5128 spin_unlock_bh(&efx->filter_lock);
5129
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005130 /* This can happen validly if the MC's capabilities have changed, so
5131 * is not an error.
5132 */
5133 if (invalid_filters)
5134 netif_dbg(efx, drv, efx->net_dev,
5135 "Did not restore %u filters that are now unsupported.\n",
5136 invalid_filters);
5137
Ben Hutchings8127d662013-08-29 19:19:29 +01005138 if (failed)
5139 netif_err(efx, hw, efx->net_dev,
Jon Cooper2d3d4ec2017-01-27 15:02:11 +00005140 "unable to restore %u filters\n", failed);
Ben Hutchings8127d662013-08-29 19:19:29 +01005141 else
5142 nic_data->must_restore_filters = false;
5143}
5144
5145static void efx_ef10_filter_table_remove(struct efx_nic *efx)
5146{
5147 struct efx_ef10_filter_table *table = efx->filter_state;
Martin Habetsbb53f4d2017-06-22 10:50:41 +01005148 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
Ben Hutchings8127d662013-08-29 19:19:29 +01005149 struct efx_filter_spec *spec;
5150 unsigned int filter_idx;
5151 int rc;
5152
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005153 efx_ef10_filter_cleanup_vlans(efx);
Edward Cree0d322412015-05-20 11:10:03 +01005154 efx->filter_state = NULL;
Edward Creedd987082016-06-15 17:43:43 +01005155 /* If we were called without locking, then it's not safe to free
5156 * the table as others might be using it. So we just WARN, leak
5157 * the memory, and potentially get an inconsistent filter table
5158 * state.
5159 * This should never actually happen.
5160 */
5161 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
5162 return;
5163
Edward Cree0d322412015-05-20 11:10:03 +01005164 if (!table)
5165 return;
5166
Ben Hutchings8127d662013-08-29 19:19:29 +01005167 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) {
5168 spec = efx_ef10_filter_entry_spec(table, filter_idx);
5169 if (!spec)
5170 continue;
5171
5172 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
5173 efx_ef10_filter_is_exclusive(spec) ?
5174 MC_CMD_FILTER_OP_IN_OP_REMOVE :
5175 MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
5176 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
5177 table->entry[filter_idx].handle);
Bert Kenwarde65a5102015-12-23 08:57:36 +00005178 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP, inbuf,
5179 sizeof(inbuf), NULL, 0, NULL);
Ben Hutchings48ce5632013-11-01 16:42:44 +00005180 if (rc)
Bert Kenwarde65a5102015-12-23 08:57:36 +00005181 netif_info(efx, drv, efx->net_dev,
5182 "%s: filter %04x remove failed\n",
5183 __func__, filter_idx);
Ben Hutchings8127d662013-08-29 19:19:29 +01005184 kfree(spec);
5185 }
5186
5187 vfree(table->entry);
5188 kfree(table);
5189}
5190
Andrew Rybchenko6a379582016-06-15 17:44:20 +01005191static void efx_ef10_filter_mark_one_old(struct efx_nic *efx, uint16_t *id)
5192{
5193 struct efx_ef10_filter_table *table = efx->filter_state;
5194 unsigned int filter_idx;
5195
5196 if (*id != EFX_EF10_FILTER_ID_INVALID) {
Jon Cooper0ccb9982017-02-17 15:49:13 +00005197 filter_idx = efx_ef10_filter_get_unsafe_id(*id);
Andrew Rybchenko6a379582016-06-15 17:44:20 +01005198 if (!table->entry[filter_idx].spec)
5199 netif_dbg(efx, drv, efx->net_dev,
5200 "marked null spec old %04x:%04x\n", *id,
5201 filter_idx);
5202 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_AUTO_OLD;
5203 *id = EFX_EF10_FILTER_ID_INVALID;
Bert Kenwarde65a5102015-12-23 08:57:36 +00005204 }
Andrew Rybchenko6a379582016-06-15 17:44:20 +01005205}
5206
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005207/* Mark old per-VLAN filters that may need to be removed */
5208static void _efx_ef10_filter_vlan_mark_old(struct efx_nic *efx,
5209 struct efx_ef10_filter_vlan *vlan)
Ben Hutchings8127d662013-08-29 19:19:29 +01005210{
5211 struct efx_ef10_filter_table *table = efx->filter_state;
Andrew Rybchenko6a379582016-06-15 17:44:20 +01005212 unsigned int i;
Ben Hutchings8127d662013-08-29 19:19:29 +01005213
Edward Cree12fb0da2015-07-21 15:11:00 +01005214 for (i = 0; i < table->dev_uc_count; i++)
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005215 efx_ef10_filter_mark_one_old(efx, &vlan->uc[i]);
Edward Cree12fb0da2015-07-21 15:11:00 +01005216 for (i = 0; i < table->dev_mc_count; i++)
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005217 efx_ef10_filter_mark_one_old(efx, &vlan->mc[i]);
Edward Cree9b410802017-01-27 15:02:52 +00005218 for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
5219 efx_ef10_filter_mark_one_old(efx, &vlan->default_filters[i]);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005220}
5221
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005222/* Mark old filters that may need to be removed.
5223 * Caller must hold efx->filter_sem for read if race against
5224 * efx_ef10_filter_table_remove() is possible
5225 */
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005226static void efx_ef10_filter_mark_old(struct efx_nic *efx)
5227{
5228 struct efx_ef10_filter_table *table = efx->filter_state;
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005229 struct efx_ef10_filter_vlan *vlan;
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005230
5231 spin_lock_bh(&efx->filter_lock);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005232 list_for_each_entry(vlan, &table->vlan_list, list)
5233 _efx_ef10_filter_vlan_mark_old(efx, vlan);
Ben Hutchings8127d662013-08-29 19:19:29 +01005234 spin_unlock_bh(&efx->filter_lock);
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005235}
Ben Hutchings8127d662013-08-29 19:19:29 +01005236
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005237static void efx_ef10_filter_uc_addr_list(struct efx_nic *efx)
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005238{
5239 struct efx_ef10_filter_table *table = efx->filter_state;
5240 struct net_device *net_dev = efx->net_dev;
5241 struct netdev_hw_addr *uc;
5242 unsigned int i;
5243
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005244 table->uc_promisc = !!(net_dev->flags & IFF_PROMISC);
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005245 ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr);
5246 i = 1;
5247 netdev_for_each_uc_addr(uc, net_dev) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005248 if (i >= EFX_EF10_FILTER_DEV_UC_MAX) {
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005249 table->uc_promisc = true;
Edward Cree12fb0da2015-07-21 15:11:00 +01005250 break;
5251 }
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005252 ether_addr_copy(table->dev_uc_list[i].addr, uc->addr);
5253 i++;
5254 }
Bert Kenwardc70d6812017-07-12 17:19:41 +01005255
5256 table->dev_uc_count = i;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005257}
5258
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005259static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx)
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005260{
5261 struct efx_ef10_filter_table *table = efx->filter_state;
5262 struct net_device *net_dev = efx->net_dev;
5263 struct netdev_hw_addr *mc;
Bert Kenwardc70d6812017-07-12 17:19:41 +01005264 unsigned int i;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005265
Edward Cree148cbab2017-04-04 17:02:49 +01005266 table->mc_overflow = false;
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005267 table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI));
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005268
Edward Cree12fb0da2015-07-21 15:11:00 +01005269 i = 0;
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005270 netdev_for_each_mc_addr(mc, net_dev) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005271 if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005272 table->mc_promisc = true;
Edward Cree148cbab2017-04-04 17:02:49 +01005273 table->mc_overflow = true;
Edward Cree12fb0da2015-07-21 15:11:00 +01005274 break;
5275 }
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005276 ether_addr_copy(table->dev_mc_list[i].addr, mc->addr);
5277 i++;
Ben Hutchings8127d662013-08-29 19:19:29 +01005278 }
Edward Cree12fb0da2015-07-21 15:11:00 +01005279
5280 table->dev_mc_count = i;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005281}
Ben Hutchings8127d662013-08-29 19:19:29 +01005282
Edward Cree12fb0da2015-07-21 15:11:00 +01005283static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005284 struct efx_ef10_filter_vlan *vlan,
5285 bool multicast, bool rollback)
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005286{
5287 struct efx_ef10_filter_table *table = efx->filter_state;
5288 struct efx_ef10_dev_addr *addr_list;
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005289 enum efx_filter_flags filter_flags;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005290 struct efx_filter_spec spec;
Edward Cree12fb0da2015-07-21 15:11:00 +01005291 u8 baddr[ETH_ALEN];
5292 unsigned int i, j;
5293 int addr_count;
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005294 u16 *ids;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005295 int rc;
5296
5297 if (multicast) {
5298 addr_list = table->dev_mc_list;
Edward Cree12fb0da2015-07-21 15:11:00 +01005299 addr_count = table->dev_mc_count;
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005300 ids = vlan->mc;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005301 } else {
5302 addr_list = table->dev_uc_list;
Edward Cree12fb0da2015-07-21 15:11:00 +01005303 addr_count = table->dev_uc_count;
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005304 ids = vlan->uc;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005305 }
5306
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005307 filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
5308
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005309 /* Insert/renew filters */
Edward Cree12fb0da2015-07-21 15:11:00 +01005310 for (i = 0; i < addr_count; i++) {
Edward Creed58299a2017-06-29 16:50:06 +01005311 EFX_WARN_ON_PARANOID(ids[i] != EFX_EF10_FILTER_ID_INVALID);
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005312 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005313 efx_filter_set_eth_local(&spec, vlan->vid, addr_list[i].addr);
Jon Cooperb6f568e2015-07-21 15:10:15 +01005314 rc = efx_ef10_filter_insert(efx, &spec, true);
5315 if (rc < 0) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005316 if (rollback) {
5317 netif_info(efx, drv, efx->net_dev,
5318 "efx_ef10_filter_insert failed rc=%d\n",
5319 rc);
5320 /* Fall back to promiscuous */
5321 for (j = 0; j < i; j++) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005322 efx_ef10_filter_remove_unsafe(
5323 efx, EFX_FILTER_PRI_AUTO,
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005324 ids[j]);
5325 ids[j] = EFX_EF10_FILTER_ID_INVALID;
Edward Cree12fb0da2015-07-21 15:11:00 +01005326 }
5327 return rc;
5328 } else {
Edward Creed58299a2017-06-29 16:50:06 +01005329 /* keep invalid ID, and carry on */
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005330 }
Edward Creed58299a2017-06-29 16:50:06 +01005331 } else {
5332 ids[i] = efx_ef10_filter_get_unsafe_id(rc);
Ben Hutchings8127d662013-08-29 19:19:29 +01005333 }
5334 }
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005335
Edward Cree12fb0da2015-07-21 15:11:00 +01005336 if (multicast && rollback) {
5337 /* Also need an Ethernet broadcast filter */
Edward Cree9b410802017-01-27 15:02:52 +00005338 EFX_WARN_ON_PARANOID(vlan->default_filters[EFX_EF10_BCAST] !=
5339 EFX_EF10_FILTER_ID_INVALID);
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005340 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
Edward Cree12fb0da2015-07-21 15:11:00 +01005341 eth_broadcast_addr(baddr);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005342 efx_filter_set_eth_local(&spec, vlan->vid, baddr);
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005343 rc = efx_ef10_filter_insert(efx, &spec, true);
Edward Cree12fb0da2015-07-21 15:11:00 +01005344 if (rc < 0) {
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005345 netif_warn(efx, drv, efx->net_dev,
Edward Cree12fb0da2015-07-21 15:11:00 +01005346 "Broadcast filter insert failed rc=%d\n", rc);
5347 /* Fall back to promiscuous */
5348 for (j = 0; j < i; j++) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005349 efx_ef10_filter_remove_unsafe(
5350 efx, EFX_FILTER_PRI_AUTO,
Andrew Rybchenkodc3273e2016-06-15 17:45:36 +01005351 ids[j]);
5352 ids[j] = EFX_EF10_FILTER_ID_INVALID;
Edward Cree12fb0da2015-07-21 15:11:00 +01005353 }
5354 return rc;
5355 } else {
Edward Cree9b410802017-01-27 15:02:52 +00005356 vlan->default_filters[EFX_EF10_BCAST] =
Jon Cooper0ccb9982017-02-17 15:49:13 +00005357 efx_ef10_filter_get_unsafe_id(rc);
Edward Cree12fb0da2015-07-21 15:11:00 +01005358 }
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005359 }
Edward Cree12fb0da2015-07-21 15:11:00 +01005360
5361 return 0;
5362}
5363
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005364static int efx_ef10_filter_insert_def(struct efx_nic *efx,
5365 struct efx_ef10_filter_vlan *vlan,
Edward Cree9b410802017-01-27 15:02:52 +00005366 enum efx_encap_type encap_type,
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005367 bool multicast, bool rollback)
Edward Cree12fb0da2015-07-21 15:11:00 +01005368{
Edward Cree12fb0da2015-07-21 15:11:00 +01005369 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005370 enum efx_filter_flags filter_flags;
Edward Cree12fb0da2015-07-21 15:11:00 +01005371 struct efx_filter_spec spec;
5372 u8 baddr[ETH_ALEN];
5373 int rc;
Edward Cree9b410802017-01-27 15:02:52 +00005374 u16 *id;
Edward Cree12fb0da2015-07-21 15:11:00 +01005375
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005376 filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
5377
5378 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
Edward Cree12fb0da2015-07-21 15:11:00 +01005379
5380 if (multicast)
5381 efx_filter_set_mc_def(&spec);
5382 else
5383 efx_filter_set_uc_def(&spec);
5384
Edward Cree9b410802017-01-27 15:02:52 +00005385 if (encap_type) {
5386 if (nic_data->datapath_caps &
5387 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN))
5388 efx_filter_set_encap_type(&spec, encap_type);
5389 else
5390 /* don't insert encap filters on non-supporting
5391 * platforms. ID will be left as INVALID.
5392 */
5393 return 0;
5394 }
5395
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005396 if (vlan->vid != EFX_FILTER_VID_UNSPEC)
5397 efx_filter_set_eth_local(&spec, vlan->vid, NULL);
5398
Edward Cree12fb0da2015-07-21 15:11:00 +01005399 rc = efx_ef10_filter_insert(efx, &spec, true);
5400 if (rc < 0) {
Edward Cree9b410802017-01-27 15:02:52 +00005401 const char *um = multicast ? "Multicast" : "Unicast";
5402 const char *encap_name = "";
5403 const char *encap_ipv = "";
5404
5405 if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
5406 EFX_ENCAP_TYPE_VXLAN)
5407 encap_name = "VXLAN ";
5408 else if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
5409 EFX_ENCAP_TYPE_NVGRE)
5410 encap_name = "NVGRE ";
5411 else if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
5412 EFX_ENCAP_TYPE_GENEVE)
5413 encap_name = "GENEVE ";
5414 if (encap_type & EFX_ENCAP_FLAG_IPV6)
5415 encap_ipv = "IPv6 ";
5416 else if (encap_type)
5417 encap_ipv = "IPv4 ";
5418
5419 /* unprivileged functions can't insert mismatch filters
5420 * for encapsulated or unicast traffic, so downgrade
5421 * those warnings to debug.
5422 */
Jon Cooper34e7aef2017-01-27 15:02:39 +00005423 netif_cond_dbg(efx, drv, efx->net_dev,
Edward Cree9b410802017-01-27 15:02:52 +00005424 rc == -EPERM && (encap_type || !multicast), warn,
5425 "%s%s%s mismatch filter insert failed rc=%d\n",
5426 encap_name, encap_ipv, um, rc);
Edward Cree12fb0da2015-07-21 15:11:00 +01005427 } else if (multicast) {
Edward Cree9b410802017-01-27 15:02:52 +00005428 /* mapping from encap types to default filter IDs (multicast) */
5429 static enum efx_ef10_default_filters map[] = {
5430 [EFX_ENCAP_TYPE_NONE] = EFX_EF10_MCDEF,
5431 [EFX_ENCAP_TYPE_VXLAN] = EFX_EF10_VXLAN4_MCDEF,
5432 [EFX_ENCAP_TYPE_NVGRE] = EFX_EF10_NVGRE4_MCDEF,
5433 [EFX_ENCAP_TYPE_GENEVE] = EFX_EF10_GENEVE4_MCDEF,
5434 [EFX_ENCAP_TYPE_VXLAN | EFX_ENCAP_FLAG_IPV6] =
5435 EFX_EF10_VXLAN6_MCDEF,
5436 [EFX_ENCAP_TYPE_NVGRE | EFX_ENCAP_FLAG_IPV6] =
5437 EFX_EF10_NVGRE6_MCDEF,
5438 [EFX_ENCAP_TYPE_GENEVE | EFX_ENCAP_FLAG_IPV6] =
5439 EFX_EF10_GENEVE6_MCDEF,
5440 };
5441
5442 /* quick bounds check (BCAST result impossible) */
5443 BUILD_BUG_ON(EFX_EF10_BCAST != 0);
Colin Ian Kinge9904992017-01-31 16:30:02 +00005444 if (encap_type >= ARRAY_SIZE(map) || map[encap_type] == 0) {
Edward Cree9b410802017-01-27 15:02:52 +00005445 WARN_ON(1);
5446 return -EINVAL;
5447 }
5448 /* then follow map */
5449 id = &vlan->default_filters[map[encap_type]];
5450
5451 EFX_WARN_ON_PARANOID(*id != EFX_EF10_FILTER_ID_INVALID);
Jon Cooper0ccb9982017-02-17 15:49:13 +00005452 *id = efx_ef10_filter_get_unsafe_id(rc);
Edward Cree9b410802017-01-27 15:02:52 +00005453 if (!nic_data->workaround_26807 && !encap_type) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005454 /* Also need an Ethernet broadcast filter */
5455 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
Bert Kenwardf1c2ef42015-12-11 09:39:32 +00005456 filter_flags, 0);
Edward Cree12fb0da2015-07-21 15:11:00 +01005457 eth_broadcast_addr(baddr);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005458 efx_filter_set_eth_local(&spec, vlan->vid, baddr);
Edward Cree12fb0da2015-07-21 15:11:00 +01005459 rc = efx_ef10_filter_insert(efx, &spec, true);
5460 if (rc < 0) {
5461 netif_warn(efx, drv, efx->net_dev,
5462 "Broadcast filter insert failed rc=%d\n",
5463 rc);
5464 if (rollback) {
5465 /* Roll back the mc_def filter */
5466 efx_ef10_filter_remove_unsafe(
5467 efx, EFX_FILTER_PRI_AUTO,
Edward Cree9b410802017-01-27 15:02:52 +00005468 *id);
5469 *id = EFX_EF10_FILTER_ID_INVALID;
Edward Cree12fb0da2015-07-21 15:11:00 +01005470 return rc;
5471 }
5472 } else {
Edward Cree9b410802017-01-27 15:02:52 +00005473 EFX_WARN_ON_PARANOID(
5474 vlan->default_filters[EFX_EF10_BCAST] !=
5475 EFX_EF10_FILTER_ID_INVALID);
5476 vlan->default_filters[EFX_EF10_BCAST] =
Jon Cooper0ccb9982017-02-17 15:49:13 +00005477 efx_ef10_filter_get_unsafe_id(rc);
Edward Cree12fb0da2015-07-21 15:11:00 +01005478 }
5479 }
5480 rc = 0;
5481 } else {
Edward Cree9b410802017-01-27 15:02:52 +00005482 /* mapping from encap types to default filter IDs (unicast) */
5483 static enum efx_ef10_default_filters map[] = {
5484 [EFX_ENCAP_TYPE_NONE] = EFX_EF10_UCDEF,
5485 [EFX_ENCAP_TYPE_VXLAN] = EFX_EF10_VXLAN4_UCDEF,
5486 [EFX_ENCAP_TYPE_NVGRE] = EFX_EF10_NVGRE4_UCDEF,
5487 [EFX_ENCAP_TYPE_GENEVE] = EFX_EF10_GENEVE4_UCDEF,
5488 [EFX_ENCAP_TYPE_VXLAN | EFX_ENCAP_FLAG_IPV6] =
5489 EFX_EF10_VXLAN6_UCDEF,
5490 [EFX_ENCAP_TYPE_NVGRE | EFX_ENCAP_FLAG_IPV6] =
5491 EFX_EF10_NVGRE6_UCDEF,
5492 [EFX_ENCAP_TYPE_GENEVE | EFX_ENCAP_FLAG_IPV6] =
5493 EFX_EF10_GENEVE6_UCDEF,
5494 };
5495
5496 /* quick bounds check (BCAST result impossible) */
5497 BUILD_BUG_ON(EFX_EF10_BCAST != 0);
Dan Carpenteree467fb2017-02-07 10:44:31 +03005498 if (encap_type >= ARRAY_SIZE(map) || map[encap_type] == 0) {
Edward Cree9b410802017-01-27 15:02:52 +00005499 WARN_ON(1);
5500 return -EINVAL;
5501 }
5502 /* then follow map */
5503 id = &vlan->default_filters[map[encap_type]];
5504 EFX_WARN_ON_PARANOID(*id != EFX_EF10_FILTER_ID_INVALID);
5505 *id = rc;
Edward Cree12fb0da2015-07-21 15:11:00 +01005506 rc = 0;
5507 }
5508 return rc;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005509}
5510
5511/* Remove filters that weren't renewed. Since nothing else changes the AUTO_OLD
5512 * flag or removes these filters, we don't need to hold the filter_lock while
5513 * scanning for these filters.
5514 */
5515static void efx_ef10_filter_remove_old(struct efx_nic *efx)
5516{
5517 struct efx_ef10_filter_table *table = efx->filter_state;
Bert Kenwarde65a5102015-12-23 08:57:36 +00005518 int remove_failed = 0;
5519 int remove_noent = 0;
5520 int rc;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005521 int i;
5522
Ben Hutchings8127d662013-08-29 19:19:29 +01005523 for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) {
Mark Rutland6aa7de02017-10-23 14:07:29 -07005524 if (READ_ONCE(table->entry[i].spec) &
Ben Hutchingsb59e6ef2013-11-21 19:02:22 +00005525 EFX_EF10_FILTER_FLAG_AUTO_OLD) {
Bert Kenwarde65a5102015-12-23 08:57:36 +00005526 rc = efx_ef10_filter_remove_internal(efx,
5527 1U << EFX_FILTER_PRI_AUTO, i, true);
5528 if (rc == -ENOENT)
5529 remove_noent++;
5530 else if (rc)
5531 remove_failed++;
Ben Hutchings8127d662013-08-29 19:19:29 +01005532 }
5533 }
Bert Kenwarde65a5102015-12-23 08:57:36 +00005534
5535 if (remove_failed)
5536 netif_info(efx, drv, efx->net_dev,
5537 "%s: failed to remove %d filters\n",
5538 __func__, remove_failed);
5539 if (remove_noent)
5540 netif_info(efx, drv, efx->net_dev,
5541 "%s: failed to remove %d non-existent filters\n",
5542 __func__, remove_noent);
Ben Hutchings8127d662013-08-29 19:19:29 +01005543}
5544
Daniel Pieczko7a186f42015-07-07 11:37:19 +01005545static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
5546{
5547 struct efx_ef10_nic_data *nic_data = efx->nic_data;
5548 u8 mac_old[ETH_ALEN];
5549 int rc, rc2;
5550
5551 /* Only reconfigure a PF-created vport */
5552 if (is_zero_ether_addr(nic_data->vport_mac))
5553 return 0;
5554
5555 efx_device_detach_sync(efx);
5556 efx_net_stop(efx->net_dev);
5557 down_write(&efx->filter_sem);
5558 efx_ef10_filter_table_remove(efx);
5559 up_write(&efx->filter_sem);
5560
5561 rc = efx_ef10_vadaptor_free(efx, nic_data->vport_id);
5562 if (rc)
5563 goto restore_filters;
5564
5565 ether_addr_copy(mac_old, nic_data->vport_mac);
5566 rc = efx_ef10_vport_del_mac(efx, nic_data->vport_id,
5567 nic_data->vport_mac);
5568 if (rc)
5569 goto restore_vadaptor;
5570
5571 rc = efx_ef10_vport_add_mac(efx, nic_data->vport_id,
5572 efx->net_dev->dev_addr);
5573 if (!rc) {
5574 ether_addr_copy(nic_data->vport_mac, efx->net_dev->dev_addr);
5575 } else {
5576 rc2 = efx_ef10_vport_add_mac(efx, nic_data->vport_id, mac_old);
5577 if (rc2) {
5578 /* Failed to add original MAC, so clear vport_mac */
5579 eth_zero_addr(nic_data->vport_mac);
5580 goto reset_nic;
5581 }
5582 }
5583
5584restore_vadaptor:
5585 rc2 = efx_ef10_vadaptor_alloc(efx, nic_data->vport_id);
5586 if (rc2)
5587 goto reset_nic;
5588restore_filters:
5589 down_write(&efx->filter_sem);
5590 rc2 = efx_ef10_filter_table_probe(efx);
5591 up_write(&efx->filter_sem);
5592 if (rc2)
5593 goto reset_nic;
5594
5595 rc2 = efx_net_open(efx->net_dev);
5596 if (rc2)
5597 goto reset_nic;
5598
Peter Dunning9c568fd2017-02-17 15:50:43 +00005599 efx_device_attach_if_not_resetting(efx);
Daniel Pieczko7a186f42015-07-07 11:37:19 +01005600
5601 return rc;
5602
5603reset_nic:
5604 netif_err(efx, drv, efx->net_dev,
5605 "Failed to restore when changing MAC address - scheduling reset\n");
5606 efx_schedule_reset(efx, RESET_TYPE_DATAPATH);
5607
5608 return rc ? rc : rc2;
5609}
5610
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005611/* Caller must hold efx->filter_sem for read if race against
5612 * efx_ef10_filter_table_remove() is possible
5613 */
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005614static void efx_ef10_filter_vlan_sync_rx_mode(struct efx_nic *efx,
5615 struct efx_ef10_filter_vlan *vlan)
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005616{
5617 struct efx_ef10_filter_table *table = efx->filter_state;
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005618 struct efx_ef10_nic_data *nic_data = efx->nic_data;
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005619
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01005620 /* Do not install unspecified VID if VLAN filtering is enabled.
5621 * Do not install all specified VIDs if VLAN filtering is disabled.
5622 */
5623 if ((vlan->vid == EFX_FILTER_VID_UNSPEC) == table->vlan_filter)
5624 return;
5625
Edward Cree12fb0da2015-07-21 15:11:00 +01005626 /* Insert/renew unicast filters */
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005627 if (table->uc_promisc) {
Edward Cree9b410802017-01-27 15:02:52 +00005628 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NONE,
5629 false, false);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005630 efx_ef10_filter_insert_addr_list(efx, vlan, false, false);
Edward Cree12fb0da2015-07-21 15:11:00 +01005631 } else {
5632 /* If any of the filters failed to insert, fall back to
5633 * promiscuous mode - add in the uc_def filter. But keep
5634 * our individual unicast filters.
5635 */
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005636 if (efx_ef10_filter_insert_addr_list(efx, vlan, false, false))
Edward Cree9b410802017-01-27 15:02:52 +00005637 efx_ef10_filter_insert_def(efx, vlan,
5638 EFX_ENCAP_TYPE_NONE,
5639 false, false);
Edward Cree12fb0da2015-07-21 15:11:00 +01005640 }
Edward Cree9b410802017-01-27 15:02:52 +00005641 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN,
5642 false, false);
5643 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN |
5644 EFX_ENCAP_FLAG_IPV6,
5645 false, false);
5646 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE,
5647 false, false);
5648 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE |
5649 EFX_ENCAP_FLAG_IPV6,
5650 false, false);
5651 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE,
5652 false, false);
5653 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE |
5654 EFX_ENCAP_FLAG_IPV6,
5655 false, false);
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005656
Edward Cree12fb0da2015-07-21 15:11:00 +01005657 /* Insert/renew multicast filters */
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005658 /* If changing promiscuous state with cascaded multicast filters, remove
5659 * old filters first, so that packets are dropped rather than duplicated
5660 */
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005661 if (nic_data->workaround_26807 &&
5662 table->mc_promisc_last != table->mc_promisc)
Daniel Pieczkoab8b1f7c2015-07-21 15:10:44 +01005663 efx_ef10_filter_remove_old(efx);
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005664 if (table->mc_promisc) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005665 if (nic_data->workaround_26807) {
5666 /* If we failed to insert promiscuous filters, rollback
5667 * and fall back to individual multicast filters
5668 */
Edward Cree9b410802017-01-27 15:02:52 +00005669 if (efx_ef10_filter_insert_def(efx, vlan,
5670 EFX_ENCAP_TYPE_NONE,
5671 true, true)) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005672 /* Changing promisc state, so remove old filters */
5673 efx_ef10_filter_remove_old(efx);
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005674 efx_ef10_filter_insert_addr_list(efx, vlan,
5675 true, false);
Edward Cree12fb0da2015-07-21 15:11:00 +01005676 }
5677 } else {
5678 /* If we failed to insert promiscuous filters, don't
Edward Cree148cbab2017-04-04 17:02:49 +01005679 * rollback. Regardless, also insert the mc_list,
5680 * unless it's incomplete due to overflow
Edward Cree12fb0da2015-07-21 15:11:00 +01005681 */
Edward Cree9b410802017-01-27 15:02:52 +00005682 efx_ef10_filter_insert_def(efx, vlan,
5683 EFX_ENCAP_TYPE_NONE,
5684 true, false);
Edward Cree148cbab2017-04-04 17:02:49 +01005685 if (!table->mc_overflow)
5686 efx_ef10_filter_insert_addr_list(efx, vlan,
5687 true, false);
Edward Cree12fb0da2015-07-21 15:11:00 +01005688 }
5689 } else {
5690 /* If any filters failed to insert, rollback and fall back to
5691 * promiscuous mode - mc_def filter and maybe broadcast. If
5692 * that fails, roll back again and insert as many of our
5693 * individual multicast filters as we can.
5694 */
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005695 if (efx_ef10_filter_insert_addr_list(efx, vlan, true, true)) {
Edward Cree12fb0da2015-07-21 15:11:00 +01005696 /* Changing promisc state, so remove old filters */
5697 if (nic_data->workaround_26807)
5698 efx_ef10_filter_remove_old(efx);
Edward Cree9b410802017-01-27 15:02:52 +00005699 if (efx_ef10_filter_insert_def(efx, vlan,
5700 EFX_ENCAP_TYPE_NONE,
5701 true, true))
Andrew Rybchenkob3a3c032016-06-15 17:47:36 +01005702 efx_ef10_filter_insert_addr_list(efx, vlan,
5703 true, false);
Edward Cree12fb0da2015-07-21 15:11:00 +01005704 }
5705 }
Edward Cree9b410802017-01-27 15:02:52 +00005706 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN,
5707 true, false);
5708 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN |
5709 EFX_ENCAP_FLAG_IPV6,
5710 true, false);
5711 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE,
5712 true, false);
5713 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE |
5714 EFX_ENCAP_FLAG_IPV6,
5715 true, false);
5716 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE,
5717 true, false);
5718 efx_ef10_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE |
5719 EFX_ENCAP_FLAG_IPV6,
5720 true, false);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005721}
5722
5723/* Caller must hold efx->filter_sem for read if race against
5724 * efx_ef10_filter_table_remove() is possible
5725 */
5726static void efx_ef10_filter_sync_rx_mode(struct efx_nic *efx)
5727{
5728 struct efx_ef10_filter_table *table = efx->filter_state;
5729 struct net_device *net_dev = efx->net_dev;
5730 struct efx_ef10_filter_vlan *vlan;
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01005731 bool vlan_filter;
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005732
5733 if (!efx_dev_registered(efx))
5734 return;
5735
5736 if (!table)
5737 return;
5738
5739 efx_ef10_filter_mark_old(efx);
5740
5741 /* Copy/convert the address lists; add the primary station
5742 * address and broadcast address
5743 */
5744 netif_addr_lock_bh(net_dev);
5745 efx_ef10_filter_uc_addr_list(efx);
5746 efx_ef10_filter_mc_addr_list(efx);
5747 netif_addr_unlock_bh(net_dev);
5748
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01005749 /* If VLAN filtering changes, all old filters are finally removed.
5750 * Do it in advance to avoid conflicts for unicast untagged and
5751 * VLAN 0 tagged filters.
5752 */
5753 vlan_filter = !!(net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
5754 if (table->vlan_filter != vlan_filter) {
5755 table->vlan_filter = vlan_filter;
5756 efx_ef10_filter_remove_old(efx);
5757 }
5758
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005759 list_for_each_entry(vlan, &table->vlan_list, list)
5760 efx_ef10_filter_vlan_sync_rx_mode(efx, vlan);
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005761
5762 efx_ef10_filter_remove_old(efx);
Andrew Rybchenkoafa4ce12016-06-15 17:45:56 +01005763 table->mc_promisc_last = table->mc_promisc;
Daniel Pieczko822b96f2015-07-21 15:10:27 +01005764}
5765
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005766static struct efx_ef10_filter_vlan *efx_ef10_filter_find_vlan(struct efx_nic *efx, u16 vid)
5767{
5768 struct efx_ef10_filter_table *table = efx->filter_state;
5769 struct efx_ef10_filter_vlan *vlan;
5770
5771 WARN_ON(!rwsem_is_locked(&efx->filter_sem));
5772
5773 list_for_each_entry(vlan, &table->vlan_list, list) {
5774 if (vlan->vid == vid)
5775 return vlan;
5776 }
5777
5778 return NULL;
5779}
5780
5781static int efx_ef10_filter_add_vlan(struct efx_nic *efx, u16 vid)
5782{
5783 struct efx_ef10_filter_table *table = efx->filter_state;
5784 struct efx_ef10_filter_vlan *vlan;
5785 unsigned int i;
5786
5787 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
5788 return -EINVAL;
5789
5790 vlan = efx_ef10_filter_find_vlan(efx, vid);
5791 if (WARN_ON(vlan)) {
5792 netif_err(efx, drv, efx->net_dev,
5793 "VLAN %u already added\n", vid);
5794 return -EALREADY;
5795 }
5796
5797 vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
5798 if (!vlan)
5799 return -ENOMEM;
5800
5801 vlan->vid = vid;
5802
5803 for (i = 0; i < ARRAY_SIZE(vlan->uc); i++)
5804 vlan->uc[i] = EFX_EF10_FILTER_ID_INVALID;
5805 for (i = 0; i < ARRAY_SIZE(vlan->mc); i++)
5806 vlan->mc[i] = EFX_EF10_FILTER_ID_INVALID;
Edward Cree9b410802017-01-27 15:02:52 +00005807 for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
5808 vlan->default_filters[i] = EFX_EF10_FILTER_ID_INVALID;
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005809
5810 list_add_tail(&vlan->list, &table->vlan_list);
5811
5812 if (efx_dev_registered(efx))
5813 efx_ef10_filter_vlan_sync_rx_mode(efx, vlan);
5814
5815 return 0;
5816}
5817
5818static void efx_ef10_filter_del_vlan_internal(struct efx_nic *efx,
5819 struct efx_ef10_filter_vlan *vlan)
5820{
5821 unsigned int i;
5822
5823 /* See comment in efx_ef10_filter_table_remove() */
5824 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
5825 return;
5826
5827 list_del(&vlan->list);
5828
Edward Cree8c915622016-06-15 17:49:05 +01005829 for (i = 0; i < ARRAY_SIZE(vlan->uc); i++)
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005830 efx_ef10_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
Edward Cree8c915622016-06-15 17:49:05 +01005831 vlan->uc[i]);
5832 for (i = 0; i < ARRAY_SIZE(vlan->mc); i++)
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005833 efx_ef10_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
Edward Cree8c915622016-06-15 17:49:05 +01005834 vlan->mc[i]);
Edward Cree9b410802017-01-27 15:02:52 +00005835 for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
5836 if (vlan->default_filters[i] != EFX_EF10_FILTER_ID_INVALID)
5837 efx_ef10_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
5838 vlan->default_filters[i]);
Andrew Rybchenko34813fe2016-06-15 17:48:14 +01005839
5840 kfree(vlan);
5841}
5842
5843static void efx_ef10_filter_del_vlan(struct efx_nic *efx, u16 vid)
5844{
5845 struct efx_ef10_filter_vlan *vlan;
5846
5847 /* See comment in efx_ef10_filter_table_remove() */
5848 if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
5849 return;
5850
5851 vlan = efx_ef10_filter_find_vlan(efx, vid);
5852 if (!vlan) {
5853 netif_err(efx, drv, efx->net_dev,
5854 "VLAN %u not found in filter state\n", vid);
5855 return;
5856 }
5857
5858 efx_ef10_filter_del_vlan_internal(efx, vlan);
5859}
5860
Shradha Shah910c8782015-05-20 11:12:48 +01005861static int efx_ef10_set_mac_address(struct efx_nic *efx)
5862{
5863 MCDI_DECLARE_BUF(inbuf, MC_CMD_VADAPTOR_SET_MAC_IN_LEN);
5864 struct efx_ef10_nic_data *nic_data = efx->nic_data;
5865 bool was_enabled = efx->port_enabled;
5866 int rc;
5867
5868 efx_device_detach_sync(efx);
5869 efx_net_stop(efx->net_dev);
Martin Habetsd2489532016-06-15 17:48:49 +01005870
5871 mutex_lock(&efx->mac_lock);
Shradha Shah910c8782015-05-20 11:12:48 +01005872 down_write(&efx->filter_sem);
5873 efx_ef10_filter_table_remove(efx);
5874
5875 ether_addr_copy(MCDI_PTR(inbuf, VADAPTOR_SET_MAC_IN_MACADDR),
5876 efx->net_dev->dev_addr);
5877 MCDI_SET_DWORD(inbuf, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
5878 nic_data->vport_id);
Daniel Pieczko535a6172015-07-07 11:37:33 +01005879 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_VADAPTOR_SET_MAC, inbuf,
5880 sizeof(inbuf), NULL, 0, NULL);
Shradha Shah910c8782015-05-20 11:12:48 +01005881
5882 efx_ef10_filter_table_probe(efx);
5883 up_write(&efx->filter_sem);
Martin Habetsd2489532016-06-15 17:48:49 +01005884 mutex_unlock(&efx->mac_lock);
5885
Shradha Shah910c8782015-05-20 11:12:48 +01005886 if (was_enabled)
5887 efx_net_open(efx->net_dev);
Peter Dunning9c568fd2017-02-17 15:50:43 +00005888 efx_device_attach_if_not_resetting(efx);
Shradha Shah910c8782015-05-20 11:12:48 +01005889
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005890#ifdef CONFIG_SFC_SRIOV
5891 if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
Shradha Shah910c8782015-05-20 11:12:48 +01005892 struct pci_dev *pci_dev_pf = efx->pci_dev->physfn;
5893
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005894 if (rc == -EPERM) {
5895 struct efx_nic *efx_pf;
Shradha Shah910c8782015-05-20 11:12:48 +01005896
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005897 /* Switch to PF and change MAC address on vport */
5898 efx_pf = pci_get_drvdata(pci_dev_pf);
5899
5900 rc = efx_ef10_sriov_set_vf_mac(efx_pf,
Shradha Shah910c8782015-05-20 11:12:48 +01005901 nic_data->vf_index,
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005902 efx->net_dev->dev_addr);
5903 } else if (!rc) {
Shradha Shah910c8782015-05-20 11:12:48 +01005904 struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
5905 struct efx_ef10_nic_data *nic_data = efx_pf->nic_data;
5906 unsigned int i;
5907
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005908 /* MAC address successfully changed by VF (with MAC
5909 * spoofing) so update the parent PF if possible.
5910 */
Shradha Shah910c8782015-05-20 11:12:48 +01005911 for (i = 0; i < efx_pf->vf_count; ++i) {
5912 struct ef10_vf *vf = nic_data->vf + i;
5913
5914 if (vf->efx == efx) {
5915 ether_addr_copy(vf->mac,
5916 efx->net_dev->dev_addr);
5917 return 0;
5918 }
5919 }
5920 }
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005921 } else
Shradha Shah910c8782015-05-20 11:12:48 +01005922#endif
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005923 if (rc == -EPERM) {
5924 netif_err(efx, drv, efx->net_dev,
5925 "Cannot change MAC address; use sfboot to enable"
5926 " mac-spoofing on this interface\n");
Daniel Pieczko7a186f42015-07-07 11:37:19 +01005927 } else if (rc == -ENOSYS && !efx_ef10_is_vf(efx)) {
5928 /* If the active MCFW does not support MC_CMD_VADAPTOR_SET_MAC
5929 * fall-back to the method of changing the MAC address on the
5930 * vport. This only applies to PFs because such versions of
5931 * MCFW do not support VFs.
5932 */
5933 rc = efx_ef10_vport_set_mac_address(efx);
Robert Stonehousecbad52e2017-11-07 17:30:30 +00005934 } else if (rc) {
Daniel Pieczko535a6172015-07-07 11:37:33 +01005935 efx_mcdi_display_error(efx, MC_CMD_VADAPTOR_SET_MAC,
5936 sizeof(inbuf), NULL, 0, rc);
Daniel Pieczko9e9f6652015-07-07 11:37:00 +01005937 }
5938
Shradha Shah910c8782015-05-20 11:12:48 +01005939 return rc;
5940}
5941
Ben Hutchings8127d662013-08-29 19:19:29 +01005942static int efx_ef10_mac_reconfigure(struct efx_nic *efx)
5943{
5944 efx_ef10_filter_sync_rx_mode(efx);
5945
5946 return efx_mcdi_set_mac(efx);
5947}
5948
Shradha Shah862f8942015-05-20 11:08:56 +01005949static int efx_ef10_mac_reconfigure_vf(struct efx_nic *efx)
5950{
5951 efx_ef10_filter_sync_rx_mode(efx);
5952
5953 return 0;
5954}
5955
Jon Cooper74cd60a2013-09-16 14:18:51 +01005956static int efx_ef10_start_bist(struct efx_nic *efx, u32 bist_type)
5957{
5958 MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
5959
5960 MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_type);
5961 return efx_mcdi_rpc(efx, MC_CMD_START_BIST, inbuf, sizeof(inbuf),
5962 NULL, 0, NULL);
5963}
5964
5965/* MC BISTs follow a different poll mechanism to phy BISTs.
5966 * The BIST is done in the poll handler on the MC, and the MCDI command
5967 * will block until the BIST is done.
5968 */
5969static int efx_ef10_poll_bist(struct efx_nic *efx)
5970{
5971 int rc;
5972 MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_LEN);
5973 size_t outlen;
5974 u32 result;
5975
5976 rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
5977 outbuf, sizeof(outbuf), &outlen);
5978 if (rc != 0)
5979 return rc;
5980
5981 if (outlen < MC_CMD_POLL_BIST_OUT_LEN)
5982 return -EIO;
5983
5984 result = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
5985 switch (result) {
5986 case MC_CMD_POLL_BIST_PASSED:
5987 netif_dbg(efx, hw, efx->net_dev, "BIST passed.\n");
5988 return 0;
5989 case MC_CMD_POLL_BIST_TIMEOUT:
5990 netif_err(efx, hw, efx->net_dev, "BIST timed out\n");
5991 return -EIO;
5992 case MC_CMD_POLL_BIST_FAILED:
5993 netif_err(efx, hw, efx->net_dev, "BIST failed.\n");
5994 return -EIO;
5995 default:
5996 netif_err(efx, hw, efx->net_dev,
5997 "BIST returned unknown result %u", result);
5998 return -EIO;
5999 }
6000}
6001
6002static int efx_ef10_run_bist(struct efx_nic *efx, u32 bist_type)
6003{
6004 int rc;
6005
6006 netif_dbg(efx, drv, efx->net_dev, "starting BIST type %u\n", bist_type);
6007
6008 rc = efx_ef10_start_bist(efx, bist_type);
6009 if (rc != 0)
6010 return rc;
6011
6012 return efx_ef10_poll_bist(efx);
6013}
6014
6015static int
6016efx_ef10_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
6017{
6018 int rc, rc2;
6019
6020 efx_reset_down(efx, RESET_TYPE_WORLD);
6021
6022 rc = efx_mcdi_rpc(efx, MC_CMD_ENABLE_OFFLINE_BIST,
6023 NULL, 0, NULL, 0, NULL);
6024 if (rc != 0)
6025 goto out;
6026
6027 tests->memory = efx_ef10_run_bist(efx, MC_CMD_MC_MEM_BIST) ? -1 : 1;
6028 tests->registers = efx_ef10_run_bist(efx, MC_CMD_REG_BIST) ? -1 : 1;
6029
6030 rc = efx_mcdi_reset(efx, RESET_TYPE_WORLD);
6031
6032out:
Daniel Pieczko27324822015-07-31 11:14:54 +01006033 if (rc == -EPERM)
6034 rc = 0;
Jon Cooper74cd60a2013-09-16 14:18:51 +01006035 rc2 = efx_reset_up(efx, RESET_TYPE_WORLD, rc == 0);
6036 return rc ? rc : rc2;
6037}
6038
Ben Hutchings8127d662013-08-29 19:19:29 +01006039#ifdef CONFIG_SFC_MTD
6040
6041struct efx_ef10_nvram_type_info {
6042 u16 type, type_mask;
6043 u8 port;
6044 const char *name;
6045};
6046
6047static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = {
6048 { NVRAM_PARTITION_TYPE_MC_FIRMWARE, 0, 0, "sfc_mcfw" },
6049 { NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 0, 0, "sfc_mcfw_backup" },
6050 { NVRAM_PARTITION_TYPE_EXPANSION_ROM, 0, 0, "sfc_exp_rom" },
6051 { NVRAM_PARTITION_TYPE_STATIC_CONFIG, 0, 0, "sfc_static_cfg" },
6052 { NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 0, 0, "sfc_dynamic_cfg" },
6053 { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0, 0, 0, "sfc_exp_rom_cfg" },
6054 { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 0, 1, "sfc_exp_rom_cfg" },
6055 { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 0, 2, "sfc_exp_rom_cfg" },
6056 { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 0, 3, "sfc_exp_rom_cfg" },
Ben Hutchingsa84f3bf92013-10-09 14:14:41 +01006057 { NVRAM_PARTITION_TYPE_LICENSE, 0, 0, "sfc_license" },
Ben Hutchings8127d662013-08-29 19:19:29 +01006058 { NVRAM_PARTITION_TYPE_PHY_MIN, 0xff, 0, "sfc_phy_fw" },
6059};
6060
6061static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
6062 struct efx_mcdi_mtd_partition *part,
6063 unsigned int type)
6064{
6065 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN);
6066 MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX);
6067 const struct efx_ef10_nvram_type_info *info;
6068 size_t size, erase_size, outlen;
6069 bool protected;
6070 int rc;
6071
6072 for (info = efx_ef10_nvram_types; ; info++) {
6073 if (info ==
6074 efx_ef10_nvram_types + ARRAY_SIZE(efx_ef10_nvram_types))
6075 return -ENODEV;
6076 if ((type & ~info->type_mask) == info->type)
6077 break;
6078 }
6079 if (info->port != efx_port_num(efx))
6080 return -ENODEV;
6081
6082 rc = efx_mcdi_nvram_info(efx, type, &size, &erase_size, &protected);
6083 if (rc)
6084 return rc;
6085 if (protected)
6086 return -ENODEV; /* hide it */
6087
6088 part->nvram_type = type;
6089
6090 MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type);
6091 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_METADATA, inbuf, sizeof(inbuf),
6092 outbuf, sizeof(outbuf), &outlen);
6093 if (rc)
6094 return rc;
6095 if (outlen < MC_CMD_NVRAM_METADATA_OUT_LENMIN)
6096 return -EIO;
6097 if (MCDI_DWORD(outbuf, NVRAM_METADATA_OUT_FLAGS) &
6098 (1 << MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN))
6099 part->fw_subtype = MCDI_DWORD(outbuf,
6100 NVRAM_METADATA_OUT_SUBTYPE);
6101
6102 part->common.dev_type_name = "EF10 NVRAM manager";
6103 part->common.type_name = info->name;
6104
6105 part->common.mtd.type = MTD_NORFLASH;
6106 part->common.mtd.flags = MTD_CAP_NORFLASH;
6107 part->common.mtd.size = size;
6108 part->common.mtd.erasesize = erase_size;
6109
6110 return 0;
6111}
6112
6113static int efx_ef10_mtd_probe(struct efx_nic *efx)
6114{
6115 MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
6116 struct efx_mcdi_mtd_partition *parts;
6117 size_t outlen, n_parts_total, i, n_parts;
6118 unsigned int type;
6119 int rc;
6120
6121 ASSERT_RTNL();
6122
6123 BUILD_BUG_ON(MC_CMD_NVRAM_PARTITIONS_IN_LEN != 0);
6124 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_PARTITIONS, NULL, 0,
6125 outbuf, sizeof(outbuf), &outlen);
6126 if (rc)
6127 return rc;
6128 if (outlen < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN)
6129 return -EIO;
6130
6131 n_parts_total = MCDI_DWORD(outbuf, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
6132 if (n_parts_total >
6133 MCDI_VAR_ARRAY_LEN(outlen, NVRAM_PARTITIONS_OUT_TYPE_ID))
6134 return -EIO;
6135
6136 parts = kcalloc(n_parts_total, sizeof(*parts), GFP_KERNEL);
6137 if (!parts)
6138 return -ENOMEM;
6139
6140 n_parts = 0;
6141 for (i = 0; i < n_parts_total; i++) {
6142 type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID,
6143 i);
6144 rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type);
6145 if (rc == 0)
6146 n_parts++;
6147 else if (rc != -ENODEV)
6148 goto fail;
6149 }
6150
6151 rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
6152fail:
6153 if (rc)
6154 kfree(parts);
6155 return rc;
6156}
6157
6158#endif /* CONFIG_SFC_MTD */
6159
6160static void efx_ef10_ptp_write_host_time(struct efx_nic *efx, u32 host_time)
6161{
6162 _efx_writed(efx, cpu_to_le32(host_time), ER_DZ_MC_DB_LWRD);
6163}
6164
Shradha Shah02246a72015-05-06 00:58:14 +01006165static void efx_ef10_ptp_write_host_time_vf(struct efx_nic *efx,
6166 u32 host_time) {}
6167
Jon Cooperbd9a2652013-11-18 12:54:41 +00006168static int efx_ef10_rx_enable_timestamping(struct efx_channel *channel,
6169 bool temp)
6170{
6171 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN);
6172 int rc;
6173
6174 if (channel->sync_events_state == SYNC_EVENTS_REQUESTED ||
6175 channel->sync_events_state == SYNC_EVENTS_VALID ||
6176 (temp && channel->sync_events_state == SYNC_EVENTS_DISABLED))
6177 return 0;
6178 channel->sync_events_state = SYNC_EVENTS_REQUESTED;
6179
6180 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_TIME_EVENT_SUBSCRIBE);
6181 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
6182 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE,
6183 channel->channel);
6184
6185 rc = efx_mcdi_rpc(channel->efx, MC_CMD_PTP,
6186 inbuf, sizeof(inbuf), NULL, 0, NULL);
6187
6188 if (rc != 0)
6189 channel->sync_events_state = temp ? SYNC_EVENTS_QUIESCENT :
6190 SYNC_EVENTS_DISABLED;
6191
6192 return rc;
6193}
6194
6195static int efx_ef10_rx_disable_timestamping(struct efx_channel *channel,
6196 bool temp)
6197{
6198 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN);
6199 int rc;
6200
6201 if (channel->sync_events_state == SYNC_EVENTS_DISABLED ||
6202 (temp && channel->sync_events_state == SYNC_EVENTS_QUIESCENT))
6203 return 0;
6204 if (channel->sync_events_state == SYNC_EVENTS_QUIESCENT) {
6205 channel->sync_events_state = SYNC_EVENTS_DISABLED;
6206 return 0;
6207 }
6208 channel->sync_events_state = temp ? SYNC_EVENTS_QUIESCENT :
6209 SYNC_EVENTS_DISABLED;
6210
6211 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE);
6212 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
6213 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL,
6214 MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE);
6215 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE,
6216 channel->channel);
6217
6218 rc = efx_mcdi_rpc(channel->efx, MC_CMD_PTP,
6219 inbuf, sizeof(inbuf), NULL, 0, NULL);
6220
6221 return rc;
6222}
6223
6224static int efx_ef10_ptp_set_ts_sync_events(struct efx_nic *efx, bool en,
6225 bool temp)
6226{
6227 int (*set)(struct efx_channel *channel, bool temp);
6228 struct efx_channel *channel;
6229
6230 set = en ?
6231 efx_ef10_rx_enable_timestamping :
6232 efx_ef10_rx_disable_timestamping;
6233
6234 efx_for_each_channel(channel, efx) {
6235 int rc = set(channel, temp);
6236 if (en && rc != 0) {
6237 efx_ef10_ptp_set_ts_sync_events(efx, false, temp);
6238 return rc;
6239 }
6240 }
6241
6242 return 0;
6243}
6244
Shradha Shah02246a72015-05-06 00:58:14 +01006245static int efx_ef10_ptp_set_ts_config_vf(struct efx_nic *efx,
6246 struct hwtstamp_config *init)
6247{
6248 return -EOPNOTSUPP;
6249}
6250
Jon Cooperbd9a2652013-11-18 12:54:41 +00006251static int efx_ef10_ptp_set_ts_config(struct efx_nic *efx,
6252 struct hwtstamp_config *init)
6253{
6254 int rc;
6255
6256 switch (init->rx_filter) {
6257 case HWTSTAMP_FILTER_NONE:
6258 efx_ef10_ptp_set_ts_sync_events(efx, false, false);
6259 /* if TX timestamping is still requested then leave PTP on */
6260 return efx_ptp_change_mode(efx,
6261 init->tx_type != HWTSTAMP_TX_OFF, 0);
6262 case HWTSTAMP_FILTER_ALL:
6263 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
6264 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
6265 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
6266 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
6267 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
6268 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
6269 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
6270 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
6271 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
6272 case HWTSTAMP_FILTER_PTP_V2_EVENT:
6273 case HWTSTAMP_FILTER_PTP_V2_SYNC:
6274 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
Miroslav Lichvare3412572017-05-19 17:52:36 +02006275 case HWTSTAMP_FILTER_NTP_ALL:
Jon Cooperbd9a2652013-11-18 12:54:41 +00006276 init->rx_filter = HWTSTAMP_FILTER_ALL;
6277 rc = efx_ptp_change_mode(efx, true, 0);
6278 if (!rc)
6279 rc = efx_ef10_ptp_set_ts_sync_events(efx, true, false);
6280 if (rc)
6281 efx_ptp_change_mode(efx, false, 0);
6282 return rc;
6283 default:
6284 return -ERANGE;
6285 }
6286}
6287
Bert Kenward08a7b29b2017-01-10 16:23:33 +00006288static int efx_ef10_get_phys_port_id(struct efx_nic *efx,
6289 struct netdev_phys_item_id *ppid)
6290{
6291 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6292
6293 if (!is_valid_ether_addr(nic_data->port_id))
6294 return -EOPNOTSUPP;
6295
6296 ppid->id_len = ETH_ALEN;
6297 memcpy(ppid->id, nic_data->port_id, ppid->id_len);
6298
6299 return 0;
6300}
6301
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01006302static int efx_ef10_vlan_rx_add_vid(struct efx_nic *efx, __be16 proto, u16 vid)
6303{
6304 if (proto != htons(ETH_P_8021Q))
6305 return -EINVAL;
6306
6307 return efx_ef10_add_vlan(efx, vid);
6308}
6309
6310static int efx_ef10_vlan_rx_kill_vid(struct efx_nic *efx, __be16 proto, u16 vid)
6311{
6312 if (proto != htons(ETH_P_8021Q))
6313 return -EINVAL;
6314
6315 return efx_ef10_del_vlan(efx, vid);
6316}
6317
Jon Coopere5fbd972017-02-08 16:52:10 +00006318/* We rely on the MCDI wiping out our TX rings if it made any changes to the
6319 * ports table, ensuring that any TSO descriptors that were made on a now-
6320 * removed tunnel port will be blown away and won't break things when we try
6321 * to transmit them using the new ports table.
6322 */
6323static int efx_ef10_set_udp_tnl_ports(struct efx_nic *efx, bool unloading)
6324{
6325 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6326 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX);
6327 MCDI_DECLARE_BUF(outbuf, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN);
6328 bool will_reset = false;
6329 size_t num_entries = 0;
6330 size_t inlen, outlen;
6331 size_t i;
6332 int rc;
6333 efx_dword_t flags_and_num_entries;
6334
6335 WARN_ON(!mutex_is_locked(&nic_data->udp_tunnels_lock));
6336
6337 nic_data->udp_tunnels_dirty = false;
6338
6339 if (!(nic_data->datapath_caps &
6340 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN))) {
Peter Dunning9c568fd2017-02-17 15:50:43 +00006341 efx_device_attach_if_not_resetting(efx);
Jon Coopere5fbd972017-02-08 16:52:10 +00006342 return 0;
6343 }
6344
6345 BUILD_BUG_ON(ARRAY_SIZE(nic_data->udp_tunnels) >
6346 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
6347
6348 for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i) {
6349 if (nic_data->udp_tunnels[i].count &&
6350 nic_data->udp_tunnels[i].port) {
6351 efx_dword_t entry;
6352
6353 EFX_POPULATE_DWORD_2(entry,
6354 TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT,
6355 ntohs(nic_data->udp_tunnels[i].port),
6356 TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL,
6357 nic_data->udp_tunnels[i].type);
6358 *_MCDI_ARRAY_DWORD(inbuf,
6359 SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES,
6360 num_entries++) = entry;
6361 }
6362 }
6363
6364 BUILD_BUG_ON((MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_NUM_ENTRIES_OFST -
6365 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS_OFST) * 8 !=
6366 EFX_WORD_1_LBN);
6367 BUILD_BUG_ON(MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_NUM_ENTRIES_LEN * 8 !=
6368 EFX_WORD_1_WIDTH);
6369 EFX_POPULATE_DWORD_2(flags_and_num_entries,
6370 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING,
6371 !!unloading,
6372 EFX_WORD_1, num_entries);
6373 *_MCDI_DWORD(inbuf, SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS) =
6374 flags_and_num_entries;
6375
6376 inlen = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LEN(num_entries);
6377
6378 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS,
6379 inbuf, inlen, outbuf, sizeof(outbuf), &outlen);
6380 if (rc == -EIO) {
6381 /* Most likely the MC rebooted due to another function also
6382 * setting its tunnel port list. Mark the tunnel port list as
6383 * dirty, so it will be pushed upon coming up from the reboot.
6384 */
6385 nic_data->udp_tunnels_dirty = true;
6386 return 0;
6387 }
6388
6389 if (rc) {
6390 /* expected not available on unprivileged functions */
6391 if (rc != -EPERM)
6392 netif_warn(efx, drv, efx->net_dev,
6393 "Unable to set UDP tunnel ports; rc=%d.\n", rc);
6394 } else if (MCDI_DWORD(outbuf, SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS) &
6395 (1 << MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN)) {
6396 netif_info(efx, drv, efx->net_dev,
6397 "Rebooting MC due to UDP tunnel port list change\n");
6398 will_reset = true;
6399 if (unloading)
6400 /* Delay for the MC reset to complete. This will make
6401 * unloading other functions a bit smoother. This is a
6402 * race, but the other unload will work whichever way
6403 * it goes, this just avoids an unnecessary error
6404 * message.
6405 */
6406 msleep(100);
6407 }
6408 if (!will_reset && !unloading) {
6409 /* The caller will have detached, relying on the MC reset to
6410 * trigger a re-attach. Since there won't be an MC reset, we
6411 * have to do the attach ourselves.
6412 */
Peter Dunning9c568fd2017-02-17 15:50:43 +00006413 efx_device_attach_if_not_resetting(efx);
Jon Coopere5fbd972017-02-08 16:52:10 +00006414 }
6415
6416 return rc;
6417}
6418
6419static int efx_ef10_udp_tnl_push_ports(struct efx_nic *efx)
6420{
6421 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6422 int rc = 0;
6423
6424 mutex_lock(&nic_data->udp_tunnels_lock);
6425 if (nic_data->udp_tunnels_dirty) {
6426 /* Make sure all TX are stopped while we modify the table, else
6427 * we might race against an efx_features_check().
6428 */
6429 efx_device_detach_sync(efx);
6430 rc = efx_ef10_set_udp_tnl_ports(efx, false);
6431 }
6432 mutex_unlock(&nic_data->udp_tunnels_lock);
6433 return rc;
6434}
6435
6436static struct efx_udp_tunnel *__efx_ef10_udp_tnl_lookup_port(struct efx_nic *efx,
6437 __be16 port)
6438{
6439 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6440 size_t i;
6441
6442 for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i) {
6443 if (!nic_data->udp_tunnels[i].count)
6444 continue;
6445 if (nic_data->udp_tunnels[i].port == port)
6446 return &nic_data->udp_tunnels[i];
6447 }
6448 return NULL;
6449}
6450
6451static int efx_ef10_udp_tnl_add_port(struct efx_nic *efx,
6452 struct efx_udp_tunnel tnl)
6453{
6454 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6455 struct efx_udp_tunnel *match;
6456 char typebuf[8];
6457 size_t i;
6458 int rc;
6459
6460 if (!(nic_data->datapath_caps &
6461 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
6462 return 0;
6463
6464 efx_get_udp_tunnel_type_name(tnl.type, typebuf, sizeof(typebuf));
6465 netif_dbg(efx, drv, efx->net_dev, "Adding UDP tunnel (%s) port %d\n",
6466 typebuf, ntohs(tnl.port));
6467
6468 mutex_lock(&nic_data->udp_tunnels_lock);
6469 /* Make sure all TX are stopped while we add to the table, else we
6470 * might race against an efx_features_check().
6471 */
6472 efx_device_detach_sync(efx);
6473
6474 match = __efx_ef10_udp_tnl_lookup_port(efx, tnl.port);
6475 if (match != NULL) {
6476 if (match->type == tnl.type) {
6477 netif_dbg(efx, drv, efx->net_dev,
6478 "Referencing existing tunnel entry\n");
6479 match->count++;
6480 /* No need to cause an MCDI update */
6481 rc = 0;
6482 goto unlock_out;
6483 }
6484 efx_get_udp_tunnel_type_name(match->type,
6485 typebuf, sizeof(typebuf));
6486 netif_dbg(efx, drv, efx->net_dev,
6487 "UDP port %d is already in use by %s\n",
6488 ntohs(tnl.port), typebuf);
6489 rc = -EEXIST;
6490 goto unlock_out;
6491 }
6492
6493 for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i)
6494 if (!nic_data->udp_tunnels[i].count) {
6495 nic_data->udp_tunnels[i] = tnl;
6496 nic_data->udp_tunnels[i].count = 1;
6497 rc = efx_ef10_set_udp_tnl_ports(efx, false);
6498 goto unlock_out;
6499 }
6500
6501 netif_dbg(efx, drv, efx->net_dev,
6502 "Unable to add UDP tunnel (%s) port %d; insufficient resources.\n",
6503 typebuf, ntohs(tnl.port));
6504
6505 rc = -ENOMEM;
6506
6507unlock_out:
6508 mutex_unlock(&nic_data->udp_tunnels_lock);
6509 return rc;
6510}
6511
6512/* Called under the TX lock with the TX queue running, hence no-one can be
6513 * in the middle of updating the UDP tunnels table. However, they could
6514 * have tried and failed the MCDI, in which case they'll have set the dirty
6515 * flag before dropping their locks.
6516 */
6517static bool efx_ef10_udp_tnl_has_port(struct efx_nic *efx, __be16 port)
6518{
6519 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6520
6521 if (!(nic_data->datapath_caps &
6522 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
6523 return false;
6524
6525 if (nic_data->udp_tunnels_dirty)
6526 /* SW table may not match HW state, so just assume we can't
6527 * use any UDP tunnel offloads.
6528 */
6529 return false;
6530
6531 return __efx_ef10_udp_tnl_lookup_port(efx, port) != NULL;
6532}
6533
6534static int efx_ef10_udp_tnl_del_port(struct efx_nic *efx,
6535 struct efx_udp_tunnel tnl)
6536{
6537 struct efx_ef10_nic_data *nic_data = efx->nic_data;
6538 struct efx_udp_tunnel *match;
6539 char typebuf[8];
6540 int rc;
6541
6542 if (!(nic_data->datapath_caps &
6543 (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
6544 return 0;
6545
6546 efx_get_udp_tunnel_type_name(tnl.type, typebuf, sizeof(typebuf));
6547 netif_dbg(efx, drv, efx->net_dev, "Removing UDP tunnel (%s) port %d\n",
6548 typebuf, ntohs(tnl.port));
6549
6550 mutex_lock(&nic_data->udp_tunnels_lock);
6551 /* Make sure all TX are stopped while we remove from the table, else we
6552 * might race against an efx_features_check().
6553 */
6554 efx_device_detach_sync(efx);
6555
6556 match = __efx_ef10_udp_tnl_lookup_port(efx, tnl.port);
6557 if (match != NULL) {
6558 if (match->type == tnl.type) {
6559 if (--match->count) {
6560 /* Port is still in use, so nothing to do */
6561 netif_dbg(efx, drv, efx->net_dev,
6562 "UDP tunnel port %d remains active\n",
6563 ntohs(tnl.port));
6564 rc = 0;
6565 goto out_unlock;
6566 }
6567 rc = efx_ef10_set_udp_tnl_ports(efx, false);
6568 goto out_unlock;
6569 }
6570 efx_get_udp_tunnel_type_name(match->type,
6571 typebuf, sizeof(typebuf));
6572 netif_warn(efx, drv, efx->net_dev,
6573 "UDP port %d is actually in use by %s, not removing\n",
6574 ntohs(tnl.port), typebuf);
6575 }
6576 rc = -ENOENT;
6577
6578out_unlock:
6579 mutex_unlock(&nic_data->udp_tunnels_lock);
6580 return rc;
6581}
6582
Andrew Rybchenko100a9db2016-06-15 17:42:26 +01006583#define EF10_OFFLOAD_FEATURES \
6584 (NETIF_F_IP_CSUM | \
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01006585 NETIF_F_HW_VLAN_CTAG_FILTER | \
Andrew Rybchenko100a9db2016-06-15 17:42:26 +01006586 NETIF_F_IPV6_CSUM | \
6587 NETIF_F_RXHASH | \
6588 NETIF_F_NTUPLE)
6589
Shradha Shah02246a72015-05-06 00:58:14 +01006590const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
Shradha Shah6f7f8aa2015-05-06 01:00:07 +01006591 .is_vf = true,
Edward Cree03714bb2017-12-18 16:55:50 +00006592 .mem_bar = efx_ef10_vf_mem_bar,
Ben Hutchings8127d662013-08-29 19:19:29 +01006593 .mem_map_size = efx_ef10_mem_map_size,
Shradha Shah02246a72015-05-06 00:58:14 +01006594 .probe = efx_ef10_probe_vf,
6595 .remove = efx_ef10_remove,
6596 .dimension_resources = efx_ef10_dimension_resources,
6597 .init = efx_ef10_init_nic,
6598 .fini = efx_port_dummy_op_void,
Jon Cooper087e9022015-05-20 11:11:35 +01006599 .map_reset_reason = efx_ef10_map_reset_reason,
Shradha Shah02246a72015-05-06 00:58:14 +01006600 .map_reset_flags = efx_ef10_map_reset_flags,
6601 .reset = efx_ef10_reset,
6602 .probe_port = efx_mcdi_port_probe,
6603 .remove_port = efx_mcdi_port_remove,
6604 .fini_dmaq = efx_ef10_fini_dmaq,
6605 .prepare_flr = efx_ef10_prepare_flr,
6606 .finish_flr = efx_port_dummy_op_void,
6607 .describe_stats = efx_ef10_describe_stats,
Daniel Pieczkod7788192015-06-02 11:39:20 +01006608 .update_stats = efx_ef10_update_stats_vf,
Shradha Shah02246a72015-05-06 00:58:14 +01006609 .start_stats = efx_port_dummy_op_void,
6610 .pull_stats = efx_port_dummy_op_void,
6611 .stop_stats = efx_port_dummy_op_void,
6612 .set_id_led = efx_mcdi_set_id_led,
6613 .push_irq_moderation = efx_ef10_push_irq_moderation,
Shradha Shah862f8942015-05-20 11:08:56 +01006614 .reconfigure_mac = efx_ef10_mac_reconfigure_vf,
Shradha Shah02246a72015-05-06 00:58:14 +01006615 .check_mac_fault = efx_mcdi_mac_check_fault,
6616 .reconfigure_port = efx_mcdi_port_reconfigure,
6617 .get_wol = efx_ef10_get_wol_vf,
6618 .set_wol = efx_ef10_set_wol_vf,
6619 .resume_wol = efx_port_dummy_op_void,
6620 .mcdi_request = efx_ef10_mcdi_request,
6621 .mcdi_poll_response = efx_ef10_mcdi_poll_response,
6622 .mcdi_read_response = efx_ef10_mcdi_read_response,
6623 .mcdi_poll_reboot = efx_ef10_mcdi_poll_reboot,
Daniel Pieczkoc577e592015-10-09 10:40:35 +01006624 .mcdi_reboot_detected = efx_ef10_mcdi_reboot_detected,
Shradha Shah02246a72015-05-06 00:58:14 +01006625 .irq_enable_master = efx_port_dummy_op_void,
6626 .irq_test_generate = efx_ef10_irq_test_generate,
6627 .irq_disable_non_ev = efx_port_dummy_op_void,
6628 .irq_handle_msi = efx_ef10_msi_interrupt,
6629 .irq_handle_legacy = efx_ef10_legacy_interrupt,
6630 .tx_probe = efx_ef10_tx_probe,
6631 .tx_init = efx_ef10_tx_init,
6632 .tx_remove = efx_ef10_tx_remove,
6633 .tx_write = efx_ef10_tx_write,
Bert Kenwarde9117e52016-11-17 10:51:54 +00006634 .tx_limit_len = efx_ef10_tx_limit_len,
Jon Cooper267c0152015-05-06 00:59:38 +01006635 .rx_push_rss_config = efx_ef10_vf_rx_push_rss_config,
Edward Creea707d182017-01-17 12:02:12 +00006636 .rx_pull_rss_config = efx_ef10_rx_pull_rss_config,
Shradha Shah02246a72015-05-06 00:58:14 +01006637 .rx_probe = efx_ef10_rx_probe,
6638 .rx_init = efx_ef10_rx_init,
6639 .rx_remove = efx_ef10_rx_remove,
6640 .rx_write = efx_ef10_rx_write,
6641 .rx_defer_refill = efx_ef10_rx_defer_refill,
6642 .ev_probe = efx_ef10_ev_probe,
6643 .ev_init = efx_ef10_ev_init,
6644 .ev_fini = efx_ef10_ev_fini,
6645 .ev_remove = efx_ef10_ev_remove,
6646 .ev_process = efx_ef10_ev_process,
6647 .ev_read_ack = efx_ef10_ev_read_ack,
6648 .ev_test_generate = efx_ef10_ev_test_generate,
6649 .filter_table_probe = efx_ef10_filter_table_probe,
6650 .filter_table_restore = efx_ef10_filter_table_restore,
6651 .filter_table_remove = efx_ef10_filter_table_remove,
6652 .filter_update_rx_scatter = efx_ef10_filter_update_rx_scatter,
6653 .filter_insert = efx_ef10_filter_insert,
6654 .filter_remove_safe = efx_ef10_filter_remove_safe,
6655 .filter_get_safe = efx_ef10_filter_get_safe,
6656 .filter_clear_rx = efx_ef10_filter_clear_rx,
6657 .filter_count_rx_used = efx_ef10_filter_count_rx_used,
6658 .filter_get_rx_id_limit = efx_ef10_filter_get_rx_id_limit,
6659 .filter_get_rx_ids = efx_ef10_filter_get_rx_ids,
6660#ifdef CONFIG_RFS_ACCEL
6661 .filter_rfs_insert = efx_ef10_filter_rfs_insert,
6662 .filter_rfs_expire_one = efx_ef10_filter_rfs_expire_one,
6663#endif
6664#ifdef CONFIG_SFC_MTD
6665 .mtd_probe = efx_port_dummy_op_int,
6666#endif
6667 .ptp_write_host_time = efx_ef10_ptp_write_host_time_vf,
6668 .ptp_set_ts_config = efx_ef10_ptp_set_ts_config_vf,
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01006669 .vlan_rx_add_vid = efx_ef10_vlan_rx_add_vid,
6670 .vlan_rx_kill_vid = efx_ef10_vlan_rx_kill_vid,
Shradha Shah02246a72015-05-06 00:58:14 +01006671#ifdef CONFIG_SFC_SRIOV
Shradha Shah7b8c7b52015-05-06 00:58:54 +01006672 .vswitching_probe = efx_ef10_vswitching_probe_vf,
6673 .vswitching_restore = efx_ef10_vswitching_restore_vf,
6674 .vswitching_remove = efx_ef10_vswitching_remove_vf,
Shradha Shah02246a72015-05-06 00:58:14 +01006675#endif
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +01006676 .get_mac_address = efx_ef10_get_mac_address_vf,
Shradha Shah910c8782015-05-20 11:12:48 +01006677 .set_mac_address = efx_ef10_set_mac_address,
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +01006678
Bert Kenward08a7b29b2017-01-10 16:23:33 +00006679 .get_phys_port_id = efx_ef10_get_phys_port_id,
Shradha Shah02246a72015-05-06 00:58:14 +01006680 .revision = EFX_REV_HUNT_A0,
6681 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),
6682 .rx_prefix_size = ES_DZ_RX_PREFIX_SIZE,
6683 .rx_hash_offset = ES_DZ_RX_PREFIX_HASH_OFST,
6684 .rx_ts_offset = ES_DZ_RX_PREFIX_TSTAMP_OFST,
6685 .can_rx_scatter = true,
6686 .always_rx_scatter = true,
Andrew Rybchenko6f9f6ec2017-02-13 14:57:39 +00006687 .min_interrupt_mode = EFX_INT_MODE_MSIX,
Shradha Shah02246a72015-05-06 00:58:14 +01006688 .max_interrupt_mode = EFX_INT_MODE_MSIX,
6689 .timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
Andrew Rybchenko100a9db2016-06-15 17:42:26 +01006690 .offload_features = EF10_OFFLOAD_FEATURES,
Shradha Shah02246a72015-05-06 00:58:14 +01006691 .mcdi_max_ver = 2,
6692 .max_rx_ip_filters = HUNT_FILTER_TBL_ROWS,
6693 .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
6694 1 << HWTSTAMP_FILTER_ALL,
Edward Creef74d1992017-01-17 12:01:53 +00006695 .rx_hash_key_size = 40,
Shradha Shah02246a72015-05-06 00:58:14 +01006696};
6697
6698const struct efx_nic_type efx_hunt_a0_nic_type = {
Shradha Shah6f7f8aa2015-05-06 01:00:07 +01006699 .is_vf = false,
Edward Cree03714bb2017-12-18 16:55:50 +00006700 .mem_bar = efx_ef10_pf_mem_bar,
Shradha Shah02246a72015-05-06 00:58:14 +01006701 .mem_map_size = efx_ef10_mem_map_size,
6702 .probe = efx_ef10_probe_pf,
Ben Hutchings8127d662013-08-29 19:19:29 +01006703 .remove = efx_ef10_remove,
6704 .dimension_resources = efx_ef10_dimension_resources,
6705 .init = efx_ef10_init_nic,
6706 .fini = efx_port_dummy_op_void,
Jon Cooper087e9022015-05-20 11:11:35 +01006707 .map_reset_reason = efx_ef10_map_reset_reason,
Ben Hutchings8127d662013-08-29 19:19:29 +01006708 .map_reset_flags = efx_ef10_map_reset_flags,
Jon Cooper3e336262014-01-17 19:48:06 +00006709 .reset = efx_ef10_reset,
Ben Hutchings8127d662013-08-29 19:19:29 +01006710 .probe_port = efx_mcdi_port_probe,
6711 .remove_port = efx_mcdi_port_remove,
6712 .fini_dmaq = efx_ef10_fini_dmaq,
Edward Creee2835462014-04-16 19:27:48 +01006713 .prepare_flr = efx_ef10_prepare_flr,
6714 .finish_flr = efx_port_dummy_op_void,
Ben Hutchings8127d662013-08-29 19:19:29 +01006715 .describe_stats = efx_ef10_describe_stats,
Daniel Pieczkod7788192015-06-02 11:39:20 +01006716 .update_stats = efx_ef10_update_stats_pf,
Ben Hutchings8127d662013-08-29 19:19:29 +01006717 .start_stats = efx_mcdi_mac_start_stats,
Jon Cooperf8f3b5a2013-09-30 17:36:50 +01006718 .pull_stats = efx_mcdi_mac_pull_stats,
Ben Hutchings8127d662013-08-29 19:19:29 +01006719 .stop_stats = efx_mcdi_mac_stop_stats,
6720 .set_id_led = efx_mcdi_set_id_led,
6721 .push_irq_moderation = efx_ef10_push_irq_moderation,
6722 .reconfigure_mac = efx_ef10_mac_reconfigure,
6723 .check_mac_fault = efx_mcdi_mac_check_fault,
6724 .reconfigure_port = efx_mcdi_port_reconfigure,
6725 .get_wol = efx_ef10_get_wol,
6726 .set_wol = efx_ef10_set_wol,
6727 .resume_wol = efx_port_dummy_op_void,
Jon Cooper74cd60a2013-09-16 14:18:51 +01006728 .test_chip = efx_ef10_test_chip,
Ben Hutchings8127d662013-08-29 19:19:29 +01006729 .test_nvram = efx_mcdi_nvram_test_all,
6730 .mcdi_request = efx_ef10_mcdi_request,
6731 .mcdi_poll_response = efx_ef10_mcdi_poll_response,
6732 .mcdi_read_response = efx_ef10_mcdi_read_response,
6733 .mcdi_poll_reboot = efx_ef10_mcdi_poll_reboot,
Daniel Pieczkoc577e592015-10-09 10:40:35 +01006734 .mcdi_reboot_detected = efx_ef10_mcdi_reboot_detected,
Ben Hutchings8127d662013-08-29 19:19:29 +01006735 .irq_enable_master = efx_port_dummy_op_void,
6736 .irq_test_generate = efx_ef10_irq_test_generate,
6737 .irq_disable_non_ev = efx_port_dummy_op_void,
6738 .irq_handle_msi = efx_ef10_msi_interrupt,
6739 .irq_handle_legacy = efx_ef10_legacy_interrupt,
6740 .tx_probe = efx_ef10_tx_probe,
6741 .tx_init = efx_ef10_tx_init,
6742 .tx_remove = efx_ef10_tx_remove,
6743 .tx_write = efx_ef10_tx_write,
Bert Kenwarde9117e52016-11-17 10:51:54 +00006744 .tx_limit_len = efx_ef10_tx_limit_len,
Jon Cooper267c0152015-05-06 00:59:38 +01006745 .rx_push_rss_config = efx_ef10_pf_rx_push_rss_config,
Edward Creea707d182017-01-17 12:02:12 +00006746 .rx_pull_rss_config = efx_ef10_rx_pull_rss_config,
Ben Hutchings8127d662013-08-29 19:19:29 +01006747 .rx_probe = efx_ef10_rx_probe,
6748 .rx_init = efx_ef10_rx_init,
6749 .rx_remove = efx_ef10_rx_remove,
6750 .rx_write = efx_ef10_rx_write,
6751 .rx_defer_refill = efx_ef10_rx_defer_refill,
6752 .ev_probe = efx_ef10_ev_probe,
6753 .ev_init = efx_ef10_ev_init,
6754 .ev_fini = efx_ef10_ev_fini,
6755 .ev_remove = efx_ef10_ev_remove,
6756 .ev_process = efx_ef10_ev_process,
6757 .ev_read_ack = efx_ef10_ev_read_ack,
6758 .ev_test_generate = efx_ef10_ev_test_generate,
6759 .filter_table_probe = efx_ef10_filter_table_probe,
6760 .filter_table_restore = efx_ef10_filter_table_restore,
6761 .filter_table_remove = efx_ef10_filter_table_remove,
6762 .filter_update_rx_scatter = efx_ef10_filter_update_rx_scatter,
6763 .filter_insert = efx_ef10_filter_insert,
6764 .filter_remove_safe = efx_ef10_filter_remove_safe,
6765 .filter_get_safe = efx_ef10_filter_get_safe,
6766 .filter_clear_rx = efx_ef10_filter_clear_rx,
6767 .filter_count_rx_used = efx_ef10_filter_count_rx_used,
6768 .filter_get_rx_id_limit = efx_ef10_filter_get_rx_id_limit,
6769 .filter_get_rx_ids = efx_ef10_filter_get_rx_ids,
6770#ifdef CONFIG_RFS_ACCEL
6771 .filter_rfs_insert = efx_ef10_filter_rfs_insert,
6772 .filter_rfs_expire_one = efx_ef10_filter_rfs_expire_one,
6773#endif
6774#ifdef CONFIG_SFC_MTD
6775 .mtd_probe = efx_ef10_mtd_probe,
6776 .mtd_rename = efx_mcdi_mtd_rename,
6777 .mtd_read = efx_mcdi_mtd_read,
6778 .mtd_erase = efx_mcdi_mtd_erase,
6779 .mtd_write = efx_mcdi_mtd_write,
6780 .mtd_sync = efx_mcdi_mtd_sync,
6781#endif
6782 .ptp_write_host_time = efx_ef10_ptp_write_host_time,
Jon Cooperbd9a2652013-11-18 12:54:41 +00006783 .ptp_set_ts_sync_events = efx_ef10_ptp_set_ts_sync_events,
6784 .ptp_set_ts_config = efx_ef10_ptp_set_ts_config,
Andrew Rybchenko4a53ea82016-06-15 17:48:32 +01006785 .vlan_rx_add_vid = efx_ef10_vlan_rx_add_vid,
6786 .vlan_rx_kill_vid = efx_ef10_vlan_rx_kill_vid,
Jon Coopere5fbd972017-02-08 16:52:10 +00006787 .udp_tnl_push_ports = efx_ef10_udp_tnl_push_ports,
6788 .udp_tnl_add_port = efx_ef10_udp_tnl_add_port,
6789 .udp_tnl_has_port = efx_ef10_udp_tnl_has_port,
6790 .udp_tnl_del_port = efx_ef10_udp_tnl_del_port,
Shradha Shah7fa8d542015-05-06 00:55:13 +01006791#ifdef CONFIG_SFC_SRIOV
Shradha Shah834e23d2015-05-06 00:55:58 +01006792 .sriov_configure = efx_ef10_sriov_configure,
Shradha Shahd98a4ff2014-11-05 12:16:46 +00006793 .sriov_init = efx_ef10_sriov_init,
6794 .sriov_fini = efx_ef10_sriov_fini,
Shradha Shahd98a4ff2014-11-05 12:16:46 +00006795 .sriov_wanted = efx_ef10_sriov_wanted,
6796 .sriov_reset = efx_ef10_sriov_reset,
Shradha Shah7fa8d542015-05-06 00:55:13 +01006797 .sriov_flr = efx_ef10_sriov_flr,
6798 .sriov_set_vf_mac = efx_ef10_sriov_set_vf_mac,
6799 .sriov_set_vf_vlan = efx_ef10_sriov_set_vf_vlan,
6800 .sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk,
6801 .sriov_get_vf_config = efx_ef10_sriov_get_vf_config,
Edward Cree4392dc62015-05-20 11:12:13 +01006802 .sriov_set_vf_link_state = efx_ef10_sriov_set_vf_link_state,
Shradha Shah7b8c7b52015-05-06 00:58:54 +01006803 .vswitching_probe = efx_ef10_vswitching_probe_pf,
6804 .vswitching_restore = efx_ef10_vswitching_restore_pf,
6805 .vswitching_remove = efx_ef10_vswitching_remove_pf,
Shradha Shah7fa8d542015-05-06 00:55:13 +01006806#endif
Daniel Pieczko0d5e0fb2015-05-20 11:10:20 +01006807 .get_mac_address = efx_ef10_get_mac_address_pf,
Shradha Shah910c8782015-05-20 11:12:48 +01006808 .set_mac_address = efx_ef10_set_mac_address,
Edward Cree46d1efd2016-11-17 10:52:36 +00006809 .tso_versions = efx_ef10_tso_versions,
Ben Hutchings8127d662013-08-29 19:19:29 +01006810
Bert Kenward08a7b29b2017-01-10 16:23:33 +00006811 .get_phys_port_id = efx_ef10_get_phys_port_id,
Ben Hutchings8127d662013-08-29 19:19:29 +01006812 .revision = EFX_REV_HUNT_A0,
6813 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),
6814 .rx_prefix_size = ES_DZ_RX_PREFIX_SIZE,
6815 .rx_hash_offset = ES_DZ_RX_PREFIX_HASH_OFST,
Jon Cooperbd9a2652013-11-18 12:54:41 +00006816 .rx_ts_offset = ES_DZ_RX_PREFIX_TSTAMP_OFST,
Ben Hutchings8127d662013-08-29 19:19:29 +01006817 .can_rx_scatter = true,
6818 .always_rx_scatter = true,
Edward Creede1deff2017-01-13 21:20:14 +00006819 .option_descriptors = true,
Andrew Rybchenko6f9f6ec2017-02-13 14:57:39 +00006820 .min_interrupt_mode = EFX_INT_MODE_LEGACY,
Ben Hutchings8127d662013-08-29 19:19:29 +01006821 .max_interrupt_mode = EFX_INT_MODE_MSIX,
6822 .timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
Andrew Rybchenko100a9db2016-06-15 17:42:26 +01006823 .offload_features = EF10_OFFLOAD_FEATURES,
Ben Hutchings8127d662013-08-29 19:19:29 +01006824 .mcdi_max_ver = 2,
6825 .max_rx_ip_filters = HUNT_FILTER_TBL_ROWS,
Jon Cooperbd9a2652013-11-18 12:54:41 +00006826 .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
6827 1 << HWTSTAMP_FILTER_ALL,
Edward Creef74d1992017-01-17 12:01:53 +00006828 .rx_hash_key_size = 40,
Ben Hutchings8127d662013-08-29 19:19:29 +01006829};