diff options
| -rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 143 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 84 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/enum.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ethtool.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/falcon.c | 10 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 424 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi.h | 19 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi_mon.c | 76 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi_pcol.h | 733 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi_port.c | 89 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/nic.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 203 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 15 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/selftest.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/selftest.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 5 |
20 files changed, 1418 insertions, 421 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 676c3c057bfb..ca922b958a2e 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "mcdi_pcol.h" | 14 | #include "mcdi_pcol.h" |
| 15 | #include "nic.h" | 15 | #include "nic.h" |
| 16 | #include "workarounds.h" | 16 | #include "workarounds.h" |
| 17 | #include "selftest.h" | ||
| 17 | #include <linux/in.h> | 18 | #include <linux/in.h> |
| 18 | #include <linux/jhash.h> | 19 | #include <linux/jhash.h> |
| 19 | #include <linux/wait.h> | 20 | #include <linux/wait.h> |
| @@ -277,11 +278,17 @@ fail1: | |||
| 277 | 278 | ||
| 278 | static int efx_ef10_free_vis(struct efx_nic *efx) | 279 | static int efx_ef10_free_vis(struct efx_nic *efx) |
| 279 | { | 280 | { |
| 280 | int rc = efx_mcdi_rpc(efx, MC_CMD_FREE_VIS, NULL, 0, NULL, 0, NULL); | 281 | MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0); |
| 282 | size_t outlen; | ||
| 283 | int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0, | ||
| 284 | outbuf, sizeof(outbuf), &outlen); | ||
| 281 | 285 | ||
| 282 | /* -EALREADY means nothing to free, so ignore */ | 286 | /* -EALREADY means nothing to free, so ignore */ |
| 283 | if (rc == -EALREADY) | 287 | if (rc == -EALREADY) |
| 284 | rc = 0; | 288 | rc = 0; |
| 289 | if (rc) | ||
| 290 | efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen, | ||
| 291 | rc); | ||
| 285 | return rc; | 292 | return rc; |
| 286 | } | 293 | } |
| 287 | 294 | ||
| @@ -901,6 +908,7 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) | |||
| 901 | return -EAGAIN; | 908 | return -EAGAIN; |
| 902 | 909 | ||
| 903 | /* Update derived statistics */ | 910 | /* Update derived statistics */ |
| 911 | efx_nic_fix_nodesc_drop_stat(efx, &stats[EF10_STAT_rx_nodesc_drops]); | ||
| 904 | stats[EF10_STAT_rx_good_bytes] = | 912 | stats[EF10_STAT_rx_good_bytes] = |
| 905 | stats[EF10_STAT_rx_bytes] - | 913 | stats[EF10_STAT_rx_bytes] - |
| 906 | stats[EF10_STAT_rx_bytes_minus_good_bytes]; | 914 | stats[EF10_STAT_rx_bytes_minus_good_bytes]; |
| @@ -1242,7 +1250,6 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue) | |||
| 1242 | 1250 | ||
| 1243 | fail: | 1251 | fail: |
| 1244 | WARN_ON(true); | 1252 | WARN_ON(true); |
| 1245 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1246 | } | 1253 | } |
| 1247 | 1254 | ||
| 1248 | static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) | 1255 | static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) |
| @@ -1256,7 +1263,7 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) | |||
| 1256 | MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE, | 1263 | MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE, |
| 1257 | tx_queue->queue); | 1264 | tx_queue->queue); |
| 1258 | 1265 | ||
| 1259 | rc = efx_mcdi_rpc(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf), | 1266 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf), |
| 1260 | outbuf, sizeof(outbuf), &outlen); | 1267 | outbuf, sizeof(outbuf), &outlen); |
| 1261 | 1268 | ||
| 1262 | if (rc && rc != -EALREADY) | 1269 | if (rc && rc != -EALREADY) |
| @@ -1265,7 +1272,8 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) | |||
| 1265 | return; | 1272 | return; |
| 1266 | 1273 | ||
| 1267 | fail: | 1274 | fail: |
| 1268 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | 1275 | efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN, |
| 1276 | outbuf, outlen, rc); | ||
| 1269 | } | 1277 | } |
| 1270 | 1278 | ||
| 1271 | static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue) | 1279 | static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue) |
| @@ -1480,14 +1488,9 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue) | |||
| 1480 | 1488 | ||
| 1481 | rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, | 1489 | rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, |
| 1482 | outbuf, sizeof(outbuf), &outlen); | 1490 | outbuf, sizeof(outbuf), &outlen); |
| 1483 | if (rc) | 1491 | WARN_ON(rc); |
| 1484 | goto fail; | ||
| 1485 | 1492 | ||
| 1486 | return; | 1493 | return; |
| 1487 | |||
| 1488 | fail: | ||
| 1489 | WARN_ON(true); | ||
| 1490 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1491 | } | 1494 | } |
| 1492 | 1495 | ||
| 1493 | static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) | 1496 | static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) |
| @@ -1501,7 +1504,7 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) | |||
| 1501 | MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE, | 1504 | MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE, |
| 1502 | efx_rx_queue_index(rx_queue)); | 1505 | efx_rx_queue_index(rx_queue)); |
| 1503 | 1506 | ||
| 1504 | rc = efx_mcdi_rpc(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf), | 1507 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf), |
| 1505 | outbuf, sizeof(outbuf), &outlen); | 1508 | outbuf, sizeof(outbuf), &outlen); |
| 1506 | 1509 | ||
| 1507 | if (rc && rc != -EALREADY) | 1510 | if (rc && rc != -EALREADY) |
| @@ -1510,7 +1513,8 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) | |||
| 1510 | return; | 1513 | return; |
| 1511 | 1514 | ||
| 1512 | fail: | 1515 | fail: |
| 1513 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | 1516 | efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN, |
| 1517 | outbuf, outlen, rc); | ||
| 1514 | } | 1518 | } |
| 1515 | 1519 | ||
| 1516 | static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue) | 1520 | static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue) |
| @@ -1647,15 +1651,7 @@ static int efx_ef10_ev_init(struct efx_channel *channel) | |||
| 1647 | 1651 | ||
| 1648 | rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen, | 1652 | rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen, |
| 1649 | outbuf, sizeof(outbuf), &outlen); | 1653 | outbuf, sizeof(outbuf), &outlen); |
| 1650 | if (rc) | ||
| 1651 | goto fail; | ||
| 1652 | |||
| 1653 | /* IRQ return is ignored */ | 1654 | /* IRQ return is ignored */ |
| 1654 | |||
| 1655 | return 0; | ||
| 1656 | |||
| 1657 | fail: | ||
| 1658 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1659 | return rc; | 1655 | return rc; |
| 1660 | } | 1656 | } |
| 1661 | 1657 | ||
| @@ -1669,7 +1665,7 @@ static void efx_ef10_ev_fini(struct efx_channel *channel) | |||
| 1669 | 1665 | ||
| 1670 | MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel); | 1666 | MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel); |
| 1671 | 1667 | ||
| 1672 | rc = efx_mcdi_rpc(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf), | 1668 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf), |
| 1673 | outbuf, sizeof(outbuf), &outlen); | 1669 | outbuf, sizeof(outbuf), &outlen); |
| 1674 | 1670 | ||
| 1675 | if (rc && rc != -EALREADY) | 1671 | if (rc && rc != -EALREADY) |
| @@ -1678,7 +1674,8 @@ static void efx_ef10_ev_fini(struct efx_channel *channel) | |||
| 1678 | return; | 1674 | return; |
| 1679 | 1675 | ||
| 1680 | fail: | 1676 | fail: |
| 1681 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | 1677 | efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN, |
| 1678 | outbuf, outlen, rc); | ||
| 1682 | } | 1679 | } |
| 1683 | 1680 | ||
| 1684 | static void efx_ef10_ev_remove(struct efx_channel *channel) | 1681 | static void efx_ef10_ev_remove(struct efx_channel *channel) |
| @@ -1765,6 +1762,8 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel, | |||
| 1765 | ((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1)); | 1762 | ((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1)); |
| 1766 | 1763 | ||
| 1767 | if (n_descs != rx_queue->scatter_n + 1) { | 1764 | if (n_descs != rx_queue->scatter_n + 1) { |
| 1765 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | ||
| 1766 | |||
| 1768 | /* detect rx abort */ | 1767 | /* detect rx abort */ |
| 1769 | if (unlikely(n_descs == rx_queue->scatter_n)) { | 1768 | if (unlikely(n_descs == rx_queue->scatter_n)) { |
| 1770 | WARN_ON(rx_bytes != 0); | 1769 | WARN_ON(rx_bytes != 0); |
| @@ -1772,10 +1771,13 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel, | |||
| 1772 | return 0; | 1771 | return 0; |
| 1773 | } | 1772 | } |
| 1774 | 1773 | ||
| 1775 | if (unlikely(rx_queue->scatter_n != 0)) { | 1774 | /* Check that RX completion merging is valid, i.e. |
| 1776 | /* Scattered packet completions cannot be | 1775 | * the current firmware supports it and this is a |
| 1777 | * merged, so something has gone wrong. | 1776 | * non-scattered packet. |
| 1778 | */ | 1777 | */ |
| 1778 | if (!(nic_data->datapath_caps & | ||
| 1779 | (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN)) || | ||
| 1780 | rx_queue->scatter_n != 0 || rx_cont) { | ||
| 1779 | efx_ef10_handle_rx_bad_lbits( | 1781 | efx_ef10_handle_rx_bad_lbits( |
| 1780 | rx_queue, next_ptr_lbits, | 1782 | rx_queue, next_ptr_lbits, |
| 1781 | (rx_queue->removed_count + | 1783 | (rx_queue->removed_count + |
| @@ -1901,7 +1903,7 @@ static void efx_ef10_handle_driver_generated_event(struct efx_channel *channel, | |||
| 1901 | * events, so efx_process_channel() won't refill the | 1903 | * events, so efx_process_channel() won't refill the |
| 1902 | * queue. Refill it here | 1904 | * queue. Refill it here |
| 1903 | */ | 1905 | */ |
| 1904 | efx_fast_push_rx_descriptors(&channel->rx_queue); | 1906 | efx_fast_push_rx_descriptors(&channel->rx_queue, true); |
| 1905 | break; | 1907 | break; |
| 1906 | default: | 1908 | default: |
| 1907 | netif_err(efx, hw, efx->net_dev, | 1909 | netif_err(efx, hw, efx->net_dev, |
| @@ -2257,6 +2259,8 @@ static int efx_ef10_filter_push(struct efx_nic *efx, | |||
| 2257 | outbuf, sizeof(outbuf), NULL); | 2259 | outbuf, sizeof(outbuf), NULL); |
| 2258 | if (rc == 0) | 2260 | if (rc == 0) |
| 2259 | *handle = MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE); | 2261 | *handle = MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE); |
| 2262 | if (rc == -ENOSPC) | ||
| 2263 | rc = -EBUSY; /* to match efx_farch_filter_insert() */ | ||
| 2260 | return rc; | 2264 | return rc; |
| 2261 | } | 2265 | } |
| 2262 | 2266 | ||
| @@ -3195,6 +3199,87 @@ static int efx_ef10_mac_reconfigure(struct efx_nic *efx) | |||
| 3195 | return efx_mcdi_set_mac(efx); | 3199 | return efx_mcdi_set_mac(efx); |
| 3196 | } | 3200 | } |
| 3197 | 3201 | ||
| 3202 | static int efx_ef10_start_bist(struct efx_nic *efx, u32 bist_type) | ||
| 3203 | { | ||
| 3204 | MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN); | ||
| 3205 | |||
| 3206 | MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_type); | ||
| 3207 | return efx_mcdi_rpc(efx, MC_CMD_START_BIST, inbuf, sizeof(inbuf), | ||
| 3208 | NULL, 0, NULL); | ||
| 3209 | } | ||
| 3210 | |||
| 3211 | /* MC BISTs follow a different poll mechanism to phy BISTs. | ||
| 3212 | * The BIST is done in the poll handler on the MC, and the MCDI command | ||
| 3213 | * will block until the BIST is done. | ||
| 3214 | */ | ||
| 3215 | static int efx_ef10_poll_bist(struct efx_nic *efx) | ||
| 3216 | { | ||
| 3217 | int rc; | ||
| 3218 | MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_LEN); | ||
| 3219 | size_t outlen; | ||
| 3220 | u32 result; | ||
| 3221 | |||
| 3222 | rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0, | ||
| 3223 | outbuf, sizeof(outbuf), &outlen); | ||
| 3224 | if (rc != 0) | ||
| 3225 | return rc; | ||
| 3226 | |||
| 3227 | if (outlen < MC_CMD_POLL_BIST_OUT_LEN) | ||
| 3228 | return -EIO; | ||
| 3229 | |||
| 3230 | result = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT); | ||
| 3231 | switch (result) { | ||
| 3232 | case MC_CMD_POLL_BIST_PASSED: | ||
| 3233 | netif_dbg(efx, hw, efx->net_dev, "BIST passed.\n"); | ||
| 3234 | return 0; | ||
| 3235 | case MC_CMD_POLL_BIST_TIMEOUT: | ||
| 3236 | netif_err(efx, hw, efx->net_dev, "BIST timed out\n"); | ||
| 3237 | return -EIO; | ||
| 3238 | case MC_CMD_POLL_BIST_FAILED: | ||
| 3239 | netif_err(efx, hw, efx->net_dev, "BIST failed.\n"); | ||
| 3240 | return -EIO; | ||
| 3241 | default: | ||
| 3242 | netif_err(efx, hw, efx->net_dev, | ||
| 3243 | "BIST returned unknown result %u", result); | ||
| 3244 | return -EIO; | ||
| 3245 | } | ||
| 3246 | } | ||
| 3247 | |||
| 3248 | static int efx_ef10_run_bist(struct efx_nic *efx, u32 bist_type) | ||
| 3249 | { | ||
| 3250 | int rc; | ||
| 3251 | |||
| 3252 | netif_dbg(efx, drv, efx->net_dev, "starting BIST type %u\n", bist_type); | ||
| 3253 | |||
| 3254 | rc = efx_ef10_start_bist(efx, bist_type); | ||
| 3255 | if (rc != 0) | ||
| 3256 | return rc; | ||
| 3257 | |||
| 3258 | return efx_ef10_poll_bist(efx); | ||
| 3259 | } | ||
| 3260 | |||
| 3261 | static int | ||
| 3262 | efx_ef10_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) | ||
| 3263 | { | ||
| 3264 | int rc, rc2; | ||
| 3265 | |||
| 3266 | efx_reset_down(efx, RESET_TYPE_WORLD); | ||
| 3267 | |||
| 3268 | rc = efx_mcdi_rpc(efx, MC_CMD_ENABLE_OFFLINE_BIST, | ||
| 3269 | NULL, 0, NULL, 0, NULL); | ||
| 3270 | if (rc != 0) | ||
| 3271 | goto out; | ||
| 3272 | |||
| 3273 | tests->memory = efx_ef10_run_bist(efx, MC_CMD_MC_MEM_BIST) ? -1 : 1; | ||
| 3274 | tests->registers = efx_ef10_run_bist(efx, MC_CMD_REG_BIST) ? -1 : 1; | ||
| 3275 | |||
| 3276 | rc = efx_mcdi_reset(efx, RESET_TYPE_WORLD); | ||
| 3277 | |||
| 3278 | out: | ||
| 3279 | rc2 = efx_reset_up(efx, RESET_TYPE_WORLD, rc == 0); | ||
| 3280 | return rc ? rc : rc2; | ||
| 3281 | } | ||
| 3282 | |||
| 3198 | #ifdef CONFIG_SFC_MTD | 3283 | #ifdef CONFIG_SFC_MTD |
| 3199 | 3284 | ||
| 3200 | struct efx_ef10_nvram_type_info { | 3285 | struct efx_ef10_nvram_type_info { |
| @@ -3213,6 +3298,7 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = { | |||
| 3213 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 0, 1, "sfc_exp_rom_cfg" }, | 3298 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 0, 1, "sfc_exp_rom_cfg" }, |
| 3214 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 0, 2, "sfc_exp_rom_cfg" }, | 3299 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 0, 2, "sfc_exp_rom_cfg" }, |
| 3215 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 0, 3, "sfc_exp_rom_cfg" }, | 3300 | { NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 0, 3, "sfc_exp_rom_cfg" }, |
| 3301 | { NVRAM_PARTITION_TYPE_LICENSE, 0, 0, "sfc_license" }, | ||
| 3216 | { NVRAM_PARTITION_TYPE_PHY_MIN, 0xff, 0, "sfc_phy_fw" }, | 3302 | { NVRAM_PARTITION_TYPE_PHY_MIN, 0xff, 0, "sfc_phy_fw" }, |
| 3217 | }; | 3303 | }; |
| 3218 | 3304 | ||
| @@ -3336,6 +3422,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { | |||
| 3336 | .describe_stats = efx_ef10_describe_stats, | 3422 | .describe_stats = efx_ef10_describe_stats, |
| 3337 | .update_stats = efx_ef10_update_stats, | 3423 | .update_stats = efx_ef10_update_stats, |
| 3338 | .start_stats = efx_mcdi_mac_start_stats, | 3424 | .start_stats = efx_mcdi_mac_start_stats, |
| 3425 | .pull_stats = efx_mcdi_mac_pull_stats, | ||
| 3339 | .stop_stats = efx_mcdi_mac_stop_stats, | 3426 | .stop_stats = efx_mcdi_mac_stop_stats, |
| 3340 | .set_id_led = efx_mcdi_set_id_led, | 3427 | .set_id_led = efx_mcdi_set_id_led, |
| 3341 | .push_irq_moderation = efx_ef10_push_irq_moderation, | 3428 | .push_irq_moderation = efx_ef10_push_irq_moderation, |
| @@ -3345,7 +3432,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { | |||
| 3345 | .get_wol = efx_ef10_get_wol, | 3432 | .get_wol = efx_ef10_get_wol, |
| 3346 | .set_wol = efx_ef10_set_wol, | 3433 | .set_wol = efx_ef10_set_wol, |
| 3347 | .resume_wol = efx_port_dummy_op_void, | 3434 | .resume_wol = efx_port_dummy_op_void, |
| 3348 | /* TODO: test_chip */ | 3435 | .test_chip = efx_ef10_test_chip, |
| 3349 | .test_nvram = efx_mcdi_nvram_test_all, | 3436 | .test_nvram = efx_mcdi_nvram_test_all, |
| 3350 | .mcdi_request = efx_ef10_mcdi_request, | 3437 | .mcdi_request = efx_ef10_mcdi_request, |
| 3351 | .mcdi_poll_response = efx_ef10_mcdi_poll_response, | 3438 | .mcdi_poll_response = efx_ef10_mcdi_poll_response, |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 12f60e782868..191ac8378eff 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
| @@ -83,6 +83,7 @@ const char *const efx_reset_type_names[] = { | |||
| 83 | [RESET_TYPE_DMA_ERROR] = "DMA_ERROR", | 83 | [RESET_TYPE_DMA_ERROR] = "DMA_ERROR", |
| 84 | [RESET_TYPE_TX_SKIP] = "TX_SKIP", | 84 | [RESET_TYPE_TX_SKIP] = "TX_SKIP", |
| 85 | [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", | 85 | [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", |
| 86 | [RESET_TYPE_MC_BIST] = "MC_BIST", | ||
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| 88 | /* Reset workqueue. If any NIC has a hardware failure then a reset will be | 89 | /* Reset workqueue. If any NIC has a hardware failure then a reset will be |
| @@ -91,6 +92,12 @@ const char *const efx_reset_type_names[] = { | |||
| 91 | */ | 92 | */ |
| 92 | static struct workqueue_struct *reset_workqueue; | 93 | static struct workqueue_struct *reset_workqueue; |
| 93 | 94 | ||
| 95 | /* How often and how many times to poll for a reset while waiting for a | ||
| 96 | * BIST that another function started to complete. | ||
| 97 | */ | ||
| 98 | #define BIST_WAIT_DELAY_MS 100 | ||
| 99 | #define BIST_WAIT_DELAY_COUNT 100 | ||
| 100 | |||
| 94 | /************************************************************************** | 101 | /************************************************************************** |
| 95 | * | 102 | * |
| 96 | * Configurable values | 103 | * Configurable values |
| @@ -246,7 +253,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) | |||
| 246 | efx_channel_get_rx_queue(channel); | 253 | efx_channel_get_rx_queue(channel); |
| 247 | 254 | ||
| 248 | efx_rx_flush_packet(channel); | 255 | efx_rx_flush_packet(channel); |
| 249 | efx_fast_push_rx_descriptors(rx_queue); | 256 | efx_fast_push_rx_descriptors(rx_queue, true); |
| 250 | } | 257 | } |
| 251 | 258 | ||
| 252 | return spent; | 259 | return spent; |
| @@ -585,7 +592,7 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
| 585 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | 592 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + |
| 586 | efx->type->rx_buffer_padding); | 593 | efx->type->rx_buffer_padding); |
| 587 | rx_buf_len = (sizeof(struct efx_rx_page_state) + | 594 | rx_buf_len = (sizeof(struct efx_rx_page_state) + |
| 588 | NET_IP_ALIGN + efx->rx_dma_len); | 595 | efx->rx_ip_align + efx->rx_dma_len); |
| 589 | if (rx_buf_len <= PAGE_SIZE) { | 596 | if (rx_buf_len <= PAGE_SIZE) { |
| 590 | efx->rx_scatter = efx->type->always_rx_scatter; | 597 | efx->rx_scatter = efx->type->always_rx_scatter; |
| 591 | efx->rx_buffer_order = 0; | 598 | efx->rx_buffer_order = 0; |
| @@ -639,12 +646,16 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
| 639 | efx_for_each_channel_rx_queue(rx_queue, channel) { | 646 | efx_for_each_channel_rx_queue(rx_queue, channel) { |
| 640 | efx_init_rx_queue(rx_queue); | 647 | efx_init_rx_queue(rx_queue); |
| 641 | atomic_inc(&efx->active_queues); | 648 | atomic_inc(&efx->active_queues); |
| 642 | efx_nic_generate_fill_event(rx_queue); | 649 | efx_stop_eventq(channel); |
| 650 | efx_fast_push_rx_descriptors(rx_queue, false); | ||
| 651 | efx_start_eventq(channel); | ||
| 643 | } | 652 | } |
| 644 | 653 | ||
| 645 | WARN_ON(channel->rx_pkt_n_frags); | 654 | WARN_ON(channel->rx_pkt_n_frags); |
| 646 | } | 655 | } |
| 647 | 656 | ||
| 657 | efx_ptp_start_datapath(efx); | ||
| 658 | |||
| 648 | if (netif_device_present(efx->net_dev)) | 659 | if (netif_device_present(efx->net_dev)) |
| 649 | netif_tx_wake_all_queues(efx->net_dev); | 660 | netif_tx_wake_all_queues(efx->net_dev); |
| 650 | } | 661 | } |
| @@ -659,6 +670,8 @@ static void efx_stop_datapath(struct efx_nic *efx) | |||
| 659 | EFX_ASSERT_RESET_SERIALISED(efx); | 670 | EFX_ASSERT_RESET_SERIALISED(efx); |
| 660 | BUG_ON(efx->port_enabled); | 671 | BUG_ON(efx->port_enabled); |
| 661 | 672 | ||
| 673 | efx_ptp_stop_datapath(efx); | ||
| 674 | |||
| 662 | /* Stop RX refill */ | 675 | /* Stop RX refill */ |
| 663 | efx_for_each_channel(channel, efx) { | 676 | efx_for_each_channel(channel, efx) { |
| 664 | efx_for_each_channel_rx_queue(rx_queue, channel) | 677 | efx_for_each_channel_rx_queue(rx_queue, channel) |
| @@ -1047,18 +1060,23 @@ static void efx_start_port(struct efx_nic *efx) | |||
| 1047 | mutex_lock(&efx->mac_lock); | 1060 | mutex_lock(&efx->mac_lock); |
| 1048 | efx->port_enabled = true; | 1061 | efx->port_enabled = true; |
| 1049 | 1062 | ||
| 1050 | /* efx_mac_work() might have been scheduled after efx_stop_port(), | 1063 | /* Ensure MAC ingress/egress is enabled */ |
| 1051 | * and then cancelled by efx_flush_all() */ | ||
| 1052 | efx->type->reconfigure_mac(efx); | 1064 | efx->type->reconfigure_mac(efx); |
| 1053 | 1065 | ||
| 1054 | mutex_unlock(&efx->mac_lock); | 1066 | mutex_unlock(&efx->mac_lock); |
| 1055 | } | 1067 | } |
| 1056 | 1068 | ||
| 1057 | /* Prevent efx_mac_work() and efx_monitor() from working */ | 1069 | /* Cancel work for MAC reconfiguration, periodic hardware monitoring |
| 1070 | * and the async self-test, wait for them to finish and prevent them | ||
| 1071 | * being scheduled again. This doesn't cover online resets, which | ||
| 1072 | * should only be cancelled when removing the device. | ||
| 1073 | */ | ||
| 1058 | static void efx_stop_port(struct efx_nic *efx) | 1074 | static void efx_stop_port(struct efx_nic *efx) |
| 1059 | { | 1075 | { |
| 1060 | netif_dbg(efx, ifdown, efx->net_dev, "stop port\n"); | 1076 | netif_dbg(efx, ifdown, efx->net_dev, "stop port\n"); |
| 1061 | 1077 | ||
| 1078 | EFX_ASSERT_RESET_SERIALISED(efx); | ||
| 1079 | |||
| 1062 | mutex_lock(&efx->mac_lock); | 1080 | mutex_lock(&efx->mac_lock); |
| 1063 | efx->port_enabled = false; | 1081 | efx->port_enabled = false; |
| 1064 | mutex_unlock(&efx->mac_lock); | 1082 | mutex_unlock(&efx->mac_lock); |
| @@ -1066,6 +1084,10 @@ static void efx_stop_port(struct efx_nic *efx) | |||
| 1066 | /* Serialise against efx_set_multicast_list() */ | 1084 | /* Serialise against efx_set_multicast_list() */ |
| 1067 | netif_addr_lock_bh(efx->net_dev); | 1085 | netif_addr_lock_bh(efx->net_dev); |
| 1068 | netif_addr_unlock_bh(efx->net_dev); | 1086 | netif_addr_unlock_bh(efx->net_dev); |
| 1087 | |||
| 1088 | cancel_delayed_work_sync(&efx->monitor_work); | ||
| 1089 | efx_selftest_async_cancel(efx); | ||
| 1090 | cancel_work_sync(&efx->mac_work); | ||
| 1069 | } | 1091 | } |
| 1070 | 1092 | ||
| 1071 | static void efx_fini_port(struct efx_nic *efx) | 1093 | static void efx_fini_port(struct efx_nic *efx) |
| @@ -1671,18 +1693,10 @@ static void efx_start_all(struct efx_nic *efx) | |||
| 1671 | } | 1693 | } |
| 1672 | 1694 | ||
| 1673 | efx->type->start_stats(efx); | 1695 | efx->type->start_stats(efx); |
| 1674 | } | 1696 | efx->type->pull_stats(efx); |
| 1675 | 1697 | spin_lock_bh(&efx->stats_lock); | |
| 1676 | /* Flush all delayed work. Should only be called when no more delayed work | 1698 | efx->type->update_stats(efx, NULL, NULL); |
| 1677 | * will be scheduled. This doesn't flush pending online resets (efx_reset), | 1699 | spin_unlock_bh(&efx->stats_lock); |
| 1678 | * since we're holding the rtnl_lock at this point. */ | ||
| 1679 | static void efx_flush_all(struct efx_nic *efx) | ||
| 1680 | { | ||
| 1681 | /* Make sure the hardware monitor and event self-test are stopped */ | ||
| 1682 | cancel_delayed_work_sync(&efx->monitor_work); | ||
| 1683 | efx_selftest_async_cancel(efx); | ||
| 1684 | /* Stop scheduled port reconfigurations */ | ||
| 1685 | cancel_work_sync(&efx->mac_work); | ||
| 1686 | } | 1700 | } |
| 1687 | 1701 | ||
| 1688 | /* Quiesce the hardware and software data path, and regular activity | 1702 | /* Quiesce the hardware and software data path, and regular activity |
| @@ -1698,12 +1712,16 @@ static void efx_stop_all(struct efx_nic *efx) | |||
| 1698 | if (!efx->port_enabled) | 1712 | if (!efx->port_enabled) |
| 1699 | return; | 1713 | return; |
| 1700 | 1714 | ||
| 1715 | /* update stats before we go down so we can accurately count | ||
| 1716 | * rx_nodesc_drops | ||
| 1717 | */ | ||
| 1718 | efx->type->pull_stats(efx); | ||
| 1719 | spin_lock_bh(&efx->stats_lock); | ||
| 1720 | efx->type->update_stats(efx, NULL, NULL); | ||
| 1721 | spin_unlock_bh(&efx->stats_lock); | ||
| 1701 | efx->type->stop_stats(efx); | 1722 | efx->type->stop_stats(efx); |
| 1702 | efx_stop_port(efx); | 1723 | efx_stop_port(efx); |
| 1703 | 1724 | ||
| 1704 | /* Flush efx_mac_work(), refill_workqueue, monitor_work */ | ||
| 1705 | efx_flush_all(efx); | ||
| 1706 | |||
| 1707 | /* Stop the kernel transmit interface. This is only valid if | 1725 | /* Stop the kernel transmit interface. This is only valid if |
| 1708 | * the device is stopped or detached; otherwise the watchdog | 1726 | * the device is stopped or detached; otherwise the watchdog |
| 1709 | * may fire immediately. | 1727 | * may fire immediately. |
| @@ -2385,6 +2403,24 @@ int efx_try_recovery(struct efx_nic *efx) | |||
| 2385 | return 0; | 2403 | return 0; |
| 2386 | } | 2404 | } |
| 2387 | 2405 | ||
| 2406 | static void efx_wait_for_bist_end(struct efx_nic *efx) | ||
| 2407 | { | ||
| 2408 | int i; | ||
| 2409 | |||
| 2410 | for (i = 0; i < BIST_WAIT_DELAY_COUNT; ++i) { | ||
| 2411 | if (efx_mcdi_poll_reboot(efx)) | ||
| 2412 | goto out; | ||
| 2413 | msleep(BIST_WAIT_DELAY_MS); | ||
| 2414 | } | ||
| 2415 | |||
| 2416 | netif_err(efx, drv, efx->net_dev, "Warning: No MC reboot after BIST mode\n"); | ||
| 2417 | out: | ||
| 2418 | /* Either way unset the BIST flag. If we found no reboot we probably | ||
| 2419 | * won't recover, but we should try. | ||
| 2420 | */ | ||
| 2421 | efx->mc_bist_for_other_fn = false; | ||
| 2422 | } | ||
| 2423 | |||
| 2388 | /* The worker thread exists so that code that cannot sleep can | 2424 | /* The worker thread exists so that code that cannot sleep can |
| 2389 | * schedule a reset for later. | 2425 | * schedule a reset for later. |
| 2390 | */ | 2426 | */ |
| @@ -2397,6 +2433,9 @@ static void efx_reset_work(struct work_struct *data) | |||
| 2397 | pending = ACCESS_ONCE(efx->reset_pending); | 2433 | pending = ACCESS_ONCE(efx->reset_pending); |
| 2398 | method = fls(pending) - 1; | 2434 | method = fls(pending) - 1; |
| 2399 | 2435 | ||
| 2436 | if (method == RESET_TYPE_MC_BIST) | ||
| 2437 | efx_wait_for_bist_end(efx); | ||
| 2438 | |||
| 2400 | if ((method == RESET_TYPE_RECOVER_OR_DISABLE || | 2439 | if ((method == RESET_TYPE_RECOVER_OR_DISABLE || |
| 2401 | method == RESET_TYPE_RECOVER_OR_ALL) && | 2440 | method == RESET_TYPE_RECOVER_OR_ALL) && |
| 2402 | efx_try_recovery(efx)) | 2441 | efx_try_recovery(efx)) |
| @@ -2435,6 +2474,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) | |||
| 2435 | case RESET_TYPE_WORLD: | 2474 | case RESET_TYPE_WORLD: |
| 2436 | case RESET_TYPE_DISABLE: | 2475 | case RESET_TYPE_DISABLE: |
| 2437 | case RESET_TYPE_RECOVER_OR_DISABLE: | 2476 | case RESET_TYPE_RECOVER_OR_DISABLE: |
| 2477 | case RESET_TYPE_MC_BIST: | ||
| 2438 | method = type; | 2478 | method = type; |
| 2439 | netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", | 2479 | netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", |
| 2440 | RESET_TYPE(method)); | 2480 | RESET_TYPE(method)); |
| @@ -2542,6 +2582,8 @@ static int efx_init_struct(struct efx_nic *efx, | |||
| 2542 | 2582 | ||
| 2543 | efx->net_dev = net_dev; | 2583 | efx->net_dev = net_dev; |
| 2544 | efx->rx_prefix_size = efx->type->rx_prefix_size; | 2584 | efx->rx_prefix_size = efx->type->rx_prefix_size; |
| 2585 | efx->rx_ip_align = | ||
| 2586 | NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0; | ||
| 2545 | efx->rx_packet_hash_offset = | 2587 | efx->rx_packet_hash_offset = |
| 2546 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; | 2588 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; |
| 2547 | spin_lock_init(&efx->stats_lock); | 2589 | spin_lock_init(&efx->stats_lock); |
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index b8235ee5d7d7..a653786fbbe7 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h | |||
| @@ -37,7 +37,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); | |||
| 37 | void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); | 37 | void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); |
| 38 | void efx_init_rx_queue(struct efx_rx_queue *rx_queue); | 38 | void efx_init_rx_queue(struct efx_rx_queue *rx_queue); |
| 39 | void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); | 39 | void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); |
| 40 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); | 40 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic); |
| 41 | void efx_rx_slow_fill(unsigned long context); | 41 | void efx_rx_slow_fill(unsigned long context); |
| 42 | void __efx_rx_packet(struct efx_channel *channel); | 42 | void __efx_rx_packet(struct efx_channel *channel); |
| 43 | void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, | 43 | void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, |
diff --git a/drivers/net/ethernet/sfc/enum.h b/drivers/net/ethernet/sfc/enum.h index 7fdfee019092..75ef7ef6450b 100644 --- a/drivers/net/ethernet/sfc/enum.h +++ b/drivers/net/ethernet/sfc/enum.h | |||
| @@ -165,6 +165,7 @@ enum reset_type { | |||
| 165 | RESET_TYPE_DMA_ERROR, | 165 | RESET_TYPE_DMA_ERROR, |
| 166 | RESET_TYPE_TX_SKIP, | 166 | RESET_TYPE_TX_SKIP, |
| 167 | RESET_TYPE_MC_FAILURE, | 167 | RESET_TYPE_MC_FAILURE, |
| 168 | RESET_TYPE_MC_BIST, | ||
| 168 | RESET_TYPE_MAX, | 169 | RESET_TYPE_MAX, |
| 169 | }; | 170 | }; |
| 170 | 171 | ||
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 1f529fa2edb1..fb8993806167 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
| @@ -318,6 +318,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
| 318 | "eventq.int", NULL); | 318 | "eventq.int", NULL); |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | efx_fill_test(n++, strings, data, &tests->memory, | ||
| 322 | "core", 0, "memory", NULL); | ||
| 321 | efx_fill_test(n++, strings, data, &tests->registers, | 323 | efx_fill_test(n++, strings, data, &tests->registers, |
| 322 | "core", 0, "registers", NULL); | 324 | "core", 0, "registers", NULL); |
| 323 | 325 | ||
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index ff5d322b9b49..4a9e05c82e2a 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c | |||
| @@ -2593,6 +2593,14 @@ void falcon_start_nic_stats(struct efx_nic *efx) | |||
| 2593 | spin_unlock_bh(&efx->stats_lock); | 2593 | spin_unlock_bh(&efx->stats_lock); |
| 2594 | } | 2594 | } |
| 2595 | 2595 | ||
| 2596 | /* We don't acutally pull stats on falcon. Wait 10ms so that | ||
| 2597 | * they arrive when we call this just after start_stats | ||
| 2598 | */ | ||
| 2599 | void falcon_pull_nic_stats(struct efx_nic *efx) | ||
| 2600 | { | ||
| 2601 | msleep(10); | ||
| 2602 | } | ||
| 2603 | |||
| 2596 | void falcon_stop_nic_stats(struct efx_nic *efx) | 2604 | void falcon_stop_nic_stats(struct efx_nic *efx) |
| 2597 | { | 2605 | { |
| 2598 | struct falcon_nic_data *nic_data = efx->nic_data; | 2606 | struct falcon_nic_data *nic_data = efx->nic_data; |
| @@ -2672,6 +2680,7 @@ const struct efx_nic_type falcon_a1_nic_type = { | |||
| 2672 | .describe_stats = falcon_describe_nic_stats, | 2680 | .describe_stats = falcon_describe_nic_stats, |
| 2673 | .update_stats = falcon_update_nic_stats, | 2681 | .update_stats = falcon_update_nic_stats, |
| 2674 | .start_stats = falcon_start_nic_stats, | 2682 | .start_stats = falcon_start_nic_stats, |
| 2683 | .pull_stats = falcon_pull_nic_stats, | ||
| 2675 | .stop_stats = falcon_stop_nic_stats, | 2684 | .stop_stats = falcon_stop_nic_stats, |
| 2676 | .set_id_led = falcon_set_id_led, | 2685 | .set_id_led = falcon_set_id_led, |
| 2677 | .push_irq_moderation = falcon_push_irq_moderation, | 2686 | .push_irq_moderation = falcon_push_irq_moderation, |
| @@ -2765,6 +2774,7 @@ const struct efx_nic_type falcon_b0_nic_type = { | |||
| 2765 | .describe_stats = falcon_describe_nic_stats, | 2774 | .describe_stats = falcon_describe_nic_stats, |
| 2766 | .update_stats = falcon_update_nic_stats, | 2775 | .update_stats = falcon_update_nic_stats, |
| 2767 | .start_stats = falcon_start_nic_stats, | 2776 | .start_stats = falcon_start_nic_stats, |
| 2777 | .pull_stats = falcon_pull_nic_stats, | ||
| 2768 | .stop_stats = falcon_stop_nic_stats, | 2778 | .stop_stats = falcon_stop_nic_stats, |
| 2769 | .set_id_led = falcon_set_id_led, | 2779 | .set_id_led = falcon_set_id_led, |
| 2770 | .push_irq_moderation = falcon_push_irq_moderation, | 2780 | .push_irq_moderation = falcon_push_irq_moderation, |
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index c0907d884d75..984e85ee76f6 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c | |||
| @@ -1147,7 +1147,7 @@ static void efx_farch_handle_generated_event(struct efx_channel *channel, | |||
| 1147 | /* The queue must be empty, so we won't receive any rx | 1147 | /* The queue must be empty, so we won't receive any rx |
| 1148 | * events, so efx_process_channel() won't refill the | 1148 | * events, so efx_process_channel() won't refill the |
| 1149 | * queue. Refill it here */ | 1149 | * queue. Refill it here */ |
| 1150 | efx_fast_push_rx_descriptors(rx_queue); | 1150 | efx_fast_push_rx_descriptors(rx_queue, true); |
| 1151 | } else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) { | 1151 | } else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) { |
| 1152 | efx_farch_handle_drain_event(channel); | 1152 | efx_farch_handle_drain_event(channel); |
| 1153 | } else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) { | 1153 | } else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) { |
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 366c8e3e3784..d317dfdee845 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c | |||
| @@ -42,6 +42,7 @@ struct efx_mcdi_async_param { | |||
| 42 | unsigned int cmd; | 42 | unsigned int cmd; |
| 43 | size_t inlen; | 43 | size_t inlen; |
| 44 | size_t outlen; | 44 | size_t outlen; |
| 45 | bool quiet; | ||
| 45 | efx_mcdi_async_completer *complete; | 46 | efx_mcdi_async_completer *complete; |
| 46 | unsigned long cookie; | 47 | unsigned long cookie; |
| 47 | /* followed by request/response buffer */ | 48 | /* followed by request/response buffer */ |
| @@ -50,6 +51,7 @@ struct efx_mcdi_async_param { | |||
| 50 | static void efx_mcdi_timeout_async(unsigned long context); | 51 | static void efx_mcdi_timeout_async(unsigned long context); |
| 51 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, | 52 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, |
| 52 | bool *was_attached_out); | 53 | bool *was_attached_out); |
| 54 | static bool efx_mcdi_poll_once(struct efx_nic *efx); | ||
| 53 | 55 | ||
| 54 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) | 56 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) |
| 55 | { | 57 | { |
| @@ -190,6 +192,8 @@ static int efx_mcdi_errno(unsigned int mcdi_err) | |||
| 190 | TRANSLATE_ERROR(EALREADY); | 192 | TRANSLATE_ERROR(EALREADY); |
| 191 | TRANSLATE_ERROR(ENOSPC); | 193 | TRANSLATE_ERROR(ENOSPC); |
| 192 | #undef TRANSLATE_ERROR | 194 | #undef TRANSLATE_ERROR |
| 195 | case MC_CMD_ERR_ENOTSUP: | ||
| 196 | return -EOPNOTSUPP; | ||
| 193 | case MC_CMD_ERR_ALLOC_FAIL: | 197 | case MC_CMD_ERR_ALLOC_FAIL: |
| 194 | return -ENOBUFS; | 198 | return -ENOBUFS; |
| 195 | case MC_CMD_ERR_MAC_EXIST: | 199 | case MC_CMD_ERR_MAC_EXIST: |
| @@ -237,6 +241,21 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx) | |||
| 237 | } | 241 | } |
| 238 | } | 242 | } |
| 239 | 243 | ||
| 244 | static bool efx_mcdi_poll_once(struct efx_nic *efx) | ||
| 245 | { | ||
| 246 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | ||
| 247 | |||
| 248 | rmb(); | ||
| 249 | if (!efx->type->mcdi_poll_response(efx)) | ||
| 250 | return false; | ||
| 251 | |||
| 252 | spin_lock_bh(&mcdi->iface_lock); | ||
| 253 | efx_mcdi_read_response_header(efx); | ||
| 254 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 255 | |||
| 256 | return true; | ||
| 257 | } | ||
| 258 | |||
| 240 | static int efx_mcdi_poll(struct efx_nic *efx) | 259 | static int efx_mcdi_poll(struct efx_nic *efx) |
| 241 | { | 260 | { |
| 242 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 261 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| @@ -272,18 +291,13 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
| 272 | 291 | ||
| 273 | time = jiffies; | 292 | time = jiffies; |
| 274 | 293 | ||
| 275 | rmb(); | 294 | if (efx_mcdi_poll_once(efx)) |
| 276 | if (efx->type->mcdi_poll_response(efx)) | ||
| 277 | break; | 295 | break; |
| 278 | 296 | ||
| 279 | if (time_after(time, finish)) | 297 | if (time_after(time, finish)) |
| 280 | return -ETIMEDOUT; | 298 | return -ETIMEDOUT; |
| 281 | } | 299 | } |
| 282 | 300 | ||
| 283 | spin_lock_bh(&mcdi->iface_lock); | ||
| 284 | efx_mcdi_read_response_header(efx); | ||
| 285 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 286 | |||
| 287 | /* Return rc=0 like wait_event_timeout() */ | 301 | /* Return rc=0 like wait_event_timeout() */ |
| 288 | return 0; | 302 | return 0; |
| 289 | } | 303 | } |
| @@ -391,8 +405,9 @@ static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout) | |||
| 391 | { | 405 | { |
| 392 | struct efx_nic *efx = mcdi->efx; | 406 | struct efx_nic *efx = mcdi->efx; |
| 393 | struct efx_mcdi_async_param *async; | 407 | struct efx_mcdi_async_param *async; |
| 394 | size_t hdr_len, data_len; | 408 | size_t hdr_len, data_len, err_len; |
| 395 | efx_dword_t *outbuf; | 409 | efx_dword_t *outbuf; |
| 410 | MCDI_DECLARE_BUF_OUT_OR_ERR(errbuf, 0); | ||
| 396 | int rc; | 411 | int rc; |
| 397 | 412 | ||
| 398 | if (cmpxchg(&mcdi->state, | 413 | if (cmpxchg(&mcdi->state, |
| @@ -433,6 +448,13 @@ static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout) | |||
| 433 | outbuf = (efx_dword_t *)(async + 1); | 448 | outbuf = (efx_dword_t *)(async + 1); |
| 434 | efx->type->mcdi_read_response(efx, outbuf, hdr_len, | 449 | efx->type->mcdi_read_response(efx, outbuf, hdr_len, |
| 435 | min(async->outlen, data_len)); | 450 | min(async->outlen, data_len)); |
| 451 | if (!timeout && rc && !async->quiet) { | ||
| 452 | err_len = min(sizeof(errbuf), data_len); | ||
| 453 | efx->type->mcdi_read_response(efx, errbuf, hdr_len, | ||
| 454 | sizeof(errbuf)); | ||
| 455 | efx_mcdi_display_error(efx, async->cmd, async->inlen, errbuf, | ||
| 456 | err_len, rc); | ||
| 457 | } | ||
| 436 | async->complete(efx, async->cookie, rc, outbuf, data_len); | 458 | async->complete(efx, async->cookie, rc, outbuf, data_len); |
| 437 | kfree(async); | 459 | kfree(async); |
| 438 | 460 | ||
| @@ -508,18 +530,129 @@ efx_mcdi_check_supported(struct efx_nic *efx, unsigned int cmd, size_t inlen) | |||
| 508 | return 0; | 530 | return 0; |
| 509 | } | 531 | } |
| 510 | 532 | ||
| 533 | static int _efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, | ||
| 534 | efx_dword_t *outbuf, size_t outlen, | ||
| 535 | size_t *outlen_actual, bool quiet) | ||
| 536 | { | ||
| 537 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | ||
| 538 | MCDI_DECLARE_BUF_OUT_OR_ERR(errbuf, 0); | ||
| 539 | int rc; | ||
| 540 | |||
| 541 | if (mcdi->mode == MCDI_MODE_POLL) | ||
| 542 | rc = efx_mcdi_poll(efx); | ||
| 543 | else | ||
| 544 | rc = efx_mcdi_await_completion(efx); | ||
| 545 | |||
| 546 | if (rc != 0) { | ||
| 547 | netif_err(efx, hw, efx->net_dev, | ||
| 548 | "MC command 0x%x inlen %d mode %d timed out\n", | ||
| 549 | cmd, (int)inlen, mcdi->mode); | ||
| 550 | |||
| 551 | if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) { | ||
| 552 | netif_err(efx, hw, efx->net_dev, | ||
| 553 | "MCDI request was completed without an event\n"); | ||
| 554 | rc = 0; | ||
| 555 | } | ||
| 556 | |||
| 557 | /* Close the race with efx_mcdi_ev_cpl() executing just too late | ||
| 558 | * and completing a request we've just cancelled, by ensuring | ||
| 559 | * that the seqno check therein fails. | ||
| 560 | */ | ||
| 561 | spin_lock_bh(&mcdi->iface_lock); | ||
| 562 | ++mcdi->seqno; | ||
| 563 | ++mcdi->credits; | ||
| 564 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 565 | } | ||
| 566 | |||
| 567 | if (rc != 0) { | ||
| 568 | if (outlen_actual) | ||
| 569 | *outlen_actual = 0; | ||
| 570 | } else { | ||
| 571 | size_t hdr_len, data_len, err_len; | ||
| 572 | |||
| 573 | /* At the very least we need a memory barrier here to ensure | ||
| 574 | * we pick up changes from efx_mcdi_ev_cpl(). Protect against | ||
| 575 | * a spurious efx_mcdi_ev_cpl() running concurrently by | ||
| 576 | * acquiring the iface_lock. */ | ||
| 577 | spin_lock_bh(&mcdi->iface_lock); | ||
| 578 | rc = mcdi->resprc; | ||
| 579 | hdr_len = mcdi->resp_hdr_len; | ||
| 580 | data_len = mcdi->resp_data_len; | ||
| 581 | err_len = min(sizeof(errbuf), data_len); | ||
| 582 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 583 | |||
| 584 | BUG_ON(rc > 0); | ||
| 585 | |||
| 586 | efx->type->mcdi_read_response(efx, outbuf, hdr_len, | ||
| 587 | min(outlen, data_len)); | ||
| 588 | if (outlen_actual) | ||
| 589 | *outlen_actual = data_len; | ||
| 590 | |||
| 591 | efx->type->mcdi_read_response(efx, errbuf, hdr_len, err_len); | ||
| 592 | |||
| 593 | if (cmd == MC_CMD_REBOOT && rc == -EIO) { | ||
| 594 | /* Don't reset if MC_CMD_REBOOT returns EIO */ | ||
| 595 | } else if (rc == -EIO || rc == -EINTR) { | ||
| 596 | netif_err(efx, hw, efx->net_dev, "MC fatal error %d\n", | ||
| 597 | -rc); | ||
| 598 | efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); | ||
| 599 | } else if (rc && !quiet) { | ||
| 600 | efx_mcdi_display_error(efx, cmd, inlen, errbuf, err_len, | ||
| 601 | rc); | ||
| 602 | } | ||
| 603 | |||
| 604 | if (rc == -EIO || rc == -EINTR) { | ||
| 605 | msleep(MCDI_STATUS_SLEEP_MS); | ||
| 606 | efx_mcdi_poll_reboot(efx); | ||
| 607 | mcdi->new_epoch = true; | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | efx_mcdi_release(mcdi); | ||
| 612 | return rc; | ||
| 613 | } | ||
| 614 | |||
| 615 | static int _efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, | ||
| 616 | const efx_dword_t *inbuf, size_t inlen, | ||
| 617 | efx_dword_t *outbuf, size_t outlen, | ||
| 618 | size_t *outlen_actual, bool quiet) | ||
| 619 | { | ||
| 620 | int rc; | ||
| 621 | |||
| 622 | rc = efx_mcdi_rpc_start(efx, cmd, inbuf, inlen); | ||
| 623 | if (rc) { | ||
| 624 | if (outlen_actual) | ||
| 625 | *outlen_actual = 0; | ||
| 626 | return rc; | ||
| 627 | } | ||
| 628 | return _efx_mcdi_rpc_finish(efx, cmd, inlen, outbuf, outlen, | ||
| 629 | outlen_actual, quiet); | ||
| 630 | } | ||
| 631 | |||
| 511 | int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, | 632 | int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, |
| 512 | const efx_dword_t *inbuf, size_t inlen, | 633 | const efx_dword_t *inbuf, size_t inlen, |
| 513 | efx_dword_t *outbuf, size_t outlen, | 634 | efx_dword_t *outbuf, size_t outlen, |
| 514 | size_t *outlen_actual) | 635 | size_t *outlen_actual) |
| 515 | { | 636 | { |
| 516 | int rc; | 637 | return _efx_mcdi_rpc(efx, cmd, inbuf, inlen, outbuf, outlen, |
| 638 | outlen_actual, false); | ||
| 639 | } | ||
| 517 | 640 | ||
| 518 | rc = efx_mcdi_rpc_start(efx, cmd, inbuf, inlen); | 641 | /* Normally, on receiving an error code in the MCDI response, |
| 519 | if (rc) | 642 | * efx_mcdi_rpc will log an error message containing (among other |
| 520 | return rc; | 643 | * things) the raw error code, by means of efx_mcdi_display_error. |
| 521 | return efx_mcdi_rpc_finish(efx, cmd, inlen, | 644 | * This _quiet version suppresses that; if the caller wishes to log |
| 522 | outbuf, outlen, outlen_actual); | 645 | * the error conditionally on the return code, it should call this |
| 646 | * function and is then responsible for calling efx_mcdi_display_error | ||
| 647 | * as needed. | ||
| 648 | */ | ||
| 649 | int efx_mcdi_rpc_quiet(struct efx_nic *efx, unsigned cmd, | ||
| 650 | const efx_dword_t *inbuf, size_t inlen, | ||
| 651 | efx_dword_t *outbuf, size_t outlen, | ||
| 652 | size_t *outlen_actual) | ||
| 653 | { | ||
| 654 | return _efx_mcdi_rpc(efx, cmd, inbuf, inlen, outbuf, outlen, | ||
| 655 | outlen_actual, true); | ||
| 523 | } | 656 | } |
| 524 | 657 | ||
| 525 | int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, | 658 | int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, |
| @@ -532,35 +665,19 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, | |||
| 532 | if (rc) | 665 | if (rc) |
| 533 | return rc; | 666 | return rc; |
| 534 | 667 | ||
| 668 | if (efx->mc_bist_for_other_fn) | ||
| 669 | return -ENETDOWN; | ||
| 670 | |||
| 535 | efx_mcdi_acquire_sync(mcdi); | 671 | efx_mcdi_acquire_sync(mcdi); |
| 536 | efx_mcdi_send_request(efx, cmd, inbuf, inlen); | 672 | efx_mcdi_send_request(efx, cmd, inbuf, inlen); |
| 537 | return 0; | 673 | return 0; |
| 538 | } | 674 | } |
| 539 | 675 | ||
| 540 | /** | 676 | static int _efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, |
| 541 | * efx_mcdi_rpc_async - Schedule an MCDI command to run asynchronously | 677 | const efx_dword_t *inbuf, size_t inlen, |
| 542 | * @efx: NIC through which to issue the command | 678 | size_t outlen, |
| 543 | * @cmd: Command type number | 679 | efx_mcdi_async_completer *complete, |
| 544 | * @inbuf: Command parameters | 680 | unsigned long cookie, bool quiet) |
| 545 | * @inlen: Length of command parameters, in bytes | ||
| 546 | * @outlen: Length to allocate for response buffer, in bytes | ||
| 547 | * @complete: Function to be called on completion or cancellation. | ||
| 548 | * @cookie: Arbitrary value to be passed to @complete. | ||
| 549 | * | ||
| 550 | * This function does not sleep and therefore may be called in atomic | ||
| 551 | * context. It will fail if event queues are disabled or if MCDI | ||
| 552 | * event completions have been disabled due to an error. | ||
| 553 | * | ||
| 554 | * If it succeeds, the @complete function will be called exactly once | ||
| 555 | * in atomic context, when one of the following occurs: | ||
| 556 | * (a) the completion event is received (in NAPI context) | ||
| 557 | * (b) event queues are disabled (in the process that disables them) | ||
| 558 | * (c) the request times-out (in timer context) | ||
| 559 | */ | ||
| 560 | int | ||
| 561 | efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | ||
| 562 | const efx_dword_t *inbuf, size_t inlen, size_t outlen, | ||
| 563 | efx_mcdi_async_completer *complete, unsigned long cookie) | ||
| 564 | { | 681 | { |
| 565 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 682 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| 566 | struct efx_mcdi_async_param *async; | 683 | struct efx_mcdi_async_param *async; |
| @@ -570,6 +687,9 @@ efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | |||
| 570 | if (rc) | 687 | if (rc) |
| 571 | return rc; | 688 | return rc; |
| 572 | 689 | ||
| 690 | if (efx->mc_bist_for_other_fn) | ||
| 691 | return -ENETDOWN; | ||
| 692 | |||
| 573 | async = kmalloc(sizeof(*async) + ALIGN(max(inlen, outlen), 4), | 693 | async = kmalloc(sizeof(*async) + ALIGN(max(inlen, outlen), 4), |
| 574 | GFP_ATOMIC); | 694 | GFP_ATOMIC); |
| 575 | if (!async) | 695 | if (!async) |
| @@ -578,6 +698,7 @@ efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | |||
| 578 | async->cmd = cmd; | 698 | async->cmd = cmd; |
| 579 | async->inlen = inlen; | 699 | async->inlen = inlen; |
| 580 | async->outlen = outlen; | 700 | async->outlen = outlen; |
| 701 | async->quiet = quiet; | ||
| 581 | async->complete = complete; | 702 | async->complete = complete; |
| 582 | async->cookie = cookie; | 703 | async->cookie = cookie; |
| 583 | memcpy(async + 1, inbuf, inlen); | 704 | memcpy(async + 1, inbuf, inlen); |
| @@ -606,71 +727,73 @@ efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | |||
| 606 | return rc; | 727 | return rc; |
| 607 | } | 728 | } |
| 608 | 729 | ||
| 730 | /** | ||
| 731 | * efx_mcdi_rpc_async - Schedule an MCDI command to run asynchronously | ||
| 732 | * @efx: NIC through which to issue the command | ||
| 733 | * @cmd: Command type number | ||
| 734 | * @inbuf: Command parameters | ||
| 735 | * @inlen: Length of command parameters, in bytes | ||
| 736 | * @outlen: Length to allocate for response buffer, in bytes | ||
| 737 | * @complete: Function to be called on completion or cancellation. | ||
| 738 | * @cookie: Arbitrary value to be passed to @complete. | ||
| 739 | * | ||
| 740 | * This function does not sleep and therefore may be called in atomic | ||
| 741 | * context. It will fail if event queues are disabled or if MCDI | ||
| 742 | * event completions have been disabled due to an error. | ||
| 743 | * | ||
| 744 | * If it succeeds, the @complete function will be called exactly once | ||
| 745 | * in atomic context, when one of the following occurs: | ||
| 746 | * (a) the completion event is received (in NAPI context) | ||
| 747 | * (b) event queues are disabled (in the process that disables them) | ||
| 748 | * (c) the request times-out (in timer context) | ||
| 749 | */ | ||
| 750 | int | ||
| 751 | efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | ||
| 752 | const efx_dword_t *inbuf, size_t inlen, size_t outlen, | ||
| 753 | efx_mcdi_async_completer *complete, unsigned long cookie) | ||
| 754 | { | ||
| 755 | return _efx_mcdi_rpc_async(efx, cmd, inbuf, inlen, outlen, complete, | ||
| 756 | cookie, false); | ||
| 757 | } | ||
| 758 | |||
| 759 | int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd, | ||
| 760 | const efx_dword_t *inbuf, size_t inlen, | ||
| 761 | size_t outlen, efx_mcdi_async_completer *complete, | ||
| 762 | unsigned long cookie) | ||
| 763 | { | ||
| 764 | return _efx_mcdi_rpc_async(efx, cmd, inbuf, inlen, outlen, complete, | ||
| 765 | cookie, true); | ||
| 766 | } | ||
| 767 | |||
| 609 | int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, | 768 | int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, |
| 610 | efx_dword_t *outbuf, size_t outlen, | 769 | efx_dword_t *outbuf, size_t outlen, |
| 611 | size_t *outlen_actual) | 770 | size_t *outlen_actual) |
| 612 | { | 771 | { |
| 613 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 772 | return _efx_mcdi_rpc_finish(efx, cmd, inlen, outbuf, outlen, |
| 614 | int rc; | 773 | outlen_actual, false); |
| 615 | 774 | } | |
| 616 | if (mcdi->mode == MCDI_MODE_POLL) | ||
| 617 | rc = efx_mcdi_poll(efx); | ||
| 618 | else | ||
| 619 | rc = efx_mcdi_await_completion(efx); | ||
| 620 | |||
| 621 | if (rc != 0) { | ||
| 622 | /* Close the race with efx_mcdi_ev_cpl() executing just too late | ||
| 623 | * and completing a request we've just cancelled, by ensuring | ||
| 624 | * that the seqno check therein fails. | ||
| 625 | */ | ||
| 626 | spin_lock_bh(&mcdi->iface_lock); | ||
| 627 | ++mcdi->seqno; | ||
| 628 | ++mcdi->credits; | ||
| 629 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 630 | |||
| 631 | netif_err(efx, hw, efx->net_dev, | ||
| 632 | "MC command 0x%x inlen %d mode %d timed out\n", | ||
| 633 | cmd, (int)inlen, mcdi->mode); | ||
| 634 | } else { | ||
| 635 | size_t hdr_len, data_len; | ||
| 636 | |||
| 637 | /* At the very least we need a memory barrier here to ensure | ||
| 638 | * we pick up changes from efx_mcdi_ev_cpl(). Protect against | ||
| 639 | * a spurious efx_mcdi_ev_cpl() running concurrently by | ||
| 640 | * acquiring the iface_lock. */ | ||
| 641 | spin_lock_bh(&mcdi->iface_lock); | ||
| 642 | rc = mcdi->resprc; | ||
| 643 | hdr_len = mcdi->resp_hdr_len; | ||
| 644 | data_len = mcdi->resp_data_len; | ||
| 645 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 646 | |||
| 647 | BUG_ON(rc > 0); | ||
| 648 | 775 | ||
| 649 | if (rc == 0) { | 776 | int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd, size_t inlen, |
| 650 | efx->type->mcdi_read_response(efx, outbuf, hdr_len, | 777 | efx_dword_t *outbuf, size_t outlen, |
| 651 | min(outlen, data_len)); | 778 | size_t *outlen_actual) |
| 652 | if (outlen_actual != NULL) | 779 | { |
| 653 | *outlen_actual = data_len; | 780 | return _efx_mcdi_rpc_finish(efx, cmd, inlen, outbuf, outlen, |
| 654 | } else if (cmd == MC_CMD_REBOOT && rc == -EIO) | 781 | outlen_actual, true); |
| 655 | ; /* Don't reset if MC_CMD_REBOOT returns EIO */ | 782 | } |
| 656 | else if (rc == -EIO || rc == -EINTR) { | ||
| 657 | netif_err(efx, hw, efx->net_dev, "MC fatal error %d\n", | ||
| 658 | -rc); | ||
| 659 | efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); | ||
| 660 | } else | ||
| 661 | netif_dbg(efx, hw, efx->net_dev, | ||
| 662 | "MC command 0x%x inlen %d failed rc=%d\n", | ||
| 663 | cmd, (int)inlen, -rc); | ||
| 664 | 783 | ||
| 665 | if (rc == -EIO || rc == -EINTR) { | 784 | void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd, |
| 666 | msleep(MCDI_STATUS_SLEEP_MS); | 785 | size_t inlen, efx_dword_t *outbuf, |
| 667 | efx_mcdi_poll_reboot(efx); | 786 | size_t outlen, int rc) |
| 668 | mcdi->new_epoch = true; | 787 | { |
| 669 | } | 788 | int code = 0, err_arg = 0; |
| 670 | } | ||
| 671 | 789 | ||
| 672 | efx_mcdi_release(mcdi); | 790 | if (outlen >= MC_CMD_ERR_CODE_OFST + 4) |
| 673 | return rc; | 791 | code = MCDI_DWORD(outbuf, ERR_CODE); |
| 792 | if (outlen >= MC_CMD_ERR_ARG_OFST + 4) | ||
| 793 | err_arg = MCDI_DWORD(outbuf, ERR_ARG); | ||
| 794 | netif_err(efx, hw, efx->net_dev, | ||
| 795 | "MC command 0x%x inlen %d failed rc=%d (raw=%d) arg=%d\n", | ||
| 796 | cmd, (int)inlen, rc, code, err_arg); | ||
| 674 | } | 797 | } |
| 675 | 798 | ||
| 676 | /* Switch to polled MCDI completions. This can be called in various | 799 | /* Switch to polled MCDI completions. This can be called in various |
| @@ -815,6 +938,30 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) | |||
| 815 | spin_unlock(&mcdi->iface_lock); | 938 | spin_unlock(&mcdi->iface_lock); |
| 816 | } | 939 | } |
| 817 | 940 | ||
| 941 | /* The MC is going down in to BIST mode. set the BIST flag to block | ||
| 942 | * new MCDI, cancel any outstanding MCDI and and schedule a BIST-type reset | ||
| 943 | * (which doesn't actually execute a reset, it waits for the controlling | ||
| 944 | * function to reset it). | ||
| 945 | */ | ||
| 946 | static void efx_mcdi_ev_bist(struct efx_nic *efx) | ||
| 947 | { | ||
| 948 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | ||
| 949 | |||
| 950 | spin_lock(&mcdi->iface_lock); | ||
| 951 | efx->mc_bist_for_other_fn = true; | ||
| 952 | if (efx_mcdi_complete_sync(mcdi)) { | ||
| 953 | if (mcdi->mode == MCDI_MODE_EVENTS) { | ||
| 954 | mcdi->resprc = -EIO; | ||
| 955 | mcdi->resp_hdr_len = 0; | ||
| 956 | mcdi->resp_data_len = 0; | ||
| 957 | ++mcdi->credits; | ||
| 958 | } | ||
| 959 | } | ||
| 960 | mcdi->new_epoch = true; | ||
| 961 | efx_schedule_reset(efx, RESET_TYPE_MC_BIST); | ||
| 962 | spin_unlock(&mcdi->iface_lock); | ||
| 963 | } | ||
| 964 | |||
| 818 | /* Called from falcon_process_eventq for MCDI events */ | 965 | /* Called from falcon_process_eventq for MCDI events */ |
| 819 | void efx_mcdi_process_event(struct efx_channel *channel, | 966 | void efx_mcdi_process_event(struct efx_channel *channel, |
| 820 | efx_qword_t *event) | 967 | efx_qword_t *event) |
| @@ -848,14 +995,18 @@ void efx_mcdi_process_event(struct efx_channel *channel, | |||
| 848 | efx_mcdi_sensor_event(efx, event); | 995 | efx_mcdi_sensor_event(efx, event); |
| 849 | break; | 996 | break; |
| 850 | case MCDI_EVENT_CODE_SCHEDERR: | 997 | case MCDI_EVENT_CODE_SCHEDERR: |
| 851 | netif_info(efx, hw, efx->net_dev, | 998 | netif_dbg(efx, hw, efx->net_dev, |
| 852 | "MC Scheduler error address=0x%x\n", data); | 999 | "MC Scheduler alert (0x%x)\n", data); |
| 853 | break; | 1000 | break; |
| 854 | case MCDI_EVENT_CODE_REBOOT: | 1001 | case MCDI_EVENT_CODE_REBOOT: |
| 855 | case MCDI_EVENT_CODE_MC_REBOOT: | 1002 | case MCDI_EVENT_CODE_MC_REBOOT: |
| 856 | netif_info(efx, hw, efx->net_dev, "MC Reboot\n"); | 1003 | netif_info(efx, hw, efx->net_dev, "MC Reboot\n"); |
| 857 | efx_mcdi_ev_death(efx, -EIO); | 1004 | efx_mcdi_ev_death(efx, -EIO); |
| 858 | break; | 1005 | break; |
| 1006 | case MCDI_EVENT_CODE_MC_BIST: | ||
| 1007 | netif_info(efx, hw, efx->net_dev, "MC entered BIST mode\n"); | ||
| 1008 | efx_mcdi_ev_bist(efx); | ||
| 1009 | break; | ||
| 859 | case MCDI_EVENT_CODE_MAC_STATS_DMA: | 1010 | case MCDI_EVENT_CODE_MAC_STATS_DMA: |
| 860 | /* MAC stats are gather lazily. We can ignore this. */ | 1011 | /* MAC stats are gather lazily. We can ignore this. */ |
| 861 | break; | 1012 | break; |
| @@ -1078,13 +1229,6 @@ int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq) | |||
| 1078 | 1229 | ||
| 1079 | rc = efx_mcdi_rpc(efx, MC_CMD_LOG_CTRL, inbuf, sizeof(inbuf), | 1230 | rc = efx_mcdi_rpc(efx, MC_CMD_LOG_CTRL, inbuf, sizeof(inbuf), |
| 1080 | NULL, 0, NULL); | 1231 | NULL, 0, NULL); |
| 1081 | if (rc) | ||
| 1082 | goto fail; | ||
| 1083 | |||
| 1084 | return 0; | ||
| 1085 | |||
| 1086 | fail: | ||
| 1087 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1088 | return rc; | 1232 | return rc; |
| 1089 | } | 1233 | } |
| 1090 | 1234 | ||
| @@ -1201,7 +1345,7 @@ fail1: | |||
| 1201 | static int efx_mcdi_read_assertion(struct efx_nic *efx) | 1345 | static int efx_mcdi_read_assertion(struct efx_nic *efx) |
| 1202 | { | 1346 | { |
| 1203 | MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN); | 1347 | MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN); |
| 1204 | MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN); | 1348 | MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN); |
| 1205 | unsigned int flags, index; | 1349 | unsigned int flags, index; |
| 1206 | const char *reason; | 1350 | const char *reason; |
| 1207 | size_t outlen; | 1351 | size_t outlen; |
| @@ -1216,13 +1360,17 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx) | |||
| 1216 | retry = 2; | 1360 | retry = 2; |
| 1217 | do { | 1361 | do { |
| 1218 | MCDI_SET_DWORD(inbuf, GET_ASSERTS_IN_CLEAR, 1); | 1362 | MCDI_SET_DWORD(inbuf, GET_ASSERTS_IN_CLEAR, 1); |
| 1219 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_ASSERTS, | 1363 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_ASSERTS, |
| 1220 | inbuf, MC_CMD_GET_ASSERTS_IN_LEN, | 1364 | inbuf, MC_CMD_GET_ASSERTS_IN_LEN, |
| 1221 | outbuf, sizeof(outbuf), &outlen); | 1365 | outbuf, sizeof(outbuf), &outlen); |
| 1222 | } while ((rc == -EINTR || rc == -EIO) && retry-- > 0); | 1366 | } while ((rc == -EINTR || rc == -EIO) && retry-- > 0); |
| 1223 | 1367 | ||
| 1224 | if (rc) | 1368 | if (rc) { |
| 1369 | efx_mcdi_display_error(efx, MC_CMD_GET_ASSERTS, | ||
| 1370 | MC_CMD_GET_ASSERTS_IN_LEN, outbuf, | ||
| 1371 | outlen, rc); | ||
| 1225 | return rc; | 1372 | return rc; |
| 1373 | } | ||
| 1226 | if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN) | 1374 | if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN) |
| 1227 | return -EIO; | 1375 | return -EIO; |
| 1228 | 1376 | ||
| @@ -1300,18 +1448,11 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) | |||
| 1300 | 1448 | ||
| 1301 | rc = efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf), | 1449 | rc = efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf), |
| 1302 | NULL, 0, NULL); | 1450 | NULL, 0, NULL); |
| 1303 | if (rc) | ||
| 1304 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", | ||
| 1305 | __func__, rc); | ||
| 1306 | } | 1451 | } |
| 1307 | 1452 | ||
| 1308 | static int efx_mcdi_reset_port(struct efx_nic *efx) | 1453 | static int efx_mcdi_reset_port(struct efx_nic *efx) |
| 1309 | { | 1454 | { |
| 1310 | int rc = efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL); | 1455 | return efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL); |
| 1311 | if (rc) | ||
| 1312 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", | ||
| 1313 | __func__, rc); | ||
| 1314 | return rc; | ||
| 1315 | } | 1456 | } |
| 1316 | 1457 | ||
| 1317 | static int efx_mcdi_reset_mc(struct efx_nic *efx) | 1458 | static int efx_mcdi_reset_mc(struct efx_nic *efx) |
| @@ -1328,7 +1469,6 @@ static int efx_mcdi_reset_mc(struct efx_nic *efx) | |||
| 1328 | return 0; | 1469 | return 0; |
| 1329 | if (rc == 0) | 1470 | if (rc == 0) |
| 1330 | rc = -EIO; | 1471 | rc = -EIO; |
| 1331 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1332 | return rc; | 1472 | return rc; |
| 1333 | } | 1473 | } |
| 1334 | 1474 | ||
| @@ -1430,13 +1570,6 @@ int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id) | |||
| 1430 | 1570 | ||
| 1431 | rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_REMOVE, inbuf, sizeof(inbuf), | 1571 | rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_REMOVE, inbuf, sizeof(inbuf), |
| 1432 | NULL, 0, NULL); | 1572 | NULL, 0, NULL); |
| 1433 | if (rc) | ||
| 1434 | goto fail; | ||
| 1435 | |||
| 1436 | return 0; | ||
| 1437 | |||
| 1438 | fail: | ||
| 1439 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1440 | return rc; | 1573 | return rc; |
| 1441 | } | 1574 | } |
| 1442 | 1575 | ||
| @@ -1477,13 +1610,6 @@ int efx_mcdi_wol_filter_reset(struct efx_nic *efx) | |||
| 1477 | int rc; | 1610 | int rc; |
| 1478 | 1611 | ||
| 1479 | rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_RESET, NULL, 0, NULL, 0, NULL); | 1612 | rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_RESET, NULL, 0, NULL, 0, NULL); |
| 1480 | if (rc) | ||
| 1481 | goto fail; | ||
| 1482 | |||
| 1483 | return 0; | ||
| 1484 | |||
| 1485 | fail: | ||
| 1486 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1487 | return rc; | 1613 | return rc; |
| 1488 | } | 1614 | } |
| 1489 | 1615 | ||
| @@ -1513,13 +1639,6 @@ static int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type) | |||
| 1513 | 1639 | ||
| 1514 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf), | 1640 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf), |
| 1515 | NULL, 0, NULL); | 1641 | NULL, 0, NULL); |
| 1516 | if (rc) | ||
| 1517 | goto fail; | ||
| 1518 | |||
| 1519 | return 0; | ||
| 1520 | |||
| 1521 | fail: | ||
| 1522 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1523 | return rc; | 1642 | return rc; |
| 1524 | } | 1643 | } |
| 1525 | 1644 | ||
| @@ -1539,14 +1658,10 @@ static int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type, | |||
| 1539 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf), | 1658 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf), |
| 1540 | outbuf, sizeof(outbuf), &outlen); | 1659 | outbuf, sizeof(outbuf), &outlen); |
| 1541 | if (rc) | 1660 | if (rc) |
| 1542 | goto fail; | 1661 | return rc; |
| 1543 | 1662 | ||
| 1544 | memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length); | 1663 | memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length); |
| 1545 | return 0; | 1664 | return 0; |
| 1546 | |||
| 1547 | fail: | ||
| 1548 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1549 | return rc; | ||
| 1550 | } | 1665 | } |
| 1551 | 1666 | ||
| 1552 | static int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, | 1667 | static int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, |
| @@ -1566,13 +1681,6 @@ static int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type, | |||
| 1566 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, | 1681 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, |
| 1567 | ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4), | 1682 | ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4), |
| 1568 | NULL, 0, NULL); | 1683 | NULL, 0, NULL); |
| 1569 | if (rc) | ||
| 1570 | goto fail; | ||
| 1571 | |||
| 1572 | return 0; | ||
| 1573 | |||
| 1574 | fail: | ||
| 1575 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1576 | return rc; | 1684 | return rc; |
| 1577 | } | 1685 | } |
| 1578 | 1686 | ||
| @@ -1590,13 +1698,6 @@ static int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type, | |||
| 1590 | 1698 | ||
| 1591 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf), | 1699 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf), |
| 1592 | NULL, 0, NULL); | 1700 | NULL, 0, NULL); |
| 1593 | if (rc) | ||
| 1594 | goto fail; | ||
| 1595 | |||
| 1596 | return 0; | ||
| 1597 | |||
| 1598 | fail: | ||
| 1599 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1600 | return rc; | 1701 | return rc; |
| 1601 | } | 1702 | } |
| 1602 | 1703 | ||
| @@ -1611,13 +1712,6 @@ static int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type) | |||
| 1611 | 1712 | ||
| 1612 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf), | 1713 | rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf), |
| 1613 | NULL, 0, NULL); | 1714 | NULL, 0, NULL); |
| 1614 | if (rc) | ||
| 1615 | goto fail; | ||
| 1616 | |||
| 1617 | return 0; | ||
| 1618 | |||
| 1619 | fail: | ||
| 1620 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 1621 | return rc; | 1715 | return rc; |
| 1622 | } | 1716 | } |
| 1623 | 1717 | ||
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 15816cacb548..171f5f58f84a 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h | |||
| @@ -116,12 +116,19 @@ void efx_mcdi_fini(struct efx_nic *efx); | |||
| 116 | int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf, | 116 | int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf, |
| 117 | size_t inlen, efx_dword_t *outbuf, size_t outlen, | 117 | size_t inlen, efx_dword_t *outbuf, size_t outlen, |
| 118 | size_t *outlen_actual); | 118 | size_t *outlen_actual); |
| 119 | int efx_mcdi_rpc_quiet(struct efx_nic *efx, unsigned cmd, | ||
| 120 | const efx_dword_t *inbuf, size_t inlen, | ||
| 121 | efx_dword_t *outbuf, size_t outlen, | ||
| 122 | size_t *outlen_actual); | ||
| 119 | 123 | ||
| 120 | int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, | 124 | int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, |
| 121 | const efx_dword_t *inbuf, size_t inlen); | 125 | const efx_dword_t *inbuf, size_t inlen); |
| 122 | int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, | 126 | int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, |
| 123 | efx_dword_t *outbuf, size_t outlen, | 127 | efx_dword_t *outbuf, size_t outlen, |
| 124 | size_t *outlen_actual); | 128 | size_t *outlen_actual); |
| 129 | int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd, | ||
| 130 | size_t inlen, efx_dword_t *outbuf, | ||
| 131 | size_t outlen, size_t *outlen_actual); | ||
| 125 | 132 | ||
| 126 | typedef void efx_mcdi_async_completer(struct efx_nic *efx, | 133 | typedef void efx_mcdi_async_completer(struct efx_nic *efx, |
| 127 | unsigned long cookie, int rc, | 134 | unsigned long cookie, int rc, |
| @@ -131,6 +138,15 @@ int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, | |||
| 131 | const efx_dword_t *inbuf, size_t inlen, size_t outlen, | 138 | const efx_dword_t *inbuf, size_t inlen, size_t outlen, |
| 132 | efx_mcdi_async_completer *complete, | 139 | efx_mcdi_async_completer *complete, |
| 133 | unsigned long cookie); | 140 | unsigned long cookie); |
| 141 | int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd, | ||
| 142 | const efx_dword_t *inbuf, size_t inlen, | ||
| 143 | size_t outlen, | ||
| 144 | efx_mcdi_async_completer *complete, | ||
| 145 | unsigned long cookie); | ||
| 146 | |||
| 147 | void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd, | ||
| 148 | size_t inlen, efx_dword_t *outbuf, | ||
| 149 | size_t outlen, int rc); | ||
| 134 | 150 | ||
| 135 | int efx_mcdi_poll_reboot(struct efx_nic *efx); | 151 | int efx_mcdi_poll_reboot(struct efx_nic *efx); |
| 136 | void efx_mcdi_mode_poll(struct efx_nic *efx); | 152 | void efx_mcdi_mode_poll(struct efx_nic *efx); |
| @@ -147,6 +163,8 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); | |||
| 147 | */ | 163 | */ |
| 148 | #define MCDI_DECLARE_BUF(_name, _len) \ | 164 | #define MCDI_DECLARE_BUF(_name, _len) \ |
| 149 | efx_dword_t _name[DIV_ROUND_UP(_len, 4)] | 165 | efx_dword_t _name[DIV_ROUND_UP(_len, 4)] |
| 166 | #define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len) \ | ||
| 167 | MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8)) | ||
| 150 | #define _MCDI_PTR(_buf, _offset) \ | 168 | #define _MCDI_PTR(_buf, _offset) \ |
| 151 | ((u8 *)(_buf) + (_offset)) | 169 | ((u8 *)(_buf) + (_offset)) |
| 152 | #define MCDI_PTR(_buf, _field) \ | 170 | #define MCDI_PTR(_buf, _field) \ |
| @@ -301,6 +319,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx); | |||
| 301 | #define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) | 319 | #define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) |
| 302 | void efx_mcdi_mac_start_stats(struct efx_nic *efx); | 320 | void efx_mcdi_mac_start_stats(struct efx_nic *efx); |
| 303 | void efx_mcdi_mac_stop_stats(struct efx_nic *efx); | 321 | void efx_mcdi_mac_stop_stats(struct efx_nic *efx); |
| 322 | void efx_mcdi_mac_pull_stats(struct efx_nic *efx); | ||
| 304 | bool efx_mcdi_mac_check_fault(struct efx_nic *efx); | 323 | bool efx_mcdi_mac_check_fault(struct efx_nic *efx); |
| 305 | enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason); | 324 | enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason); |
| 306 | int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method); | 325 | int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method); |
diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c index d72ad4fc3617..bc27d5b580f5 100644 --- a/drivers/net/ethernet/sfc/mcdi_mon.c +++ b/drivers/net/ethernet/sfc/mcdi_mon.c | |||
| @@ -24,6 +24,15 @@ enum efx_hwmon_type { | |||
| 24 | EFX_HWMON_IN, /* voltage */ | 24 | EFX_HWMON_IN, /* voltage */ |
| 25 | EFX_HWMON_CURR, /* current */ | 25 | EFX_HWMON_CURR, /* current */ |
| 26 | EFX_HWMON_POWER, /* power */ | 26 | EFX_HWMON_POWER, /* power */ |
| 27 | EFX_HWMON_TYPES_COUNT | ||
| 28 | }; | ||
| 29 | |||
| 30 | static const char *const efx_hwmon_unit[EFX_HWMON_TYPES_COUNT] = { | ||
| 31 | [EFX_HWMON_TEMP] = " degC", | ||
| 32 | [EFX_HWMON_COOL] = " rpm", /* though nonsense for a heatsink */ | ||
| 33 | [EFX_HWMON_IN] = " mV", | ||
| 34 | [EFX_HWMON_CURR] = " mA", | ||
| 35 | [EFX_HWMON_POWER] = " W", | ||
| 27 | }; | 36 | }; |
| 28 | 37 | ||
| 29 | static const struct { | 38 | static const struct { |
| @@ -33,13 +42,13 @@ static const struct { | |||
| 33 | } efx_mcdi_sensor_type[] = { | 42 | } efx_mcdi_sensor_type[] = { |
| 34 | #define SENSOR(name, label, hwmon_type, port) \ | 43 | #define SENSOR(name, label, hwmon_type, port) \ |
| 35 | [MC_CMD_SENSOR_##name] = { label, EFX_HWMON_ ## hwmon_type, port } | 44 | [MC_CMD_SENSOR_##name] = { label, EFX_HWMON_ ## hwmon_type, port } |
| 36 | SENSOR(CONTROLLER_TEMP, "Controller ext. temp.", TEMP, -1), | 45 | SENSOR(CONTROLLER_TEMP, "Controller board temp.", TEMP, -1), |
| 37 | SENSOR(PHY_COMMON_TEMP, "PHY temp.", TEMP, -1), | 46 | SENSOR(PHY_COMMON_TEMP, "PHY temp.", TEMP, -1), |
| 38 | SENSOR(CONTROLLER_COOLING, "Controller cooling", COOL, -1), | 47 | SENSOR(CONTROLLER_COOLING, "Controller heat sink", COOL, -1), |
| 39 | SENSOR(PHY0_TEMP, "PHY temp.", TEMP, 0), | 48 | SENSOR(PHY0_TEMP, "PHY temp.", TEMP, 0), |
| 40 | SENSOR(PHY0_COOLING, "PHY cooling", COOL, 0), | 49 | SENSOR(PHY0_COOLING, "PHY heat sink", COOL, 0), |
| 41 | SENSOR(PHY1_TEMP, "PHY temp.", TEMP, 1), | 50 | SENSOR(PHY1_TEMP, "PHY temp.", TEMP, 1), |
| 42 | SENSOR(PHY1_COOLING, "PHY cooling", COOL, 1), | 51 | SENSOR(PHY1_COOLING, "PHY heat sink", COOL, 1), |
| 43 | SENSOR(IN_1V0, "1.0V supply", IN, -1), | 52 | SENSOR(IN_1V0, "1.0V supply", IN, -1), |
| 44 | SENSOR(IN_1V2, "1.2V supply", IN, -1), | 53 | SENSOR(IN_1V2, "1.2V supply", IN, -1), |
| 45 | SENSOR(IN_1V8, "1.8V supply", IN, -1), | 54 | SENSOR(IN_1V8, "1.8V supply", IN, -1), |
| @@ -47,36 +56,42 @@ static const struct { | |||
| 47 | SENSOR(IN_3V3, "3.3V supply", IN, -1), | 56 | SENSOR(IN_3V3, "3.3V supply", IN, -1), |
| 48 | SENSOR(IN_12V0, "12.0V supply", IN, -1), | 57 | SENSOR(IN_12V0, "12.0V supply", IN, -1), |
| 49 | SENSOR(IN_1V2A, "1.2V analogue supply", IN, -1), | 58 | SENSOR(IN_1V2A, "1.2V analogue supply", IN, -1), |
| 50 | SENSOR(IN_VREF, "ref. voltage", IN, -1), | 59 | SENSOR(IN_VREF, "Ref. voltage", IN, -1), |
| 51 | SENSOR(OUT_VAOE, "AOE power supply", IN, -1), | 60 | SENSOR(OUT_VAOE, "AOE FPGA supply", IN, -1), |
| 52 | SENSOR(AOE_TEMP, "AOE temp.", TEMP, -1), | 61 | SENSOR(AOE_TEMP, "AOE FPGA temp.", TEMP, -1), |
| 53 | SENSOR(PSU_AOE_TEMP, "AOE PSU temp.", TEMP, -1), | 62 | SENSOR(PSU_AOE_TEMP, "AOE regulator temp.", TEMP, -1), |
| 54 | SENSOR(PSU_TEMP, "Controller PSU temp.", TEMP, -1), | 63 | SENSOR(PSU_TEMP, "Controller regulator temp.", |
| 55 | SENSOR(FAN_0, NULL, COOL, -1), | 64 | TEMP, -1), |
| 56 | SENSOR(FAN_1, NULL, COOL, -1), | 65 | SENSOR(FAN_0, "Fan 0", COOL, -1), |
| 57 | SENSOR(FAN_2, NULL, COOL, -1), | 66 | SENSOR(FAN_1, "Fan 1", COOL, -1), |
| 58 | SENSOR(FAN_3, NULL, COOL, -1), | 67 | SENSOR(FAN_2, "Fan 2", COOL, -1), |
| 59 | SENSOR(FAN_4, NULL, COOL, -1), | 68 | SENSOR(FAN_3, "Fan 3", COOL, -1), |
| 69 | SENSOR(FAN_4, "Fan 4", COOL, -1), | ||
| 60 | SENSOR(IN_VAOE, "AOE input supply", IN, -1), | 70 | SENSOR(IN_VAOE, "AOE input supply", IN, -1), |
| 61 | SENSOR(OUT_IAOE, "AOE output current", CURR, -1), | 71 | SENSOR(OUT_IAOE, "AOE output current", CURR, -1), |
| 62 | SENSOR(IN_IAOE, "AOE input current", CURR, -1), | 72 | SENSOR(IN_IAOE, "AOE input current", CURR, -1), |
| 63 | SENSOR(NIC_POWER, "Board power use", POWER, -1), | 73 | SENSOR(NIC_POWER, "Board power use", POWER, -1), |
| 64 | SENSOR(IN_0V9, "0.9V supply", IN, -1), | 74 | SENSOR(IN_0V9, "0.9V supply", IN, -1), |
| 65 | SENSOR(IN_I0V9, "0.9V input current", CURR, -1), | 75 | SENSOR(IN_I0V9, "0.9V supply current", CURR, -1), |
| 66 | SENSOR(IN_I1V2, "1.2V input current", CURR, -1), | 76 | SENSOR(IN_I1V2, "1.2V supply current", CURR, -1), |
| 67 | SENSOR(IN_0V9_ADC, "0.9V supply (at ADC)", IN, -1), | 77 | SENSOR(IN_0V9_ADC, "0.9V supply (ext. ADC)", IN, -1), |
| 68 | SENSOR(CONTROLLER_2_TEMP, "Controller ext. temp. 2", TEMP, -1), | 78 | SENSOR(CONTROLLER_2_TEMP, "Controller board temp. 2", TEMP, -1), |
| 69 | SENSOR(VREG_INTERNAL_TEMP, "Voltage regulator temp.", TEMP, -1), | 79 | SENSOR(VREG_INTERNAL_TEMP, "Regulator die temp.", TEMP, -1), |
| 70 | SENSOR(VREG_0V9_TEMP, "0.9V regulator temp.", TEMP, -1), | 80 | SENSOR(VREG_0V9_TEMP, "0.9V regulator temp.", TEMP, -1), |
| 71 | SENSOR(VREG_1V2_TEMP, "1.2V regulator temp.", TEMP, -1), | 81 | SENSOR(VREG_1V2_TEMP, "1.2V regulator temp.", TEMP, -1), |
| 72 | SENSOR(CONTROLLER_VPTAT, "Controller int. temp. raw", IN, -1), | 82 | SENSOR(CONTROLLER_VPTAT, |
| 73 | SENSOR(CONTROLLER_INTERNAL_TEMP, "Controller int. temp.", TEMP, -1), | 83 | "Controller PTAT voltage (int. ADC)", IN, -1), |
| 84 | SENSOR(CONTROLLER_INTERNAL_TEMP, | ||
| 85 | "Controller die temp. (int. ADC)", TEMP, -1), | ||
| 74 | SENSOR(CONTROLLER_VPTAT_EXTADC, | 86 | SENSOR(CONTROLLER_VPTAT_EXTADC, |
| 75 | "Controller int. temp. raw (at ADC)", IN, -1), | 87 | "Controller PTAT voltage (ext. ADC)", IN, -1), |
| 76 | SENSOR(CONTROLLER_INTERNAL_TEMP_EXTADC, | 88 | SENSOR(CONTROLLER_INTERNAL_TEMP_EXTADC, |
| 77 | "Controller int. temp. (via ADC)", TEMP, -1), | 89 | "Controller die temp. (ext. ADC)", TEMP, -1), |
| 78 | SENSOR(AMBIENT_TEMP, "Ambient temp.", TEMP, -1), | 90 | SENSOR(AMBIENT_TEMP, "Ambient temp.", TEMP, -1), |
| 79 | SENSOR(AIRFLOW, "Air flow raw", IN, -1), | 91 | SENSOR(AIRFLOW, "Air flow raw", IN, -1), |
| 92 | SENSOR(VDD08D_VSS08D_CSR, "0.9V die (int. ADC)", IN, -1), | ||
| 93 | SENSOR(VDD08D_VSS08D_CSR_EXTADC, "0.9V die (ext. ADC)", IN, -1), | ||
| 94 | SENSOR(HOTPOINT_TEMP, "Controller board temp. (hotpoint)", TEMP, -1), | ||
| 80 | #undef SENSOR | 95 | #undef SENSOR |
| 81 | }; | 96 | }; |
| 82 | 97 | ||
| @@ -91,7 +106,8 @@ static const char *const sensor_status_names[] = { | |||
| 91 | void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) | 106 | void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) |
| 92 | { | 107 | { |
| 93 | unsigned int type, state, value; | 108 | unsigned int type, state, value; |
| 94 | const char *name = NULL, *state_txt; | 109 | enum efx_hwmon_type hwmon_type = EFX_HWMON_UNKNOWN; |
| 110 | const char *name = NULL, *state_txt, *unit; | ||
| 95 | 111 | ||
| 96 | type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); | 112 | type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); |
| 97 | state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); | 113 | state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); |
| @@ -99,16 +115,22 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) | |||
| 99 | 115 | ||
| 100 | /* Deal gracefully with the board having more drivers than we | 116 | /* Deal gracefully with the board having more drivers than we |
| 101 | * know about, but do not expect new sensor states. */ | 117 | * know about, but do not expect new sensor states. */ |
| 102 | if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) | 118 | if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) { |
| 103 | name = efx_mcdi_sensor_type[type].label; | 119 | name = efx_mcdi_sensor_type[type].label; |
| 120 | hwmon_type = efx_mcdi_sensor_type[type].hwmon_type; | ||
| 121 | } | ||
| 104 | if (!name) | 122 | if (!name) |
| 105 | name = "No sensor name available"; | 123 | name = "No sensor name available"; |
| 106 | EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); | 124 | EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); |
| 107 | state_txt = sensor_status_names[state]; | 125 | state_txt = sensor_status_names[state]; |
| 126 | EFX_BUG_ON_PARANOID(hwmon_type >= EFX_HWMON_TYPES_COUNT); | ||
| 127 | unit = efx_hwmon_unit[hwmon_type]; | ||
| 128 | if (!unit) | ||
| 129 | unit = ""; | ||
| 108 | 130 | ||
| 109 | netif_err(efx, hw, efx->net_dev, | 131 | netif_err(efx, hw, efx->net_dev, |
| 110 | "Sensor %d (%s) reports condition '%s' for raw value %d\n", | 132 | "Sensor %d (%s) reports condition '%s' for value %d%s\n", |
| 111 | type, name, state_txt, value); | 133 | type, name, state_txt, value, unit); |
| 112 | } | 134 | } |
| 113 | 135 | ||
| 114 | #ifdef CONFIG_SFC_MCDI_MON | 136 | #ifdef CONFIG_SFC_MCDI_MON |
diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index e0a63ddb7a6c..a707fb5ef14c 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h | |||
| @@ -224,6 +224,8 @@ | |||
| 224 | #define MC_CMD_ERR_MAC_EXIST 0x1009 | 224 | #define MC_CMD_ERR_MAC_EXIST 0x1009 |
| 225 | /* Slave core not present */ | 225 | /* Slave core not present */ |
| 226 | #define MC_CMD_ERR_SLAVE_NOT_PRESENT 0x100a | 226 | #define MC_CMD_ERR_SLAVE_NOT_PRESENT 0x100a |
| 227 | /* The datapath is disabled. */ | ||
| 228 | #define MC_CMD_ERR_DATAPATH_DISABLED 0x100b | ||
| 227 | 229 | ||
| 228 | #define MC_CMD_ERR_CODE_OFST 0 | 230 | #define MC_CMD_ERR_CODE_OFST 0 |
| 229 | 231 | ||
| @@ -390,6 +392,8 @@ | |||
| 390 | * AOE_ERR_DATA) | 392 | * AOE_ERR_DATA) |
| 391 | */ | 393 | */ |
| 392 | #define MCDI_EVENT_AOE_BYTEBLASTER 0x9 | 394 | #define MCDI_EVENT_AOE_BYTEBLASTER 0x9 |
| 395 | /* enum: DDR ECC status update */ | ||
| 396 | #define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa | ||
| 393 | #define MCDI_EVENT_AOE_ERR_DATA_LBN 8 | 397 | #define MCDI_EVENT_AOE_ERR_DATA_LBN 8 |
| 394 | #define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8 | 398 | #define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8 |
| 395 | #define MCDI_EVENT_RX_ERR_RXQ_LBN 0 | 399 | #define MCDI_EVENT_RX_ERR_RXQ_LBN 0 |
| @@ -462,6 +466,10 @@ | |||
| 462 | #define MCDI_EVENT_CODE_ECC_CORR_ERR 0x17 | 466 | #define MCDI_EVENT_CODE_ECC_CORR_ERR 0x17 |
| 463 | /* enum: the MC has detected an uncorrectable error */ | 467 | /* enum: the MC has detected an uncorrectable error */ |
| 464 | #define MCDI_EVENT_CODE_ECC_FATAL_ERR 0x18 | 468 | #define MCDI_EVENT_CODE_ECC_FATAL_ERR 0x18 |
| 469 | /* enum: The MC has entered offline BIST mode */ | ||
| 470 | #define MCDI_EVENT_CODE_MC_BIST 0x19 | ||
| 471 | /* enum: PTP tick event providing current NIC time */ | ||
| 472 | #define MCDI_EVENT_CODE_PTP_TIME 0x1a | ||
| 465 | /* enum: Artificial event generated by host and posted via MC for test | 473 | /* enum: Artificial event generated by host and posted via MC for test |
| 466 | * purposes. | 474 | * purposes. |
| 467 | */ | 475 | */ |
| @@ -481,15 +489,32 @@ | |||
| 481 | #define MCDI_EVENT_TX_ERR_DATA_OFST 0 | 489 | #define MCDI_EVENT_TX_ERR_DATA_OFST 0 |
| 482 | #define MCDI_EVENT_TX_ERR_DATA_LBN 0 | 490 | #define MCDI_EVENT_TX_ERR_DATA_LBN 0 |
| 483 | #define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 | 491 | #define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 |
| 484 | /* Seconds field of timestamp */ | 492 | /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the seconds field of |
| 493 | * timestamp | ||
| 494 | */ | ||
| 485 | #define MCDI_EVENT_PTP_SECONDS_OFST 0 | 495 | #define MCDI_EVENT_PTP_SECONDS_OFST 0 |
| 486 | #define MCDI_EVENT_PTP_SECONDS_LBN 0 | 496 | #define MCDI_EVENT_PTP_SECONDS_LBN 0 |
| 487 | #define MCDI_EVENT_PTP_SECONDS_WIDTH 32 | 497 | #define MCDI_EVENT_PTP_SECONDS_WIDTH 32 |
| 488 | /* Nanoseconds field of timestamp */ | 498 | /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the major field of |
| 499 | * timestamp | ||
| 500 | */ | ||
| 501 | #define MCDI_EVENT_PTP_MAJOR_OFST 0 | ||
| 502 | #define MCDI_EVENT_PTP_MAJOR_LBN 0 | ||
| 503 | #define MCDI_EVENT_PTP_MAJOR_WIDTH 32 | ||
| 504 | /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the nanoseconds field | ||
| 505 | * of timestamp | ||
| 506 | */ | ||
| 489 | #define MCDI_EVENT_PTP_NANOSECONDS_OFST 0 | 507 | #define MCDI_EVENT_PTP_NANOSECONDS_OFST 0 |
| 490 | #define MCDI_EVENT_PTP_NANOSECONDS_LBN 0 | 508 | #define MCDI_EVENT_PTP_NANOSECONDS_LBN 0 |
| 491 | #define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32 | 509 | #define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32 |
| 492 | /* Lowest four bytes of sourceUUID from PTP packet */ | 510 | /* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the minor field of |
| 511 | * timestamp | ||
| 512 | */ | ||
| 513 | #define MCDI_EVENT_PTP_MINOR_OFST 0 | ||
| 514 | #define MCDI_EVENT_PTP_MINOR_LBN 0 | ||
| 515 | #define MCDI_EVENT_PTP_MINOR_WIDTH 32 | ||
| 516 | /* For CODE_PTP_RX events, the lowest four bytes of sourceUUID from PTP packet | ||
| 517 | */ | ||
| 493 | #define MCDI_EVENT_PTP_UUID_OFST 0 | 518 | #define MCDI_EVENT_PTP_UUID_OFST 0 |
| 494 | #define MCDI_EVENT_PTP_UUID_LBN 0 | 519 | #define MCDI_EVENT_PTP_UUID_LBN 0 |
| 495 | #define MCDI_EVENT_PTP_UUID_WIDTH 32 | 520 | #define MCDI_EVENT_PTP_UUID_WIDTH 32 |
| @@ -505,6 +530,13 @@ | |||
| 505 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_OFST 0 | 530 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_OFST 0 |
| 506 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_LBN 0 | 531 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_LBN 0 |
| 507 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_WIDTH 32 | 532 | #define MCDI_EVENT_ECC_FATAL_ERR_DATA_WIDTH 32 |
| 533 | /* For CODE_PTP_TIME events, the major value of the PTP clock */ | ||
| 534 | #define MCDI_EVENT_PTP_TIME_MAJOR_OFST 0 | ||
| 535 | #define MCDI_EVENT_PTP_TIME_MAJOR_LBN 0 | ||
| 536 | #define MCDI_EVENT_PTP_TIME_MAJOR_WIDTH 32 | ||
| 537 | /* For CODE_PTP_TIME events, bits 19-26 of the minor value of the PTP clock */ | ||
| 538 | #define MCDI_EVENT_PTP_TIME_MINOR_26_19_LBN 36 | ||
| 539 | #define MCDI_EVENT_PTP_TIME_MINOR_26_19_WIDTH 8 | ||
| 508 | 540 | ||
| 509 | /* FCDI_EVENT structuredef */ | 541 | /* FCDI_EVENT structuredef */ |
| 510 | #define FCDI_EVENT_LEN 8 | 542 | #define FCDI_EVENT_LEN 8 |
| @@ -545,8 +577,10 @@ | |||
| 545 | #define FCDI_EVENT_CODE_TIMED_READ 0x5 | 577 | #define FCDI_EVENT_CODE_TIMED_READ 0x5 |
| 546 | /* enum: One or more PPS IN events */ | 578 | /* enum: One or more PPS IN events */ |
| 547 | #define FCDI_EVENT_CODE_PPS_IN 0x6 | 579 | #define FCDI_EVENT_CODE_PPS_IN 0x6 |
| 548 | /* enum: One or more PPS OUT events */ | 580 | /* enum: Tick event from PTP clock */ |
| 549 | #define FCDI_EVENT_CODE_PPS_OUT 0x7 | 581 | #define FCDI_EVENT_CODE_PTP_TICK 0x7 |
| 582 | /* enum: ECC error counters */ | ||
| 583 | #define FCDI_EVENT_CODE_DDR_ECC_STATUS 0x8 | ||
| 550 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_OFST 0 | 584 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_OFST 0 |
| 551 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LBN 0 | 585 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LBN 0 |
| 552 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_WIDTH 32 | 586 | #define FCDI_EVENT_ASSERT_INSTR_ADDRESS_WIDTH 32 |
| @@ -560,14 +594,21 @@ | |||
| 560 | #define FCDI_EVENT_LINK_STATE_DATA_OFST 0 | 594 | #define FCDI_EVENT_LINK_STATE_DATA_OFST 0 |
| 561 | #define FCDI_EVENT_LINK_STATE_DATA_LBN 0 | 595 | #define FCDI_EVENT_LINK_STATE_DATA_LBN 0 |
| 562 | #define FCDI_EVENT_LINK_STATE_DATA_WIDTH 32 | 596 | #define FCDI_EVENT_LINK_STATE_DATA_WIDTH 32 |
| 563 | #define FCDI_EVENT_PPS_COUNT_OFST 0 | 597 | #define FCDI_EVENT_DDR_ECC_STATUS_BANK_ID_LBN 36 |
| 564 | #define FCDI_EVENT_PPS_COUNT_LBN 0 | 598 | #define FCDI_EVENT_DDR_ECC_STATUS_BANK_ID_WIDTH 8 |
| 565 | #define FCDI_EVENT_PPS_COUNT_WIDTH 32 | 599 | #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_OFST 0 |
| 566 | 600 | #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_LBN 0 | |
| 567 | /* FCDI_EXTENDED_EVENT structuredef */ | 601 | #define FCDI_EVENT_DDR_ECC_STATUS_STATUS_WIDTH 32 |
| 568 | #define FCDI_EXTENDED_EVENT_LENMIN 16 | 602 | |
| 569 | #define FCDI_EXTENDED_EVENT_LENMAX 248 | 603 | /* FCDI_EXTENDED_EVENT_PPS structuredef: Extended FCDI event to send PPS events |
| 570 | #define FCDI_EXTENDED_EVENT_LEN(num) (8+8*(num)) | 604 | * to the MC. Note that this structure | is overlayed over a normal FCDI event |
| 605 | * such that bits 32-63 containing | event code, level, source etc remain the | ||
| 606 | * same. In this case the data | field of the header is defined to be the | ||
| 607 | * number of timestamps | ||
| 608 | */ | ||
| 609 | #define FCDI_EXTENDED_EVENT_PPS_LENMIN 16 | ||
| 610 | #define FCDI_EXTENDED_EVENT_PPS_LENMAX 248 | ||
| 611 | #define FCDI_EXTENDED_EVENT_PPS_LEN(num) (8+8*(num)) | ||
| 571 | /* Number of timestamps following */ | 612 | /* Number of timestamps following */ |
| 572 | #define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0 | 613 | #define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0 |
| 573 | #define FCDI_EXTENDED_EVENT_PPS_COUNT_LBN 0 | 614 | #define FCDI_EXTENDED_EVENT_PPS_COUNT_LBN 0 |
| @@ -581,14 +622,14 @@ | |||
| 581 | #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LBN 96 | 622 | #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LBN 96 |
| 582 | #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_WIDTH 32 | 623 | #define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_WIDTH 32 |
| 583 | /* Timestamp records comprising the event */ | 624 | /* Timestamp records comprising the event */ |
| 584 | #define FCDI_EXTENDED_EVENT_PPS_TIME_OFST 8 | 625 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_OFST 8 |
| 585 | #define FCDI_EXTENDED_EVENT_PPS_TIME_LEN 8 | 626 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LEN 8 |
| 586 | #define FCDI_EXTENDED_EVENT_PPS_TIME_LO_OFST 8 | 627 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LO_OFST 8 |
| 587 | #define FCDI_EXTENDED_EVENT_PPS_TIME_HI_OFST 12 | 628 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_HI_OFST 12 |
| 588 | #define FCDI_EXTENDED_EVENT_PPS_TIME_MINNUM 1 | 629 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_MINNUM 1 |
| 589 | #define FCDI_EXTENDED_EVENT_PPS_TIME_MAXNUM 30 | 630 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_MAXNUM 30 |
| 590 | #define FCDI_EXTENDED_EVENT_PPS_TIME_LBN 64 | 631 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LBN 64 |
| 591 | #define FCDI_EXTENDED_EVENT_PPS_TIME_WIDTH 64 | 632 | #define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_WIDTH 64 |
| 592 | 633 | ||
| 593 | 634 | ||
| 594 | /***********************************/ | 635 | /***********************************/ |
| @@ -642,6 +683,10 @@ | |||
| 642 | #define MC_CMD_COPYCODE_IN_LEN 16 | 683 | #define MC_CMD_COPYCODE_IN_LEN 16 |
| 643 | /* Source address */ | 684 | /* Source address */ |
| 644 | #define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 | 685 | #define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 |
| 686 | /* enum: The main image should be entered via a copy of a single word from and | ||
| 687 | * to this address when none of the other magic behaviours are required. | ||
| 688 | */ | ||
| 689 | #define MC_CMD_COPYCODE_HUNT_NO_MAGIC_ADDR 0x10000 | ||
| 645 | /* enum: Entering the main image via a copy of a single word from and to this | 690 | /* enum: Entering the main image via a copy of a single word from and to this |
| 646 | * address indicates that it should not attempt to start the datapath CPUs. | 691 | * address indicates that it should not attempt to start the datapath CPUs. |
| 647 | * This is useful for certain soft rebooting scenarios. (Huntington only) | 692 | * This is useful for certain soft rebooting scenarios. (Huntington only) |
| @@ -872,8 +917,28 @@ | |||
| 872 | #define MC_CMD_PTP_OP_RST_CLK 0x14 | 917 | #define MC_CMD_PTP_OP_RST_CLK 0x14 |
| 873 | /* enum: Enable the forwarding of PPS events to the host */ | 918 | /* enum: Enable the forwarding of PPS events to the host */ |
| 874 | #define MC_CMD_PTP_OP_PPS_ENABLE 0x15 | 919 | #define MC_CMD_PTP_OP_PPS_ENABLE 0x15 |
| 920 | /* enum: Get the time format used by this NIC for PTP operations */ | ||
| 921 | #define MC_CMD_PTP_OP_GET_TIME_FORMAT 0x16 | ||
| 922 | /* enum: Get the clock attributes. NOTE- extended version of | ||
| 923 | * MC_CMD_PTP_OP_GET_TIME_FORMAT | ||
| 924 | */ | ||
| 925 | #define MC_CMD_PTP_OP_GET_ATTRIBUTES 0x16 | ||
| 926 | /* enum: Get corrections that should be applied to the various different | ||
| 927 | * timestamps | ||
| 928 | */ | ||
| 929 | #define MC_CMD_PTP_OP_GET_TIMESTAMP_CORRECTIONS 0x17 | ||
| 930 | /* enum: Subscribe to receive periodic time events indicating the current NIC | ||
| 931 | * time | ||
| 932 | */ | ||
| 933 | #define MC_CMD_PTP_OP_TIME_EVENT_SUBSCRIBE 0x18 | ||
| 934 | /* enum: Unsubscribe to stop receiving time events */ | ||
| 935 | #define MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE 0x19 | ||
| 936 | /* enum: PPS based manfacturing tests. Requires PPS output to be looped to PPS | ||
| 937 | * input on the same NIC. | ||
| 938 | */ | ||
| 939 | #define MC_CMD_PTP_OP_MANFTEST_PPS 0x1a | ||
| 875 | /* enum: Above this for future use. */ | 940 | /* enum: Above this for future use. */ |
| 876 | #define MC_CMD_PTP_OP_MAX 0x16 | 941 | #define MC_CMD_PTP_OP_MAX 0x1b |
| 877 | 942 | ||
| 878 | /* MC_CMD_PTP_IN_ENABLE msgrequest */ | 943 | /* MC_CMD_PTP_IN_ENABLE msgrequest */ |
| 879 | #define MC_CMD_PTP_IN_ENABLE_LEN 16 | 944 | #define MC_CMD_PTP_IN_ENABLE_LEN 16 |
| @@ -938,8 +1003,12 @@ | |||
| 938 | #define MC_CMD_PTP_IN_ADJUST_BITS 0x28 | 1003 | #define MC_CMD_PTP_IN_ADJUST_BITS 0x28 |
| 939 | /* Time adjustment in seconds */ | 1004 | /* Time adjustment in seconds */ |
| 940 | #define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16 | 1005 | #define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16 |
| 1006 | /* Time adjustment major value */ | ||
| 1007 | #define MC_CMD_PTP_IN_ADJUST_MAJOR_OFST 16 | ||
| 941 | /* Time adjustment in nanoseconds */ | 1008 | /* Time adjustment in nanoseconds */ |
| 942 | #define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20 | 1009 | #define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20 |
| 1010 | /* Time adjustment minor value */ | ||
| 1011 | #define MC_CMD_PTP_IN_ADJUST_MINOR_OFST 20 | ||
| 943 | 1012 | ||
| 944 | /* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */ | 1013 | /* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */ |
| 945 | #define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20 | 1014 | #define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20 |
| @@ -1005,8 +1074,12 @@ | |||
| 1005 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | 1074 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ |
| 1006 | /* Time adjustment in seconds */ | 1075 | /* Time adjustment in seconds */ |
| 1007 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_OFST 8 | 1076 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_OFST 8 |
| 1077 | /* Time adjustment major value */ | ||
| 1078 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MAJOR_OFST 8 | ||
| 1008 | /* Time adjustment in nanoseconds */ | 1079 | /* Time adjustment in nanoseconds */ |
| 1009 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_OFST 12 | 1080 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_OFST 12 |
| 1081 | /* Time adjustment minor value */ | ||
| 1082 | #define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MINOR_OFST 12 | ||
| 1010 | 1083 | ||
| 1011 | /* MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST msgrequest */ | 1084 | /* MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST msgrequest */ |
| 1012 | #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_LEN 16 | 1085 | #define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_LEN 16 |
| @@ -1078,9 +1151,51 @@ | |||
| 1078 | #define MC_CMD_PTP_ENABLE_PPS 0x0 | 1151 | #define MC_CMD_PTP_ENABLE_PPS 0x0 |
| 1079 | /* enum: Disable */ | 1152 | /* enum: Disable */ |
| 1080 | #define MC_CMD_PTP_DISABLE_PPS 0x1 | 1153 | #define MC_CMD_PTP_DISABLE_PPS 0x1 |
| 1081 | /* Queueid to send events back */ | 1154 | /* Queue id to send events back */ |
| 1082 | #define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_OFST 8 | 1155 | #define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_OFST 8 |
| 1083 | 1156 | ||
| 1157 | /* MC_CMD_PTP_IN_GET_TIME_FORMAT msgrequest */ | ||
| 1158 | #define MC_CMD_PTP_IN_GET_TIME_FORMAT_LEN 8 | ||
| 1159 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1160 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1161 | |||
| 1162 | /* MC_CMD_PTP_IN_GET_ATTRIBUTES msgrequest */ | ||
| 1163 | #define MC_CMD_PTP_IN_GET_ATTRIBUTES_LEN 8 | ||
| 1164 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1165 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1166 | |||
| 1167 | /* MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS msgrequest */ | ||
| 1168 | #define MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN 8 | ||
| 1169 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1170 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1171 | |||
| 1172 | /* MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE msgrequest */ | ||
| 1173 | #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN 12 | ||
| 1174 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1175 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1176 | /* Event queue to send PTP time events to */ | ||
| 1177 | #define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_OFST 8 | ||
| 1178 | |||
| 1179 | /* MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE msgrequest */ | ||
| 1180 | #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN 16 | ||
| 1181 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1182 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1183 | /* Unsubscribe options */ | ||
| 1184 | #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL_OFST 8 | ||
| 1185 | /* enum: Unsubscribe a single queue */ | ||
| 1186 | #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE 0x0 | ||
| 1187 | /* enum: Unsubscribe all queues */ | ||
| 1188 | #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_ALL 0x1 | ||
| 1189 | /* Event queue ID */ | ||
| 1190 | #define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE_OFST 12 | ||
| 1191 | |||
| 1192 | /* MC_CMD_PTP_IN_MANFTEST_PPS msgrequest */ | ||
| 1193 | #define MC_CMD_PTP_IN_MANFTEST_PPS_LEN 12 | ||
| 1194 | /* MC_CMD_PTP_IN_CMD_OFST 0 */ | ||
| 1195 | /* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ | ||
| 1196 | /* 1 to enable PPS test mode, 0 to disable and return result. */ | ||
| 1197 | #define MC_CMD_PTP_IN_MANFTEST_PPS_TEST_ENABLE_OFST 8 | ||
| 1198 | |||
| 1084 | /* MC_CMD_PTP_OUT msgresponse */ | 1199 | /* MC_CMD_PTP_OUT msgresponse */ |
| 1085 | #define MC_CMD_PTP_OUT_LEN 0 | 1200 | #define MC_CMD_PTP_OUT_LEN 0 |
| 1086 | 1201 | ||
| @@ -1088,15 +1203,29 @@ | |||
| 1088 | #define MC_CMD_PTP_OUT_TRANSMIT_LEN 8 | 1203 | #define MC_CMD_PTP_OUT_TRANSMIT_LEN 8 |
| 1089 | /* Value of seconds timestamp */ | 1204 | /* Value of seconds timestamp */ |
| 1090 | #define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0 | 1205 | #define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0 |
| 1206 | /* Timestamp major value */ | ||
| 1207 | #define MC_CMD_PTP_OUT_TRANSMIT_MAJOR_OFST 0 | ||
| 1091 | /* Value of nanoseconds timestamp */ | 1208 | /* Value of nanoseconds timestamp */ |
| 1092 | #define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4 | 1209 | #define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4 |
| 1210 | /* Timestamp minor value */ | ||
| 1211 | #define MC_CMD_PTP_OUT_TRANSMIT_MINOR_OFST 4 | ||
| 1212 | |||
| 1213 | /* MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE msgresponse */ | ||
| 1214 | #define MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE_LEN 0 | ||
| 1215 | |||
| 1216 | /* MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE msgresponse */ | ||
| 1217 | #define MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE_LEN 0 | ||
| 1093 | 1218 | ||
| 1094 | /* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */ | 1219 | /* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */ |
| 1095 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8 | 1220 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8 |
| 1096 | /* Value of seconds timestamp */ | 1221 | /* Value of seconds timestamp */ |
| 1097 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0 | 1222 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0 |
| 1223 | /* Timestamp major value */ | ||
| 1224 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_MAJOR_OFST 0 | ||
| 1098 | /* Value of nanoseconds timestamp */ | 1225 | /* Value of nanoseconds timestamp */ |
| 1099 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4 | 1226 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4 |
| 1227 | /* Timestamp minor value */ | ||
| 1228 | #define MC_CMD_PTP_OUT_READ_NIC_TIME_MINOR_OFST 4 | ||
| 1100 | 1229 | ||
| 1101 | /* MC_CMD_PTP_OUT_STATUS msgresponse */ | 1230 | /* MC_CMD_PTP_OUT_STATUS msgresponse */ |
| 1102 | #define MC_CMD_PTP_OUT_STATUS_LEN 64 | 1231 | #define MC_CMD_PTP_OUT_STATUS_LEN 64 |
| @@ -1116,21 +1245,21 @@ | |||
| 1116 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24 | 1245 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24 |
| 1117 | /* Number of PPS bad periods */ | 1246 | /* Number of PPS bad periods */ |
| 1118 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28 | 1247 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28 |
| 1119 | /* Minimum period of PPS pulse */ | 1248 | /* Minimum period of PPS pulse in nanoseconds */ |
| 1120 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32 | 1249 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32 |
| 1121 | /* Maximum period of PPS pulse */ | 1250 | /* Maximum period of PPS pulse in nanoseconds */ |
| 1122 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36 | 1251 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36 |
| 1123 | /* Last period of PPS pulse */ | 1252 | /* Last period of PPS pulse in nanoseconds */ |
| 1124 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40 | 1253 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40 |
| 1125 | /* Mean period of PPS pulse */ | 1254 | /* Mean period of PPS pulse in nanoseconds */ |
| 1126 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44 | 1255 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44 |
| 1127 | /* Minimum offset of PPS pulse (signed) */ | 1256 | /* Minimum offset of PPS pulse in nanoseconds (signed) */ |
| 1128 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48 | 1257 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48 |
| 1129 | /* Maximum offset of PPS pulse (signed) */ | 1258 | /* Maximum offset of PPS pulse in nanoseconds (signed) */ |
| 1130 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52 | 1259 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52 |
| 1131 | /* Last offset of PPS pulse (signed) */ | 1260 | /* Last offset of PPS pulse in nanoseconds (signed) */ |
| 1132 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56 | 1261 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56 |
| 1133 | /* Mean offset of PPS pulse (signed) */ | 1262 | /* Mean offset of PPS pulse in nanoseconds (signed) */ |
| 1134 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60 | 1263 | #define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60 |
| 1135 | 1264 | ||
| 1136 | /* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */ | 1265 | /* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */ |
| @@ -1146,8 +1275,12 @@ | |||
| 1146 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0 | 1275 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0 |
| 1147 | /* Value of seconds timestamp */ | 1276 | /* Value of seconds timestamp */ |
| 1148 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4 | 1277 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4 |
| 1278 | /* Timestamp major value */ | ||
| 1279 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_MAJOR_OFST 4 | ||
| 1149 | /* Value of nanoseconds timestamp */ | 1280 | /* Value of nanoseconds timestamp */ |
| 1150 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8 | 1281 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8 |
| 1282 | /* Timestamp minor value */ | ||
| 1283 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_MINOR_OFST 8 | ||
| 1151 | /* Host time immediately after NIC's hardware clock read */ | 1284 | /* Host time immediately after NIC's hardware clock read */ |
| 1152 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12 | 1285 | #define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12 |
| 1153 | /* Number of nanoseconds waited after reading NIC's hardware clock */ | 1286 | /* Number of nanoseconds waited after reading NIC's hardware clock */ |
| @@ -1177,6 +1310,16 @@ | |||
| 1177 | #define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 | 1310 | #define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 |
| 1178 | /* enum: Timestamp trigger GPIO not working */ | 1311 | /* enum: Timestamp trigger GPIO not working */ |
| 1179 | #define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 | 1312 | #define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 |
| 1313 | /* enum: Insufficient PPS events to perform checks */ | ||
| 1314 | #define MC_CMD_PTP_MANF_PPS_ENOUGH 0xa | ||
| 1315 | /* enum: PPS time event period not sufficiently close to 1s. */ | ||
| 1316 | #define MC_CMD_PTP_MANF_PPS_PERIOD 0xb | ||
| 1317 | /* enum: PPS time event nS reading not sufficiently close to zero. */ | ||
| 1318 | #define MC_CMD_PTP_MANF_PPS_NS 0xc | ||
| 1319 | /* enum: PTP peripheral registers incorrect */ | ||
| 1320 | #define MC_CMD_PTP_MANF_REGISTERS 0xd | ||
| 1321 | /* enum: Failed to read time from PTP peripheral */ | ||
| 1322 | #define MC_CMD_PTP_MANF_CLOCK_READ 0xe | ||
| 1180 | /* Presence of external oscillator */ | 1323 | /* Presence of external oscillator */ |
| 1181 | #define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4 | 1324 | #define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4 |
| 1182 | 1325 | ||
| @@ -1198,6 +1341,62 @@ | |||
| 1198 | #define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MINNUM 1 | 1341 | #define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MINNUM 1 |
| 1199 | #define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM 252 | 1342 | #define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM 252 |
| 1200 | 1343 | ||
| 1344 | /* MC_CMD_PTP_OUT_GET_TIME_FORMAT msgresponse */ | ||
| 1345 | #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_LEN 4 | ||
| 1346 | /* Time format required/used by for this NIC. Applies to all PTP MCDI | ||
| 1347 | * operations that pass times between the host and firmware. If this operation | ||
| 1348 | * is not supported (older firmware) a format of seconds and nanoseconds should | ||
| 1349 | * be assumed. | ||
| 1350 | */ | ||
| 1351 | #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_FORMAT_OFST 0 | ||
| 1352 | /* enum: Times are in seconds and nanoseconds */ | ||
| 1353 | #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_NANOSECONDS 0x0 | ||
| 1354 | /* enum: Major register has units of 16 second per tick, minor 8 ns per tick */ | ||
| 1355 | #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_16SECONDS_8NANOSECONDS 0x1 | ||
| 1356 | /* enum: Major register has units of seconds, minor 2^-27s per tick */ | ||
| 1357 | #define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_27FRACTION 0x2 | ||
| 1358 | |||
| 1359 | /* MC_CMD_PTP_OUT_GET_ATTRIBUTES msgresponse */ | ||
| 1360 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_LEN 8 | ||
| 1361 | /* Time format required/used by for this NIC. Applies to all PTP MCDI | ||
| 1362 | * operations that pass times between the host and firmware. If this operation | ||
| 1363 | * is not supported (older firmware) a format of seconds and nanoseconds should | ||
| 1364 | * be assumed. | ||
| 1365 | */ | ||
| 1366 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_TIME_FORMAT_OFST 0 | ||
| 1367 | /* enum: Times are in seconds and nanoseconds */ | ||
| 1368 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS 0x0 | ||
| 1369 | /* enum: Major register has units of 16 second per tick, minor 8 ns per tick */ | ||
| 1370 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_16SECONDS_8NANOSECONDS 0x1 | ||
| 1371 | /* enum: Major register has units of seconds, minor 2^-27s per tick */ | ||
| 1372 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION 0x2 | ||
| 1373 | /* Minimum acceptable value for a corrected synchronization timeset. When | ||
| 1374 | * comparing host and NIC clock times, the MC returns a set of samples that | ||
| 1375 | * contain the host start and end time, the MC time when the host start was | ||
| 1376 | * detected and the time the MC waited between reading the time and detecting | ||
| 1377 | * the host end. The corrected sync window is the difference between the host | ||
| 1378 | * end and start times minus the time that the MC waited for host end. | ||
| 1379 | */ | ||
| 1380 | #define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SYNC_WINDOW_MIN_OFST 4 | ||
| 1381 | |||
| 1382 | /* MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS msgresponse */ | ||
| 1383 | #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_LEN 16 | ||
| 1384 | /* Uncorrected error on transmit timestamps in NIC clock format */ | ||
| 1385 | #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT_OFST 0 | ||
| 1386 | /* Uncorrected error on receive timestamps in NIC clock format */ | ||
| 1387 | #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE_OFST 4 | ||
| 1388 | /* Uncorrected error on PPS output in NIC clock format */ | ||
| 1389 | #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT_OFST 8 | ||
| 1390 | /* Uncorrected error on PPS input in NIC clock format */ | ||
| 1391 | #define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN_OFST 12 | ||
| 1392 | |||
| 1393 | /* MC_CMD_PTP_OUT_MANFTEST_PPS msgresponse */ | ||
| 1394 | #define MC_CMD_PTP_OUT_MANFTEST_PPS_LEN 4 | ||
| 1395 | /* Results of testing */ | ||
| 1396 | #define MC_CMD_PTP_OUT_MANFTEST_PPS_TEST_RESULT_OFST 0 | ||
| 1397 | /* Enum values, see field(s): */ | ||
| 1398 | /* MC_CMD_PTP_OUT_MANFTEST_BASIC/TEST_RESULT */ | ||
| 1399 | |||
| 1201 | 1400 | ||
| 1202 | /***********************************/ | 1401 | /***********************************/ |
| 1203 | /* MC_CMD_CSR_READ32 | 1402 | /* MC_CMD_CSR_READ32 |
| @@ -1923,6 +2122,8 @@ | |||
| 1923 | #define MC_CMD_MEDIA_SFP_PLUS 0x5 | 2122 | #define MC_CMD_MEDIA_SFP_PLUS 0x5 |
| 1924 | /* enum: 10GBaseT. */ | 2123 | /* enum: 10GBaseT. */ |
| 1925 | #define MC_CMD_MEDIA_BASE_T 0x6 | 2124 | #define MC_CMD_MEDIA_BASE_T 0x6 |
| 2125 | /* enum: QSFP+. */ | ||
| 2126 | #define MC_CMD_MEDIA_QSFP_PLUS 0x7 | ||
| 1926 | #define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 | 2127 | #define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 |
| 1927 | /* enum: Native clause 22 */ | 2128 | /* enum: Native clause 22 */ |
| 1928 | #define MC_CMD_MMD_CLAUSE22 0x0 | 2129 | #define MC_CMD_MMD_CLAUSE22 0x0 |
| @@ -2223,6 +2424,8 @@ | |||
| 2223 | #define MC_CMD_LOOPBACK_SD_FEP_WS 0x21 | 2424 | #define MC_CMD_LOOPBACK_SD_FEP_WS 0x21 |
| 2224 | /* enum: KR Serdes Serial Wireside. */ | 2425 | /* enum: KR Serdes Serial Wireside. */ |
| 2225 | #define MC_CMD_LOOPBACK_SD_FES_WS 0x22 | 2426 | #define MC_CMD_LOOPBACK_SD_FES_WS 0x22 |
| 2427 | /* enum: Near side of AOE Siena side port */ | ||
| 2428 | #define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 | ||
| 2226 | /* Supported loopbacks. */ | 2429 | /* Supported loopbacks. */ |
| 2227 | #define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 | 2430 | #define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 |
| 2228 | #define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 | 2431 | #define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 |
| @@ -2286,6 +2489,10 @@ | |||
| 2286 | #define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1 | 2489 | #define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1 |
| 2287 | #define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3 | 2490 | #define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3 |
| 2288 | #define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1 | 2491 | #define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1 |
| 2492 | #define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_LBN 6 | ||
| 2493 | #define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_WIDTH 1 | ||
| 2494 | #define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_LBN 7 | ||
| 2495 | #define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_WIDTH 1 | ||
| 2289 | /* This returns the negotiated flow control value. */ | 2496 | /* This returns the negotiated flow control value. */ |
| 2290 | #define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 | 2497 | #define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 |
| 2291 | /* enum: Flow control is off. */ | 2498 | /* enum: Flow control is off. */ |
| @@ -3175,7 +3382,7 @@ | |||
| 3175 | #define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0 | 3382 | #define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0 |
| 3176 | 3383 | ||
| 3177 | /* MC_CMD_SENSOR_INFO_OUT msgresponse */ | 3384 | /* MC_CMD_SENSOR_INFO_OUT msgresponse */ |
| 3178 | #define MC_CMD_SENSOR_INFO_OUT_LENMIN 12 | 3385 | #define MC_CMD_SENSOR_INFO_OUT_LENMIN 4 |
| 3179 | #define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 | 3386 | #define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 |
| 3180 | #define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) | 3387 | #define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) |
| 3181 | #define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 | 3388 | #define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 |
| @@ -3269,16 +3476,18 @@ | |||
| 3269 | #define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b | 3476 | #define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b |
| 3270 | /* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */ | 3477 | /* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */ |
| 3271 | #define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c | 3478 | #define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c |
| 3479 | /* enum: Hotpoint temperature: degC */ | ||
| 3480 | #define MC_CMD_SENSOR_HOTPOINT_TEMP 0x2d | ||
| 3272 | /* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */ | 3481 | /* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */ |
| 3273 | #define MC_CMD_SENSOR_ENTRY_OFST 4 | 3482 | #define MC_CMD_SENSOR_ENTRY_OFST 4 |
| 3274 | #define MC_CMD_SENSOR_ENTRY_LEN 8 | 3483 | #define MC_CMD_SENSOR_ENTRY_LEN 8 |
| 3275 | #define MC_CMD_SENSOR_ENTRY_LO_OFST 4 | 3484 | #define MC_CMD_SENSOR_ENTRY_LO_OFST 4 |
| 3276 | #define MC_CMD_SENSOR_ENTRY_HI_OFST 8 | 3485 | #define MC_CMD_SENSOR_ENTRY_HI_OFST 8 |
| 3277 | #define MC_CMD_SENSOR_ENTRY_MINNUM 1 | 3486 | #define MC_CMD_SENSOR_ENTRY_MINNUM 0 |
| 3278 | #define MC_CMD_SENSOR_ENTRY_MAXNUM 31 | 3487 | #define MC_CMD_SENSOR_ENTRY_MAXNUM 31 |
| 3279 | 3488 | ||
| 3280 | /* MC_CMD_SENSOR_INFO_EXT_OUT msgresponse */ | 3489 | /* MC_CMD_SENSOR_INFO_EXT_OUT msgresponse */ |
| 3281 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LENMIN 12 | 3490 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LENMIN 4 |
| 3282 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252 | 3491 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252 |
| 3283 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num)) | 3492 | #define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num)) |
| 3284 | #define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0 | 3493 | #define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0 |
| @@ -3291,7 +3500,7 @@ | |||
| 3291 | /* MC_CMD_SENSOR_ENTRY_LEN 8 */ | 3500 | /* MC_CMD_SENSOR_ENTRY_LEN 8 */ |
| 3292 | /* MC_CMD_SENSOR_ENTRY_LO_OFST 4 */ | 3501 | /* MC_CMD_SENSOR_ENTRY_LO_OFST 4 */ |
| 3293 | /* MC_CMD_SENSOR_ENTRY_HI_OFST 8 */ | 3502 | /* MC_CMD_SENSOR_ENTRY_HI_OFST 8 */ |
| 3294 | /* MC_CMD_SENSOR_ENTRY_MINNUM 1 */ | 3503 | /* MC_CMD_SENSOR_ENTRY_MINNUM 0 */ |
| 3295 | /* MC_CMD_SENSOR_ENTRY_MAXNUM 31 */ | 3504 | /* MC_CMD_SENSOR_ENTRY_MAXNUM 31 */ |
| 3296 | 3505 | ||
| 3297 | /* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */ | 3506 | /* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */ |
| @@ -3864,6 +4073,18 @@ | |||
| 3864 | #define NVRAM_PARTITION_TYPE_ID_LBN 0 | 4073 | #define NVRAM_PARTITION_TYPE_ID_LBN 0 |
| 3865 | #define NVRAM_PARTITION_TYPE_ID_WIDTH 16 | 4074 | #define NVRAM_PARTITION_TYPE_ID_WIDTH 16 |
| 3866 | 4075 | ||
| 4076 | /* LICENSED_APP_ID structuredef */ | ||
| 4077 | #define LICENSED_APP_ID_LEN 4 | ||
| 4078 | #define LICENSED_APP_ID_ID_OFST 0 | ||
| 4079 | /* enum: OpenOnload */ | ||
| 4080 | #define LICENSED_APP_ID_ONLOAD 0x1 | ||
| 4081 | /* enum: PTP timestamping */ | ||
| 4082 | #define LICENSED_APP_ID_PTP 0x2 | ||
| 4083 | /* enum: SolarCapture Pro */ | ||
| 4084 | #define LICENSED_APP_ID_SOLARCAPTURE_PRO 0x4 | ||
| 4085 | #define LICENSED_APP_ID_ID_LBN 0 | ||
| 4086 | #define LICENSED_APP_ID_ID_WIDTH 32 | ||
| 4087 | |||
| 3867 | 4088 | ||
| 3868 | /***********************************/ | 4089 | /***********************************/ |
| 3869 | /* MC_CMD_READ_REGS | 4090 | /* MC_CMD_READ_REGS |
| @@ -4021,6 +4242,8 @@ | |||
| 4021 | #define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_WIDTH 1 | 4242 | #define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_WIDTH 1 |
| 4022 | #define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_LBN 8 | 4243 | #define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_LBN 8 |
| 4023 | #define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_WIDTH 1 | 4244 | #define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_WIDTH 1 |
| 4245 | #define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_LBN 9 | ||
| 4246 | #define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_WIDTH 1 | ||
| 4024 | /* Owner ID to use if in buffer mode (zero if physical) */ | 4247 | /* Owner ID to use if in buffer mode (zero if physical) */ |
| 4025 | #define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20 | 4248 | #define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20 |
| 4026 | /* The port ID associated with the v-adaptor which should contain this DMAQ. */ | 4249 | /* The port ID associated with the v-adaptor which should contain this DMAQ. */ |
| @@ -4179,6 +4402,9 @@ | |||
| 4179 | #define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16 | 4402 | #define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16 |
| 4180 | #define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */ | 4403 | #define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */ |
| 4181 | 4404 | ||
| 4405 | /* MC_CMD_PROXY_CMD_OUT msgresponse */ | ||
| 4406 | #define MC_CMD_PROXY_CMD_OUT_LEN 0 | ||
| 4407 | |||
| 4182 | 4408 | ||
| 4183 | /***********************************/ | 4409 | /***********************************/ |
| 4184 | /* MC_CMD_ALLOC_BUFTBL_CHUNK | 4410 | /* MC_CMD_ALLOC_BUFTBL_CHUNK |
| @@ -4213,7 +4439,7 @@ | |||
| 4213 | 4439 | ||
| 4214 | /* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */ | 4440 | /* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */ |
| 4215 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20 | 4441 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20 |
| 4216 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 252 | 4442 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 268 |
| 4217 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num)) | 4443 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num)) |
| 4218 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0 | 4444 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0 |
| 4219 | /* ID */ | 4445 | /* ID */ |
| @@ -4226,7 +4452,7 @@ | |||
| 4226 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LO_OFST 12 | 4452 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LO_OFST 12 |
| 4227 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16 | 4453 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16 |
| 4228 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1 | 4454 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1 |
| 4229 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 30 | 4455 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 32 |
| 4230 | 4456 | ||
| 4231 | /* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */ | 4457 | /* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */ |
| 4232 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0 | 4458 | #define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0 |
| @@ -6800,6 +7026,30 @@ | |||
| 6800 | 7026 | ||
| 6801 | 7027 | ||
| 6802 | /***********************************/ | 7028 | /***********************************/ |
| 7029 | /* MC_CMD_CAP_BLK_READ | ||
| 7030 | * Read multiple 64bit words from capture block memory | ||
| 7031 | */ | ||
| 7032 | #define MC_CMD_CAP_BLK_READ 0xe7 | ||
| 7033 | |||
| 7034 | /* MC_CMD_CAP_BLK_READ_IN msgrequest */ | ||
| 7035 | #define MC_CMD_CAP_BLK_READ_IN_LEN 12 | ||
| 7036 | #define MC_CMD_CAP_BLK_READ_IN_CAP_REG_OFST 0 | ||
| 7037 | #define MC_CMD_CAP_BLK_READ_IN_ADDR_OFST 4 | ||
| 7038 | #define MC_CMD_CAP_BLK_READ_IN_COUNT_OFST 8 | ||
| 7039 | |||
| 7040 | /* MC_CMD_CAP_BLK_READ_OUT msgresponse */ | ||
| 7041 | #define MC_CMD_CAP_BLK_READ_OUT_LENMIN 8 | ||
| 7042 | #define MC_CMD_CAP_BLK_READ_OUT_LENMAX 248 | ||
| 7043 | #define MC_CMD_CAP_BLK_READ_OUT_LEN(num) (0+8*(num)) | ||
| 7044 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_OFST 0 | ||
| 7045 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LEN 8 | ||
| 7046 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LO_OFST 0 | ||
| 7047 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_HI_OFST 4 | ||
| 7048 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MINNUM 1 | ||
| 7049 | #define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MAXNUM 31 | ||
| 7050 | |||
| 7051 | |||
| 7052 | /***********************************/ | ||
| 6803 | /* MC_CMD_DUMP_DO | 7053 | /* MC_CMD_DUMP_DO |
| 6804 | * Take a dump of the DUT state | 7054 | * Take a dump of the DUT state |
| 6805 | */ | 7055 | */ |
| @@ -6826,6 +7076,10 @@ | |||
| 6826 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20 | 7076 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20 |
| 6827 | #define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */ | 7077 | #define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */ |
| 6828 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12 | 7078 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12 |
| 7079 | /* enum: The uart port this command was received over (if using a uart | ||
| 7080 | * transport) | ||
| 7081 | */ | ||
| 7082 | #define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff | ||
| 6829 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24 | 7083 | #define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24 |
| 6830 | #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28 | 7084 | #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28 |
| 6831 | #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */ | 7085 | #define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */ |
| @@ -6942,39 +7196,68 @@ | |||
| 6942 | 7196 | ||
| 6943 | 7197 | ||
| 6944 | /***********************************/ | 7198 | /***********************************/ |
| 6945 | /* MC_CMD_START_KR_EYE_PLOT | 7199 | /* MC_CMD_UART_SEND_DATA |
| 6946 | * Start KR Serdes Eye diagram plot on a given lane. Lane must have valid | 7200 | * Send checksummed[sic] block of data over the uart. Response is a placeholder |
| 6947 | * signal. | 7201 | * should we wish to make this reliable; currently requests are fire-and- |
| 6948 | */ | 7202 | * forget. |
| 6949 | #define MC_CMD_START_KR_EYE_PLOT 0xee | 7203 | */ |
| 6950 | 7204 | #define MC_CMD_UART_SEND_DATA 0xee | |
| 6951 | /* MC_CMD_START_KR_EYE_PLOT_IN msgrequest */ | 7205 | |
| 6952 | #define MC_CMD_START_KR_EYE_PLOT_IN_LEN 4 | 7206 | /* MC_CMD_UART_SEND_DATA_OUT msgrequest */ |
| 6953 | #define MC_CMD_START_KR_EYE_PLOT_IN_LANE_OFST 0 | 7207 | #define MC_CMD_UART_SEND_DATA_OUT_LENMIN 16 |
| 6954 | 7208 | #define MC_CMD_UART_SEND_DATA_OUT_LENMAX 252 | |
| 6955 | /* MC_CMD_START_KR_EYE_PLOT_OUT msgresponse */ | 7209 | #define MC_CMD_UART_SEND_DATA_OUT_LEN(num) (16+1*(num)) |
| 6956 | #define MC_CMD_START_KR_EYE_PLOT_OUT_LEN 0 | 7210 | /* CRC32 over OFFSET, LENGTH, RESERVED, DATA */ |
| 6957 | 7211 | #define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_OFST 0 | |
| 6958 | 7212 | /* Offset at which to write the data */ | |
| 6959 | /***********************************/ | 7213 | #define MC_CMD_UART_SEND_DATA_OUT_OFFSET_OFST 4 |
| 6960 | /* MC_CMD_POLL_KR_EYE_PLOT | 7214 | /* Length of data */ |
| 6961 | * Poll KR Serdes Eye diagram plot. Returns one row of BER data. The caller | 7215 | #define MC_CMD_UART_SEND_DATA_OUT_LENGTH_OFST 8 |
| 6962 | * should call this command repeatedly after starting eye plot, until no more | 7216 | /* Reserved for future use */ |
| 6963 | * data is returned. | 7217 | #define MC_CMD_UART_SEND_DATA_OUT_RESERVED_OFST 12 |
| 6964 | */ | 7218 | #define MC_CMD_UART_SEND_DATA_OUT_DATA_OFST 16 |
| 6965 | #define MC_CMD_POLL_KR_EYE_PLOT 0xef | 7219 | #define MC_CMD_UART_SEND_DATA_OUT_DATA_LEN 1 |
| 6966 | 7220 | #define MC_CMD_UART_SEND_DATA_OUT_DATA_MINNUM 0 | |
| 6967 | /* MC_CMD_POLL_KR_EYE_PLOT_IN msgrequest */ | 7221 | #define MC_CMD_UART_SEND_DATA_OUT_DATA_MAXNUM 236 |
| 6968 | #define MC_CMD_POLL_KR_EYE_PLOT_IN_LEN 0 | 7222 | |
| 6969 | 7223 | /* MC_CMD_UART_SEND_DATA_IN msgresponse */ | |
| 6970 | /* MC_CMD_POLL_KR_EYE_PLOT_OUT msgresponse */ | 7224 | #define MC_CMD_UART_SEND_DATA_IN_LEN 0 |
| 6971 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_LENMIN 0 | 7225 | |
| 6972 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_LENMAX 252 | 7226 | |
| 6973 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_LEN(num) (0+2*(num)) | 7227 | /***********************************/ |
| 6974 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_SAMPLES_OFST 0 | 7228 | /* MC_CMD_UART_RECV_DATA |
| 6975 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_SAMPLES_LEN 2 | 7229 | * Request checksummed[sic] block of data over the uart. Only a placeholder, |
| 6976 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_SAMPLES_MINNUM 0 | 7230 | * subject to change and not currently implemented. |
| 6977 | #define MC_CMD_POLL_KR_EYE_PLOT_OUT_SAMPLES_MAXNUM 126 | 7231 | */ |
| 7232 | #define MC_CMD_UART_RECV_DATA 0xef | ||
| 7233 | |||
| 7234 | /* MC_CMD_UART_RECV_DATA_OUT msgrequest */ | ||
| 7235 | #define MC_CMD_UART_RECV_DATA_OUT_LEN 16 | ||
| 7236 | /* CRC32 over OFFSET, LENGTH, RESERVED */ | ||
| 7237 | #define MC_CMD_UART_RECV_DATA_OUT_CHECKSUM_OFST 0 | ||
| 7238 | /* Offset from which to read the data */ | ||
| 7239 | #define MC_CMD_UART_RECV_DATA_OUT_OFFSET_OFST 4 | ||
| 7240 | /* Length of data */ | ||
| 7241 | #define MC_CMD_UART_RECV_DATA_OUT_LENGTH_OFST 8 | ||
| 7242 | /* Reserved for future use */ | ||
| 7243 | #define MC_CMD_UART_RECV_DATA_OUT_RESERVED_OFST 12 | ||
| 7244 | |||
| 7245 | /* MC_CMD_UART_RECV_DATA_IN msgresponse */ | ||
| 7246 | #define MC_CMD_UART_RECV_DATA_IN_LENMIN 16 | ||
| 7247 | #define MC_CMD_UART_RECV_DATA_IN_LENMAX 252 | ||
| 7248 | #define MC_CMD_UART_RECV_DATA_IN_LEN(num) (16+1*(num)) | ||
| 7249 | /* CRC32 over RESERVED1, RESERVED2, RESERVED3, DATA */ | ||
| 7250 | #define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_OFST 0 | ||
| 7251 | /* Offset at which to write the data */ | ||
| 7252 | #define MC_CMD_UART_RECV_DATA_IN_RESERVED1_OFST 4 | ||
| 7253 | /* Length of data */ | ||
| 7254 | #define MC_CMD_UART_RECV_DATA_IN_RESERVED2_OFST 8 | ||
| 7255 | /* Reserved for future use */ | ||
| 7256 | #define MC_CMD_UART_RECV_DATA_IN_RESERVED3_OFST 12 | ||
| 7257 | #define MC_CMD_UART_RECV_DATA_IN_DATA_OFST 16 | ||
| 7258 | #define MC_CMD_UART_RECV_DATA_IN_DATA_LEN 1 | ||
| 7259 | #define MC_CMD_UART_RECV_DATA_IN_DATA_MINNUM 0 | ||
| 7260 | #define MC_CMD_UART_RECV_DATA_IN_DATA_MAXNUM 236 | ||
| 6978 | 7261 | ||
| 6979 | 7262 | ||
| 6980 | /***********************************/ | 7263 | /***********************************/ |
| @@ -7026,6 +7309,15 @@ | |||
| 7026 | #define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3 | 7309 | #define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3 |
| 7027 | /* enum: Force KR Serdes reset / recalibration */ | 7310 | /* enum: Force KR Serdes reset / recalibration */ |
| 7028 | #define MC_CMD_KR_TUNE_IN_RECAL 0x4 | 7311 | #define MC_CMD_KR_TUNE_IN_RECAL 0x4 |
| 7312 | /* enum: Start KR Serdes Eye diagram plot on a given lane. Lane must have valid | ||
| 7313 | * signal. | ||
| 7314 | */ | ||
| 7315 | #define MC_CMD_KR_TUNE_IN_START_EYE_PLOT 0x5 | ||
| 7316 | /* enum: Poll KR Serdes Eye diagram plot. Returns one row of BER data. The | ||
| 7317 | * caller should call this command repeatedly after starting eye plot, until no | ||
| 7318 | * more data is returned. | ||
| 7319 | */ | ||
| 7320 | #define MC_CMD_KR_TUNE_IN_POLL_EYE_PLOT 0x6 | ||
| 7029 | /* Align the arguments to 32 bits */ | 7321 | /* Align the arguments to 32 bits */ |
| 7030 | #define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1 | 7322 | #define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1 |
| 7031 | #define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3 | 7323 | #define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3 |
| @@ -7123,6 +7415,91 @@ | |||
| 7123 | /* MC_CMD_KR_TUNE_RXEQ_SET_OUT msgresponse */ | 7415 | /* MC_CMD_KR_TUNE_RXEQ_SET_OUT msgresponse */ |
| 7124 | #define MC_CMD_KR_TUNE_RXEQ_SET_OUT_LEN 0 | 7416 | #define MC_CMD_KR_TUNE_RXEQ_SET_OUT_LEN 0 |
| 7125 | 7417 | ||
| 7418 | /* MC_CMD_KR_TUNE_TXEQ_GET_IN msgrequest */ | ||
| 7419 | #define MC_CMD_KR_TUNE_TXEQ_GET_IN_LEN 4 | ||
| 7420 | /* Requested operation */ | ||
| 7421 | #define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_OFST 0 | ||
| 7422 | #define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_LEN 1 | ||
| 7423 | /* Align the arguments to 32 bits */ | ||
| 7424 | #define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_OFST 1 | ||
| 7425 | #define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_LEN 3 | ||
| 7426 | |||
| 7427 | /* MC_CMD_KR_TUNE_TXEQ_GET_OUT msgresponse */ | ||
| 7428 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMIN 4 | ||
| 7429 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMAX 252 | ||
| 7430 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num)) | ||
| 7431 | /* TXEQ Parameter */ | ||
| 7432 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_OFST 0 | ||
| 7433 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LEN 4 | ||
| 7434 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1 | ||
| 7435 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63 | ||
| 7436 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0 | ||
| 7437 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8 | ||
| 7438 | /* enum: TX Amplitude */ | ||
| 7439 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0 | ||
| 7440 | /* enum: De-Emphasis Tap1 Magnitude (0-7) */ | ||
| 7441 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1 | ||
| 7442 | /* enum: De-Emphasis Tap1 Fine */ | ||
| 7443 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_DTLEV 0x2 | ||
| 7444 | /* enum: De-Emphasis Tap2 Magnitude (0-6) */ | ||
| 7445 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2 0x3 | ||
| 7446 | /* enum: De-Emphasis Tap2 Fine */ | ||
| 7447 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2TLEV 0x4 | ||
| 7448 | /* enum: Pre-Emphasis Magnitude */ | ||
| 7449 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_E 0x5 | ||
| 7450 | /* enum: Pre-Emphasis Fine */ | ||
| 7451 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_ETLEV 0x6 | ||
| 7452 | /* enum: TX Slew Rate Coarse control */ | ||
| 7453 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_PREDRV_DLY 0x7 | ||
| 7454 | /* enum: TX Slew Rate Fine control */ | ||
| 7455 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_SR_SET 0x8 | ||
| 7456 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8 | ||
| 7457 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3 | ||
| 7458 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */ | ||
| 7459 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_1 0x1 /* enum */ | ||
| 7460 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */ | ||
| 7461 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */ | ||
| 7462 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */ | ||
| 7463 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11 | ||
| 7464 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5 | ||
| 7465 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16 | ||
| 7466 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8 | ||
| 7467 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_LBN 24 | ||
| 7468 | #define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_WIDTH 8 | ||
| 7469 | |||
| 7470 | /* MC_CMD_KR_TUNE_TXEQ_SET_IN msgrequest */ | ||
| 7471 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMIN 8 | ||
| 7472 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMAX 252 | ||
| 7473 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_LEN(num) (4+4*(num)) | ||
| 7474 | /* Requested operation */ | ||
| 7475 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_OFST 0 | ||
| 7476 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_LEN 1 | ||
| 7477 | /* Align the arguments to 32 bits */ | ||
| 7478 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_OFST 1 | ||
| 7479 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_LEN 3 | ||
| 7480 | /* TXEQ Parameter */ | ||
| 7481 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_OFST 4 | ||
| 7482 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LEN 4 | ||
| 7483 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MINNUM 1 | ||
| 7484 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MAXNUM 62 | ||
| 7485 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_LBN 0 | ||
| 7486 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_WIDTH 8 | ||
| 7487 | /* Enum values, see field(s): */ | ||
| 7488 | /* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_ID */ | ||
| 7489 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_LBN 8 | ||
| 7490 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_WIDTH 3 | ||
| 7491 | /* Enum values, see field(s): */ | ||
| 7492 | /* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_LANE */ | ||
| 7493 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_LBN 11 | ||
| 7494 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_WIDTH 5 | ||
| 7495 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_LBN 16 | ||
| 7496 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_WIDTH 8 | ||
| 7497 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_LBN 24 | ||
| 7498 | #define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_WIDTH 8 | ||
| 7499 | |||
| 7500 | /* MC_CMD_KR_TUNE_TXEQ_SET_OUT msgresponse */ | ||
| 7501 | #define MC_CMD_KR_TUNE_TXEQ_SET_OUT_LEN 0 | ||
| 7502 | |||
| 7126 | /* MC_CMD_KR_TUNE_RECAL_IN msgrequest */ | 7503 | /* MC_CMD_KR_TUNE_RECAL_IN msgrequest */ |
| 7127 | #define MC_CMD_KR_TUNE_RECAL_IN_LEN 4 | 7504 | #define MC_CMD_KR_TUNE_RECAL_IN_LEN 4 |
| 7128 | /* Requested operation */ | 7505 | /* Requested operation */ |
| @@ -7135,6 +7512,37 @@ | |||
| 7135 | /* MC_CMD_KR_TUNE_RECAL_OUT msgresponse */ | 7512 | /* MC_CMD_KR_TUNE_RECAL_OUT msgresponse */ |
| 7136 | #define MC_CMD_KR_TUNE_RECAL_OUT_LEN 0 | 7513 | #define MC_CMD_KR_TUNE_RECAL_OUT_LEN 0 |
| 7137 | 7514 | ||
| 7515 | /* MC_CMD_KR_TUNE_START_EYE_PLOT_IN msgrequest */ | ||
| 7516 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LEN 8 | ||
| 7517 | /* Requested operation */ | ||
| 7518 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_OFST 0 | ||
| 7519 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_LEN 1 | ||
| 7520 | /* Align the arguments to 32 bits */ | ||
| 7521 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1 | ||
| 7522 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3 | ||
| 7523 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LANE_OFST 4 | ||
| 7524 | |||
| 7525 | /* MC_CMD_KR_TUNE_START_EYE_PLOT_OUT msgresponse */ | ||
| 7526 | #define MC_CMD_KR_TUNE_START_EYE_PLOT_OUT_LEN 0 | ||
| 7527 | |||
| 7528 | /* MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN msgrequest */ | ||
| 7529 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_LEN 4 | ||
| 7530 | /* Requested operation */ | ||
| 7531 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_OFST 0 | ||
| 7532 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_LEN 1 | ||
| 7533 | /* Align the arguments to 32 bits */ | ||
| 7534 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1 | ||
| 7535 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3 | ||
| 7536 | |||
| 7537 | /* MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT msgresponse */ | ||
| 7538 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0 | ||
| 7539 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252 | ||
| 7540 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num)) | ||
| 7541 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0 | ||
| 7542 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2 | ||
| 7543 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0 | ||
| 7544 | #define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126 | ||
| 7545 | |||
| 7138 | 7546 | ||
| 7139 | /***********************************/ | 7547 | /***********************************/ |
| 7140 | /* MC_CMD_PCIE_TUNE | 7548 | /* MC_CMD_PCIE_TUNE |
| @@ -7157,6 +7565,13 @@ | |||
| 7157 | #define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2 | 7565 | #define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2 |
| 7158 | /* enum: Override TX Driver settings */ | 7566 | /* enum: Override TX Driver settings */ |
| 7159 | #define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3 | 7567 | #define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3 |
| 7568 | /* enum: Start PCIe Serdes Eye diagram plot on a given lane. */ | ||
| 7569 | #define MC_CMD_PCIE_TUNE_IN_START_EYE_PLOT 0x5 | ||
| 7570 | /* enum: Poll PCIe Serdes Eye diagram plot. Returns one row of BER data. The | ||
| 7571 | * caller should call this command repeatedly after starting eye plot, until no | ||
| 7572 | * more data is returned. | ||
| 7573 | */ | ||
| 7574 | #define MC_CMD_PCIE_TUNE_IN_POLL_EYE_PLOT 0x6 | ||
| 7160 | /* Align the arguments to 32 bits */ | 7575 | /* Align the arguments to 32 bits */ |
| 7161 | #define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1 | 7576 | #define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1 |
| 7162 | #define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3 | 7577 | #define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3 |
| @@ -7258,6 +7673,37 @@ | |||
| 7258 | #define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_LBN 24 | 7673 | #define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_LBN 24 |
| 7259 | #define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8 | 7674 | #define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8 |
| 7260 | 7675 | ||
| 7676 | /* MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN msgrequest */ | ||
| 7677 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LEN 8 | ||
| 7678 | /* Requested operation */ | ||
| 7679 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0 | ||
| 7680 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1 | ||
| 7681 | /* Align the arguments to 32 bits */ | ||
| 7682 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1 | ||
| 7683 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3 | ||
| 7684 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LANE_OFST 4 | ||
| 7685 | |||
| 7686 | /* MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT msgresponse */ | ||
| 7687 | #define MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT_LEN 0 | ||
| 7688 | |||
| 7689 | /* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN msgrequest */ | ||
| 7690 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_LEN 4 | ||
| 7691 | /* Requested operation */ | ||
| 7692 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0 | ||
| 7693 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1 | ||
| 7694 | /* Align the arguments to 32 bits */ | ||
| 7695 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1 | ||
| 7696 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3 | ||
| 7697 | |||
| 7698 | /* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT msgresponse */ | ||
| 7699 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0 | ||
| 7700 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252 | ||
| 7701 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num)) | ||
| 7702 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0 | ||
| 7703 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2 | ||
| 7704 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0 | ||
| 7705 | #define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126 | ||
| 7706 | |||
| 7261 | 7707 | ||
| 7262 | /***********************************/ | 7708 | /***********************************/ |
| 7263 | /* MC_CMD_LICENSING | 7709 | /* MC_CMD_LICENSING |
| @@ -7310,5 +7756,152 @@ | |||
| 7310 | */ | 7756 | */ |
| 7311 | #define MC_CMD_MC2MC_PROXY 0xf4 | 7757 | #define MC_CMD_MC2MC_PROXY 0xf4 |
| 7312 | 7758 | ||
| 7759 | /* MC_CMD_MC2MC_PROXY_IN msgrequest */ | ||
| 7760 | #define MC_CMD_MC2MC_PROXY_IN_LEN 0 | ||
| 7761 | |||
| 7762 | /* MC_CMD_MC2MC_PROXY_OUT msgresponse */ | ||
| 7763 | #define MC_CMD_MC2MC_PROXY_OUT_LEN 0 | ||
| 7764 | |||
| 7765 | |||
| 7766 | /***********************************/ | ||
| 7767 | /* MC_CMD_GET_LICENSED_APP_STATE | ||
| 7768 | * Query the state of an individual licensed application. (Note that the actual | ||
| 7769 | * state may be invalidated by the MC_CMD_LICENSING OP_UPDATE_LICENSE operation | ||
| 7770 | * or a reboot of the MC.) | ||
| 7771 | */ | ||
| 7772 | #define MC_CMD_GET_LICENSED_APP_STATE 0xf5 | ||
| 7773 | |||
| 7774 | /* MC_CMD_GET_LICENSED_APP_STATE_IN msgrequest */ | ||
| 7775 | #define MC_CMD_GET_LICENSED_APP_STATE_IN_LEN 4 | ||
| 7776 | /* application ID to query (LICENSED_APP_ID_xxx) */ | ||
| 7777 | #define MC_CMD_GET_LICENSED_APP_STATE_IN_APP_ID_OFST 0 | ||
| 7778 | |||
| 7779 | /* MC_CMD_GET_LICENSED_APP_STATE_OUT msgresponse */ | ||
| 7780 | #define MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN 4 | ||
| 7781 | /* state of this application */ | ||
| 7782 | #define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0 | ||
| 7783 | /* enum: no (or invalid) license is present for the application */ | ||
| 7784 | #define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0 | ||
| 7785 | /* enum: a valid license is present for the application */ | ||
| 7786 | #define MC_CMD_GET_LICENSED_APP_STATE_OUT_LICENSED 0x1 | ||
| 7787 | |||
| 7788 | |||
| 7789 | /***********************************/ | ||
| 7790 | /* MC_CMD_LICENSED_APP_OP | ||
| 7791 | * Perform an action for an individual licensed application. | ||
| 7792 | */ | ||
| 7793 | #define MC_CMD_LICENSED_APP_OP 0xf6 | ||
| 7794 | |||
| 7795 | /* MC_CMD_LICENSED_APP_OP_IN msgrequest */ | ||
| 7796 | #define MC_CMD_LICENSED_APP_OP_IN_LENMIN 8 | ||
| 7797 | #define MC_CMD_LICENSED_APP_OP_IN_LENMAX 252 | ||
| 7798 | #define MC_CMD_LICENSED_APP_OP_IN_LEN(num) (8+4*(num)) | ||
| 7799 | /* application ID */ | ||
| 7800 | #define MC_CMD_LICENSED_APP_OP_IN_APP_ID_OFST 0 | ||
| 7801 | /* the type of operation requested */ | ||
| 7802 | #define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4 | ||
| 7803 | /* enum: validate application */ | ||
| 7804 | #define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0 | ||
| 7805 | /* arguments specific to this particular operation */ | ||
| 7806 | #define MC_CMD_LICENSED_APP_OP_IN_ARGS_OFST 8 | ||
| 7807 | #define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4 | ||
| 7808 | #define MC_CMD_LICENSED_APP_OP_IN_ARGS_MINNUM 0 | ||
| 7809 | #define MC_CMD_LICENSED_APP_OP_IN_ARGS_MAXNUM 61 | ||
| 7810 | |||
| 7811 | /* MC_CMD_LICENSED_APP_OP_OUT msgresponse */ | ||
| 7812 | #define MC_CMD_LICENSED_APP_OP_OUT_LENMIN 0 | ||
| 7813 | #define MC_CMD_LICENSED_APP_OP_OUT_LENMAX 252 | ||
| 7814 | #define MC_CMD_LICENSED_APP_OP_OUT_LEN(num) (0+4*(num)) | ||
| 7815 | /* result specific to this particular operation */ | ||
| 7816 | #define MC_CMD_LICENSED_APP_OP_OUT_RESULT_OFST 0 | ||
| 7817 | #define MC_CMD_LICENSED_APP_OP_OUT_RESULT_LEN 4 | ||
| 7818 | #define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MINNUM 0 | ||
| 7819 | #define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MAXNUM 63 | ||
| 7820 | |||
| 7821 | /* MC_CMD_LICENSED_APP_OP_VALIDATE_IN msgrequest */ | ||
| 7822 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_LEN 72 | ||
| 7823 | /* application ID */ | ||
| 7824 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_APP_ID_OFST 0 | ||
| 7825 | /* the type of operation requested */ | ||
| 7826 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_OP_OFST 4 | ||
| 7827 | /* validation challenge */ | ||
| 7828 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_OFST 8 | ||
| 7829 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_LEN 64 | ||
| 7830 | |||
| 7831 | /* MC_CMD_LICENSED_APP_OP_VALIDATE_OUT msgresponse */ | ||
| 7832 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_LEN 68 | ||
| 7833 | /* feature expiry (time_t) */ | ||
| 7834 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_EXPIRY_OFST 0 | ||
| 7835 | /* validation response */ | ||
| 7836 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_OFST 4 | ||
| 7837 | #define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_LEN 64 | ||
| 7838 | |||
| 7839 | |||
| 7840 | /***********************************/ | ||
| 7841 | /* MC_CMD_SET_PORT_SNIFF_CONFIG | ||
| 7842 | * Configure port sniffing for the physical port associated with the calling | ||
| 7843 | * function. Only a privileged function may change the port sniffing | ||
| 7844 | * configuration. A copy of all traffic delivered to the host (non-promiscuous | ||
| 7845 | * mode) or all traffic arriving at the port (promiscuous mode) may be | ||
| 7846 | * delivered to a specific queue, or a set of queues with RSS. | ||
| 7847 | */ | ||
| 7848 | #define MC_CMD_SET_PORT_SNIFF_CONFIG 0xf7 | ||
| 7849 | |||
| 7850 | /* MC_CMD_SET_PORT_SNIFF_CONFIG_IN msgrequest */ | ||
| 7851 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_LEN 16 | ||
| 7852 | /* configuration flags */ | ||
| 7853 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0 | ||
| 7854 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0 | ||
| 7855 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1 | ||
| 7856 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_LBN 1 | ||
| 7857 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_WIDTH 1 | ||
| 7858 | /* receive queue handle (for RSS mode, this is the base queue) */ | ||
| 7859 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4 | ||
| 7860 | /* receive mode */ | ||
| 7861 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8 | ||
| 7862 | /* enum: receive to just the specified queue */ | ||
| 7863 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0 | ||
| 7864 | /* enum: receive to multiple queues using RSS context */ | ||
| 7865 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1 | ||
| 7866 | /* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note | ||
| 7867 | * that these handles should be considered opaque to the host, although a value | ||
| 7868 | * of 0xFFFFFFFF is guaranteed never to be a valid handle. | ||
| 7869 | */ | ||
| 7870 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12 | ||
| 7871 | |||
| 7872 | /* MC_CMD_SET_PORT_SNIFF_CONFIG_OUT msgresponse */ | ||
| 7873 | #define MC_CMD_SET_PORT_SNIFF_CONFIG_OUT_LEN 0 | ||
| 7874 | |||
| 7875 | |||
| 7876 | /***********************************/ | ||
| 7877 | /* MC_CMD_GET_PORT_SNIFF_CONFIG | ||
| 7878 | * Obtain the current port sniffing configuration for the physical port | ||
| 7879 | * associated with the calling function. Only a privileged function may read | ||
| 7880 | * the configuration. | ||
| 7881 | */ | ||
| 7882 | #define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8 | ||
| 7883 | |||
| 7884 | /* MC_CMD_GET_PORT_SNIFF_CONFIG_IN msgrequest */ | ||
| 7885 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_IN_LEN 0 | ||
| 7886 | |||
| 7887 | /* MC_CMD_GET_PORT_SNIFF_CONFIG_OUT msgresponse */ | ||
| 7888 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_LEN 16 | ||
| 7889 | /* configuration flags */ | ||
| 7890 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0 | ||
| 7891 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0 | ||
| 7892 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1 | ||
| 7893 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_LBN 1 | ||
| 7894 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_WIDTH 1 | ||
| 7895 | /* receiving queue handle (for RSS mode, this is the base queue) */ | ||
| 7896 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4 | ||
| 7897 | /* receive mode */ | ||
| 7898 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8 | ||
| 7899 | /* enum: receiving to just the specified queue */ | ||
| 7900 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0 | ||
| 7901 | /* enum: receiving to multiple queues using RSS context */ | ||
| 7902 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1 | ||
| 7903 | /* RSS context (for RX_MODE_RSS) */ | ||
| 7904 | #define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12 | ||
| 7905 | |||
| 7313 | 7906 | ||
| 7314 | #endif /* MCDI_PCOL_H */ | 7907 | #endif /* MCDI_PCOL_H */ |
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c index 7b6be61d549f..91d23252f8fa 100644 --- a/drivers/net/ethernet/sfc/mcdi_port.c +++ b/drivers/net/ethernet/sfc/mcdi_port.c | |||
| @@ -90,13 +90,6 @@ static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities, | |||
| 90 | 90 | ||
| 91 | rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf), | 91 | rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf), |
| 92 | NULL, 0, NULL); | 92 | NULL, 0, NULL); |
| 93 | if (rc) | ||
| 94 | goto fail; | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | |||
| 98 | fail: | ||
| 99 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 100 | return rc; | 93 | return rc; |
| 101 | } | 94 | } |
| 102 | 95 | ||
| @@ -143,17 +136,13 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev, | |||
| 143 | rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf), | 136 | rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf), |
| 144 | outbuf, sizeof(outbuf), &outlen); | 137 | outbuf, sizeof(outbuf), &outlen); |
| 145 | if (rc) | 138 | if (rc) |
| 146 | goto fail; | 139 | return rc; |
| 147 | 140 | ||
| 148 | if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) != | 141 | if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) != |
| 149 | MC_CMD_MDIO_STATUS_GOOD) | 142 | MC_CMD_MDIO_STATUS_GOOD) |
| 150 | return -EIO; | 143 | return -EIO; |
| 151 | 144 | ||
| 152 | return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE); | 145 | return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE); |
| 153 | |||
| 154 | fail: | ||
| 155 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 156 | return rc; | ||
| 157 | } | 146 | } |
| 158 | 147 | ||
| 159 | static int efx_mcdi_mdio_write(struct net_device *net_dev, | 148 | static int efx_mcdi_mdio_write(struct net_device *net_dev, |
| @@ -174,17 +163,13 @@ static int efx_mcdi_mdio_write(struct net_device *net_dev, | |||
| 174 | rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf), | 163 | rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf), |
| 175 | outbuf, sizeof(outbuf), &outlen); | 164 | outbuf, sizeof(outbuf), &outlen); |
| 176 | if (rc) | 165 | if (rc) |
| 177 | goto fail; | 166 | return rc; |
| 178 | 167 | ||
| 179 | if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) != | 168 | if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) != |
| 180 | MC_CMD_MDIO_STATUS_GOOD) | 169 | MC_CMD_MDIO_STATUS_GOOD) |
| 181 | return -EIO; | 170 | return -EIO; |
| 182 | 171 | ||
| 183 | return 0; | 172 | return 0; |
| 184 | |||
| 185 | fail: | ||
| 186 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | ||
| 187 | return rc; | ||
| 188 | } | 173 | } |
| 189 | 174 | ||
| 190 | static u32 mcdi_to_ethtool_cap(u32 media, u32 cap) | 175 | static u32 mcdi_to_ethtool_cap(u32 media, u32 cap) |
| @@ -487,17 +472,14 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx) | |||
| 487 | 472 | ||
| 488 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | 473 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, |
| 489 | outbuf, sizeof(outbuf), NULL); | 474 | outbuf, sizeof(outbuf), NULL); |
| 490 | if (rc) { | 475 | if (rc) |
| 491 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", | ||
| 492 | __func__, rc); | ||
| 493 | efx->link_state.up = false; | 476 | efx->link_state.up = false; |
| 494 | } else { | 477 | else |
| 495 | efx_mcdi_phy_decode_link( | 478 | efx_mcdi_phy_decode_link( |
| 496 | efx, &efx->link_state, | 479 | efx, &efx->link_state, |
| 497 | MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED), | 480 | MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED), |
| 498 | MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), | 481 | MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), |
| 499 | MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); | 482 | MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); |
| 500 | } | ||
| 501 | 483 | ||
| 502 | return !efx_link_state_equal(&efx->link_state, &old_state); | 484 | return !efx_link_state_equal(&efx->link_state, &old_state); |
| 503 | } | 485 | } |
| @@ -531,11 +513,8 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e | |||
| 531 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); | 513 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); |
| 532 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | 514 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, |
| 533 | outbuf, sizeof(outbuf), NULL); | 515 | outbuf, sizeof(outbuf), NULL); |
| 534 | if (rc) { | 516 | if (rc) |
| 535 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", | ||
| 536 | __func__, rc); | ||
| 537 | return; | 517 | return; |
| 538 | } | ||
| 539 | ecmd->lp_advertising = | 518 | ecmd->lp_advertising = |
| 540 | mcdi_to_ethtool_cap(phy_cfg->media, | 519 | mcdi_to_ethtool_cap(phy_cfg->media, |
| 541 | MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP)); | 520 | MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP)); |
| @@ -918,21 +897,29 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx) | |||
| 918 | 897 | ||
| 919 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | 898 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, |
| 920 | outbuf, sizeof(outbuf), &outlength); | 899 | outbuf, sizeof(outbuf), &outlength); |
| 921 | if (rc) { | 900 | if (rc) |
| 922 | netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", | ||
| 923 | __func__, rc); | ||
| 924 | return true; | 901 | return true; |
| 925 | } | ||
| 926 | 902 | ||
| 927 | return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; | 903 | return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; |
| 928 | } | 904 | } |
| 929 | 905 | ||
| 930 | static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, | 906 | enum efx_stats_action { |
| 931 | u32 dma_len, int enable, int clear) | 907 | EFX_STATS_ENABLE, |
| 908 | EFX_STATS_DISABLE, | ||
| 909 | EFX_STATS_PULL, | ||
| 910 | }; | ||
| 911 | |||
| 912 | static int efx_mcdi_mac_stats(struct efx_nic *efx, | ||
| 913 | enum efx_stats_action action, int clear) | ||
| 932 | { | 914 | { |
| 933 | MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN); | 915 | MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN); |
| 934 | int rc; | 916 | int rc; |
| 935 | int period = enable ? 1000 : 0; | 917 | int change = action == EFX_STATS_PULL ? 0 : 1; |
| 918 | int enable = action == EFX_STATS_ENABLE ? 1 : 0; | ||
| 919 | int period = action == EFX_STATS_ENABLE ? 1000 : 0; | ||
| 920 | dma_addr_t dma_addr = efx->stats_buffer.dma_addr; | ||
| 921 | u32 dma_len = action != EFX_STATS_DISABLE ? | ||
| 922 | MC_CMD_MAC_NSTATS * sizeof(u64) : 0; | ||
| 936 | 923 | ||
| 937 | BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); | 924 | BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); |
| 938 | 925 | ||
| @@ -940,8 +927,8 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, | |||
| 940 | MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD, | 927 | MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD, |
| 941 | MAC_STATS_IN_DMA, !!enable, | 928 | MAC_STATS_IN_DMA, !!enable, |
| 942 | MAC_STATS_IN_CLEAR, clear, | 929 | MAC_STATS_IN_CLEAR, clear, |
| 943 | MAC_STATS_IN_PERIODIC_CHANGE, 1, | 930 | MAC_STATS_IN_PERIODIC_CHANGE, change, |
| 944 | MAC_STATS_IN_PERIODIC_ENABLE, !!enable, | 931 | MAC_STATS_IN_PERIODIC_ENABLE, enable, |
| 945 | MAC_STATS_IN_PERIODIC_CLEAR, 0, | 932 | MAC_STATS_IN_PERIODIC_CLEAR, 0, |
| 946 | MAC_STATS_IN_PERIODIC_NOEVENT, 1, | 933 | MAC_STATS_IN_PERIODIC_NOEVENT, 1, |
| 947 | MAC_STATS_IN_PERIOD_MS, period); | 934 | MAC_STATS_IN_PERIOD_MS, period); |
| @@ -949,14 +936,6 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, | |||
| 949 | 936 | ||
| 950 | rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), | 937 | rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), |
| 951 | NULL, 0, NULL); | 938 | NULL, 0, NULL); |
| 952 | if (rc) | ||
| 953 | goto fail; | ||
| 954 | |||
| 955 | return 0; | ||
| 956 | |||
| 957 | fail: | ||
| 958 | netif_err(efx, hw, efx->net_dev, "%s: %s failed rc=%d\n", | ||
| 959 | __func__, enable ? "enable" : "disable", rc); | ||
| 960 | return rc; | 939 | return rc; |
| 961 | } | 940 | } |
| 962 | 941 | ||
| @@ -966,13 +945,29 @@ void efx_mcdi_mac_start_stats(struct efx_nic *efx) | |||
| 966 | 945 | ||
| 967 | dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; | 946 | dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; |
| 968 | 947 | ||
| 969 | efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, | 948 | efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0); |
| 970 | MC_CMD_MAC_NSTATS * sizeof(u64), 1, 0); | ||
| 971 | } | 949 | } |
| 972 | 950 | ||
| 973 | void efx_mcdi_mac_stop_stats(struct efx_nic *efx) | 951 | void efx_mcdi_mac_stop_stats(struct efx_nic *efx) |
| 974 | { | 952 | { |
| 975 | efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 0); | 953 | efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0); |
| 954 | } | ||
| 955 | |||
| 956 | #define EFX_MAC_STATS_WAIT_US 100 | ||
| 957 | #define EFX_MAC_STATS_WAIT_ATTEMPTS 10 | ||
| 958 | |||
| 959 | void efx_mcdi_mac_pull_stats(struct efx_nic *efx) | ||
| 960 | { | ||
| 961 | __le64 *dma_stats = efx->stats_buffer.addr; | ||
| 962 | int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS; | ||
| 963 | |||
| 964 | dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; | ||
| 965 | efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0); | ||
| 966 | |||
| 967 | while (dma_stats[MC_CMD_MAC_GENERATION_END] == | ||
| 968 | EFX_MC_STATS_GENERATION_INVALID && | ||
| 969 | attempts-- != 0) | ||
| 970 | udelay(EFX_MAC_STATS_WAIT_US); | ||
| 976 | } | 971 | } |
| 977 | 972 | ||
| 978 | int efx_mcdi_port_probe(struct efx_nic *efx) | 973 | int efx_mcdi_port_probe(struct efx_nic *efx) |
| @@ -1003,7 +998,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx) | |||
| 1003 | efx->stats_buffer.addr, | 998 | efx->stats_buffer.addr, |
| 1004 | (u64)virt_to_phys(efx->stats_buffer.addr)); | 999 | (u64)virt_to_phys(efx->stats_buffer.addr)); |
| 1005 | 1000 | ||
| 1006 | efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 1); | 1001 | efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1); |
| 1007 | 1002 | ||
| 1008 | return 0; | 1003 | return 0; |
| 1009 | } | 1004 | } |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b14a717ac3e8..f47bac78b92c 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
| @@ -683,6 +683,8 @@ struct vfdi_status; | |||
| 683 | * @n_channels: Number of channels in use | 683 | * @n_channels: Number of channels in use |
| 684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) | 684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) |
| 685 | * @n_tx_channels: Number of channels used for TX | 685 | * @n_tx_channels: Number of channels used for TX |
| 686 | * @rx_ip_align: RX DMA address offset to have IP header aligned in | ||
| 687 | * in accordance with NET_IP_ALIGN | ||
| 686 | * @rx_dma_len: Current maximum RX DMA length | 688 | * @rx_dma_len: Current maximum RX DMA length |
| 687 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer | 689 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer |
| 688 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, | 690 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, |
| @@ -816,6 +818,7 @@ struct efx_nic { | |||
| 816 | unsigned rss_spread; | 818 | unsigned rss_spread; |
| 817 | unsigned tx_channel_offset; | 819 | unsigned tx_channel_offset; |
| 818 | unsigned n_tx_channels; | 820 | unsigned n_tx_channels; |
| 821 | unsigned int rx_ip_align; | ||
| 819 | unsigned int rx_dma_len; | 822 | unsigned int rx_dma_len; |
| 820 | unsigned int rx_buffer_order; | 823 | unsigned int rx_buffer_order; |
| 821 | unsigned int rx_buffer_truesize; | 824 | unsigned int rx_buffer_truesize; |
| @@ -849,10 +852,14 @@ struct efx_nic { | |||
| 849 | struct work_struct mac_work; | 852 | struct work_struct mac_work; |
| 850 | bool port_enabled; | 853 | bool port_enabled; |
| 851 | 854 | ||
| 855 | bool mc_bist_for_other_fn; | ||
| 852 | bool port_initialized; | 856 | bool port_initialized; |
| 853 | struct net_device *net_dev; | 857 | struct net_device *net_dev; |
| 854 | 858 | ||
| 855 | struct efx_buffer stats_buffer; | 859 | struct efx_buffer stats_buffer; |
| 860 | u64 rx_nodesc_drops_total; | ||
| 861 | u64 rx_nodesc_drops_while_down; | ||
| 862 | bool rx_nodesc_drops_prev_state; | ||
| 856 | 863 | ||
| 857 | unsigned int phy_type; | 864 | unsigned int phy_type; |
| 858 | const struct efx_phy_operations *phy_op; | 865 | const struct efx_phy_operations *phy_op; |
| @@ -956,6 +963,7 @@ struct efx_mtd_partition { | |||
| 956 | * @update_stats: Update statistics not provided by event handling. | 963 | * @update_stats: Update statistics not provided by event handling. |
| 957 | * Either argument may be %NULL. | 964 | * Either argument may be %NULL. |
| 958 | * @start_stats: Start the regular fetching of statistics | 965 | * @start_stats: Start the regular fetching of statistics |
| 966 | * @pull_stats: Pull stats from the NIC and wait until they arrive. | ||
| 959 | * @stop_stats: Stop the regular fetching of statistics | 967 | * @stop_stats: Stop the regular fetching of statistics |
| 960 | * @set_id_led: Set state of identifying LED or revert to automatic function | 968 | * @set_id_led: Set state of identifying LED or revert to automatic function |
| 961 | * @push_irq_moderation: Apply interrupt moderation value | 969 | * @push_irq_moderation: Apply interrupt moderation value |
| @@ -1074,6 +1082,7 @@ struct efx_nic_type { | |||
| 1074 | size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats, | 1082 | size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats, |
| 1075 | struct rtnl_link_stats64 *core_stats); | 1083 | struct rtnl_link_stats64 *core_stats); |
| 1076 | void (*start_stats)(struct efx_nic *efx); | 1084 | void (*start_stats)(struct efx_nic *efx); |
| 1085 | void (*pull_stats)(struct efx_nic *efx); | ||
| 1077 | void (*stop_stats)(struct efx_nic *efx); | 1086 | void (*stop_stats)(struct efx_nic *efx); |
| 1078 | void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); | 1087 | void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); |
| 1079 | void (*push_irq_moderation)(struct efx_channel *channel); | 1088 | void (*push_irq_moderation)(struct efx_channel *channel); |
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 9c90bf56090f..79226b19e3c4 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c | |||
| @@ -519,3 +519,15 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, | |||
| 519 | } | 519 | } |
| 520 | } | 520 | } |
| 521 | } | 521 | } |
| 522 | |||
| 523 | void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *rx_nodesc_drops) | ||
| 524 | { | ||
| 525 | /* if down, or this is the first update after coming up */ | ||
| 526 | if (!(efx->net_dev->flags & IFF_UP) || !efx->rx_nodesc_drops_prev_state) | ||
| 527 | efx->rx_nodesc_drops_while_down += | ||
| 528 | *rx_nodesc_drops - efx->rx_nodesc_drops_total; | ||
| 529 | efx->rx_nodesc_drops_total = *rx_nodesc_drops; | ||
| 530 | efx->rx_nodesc_drops_prev_state = !!(efx->net_dev->flags & IFF_UP); | ||
| 531 | *rx_nodesc_drops -= efx->rx_nodesc_drops_while_down; | ||
| 532 | } | ||
| 533 | |||
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 33852e824f12..25178536f053 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
| @@ -554,13 +554,17 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf, | |||
| 554 | bool spoofchk); | 554 | bool spoofchk); |
| 555 | 555 | ||
| 556 | struct ethtool_ts_info; | 556 | struct ethtool_ts_info; |
| 557 | void efx_ptp_probe(struct efx_nic *efx); | 557 | int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel); |
| 558 | void efx_ptp_defer_probe_with_channel(struct efx_nic *efx); | ||
| 559 | void efx_ptp_remove(struct efx_nic *efx); | ||
| 558 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); | 560 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); |
| 559 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); | 561 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); |
| 560 | void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); | 562 | void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); |
| 561 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 563 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
| 562 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 564 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
| 563 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); | 565 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); |
| 566 | void efx_ptp_start_datapath(struct efx_nic *efx); | ||
| 567 | void efx_ptp_stop_datapath(struct efx_nic *efx); | ||
| 564 | 568 | ||
| 565 | extern const struct efx_nic_type falcon_a1_nic_type; | 569 | extern const struct efx_nic_type falcon_a1_nic_type; |
| 566 | extern const struct efx_nic_type falcon_b0_nic_type; | 570 | extern const struct efx_nic_type falcon_b0_nic_type; |
| @@ -773,6 +777,7 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, | |||
| 773 | void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, | 777 | void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, |
| 774 | const unsigned long *mask, u64 *stats, | 778 | const unsigned long *mask, u64 *stats, |
| 775 | const void *dma_buf, bool accumulate); | 779 | const void *dma_buf, bool accumulate); |
| 780 | void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *stat); | ||
| 776 | 781 | ||
| 777 | #define EFX_MAX_FLUSH_TIME 5000 | 782 | #define EFX_MAX_FLUSH_TIME 5000 |
| 778 | 783 | ||
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index afd4d3a50460..aa4876edaac6 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
| @@ -214,12 +214,14 @@ struct efx_ptp_timeset { | |||
| 214 | 214 | ||
| 215 | /** | 215 | /** |
| 216 | * struct efx_ptp_data - Precision Time Protocol (PTP) state | 216 | * struct efx_ptp_data - Precision Time Protocol (PTP) state |
| 217 | * @channel: The PTP channel | 217 | * @efx: The NIC context |
| 218 | * @channel: The PTP channel (Siena only) | ||
| 218 | * @rxq: Receive queue (awaiting timestamps) | 219 | * @rxq: Receive queue (awaiting timestamps) |
| 219 | * @txq: Transmit queue | 220 | * @txq: Transmit queue |
| 220 | * @evt_list: List of MC receive events awaiting packets | 221 | * @evt_list: List of MC receive events awaiting packets |
| 221 | * @evt_free_list: List of free events | 222 | * @evt_free_list: List of free events |
| 222 | * @evt_lock: Lock for manipulating evt_list and evt_free_list | 223 | * @evt_lock: Lock for manipulating evt_list and evt_free_list |
| 224 | * @evt_overflow: Boolean indicating that event list has overflowed | ||
| 223 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) | 225 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) |
| 224 | * @workwq: Work queue for processing pending PTP operations | 226 | * @workwq: Work queue for processing pending PTP operations |
| 225 | * @work: Work task | 227 | * @work: Work task |
| @@ -264,12 +266,14 @@ struct efx_ptp_timeset { | |||
| 264 | * @timeset: Last set of synchronisation statistics. | 266 | * @timeset: Last set of synchronisation statistics. |
| 265 | */ | 267 | */ |
| 266 | struct efx_ptp_data { | 268 | struct efx_ptp_data { |
| 269 | struct efx_nic *efx; | ||
| 267 | struct efx_channel *channel; | 270 | struct efx_channel *channel; |
| 268 | struct sk_buff_head rxq; | 271 | struct sk_buff_head rxq; |
| 269 | struct sk_buff_head txq; | 272 | struct sk_buff_head txq; |
| 270 | struct list_head evt_list; | 273 | struct list_head evt_list; |
| 271 | struct list_head evt_free_list; | 274 | struct list_head evt_free_list; |
| 272 | spinlock_t evt_lock; | 275 | spinlock_t evt_lock; |
| 276 | bool evt_overflow; | ||
| 273 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; | 277 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; |
| 274 | struct workqueue_struct *workwq; | 278 | struct workqueue_struct *workwq; |
| 275 | struct work_struct work; | 279 | struct work_struct work; |
| @@ -311,15 +315,24 @@ static int efx_phc_enable(struct ptp_clock_info *ptp, | |||
| 311 | static int efx_ptp_enable(struct efx_nic *efx) | 315 | static int efx_ptp_enable(struct efx_nic *efx) |
| 312 | { | 316 | { |
| 313 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ENABLE_LEN); | 317 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ENABLE_LEN); |
| 318 | MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0); | ||
| 319 | int rc; | ||
| 314 | 320 | ||
| 315 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE); | 321 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE); |
| 316 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); | 322 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); |
| 317 | MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_QUEUE, | 323 | MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_QUEUE, |
| 318 | efx->ptp_data->channel->channel); | 324 | efx->ptp_data->channel ? |
| 325 | efx->ptp_data->channel->channel : 0); | ||
| 319 | MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode); | 326 | MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode); |
| 320 | 327 | ||
| 321 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), | 328 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), |
| 322 | NULL, 0, NULL); | 329 | outbuf, sizeof(outbuf), NULL); |
| 330 | rc = (rc == -EALREADY) ? 0 : rc; | ||
| 331 | if (rc) | ||
| 332 | efx_mcdi_display_error(efx, MC_CMD_PTP, | ||
| 333 | MC_CMD_PTP_IN_ENABLE_LEN, | ||
| 334 | outbuf, sizeof(outbuf), rc); | ||
| 335 | return rc; | ||
| 323 | } | 336 | } |
| 324 | 337 | ||
| 325 | /* Disable MCDI PTP support. | 338 | /* Disable MCDI PTP support. |
| @@ -330,11 +343,19 @@ static int efx_ptp_enable(struct efx_nic *efx) | |||
| 330 | static int efx_ptp_disable(struct efx_nic *efx) | 343 | static int efx_ptp_disable(struct efx_nic *efx) |
| 331 | { | 344 | { |
| 332 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_DISABLE_LEN); | 345 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_DISABLE_LEN); |
| 346 | MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0); | ||
| 347 | int rc; | ||
| 333 | 348 | ||
| 334 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_DISABLE); | 349 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_DISABLE); |
| 335 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); | 350 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); |
| 336 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), | 351 | rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), |
| 337 | NULL, 0, NULL); | 352 | outbuf, sizeof(outbuf), NULL); |
| 353 | rc = (rc == -EALREADY) ? 0 : rc; | ||
| 354 | if (rc) | ||
| 355 | efx_mcdi_display_error(efx, MC_CMD_PTP, | ||
| 356 | MC_CMD_PTP_IN_DISABLE_LEN, | ||
| 357 | outbuf, sizeof(outbuf), rc); | ||
| 358 | return rc; | ||
| 338 | } | 359 | } |
| 339 | 360 | ||
| 340 | static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q) | 361 | static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q) |
| @@ -635,6 +656,11 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx) | |||
| 635 | } | 656 | } |
| 636 | } | 657 | } |
| 637 | } | 658 | } |
| 659 | /* If the event overflow flag is set and the event list is now empty | ||
| 660 | * clear the flag to re-enable the overflow warning message. | ||
| 661 | */ | ||
| 662 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
| 663 | ptp->evt_overflow = false; | ||
| 638 | spin_unlock_bh(&ptp->evt_lock); | 664 | spin_unlock_bh(&ptp->evt_lock); |
| 639 | } | 665 | } |
| 640 | 666 | ||
| @@ -676,6 +702,11 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx, | |||
| 676 | break; | 702 | break; |
| 677 | } | 703 | } |
| 678 | } | 704 | } |
| 705 | /* If the event overflow flag is set and the event list is now empty | ||
| 706 | * clear the flag to re-enable the overflow warning message. | ||
| 707 | */ | ||
| 708 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
| 709 | ptp->evt_overflow = false; | ||
| 679 | spin_unlock_bh(&ptp->evt_lock); | 710 | spin_unlock_bh(&ptp->evt_lock); |
| 680 | 711 | ||
| 681 | return rc; | 712 | return rc; |
| @@ -705,8 +736,9 @@ static bool efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q) | |||
| 705 | __skb_queue_tail(q, skb); | 736 | __skb_queue_tail(q, skb); |
| 706 | } else if (time_after(jiffies, match->expiry)) { | 737 | } else if (time_after(jiffies, match->expiry)) { |
| 707 | match->state = PTP_PACKET_STATE_TIMED_OUT; | 738 | match->state = PTP_PACKET_STATE_TIMED_OUT; |
| 708 | netif_warn(efx, rx_err, efx->net_dev, | 739 | if (net_ratelimit()) |
| 709 | "PTP packet - no timestamp seen\n"); | 740 | netif_warn(efx, rx_err, efx->net_dev, |
| 741 | "PTP packet - no timestamp seen\n"); | ||
| 710 | __skb_queue_tail(q, skb); | 742 | __skb_queue_tail(q, skb); |
| 711 | } else { | 743 | } else { |
| 712 | /* Replace unprocessed entry and stop */ | 744 | /* Replace unprocessed entry and stop */ |
| @@ -726,13 +758,27 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) | |||
| 726 | local_bh_enable(); | 758 | local_bh_enable(); |
| 727 | } | 759 | } |
| 728 | 760 | ||
| 729 | static int efx_ptp_start(struct efx_nic *efx) | 761 | static void efx_ptp_remove_multicast_filters(struct efx_nic *efx) |
| 762 | { | ||
| 763 | struct efx_ptp_data *ptp = efx->ptp_data; | ||
| 764 | |||
| 765 | if (ptp->rxfilter_installed) { | ||
| 766 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | ||
| 767 | ptp->rxfilter_general); | ||
| 768 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | ||
| 769 | ptp->rxfilter_event); | ||
| 770 | ptp->rxfilter_installed = false; | ||
| 771 | } | ||
| 772 | } | ||
| 773 | |||
| 774 | static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) | ||
| 730 | { | 775 | { |
| 731 | struct efx_ptp_data *ptp = efx->ptp_data; | 776 | struct efx_ptp_data *ptp = efx->ptp_data; |
| 732 | struct efx_filter_spec rxfilter; | 777 | struct efx_filter_spec rxfilter; |
| 733 | int rc; | 778 | int rc; |
| 734 | 779 | ||
| 735 | ptp->reset_required = false; | 780 | if (!ptp->channel || ptp->rxfilter_installed) |
| 781 | return 0; | ||
| 736 | 782 | ||
| 737 | /* Must filter on both event and general ports to ensure | 783 | /* Must filter on both event and general ports to ensure |
| 738 | * that there is no packet re-ordering. | 784 | * that there is no packet re-ordering. |
| @@ -765,40 +811,53 @@ static int efx_ptp_start(struct efx_nic *efx) | |||
| 765 | goto fail; | 811 | goto fail; |
| 766 | ptp->rxfilter_general = rc; | 812 | ptp->rxfilter_general = rc; |
| 767 | 813 | ||
| 814 | ptp->rxfilter_installed = true; | ||
| 815 | return 0; | ||
| 816 | |||
| 817 | fail: | ||
| 818 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | ||
| 819 | ptp->rxfilter_event); | ||
| 820 | return rc; | ||
| 821 | } | ||
| 822 | |||
| 823 | static int efx_ptp_start(struct efx_nic *efx) | ||
| 824 | { | ||
| 825 | struct efx_ptp_data *ptp = efx->ptp_data; | ||
| 826 | int rc; | ||
| 827 | |||
| 828 | ptp->reset_required = false; | ||
| 829 | |||
| 830 | rc = efx_ptp_insert_multicast_filters(efx); | ||
| 831 | if (rc) | ||
| 832 | return rc; | ||
| 833 | |||
| 768 | rc = efx_ptp_enable(efx); | 834 | rc = efx_ptp_enable(efx); |
| 769 | if (rc != 0) | 835 | if (rc != 0) |
| 770 | goto fail2; | 836 | goto fail; |
| 771 | 837 | ||
| 772 | ptp->evt_frag_idx = 0; | 838 | ptp->evt_frag_idx = 0; |
| 773 | ptp->current_adjfreq = 0; | 839 | ptp->current_adjfreq = 0; |
| 774 | ptp->rxfilter_installed = true; | ||
| 775 | 840 | ||
| 776 | return 0; | 841 | return 0; |
| 777 | 842 | ||
| 778 | fail2: | ||
| 779 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | ||
| 780 | ptp->rxfilter_general); | ||
| 781 | fail: | 843 | fail: |
| 782 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | 844 | efx_ptp_remove_multicast_filters(efx); |
| 783 | ptp->rxfilter_event); | ||
| 784 | |||
| 785 | return rc; | 845 | return rc; |
| 786 | } | 846 | } |
| 787 | 847 | ||
| 788 | static int efx_ptp_stop(struct efx_nic *efx) | 848 | static int efx_ptp_stop(struct efx_nic *efx) |
| 789 | { | 849 | { |
| 790 | struct efx_ptp_data *ptp = efx->ptp_data; | 850 | struct efx_ptp_data *ptp = efx->ptp_data; |
| 791 | int rc = efx_ptp_disable(efx); | ||
| 792 | struct list_head *cursor; | 851 | struct list_head *cursor; |
| 793 | struct list_head *next; | 852 | struct list_head *next; |
| 853 | int rc; | ||
| 794 | 854 | ||
| 795 | if (ptp->rxfilter_installed) { | 855 | if (ptp == NULL) |
| 796 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | 856 | return 0; |
| 797 | ptp->rxfilter_general); | 857 | |
| 798 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | 858 | rc = efx_ptp_disable(efx); |
| 799 | ptp->rxfilter_event); | 859 | |
| 800 | ptp->rxfilter_installed = false; | 860 | efx_ptp_remove_multicast_filters(efx); |
| 801 | } | ||
| 802 | 861 | ||
| 803 | /* Make sure RX packets are really delivered */ | 862 | /* Make sure RX packets are really delivered */ |
| 804 | efx_ptp_deliver_rx_queue(&efx->ptp_data->rxq); | 863 | efx_ptp_deliver_rx_queue(&efx->ptp_data->rxq); |
| @@ -809,16 +868,24 @@ static int efx_ptp_stop(struct efx_nic *efx) | |||
| 809 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { | 868 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { |
| 810 | list_move(cursor, &efx->ptp_data->evt_free_list); | 869 | list_move(cursor, &efx->ptp_data->evt_free_list); |
| 811 | } | 870 | } |
| 871 | ptp->evt_overflow = false; | ||
| 812 | spin_unlock_bh(&efx->ptp_data->evt_lock); | 872 | spin_unlock_bh(&efx->ptp_data->evt_lock); |
| 813 | 873 | ||
| 814 | return rc; | 874 | return rc; |
| 815 | } | 875 | } |
| 816 | 876 | ||
| 877 | static int efx_ptp_restart(struct efx_nic *efx) | ||
| 878 | { | ||
| 879 | if (efx->ptp_data && efx->ptp_data->enabled) | ||
| 880 | return efx_ptp_start(efx); | ||
| 881 | return 0; | ||
| 882 | } | ||
| 883 | |||
| 817 | static void efx_ptp_pps_worker(struct work_struct *work) | 884 | static void efx_ptp_pps_worker(struct work_struct *work) |
| 818 | { | 885 | { |
| 819 | struct efx_ptp_data *ptp = | 886 | struct efx_ptp_data *ptp = |
| 820 | container_of(work, struct efx_ptp_data, pps_work); | 887 | container_of(work, struct efx_ptp_data, pps_work); |
| 821 | struct efx_nic *efx = ptp->channel->efx; | 888 | struct efx_nic *efx = ptp->efx; |
| 822 | struct ptp_clock_event ptp_evt; | 889 | struct ptp_clock_event ptp_evt; |
| 823 | 890 | ||
| 824 | if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS)) | 891 | if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS)) |
| @@ -835,7 +902,7 @@ static void efx_ptp_worker(struct work_struct *work) | |||
| 835 | { | 902 | { |
| 836 | struct efx_ptp_data *ptp_data = | 903 | struct efx_ptp_data *ptp_data = |
| 837 | container_of(work, struct efx_ptp_data, work); | 904 | container_of(work, struct efx_ptp_data, work); |
| 838 | struct efx_nic *efx = ptp_data->channel->efx; | 905 | struct efx_nic *efx = ptp_data->efx; |
| 839 | struct sk_buff *skb; | 906 | struct sk_buff *skb; |
| 840 | struct sk_buff_head tempq; | 907 | struct sk_buff_head tempq; |
| 841 | 908 | ||
| @@ -859,31 +926,25 @@ static void efx_ptp_worker(struct work_struct *work) | |||
| 859 | efx_ptp_process_rx(efx, skb); | 926 | efx_ptp_process_rx(efx, skb); |
| 860 | } | 927 | } |
| 861 | 928 | ||
| 862 | /* Initialise PTP channel and state. | 929 | /* Initialise PTP state. */ |
| 863 | * | 930 | int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) |
| 864 | * Setting core_index to zero causes the queue to be initialised and doesn't | ||
| 865 | * overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue. | ||
| 866 | */ | ||
| 867 | static int efx_ptp_probe_channel(struct efx_channel *channel) | ||
| 868 | { | 931 | { |
| 869 | struct efx_nic *efx = channel->efx; | ||
| 870 | struct efx_ptp_data *ptp; | 932 | struct efx_ptp_data *ptp; |
| 871 | int rc = 0; | 933 | int rc = 0; |
| 872 | unsigned int pos; | 934 | unsigned int pos; |
| 873 | 935 | ||
| 874 | channel->irq_moderation = 0; | ||
| 875 | channel->rx_queue.core_index = 0; | ||
| 876 | |||
| 877 | ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); | 936 | ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); |
| 878 | efx->ptp_data = ptp; | 937 | efx->ptp_data = ptp; |
| 879 | if (!efx->ptp_data) | 938 | if (!efx->ptp_data) |
| 880 | return -ENOMEM; | 939 | return -ENOMEM; |
| 881 | 940 | ||
| 941 | ptp->efx = efx; | ||
| 942 | ptp->channel = channel; | ||
| 943 | |||
| 882 | rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL); | 944 | rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL); |
| 883 | if (rc != 0) | 945 | if (rc != 0) |
| 884 | goto fail1; | 946 | goto fail1; |
| 885 | 947 | ||
| 886 | ptp->channel = channel; | ||
| 887 | skb_queue_head_init(&ptp->rxq); | 948 | skb_queue_head_init(&ptp->rxq); |
| 888 | skb_queue_head_init(&ptp->txq); | 949 | skb_queue_head_init(&ptp->txq); |
| 889 | ptp->workwq = create_singlethread_workqueue("sfc_ptp"); | 950 | ptp->workwq = create_singlethread_workqueue("sfc_ptp"); |
| @@ -901,6 +962,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel) | |||
| 901 | spin_lock_init(&ptp->evt_lock); | 962 | spin_lock_init(&ptp->evt_lock); |
| 902 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) | 963 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) |
| 903 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); | 964 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); |
| 965 | ptp->evt_overflow = false; | ||
| 904 | 966 | ||
| 905 | ptp->phc_clock_info.owner = THIS_MODULE; | 967 | ptp->phc_clock_info.owner = THIS_MODULE; |
| 906 | snprintf(ptp->phc_clock_info.name, | 968 | snprintf(ptp->phc_clock_info.name, |
| @@ -949,14 +1011,27 @@ fail1: | |||
| 949 | return rc; | 1011 | return rc; |
| 950 | } | 1012 | } |
| 951 | 1013 | ||
| 952 | static void efx_ptp_remove_channel(struct efx_channel *channel) | 1014 | /* Initialise PTP channel. |
| 1015 | * | ||
| 1016 | * Setting core_index to zero causes the queue to be initialised and doesn't | ||
| 1017 | * overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue. | ||
| 1018 | */ | ||
| 1019 | static int efx_ptp_probe_channel(struct efx_channel *channel) | ||
| 953 | { | 1020 | { |
| 954 | struct efx_nic *efx = channel->efx; | 1021 | struct efx_nic *efx = channel->efx; |
| 955 | 1022 | ||
| 1023 | channel->irq_moderation = 0; | ||
| 1024 | channel->rx_queue.core_index = 0; | ||
| 1025 | |||
| 1026 | return efx_ptp_probe(efx, channel); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | void efx_ptp_remove(struct efx_nic *efx) | ||
| 1030 | { | ||
| 956 | if (!efx->ptp_data) | 1031 | if (!efx->ptp_data) |
| 957 | return; | 1032 | return; |
| 958 | 1033 | ||
| 959 | (void)efx_ptp_disable(channel->efx); | 1034 | (void)efx_ptp_disable(efx); |
| 960 | 1035 | ||
| 961 | cancel_work_sync(&efx->ptp_data->work); | 1036 | cancel_work_sync(&efx->ptp_data->work); |
| 962 | cancel_work_sync(&efx->ptp_data->pps_work); | 1037 | cancel_work_sync(&efx->ptp_data->pps_work); |
| @@ -973,6 +1048,11 @@ static void efx_ptp_remove_channel(struct efx_channel *channel) | |||
| 973 | kfree(efx->ptp_data); | 1048 | kfree(efx->ptp_data); |
| 974 | } | 1049 | } |
| 975 | 1050 | ||
| 1051 | static void efx_ptp_remove_channel(struct efx_channel *channel) | ||
| 1052 | { | ||
| 1053 | efx_ptp_remove(channel->efx); | ||
| 1054 | } | ||
| 1055 | |||
| 976 | static void efx_ptp_get_channel_name(struct efx_channel *channel, | 1056 | static void efx_ptp_get_channel_name(struct efx_channel *channel, |
| 977 | char *buf, size_t len) | 1057 | char *buf, size_t len) |
| 978 | { | 1058 | { |
| @@ -989,7 +1069,11 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) | |||
| 989 | skb->len >= PTP_MIN_LENGTH && | 1069 | skb->len >= PTP_MIN_LENGTH && |
| 990 | skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM && | 1070 | skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM && |
| 991 | likely(skb->protocol == htons(ETH_P_IP)) && | 1071 | likely(skb->protocol == htons(ETH_P_IP)) && |
| 1072 | skb_transport_header_was_set(skb) && | ||
| 1073 | skb_network_header_len(skb) >= sizeof(struct iphdr) && | ||
| 992 | ip_hdr(skb)->protocol == IPPROTO_UDP && | 1074 | ip_hdr(skb)->protocol == IPPROTO_UDP && |
| 1075 | skb_headlen(skb) >= | ||
| 1076 | skb_transport_offset(skb) + sizeof(struct udphdr) && | ||
| 993 | udp_hdr(skb)->dest == htons(PTP_EVENT_PORT); | 1077 | udp_hdr(skb)->dest == htons(PTP_EVENT_PORT); |
| 994 | } | 1078 | } |
| 995 | 1079 | ||
| @@ -1106,7 +1190,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | |||
| 1106 | { | 1190 | { |
| 1107 | if ((enable_wanted != efx->ptp_data->enabled) || | 1191 | if ((enable_wanted != efx->ptp_data->enabled) || |
| 1108 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { | 1192 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { |
| 1109 | int rc; | 1193 | int rc = 0; |
| 1110 | 1194 | ||
| 1111 | if (enable_wanted) { | 1195 | if (enable_wanted) { |
| 1112 | /* Change of mode requires disable */ | 1196 | /* Change of mode requires disable */ |
| @@ -1123,7 +1207,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | |||
| 1123 | * succeed. | 1207 | * succeed. |
| 1124 | */ | 1208 | */ |
| 1125 | efx->ptp_data->mode = new_mode; | 1209 | efx->ptp_data->mode = new_mode; |
| 1126 | rc = efx_ptp_start(efx); | 1210 | if (netif_running(efx->net_dev)) |
| 1211 | rc = efx_ptp_start(efx); | ||
| 1127 | if (rc == 0) { | 1212 | if (rc == 0) { |
| 1128 | rc = efx_ptp_synchronize(efx, | 1213 | rc = efx_ptp_synchronize(efx, |
| 1129 | PTP_SYNC_ATTEMPTS * 2); | 1214 | PTP_SYNC_ATTEMPTS * 2); |
| @@ -1304,8 +1389,13 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp) | |||
| 1304 | list_add_tail(&evt->link, &ptp->evt_list); | 1389 | list_add_tail(&evt->link, &ptp->evt_list); |
| 1305 | 1390 | ||
| 1306 | queue_work(ptp->workwq, &ptp->work); | 1391 | queue_work(ptp->workwq, &ptp->work); |
| 1307 | } else { | 1392 | } else if (!ptp->evt_overflow) { |
| 1308 | netif_err(efx, rx_err, efx->net_dev, "No free PTP event"); | 1393 | /* Log a warning message and set the event overflow flag. |
| 1394 | * The message won't be logged again until the event queue | ||
| 1395 | * becomes empty. | ||
| 1396 | */ | ||
| 1397 | netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n"); | ||
| 1398 | ptp->evt_overflow = true; | ||
| 1309 | } | 1399 | } |
| 1310 | spin_unlock_bh(&ptp->evt_lock); | 1400 | spin_unlock_bh(&ptp->evt_lock); |
| 1311 | } | 1401 | } |
| @@ -1374,7 +1464,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) | |||
| 1374 | struct efx_ptp_data *ptp_data = container_of(ptp, | 1464 | struct efx_ptp_data *ptp_data = container_of(ptp, |
| 1375 | struct efx_ptp_data, | 1465 | struct efx_ptp_data, |
| 1376 | phc_clock_info); | 1466 | phc_clock_info); |
| 1377 | struct efx_nic *efx = ptp_data->channel->efx; | 1467 | struct efx_nic *efx = ptp_data->efx; |
| 1378 | MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN); | 1468 | MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN); |
| 1379 | s64 adjustment_ns; | 1469 | s64 adjustment_ns; |
| 1380 | int rc; | 1470 | int rc; |
| @@ -1398,7 +1488,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) | |||
| 1398 | if (rc != 0) | 1488 | if (rc != 0) |
| 1399 | return rc; | 1489 | return rc; |
| 1400 | 1490 | ||
| 1401 | ptp_data->current_adjfreq = delta; | 1491 | ptp_data->current_adjfreq = adjustment_ns; |
| 1402 | return 0; | 1492 | return 0; |
| 1403 | } | 1493 | } |
| 1404 | 1494 | ||
| @@ -1407,13 +1497,13 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
| 1407 | struct efx_ptp_data *ptp_data = container_of(ptp, | 1497 | struct efx_ptp_data *ptp_data = container_of(ptp, |
| 1408 | struct efx_ptp_data, | 1498 | struct efx_ptp_data, |
| 1409 | phc_clock_info); | 1499 | phc_clock_info); |
| 1410 | struct efx_nic *efx = ptp_data->channel->efx; | 1500 | struct efx_nic *efx = ptp_data->efx; |
| 1411 | struct timespec delta_ts = ns_to_timespec(delta); | 1501 | struct timespec delta_ts = ns_to_timespec(delta); |
| 1412 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN); | 1502 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN); |
| 1413 | 1503 | ||
| 1414 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST); | 1504 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST); |
| 1415 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); | 1505 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); |
| 1416 | MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, 0); | 1506 | MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq); |
| 1417 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec); | 1507 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec); |
| 1418 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec); | 1508 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec); |
| 1419 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), | 1509 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), |
| @@ -1425,7 +1515,7 @@ static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | |||
| 1425 | struct efx_ptp_data *ptp_data = container_of(ptp, | 1515 | struct efx_ptp_data *ptp_data = container_of(ptp, |
| 1426 | struct efx_ptp_data, | 1516 | struct efx_ptp_data, |
| 1427 | phc_clock_info); | 1517 | phc_clock_info); |
| 1428 | struct efx_nic *efx = ptp_data->channel->efx; | 1518 | struct efx_nic *efx = ptp_data->efx; |
| 1429 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_READ_NIC_TIME_LEN); | 1519 | MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_READ_NIC_TIME_LEN); |
| 1430 | MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_READ_NIC_TIME_LEN); | 1520 | MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_READ_NIC_TIME_LEN); |
| 1431 | int rc; | 1521 | int rc; |
| @@ -1491,7 +1581,7 @@ static const struct efx_channel_type efx_ptp_channel_type = { | |||
| 1491 | .keep_eventq = false, | 1581 | .keep_eventq = false, |
| 1492 | }; | 1582 | }; |
| 1493 | 1583 | ||
| 1494 | void efx_ptp_probe(struct efx_nic *efx) | 1584 | void efx_ptp_defer_probe_with_channel(struct efx_nic *efx) |
| 1495 | { | 1585 | { |
| 1496 | /* Check whether PTP is implemented on this NIC. The DISABLE | 1586 | /* Check whether PTP is implemented on this NIC. The DISABLE |
| 1497 | * operation will succeed if and only if it is implemented. | 1587 | * operation will succeed if and only if it is implemented. |
| @@ -1500,3 +1590,14 @@ void efx_ptp_probe(struct efx_nic *efx) | |||
| 1500 | efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = | 1590 | efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = |
| 1501 | &efx_ptp_channel_type; | 1591 | &efx_ptp_channel_type; |
| 1502 | } | 1592 | } |
| 1593 | |||
| 1594 | void efx_ptp_start_datapath(struct efx_nic *efx) | ||
| 1595 | { | ||
| 1596 | if (efx_ptp_restart(efx)) | ||
| 1597 | netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n"); | ||
| 1598 | } | ||
| 1599 | |||
| 1600 | void efx_ptp_stop_datapath(struct efx_nic *efx) | ||
| 1601 | { | ||
| 1602 | efx_ptp_stop(efx); | ||
| 1603 | } | ||
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 8f09e686fc23..8671bc199a9d 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
| @@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, | |||
| 94 | 94 | ||
| 95 | void efx_rx_config_page_split(struct efx_nic *efx) | 95 | void efx_rx_config_page_split(struct efx_nic *efx) |
| 96 | { | 96 | { |
| 97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN, | 97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align, |
| 98 | EFX_RX_BUF_ALIGNMENT); | 98 | EFX_RX_BUF_ALIGNMENT); |
| 99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : | 99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : |
| 100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / | 100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / |
| @@ -149,7 +149,7 @@ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) | |||
| 149 | * 0 on success. If a single page can be used for multiple buffers, | 149 | * 0 on success. If a single page can be used for multiple buffers, |
| 150 | * then the page will either be inserted fully, or not at all. | 150 | * then the page will either be inserted fully, or not at all. |
| 151 | */ | 151 | */ |
| 152 | static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | 152 | static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue, bool atomic) |
| 153 | { | 153 | { |
| 154 | struct efx_nic *efx = rx_queue->efx; | 154 | struct efx_nic *efx = rx_queue->efx; |
| 155 | struct efx_rx_buffer *rx_buf; | 155 | struct efx_rx_buffer *rx_buf; |
| @@ -163,7 +163,8 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | |||
| 163 | do { | 163 | do { |
| 164 | page = efx_reuse_page(rx_queue); | 164 | page = efx_reuse_page(rx_queue); |
| 165 | if (page == NULL) { | 165 | if (page == NULL) { |
| 166 | page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC, | 166 | page = alloc_pages(__GFP_COLD | __GFP_COMP | |
| 167 | (atomic ? GFP_ATOMIC : GFP_KERNEL), | ||
| 167 | efx->rx_buffer_order); | 168 | efx->rx_buffer_order); |
| 168 | if (unlikely(page == NULL)) | 169 | if (unlikely(page == NULL)) |
| 169 | return -ENOMEM; | 170 | return -ENOMEM; |
| @@ -189,9 +190,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | |||
| 189 | do { | 190 | do { |
| 190 | index = rx_queue->added_count & rx_queue->ptr_mask; | 191 | index = rx_queue->added_count & rx_queue->ptr_mask; |
| 191 | rx_buf = efx_rx_buffer(rx_queue, index); | 192 | rx_buf = efx_rx_buffer(rx_queue, index); |
| 192 | rx_buf->dma_addr = dma_addr + NET_IP_ALIGN; | 193 | rx_buf->dma_addr = dma_addr + efx->rx_ip_align; |
| 193 | rx_buf->page = page; | 194 | rx_buf->page = page; |
| 194 | rx_buf->page_offset = page_offset + NET_IP_ALIGN; | 195 | rx_buf->page_offset = page_offset + efx->rx_ip_align; |
| 195 | rx_buf->len = efx->rx_dma_len; | 196 | rx_buf->len = efx->rx_dma_len; |
| 196 | rx_buf->flags = 0; | 197 | rx_buf->flags = 0; |
| 197 | ++rx_queue->added_count; | 198 | ++rx_queue->added_count; |
| @@ -321,7 +322,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel, | |||
| 321 | * this means this function must run from the NAPI handler, or be called | 322 | * this means this function must run from the NAPI handler, or be called |
| 322 | * when NAPI is disabled. | 323 | * when NAPI is disabled. |
| 323 | */ | 324 | */ |
| 324 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) | 325 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic) |
| 325 | { | 326 | { |
| 326 | struct efx_nic *efx = rx_queue->efx; | 327 | struct efx_nic *efx = rx_queue->efx; |
| 327 | unsigned int fill_level, batch_size; | 328 | unsigned int fill_level, batch_size; |
| @@ -354,7 +355,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) | |||
| 354 | 355 | ||
| 355 | 356 | ||
| 356 | do { | 357 | do { |
| 357 | rc = efx_init_rx_buffers(rx_queue); | 358 | rc = efx_init_rx_buffers(rx_queue, atomic); |
| 358 | if (unlikely(rc)) { | 359 | if (unlikely(rc)) { |
| 359 | /* Ensure that we don't leave the rx queue empty */ | 360 | /* Ensure that we don't leave the rx queue empty */ |
| 360 | if (rx_queue->added_count == rx_queue->removed_count) | 361 | if (rx_queue->added_count == rx_queue->removed_count) |
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 144bbff5a4ae..26641817a9c7 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c | |||
| @@ -722,7 +722,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, | |||
| 722 | return rc_reset; | 722 | return rc_reset; |
| 723 | } | 723 | } |
| 724 | 724 | ||
| 725 | if ((tests->registers < 0) && !rc_test) | 725 | if ((tests->memory < 0 || tests->registers < 0) && !rc_test) |
| 726 | rc_test = -EIO; | 726 | rc_test = -EIO; |
| 727 | } | 727 | } |
| 728 | 728 | ||
diff --git a/drivers/net/ethernet/sfc/selftest.h b/drivers/net/ethernet/sfc/selftest.h index a2f4a06ffa4e..009dbe88f3be 100644 --- a/drivers/net/ethernet/sfc/selftest.h +++ b/drivers/net/ethernet/sfc/selftest.h | |||
| @@ -38,6 +38,7 @@ struct efx_self_tests { | |||
| 38 | int eventq_dma[EFX_MAX_CHANNELS]; | 38 | int eventq_dma[EFX_MAX_CHANNELS]; |
| 39 | int eventq_int[EFX_MAX_CHANNELS]; | 39 | int eventq_int[EFX_MAX_CHANNELS]; |
| 40 | /* offline tests */ | 40 | /* offline tests */ |
| 41 | int memory; | ||
| 41 | int registers; | 42 | int registers; |
| 42 | int phy_ext[EFX_MAX_PHY_TESTS]; | 43 | int phy_ext[EFX_MAX_PHY_TESTS]; |
| 43 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; | 44 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; |
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index d034bcd124ef..53b4ce67be0e 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c | |||
| @@ -259,7 +259,7 @@ static int siena_probe_nic(struct efx_nic *efx) | |||
| 259 | goto fail5; | 259 | goto fail5; |
| 260 | 260 | ||
| 261 | efx_sriov_probe(efx); | 261 | efx_sriov_probe(efx); |
| 262 | efx_ptp_probe(efx); | 262 | efx_ptp_defer_probe_with_channel(efx); |
| 263 | 263 | ||
| 264 | return 0; | 264 | return 0; |
| 265 | 265 | ||
| @@ -458,6 +458,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) | |||
| 458 | return -EAGAIN; | 458 | return -EAGAIN; |
| 459 | 459 | ||
| 460 | /* Update derived statistics */ | 460 | /* Update derived statistics */ |
| 461 | efx_nic_fix_nodesc_drop_stat(efx, | ||
| 462 | &stats[SIENA_STAT_rx_nodesc_drop_cnt]); | ||
| 461 | efx_update_diff_stat(&stats[SIENA_STAT_tx_good_bytes], | 463 | efx_update_diff_stat(&stats[SIENA_STAT_tx_good_bytes], |
| 462 | stats[SIENA_STAT_tx_bytes] - | 464 | stats[SIENA_STAT_tx_bytes] - |
| 463 | stats[SIENA_STAT_tx_bad_bytes]); | 465 | stats[SIENA_STAT_tx_bad_bytes]); |
| @@ -878,6 +880,7 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
| 878 | .describe_stats = siena_describe_nic_stats, | 880 | .describe_stats = siena_describe_nic_stats, |
| 879 | .update_stats = siena_update_nic_stats, | 881 | .update_stats = siena_update_nic_stats, |
| 880 | .start_stats = efx_mcdi_mac_start_stats, | 882 | .start_stats = efx_mcdi_mac_start_stats, |
| 883 | .pull_stats = efx_mcdi_mac_pull_stats, | ||
| 881 | .stop_stats = efx_mcdi_mac_stop_stats, | 884 | .stop_stats = efx_mcdi_mac_stop_stats, |
| 882 | .set_id_led = efx_mcdi_set_id_led, | 885 | .set_id_led = efx_mcdi_set_id_led, |
| 883 | .push_irq_moderation = siena_push_irq_moderation, | 886 | .push_irq_moderation = siena_push_irq_moderation, |
