hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/misc/mei/hbm.c
....@@ -1,19 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
2
- *
3
+ * Copyright (c) 2003-2020, Intel Corporation. All rights reserved.
34 * Intel Management Engine Interface (Intel MEI) Linux driver
4
- * Copyright (c) 2003-2012, Intel Corporation.
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms and conditions of the GNU General Public License,
8
- * version 2, as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope it will be useful, but WITHOUT
11
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- * more details.
14
- *
155 */
16
-
176 #include <linux/export.h>
187 #include <linux/sched.h>
198 #include <linux/wait.h>
....@@ -65,6 +54,7 @@
6554 MEI_HBM_STATE(IDLE);
6655 MEI_HBM_STATE(STARTING);
6756 MEI_HBM_STATE(STARTED);
57
+ MEI_HBM_STATE(DR_SETUP);
6858 MEI_HBM_STATE(ENUM_CLIENTS);
6959 MEI_HBM_STATE(CLIENT_PROPERTIES);
7060 MEI_HBM_STATE(STOPPED);
....@@ -135,19 +125,15 @@
135125 /**
136126 * mei_hbm_hdr - construct hbm header
137127 *
138
- * @hdr: hbm header
128
+ * @mei_hdr: hbm header
139129 * @length: payload length
140130 */
141131
142
-static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
132
+static inline void mei_hbm_hdr(struct mei_msg_hdr *mei_hdr, size_t length)
143133 {
144
- hdr->host_addr = 0;
145
- hdr->me_addr = 0;
146
- hdr->length = length;
147
- hdr->msg_complete = 1;
148
- hdr->dma_ring = 0;
149
- hdr->reserved = 0;
150
- hdr->internal = 0;
134
+ memset(mei_hdr, 0, sizeof(*mei_hdr));
135
+ mei_hdr->length = length;
136
+ mei_hdr->msg_complete = 1;
151137 }
152138
153139 /**
....@@ -267,22 +253,21 @@
267253 int mei_hbm_start_req(struct mei_device *dev)
268254 {
269255 struct mei_msg_hdr mei_hdr;
270
- struct hbm_host_version_request start_req;
271
- const size_t len = sizeof(struct hbm_host_version_request);
256
+ struct hbm_host_version_request req;
272257 int ret;
273258
274259 mei_hbm_reset(dev);
275260
276
- mei_hbm_hdr(&mei_hdr, len);
261
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
277262
278263 /* host start message */
279
- memset(&start_req, 0, len);
280
- start_req.hbm_cmd = HOST_START_REQ_CMD;
281
- start_req.host_version.major_version = HBM_MAJOR_VERSION;
282
- start_req.host_version.minor_version = HBM_MINOR_VERSION;
264
+ memset(&req, 0, sizeof(req));
265
+ req.hbm_cmd = HOST_START_REQ_CMD;
266
+ req.host_version.major_version = HBM_MAJOR_VERSION;
267
+ req.host_version.minor_version = HBM_MINOR_VERSION;
283268
284269 dev->hbm_state = MEI_HBM_IDLE;
285
- ret = mei_hbm_write_message(dev, &mei_hdr, &start_req);
270
+ ret = mei_hbm_write_message(dev, &mei_hdr, &req);
286271 if (ret) {
287272 dev_err(dev->dev, "version message write failed: ret = %d\n",
288273 ret);
....@@ -290,6 +275,80 @@
290275 }
291276
292277 dev->hbm_state = MEI_HBM_STARTING;
278
+ dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
279
+ mei_schedule_stall_timer(dev);
280
+ return 0;
281
+}
282
+
283
+/**
284
+ * mei_hbm_dma_setup_req() - setup DMA request
285
+ * @dev: the device structure
286
+ *
287
+ * Return: 0 on success and < 0 on failure
288
+ */
289
+static int mei_hbm_dma_setup_req(struct mei_device *dev)
290
+{
291
+ struct mei_msg_hdr mei_hdr;
292
+ struct hbm_dma_setup_request req;
293
+ unsigned int i;
294
+ int ret;
295
+
296
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
297
+
298
+ memset(&req, 0, sizeof(req));
299
+ req.hbm_cmd = MEI_HBM_DMA_SETUP_REQ_CMD;
300
+ for (i = 0; i < DMA_DSCR_NUM; i++) {
301
+ phys_addr_t paddr;
302
+
303
+ paddr = dev->dr_dscr[i].daddr;
304
+ req.dma_dscr[i].addr_hi = upper_32_bits(paddr);
305
+ req.dma_dscr[i].addr_lo = lower_32_bits(paddr);
306
+ req.dma_dscr[i].size = dev->dr_dscr[i].size;
307
+ }
308
+
309
+ mei_dma_ring_reset(dev);
310
+
311
+ ret = mei_hbm_write_message(dev, &mei_hdr, &req);
312
+ if (ret) {
313
+ dev_err(dev->dev, "dma setup request write failed: ret = %d.\n",
314
+ ret);
315
+ return ret;
316
+ }
317
+
318
+ dev->hbm_state = MEI_HBM_DR_SETUP;
319
+ dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
320
+ mei_schedule_stall_timer(dev);
321
+ return 0;
322
+}
323
+
324
+/**
325
+ * mei_hbm_capabilities_req - request capabilities
326
+ *
327
+ * @dev: the device structure
328
+ *
329
+ * Return: 0 on success and < 0 on failure
330
+ */
331
+static int mei_hbm_capabilities_req(struct mei_device *dev)
332
+{
333
+ struct mei_msg_hdr mei_hdr;
334
+ struct hbm_capability_request req;
335
+ int ret;
336
+
337
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
338
+
339
+ memset(&req, 0, sizeof(req));
340
+ req.hbm_cmd = MEI_HBM_CAPABILITIES_REQ_CMD;
341
+ if (dev->hbm_f_vt_supported)
342
+ req.capability_requested[0] = HBM_CAP_VT;
343
+
344
+ ret = mei_hbm_write_message(dev, &mei_hdr, &req);
345
+ if (ret) {
346
+ dev_err(dev->dev,
347
+ "capabilities request write failed: ret = %d.\n", ret);
348
+ return ret;
349
+ }
350
+
351
+ dev->hbm_state = MEI_HBM_CAP_SETUP;
293352 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
294353 mei_schedule_stall_timer(dev);
295354 return 0;
....@@ -305,21 +364,19 @@
305364 static int mei_hbm_enum_clients_req(struct mei_device *dev)
306365 {
307366 struct mei_msg_hdr mei_hdr;
308
- struct hbm_host_enum_request enum_req;
309
- const size_t len = sizeof(struct hbm_host_enum_request);
367
+ struct hbm_host_enum_request req;
310368 int ret;
311369
312370 /* enumerate clients */
313
- mei_hbm_hdr(&mei_hdr, len);
371
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
314372
315
- memset(&enum_req, 0, len);
316
- enum_req.hbm_cmd = HOST_ENUM_REQ_CMD;
317
- enum_req.flags |= dev->hbm_f_dc_supported ?
318
- MEI_HBM_ENUM_F_ALLOW_ADD : 0;
319
- enum_req.flags |= dev->hbm_f_ie_supported ?
373
+ memset(&req, 0, sizeof(req));
374
+ req.hbm_cmd = HOST_ENUM_REQ_CMD;
375
+ req.flags |= dev->hbm_f_dc_supported ? MEI_HBM_ENUM_F_ALLOW_ADD : 0;
376
+ req.flags |= dev->hbm_f_ie_supported ?
320377 MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0;
321378
322
- ret = mei_hbm_write_message(dev, &mei_hdr, &enum_req);
379
+ ret = mei_hbm_write_message(dev, &mei_hdr, &req);
323380 if (ret) {
324381 dev_err(dev->dev, "enumeration request write failed: ret = %d.\n",
325382 ret);
....@@ -348,7 +405,7 @@
348405
349406 mei_me_cl_rm_by_uuid(dev, uuid);
350407
351
- me_cl = kzalloc(sizeof(struct mei_me_client), GFP_KERNEL);
408
+ me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL);
352409 if (!me_cl)
353410 return -ENOMEM;
354411
....@@ -376,14 +433,13 @@
376433 {
377434 struct mei_msg_hdr mei_hdr;
378435 struct hbm_add_client_response resp;
379
- const size_t len = sizeof(struct hbm_add_client_response);
380436 int ret;
381437
382438 dev_dbg(dev->dev, "adding client response\n");
383439
384
- mei_hbm_hdr(&mei_hdr, len);
440
+ mei_hbm_hdr(&mei_hdr, sizeof(resp));
385441
386
- memset(&resp, 0, sizeof(struct hbm_add_client_response));
442
+ memset(&resp, 0, sizeof(resp));
387443 resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD;
388444 resp.me_addr = addr;
389445 resp.status = status;
....@@ -437,11 +493,10 @@
437493
438494 struct mei_msg_hdr mei_hdr;
439495 struct hbm_notification_request req;
440
- const size_t len = sizeof(struct hbm_notification_request);
441496 int ret;
442497
443
- mei_hbm_hdr(&mei_hdr, len);
444
- mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, len);
498
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
499
+ mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, sizeof(req));
445500
446501 req.start = start;
447502
....@@ -548,8 +603,7 @@
548603 static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
549604 {
550605 struct mei_msg_hdr mei_hdr;
551
- struct hbm_props_request prop_req;
552
- const size_t len = sizeof(struct hbm_props_request);
606
+ struct hbm_props_request req;
553607 unsigned long addr;
554608 int ret;
555609
....@@ -559,18 +613,17 @@
559613 if (addr == MEI_CLIENTS_MAX) {
560614 dev->hbm_state = MEI_HBM_STARTED;
561615 mei_host_client_init(dev);
562
-
563616 return 0;
564617 }
565618
566
- mei_hbm_hdr(&mei_hdr, len);
619
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
567620
568
- memset(&prop_req, 0, sizeof(struct hbm_props_request));
621
+ memset(&req, 0, sizeof(req));
569622
570
- prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
571
- prop_req.me_addr = addr;
623
+ req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
624
+ req.me_addr = addr;
572625
573
- ret = mei_hbm_write_message(dev, &mei_hdr, &prop_req);
626
+ ret = mei_hbm_write_message(dev, &mei_hdr, &req);
574627 if (ret) {
575628 dev_err(dev->dev, "properties request write failed: ret = %d\n",
576629 ret);
....@@ -596,15 +649,14 @@
596649 {
597650 struct mei_msg_hdr mei_hdr;
598651 struct hbm_power_gate req;
599
- const size_t len = sizeof(struct hbm_power_gate);
600652 int ret;
601653
602654 if (!dev->hbm_f_pg_supported)
603655 return -EOPNOTSUPP;
604656
605
- mei_hbm_hdr(&mei_hdr, len);
657
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
606658
607
- memset(&req, 0, len);
659
+ memset(&req, 0, sizeof(req));
608660 req.hbm_cmd = pg_cmd;
609661
610662 ret = mei_hbm_write_message(dev, &mei_hdr, &req);
....@@ -625,11 +677,10 @@
625677 {
626678 struct mei_msg_hdr mei_hdr;
627679 struct hbm_host_stop_request req;
628
- const size_t len = sizeof(struct hbm_host_stop_request);
629680
630
- mei_hbm_hdr(&mei_hdr, len);
681
+ mei_hbm_hdr(&mei_hdr, sizeof(req));
631682
632
- memset(&req, 0, len);
683
+ memset(&req, 0, sizeof(req));
633684 req.hbm_cmd = HOST_STOP_REQ_CMD;
634685 req.reason = DRIVER_STOP_REQUEST;
635686
....@@ -1020,6 +1071,20 @@
10201071 (dev->version.major_version == HBM_MAJOR_VERSION_DR &&
10211072 dev->version.minor_version >= HBM_MINOR_VERSION_DR))
10221073 dev->hbm_f_dr_supported = 1;
1074
+
1075
+ /* VTag Support */
1076
+ dev->hbm_f_vt_supported = 0;
1077
+ if (dev->version.major_version > HBM_MAJOR_VERSION_VT ||
1078
+ (dev->version.major_version == HBM_MAJOR_VERSION_VT &&
1079
+ dev->version.minor_version >= HBM_MINOR_VERSION_VT))
1080
+ dev->hbm_f_vt_supported = 1;
1081
+
1082
+ /* Capability message Support */
1083
+ dev->hbm_f_cap_supported = 0;
1084
+ if (dev->version.major_version > HBM_MAJOR_VERSION_CAP ||
1085
+ (dev->version.major_version == HBM_MAJOR_VERSION_CAP &&
1086
+ dev->version.minor_version >= HBM_MINOR_VERSION_CAP))
1087
+ dev->hbm_f_cap_supported = 1;
10231088 }
10241089
10251090 /**
....@@ -1051,7 +1116,9 @@
10511116 struct hbm_host_version_response *version_res;
10521117 struct hbm_props_response *props_res;
10531118 struct hbm_host_enum_response *enum_res;
1119
+ struct hbm_dma_setup_response *dma_setup_res;
10541120 struct hbm_add_client_request *add_cl_req;
1121
+ struct hbm_capability_response *capability_res;
10551122 int ret;
10561123
10571124 struct mei_hbm_cl_cmd *cl_cmd;
....@@ -1115,12 +1182,95 @@
11151182 return -EPROTO;
11161183 }
11171184
1118
- if (mei_hbm_enum_clients_req(dev)) {
1119
- dev_err(dev->dev, "hbm: start: failed to send enumeration request\n");
1120
- return -EIO;
1185
+ if (dev->hbm_f_cap_supported) {
1186
+ if (mei_hbm_capabilities_req(dev))
1187
+ return -EIO;
1188
+ wake_up(&dev->wait_hbm_start);
1189
+ break;
11211190 }
11221191
1192
+ if (dev->hbm_f_dr_supported) {
1193
+ if (mei_dmam_ring_alloc(dev))
1194
+ dev_info(dev->dev, "running w/o dma ring\n");
1195
+ if (mei_dma_ring_is_allocated(dev)) {
1196
+ if (mei_hbm_dma_setup_req(dev))
1197
+ return -EIO;
1198
+
1199
+ wake_up(&dev->wait_hbm_start);
1200
+ break;
1201
+ }
1202
+ }
1203
+
1204
+ dev->hbm_f_dr_supported = 0;
1205
+ mei_dmam_ring_free(dev);
1206
+
1207
+ if (mei_hbm_enum_clients_req(dev))
1208
+ return -EIO;
1209
+
11231210 wake_up(&dev->wait_hbm_start);
1211
+ break;
1212
+
1213
+ case MEI_HBM_CAPABILITIES_RES_CMD:
1214
+ dev_dbg(dev->dev, "hbm: capabilities response: message received.\n");
1215
+
1216
+ dev->init_clients_timer = 0;
1217
+
1218
+ if (dev->hbm_state != MEI_HBM_CAP_SETUP) {
1219
+ dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n",
1220
+ dev->dev_state, dev->hbm_state);
1221
+ return -EPROTO;
1222
+ }
1223
+
1224
+ capability_res = (struct hbm_capability_response *)mei_msg;
1225
+ if (!(capability_res->capability_granted[0] & HBM_CAP_VT))
1226
+ dev->hbm_f_vt_supported = 0;
1227
+
1228
+ if (dev->hbm_f_dr_supported) {
1229
+ if (mei_dmam_ring_alloc(dev))
1230
+ dev_info(dev->dev, "running w/o dma ring\n");
1231
+ if (mei_dma_ring_is_allocated(dev)) {
1232
+ if (mei_hbm_dma_setup_req(dev))
1233
+ return -EIO;
1234
+ break;
1235
+ }
1236
+ }
1237
+
1238
+ dev->hbm_f_dr_supported = 0;
1239
+ mei_dmam_ring_free(dev);
1240
+
1241
+ if (mei_hbm_enum_clients_req(dev))
1242
+ return -EIO;
1243
+ break;
1244
+
1245
+ case MEI_HBM_DMA_SETUP_RES_CMD:
1246
+ dev_dbg(dev->dev, "hbm: dma setup response: message received.\n");
1247
+
1248
+ dev->init_clients_timer = 0;
1249
+
1250
+ if (dev->hbm_state != MEI_HBM_DR_SETUP) {
1251
+ dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n",
1252
+ dev->dev_state, dev->hbm_state);
1253
+ return -EPROTO;
1254
+ }
1255
+
1256
+ dma_setup_res = (struct hbm_dma_setup_response *)mei_msg;
1257
+
1258
+ if (dma_setup_res->status) {
1259
+ u8 status = dma_setup_res->status;
1260
+
1261
+ if (status == MEI_HBMS_NOT_ALLOWED) {
1262
+ dev_dbg(dev->dev, "hbm: dma setup not allowed\n");
1263
+ } else {
1264
+ dev_info(dev->dev, "hbm: dma setup response: failure = %d %s\n",
1265
+ status,
1266
+ mei_hbm_status_str(status));
1267
+ }
1268
+ dev->hbm_f_dr_supported = 0;
1269
+ mei_dmam_ring_free(dev);
1270
+ }
1271
+
1272
+ if (mei_hbm_enum_clients_req(dev))
1273
+ return -EIO;
11241274 break;
11251275
11261276 case CLIENT_CONNECT_RES_CMD:
....@@ -1223,7 +1373,7 @@
12231373 return -EPROTO;
12241374 }
12251375
1226
- dev->dev_state = MEI_DEV_POWER_DOWN;
1376
+ mei_set_devstate(dev, MEI_DEV_POWER_DOWN);
12271377 dev_info(dev->dev, "hbm: stop response: resetting.\n");
12281378 /* force the reset */
12291379 return -EPROTO;
....@@ -1278,8 +1428,8 @@
12781428 break;
12791429
12801430 default:
1281
- BUG();
1282
- break;
1431
+ WARN(1, "hbm: wrong command %d\n", mei_msg->hbm_cmd);
1432
+ return -EPROTO;
12831433
12841434 }
12851435 return 0;