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

Merge branch 'sfc-more-code-refactoring'

Alex Maftei says:

====================
sfc: more code refactoring

Splitting more of the driver code into different files, which will
later be used in another driver for a new product.

This is a continuation to my previous patch series.
There will be another series and a stand-alone patch as well
after this.

This series in particular covers MCDI (management controller
driver interface) code.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+958 -860
+2 -2
drivers/net/ethernet/sfc/Makefile
··· 3 3 farch.o siena.o ef10.o \ 4 4 tx.o tx_common.o rx.o rx_common.o \ 5 5 selftest.o ethtool.o ptp.o tx_tso.o \ 6 - mcdi.o mcdi_port.o \ 7 - mcdi_mon.o 6 + mcdi.o mcdi_port.o mcdi_port_common.o \ 7 + mcdi_functions.o mcdi_mon.o 8 8 sfc-$(CONFIG_SFC_MTD) += mtd.o 9 9 sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o ef10_sriov.o 10 10
+35 -320
drivers/net/ethernet/sfc/ef10.c
··· 11 11 #include "mcdi.h" 12 12 #include "mcdi_pcol.h" 13 13 #include "mcdi_port_common.h" 14 + #include "mcdi_functions.h" 14 15 #include "nic.h" 15 16 #include "workarounds.h" 16 17 #include "selftest.h" ··· 835 834 return rc; 836 835 } 837 836 838 - static int efx_ef10_free_vis(struct efx_nic *efx) 839 - { 840 - MCDI_DECLARE_BUF_ERR(outbuf); 841 - size_t outlen; 842 - int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0, 843 - outbuf, sizeof(outbuf), &outlen); 844 - 845 - /* -EALREADY means nothing to free, so ignore */ 846 - if (rc == -EALREADY) 847 - rc = 0; 848 - if (rc) 849 - efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen, 850 - rc); 851 - return rc; 852 - } 853 - 854 837 #ifdef EFX_USE_PIO 855 838 856 839 static void efx_ef10_free_piobufs(struct efx_nic *efx) ··· 1077 1092 if (nic_data->wc_membase) 1078 1093 iounmap(nic_data->wc_membase); 1079 1094 1080 - rc = efx_ef10_free_vis(efx); 1095 + rc = efx_mcdi_free_vis(efx); 1081 1096 WARN_ON(rc != 0); 1082 1097 1083 1098 if (!nic_data->must_restore_piobufs) ··· 1248 1263 static int efx_ef10_alloc_vis(struct efx_nic *efx, 1249 1264 unsigned int min_vis, unsigned int max_vis) 1250 1265 { 1251 - MCDI_DECLARE_BUF(inbuf, MC_CMD_ALLOC_VIS_IN_LEN); 1252 - MCDI_DECLARE_BUF(outbuf, MC_CMD_ALLOC_VIS_OUT_LEN); 1253 1266 struct efx_ef10_nic_data *nic_data = efx->nic_data; 1254 - size_t outlen; 1255 - int rc; 1256 1267 1257 - MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MIN_VI_COUNT, min_vis); 1258 - MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MAX_VI_COUNT, max_vis); 1259 - rc = efx_mcdi_rpc(efx, MC_CMD_ALLOC_VIS, inbuf, sizeof(inbuf), 1260 - outbuf, sizeof(outbuf), &outlen); 1261 - if (rc != 0) 1262 - return rc; 1263 - 1264 - if (outlen < MC_CMD_ALLOC_VIS_OUT_LEN) 1265 - return -EIO; 1266 - 1267 - netif_dbg(efx, drv, efx->net_dev, "base VI is A0x%03x\n", 1268 - MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE)); 1269 - 1270 - nic_data->vi_base = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE); 1271 - nic_data->n_allocated_vis = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_COUNT); 1272 - return 0; 1268 + return efx_mcdi_alloc_vis(efx, min_vis, max_vis, &nic_data->vi_base, 1269 + &nic_data->n_allocated_vis); 1273 1270 } 1274 1271 1275 1272 /* Note that the failure path of this function does not free ··· 1333 1366 } 1334 1367 1335 1368 /* In case the last attached driver failed to free VIs, do it now */ 1336 - rc = efx_ef10_free_vis(efx); 1369 + rc = efx_mcdi_free_vis(efx); 1337 1370 if (rc != 0) 1338 1371 return rc; 1339 1372 ··· 1354 1387 efx->max_tx_channels = 1355 1388 nic_data->n_allocated_vis / EFX_TXQ_TYPES; 1356 1389 1357 - efx_ef10_free_vis(efx); 1390 + efx_mcdi_free_vis(efx); 1358 1391 return -EAGAIN; 1359 1392 } 1360 1393 ··· 2378 2411 2379 2412 static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue) 2380 2413 { 2381 - MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / 2382 - EFX_BUF_SIZE)); 2383 2414 bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; 2384 - size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE; 2385 2415 struct efx_channel *channel = tx_queue->channel; 2386 2416 struct efx_nic *efx = tx_queue->efx; 2387 - struct efx_ef10_nic_data *nic_data = efx->nic_data; 2417 + struct efx_ef10_nic_data *nic_data; 2388 2418 bool tso_v2 = false; 2389 - size_t inlen; 2390 - dma_addr_t dma_addr; 2391 2419 efx_qword_t *txd; 2392 2420 int rc; 2393 - int i; 2394 - BUILD_BUG_ON(MC_CMD_INIT_TXQ_OUT_LEN != 0); 2421 + 2422 + nic_data = efx->nic_data; 2395 2423 2396 2424 /* Only attempt to enable TX timestamping if we have the license for it, 2397 2425 * otherwise TXQ init will fail ··· 2413 2451 channel->channel); 2414 2452 } 2415 2453 2416 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1); 2417 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel); 2418 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue); 2419 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue); 2420 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0); 2421 - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, nic_data->vport_id); 2422 - 2423 - dma_addr = tx_queue->txd.buf.dma_addr; 2424 - 2425 - netif_dbg(efx, hw, efx->net_dev, "pushing TXQ %d. %zu entries (%llx)\n", 2426 - tx_queue->queue, entries, (u64)dma_addr); 2427 - 2428 - for (i = 0; i < entries; ++i) { 2429 - MCDI_SET_ARRAY_QWORD(inbuf, INIT_TXQ_IN_DMA_ADDR, i, dma_addr); 2430 - dma_addr += EFX_BUF_SIZE; 2431 - } 2432 - 2433 - inlen = MC_CMD_INIT_TXQ_IN_LEN(entries); 2434 - 2435 - do { 2436 - MCDI_POPULATE_DWORD_4(inbuf, INIT_TXQ_IN_FLAGS, 2437 - /* This flag was removed from mcdi_pcol.h for 2438 - * the non-_EXT version of INIT_TXQ. However, 2439 - * firmware still honours it. 2440 - */ 2441 - INIT_TXQ_EXT_IN_FLAG_TSOV2_EN, tso_v2, 2442 - INIT_TXQ_IN_FLAG_IP_CSUM_DIS, !csum_offload, 2443 - INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, !csum_offload, 2444 - INIT_TXQ_EXT_IN_FLAG_TIMESTAMP, 2445 - tx_queue->timestamping); 2446 - 2447 - rc = efx_mcdi_rpc_quiet(efx, MC_CMD_INIT_TXQ, inbuf, inlen, 2448 - NULL, 0, NULL); 2449 - if (rc == -ENOSPC && tso_v2) { 2450 - /* Retry without TSOv2 if we're short on contexts. */ 2451 - tso_v2 = false; 2452 - netif_warn(efx, probe, efx->net_dev, 2453 - "TSOv2 context not available to segment in hardware. TCP performance may be reduced.\n"); 2454 - } else if (rc) { 2455 - efx_mcdi_display_error(efx, MC_CMD_INIT_TXQ, 2456 - MC_CMD_INIT_TXQ_EXT_IN_LEN, 2457 - NULL, 0, rc); 2458 - goto fail; 2459 - } 2460 - } while (rc); 2454 + rc = efx_mcdi_tx_init(tx_queue, tso_v2); 2455 + if (rc) 2456 + goto fail; 2461 2457 2462 2458 /* A previous user of this TX queue might have set us up the 2463 2459 * bomb by writing a descriptor to the TX push collector but ··· 2451 2531 fail: 2452 2532 netdev_WARN(efx->net_dev, "failed to initialise TXQ %d\n", 2453 2533 tx_queue->queue); 2454 - } 2455 - 2456 - static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) 2457 - { 2458 - MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_TXQ_IN_LEN); 2459 - MCDI_DECLARE_BUF_ERR(outbuf); 2460 - struct efx_nic *efx = tx_queue->efx; 2461 - size_t outlen; 2462 - int rc; 2463 - 2464 - MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE, 2465 - tx_queue->queue); 2466 - 2467 - rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf), 2468 - outbuf, sizeof(outbuf), &outlen); 2469 - 2470 - if (rc && rc != -EALREADY) 2471 - goto fail; 2472 - 2473 - return; 2474 - 2475 - fail: 2476 - efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN, 2477 - outbuf, outlen, rc); 2478 - } 2479 - 2480 - static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue) 2481 - { 2482 - efx_nic_free_buffer(tx_queue->efx, &tx_queue->txd.buf); 2483 2534 } 2484 2535 2485 2536 /* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */ ··· 2967 3076 return efx_ef10_rx_push_shared_rss_config(efx, NULL); 2968 3077 } 2969 3078 2970 - static int efx_ef10_rx_probe(struct efx_rx_queue *rx_queue) 2971 - { 2972 - return efx_nic_alloc_buffer(rx_queue->efx, &rx_queue->rxd.buf, 2973 - (rx_queue->ptr_mask + 1) * 2974 - sizeof(efx_qword_t), 2975 - GFP_KERNEL); 2976 - } 2977 - 2978 - static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue) 2979 - { 2980 - MCDI_DECLARE_BUF(inbuf, 2981 - MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / 2982 - EFX_BUF_SIZE)); 2983 - struct efx_channel *channel = efx_rx_queue_channel(rx_queue); 2984 - size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE; 2985 - struct efx_nic *efx = rx_queue->efx; 2986 - struct efx_ef10_nic_data *nic_data = efx->nic_data; 2987 - size_t inlen; 2988 - dma_addr_t dma_addr; 2989 - int rc; 2990 - int i; 2991 - BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0); 2992 - 2993 - rx_queue->scatter_n = 0; 2994 - rx_queue->scatter_len = 0; 2995 - 2996 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_SIZE, rx_queue->ptr_mask + 1); 2997 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_TARGET_EVQ, channel->channel); 2998 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_LABEL, efx_rx_queue_index(rx_queue)); 2999 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_INSTANCE, 3000 - efx_rx_queue_index(rx_queue)); 3001 - MCDI_POPULATE_DWORD_2(inbuf, INIT_RXQ_IN_FLAGS, 3002 - INIT_RXQ_IN_FLAG_PREFIX, 1, 3003 - INIT_RXQ_IN_FLAG_TIMESTAMP, 1); 3004 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0); 3005 - MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, nic_data->vport_id); 3006 - 3007 - dma_addr = rx_queue->rxd.buf.dma_addr; 3008 - 3009 - netif_dbg(efx, hw, efx->net_dev, "pushing RXQ %d. %zu entries (%llx)\n", 3010 - efx_rx_queue_index(rx_queue), entries, (u64)dma_addr); 3011 - 3012 - for (i = 0; i < entries; ++i) { 3013 - MCDI_SET_ARRAY_QWORD(inbuf, INIT_RXQ_IN_DMA_ADDR, i, dma_addr); 3014 - dma_addr += EFX_BUF_SIZE; 3015 - } 3016 - 3017 - inlen = MC_CMD_INIT_RXQ_IN_LEN(entries); 3018 - 3019 - rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, 3020 - NULL, 0, NULL); 3021 - if (rc) 3022 - netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n", 3023 - efx_rx_queue_index(rx_queue)); 3024 - } 3025 - 3026 - static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) 3027 - { 3028 - MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_RXQ_IN_LEN); 3029 - MCDI_DECLARE_BUF_ERR(outbuf); 3030 - struct efx_nic *efx = rx_queue->efx; 3031 - size_t outlen; 3032 - int rc; 3033 - 3034 - MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE, 3035 - efx_rx_queue_index(rx_queue)); 3036 - 3037 - rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf), 3038 - outbuf, sizeof(outbuf), &outlen); 3039 - 3040 - if (rc && rc != -EALREADY) 3041 - goto fail; 3042 - 3043 - return; 3044 - 3045 - fail: 3046 - efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN, 3047 - outbuf, outlen, rc); 3048 - } 3049 - 3050 - static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue) 3051 - { 3052 - efx_nic_free_buffer(rx_queue->efx, &rx_queue->rxd.buf); 3053 - } 3054 - 3055 3079 /* This creates an entry in the RX descriptor queue */ 3056 3080 static inline void 3057 3081 efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index) ··· 3038 3232 /* nothing to do */ 3039 3233 } 3040 3234 3041 - static int efx_ef10_ev_probe(struct efx_channel *channel) 3042 - { 3043 - return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf, 3044 - (channel->eventq_mask + 1) * 3045 - sizeof(efx_qword_t), 3046 - GFP_KERNEL); 3047 - } 3048 - 3049 - static void efx_ef10_ev_fini(struct efx_channel *channel) 3050 - { 3051 - MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_EVQ_IN_LEN); 3052 - MCDI_DECLARE_BUF_ERR(outbuf); 3053 - struct efx_nic *efx = channel->efx; 3054 - size_t outlen; 3055 - int rc; 3056 - 3057 - MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel); 3058 - 3059 - rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf), 3060 - outbuf, sizeof(outbuf), &outlen); 3061 - 3062 - if (rc && rc != -EALREADY) 3063 - goto fail; 3064 - 3065 - return; 3066 - 3067 - fail: 3068 - efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN, 3069 - outbuf, outlen, rc); 3070 - } 3071 - 3072 3235 static int efx_ef10_ev_init(struct efx_channel *channel) 3073 3236 { 3074 - MCDI_DECLARE_BUF(inbuf, 3075 - MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_MAX_EVQ_SIZE * 8 / 3076 - EFX_BUF_SIZE)); 3077 - MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_EVQ_V2_OUT_LEN); 3078 - size_t entries = channel->eventq.buf.len / EFX_BUF_SIZE; 3079 3237 struct efx_nic *efx = channel->efx; 3080 3238 struct efx_ef10_nic_data *nic_data; 3081 - size_t inlen, outlen; 3082 3239 unsigned int enabled, implemented; 3083 - dma_addr_t dma_addr; 3240 + bool use_v2, cut_thru; 3084 3241 int rc; 3085 - int i; 3086 3242 3087 3243 nic_data = efx->nic_data; 3088 - 3089 - /* Fill event queue with all ones (i.e. empty events) */ 3090 - memset(channel->eventq.buf.addr, 0xff, channel->eventq.buf.len); 3091 - 3092 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_SIZE, channel->eventq_mask + 1); 3093 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_INSTANCE, channel->channel); 3094 - /* INIT_EVQ expects index in vector table, not absolute */ 3095 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_IRQ_NUM, channel->channel); 3096 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_MODE, 3097 - MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS); 3098 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_LOAD, 0); 3099 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_RELOAD, 0); 3100 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_MODE, 3101 - MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS); 3102 - MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_THRSHLD, 0); 3103 - 3104 - if (nic_data->datapath_caps2 & 3105 - 1 << MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_LBN) { 3106 - /* Use the new generic approach to specifying event queue 3107 - * configuration, requesting lower latency or higher throughput. 3108 - * The options that actually get used appear in the output. 3109 - */ 3110 - MCDI_POPULATE_DWORD_2(inbuf, INIT_EVQ_V2_IN_FLAGS, 3111 - INIT_EVQ_V2_IN_FLAG_INTERRUPTING, 1, 3112 - INIT_EVQ_V2_IN_FLAG_TYPE, 3113 - MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO); 3114 - } else { 3115 - bool cut_thru = !(nic_data->datapath_caps & 3116 - 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN); 3117 - 3118 - MCDI_POPULATE_DWORD_4(inbuf, INIT_EVQ_IN_FLAGS, 3119 - INIT_EVQ_IN_FLAG_INTERRUPTING, 1, 3120 - INIT_EVQ_IN_FLAG_RX_MERGE, 1, 3121 - INIT_EVQ_IN_FLAG_TX_MERGE, 1, 3122 - INIT_EVQ_IN_FLAG_CUT_THRU, cut_thru); 3123 - } 3124 - 3125 - dma_addr = channel->eventq.buf.dma_addr; 3126 - for (i = 0; i < entries; ++i) { 3127 - MCDI_SET_ARRAY_QWORD(inbuf, INIT_EVQ_IN_DMA_ADDR, i, dma_addr); 3128 - dma_addr += EFX_BUF_SIZE; 3129 - } 3130 - 3131 - inlen = MC_CMD_INIT_EVQ_IN_LEN(entries); 3132 - 3133 - rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen, 3134 - outbuf, sizeof(outbuf), &outlen); 3135 - 3136 - if (outlen >= MC_CMD_INIT_EVQ_V2_OUT_LEN) 3137 - netif_dbg(efx, drv, efx->net_dev, 3138 - "Channel %d using event queue flags %08x\n", 3139 - channel->channel, 3140 - MCDI_DWORD(outbuf, INIT_EVQ_V2_OUT_FLAGS)); 3244 + use_v2 = nic_data->datapath_caps2 & 3245 + 1 << MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_LBN; 3246 + cut_thru = !(nic_data->datapath_caps & 3247 + 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN); 3248 + rc = efx_mcdi_ev_init(channel, cut_thru, use_v2); 3141 3249 3142 3250 /* IRQ return is ignored */ 3143 3251 if (channel->channel || rc) ··· 3109 3389 return 0; 3110 3390 3111 3391 fail: 3112 - efx_ef10_ev_fini(channel); 3392 + efx_mcdi_ev_fini(channel); 3113 3393 return rc; 3114 - } 3115 - 3116 - static void efx_ef10_ev_remove(struct efx_channel *channel) 3117 - { 3118 - efx_nic_free_buffer(channel->efx, &channel->eventq.buf); 3119 3394 } 3120 3395 3121 3396 static void efx_ef10_handle_rx_wrong_queue(struct efx_rx_queue *rx_queue, ··· 3694 3979 if (efx->state != STATE_RECOVERY) { 3695 3980 efx_for_each_channel(channel, efx) { 3696 3981 efx_for_each_channel_rx_queue(rx_queue, channel) 3697 - efx_ef10_rx_fini(rx_queue); 3982 + efx_mcdi_rx_fini(rx_queue); 3698 3983 efx_for_each_channel_tx_queue(tx_queue, channel) 3699 - efx_ef10_tx_fini(tx_queue); 3984 + efx_mcdi_tx_fini(tx_queue); 3700 3985 } 3701 3986 3702 3987 wait_event_timeout(efx->flush_wq, ··· 6368 6653 .irq_handle_legacy = efx_ef10_legacy_interrupt, 6369 6654 .tx_probe = efx_ef10_tx_probe, 6370 6655 .tx_init = efx_ef10_tx_init, 6371 - .tx_remove = efx_ef10_tx_remove, 6656 + .tx_remove = efx_mcdi_tx_remove, 6372 6657 .tx_write = efx_ef10_tx_write, 6373 6658 .tx_limit_len = efx_ef10_tx_limit_len, 6374 6659 .rx_push_rss_config = efx_ef10_vf_rx_push_rss_config, 6375 6660 .rx_pull_rss_config = efx_ef10_rx_pull_rss_config, 6376 - .rx_probe = efx_ef10_rx_probe, 6377 - .rx_init = efx_ef10_rx_init, 6378 - .rx_remove = efx_ef10_rx_remove, 6661 + .rx_probe = efx_mcdi_rx_probe, 6662 + .rx_init = efx_mcdi_rx_init, 6663 + .rx_remove = efx_mcdi_rx_remove, 6379 6664 .rx_write = efx_ef10_rx_write, 6380 6665 .rx_defer_refill = efx_ef10_rx_defer_refill, 6381 - .ev_probe = efx_ef10_ev_probe, 6666 + .ev_probe = efx_mcdi_ev_probe, 6382 6667 .ev_init = efx_ef10_ev_init, 6383 - .ev_fini = efx_ef10_ev_fini, 6384 - .ev_remove = efx_ef10_ev_remove, 6668 + .ev_fini = efx_mcdi_ev_fini, 6669 + .ev_remove = efx_mcdi_ev_remove, 6385 6670 .ev_process = efx_ef10_ev_process, 6386 6671 .ev_read_ack = efx_ef10_ev_read_ack, 6387 6672 .ev_test_generate = efx_ef10_ev_test_generate, ··· 6477 6762 .irq_handle_legacy = efx_ef10_legacy_interrupt, 6478 6763 .tx_probe = efx_ef10_tx_probe, 6479 6764 .tx_init = efx_ef10_tx_init, 6480 - .tx_remove = efx_ef10_tx_remove, 6765 + .tx_remove = efx_mcdi_tx_remove, 6481 6766 .tx_write = efx_ef10_tx_write, 6482 6767 .tx_limit_len = efx_ef10_tx_limit_len, 6483 6768 .rx_push_rss_config = efx_ef10_pf_rx_push_rss_config, ··· 6485 6770 .rx_push_rss_context_config = efx_ef10_rx_push_rss_context_config, 6486 6771 .rx_pull_rss_context_config = efx_ef10_rx_pull_rss_context_config, 6487 6772 .rx_restore_rss_contexts = efx_ef10_rx_restore_rss_contexts, 6488 - .rx_probe = efx_ef10_rx_probe, 6489 - .rx_init = efx_ef10_rx_init, 6490 - .rx_remove = efx_ef10_rx_remove, 6773 + .rx_probe = efx_mcdi_rx_probe, 6774 + .rx_init = efx_mcdi_rx_init, 6775 + .rx_remove = efx_mcdi_rx_remove, 6491 6776 .rx_write = efx_ef10_rx_write, 6492 6777 .rx_defer_refill = efx_ef10_rx_defer_refill, 6493 - .ev_probe = efx_ef10_ev_probe, 6778 + .ev_probe = efx_mcdi_ev_probe, 6494 6779 .ev_init = efx_ef10_ev_init, 6495 - .ev_fini = efx_ef10_ev_fini, 6496 - .ev_remove = efx_ef10_ev_remove, 6780 + .ev_fini = efx_mcdi_ev_fini, 6781 + .ev_remove = efx_mcdi_ev_remove, 6497 6782 .ev_process = efx_ef10_ev_process, 6498 6783 .ev_read_ack = efx_ef10_ev_read_ack, 6499 6784 .ev_test_generate = efx_ef10_ev_test_generate,
+3 -52
drivers/net/ethernet/sfc/efx.c
··· 134 134 * 135 135 **************************************************************************/ 136 136 137 - void efx_link_set_advertising(struct efx_nic *efx, 138 - const unsigned long *advertising) 139 - { 140 - memcpy(efx->link_advertising, advertising, 141 - sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK())); 142 - 143 - efx->link_advertising[0] |= ADVERTISED_Autoneg; 144 - if (advertising[0] & ADVERTISED_Pause) 145 - efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX); 146 - else 147 - efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX); 148 - if (advertising[0] & ADVERTISED_Asym_Pause) 149 - efx->wanted_fc ^= EFX_FC_TX; 150 - } 151 - 152 137 /* Equivalent to efx_link_set_advertising with all-zeroes, except does not 153 138 * force the Autoneg bit on. 154 139 */ ··· 1036 1051 } 1037 1052 static DEVICE_ATTR(phy_type, 0444, show_phy_type, NULL); 1038 1053 1039 - #ifdef CONFIG_SFC_MCDI_LOGGING 1040 - static ssize_t show_mcdi_log(struct device *dev, struct device_attribute *attr, 1041 - char *buf) 1042 - { 1043 - struct efx_nic *efx = dev_get_drvdata(dev); 1044 - struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 1045 - 1046 - return scnprintf(buf, PAGE_SIZE, "%d\n", mcdi->logging_enabled); 1047 - } 1048 - static ssize_t set_mcdi_log(struct device *dev, struct device_attribute *attr, 1049 - const char *buf, size_t count) 1050 - { 1051 - struct efx_nic *efx = dev_get_drvdata(dev); 1052 - struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 1053 - bool enable = count > 0 && *buf != '0'; 1054 - 1055 - mcdi->logging_enabled = enable; 1056 - return count; 1057 - } 1058 - static DEVICE_ATTR(mcdi_logging, 0644, show_mcdi_log, set_mcdi_log); 1059 - #endif 1060 - 1061 1054 static int efx_register_netdev(struct efx_nic *efx) 1062 1055 { 1063 1056 struct net_device *net_dev = efx->net_dev; ··· 1095 1132 "failed to init net dev attributes\n"); 1096 1133 goto fail_registered; 1097 1134 } 1098 - #ifdef CONFIG_SFC_MCDI_LOGGING 1099 - rc = device_create_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 1100 - if (rc) { 1101 - netif_err(efx, drv, efx->net_dev, 1102 - "failed to init net dev attributes\n"); 1103 - goto fail_attr_mcdi_logging; 1104 - } 1105 - #endif 1135 + 1136 + efx_init_mcdi_logging(efx); 1106 1137 1107 1138 return 0; 1108 1139 1109 - #ifdef CONFIG_SFC_MCDI_LOGGING 1110 - fail_attr_mcdi_logging: 1111 - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 1112 - #endif 1113 1140 fail_registered: 1114 1141 rtnl_lock(); 1115 1142 efx_dissociate(efx); ··· 1120 1167 1121 1168 if (efx_dev_registered(efx)) { 1122 1169 strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); 1123 - #ifdef CONFIG_SFC_MCDI_LOGGING 1124 - device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 1125 - #endif 1170 + efx_fini_mcdi_logging(efx); 1126 1171 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 1127 1172 unregister_netdev(efx->net_dev); 1128 1173 }
+4 -2
drivers/net/ethernet/sfc/efx_channels.c
··· 1039 1039 struct efx_tx_queue *tx_queue; 1040 1040 struct efx_rx_queue *rx_queue; 1041 1041 struct efx_channel *channel; 1042 - int rc; 1042 + int rc = 0; 1043 1043 1044 1044 /* Stop RX refill */ 1045 1045 efx_for_each_channel(channel, efx) { ··· 1060 1060 } 1061 1061 } 1062 1062 1063 - rc = efx->type->fini_dmaq(efx); 1063 + if (efx->type->fini_dmaq) 1064 + rc = efx->type->fini_dmaq(efx); 1065 + 1064 1066 if (rc) { 1065 1067 netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); 1066 1068 } else {
+67 -19
drivers/net/ethernet/sfc/efx_common.c
··· 141 141 */ 142 142 void efx_mac_reconfigure(struct efx_nic *efx) 143 143 { 144 - down_read(&efx->filter_sem); 145 - efx->type->reconfigure_mac(efx); 146 - up_read(&efx->filter_sem); 144 + if (efx->type->reconfigure_mac) { 145 + down_read(&efx->filter_sem); 146 + efx->type->reconfigure_mac(efx); 147 + up_read(&efx->filter_sem); 148 + } 147 149 } 148 150 149 151 /* Asynchronous work item for changing MAC promiscuity and multicast ··· 298 296 netdev_features_change(efx->net_dev); 299 297 300 298 /* RX filters may also have scatter-enabled flags */ 301 - if (efx->rx_scatter != old_rx_scatter) 299 + if ((efx->rx_scatter != old_rx_scatter) && 300 + efx->type->filter_update_rx_scatter) 302 301 efx->type->filter_update_rx_scatter(efx); 303 302 304 303 /* We must keep at least one descriptor in a TX ring empty. ··· 408 405 efx_link_status_changed(efx); 409 406 mutex_unlock(&efx->mac_lock); 410 407 411 - efx->type->start_stats(efx); 412 - efx->type->pull_stats(efx); 413 - spin_lock_bh(&efx->stats_lock); 414 - efx->type->update_stats(efx, NULL, NULL); 415 - spin_unlock_bh(&efx->stats_lock); 408 + if (efx->type->start_stats) { 409 + efx->type->start_stats(efx); 410 + efx->type->pull_stats(efx); 411 + spin_lock_bh(&efx->stats_lock); 412 + efx->type->update_stats(efx, NULL, NULL); 413 + spin_unlock_bh(&efx->stats_lock); 414 + } 416 415 } 417 416 418 417 /* Quiesce the hardware and software data path, and regular activity ··· 430 425 if (!efx->port_enabled) 431 426 return; 432 427 433 - /* update stats before we go down so we can accurately count 434 - * rx_nodesc_drops 435 - */ 436 - efx->type->pull_stats(efx); 437 - spin_lock_bh(&efx->stats_lock); 438 - efx->type->update_stats(efx, NULL, NULL); 439 - spin_unlock_bh(&efx->stats_lock); 440 - efx->type->stop_stats(efx); 428 + if (efx->type->update_stats) { 429 + /* update stats before we go down so we can accurately count 430 + * rx_nodesc_drops 431 + */ 432 + efx->type->pull_stats(efx); 433 + spin_lock_bh(&efx->stats_lock); 434 + efx->type->update_stats(efx, NULL, NULL); 435 + spin_unlock_bh(&efx->stats_lock); 436 + efx->type->stop_stats(efx); 437 + } 438 + 441 439 efx_stop_port(efx); 442 440 443 441 /* Stop the kernel transmit interface. This is only valid if ··· 464 456 int __efx_reconfigure_port(struct efx_nic *efx) 465 457 { 466 458 enum efx_phy_mode phy_mode; 467 - int rc; 459 + int rc = 0; 468 460 469 461 WARN_ON(!mutex_is_locked(&efx->mac_lock)); 470 462 ··· 475 467 else 476 468 efx->phy_mode &= ~PHY_MODE_TX_DISABLED; 477 469 478 - rc = efx->type->reconfigure_port(efx); 470 + if (efx->type->reconfigure_port) 471 + rc = efx->type->reconfigure_port(efx); 479 472 480 473 if (rc) 481 474 efx->phy_mode = phy_mode; ··· 1006 997 if (!pci_vfs_assigned(efx->pci_dev)) 1007 998 pci_disable_device(efx->pci_dev); 1008 999 } 1000 + 1001 + #ifdef CONFIG_SFC_MCDI_LOGGING 1002 + static ssize_t show_mcdi_log(struct device *dev, struct device_attribute *attr, 1003 + char *buf) 1004 + { 1005 + struct efx_nic *efx = dev_get_drvdata(dev); 1006 + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 1007 + 1008 + return scnprintf(buf, PAGE_SIZE, "%d\n", mcdi->logging_enabled); 1009 + } 1010 + 1011 + static ssize_t set_mcdi_log(struct device *dev, struct device_attribute *attr, 1012 + const char *buf, size_t count) 1013 + { 1014 + struct efx_nic *efx = dev_get_drvdata(dev); 1015 + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); 1016 + bool enable = count > 0 && *buf != '0'; 1017 + 1018 + mcdi->logging_enabled = enable; 1019 + return count; 1020 + } 1021 + 1022 + static DEVICE_ATTR(mcdi_logging, 0644, show_mcdi_log, set_mcdi_log); 1023 + 1024 + void efx_init_mcdi_logging(struct efx_nic *efx) 1025 + { 1026 + int rc = device_create_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 1027 + 1028 + if (rc) { 1029 + netif_warn(efx, drv, efx->net_dev, 1030 + "failed to init net dev attributes\n"); 1031 + } 1032 + } 1033 + 1034 + void efx_fini_mcdi_logging(struct efx_nic *efx) 1035 + { 1036 + device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging); 1037 + } 1038 + #endif
+8
drivers/net/ethernet/sfc/efx_common.h
··· 55 55 return 0; 56 56 } 57 57 58 + #ifdef CONFIG_SFC_MCDI_LOGGING 59 + void efx_init_mcdi_logging(struct efx_nic *efx); 60 + void efx_fini_mcdi_logging(struct efx_nic *efx); 61 + #else 62 + static inline void efx_init_mcdi_logging(struct efx_nic *efx) {} 63 + static inline void efx_fini_mcdi_logging(struct efx_nic *efx) {} 64 + #endif 65 + 58 66 void efx_mac_reconfigure(struct efx_nic *efx); 59 67 void efx_link_status_changed(struct efx_nic *efx); 60 68
+349
drivers/net/ethernet/sfc/mcdi_functions.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 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 "efx.h" 13 + #include "nic.h" 14 + #include "mcdi_functions.h" 15 + #include "mcdi.h" 16 + #include "mcdi_pcol.h" 17 + 18 + int efx_mcdi_free_vis(struct efx_nic *efx) 19 + { 20 + MCDI_DECLARE_BUF_ERR(outbuf); 21 + size_t outlen; 22 + int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0, 23 + outbuf, sizeof(outbuf), &outlen); 24 + 25 + /* -EALREADY means nothing to free, so ignore */ 26 + if (rc == -EALREADY) 27 + rc = 0; 28 + if (rc) 29 + efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen, 30 + rc); 31 + return rc; 32 + } 33 + 34 + int efx_mcdi_alloc_vis(struct efx_nic *efx, unsigned int min_vis, 35 + unsigned int max_vis, unsigned int *vi_base, 36 + unsigned int *allocated_vis) 37 + { 38 + MCDI_DECLARE_BUF(outbuf, MC_CMD_ALLOC_VIS_OUT_LEN); 39 + MCDI_DECLARE_BUF(inbuf, MC_CMD_ALLOC_VIS_IN_LEN); 40 + size_t outlen; 41 + int rc; 42 + 43 + MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MIN_VI_COUNT, min_vis); 44 + MCDI_SET_DWORD(inbuf, ALLOC_VIS_IN_MAX_VI_COUNT, max_vis); 45 + rc = efx_mcdi_rpc(efx, MC_CMD_ALLOC_VIS, inbuf, sizeof(inbuf), 46 + outbuf, sizeof(outbuf), &outlen); 47 + if (rc != 0) 48 + return rc; 49 + 50 + if (outlen < MC_CMD_ALLOC_VIS_OUT_LEN) 51 + return -EIO; 52 + 53 + netif_dbg(efx, drv, efx->net_dev, "base VI is A0x%03x\n", 54 + MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE)); 55 + 56 + if (vi_base) 57 + *vi_base = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_BASE); 58 + if (allocated_vis) 59 + *allocated_vis = MCDI_DWORD(outbuf, ALLOC_VIS_OUT_VI_COUNT); 60 + return 0; 61 + } 62 + 63 + int efx_mcdi_ev_probe(struct efx_channel *channel) 64 + { 65 + return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf, 66 + (channel->eventq_mask + 1) * 67 + sizeof(efx_qword_t), 68 + GFP_KERNEL); 69 + } 70 + 71 + int efx_mcdi_ev_init(struct efx_channel *channel, bool v1_cut_thru, bool v2) 72 + { 73 + MCDI_DECLARE_BUF(inbuf, 74 + MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_MAX_EVQ_SIZE * 8 / 75 + EFX_BUF_SIZE)); 76 + MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_EVQ_V2_OUT_LEN); 77 + size_t entries = channel->eventq.buf.len / EFX_BUF_SIZE; 78 + struct efx_nic *efx = channel->efx; 79 + struct efx_ef10_nic_data *nic_data; 80 + size_t inlen, outlen; 81 + dma_addr_t dma_addr; 82 + int rc, i; 83 + 84 + nic_data = efx->nic_data; 85 + 86 + /* Fill event queue with all ones (i.e. empty events) */ 87 + memset(channel->eventq.buf.addr, 0xff, channel->eventq.buf.len); 88 + 89 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_SIZE, channel->eventq_mask + 1); 90 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_INSTANCE, channel->channel); 91 + /* INIT_EVQ expects index in vector table, not absolute */ 92 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_IRQ_NUM, channel->channel); 93 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_MODE, 94 + MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS); 95 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_LOAD, 0); 96 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_TMR_RELOAD, 0); 97 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_MODE, 98 + MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS); 99 + MCDI_SET_DWORD(inbuf, INIT_EVQ_IN_COUNT_THRSHLD, 0); 100 + 101 + if (v2) { 102 + /* Use the new generic approach to specifying event queue 103 + * configuration, requesting lower latency or higher throughput. 104 + * The options that actually get used appear in the output. 105 + */ 106 + MCDI_POPULATE_DWORD_2(inbuf, INIT_EVQ_V2_IN_FLAGS, 107 + INIT_EVQ_V2_IN_FLAG_INTERRUPTING, 1, 108 + INIT_EVQ_V2_IN_FLAG_TYPE, 109 + MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO); 110 + } else { 111 + MCDI_POPULATE_DWORD_4(inbuf, INIT_EVQ_IN_FLAGS, 112 + INIT_EVQ_IN_FLAG_INTERRUPTING, 1, 113 + INIT_EVQ_IN_FLAG_RX_MERGE, 1, 114 + INIT_EVQ_IN_FLAG_TX_MERGE, 1, 115 + INIT_EVQ_IN_FLAG_CUT_THRU, v1_cut_thru); 116 + } 117 + 118 + dma_addr = channel->eventq.buf.dma_addr; 119 + for (i = 0; i < entries; ++i) { 120 + MCDI_SET_ARRAY_QWORD(inbuf, INIT_EVQ_IN_DMA_ADDR, i, dma_addr); 121 + dma_addr += EFX_BUF_SIZE; 122 + } 123 + 124 + inlen = MC_CMD_INIT_EVQ_IN_LEN(entries); 125 + 126 + rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen, 127 + outbuf, sizeof(outbuf), &outlen); 128 + 129 + if (outlen >= MC_CMD_INIT_EVQ_V2_OUT_LEN) 130 + netif_dbg(efx, drv, efx->net_dev, 131 + "Channel %d using event queue flags %08x\n", 132 + channel->channel, 133 + MCDI_DWORD(outbuf, INIT_EVQ_V2_OUT_FLAGS)); 134 + 135 + return rc; 136 + } 137 + 138 + void efx_mcdi_ev_remove(struct efx_channel *channel) 139 + { 140 + efx_nic_free_buffer(channel->efx, &channel->eventq.buf); 141 + } 142 + 143 + void efx_mcdi_ev_fini(struct efx_channel *channel) 144 + { 145 + MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_EVQ_IN_LEN); 146 + MCDI_DECLARE_BUF_ERR(outbuf); 147 + struct efx_nic *efx = channel->efx; 148 + size_t outlen; 149 + int rc; 150 + 151 + MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel); 152 + 153 + rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf), 154 + outbuf, sizeof(outbuf), &outlen); 155 + 156 + if (rc && rc != -EALREADY) 157 + goto fail; 158 + 159 + return; 160 + 161 + fail: 162 + efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN, 163 + outbuf, outlen, rc); 164 + } 165 + 166 + int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2) 167 + { 168 + MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / 169 + EFX_BUF_SIZE)); 170 + bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; 171 + size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE; 172 + struct efx_channel *channel = tx_queue->channel; 173 + struct efx_nic *efx = tx_queue->efx; 174 + struct efx_ef10_nic_data *nic_data; 175 + dma_addr_t dma_addr; 176 + size_t inlen; 177 + int rc, i; 178 + 179 + BUILD_BUG_ON(MC_CMD_INIT_TXQ_OUT_LEN != 0); 180 + 181 + nic_data = efx->nic_data; 182 + 183 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1); 184 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel); 185 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue); 186 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue); 187 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0); 188 + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, nic_data->vport_id); 189 + 190 + dma_addr = tx_queue->txd.buf.dma_addr; 191 + 192 + netif_dbg(efx, hw, efx->net_dev, "pushing TXQ %d. %zu entries (%llx)\n", 193 + tx_queue->queue, entries, (u64)dma_addr); 194 + 195 + for (i = 0; i < entries; ++i) { 196 + MCDI_SET_ARRAY_QWORD(inbuf, INIT_TXQ_IN_DMA_ADDR, i, dma_addr); 197 + dma_addr += EFX_BUF_SIZE; 198 + } 199 + 200 + inlen = MC_CMD_INIT_TXQ_IN_LEN(entries); 201 + 202 + do { 203 + MCDI_POPULATE_DWORD_4(inbuf, INIT_TXQ_IN_FLAGS, 204 + /* This flag was removed from mcdi_pcol.h for 205 + * the non-_EXT version of INIT_TXQ. However, 206 + * firmware still honours it. 207 + */ 208 + INIT_TXQ_EXT_IN_FLAG_TSOV2_EN, tso_v2, 209 + INIT_TXQ_IN_FLAG_IP_CSUM_DIS, !csum_offload, 210 + INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, !csum_offload, 211 + INIT_TXQ_EXT_IN_FLAG_TIMESTAMP, 212 + tx_queue->timestamping); 213 + 214 + rc = efx_mcdi_rpc_quiet(efx, MC_CMD_INIT_TXQ, inbuf, inlen, 215 + NULL, 0, NULL); 216 + if (rc == -ENOSPC && tso_v2) { 217 + /* Retry without TSOv2 if we're short on contexts. */ 218 + tso_v2 = false; 219 + netif_warn(efx, probe, efx->net_dev, 220 + "TSOv2 context not available to segment in " 221 + "hardware. TCP performance may be reduced.\n" 222 + ); 223 + } else if (rc) { 224 + efx_mcdi_display_error(efx, MC_CMD_INIT_TXQ, 225 + MC_CMD_INIT_TXQ_EXT_IN_LEN, 226 + NULL, 0, rc); 227 + goto fail; 228 + } 229 + } while (rc); 230 + 231 + return 0; 232 + 233 + fail: 234 + return rc; 235 + } 236 + 237 + void efx_mcdi_tx_remove(struct efx_tx_queue *tx_queue) 238 + { 239 + efx_nic_free_buffer(tx_queue->efx, &tx_queue->txd.buf); 240 + } 241 + 242 + void efx_mcdi_tx_fini(struct efx_tx_queue *tx_queue) 243 + { 244 + MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_TXQ_IN_LEN); 245 + MCDI_DECLARE_BUF_ERR(outbuf); 246 + struct efx_nic *efx = tx_queue->efx; 247 + size_t outlen; 248 + int rc; 249 + 250 + MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE, 251 + tx_queue->queue); 252 + 253 + rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf), 254 + outbuf, sizeof(outbuf), &outlen); 255 + 256 + if (rc && rc != -EALREADY) 257 + goto fail; 258 + 259 + return; 260 + 261 + fail: 262 + efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN, 263 + outbuf, outlen, rc); 264 + } 265 + 266 + int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue) 267 + { 268 + return efx_nic_alloc_buffer(rx_queue->efx, &rx_queue->rxd.buf, 269 + (rx_queue->ptr_mask + 1) * 270 + sizeof(efx_qword_t), 271 + GFP_KERNEL); 272 + } 273 + 274 + void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue) 275 + { 276 + MCDI_DECLARE_BUF(inbuf, 277 + MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / 278 + EFX_BUF_SIZE)); 279 + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); 280 + size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE; 281 + struct efx_nic *efx = rx_queue->efx; 282 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 283 + dma_addr_t dma_addr; 284 + size_t inlen; 285 + int rc; 286 + int i; 287 + BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0); 288 + 289 + rx_queue->scatter_n = 0; 290 + rx_queue->scatter_len = 0; 291 + 292 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_SIZE, rx_queue->ptr_mask + 1); 293 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_TARGET_EVQ, channel->channel); 294 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_LABEL, efx_rx_queue_index(rx_queue)); 295 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_INSTANCE, 296 + efx_rx_queue_index(rx_queue)); 297 + MCDI_POPULATE_DWORD_2(inbuf, INIT_RXQ_IN_FLAGS, 298 + INIT_RXQ_IN_FLAG_PREFIX, 1, 299 + INIT_RXQ_IN_FLAG_TIMESTAMP, 1); 300 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0); 301 + MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, nic_data->vport_id); 302 + 303 + dma_addr = rx_queue->rxd.buf.dma_addr; 304 + 305 + netif_dbg(efx, hw, efx->net_dev, "pushing RXQ %d. %zu entries (%llx)\n", 306 + efx_rx_queue_index(rx_queue), entries, (u64)dma_addr); 307 + 308 + for (i = 0; i < entries; ++i) { 309 + MCDI_SET_ARRAY_QWORD(inbuf, INIT_RXQ_IN_DMA_ADDR, i, dma_addr); 310 + dma_addr += EFX_BUF_SIZE; 311 + } 312 + 313 + inlen = MC_CMD_INIT_RXQ_IN_LEN(entries); 314 + 315 + rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, 316 + NULL, 0, NULL); 317 + if (rc) 318 + netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n", 319 + efx_rx_queue_index(rx_queue)); 320 + } 321 + 322 + void efx_mcdi_rx_remove(struct efx_rx_queue *rx_queue) 323 + { 324 + efx_nic_free_buffer(rx_queue->efx, &rx_queue->rxd.buf); 325 + } 326 + 327 + void efx_mcdi_rx_fini(struct efx_rx_queue *rx_queue) 328 + { 329 + MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_RXQ_IN_LEN); 330 + MCDI_DECLARE_BUF_ERR(outbuf); 331 + struct efx_nic *efx = rx_queue->efx; 332 + size_t outlen; 333 + int rc; 334 + 335 + MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE, 336 + efx_rx_queue_index(rx_queue)); 337 + 338 + rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf), 339 + outbuf, sizeof(outbuf), &outlen); 340 + 341 + if (rc && rc != -EALREADY) 342 + goto fail; 343 + 344 + return; 345 + 346 + fail: 347 + efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN, 348 + outbuf, outlen, rc); 349 + }
+1 -1
drivers/net/ethernet/sfc/mcdi_functions.h
··· 23 23 void efx_mcdi_tx_remove(struct efx_tx_queue *tx_queue); 24 24 void efx_mcdi_tx_fini(struct efx_tx_queue *tx_queue); 25 25 int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue); 26 - int efx_mcdi_rx_init(struct efx_rx_queue *rx_queue, bool want_outer_classes); 26 + void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue); 27 27 void efx_mcdi_rx_remove(struct efx_rx_queue *rx_queue); 28 28 void efx_mcdi_rx_fini(struct efx_rx_queue *rx_queue); 29 29
-464
drivers/net/ethernet/sfc/mcdi_port.c
··· 16 16 #include "selftest.h" 17 17 #include "mcdi_port_common.h" 18 18 19 - int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg) 20 - { 21 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN); 22 - size_t outlen; 23 - int rc; 24 - 25 - BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0); 26 - BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name)); 27 - 28 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0, 29 - outbuf, sizeof(outbuf), &outlen); 30 - if (rc) 31 - goto fail; 32 - 33 - if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) { 34 - rc = -EIO; 35 - goto fail; 36 - } 37 - 38 - cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS); 39 - cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE); 40 - cfg->supported_cap = 41 - MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP); 42 - cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL); 43 - cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT); 44 - cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK); 45 - memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME), 46 - sizeof(cfg->name)); 47 - cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE); 48 - cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK); 49 - memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION), 50 - sizeof(cfg->revision)); 51 - 52 - return 0; 53 - 54 - fail: 55 - netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); 56 - return rc; 57 - } 58 - 59 - int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities, 60 - u32 flags, u32 loopback_mode, 61 - u32 loopback_speed) 62 - { 63 - MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN); 64 - int rc; 65 - 66 - BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0); 67 - 68 - MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities); 69 - MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags); 70 - MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode); 71 - MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed); 72 - 73 - rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf), 74 - NULL, 0, NULL); 75 - return rc; 76 - } 77 - 78 - int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes) 79 - { 80 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN); 81 - size_t outlen; 82 - int rc; 83 - 84 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0, 85 - outbuf, sizeof(outbuf), &outlen); 86 - if (rc) 87 - goto fail; 88 - 89 - if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST + 90 - MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) { 91 - rc = -EIO; 92 - goto fail; 93 - } 94 - 95 - *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED); 96 - 97 - return 0; 98 - 99 - fail: 100 - netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); 101 - return rc; 102 - } 103 - 104 19 static int efx_mcdi_mdio_read(struct net_device *net_dev, 105 20 int prtad, int devad, u16 addr) 106 21 { ··· 67 152 return -EIO; 68 153 69 154 return 0; 70 - } 71 - 72 - void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset) 73 - { 74 - #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \ 75 - linkset) 76 - 77 - bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS); 78 - switch (media) { 79 - case MC_CMD_MEDIA_KX4: 80 - SET_BIT(Backplane); 81 - if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 82 - SET_BIT(1000baseKX_Full); 83 - if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 84 - SET_BIT(10000baseKX4_Full); 85 - if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 86 - SET_BIT(40000baseKR4_Full); 87 - break; 88 - 89 - case MC_CMD_MEDIA_XFP: 90 - case MC_CMD_MEDIA_SFP_PLUS: 91 - case MC_CMD_MEDIA_QSFP_PLUS: 92 - SET_BIT(FIBRE); 93 - if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 94 - SET_BIT(1000baseT_Full); 95 - if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 96 - SET_BIT(10000baseT_Full); 97 - if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 98 - SET_BIT(40000baseCR4_Full); 99 - if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN)) 100 - SET_BIT(100000baseCR4_Full); 101 - if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN)) 102 - SET_BIT(25000baseCR_Full); 103 - if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN)) 104 - SET_BIT(50000baseCR2_Full); 105 - break; 106 - 107 - case MC_CMD_MEDIA_BASE_T: 108 - SET_BIT(TP); 109 - if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) 110 - SET_BIT(10baseT_Half); 111 - if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) 112 - SET_BIT(10baseT_Full); 113 - if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) 114 - SET_BIT(100baseT_Half); 115 - if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) 116 - SET_BIT(100baseT_Full); 117 - if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) 118 - SET_BIT(1000baseT_Half); 119 - if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 120 - SET_BIT(1000baseT_Full); 121 - if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 122 - SET_BIT(10000baseT_Full); 123 - break; 124 - } 125 - 126 - if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) 127 - SET_BIT(Pause); 128 - if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) 129 - SET_BIT(Asym_Pause); 130 - if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 131 - SET_BIT(Autoneg); 132 - 133 - #undef SET_BIT 134 - } 135 - 136 - u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset) 137 - { 138 - u32 result = 0; 139 - 140 - #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \ 141 - linkset) 142 - 143 - if (TEST_BIT(10baseT_Half)) 144 - result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN); 145 - if (TEST_BIT(10baseT_Full)) 146 - result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN); 147 - if (TEST_BIT(100baseT_Half)) 148 - result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN); 149 - if (TEST_BIT(100baseT_Full)) 150 - result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN); 151 - if (TEST_BIT(1000baseT_Half)) 152 - result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN); 153 - if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full)) 154 - result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN); 155 - if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full)) 156 - result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN); 157 - if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full)) 158 - result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN); 159 - if (TEST_BIT(100000baseCR4_Full)) 160 - result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN); 161 - if (TEST_BIT(25000baseCR_Full)) 162 - result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN); 163 - if (TEST_BIT(50000baseCR2_Full)) 164 - result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN); 165 - if (TEST_BIT(Pause)) 166 - result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN); 167 - if (TEST_BIT(Asym_Pause)) 168 - result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN); 169 - if (TEST_BIT(Autoneg)) 170 - result |= (1 << MC_CMD_PHY_CAP_AN_LBN); 171 - 172 - #undef TEST_BIT 173 - 174 - return result; 175 - } 176 - 177 - u32 efx_get_mcdi_phy_flags(struct efx_nic *efx) 178 - { 179 - struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 180 - enum efx_phy_mode mode, supported; 181 - u32 flags; 182 - 183 - /* TODO: Advertise the capabilities supported by this PHY */ 184 - supported = 0; 185 - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN)) 186 - supported |= PHY_MODE_TX_DISABLED; 187 - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN)) 188 - supported |= PHY_MODE_LOW_POWER; 189 - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN)) 190 - supported |= PHY_MODE_OFF; 191 - 192 - mode = efx->phy_mode & supported; 193 - 194 - flags = 0; 195 - if (mode & PHY_MODE_TX_DISABLED) 196 - flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN); 197 - if (mode & PHY_MODE_LOW_POWER) 198 - flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN); 199 - if (mode & PHY_MODE_OFF) 200 - flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN); 201 - 202 - return flags; 203 - } 204 - 205 - u8 mcdi_to_ethtool_media(u32 media) 206 - { 207 - switch (media) { 208 - case MC_CMD_MEDIA_XAUI: 209 - case MC_CMD_MEDIA_CX4: 210 - case MC_CMD_MEDIA_KX4: 211 - return PORT_OTHER; 212 - 213 - case MC_CMD_MEDIA_XFP: 214 - case MC_CMD_MEDIA_SFP_PLUS: 215 - case MC_CMD_MEDIA_QSFP_PLUS: 216 - return PORT_FIBRE; 217 - 218 - case MC_CMD_MEDIA_BASE_T: 219 - return PORT_TP; 220 - 221 - default: 222 - return PORT_OTHER; 223 - } 224 - } 225 - 226 - void efx_mcdi_phy_decode_link(struct efx_nic *efx, 227 - struct efx_link_state *link_state, 228 - u32 speed, u32 flags, u32 fcntl) 229 - { 230 - switch (fcntl) { 231 - case MC_CMD_FCNTL_AUTO: 232 - WARN_ON(1); /* This is not a link mode */ 233 - link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX; 234 - break; 235 - case MC_CMD_FCNTL_BIDIR: 236 - link_state->fc = EFX_FC_TX | EFX_FC_RX; 237 - break; 238 - case MC_CMD_FCNTL_RESPOND: 239 - link_state->fc = EFX_FC_RX; 240 - break; 241 - default: 242 - WARN_ON(1); 243 - /* Fall through */ 244 - case MC_CMD_FCNTL_OFF: 245 - link_state->fc = 0; 246 - break; 247 - } 248 - 249 - link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); 250 - link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); 251 - link_state->speed = speed; 252 - } 253 - 254 - /* The semantics of the ethtool FEC mode bitmask are not well defined, 255 - * particularly the meaning of combinations of bits. Which means we get to 256 - * define our own semantics, as follows: 257 - * OFF overrides any other bits, and means "disable all FEC" (with the 258 - * exception of 25G KR4/CR4, where it is not possible to reject it if AN 259 - * partner requests it). 260 - * AUTO on its own means use cable requirements and link partner autoneg with 261 - * fw-default preferences for the cable type. 262 - * AUTO and either RS or BASER means use the specified FEC type if cable and 263 - * link partner support it, otherwise autoneg/fw-default. 264 - * RS or BASER alone means use the specified FEC type if cable and link partner 265 - * support it and either requests it, otherwise no FEC. 266 - * Both RS and BASER (whether AUTO or not) means use FEC if cable and link 267 - * partner support it, preferring RS to BASER. 268 - */ 269 - u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap) 270 - { 271 - u32 ret = 0; 272 - 273 - if (ethtool_cap & ETHTOOL_FEC_OFF) 274 - return 0; 275 - 276 - if (ethtool_cap & ETHTOOL_FEC_AUTO) 277 - ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) | 278 - (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) | 279 - (1 << MC_CMD_PHY_CAP_RS_FEC_LBN); 280 - if (ethtool_cap & ETHTOOL_FEC_RS) 281 - ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) | 282 - (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN); 283 - if (ethtool_cap & ETHTOOL_FEC_BASER) 284 - ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) | 285 - (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) | 286 - (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) | 287 - (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN); 288 - return ret; 289 - } 290 - 291 - /* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function 292 - * can never produce, (baser xor rs) and neither req; the implementation below 293 - * maps both of those to AUTO. This should never matter, and it's not clear 294 - * what a better mapping would be anyway. 295 - */ 296 - u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g) 297 - { 298 - bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN), 299 - rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN), 300 - baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) 301 - : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN), 302 - baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN) 303 - : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN); 304 - 305 - if (!baser && !rs) 306 - return ETHTOOL_FEC_OFF; 307 - return (rs_req ? ETHTOOL_FEC_RS : 0) | 308 - (baser_req ? ETHTOOL_FEC_BASER : 0) | 309 - (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO); 310 155 } 311 156 312 157 static int efx_mcdi_phy_probe(struct efx_nic *efx) ··· 188 513 efx->loopback_mode, 0); 189 514 } 190 515 191 - /* Verify that the forced flow control settings (!EFX_FC_AUTO) are 192 - * supported by the link partner. Warn the user if this isn't the case 193 - */ 194 - void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa) 195 - { 196 - struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 197 - u32 rmtadv; 198 - 199 - /* The link partner capabilities are only relevant if the 200 - * link supports flow control autonegotiation */ 201 - if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 202 - return; 203 - 204 - /* If flow control autoneg is supported and enabled, then fine */ 205 - if (efx->wanted_fc & EFX_FC_AUTO) 206 - return; 207 - 208 - rmtadv = 0; 209 - if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) 210 - rmtadv |= ADVERTISED_Pause; 211 - if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) 212 - rmtadv |= ADVERTISED_Asym_Pause; 213 - 214 - if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause) 215 - netif_err(efx, link, efx->net_dev, 216 - "warning: link partner doesn't support pause frames"); 217 - } 218 - 219 - bool efx_mcdi_phy_poll(struct efx_nic *efx) 220 - { 221 - struct efx_link_state old_state = efx->link_state; 222 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN); 223 - int rc; 224 - 225 - WARN_ON(!mutex_is_locked(&efx->mac_lock)); 226 - 227 - BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 228 - 229 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 230 - outbuf, sizeof(outbuf), NULL); 231 - if (rc) 232 - efx->link_state.up = false; 233 - else 234 - efx_mcdi_phy_decode_link( 235 - efx, &efx->link_state, 236 - MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED), 237 - MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), 238 - MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); 239 - 240 - return !efx_link_state_equal(&efx->link_state, &old_state); 241 - } 242 - 243 516 static void efx_mcdi_phy_remove(struct efx_nic *efx) 244 517 { 245 518 struct efx_mcdi_phy_data *phy_data = efx->phy_data; ··· 275 652 return 0; 276 653 } 277 654 278 - int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, 279 - struct ethtool_fecparam *fec) 280 - { 281 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN); 282 - u32 caps, active, speed; /* MCDI format */ 283 - bool is_25g = false; 284 - size_t outlen; 285 - int rc; 286 - 287 - BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 288 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 289 - outbuf, sizeof(outbuf), &outlen); 290 - if (rc) 291 - return rc; 292 - if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN) 293 - return -EOPNOTSUPP; 294 - 295 - /* behaviour for 25G/50G links depends on 25G BASER bit */ 296 - speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED); 297 - is_25g = speed == 25000 || speed == 50000; 298 - 299 - caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP); 300 - fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g); 301 - /* BASER is never supported on 100G */ 302 - if (speed == 100000) 303 - fec->fec &= ~ETHTOOL_FEC_BASER; 304 - 305 - active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE); 306 - switch (active) { 307 - case MC_CMD_FEC_NONE: 308 - fec->active_fec = ETHTOOL_FEC_OFF; 309 - break; 310 - case MC_CMD_FEC_BASER: 311 - fec->active_fec = ETHTOOL_FEC_BASER; 312 - break; 313 - case MC_CMD_FEC_RS: 314 - fec->active_fec = ETHTOOL_FEC_RS; 315 - break; 316 - default: 317 - netif_warn(efx, hw, efx->net_dev, 318 - "Firmware reports unrecognised FEC_TYPE %u\n", 319 - active); 320 - /* We don't know what firmware has picked. AUTO is as good a 321 - * "can't happen" value as any other. 322 - */ 323 - fec->active_fec = ETHTOOL_FEC_AUTO; 324 - break; 325 - } 326 - 327 - return 0; 328 - } 329 - 330 655 static int efx_mcdi_phy_set_fecparam(struct efx_nic *efx, 331 656 const struct ethtool_fecparam *fec) 332 657 { ··· 299 728 300 729 /* Record the new FEC setting for subsequent set_link calls */ 301 730 efx->fec_config = fec->fec; 302 - return 0; 303 - } 304 - 305 - int efx_mcdi_phy_test_alive(struct efx_nic *efx) 306 - { 307 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN); 308 - size_t outlen; 309 - int rc; 310 - 311 - BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0); 312 - 313 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0, 314 - outbuf, sizeof(outbuf), &outlen); 315 - if (rc) 316 - return rc; 317 - 318 - if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN) 319 - return -EIO; 320 - if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK) 321 - return -EINVAL; 322 - 323 731 return 0; 324 732 } 325 733 ··· 883 1333 { 884 1334 efx->phy_op->remove(efx); 885 1335 efx_nic_free_buffer(efx, &efx->stats_buffer); 886 - } 887 - 888 - /* Get physical port number (EF10 only; on Siena it is same as PF number) */ 889 - int efx_mcdi_port_get_number(struct efx_nic *efx) 890 - { 891 - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN); 892 - int rc; 893 - 894 - rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0, 895 - outbuf, sizeof(outbuf), NULL); 896 - if (rc) 897 - return rc; 898 - 899 - return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT); 900 1336 }
+489
drivers/net/ethernet/sfc/mcdi_port_common.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 + * 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 "mcdi_port_common.h" 12 + 13 + int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg) 14 + { 15 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN); 16 + size_t outlen; 17 + int rc; 18 + 19 + BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0); 20 + BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name)); 21 + 22 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0, 23 + outbuf, sizeof(outbuf), &outlen); 24 + if (rc) 25 + goto fail; 26 + 27 + if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) { 28 + rc = -EIO; 29 + goto fail; 30 + } 31 + 32 + cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS); 33 + cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE); 34 + cfg->supported_cap = 35 + MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP); 36 + cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL); 37 + cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT); 38 + cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK); 39 + memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME), 40 + sizeof(cfg->name)); 41 + cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE); 42 + cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK); 43 + memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION), 44 + sizeof(cfg->revision)); 45 + 46 + return 0; 47 + 48 + fail: 49 + netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); 50 + return rc; 51 + } 52 + 53 + void efx_link_set_advertising(struct efx_nic *efx, 54 + const unsigned long *advertising) 55 + { 56 + memcpy(efx->link_advertising, advertising, 57 + sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK())); 58 + 59 + efx->link_advertising[0] |= ADVERTISED_Autoneg; 60 + if (advertising[0] & ADVERTISED_Pause) 61 + efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX); 62 + else 63 + efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX); 64 + if (advertising[0] & ADVERTISED_Asym_Pause) 65 + efx->wanted_fc ^= EFX_FC_TX; 66 + } 67 + 68 + int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities, 69 + u32 flags, u32 loopback_mode, u32 loopback_speed) 70 + { 71 + MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN); 72 + int rc; 73 + 74 + BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0); 75 + 76 + MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities); 77 + MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags); 78 + MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode); 79 + MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed); 80 + 81 + rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf), 82 + NULL, 0, NULL); 83 + return rc; 84 + } 85 + 86 + int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes) 87 + { 88 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN); 89 + size_t outlen; 90 + int rc; 91 + 92 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0, 93 + outbuf, sizeof(outbuf), &outlen); 94 + if (rc) 95 + goto fail; 96 + 97 + if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST + 98 + MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) { 99 + rc = -EIO; 100 + goto fail; 101 + } 102 + 103 + *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED); 104 + 105 + return 0; 106 + 107 + fail: 108 + netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); 109 + return rc; 110 + } 111 + 112 + void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset) 113 + { 114 + #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \ 115 + linkset) 116 + 117 + bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS); 118 + switch (media) { 119 + case MC_CMD_MEDIA_KX4: 120 + SET_BIT(Backplane); 121 + if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 122 + SET_BIT(1000baseKX_Full); 123 + if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 124 + SET_BIT(10000baseKX4_Full); 125 + if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 126 + SET_BIT(40000baseKR4_Full); 127 + break; 128 + 129 + case MC_CMD_MEDIA_XFP: 130 + case MC_CMD_MEDIA_SFP_PLUS: 131 + case MC_CMD_MEDIA_QSFP_PLUS: 132 + SET_BIT(FIBRE); 133 + if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 134 + SET_BIT(1000baseT_Full); 135 + if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 136 + SET_BIT(10000baseT_Full); 137 + if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 138 + SET_BIT(40000baseCR4_Full); 139 + if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN)) 140 + SET_BIT(100000baseCR4_Full); 141 + if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN)) 142 + SET_BIT(25000baseCR_Full); 143 + if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN)) 144 + SET_BIT(50000baseCR2_Full); 145 + break; 146 + 147 + case MC_CMD_MEDIA_BASE_T: 148 + SET_BIT(TP); 149 + if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) 150 + SET_BIT(10baseT_Half); 151 + if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) 152 + SET_BIT(10baseT_Full); 153 + if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) 154 + SET_BIT(100baseT_Half); 155 + if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) 156 + SET_BIT(100baseT_Full); 157 + if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) 158 + SET_BIT(1000baseT_Half); 159 + if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 160 + SET_BIT(1000baseT_Full); 161 + if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 162 + SET_BIT(10000baseT_Full); 163 + break; 164 + } 165 + 166 + if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) 167 + SET_BIT(Pause); 168 + if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) 169 + SET_BIT(Asym_Pause); 170 + if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 171 + SET_BIT(Autoneg); 172 + 173 + #undef SET_BIT 174 + } 175 + 176 + u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset) 177 + { 178 + u32 result = 0; 179 + 180 + #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \ 181 + linkset) 182 + 183 + if (TEST_BIT(10baseT_Half)) 184 + result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN); 185 + if (TEST_BIT(10baseT_Full)) 186 + result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN); 187 + if (TEST_BIT(100baseT_Half)) 188 + result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN); 189 + if (TEST_BIT(100baseT_Full)) 190 + result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN); 191 + if (TEST_BIT(1000baseT_Half)) 192 + result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN); 193 + if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full)) 194 + result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN); 195 + if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full)) 196 + result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN); 197 + if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full)) 198 + result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN); 199 + if (TEST_BIT(100000baseCR4_Full)) 200 + result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN); 201 + if (TEST_BIT(25000baseCR_Full)) 202 + result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN); 203 + if (TEST_BIT(50000baseCR2_Full)) 204 + result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN); 205 + if (TEST_BIT(Pause)) 206 + result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN); 207 + if (TEST_BIT(Asym_Pause)) 208 + result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN); 209 + if (TEST_BIT(Autoneg)) 210 + result |= (1 << MC_CMD_PHY_CAP_AN_LBN); 211 + 212 + #undef TEST_BIT 213 + 214 + return result; 215 + } 216 + 217 + u32 efx_get_mcdi_phy_flags(struct efx_nic *efx) 218 + { 219 + struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 220 + enum efx_phy_mode mode, supported; 221 + u32 flags; 222 + 223 + /* TODO: Advertise the capabilities supported by this PHY */ 224 + supported = 0; 225 + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN)) 226 + supported |= PHY_MODE_TX_DISABLED; 227 + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN)) 228 + supported |= PHY_MODE_LOW_POWER; 229 + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN)) 230 + supported |= PHY_MODE_OFF; 231 + 232 + mode = efx->phy_mode & supported; 233 + 234 + flags = 0; 235 + if (mode & PHY_MODE_TX_DISABLED) 236 + flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN); 237 + if (mode & PHY_MODE_LOW_POWER) 238 + flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN); 239 + if (mode & PHY_MODE_OFF) 240 + flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN); 241 + 242 + return flags; 243 + } 244 + 245 + u8 mcdi_to_ethtool_media(u32 media) 246 + { 247 + switch (media) { 248 + case MC_CMD_MEDIA_XAUI: 249 + case MC_CMD_MEDIA_CX4: 250 + case MC_CMD_MEDIA_KX4: 251 + return PORT_OTHER; 252 + 253 + case MC_CMD_MEDIA_XFP: 254 + case MC_CMD_MEDIA_SFP_PLUS: 255 + case MC_CMD_MEDIA_QSFP_PLUS: 256 + return PORT_FIBRE; 257 + 258 + case MC_CMD_MEDIA_BASE_T: 259 + return PORT_TP; 260 + 261 + default: 262 + return PORT_OTHER; 263 + } 264 + } 265 + 266 + void efx_mcdi_phy_decode_link(struct efx_nic *efx, 267 + struct efx_link_state *link_state, 268 + u32 speed, u32 flags, u32 fcntl) 269 + { 270 + switch (fcntl) { 271 + case MC_CMD_FCNTL_AUTO: 272 + WARN_ON(1); /* This is not a link mode */ 273 + link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX; 274 + break; 275 + case MC_CMD_FCNTL_BIDIR: 276 + link_state->fc = EFX_FC_TX | EFX_FC_RX; 277 + break; 278 + case MC_CMD_FCNTL_RESPOND: 279 + link_state->fc = EFX_FC_RX; 280 + break; 281 + default: 282 + WARN_ON(1); 283 + /* Fall through */ 284 + case MC_CMD_FCNTL_OFF: 285 + link_state->fc = 0; 286 + break; 287 + } 288 + 289 + link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); 290 + link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); 291 + link_state->speed = speed; 292 + } 293 + 294 + /* The semantics of the ethtool FEC mode bitmask are not well defined, 295 + * particularly the meaning of combinations of bits. Which means we get to 296 + * define our own semantics, as follows: 297 + * OFF overrides any other bits, and means "disable all FEC" (with the 298 + * exception of 25G KR4/CR4, where it is not possible to reject it if AN 299 + * partner requests it). 300 + * AUTO on its own means use cable requirements and link partner autoneg with 301 + * fw-default preferences for the cable type. 302 + * AUTO and either RS or BASER means use the specified FEC type if cable and 303 + * link partner support it, otherwise autoneg/fw-default. 304 + * RS or BASER alone means use the specified FEC type if cable and link partner 305 + * support it and either requests it, otherwise no FEC. 306 + * Both RS and BASER (whether AUTO or not) means use FEC if cable and link 307 + * partner support it, preferring RS to BASER. 308 + */ 309 + u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap) 310 + { 311 + u32 ret = 0; 312 + 313 + if (ethtool_cap & ETHTOOL_FEC_OFF) 314 + return 0; 315 + 316 + if (ethtool_cap & ETHTOOL_FEC_AUTO) 317 + ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) | 318 + (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) | 319 + (1 << MC_CMD_PHY_CAP_RS_FEC_LBN); 320 + if (ethtool_cap & ETHTOOL_FEC_RS) 321 + ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) | 322 + (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN); 323 + if (ethtool_cap & ETHTOOL_FEC_BASER) 324 + ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) | 325 + (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) | 326 + (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) | 327 + (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN); 328 + return ret; 329 + } 330 + 331 + /* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function 332 + * can never produce, (baser xor rs) and neither req; the implementation below 333 + * maps both of those to AUTO. This should never matter, and it's not clear 334 + * what a better mapping would be anyway. 335 + */ 336 + u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g) 337 + { 338 + bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN), 339 + rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN), 340 + baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) 341 + : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN), 342 + baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN) 343 + : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN); 344 + 345 + if (!baser && !rs) 346 + return ETHTOOL_FEC_OFF; 347 + return (rs_req ? ETHTOOL_FEC_RS : 0) | 348 + (baser_req ? ETHTOOL_FEC_BASER : 0) | 349 + (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO); 350 + } 351 + 352 + /* Verify that the forced flow control settings (!EFX_FC_AUTO) are 353 + * supported by the link partner. Warn the user if this isn't the case 354 + */ 355 + void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa) 356 + { 357 + struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 358 + u32 rmtadv; 359 + 360 + /* The link partner capabilities are only relevant if the 361 + * link supports flow control autonegotiation 362 + */ 363 + if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 364 + return; 365 + 366 + /* If flow control autoneg is supported and enabled, then fine */ 367 + if (efx->wanted_fc & EFX_FC_AUTO) 368 + return; 369 + 370 + rmtadv = 0; 371 + if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) 372 + rmtadv |= ADVERTISED_Pause; 373 + if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) 374 + rmtadv |= ADVERTISED_Asym_Pause; 375 + 376 + if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause) 377 + netif_err(efx, link, efx->net_dev, 378 + "warning: link partner doesn't support pause frames"); 379 + } 380 + 381 + bool efx_mcdi_phy_poll(struct efx_nic *efx) 382 + { 383 + struct efx_link_state old_state = efx->link_state; 384 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN); 385 + int rc; 386 + 387 + WARN_ON(!mutex_is_locked(&efx->mac_lock)); 388 + 389 + BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 390 + 391 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 392 + outbuf, sizeof(outbuf), NULL); 393 + if (rc) 394 + efx->link_state.up = false; 395 + else 396 + efx_mcdi_phy_decode_link( 397 + efx, &efx->link_state, 398 + MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED), 399 + MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), 400 + MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); 401 + 402 + return !efx_link_state_equal(&efx->link_state, &old_state); 403 + } 404 + 405 + int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec) 406 + { 407 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN); 408 + u32 caps, active, speed; /* MCDI format */ 409 + bool is_25g = false; 410 + size_t outlen; 411 + int rc; 412 + 413 + BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 414 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 415 + outbuf, sizeof(outbuf), &outlen); 416 + if (rc) 417 + return rc; 418 + if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN) 419 + return -EOPNOTSUPP; 420 + 421 + /* behaviour for 25G/50G links depends on 25G BASER bit */ 422 + speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED); 423 + is_25g = speed == 25000 || speed == 50000; 424 + 425 + caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP); 426 + fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g); 427 + /* BASER is never supported on 100G */ 428 + if (speed == 100000) 429 + fec->fec &= ~ETHTOOL_FEC_BASER; 430 + 431 + active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE); 432 + switch (active) { 433 + case MC_CMD_FEC_NONE: 434 + fec->active_fec = ETHTOOL_FEC_OFF; 435 + break; 436 + case MC_CMD_FEC_BASER: 437 + fec->active_fec = ETHTOOL_FEC_BASER; 438 + break; 439 + case MC_CMD_FEC_RS: 440 + fec->active_fec = ETHTOOL_FEC_RS; 441 + break; 442 + default: 443 + netif_warn(efx, hw, efx->net_dev, 444 + "Firmware reports unrecognised FEC_TYPE %u\n", 445 + active); 446 + /* We don't know what firmware has picked. AUTO is as good a 447 + * "can't happen" value as any other. 448 + */ 449 + fec->active_fec = ETHTOOL_FEC_AUTO; 450 + break; 451 + } 452 + 453 + return 0; 454 + } 455 + 456 + int efx_mcdi_phy_test_alive(struct efx_nic *efx) 457 + { 458 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN); 459 + size_t outlen; 460 + int rc; 461 + 462 + BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0); 463 + 464 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0, 465 + outbuf, sizeof(outbuf), &outlen); 466 + if (rc) 467 + return rc; 468 + 469 + if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN) 470 + return -EIO; 471 + if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK) 472 + return -EINVAL; 473 + 474 + return 0; 475 + } 476 + 477 + /* Get physical port number (EF10 only; on Siena it is same as PF number) */ 478 + int efx_mcdi_port_get_number(struct efx_nic *efx) 479 + { 480 + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN); 481 + int rc; 482 + 483 + rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0, 484 + outbuf, sizeof(outbuf), NULL); 485 + if (rc) 486 + return rc; 487 + 488 + return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT); 489 + }