hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/net/ethernet/sfc/mcdi.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /****************************************************************************
23 * Driver for Solarflare network controllers and boards
34 * Copyright 2008-2013 Solarflare Communications Inc.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License version 2 as published
7
- * by the Free Software Foundation, incorporated herein by reference.
85 */
96
107 #include <linux/delay.h>
....@@ -166,9 +163,9 @@
166163 /* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
167164 spin_lock_bh(&mcdi->iface_lock);
168165 ++mcdi->seqno;
166
+ seqno = mcdi->seqno & SEQ_MASK;
169167 spin_unlock_bh(&mcdi->iface_lock);
170168
171
- seqno = mcdi->seqno & SEQ_MASK;
172169 xflags = 0;
173170 if (mcdi->mode == MCDI_MODE_EVENTS)
174171 xflags |= MCDI_HEADER_XFLAGS_EVREQ;
....@@ -215,12 +212,14 @@
215212 * progress on a NIC at any one time. So no need for locking.
216213 */
217214 for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++)
218
- bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
219
- " %08x", le32_to_cpu(hdr[i].u32[0]));
215
+ bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
216
+ " %08x",
217
+ le32_to_cpu(hdr[i].u32[0]));
220218
221219 for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++)
222
- bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
223
- " %08x", le32_to_cpu(inbuf[i].u32[0]));
220
+ bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
221
+ " %08x",
222
+ le32_to_cpu(inbuf[i].u32[0]));
224223
225224 netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf);
226225 }
....@@ -305,15 +304,15 @@
305304 */
306305 for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) {
307306 efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4);
308
- bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
309
- " %08x", le32_to_cpu(hdr.u32[0]));
307
+ bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
308
+ " %08x", le32_to_cpu(hdr.u32[0]));
310309 }
311310
312311 for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) {
313312 efx->type->mcdi_read_response(efx, &hdr,
314313 mcdi->resp_hdr_len + (i * 4), 4);
315
- bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
316
- " %08x", le32_to_cpu(hdr.u32[0]));
314
+ bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
315
+ " %08x", le32_to_cpu(hdr.u32[0]));
317316 }
318317
319318 netif_info(efx, hw, efx->net_dev, "MCDI RPC RESP:%s\n", buf);
....@@ -1300,6 +1299,14 @@
13001299 efx_schedule_reset(efx, RESET_TYPE_MCDI_TIMEOUT);
13011300 }
13021301
1302
+static void efx_handle_drain_event(struct efx_nic *efx)
1303
+{
1304
+ if (atomic_dec_and_test(&efx->active_queues))
1305
+ wake_up(&efx->flush_wq);
1306
+
1307
+ WARN_ON(atomic_read(&efx->active_queues) < 0);
1308
+}
1309
+
13031310 /* Called from efx_farch_ev_process and efx_ef10_ev_process for MCDI events */
13041311 void efx_mcdi_process_event(struct efx_channel *channel,
13051312 efx_qword_t *event)
....@@ -1330,7 +1337,7 @@
13301337 efx_mcdi_process_link_change(efx, event);
13311338 break;
13321339 case MCDI_EVENT_CODE_SENSOREVT:
1333
- efx_mcdi_sensor_event(efx, event);
1340
+ efx_sensor_event(efx, event);
13341341 break;
13351342 case MCDI_EVENT_CODE_SCHEDERR:
13361343 netif_dbg(efx, hw, efx->net_dev,
....@@ -1372,7 +1379,7 @@
13721379 BUILD_BUG_ON(MCDI_EVENT_TX_FLUSH_TO_DRIVER_LBN !=
13731380 MCDI_EVENT_RX_FLUSH_TO_DRIVER_LBN);
13741381 if (!MCDI_EVENT_FIELD(*event, TX_FLUSH_TO_DRIVER))
1375
- efx_ef10_handle_drain_event(efx);
1382
+ efx_handle_drain_event(efx);
13761383 break;
13771384 case MCDI_EVENT_CODE_TX_ERR:
13781385 case MCDI_EVENT_CODE_RX_ERR:
....@@ -1420,27 +1427,22 @@
14201427 }
14211428
14221429 ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION);
1423
- offset = snprintf(buf, len, "%u.%u.%u.%u",
1424
- le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]),
1425
- le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3]));
1430
+ offset = scnprintf(buf, len, "%u.%u.%u.%u",
1431
+ le16_to_cpu(ver_words[0]),
1432
+ le16_to_cpu(ver_words[1]),
1433
+ le16_to_cpu(ver_words[2]),
1434
+ le16_to_cpu(ver_words[3]));
14261435
1427
- /* EF10 may have multiple datapath firmware variants within a
1428
- * single version. Report which variants are running.
1436
+ if (efx->type->print_additional_fwver)
1437
+ offset += efx->type->print_additional_fwver(efx, buf + offset,
1438
+ len - offset);
1439
+
1440
+ /* It's theoretically possible for the string to exceed 31
1441
+ * characters, though in practice the first three version
1442
+ * components are short enough that this doesn't happen.
14291443 */
1430
- if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
1431
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
1432
-
1433
- offset += snprintf(buf + offset, len - offset, " rx%x tx%x",
1434
- nic_data->rx_dpcpu_fw_id,
1435
- nic_data->tx_dpcpu_fw_id);
1436
-
1437
- /* It's theoretically possible for the string to exceed 31
1438
- * characters, though in practice the first three version
1439
- * components are short enough that this doesn't happen.
1440
- */
1441
- if (WARN_ON(offset >= len))
1442
- buf[0] = 0;
1443
- }
1444
+ if (WARN_ON(offset >= len))
1445
+ buf[0] = 0;
14441446
14451447 return;
14461448
....@@ -1619,6 +1621,35 @@
16191621 return rc;
16201622 }
16211623
1624
+/* This function finds types using the new NVRAM_PARTITIONS mcdi. */
1625
+static int efx_new_mcdi_nvram_types(struct efx_nic *efx, u32 *number,
1626
+ u32 *nvram_types)
1627
+{
1628
+ efx_dword_t *outbuf = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
1629
+ GFP_KERNEL);
1630
+ size_t outlen;
1631
+ int rc;
1632
+
1633
+ if (!outbuf)
1634
+ return -ENOMEM;
1635
+
1636
+ BUILD_BUG_ON(MC_CMD_NVRAM_PARTITIONS_IN_LEN != 0);
1637
+
1638
+ rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_PARTITIONS, NULL, 0,
1639
+ outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2, &outlen);
1640
+ if (rc)
1641
+ goto fail;
1642
+
1643
+ *number = MCDI_DWORD(outbuf, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
1644
+
1645
+ memcpy(nvram_types, MCDI_PTR(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID),
1646
+ *number * sizeof(u32));
1647
+
1648
+fail:
1649
+ kfree(outbuf);
1650
+ return rc;
1651
+}
1652
+
16221653 int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
16231654 size_t *size_out, size_t *erase_size_out,
16241655 bool *protected_out)
....@@ -1670,6 +1701,39 @@
16701701 default:
16711702 return -EIO;
16721703 }
1704
+}
1705
+
1706
+/* This function tests nvram partitions using the new mcdi partition lookup scheme */
1707
+int efx_new_mcdi_nvram_test_all(struct efx_nic *efx)
1708
+{
1709
+ u32 *nvram_types = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
1710
+ GFP_KERNEL);
1711
+ unsigned int number;
1712
+ int rc, i;
1713
+
1714
+ if (!nvram_types)
1715
+ return -ENOMEM;
1716
+
1717
+ rc = efx_new_mcdi_nvram_types(efx, &number, nvram_types);
1718
+ if (rc)
1719
+ goto fail;
1720
+
1721
+ /* Require at least one check */
1722
+ rc = -EAGAIN;
1723
+
1724
+ for (i = 0; i < number; i++) {
1725
+ if (nvram_types[i] == NVRAM_PARTITION_TYPE_PARTITION_MAP ||
1726
+ nvram_types[i] == NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG)
1727
+ continue;
1728
+
1729
+ rc = efx_mcdi_nvram_test(efx, nvram_types[i]);
1730
+ if (rc)
1731
+ goto fail;
1732
+ }
1733
+
1734
+fail:
1735
+ kfree(nvram_types);
1736
+ return rc;
16731737 }
16741738
16751739 int efx_mcdi_nvram_test_all(struct efx_nic *efx)
....@@ -1804,10 +1868,9 @@
18041868 return efx_mcdi_exit_assertion(efx);
18051869 }
18061870
1807
-void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
1871
+int efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
18081872 {
18091873 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_ID_LED_IN_LEN);
1810
- int rc;
18111874
18121875 BUILD_BUG_ON(EFX_LED_OFF != MC_CMD_LED_OFF);
18131876 BUILD_BUG_ON(EFX_LED_ON != MC_CMD_LED_ON);
....@@ -1817,8 +1880,7 @@
18171880
18181881 MCDI_SET_DWORD(inbuf, SET_ID_LED_IN_STATE, mode);
18191882
1820
- rc = efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf),
1821
- NULL, 0, NULL);
1883
+ return efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf), NULL, 0, NULL);
18221884 }
18231885
18241886 static int efx_mcdi_reset_func(struct efx_nic *efx)
....@@ -2074,22 +2136,26 @@
20742136
20752137 static int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
20762138 {
2077
- MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_IN_LEN);
2139
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN);
20782140 int rc;
20792141
20802142 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
2143
+ MCDI_POPULATE_DWORD_1(inbuf, NVRAM_UPDATE_START_V2_IN_FLAGS,
2144
+ NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT,
2145
+ 1);
20812146
20822147 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
20832148
20842149 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
20852150 NULL, 0, NULL);
2151
+
20862152 return rc;
20872153 }
20882154
20892155 static int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
20902156 loff_t offset, u8 *buffer, size_t length)
20912157 {
2092
- MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_LEN);
2158
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_V2_LEN);
20932159 MCDI_DECLARE_BUF(outbuf,
20942160 MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX));
20952161 size_t outlen;
....@@ -2098,6 +2164,8 @@
20982164 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
20992165 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
21002166 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
2167
+ MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_V2_MODE,
2168
+ MC_CMD_NVRAM_READ_IN_V2_DEFAULT);
21012169
21022170 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
21032171 outbuf, sizeof(outbuf), &outlen);
....@@ -2147,15 +2215,51 @@
21472215
21482216 static int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
21492217 {
2150
- MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN);
2151
- int rc;
2218
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN);
2219
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN);
2220
+ size_t outlen;
2221
+ int rc, rc2;
21522222
21532223 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
2154
-
2155
- BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
2224
+ /* Always set this flag. Old firmware ignores it */
2225
+ MCDI_POPULATE_DWORD_1(inbuf, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
2226
+ NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT,
2227
+ 1);
21562228
21572229 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
2158
- NULL, 0, NULL);
2230
+ outbuf, sizeof(outbuf), &outlen);
2231
+ if (!rc && outlen >= MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN) {
2232
+ rc2 = MCDI_DWORD(outbuf, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE);
2233
+ if (rc2 != MC_CMD_NVRAM_VERIFY_RC_SUCCESS)
2234
+ netif_err(efx, drv, efx->net_dev,
2235
+ "NVRAM update failed verification with code 0x%x\n",
2236
+ rc2);
2237
+ switch (rc2) {
2238
+ case MC_CMD_NVRAM_VERIFY_RC_SUCCESS:
2239
+ break;
2240
+ case MC_CMD_NVRAM_VERIFY_RC_CMS_CHECK_FAILED:
2241
+ case MC_CMD_NVRAM_VERIFY_RC_MESSAGE_DIGEST_CHECK_FAILED:
2242
+ case MC_CMD_NVRAM_VERIFY_RC_SIGNATURE_CHECK_FAILED:
2243
+ case MC_CMD_NVRAM_VERIFY_RC_TRUSTED_APPROVERS_CHECK_FAILED:
2244
+ case MC_CMD_NVRAM_VERIFY_RC_SIGNATURE_CHAIN_CHECK_FAILED:
2245
+ rc = -EIO;
2246
+ break;
2247
+ case MC_CMD_NVRAM_VERIFY_RC_INVALID_CMS_FORMAT:
2248
+ case MC_CMD_NVRAM_VERIFY_RC_BAD_MESSAGE_DIGEST:
2249
+ rc = -EINVAL;
2250
+ break;
2251
+ case MC_CMD_NVRAM_VERIFY_RC_NO_VALID_SIGNATURES:
2252
+ case MC_CMD_NVRAM_VERIFY_RC_NO_TRUSTED_APPROVERS:
2253
+ case MC_CMD_NVRAM_VERIFY_RC_NO_SIGNATURE_MATCH:
2254
+ rc = -EPERM;
2255
+ break;
2256
+ default:
2257
+ netif_err(efx, drv, efx->net_dev,
2258
+ "Unknown response to NVRAM_UPDATE_FINISH\n");
2259
+ rc = -EIO;
2260
+ }
2261
+ }
2262
+
21592263 return rc;
21602264 }
21612265