Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: skeleton EF100 PF driver

No TX or RX path, no MCDI, not even an ifup/down handler.
Besides stubs, the bulk of the patch deals with reading the Xilinx
extended PCIe capability, which tells us where to find our BAR.

Though in the same module, EF100 has its own struct pci_driver,
which is named sfc_ef100.

A small number of additional nic_type methods are added; those in the
TX (tx_enqueue) and RX (rx_packet) paths are called through indirect
call wrappers to minimise the performance impact.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Edward Cree and committed by
David S. Miller
51b35a45 61060c5d

+1095 -13
+4 -1
drivers/net/ethernet/sfc/Kconfig
··· 17 17 if NET_VENDOR_SOLARFLARE 18 18 19 19 config SFC 20 - tristate "Solarflare SFC9000/SFC9100-family support" 20 + tristate "Solarflare SFC9000/SFC9100/EF100-family support" 21 21 depends on PCI 22 22 select MDIO 23 23 select CRC32 ··· 25 25 help 26 26 This driver supports 10/40-gigabit Ethernet cards based on 27 27 the Solarflare SFC9000-family and SFC9100-family controllers. 28 + 29 + It also supports 10/25/40/100-gigabit Ethernet cards based 30 + on the Solarflare EF100 networking IP in Xilinx FPGAs. 28 31 29 32 To compile this driver as a module, choose M here. The module 30 33 will be called sfc.
+3 -1
drivers/net/ethernet/sfc/Makefile
··· 4 4 tx.o tx_common.o tx_tso.o rx.o rx_common.o \ 5 5 selftest.o ethtool.o ethtool_common.o ptp.o \ 6 6 mcdi.o mcdi_port.o mcdi_port_common.o \ 7 - mcdi_functions.o mcdi_filters.o mcdi_mon.o 7 + mcdi_functions.o mcdi_filters.o mcdi_mon.o \ 8 + ef100.o ef100_nic.o ef100_netdev.o \ 9 + ef100_ethtool.o ef100_rx.o ef100_tx.o 8 10 sfc-$(CONFIG_SFC_MTD) += mtd.o 9 11 sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o ef10_sriov.o 10 12
+7
drivers/net/ethernet/sfc/ef10.c
··· 6 6 7 7 #include "net_driver.h" 8 8 #include "rx_common.h" 9 + #include "tx_common.h" 9 10 #include "ef10_regs.h" 10 11 #include "io.h" 11 12 #include "mcdi.h" ··· 3978 3977 .tx_remove = efx_mcdi_tx_remove, 3979 3978 .tx_write = efx_ef10_tx_write, 3980 3979 .tx_limit_len = efx_ef10_tx_limit_len, 3980 + .tx_enqueue = __efx_enqueue_skb, 3981 3981 .rx_push_rss_config = efx_mcdi_vf_rx_push_rss_config, 3982 3982 .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, 3983 3983 .rx_probe = efx_mcdi_rx_probe, ··· 3986 3984 .rx_remove = efx_mcdi_rx_remove, 3987 3985 .rx_write = efx_ef10_rx_write, 3988 3986 .rx_defer_refill = efx_ef10_rx_defer_refill, 3987 + .rx_packet = __efx_rx_packet, 3989 3988 .ev_probe = efx_mcdi_ev_probe, 3990 3989 .ev_init = efx_ef10_ev_init, 3991 3990 .ev_fini = efx_mcdi_ev_fini, ··· 4041 4038 .rx_hash_key_size = 40, 4042 4039 .check_caps = ef10_check_caps, 4043 4040 .print_additional_fwver = efx_ef10_print_additional_fwver, 4041 + .sensor_event = efx_mcdi_sensor_event, 4044 4042 }; 4045 4043 4046 4044 const struct efx_nic_type efx_hunt_a0_nic_type = { ··· 4091 4087 .tx_remove = efx_mcdi_tx_remove, 4092 4088 .tx_write = efx_ef10_tx_write, 4093 4089 .tx_limit_len = efx_ef10_tx_limit_len, 4090 + .tx_enqueue = __efx_enqueue_skb, 4094 4091 .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, 4095 4092 .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, 4096 4093 .rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config, ··· 4102 4097 .rx_remove = efx_mcdi_rx_remove, 4103 4098 .rx_write = efx_ef10_rx_write, 4104 4099 .rx_defer_refill = efx_ef10_rx_defer_refill, 4100 + .rx_packet = __efx_rx_packet, 4105 4101 .ev_probe = efx_mcdi_ev_probe, 4106 4102 .ev_init = efx_ef10_ev_init, 4107 4103 .ev_fini = efx_mcdi_ev_fini, ··· 4178 4172 .rx_hash_key_size = 40, 4179 4173 .check_caps = ef10_check_caps, 4180 4174 .print_additional_fwver = efx_ef10_print_additional_fwver, 4175 + .sensor_event = efx_mcdi_sensor_event, 4181 4176 };
+541
drivers/net/ethernet/sfc/ef100.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2005-2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include "net_driver.h" 13 + #include <linux/module.h> 14 + #include <linux/aer.h> 15 + #include "efx_common.h" 16 + #include "efx_channels.h" 17 + #include "io.h" 18 + #include "ef100_nic.h" 19 + #include "ef100_netdev.h" 20 + #include "ef100_regs.h" 21 + #include "ef100.h" 22 + 23 + #define EFX_EF100_PCI_DEFAULT_BAR 2 24 + 25 + /* Number of bytes at start of vendor specified extended capability that indicate 26 + * that the capability is vendor specified. i.e. offset from value returned by 27 + * pci_find_next_ext_capability() to beginning of vendor specified capability 28 + * header. 29 + */ 30 + #define PCI_EXT_CAP_HDR_LENGTH 4 31 + 32 + /* Expected size of a Xilinx continuation address table entry. */ 33 + #define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH 16 34 + 35 + struct ef100_func_ctl_window { 36 + bool valid; 37 + unsigned int bar; 38 + u64 offset; 39 + }; 40 + 41 + static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset, 42 + struct ef100_func_ctl_window *result); 43 + 44 + /* Number of bytes to offset when reading bit position x with dword accessors. */ 45 + #define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3) 46 + 47 + #define EXTRACT_BITS(x, lbn, width) \ 48 + (((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1)) 49 + 50 + static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx, 51 + int structure_start, 52 + int lbn, int width) 53 + { 54 + efx_dword_t dword; 55 + 56 + efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn)); 57 + 58 + return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width); 59 + } 60 + 61 + #define ef100_pci_get_bar_bits(efx, entry_location, bitdef) \ 62 + _ef100_pci_get_bar_bits_with_width(efx, entry_location, \ 63 + ESF_GZ_CFGBAR_ ## bitdef ## _LBN, \ 64 + ESF_GZ_CFGBAR_ ## bitdef ## _WIDTH) 65 + 66 + static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location, 67 + struct ef100_func_ctl_window *result) 68 + { 69 + u64 offset = ef100_pci_get_bar_bits(efx, entry_location, EF100_FUNC_CTL_WIN_OFF) << 70 + ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT; 71 + u32 bar = ef100_pci_get_bar_bits(efx, entry_location, EF100_BAR); 72 + 73 + netif_dbg(efx, probe, efx->net_dev, 74 + "Found EF100 function control window bar=%d offset=0x%llx\n", 75 + bar, offset); 76 + 77 + if (result->valid) { 78 + netif_err(efx, probe, efx->net_dev, 79 + "Duplicated EF100 table entry.\n"); 80 + return -EINVAL; 81 + } 82 + 83 + if (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM || 84 + bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID) { 85 + netif_err(efx, probe, efx->net_dev, 86 + "Bad BAR value of %d in Xilinx capabilities EF100 entry.\n", 87 + bar); 88 + return -EINVAL; 89 + } 90 + 91 + result->bar = bar; 92 + result->offset = offset; 93 + result->valid = true; 94 + return 0; 95 + } 96 + 97 + static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar, 98 + u64 next_entry) 99 + { 100 + return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE > 101 + pci_resource_len(efx->pci_dev, bar); 102 + } 103 + 104 + /* Parse a Xilinx capabilities table entry describing a continuation to a new 105 + * sub-table. 106 + */ 107 + static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location, 108 + struct ef100_func_ctl_window *result) 109 + { 110 + unsigned int previous_bar; 111 + efx_oword_t entry; 112 + u64 offset; 113 + int rc = 0; 114 + u32 bar; 115 + 116 + efx_reado(efx, &entry, entry_location); 117 + 118 + bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR); 119 + 120 + offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) << 121 + ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT; 122 + 123 + previous_bar = efx->mem_bar; 124 + 125 + if (bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM || 126 + bar == ESE_GZ_VSEC_BAR_NUM_INVALID) { 127 + netif_err(efx, probe, efx->net_dev, 128 + "Bad BAR value of %d in Xilinx capabilities sub-table.\n", 129 + bar); 130 + return -EINVAL; 131 + } 132 + 133 + if (bar != previous_bar) { 134 + efx_fini_io(efx); 135 + 136 + if (ef100_pci_does_bar_overflow(efx, bar, offset)) { 137 + netif_err(efx, probe, efx->net_dev, 138 + "Xilinx table will overrun BAR[%d] offset=0x%llx\n", 139 + bar, offset); 140 + return -EINVAL; 141 + } 142 + 143 + /* Temporarily map new BAR. */ 144 + rc = efx_init_io(efx, bar, 145 + DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH), 146 + pci_resource_len(efx->pci_dev, bar)); 147 + if (rc) { 148 + netif_err(efx, probe, efx->net_dev, 149 + "Mapping new BAR for Xilinx table failed, rc=%d\n", rc); 150 + return rc; 151 + } 152 + } 153 + 154 + rc = ef100_pci_walk_xilinx_table(efx, offset, result); 155 + if (rc) 156 + return rc; 157 + 158 + if (bar != previous_bar) { 159 + efx_fini_io(efx); 160 + 161 + /* Put old BAR back. */ 162 + rc = efx_init_io(efx, previous_bar, 163 + DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH), 164 + pci_resource_len(efx->pci_dev, previous_bar)); 165 + if (rc) { 166 + netif_err(efx, probe, efx->net_dev, 167 + "Putting old BAR back failed, rc=%d\n", rc); 168 + return rc; 169 + } 170 + } 171 + 172 + return 0; 173 + } 174 + 175 + /* Iterate over the Xilinx capabilities table in the currently mapped BAR and 176 + * call ef100_pci_parse_ef100_entry() on any EF100 entries and 177 + * ef100_pci_parse_continue_entry() on any table continuations. 178 + */ 179 + static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset, 180 + struct ef100_func_ctl_window *result) 181 + { 182 + u64 current_entry = offset; 183 + int rc = 0; 184 + 185 + while (true) { 186 + u32 id = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_FORMAT); 187 + u32 last = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_LAST); 188 + u32 rev = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_REV); 189 + u32 entry_size; 190 + 191 + if (id == ESE_GZ_CFGBAR_ENTRY_LAST) 192 + return 0; 193 + 194 + entry_size = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_SIZE); 195 + 196 + netif_dbg(efx, probe, efx->net_dev, 197 + "Seen Xilinx table entry 0x%x size 0x%x at 0x%llx in BAR[%d]\n", 198 + id, entry_size, current_entry, efx->mem_bar); 199 + 200 + if (entry_size < sizeof(u32) * 2) { 201 + netif_err(efx, probe, efx->net_dev, 202 + "Xilinx table entry too short len=0x%x\n", entry_size); 203 + return -EINVAL; 204 + } 205 + 206 + switch (id) { 207 + case ESE_GZ_CFGBAR_ENTRY_EF100: 208 + if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 || 209 + entry_size < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) { 210 + netif_err(efx, probe, efx->net_dev, 211 + "Bad length or rev for EF100 entry in Xilinx capabilities table. entry_size=%d rev=%d.\n", 212 + entry_size, rev); 213 + return -EINVAL; 214 + } 215 + 216 + rc = ef100_pci_parse_ef100_entry(efx, current_entry, 217 + result); 218 + if (rc) 219 + return rc; 220 + break; 221 + case ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR: 222 + if (rev != 0 || entry_size < ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH) { 223 + netif_err(efx, probe, efx->net_dev, 224 + "Bad length or rev for continue entry in Xilinx capabilities table. entry_size=%d rev=%d.\n", 225 + entry_size, rev); 226 + return -EINVAL; 227 + } 228 + 229 + rc = ef100_pci_parse_continue_entry(efx, current_entry, result); 230 + if (rc) 231 + return rc; 232 + break; 233 + default: 234 + /* Ignore unknown table entries. */ 235 + break; 236 + } 237 + 238 + if (last) 239 + return 0; 240 + 241 + current_entry += entry_size; 242 + 243 + if (ef100_pci_does_bar_overflow(efx, efx->mem_bar, current_entry)) { 244 + netif_err(efx, probe, efx->net_dev, 245 + "Xilinx table overrun at position=0x%llx.\n", 246 + current_entry); 247 + return -EINVAL; 248 + } 249 + } 250 + } 251 + 252 + static int _ef100_pci_get_config_bits_with_width(struct efx_nic *efx, 253 + int structure_start, int lbn, 254 + int width, u32 *result) 255 + { 256 + int rc, pos = structure_start + ROUND_DOWN_TO_DWORD(lbn); 257 + u32 temp; 258 + 259 + rc = pci_read_config_dword(efx->pci_dev, pos, &temp); 260 + if (rc) { 261 + netif_err(efx, probe, efx->net_dev, 262 + "Failed to read PCI config dword at %d\n", 263 + pos); 264 + return rc; 265 + } 266 + 267 + *result = EXTRACT_BITS(temp, lbn, width); 268 + 269 + return 0; 270 + } 271 + 272 + #define ef100_pci_get_config_bits(efx, entry_location, bitdef, result) \ 273 + _ef100_pci_get_config_bits_with_width(efx, entry_location, \ 274 + ESF_GZ_VSEC_ ## bitdef ## _LBN, \ 275 + ESF_GZ_VSEC_ ## bitdef ## _WIDTH, result) 276 + 277 + /* Call ef100_pci_walk_xilinx_table() for the Xilinx capabilities table pointed 278 + * to by this PCI_EXT_CAP_ID_VNDR. 279 + */ 280 + static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap, 281 + bool has_offset_hi, 282 + struct ef100_func_ctl_window *result) 283 + { 284 + u32 offset_high = 0; 285 + u32 offset_lo = 0; 286 + u64 offset = 0; 287 + u32 bar = 0; 288 + int rc = 0; 289 + 290 + rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_BAR, &bar); 291 + if (rc) { 292 + netif_err(efx, probe, efx->net_dev, 293 + "Failed to read ESF_GZ_VSEC_TBL_BAR, rc=%d\n", 294 + rc); 295 + return rc; 296 + } 297 + 298 + if (bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM || 299 + bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID) { 300 + netif_err(efx, probe, efx->net_dev, 301 + "Bad BAR value of %d in Xilinx capabilities sub-table.\n", 302 + bar); 303 + return -EINVAL; 304 + } 305 + 306 + rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_LO, &offset_lo); 307 + if (rc) { 308 + netif_err(efx, probe, efx->net_dev, 309 + "Failed to read ESF_GZ_VSEC_TBL_OFF_LO, rc=%d\n", 310 + rc); 311 + return rc; 312 + } 313 + 314 + /* Get optional extension to 64bit offset. */ 315 + if (has_offset_hi) { 316 + rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_HI, &offset_high); 317 + if (rc) { 318 + netif_err(efx, probe, efx->net_dev, 319 + "Failed to read ESF_GZ_VSEC_TBL_OFF_HI, rc=%d\n", 320 + rc); 321 + return rc; 322 + } 323 + } 324 + 325 + offset = (((u64)offset_lo) << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT) | 326 + (((u64)offset_high) << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT); 327 + 328 + if (offset > pci_resource_len(efx->pci_dev, bar) - sizeof(u32) * 2) { 329 + netif_err(efx, probe, efx->net_dev, 330 + "Xilinx table will overrun BAR[%d] offset=0x%llx\n", 331 + bar, offset); 332 + return -EINVAL; 333 + } 334 + 335 + /* Temporarily map BAR. */ 336 + rc = efx_init_io(efx, bar, 337 + DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH), 338 + pci_resource_len(efx->pci_dev, bar)); 339 + if (rc) { 340 + netif_err(efx, probe, efx->net_dev, 341 + "efx_init_io failed, rc=%d\n", rc); 342 + return rc; 343 + } 344 + 345 + rc = ef100_pci_walk_xilinx_table(efx, offset, result); 346 + 347 + /* Unmap temporarily mapped BAR. */ 348 + efx_fini_io(efx); 349 + return rc; 350 + } 351 + 352 + /* Call ef100_pci_parse_ef100_entry() for each Xilinx PCI_EXT_CAP_ID_VNDR 353 + * capability. 354 + */ 355 + static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx, 356 + struct ef100_func_ctl_window *result) 357 + { 358 + int num_xilinx_caps = 0; 359 + int cap = 0; 360 + 361 + result->valid = false; 362 + 363 + while ((cap = pci_find_next_ext_capability(efx->pci_dev, cap, PCI_EXT_CAP_ID_VNDR)) != 0) { 364 + int vndr_cap = cap + PCI_EXT_CAP_HDR_LENGTH; 365 + u32 vsec_ver = 0; 366 + u32 vsec_len = 0; 367 + u32 vsec_id = 0; 368 + int rc = 0; 369 + 370 + num_xilinx_caps++; 371 + 372 + rc = ef100_pci_get_config_bits(efx, vndr_cap, ID, &vsec_id); 373 + if (rc) { 374 + netif_err(efx, probe, efx->net_dev, 375 + "Failed to read ESF_GZ_VSEC_ID, rc=%d\n", 376 + rc); 377 + return rc; 378 + } 379 + 380 + rc = ef100_pci_get_config_bits(efx, vndr_cap, VER, &vsec_ver); 381 + if (rc) { 382 + netif_err(efx, probe, efx->net_dev, 383 + "Failed to read ESF_GZ_VSEC_VER, rc=%d\n", 384 + rc); 385 + return rc; 386 + } 387 + 388 + /* Get length of whole capability - i.e. starting at cap */ 389 + rc = ef100_pci_get_config_bits(efx, vndr_cap, LEN, &vsec_len); 390 + if (rc) { 391 + netif_err(efx, probe, efx->net_dev, 392 + "Failed to read ESF_GZ_VSEC_LEN, rc=%d\n", 393 + rc); 394 + return rc; 395 + } 396 + 397 + if (vsec_id == ESE_GZ_XILINX_VSEC_ID && 398 + vsec_ver == ESE_GZ_VSEC_VER_XIL_CFGBAR && 399 + vsec_len >= ESE_GZ_VSEC_LEN_MIN) { 400 + bool has_offset_hi = (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT); 401 + 402 + rc = ef100_pci_parse_xilinx_cap(efx, vndr_cap, 403 + has_offset_hi, result); 404 + if (rc) 405 + return rc; 406 + } 407 + } 408 + 409 + if (num_xilinx_caps && !result->valid) { 410 + netif_err(efx, probe, efx->net_dev, 411 + "Seen %d Xilinx tables, but no EF100 entry.\n", 412 + num_xilinx_caps); 413 + return -EINVAL; 414 + } 415 + 416 + return 0; 417 + } 418 + 419 + /* Final NIC shutdown 420 + * This is called only at module unload (or hotplug removal). A PF can call 421 + * this on its VFs to ensure they are unbound first. 422 + */ 423 + static void ef100_pci_remove(struct pci_dev *pci_dev) 424 + { 425 + struct efx_nic *efx; 426 + 427 + efx = pci_get_drvdata(pci_dev); 428 + if (!efx) 429 + return; 430 + 431 + rtnl_lock(); 432 + dev_close(efx->net_dev); 433 + rtnl_unlock(); 434 + 435 + /* Unregistering our netdev notifier triggers unbinding of TC indirect 436 + * blocks, so we have to do it before PCI removal. 437 + */ 438 + unregister_netdevice_notifier(&efx->netdev_notifier); 439 + ef100_remove(efx); 440 + efx_fini_io(efx); 441 + netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); 442 + 443 + pci_set_drvdata(pci_dev, NULL); 444 + efx_fini_struct(efx); 445 + free_netdev(efx->net_dev); 446 + 447 + pci_disable_pcie_error_reporting(pci_dev); 448 + }; 449 + 450 + static int ef100_pci_probe(struct pci_dev *pci_dev, 451 + const struct pci_device_id *entry) 452 + { 453 + struct ef100_func_ctl_window fcw = { 0 }; 454 + struct net_device *net_dev; 455 + struct efx_nic *efx; 456 + int rc; 457 + 458 + /* Allocate and initialise a struct net_device and struct efx_nic */ 459 + net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES); 460 + if (!net_dev) 461 + return -ENOMEM; 462 + efx = netdev_priv(net_dev); 463 + efx->type = (const struct efx_nic_type *)entry->driver_data; 464 + 465 + pci_set_drvdata(pci_dev, efx); 466 + SET_NETDEV_DEV(net_dev, &pci_dev->dev); 467 + rc = efx_init_struct(efx, pci_dev, net_dev); 468 + if (rc) 469 + goto fail; 470 + 471 + efx->vi_stride = EF100_DEFAULT_VI_STRIDE; 472 + netif_info(efx, probe, efx->net_dev, 473 + "Solarflare EF100 NIC detected\n"); 474 + 475 + rc = ef100_pci_find_func_ctrl_window(efx, &fcw); 476 + if (rc) { 477 + netif_err(efx, probe, efx->net_dev, 478 + "Error looking for ef100 function control window, rc=%d\n", 479 + rc); 480 + goto fail; 481 + } 482 + 483 + if (!fcw.valid) { 484 + /* Extended capability not found - use defaults. */ 485 + fcw.bar = EFX_EF100_PCI_DEFAULT_BAR; 486 + fcw.offset = 0; 487 + fcw.valid = true; 488 + } 489 + 490 + if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) { 491 + netif_err(efx, probe, efx->net_dev, 492 + "Func control window overruns BAR\n"); 493 + goto fail; 494 + } 495 + 496 + /* Set up basic I/O (BAR mappings etc) */ 497 + rc = efx_init_io(efx, fcw.bar, 498 + DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH), 499 + pci_resource_len(efx->pci_dev, fcw.bar)); 500 + if (rc) 501 + goto fail; 502 + 503 + efx->reg_base = fcw.offset; 504 + 505 + efx->netdev_notifier.notifier_call = ef100_netdev_event; 506 + rc = register_netdevice_notifier(&efx->netdev_notifier); 507 + if (rc) { 508 + netif_err(efx, probe, efx->net_dev, 509 + "Failed to register netdevice notifier, rc=%d\n", rc); 510 + goto fail; 511 + } 512 + 513 + rc = efx->type->probe(efx); 514 + if (rc) 515 + goto fail; 516 + 517 + netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n"); 518 + 519 + return 0; 520 + 521 + fail: 522 + ef100_pci_remove(pci_dev); 523 + return rc; 524 + } 525 + 526 + /* PCI device ID table */ 527 + static const struct pci_device_id ef100_pci_table[] = { 528 + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x0100), /* Riverhead PF */ 529 + .driver_data = (unsigned long) &ef100_pf_nic_type }, 530 + {0} /* end of list */ 531 + }; 532 + 533 + struct pci_driver ef100_pci_driver = { 534 + .name = "sfc_ef100", 535 + .id_table = ef100_pci_table, 536 + .probe = ef100_pci_probe, 537 + .remove = ef100_pci_remove, 538 + .err_handler = &efx_err_handlers, 539 + }; 540 + 541 + MODULE_DEVICE_TABLE(pci, ef100_pci_table);
+12
drivers/net/ethernet/sfc/ef100.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + extern struct pci_driver ef100_pci_driver;
+24
drivers/net/ethernet/sfc/ef100_ethtool.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + #include <linux/module.h> 12 + #include <linux/netdevice.h> 13 + #include "net_driver.h" 14 + #include "efx.h" 15 + #include "mcdi_port_common.h" 16 + #include "ethtool_common.h" 17 + #include "ef100_ethtool.h" 18 + #include "mcdi_functions.h" 19 + 20 + /* Ethtool options available 21 + */ 22 + const struct ethtool_ops ef100_ethtool_ops = { 23 + .get_drvinfo = efx_ethtool_get_drvinfo, 24 + };
+12
drivers/net/ethernet/sfc/ef100_ethtool.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + extern const struct ethtool_ops ef100_ethtool_ops;
+129
drivers/net/ethernet/sfc/ef100_netdev.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + #include "net_driver.h" 12 + #include "mcdi_port_common.h" 13 + #include "mcdi_functions.h" 14 + #include "efx_common.h" 15 + #include "efx_channels.h" 16 + #include "tx_common.h" 17 + #include "ef100_netdev.h" 18 + #include "ef100_ethtool.h" 19 + #include "efx_common.h" 20 + #include "nic_common.h" 21 + #include "ef100_nic.h" 22 + #include "ef100_tx.h" 23 + #include "ef100_regs.h" 24 + #include "mcdi_filters.h" 25 + #include "rx_common.h" 26 + 27 + static void ef100_update_name(struct efx_nic *efx) 28 + { 29 + strcpy(efx->name, efx->net_dev->name); 30 + } 31 + 32 + /* Initiate a packet transmission. We use one channel per CPU 33 + * (sharing when we have more CPUs than channels). 34 + * 35 + * Context: non-blocking. 36 + * Note that returning anything other than NETDEV_TX_OK will cause the 37 + * OS to free the skb. 38 + */ 39 + static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb, 40 + struct net_device *net_dev) 41 + { 42 + struct efx_nic *efx = netdev_priv(net_dev); 43 + struct efx_tx_queue *tx_queue; 44 + struct efx_channel *channel; 45 + int rc; 46 + 47 + channel = efx_get_tx_channel(efx, skb_get_queue_mapping(skb)); 48 + netif_vdbg(efx, tx_queued, efx->net_dev, 49 + "%s len %d data %d channel %d\n", __func__, 50 + skb->len, skb->data_len, channel->channel); 51 + if (!efx->n_channels || !efx->n_tx_channels || !channel) { 52 + netif_stop_queue(net_dev); 53 + goto err; 54 + } 55 + 56 + tx_queue = &channel->tx_queue[0]; 57 + rc = ef100_enqueue_skb(tx_queue, skb); 58 + if (rc == 0) 59 + return NETDEV_TX_OK; 60 + 61 + err: 62 + net_dev->stats.tx_dropped++; 63 + return NETDEV_TX_OK; 64 + } 65 + 66 + static const struct net_device_ops ef100_netdev_ops = { 67 + .ndo_start_xmit = ef100_hard_start_xmit, 68 + }; 69 + 70 + /* Netdev registration 71 + */ 72 + int ef100_netdev_event(struct notifier_block *this, 73 + unsigned long event, void *ptr) 74 + { 75 + struct efx_nic *efx = container_of(this, struct efx_nic, netdev_notifier); 76 + struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); 77 + 78 + if (netdev_priv(net_dev) == efx && event == NETDEV_CHANGENAME) 79 + ef100_update_name(efx); 80 + 81 + return NOTIFY_DONE; 82 + } 83 + 84 + int ef100_register_netdev(struct efx_nic *efx) 85 + { 86 + struct net_device *net_dev = efx->net_dev; 87 + int rc; 88 + 89 + net_dev->watchdog_timeo = 5 * HZ; 90 + net_dev->irq = efx->pci_dev->irq; 91 + net_dev->netdev_ops = &ef100_netdev_ops; 92 + net_dev->min_mtu = EFX_MIN_MTU; 93 + net_dev->max_mtu = EFX_MAX_MTU; 94 + net_dev->ethtool_ops = &ef100_ethtool_ops; 95 + 96 + rtnl_lock(); 97 + 98 + rc = dev_alloc_name(net_dev, net_dev->name); 99 + if (rc < 0) 100 + goto fail_locked; 101 + ef100_update_name(efx); 102 + 103 + rc = register_netdevice(net_dev); 104 + if (rc) 105 + goto fail_locked; 106 + 107 + /* Always start with carrier off; PHY events will detect the link */ 108 + netif_carrier_off(net_dev); 109 + 110 + efx->state = STATE_READY; 111 + rtnl_unlock(); 112 + efx_init_mcdi_logging(efx); 113 + 114 + return 0; 115 + 116 + fail_locked: 117 + rtnl_unlock(); 118 + netif_err(efx, drv, efx->net_dev, "could not register net dev\n"); 119 + return rc; 120 + } 121 + 122 + void ef100_unregister_netdev(struct efx_nic *efx) 123 + { 124 + if (efx_dev_registered(efx)) { 125 + efx_fini_mcdi_logging(efx); 126 + efx->state = STATE_UNINIT; 127 + unregister_netdev(efx->net_dev); 128 + } 129 + }
+17
drivers/net/ethernet/sfc/ef100_netdev.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include <linux/netdevice.h> 13 + 14 + int ef100_netdev_event(struct notifier_block *this, 15 + unsigned long event, void *ptr); 16 + int ef100_register_netdev(struct efx_nic *efx); 17 + void ef100_unregister_netdev(struct efx_nic *efx);
+174
drivers/net/ethernet/sfc/ef100_nic.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include "ef100_nic.h" 13 + #include "efx_common.h" 14 + #include "efx_channels.h" 15 + #include "io.h" 16 + #include "selftest.h" 17 + #include "ef100_regs.h" 18 + #include "mcdi.h" 19 + #include "mcdi_pcol.h" 20 + #include "mcdi_port_common.h" 21 + #include "mcdi_functions.h" 22 + #include "mcdi_filters.h" 23 + #include "ef100_rx.h" 24 + #include "ef100_tx.h" 25 + #include "ef100_netdev.h" 26 + 27 + #define EF100_MAX_VIS 4096 28 + 29 + /* MCDI 30 + */ 31 + static int ef100_get_warm_boot_count(struct efx_nic *efx) 32 + { 33 + efx_dword_t reg; 34 + 35 + efx_readd(efx, &reg, efx_reg(efx, ER_GZ_MC_SFT_STATUS)); 36 + 37 + if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) == 0xffffffff) { 38 + netif_err(efx, hw, efx->net_dev, "Hardware unavailable\n"); 39 + efx->state = STATE_DISABLED; 40 + return -ENETDOWN; 41 + } else { 42 + return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ? 43 + EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO; 44 + } 45 + } 46 + 47 + /* Event handling 48 + */ 49 + static int ef100_ev_probe(struct efx_channel *channel) 50 + { 51 + /* Allocate an extra descriptor for the QMDA status completion entry */ 52 + return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf, 53 + (channel->eventq_mask + 2) * 54 + sizeof(efx_qword_t), 55 + GFP_KERNEL); 56 + } 57 + 58 + static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id) 59 + { 60 + struct efx_msi_context *context = dev_id; 61 + struct efx_nic *efx = context->efx; 62 + 63 + netif_vdbg(efx, intr, efx->net_dev, 64 + "IRQ %d on CPU %d\n", irq, raw_smp_processor_id()); 65 + 66 + if (likely(READ_ONCE(efx->irq_soft_enabled))) { 67 + /* Note test interrupts */ 68 + if (context->index == efx->irq_level) 69 + efx->last_irq_cpu = raw_smp_processor_id(); 70 + 71 + /* Schedule processing of the channel */ 72 + efx_schedule_channel_irq(efx->channel[context->index]); 73 + } 74 + 75 + return IRQ_HANDLED; 76 + } 77 + 78 + /* NIC level access functions 79 + */ 80 + const struct efx_nic_type ef100_pf_nic_type = { 81 + .revision = EFX_REV_EF100, 82 + .is_vf = false, 83 + .probe = ef100_probe_pf, 84 + .mcdi_max_ver = 2, 85 + .irq_enable_master = efx_port_dummy_op_void, 86 + .irq_disable_non_ev = efx_port_dummy_op_void, 87 + .push_irq_moderation = efx_channel_dummy_op_void, 88 + .min_interrupt_mode = EFX_INT_MODE_MSIX, 89 + 90 + .ev_probe = ef100_ev_probe, 91 + .irq_handle_msi = ef100_msi_interrupt, 92 + 93 + /* Per-type bar/size configuration not used on ef100. Location of 94 + * registers is defined by extended capabilities. 95 + */ 96 + .mem_bar = NULL, 97 + .mem_map_size = NULL, 98 + 99 + }; 100 + 101 + /* NIC probe and remove 102 + */ 103 + static int ef100_probe_main(struct efx_nic *efx) 104 + { 105 + unsigned int bar_size = resource_size(&efx->pci_dev->resource[efx->mem_bar]); 106 + struct net_device *net_dev = efx->net_dev; 107 + struct ef100_nic_data *nic_data; 108 + int i, rc; 109 + 110 + if (WARN_ON(bar_size == 0)) 111 + return -EIO; 112 + 113 + nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); 114 + if (!nic_data) 115 + return -ENOMEM; 116 + efx->nic_data = nic_data; 117 + nic_data->efx = efx; 118 + net_dev->features |= efx->type->offload_features; 119 + net_dev->hw_features |= efx->type->offload_features; 120 + 121 + /* Get the MC's warm boot count. In case it's rebooting right 122 + * now, be prepared to retry. 123 + */ 124 + i = 0; 125 + for (;;) { 126 + rc = ef100_get_warm_boot_count(efx); 127 + if (rc >= 0) 128 + break; 129 + if (++i == 5) 130 + goto fail; 131 + ssleep(1); 132 + } 133 + nic_data->warm_boot_count = rc; 134 + 135 + /* In case we're recovering from a crash (kexec), we want to 136 + * cancel any outstanding request by the previous user of this 137 + * function. We send a special message using the least 138 + * significant bits of the 'high' (doorbell) register. 139 + */ 140 + _efx_writed(efx, cpu_to_le32(1), efx_reg(efx, ER_GZ_MC_DB_HWRD)); 141 + 142 + /* Post-IO section. */ 143 + 144 + efx->max_vis = EF100_MAX_VIS; 145 + 146 + rc = efx_init_channels(efx); 147 + if (rc) 148 + goto fail; 149 + 150 + rc = ef100_register_netdev(efx); 151 + if (rc) 152 + goto fail; 153 + 154 + return 0; 155 + fail: 156 + return rc; 157 + } 158 + 159 + int ef100_probe_pf(struct efx_nic *efx) 160 + { 161 + return ef100_probe_main(efx); 162 + } 163 + 164 + void ef100_remove(struct efx_nic *efx) 165 + { 166 + struct ef100_nic_data *nic_data = efx->nic_data; 167 + 168 + ef100_unregister_netdev(efx); 169 + efx_fini_channels(efx); 170 + kfree(efx->phy_data); 171 + efx->phy_data = NULL; 172 + kfree(nic_data); 173 + efx->nic_data = NULL; 174 + }
+26
drivers/net/ethernet/sfc/ef100_nic.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include "net_driver.h" 13 + #include "nic_common.h" 14 + 15 + extern const struct efx_nic_type ef100_pf_nic_type; 16 + 17 + int ef100_probe_pf(struct efx_nic *efx); 18 + void ef100_remove(struct efx_nic *efx); 19 + 20 + struct ef100_nic_data { 21 + struct efx_nic *efx; 22 + u16 warm_boot_count; 23 + }; 24 + 25 + #define efx_ef100_has_cap(caps, flag) \ 26 + (!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN)))
+25
drivers/net/ethernet/sfc/ef100_rx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2005-2019 Solarflare Communications Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License version 2 as published 8 + * by the Free Software Foundation, incorporated herein by reference. 9 + */ 10 + 11 + #include "net_driver.h" 12 + #include "ef100_rx.h" 13 + #include "rx_common.h" 14 + #include "efx.h" 15 + 16 + void __ef100_rx_packet(struct efx_channel *channel) 17 + { 18 + /* Stub. No RX path yet. Discard the buffer. */ 19 + struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue, 20 + channel->rx_pkt_index); 21 + struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); 22 + 23 + efx_free_rx_buffers(rx_queue, rx_buf, 1); 24 + channel->rx_pkt_n_frags = 0; 25 + }
+19
drivers/net/ethernet/sfc/ef100_rx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2019 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #ifndef EFX_EF100_RX_H 13 + #define EFX_EF100_RX_H 14 + 15 + #include "net_driver.h" 16 + 17 + void __ef100_rx_packet(struct efx_channel *channel); 18 + 19 + #endif
+32
drivers/net/ethernet/sfc/ef100_tx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2018 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include "net_driver.h" 13 + #include "tx_common.h" 14 + #include "nic_common.h" 15 + #include "ef100_tx.h" 16 + 17 + /* Add a socket buffer to a TX queue 18 + * 19 + * You must hold netif_tx_lock() to call this function. 20 + * 21 + * Returns 0 on success, error code otherwise. In case of an error this 22 + * function will free the SKB. 23 + */ 24 + int ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) 25 + { 26 + /* Stub. No TX path yet. */ 27 + struct efx_nic *efx = tx_queue->efx; 28 + 29 + netif_stop_queue(efx->net_dev); 30 + dev_kfree_skb_any(skb); 31 + return -ENODEV; 32 + }
+18
drivers/net/ethernet/sfc/ef100_tx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2019 Solarflare Communications Inc. 5 + * Copyright 2019-2020 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #ifndef EFX_EF100_TX_H 13 + #define EFX_EF100_TX_H 14 + 15 + #include "net_driver.h" 16 + 17 + netdev_tx_t ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); 18 + #endif
+8
drivers/net/ethernet/sfc/efx.c
··· 25 25 #include "efx.h" 26 26 #include "efx_common.h" 27 27 #include "efx_channels.h" 28 + #include "ef100.h" 28 29 #include "rx_common.h" 29 30 #include "tx_common.h" 30 31 #include "nic.h" ··· 1361 1360 if (rc < 0) 1362 1361 goto err_pci; 1363 1362 1363 + rc = pci_register_driver(&ef100_pci_driver); 1364 + if (rc < 0) 1365 + goto err_pci_ef100; 1366 + 1364 1367 return 0; 1365 1368 1369 + err_pci_ef100: 1370 + pci_unregister_driver(&efx_pci_driver); 1366 1371 err_pci: 1367 1372 efx_destroy_reset_workqueue(); 1368 1373 err_reset: ··· 1385 1378 { 1386 1379 printk(KERN_INFO "Solarflare NET driver unloading\n"); 1387 1380 1381 + pci_unregister_driver(&ef100_pci_driver); 1388 1382 pci_unregister_driver(&efx_pci_driver); 1389 1383 efx_destroy_reset_workqueue(); 1390 1384 #ifdef CONFIG_SFC_SRIOV
+13 -3
drivers/net/ethernet/sfc/efx.h
··· 8 8 #ifndef EFX_EFX_H 9 9 #define EFX_EFX_H 10 10 11 + #include <linux/indirect_call_wrapper.h> 11 12 #include "net_driver.h" 13 + #include "ef100_rx.h" 14 + #include "ef100_tx.h" 12 15 #include "filter.h" 13 16 14 17 int efx_net_open(struct net_device *net_dev); ··· 21 18 void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue); 22 19 netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, 23 20 struct net_device *net_dev); 24 - netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); 21 + netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); 22 + static inline netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) 23 + { 24 + return INDIRECT_CALL_2(tx_queue->efx->type->tx_enqueue, 25 + ef100_enqueue_skb, __efx_enqueue_skb, 26 + tx_queue, skb); 27 + } 25 28 void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); 26 29 void efx_xmit_done_single(struct efx_tx_queue *tx_queue); 27 30 int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type, 28 31 void *type_data); 29 32 extern unsigned int efx_piobuf_size; 30 - extern bool efx_separate_tx_channels; 31 33 32 34 /* RX */ 33 35 void __efx_rx_packet(struct efx_channel *channel); ··· 41 33 static inline void efx_rx_flush_packet(struct efx_channel *channel) 42 34 { 43 35 if (channel->rx_pkt_n_frags) 44 - __efx_rx_packet(channel); 36 + INDIRECT_CALL_2(channel->efx->type->rx_packet, 37 + __ef100_rx_packet, __efx_rx_packet, 38 + channel); 45 39 } 46 40 47 41 /* Maximum number of TCP segments we support for soft-TSO */
-2
drivers/net/ethernet/sfc/ethtool.c
··· 221 221 return 0; 222 222 } 223 223 224 - const char *efx_driver_name = KBUILD_MODNAME; 225 - 226 224 const struct ethtool_ops efx_ethtool_ops = { 227 225 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 228 226 ETHTOOL_COALESCE_USECS_IRQ |
+1 -1
drivers/net/ethernet/sfc/ethtool_common.c
··· 104 104 { 105 105 struct efx_nic *efx = netdev_priv(net_dev); 106 106 107 - strlcpy(info->driver, efx_driver_name, sizeof(info->driver)); 107 + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 108 108 strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version)); 109 109 efx_mcdi_print_fwver(efx, info->fw_version, 110 110 sizeof(info->fw_version));
-2
drivers/net/ethernet/sfc/ethtool_common.h
··· 11 11 #ifndef EFX_ETHTOOL_COMMON_H 12 12 #define EFX_ETHTOOL_COMMON_H 13 13 14 - extern const char *efx_driver_name; 15 - 16 14 void efx_ethtool_get_drvinfo(struct net_device *net_dev, 17 15 struct ethtool_drvinfo *info); 18 16 u32 efx_ethtool_get_msglevel(struct net_device *net_dev);
+1 -1
drivers/net/ethernet/sfc/mcdi.c
··· 1337 1337 efx_mcdi_process_link_change(efx, event); 1338 1338 break; 1339 1339 case MCDI_EVENT_CODE_SENSOREVT: 1340 - efx_mcdi_sensor_event(efx, event); 1340 + efx_sensor_event(efx, event); 1341 1341 break; 1342 1342 case MCDI_EVENT_CODE_SCHEDERR: 1343 1343 netif_dbg(efx, hw, efx->net_dev,
+16
drivers/net/ethernet/sfc/net_driver.h
··· 963 963 * @vpd_sn: Serial number read from VPD 964 964 * @xdp_rxq_info_failed: Have any of the rx queues failed to initialise their 965 965 * xdp_rxq_info structures? 966 + * @netdev_notifier: Netdevice notifier. 966 967 * @mem_bar: The BAR that is mapped into membase. 967 968 * @reg_base: Offset from the start of the bar to the function control window. 968 969 * @monitor_work: Hardware monitor workitem ··· 1143 1142 char *vpd_sn; 1144 1143 bool xdp_rxq_info_failed; 1145 1144 1145 + struct notifier_block netdev_notifier; 1146 + 1146 1147 unsigned int mem_bar; 1147 1148 u32 reg_base; 1148 1149 ··· 1249 1246 * @tx_init: Initialise TX queue on the NIC 1250 1247 * @tx_remove: Free resources for TX queue 1251 1248 * @tx_write: Write TX descriptors and doorbell 1249 + * @tx_enqueue: Add an SKB to TX queue 1252 1250 * @rx_push_rss_config: Write RSS hash key and indirection table to the NIC 1253 1251 * @rx_pull_rss_config: Read RSS hash key and indirection table back from the NIC 1254 1252 * @rx_push_rss_context_config: Write RSS hash key and indirection table for ··· 1261 1257 * @rx_remove: Free resources for RX queue 1262 1258 * @rx_write: Write RX descriptors and doorbell 1263 1259 * @rx_defer_refill: Generate a refill reminder event 1260 + * @rx_packet: Receive the queued RX buffer on a channel 1264 1261 * @ev_probe: Allocate resources for event queue 1265 1262 * @ev_init: Initialise event queue on the NIC 1266 1263 * @ev_fini: Deinitialise event queue on the NIC ··· 1306 1301 * @udp_tnl_push_ports: Push the list of UDP tunnel ports to the NIC if required. 1307 1302 * @udp_tnl_has_port: Check if a port has been added as UDP tunnel 1308 1303 * @print_additional_fwver: Dump NIC-specific additional FW version info 1304 + * @sensor_event: Handle a sensor event from MCDI 1309 1305 * @revision: Hardware architecture revision 1310 1306 * @txd_ptr_tbl_base: TX descriptor ring base address 1311 1307 * @rxd_ptr_tbl_base: RX descriptor ring base address ··· 1387 1381 void (*tx_init)(struct efx_tx_queue *tx_queue); 1388 1382 void (*tx_remove)(struct efx_tx_queue *tx_queue); 1389 1383 void (*tx_write)(struct efx_tx_queue *tx_queue); 1384 + netdev_tx_t (*tx_enqueue)(struct efx_tx_queue *tx_queue, struct sk_buff *skb); 1390 1385 unsigned int (*tx_limit_len)(struct efx_tx_queue *tx_queue, 1391 1386 dma_addr_t dma_addr, unsigned int len); 1392 1387 int (*rx_push_rss_config)(struct efx_nic *efx, bool user, ··· 1405 1398 void (*rx_remove)(struct efx_rx_queue *rx_queue); 1406 1399 void (*rx_write)(struct efx_rx_queue *rx_queue); 1407 1400 void (*rx_defer_refill)(struct efx_rx_queue *rx_queue); 1401 + void (*rx_packet)(struct efx_channel *channel); 1408 1402 int (*ev_probe)(struct efx_channel *channel); 1409 1403 int (*ev_init)(struct efx_channel *channel); 1410 1404 void (*ev_fini)(struct efx_channel *channel); ··· 1480 1472 bool (*udp_tnl_has_port)(struct efx_nic *efx, __be16 port); 1481 1473 size_t (*print_additional_fwver)(struct efx_nic *efx, char *buf, 1482 1474 size_t len); 1475 + void (*sensor_event)(struct efx_nic *efx, efx_qword_t *ev); 1483 1476 1484 1477 int revision; 1485 1478 unsigned int txd_ptr_tbl_base; ··· 1531 1522 _channel; \ 1532 1523 _channel = _channel->channel ? \ 1533 1524 (_efx)->channel[_channel->channel - 1] : NULL) 1525 + 1526 + static inline struct efx_channel * 1527 + efx_get_tx_channel(struct efx_nic *efx, unsigned int index) 1528 + { 1529 + EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels); 1530 + return efx->channel[efx->tx_channel_offset + index]; 1531 + } 1534 1532 1535 1533 static inline struct efx_tx_queue * 1536 1534 efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
+6
drivers/net/ethernet/sfc/nic_common.h
··· 225 225 226 226 bool efx_nic_event_present(struct efx_channel *channel); 227 227 228 + static inline void efx_sensor_event(struct efx_nic *efx, efx_qword_t *ev) 229 + { 230 + if (efx->type->sensor_event) 231 + efx->type->sensor_event(efx, ev); 232 + } 233 + 228 234 /* Some statistics are computed as A - B where A and B each increase 229 235 * linearly with some hardware counter(s) and the counters are read 230 236 * asynchronously. If the counters contributing to B are always read
+3
drivers/net/ethernet/sfc/siena.c
··· 1018 1018 .tx_remove = efx_farch_tx_remove, 1019 1019 .tx_write = efx_farch_tx_write, 1020 1020 .tx_limit_len = efx_farch_tx_limit_len, 1021 + .tx_enqueue = __efx_enqueue_skb, 1021 1022 .rx_push_rss_config = siena_rx_push_rss_config, 1022 1023 .rx_pull_rss_config = siena_rx_pull_rss_config, 1023 1024 .rx_probe = efx_farch_rx_probe, ··· 1026 1025 .rx_remove = efx_farch_rx_remove, 1027 1026 .rx_write = efx_farch_rx_write, 1028 1027 .rx_defer_refill = efx_farch_rx_defer_refill, 1028 + .rx_packet = __efx_rx_packet, 1029 1029 .ev_probe = efx_farch_ev_probe, 1030 1030 .ev_init = efx_farch_ev_init, 1031 1031 .ev_fini = efx_farch_ev_fini, ··· 1098 1096 1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT), 1099 1097 .rx_hash_key_size = 16, 1100 1098 .check_caps = siena_check_caps, 1099 + .sensor_event = efx_mcdi_sensor_event, 1101 1100 };
+2 -2
drivers/net/ethernet/sfc/tx.c
··· 284 284 * Returns NETDEV_TX_OK. 285 285 * You must hold netif_tx_lock() to call this function. 286 286 */ 287 - netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) 287 + netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) 288 288 { 289 289 unsigned int old_insert_count = tx_queue->insert_count; 290 290 bool xmit_more = netdev_xmit_more(); ··· 503 503 } 504 504 tx_queue = efx_get_tx_queue(efx, index, type); 505 505 506 - return efx_enqueue_skb(tx_queue, skb); 506 + return __efx_enqueue_skb(tx_queue, skb); 507 507 } 508 508 509 509 void efx_xmit_done_single(struct efx_tx_queue *tx_queue)
+2
drivers/net/ethernet/sfc/tx_common.h
··· 40 40 41 41 unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); 42 42 int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb); 43 + 44 + extern bool efx_separate_tx_channels; 43 45 #endif