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

sfc: add sysfs entry to control MCDI tracing

MCDI tracing is enabled per-function with a sysfs file
/sys/class/net/<NET_DEV>/device/mcdi_logging

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
e7fef9b4 75aba2a5

+48 -10
+2 -1
drivers/net/ethernet/sfc/Kconfig
··· 43 43 ---help--- 44 44 This enables support for tracing of MCDI (Management-Controller-to- 45 45 Driver-Interface) commands and responses, allowing debugging of 46 - driver/firmware interaction. 46 + driver/firmware interaction. The tracing is actually enabled by 47 + a sysfs file 'mcdi_logging' under the PCI device.
+42 -7
drivers/net/ethernet/sfc/efx.c
··· 2326 2326 } 2327 2327 static DEVICE_ATTR(phy_type, 0444, show_phy_type, NULL); 2328 2328 2329 + #ifdef CONFIG_SFC_MCDI_LOGGING 2330 + static ssize_t show_mcdi_log(struct device *dev, struct device_attribute *attr, 2331 + char *buf) 2332 + { 2333 + struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 2334 + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 2335 + 2336 + return scnprintf(buf, PAGE_SIZE, "%d\n", mcdi->logging_enabled); 2337 + } 2338 + static ssize_t set_mcdi_log(struct device *dev, struct device_attribute *attr, 2339 + const char *buf, size_t count) 2340 + { 2341 + struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 2342 + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 2343 + bool enable = count > 0 && *buf != '0'; 2344 + 2345 + mcdi->logging_enabled = enable; 2346 + return count; 2347 + } 2348 + static DEVICE_ATTR(mcdi_logging, 0644, show_mcdi_log, set_mcdi_log); 2349 + #endif 2350 + 2329 2351 static int efx_register_netdev(struct efx_nic *efx) 2330 2352 { 2331 2353 struct net_device *net_dev = efx->net_dev; ··· 2405 2383 "failed to init net dev attributes\n"); 2406 2384 goto fail_registered; 2407 2385 } 2386 + #ifdef CONFIG_SFC_MCDI_LOGGING 2387 + rc = device_create_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 2388 + if (rc) { 2389 + netif_err(efx, drv, efx->net_dev, 2390 + "failed to init net dev attributes\n"); 2391 + goto fail_attr_mcdi_logging; 2392 + } 2393 + #endif 2408 2394 2409 2395 return 0; 2410 2396 2397 + #ifdef CONFIG_SFC_MCDI_LOGGING 2398 + fail_attr_mcdi_logging: 2399 + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 2400 + #endif 2411 2401 fail_registered: 2412 2402 rtnl_lock(); 2413 2403 efx_dissociate(efx); ··· 2438 2404 2439 2405 BUG_ON(netdev_priv(efx->net_dev) != efx); 2440 2406 2441 - strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); 2442 - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 2443 - 2444 - rtnl_lock(); 2445 - unregister_netdevice(efx->net_dev); 2446 - efx->state = STATE_UNINIT; 2447 - rtnl_unlock(); 2407 + if (efx_dev_registered(efx)) { 2408 + strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); 2409 + #ifdef CONFIG_SFC_MCDI_LOGGING 2410 + device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 2411 + #endif 2412 + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 2413 + unregister_netdev(efx->net_dev); 2414 + } 2448 2415 } 2449 2416 2450 2417 /**************************************************************************
+2 -2
drivers/net/ethernet/sfc/mcdi.c
··· 188 188 } 189 189 190 190 #ifdef CONFIG_SFC_MCDI_LOGGING 191 - if (!WARN_ON_ONCE(!buf)) { 191 + if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { 192 192 int bytes = 0; 193 193 int i; 194 194 /* Lengths should always be a whole number of dwords, so scream ··· 274 274 } 275 275 276 276 #ifdef CONFIG_SFC_MCDI_LOGGING 277 - if (!WARN_ON_ONCE(!buf)) { 277 + if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { 278 278 size_t hdr_len, data_len; 279 279 int bytes = 0; 280 280 int i;
+2
drivers/net/ethernet/sfc/mcdi.h
··· 59 59 * @async_list: Queue of asynchronous requests 60 60 * @async_timer: Timer for asynchronous request timeout 61 61 * @logging_buffer: buffer that may be used to build MCDI tracing messages 62 + * @logging_enabled: whether to trace MCDI 62 63 */ 63 64 struct efx_mcdi_iface { 64 65 struct efx_nic *efx; ··· 78 77 struct timer_list async_timer; 79 78 #ifdef CONFIG_SFC_MCDI_LOGGING 80 79 char *logging_buffer; 80 + bool logging_enabled; 81 81 #endif 82 82 }; 83 83