GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / misc / mei / bus-fixup.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2013-2020, Intel Corporation. All rights reserved.
4  * Intel Management Engine Interface (Intel MEI) Linux driver
5  */
6
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/module.h>
10 #include <linux/device.h>
11 #include <linux/slab.h>
12 #include <linux/uuid.h>
13
14 #include <linux/mei_cl_bus.h>
15
16 #include "mei_dev.h"
17 #include "client.h"
18
19 #define MEI_UUID_NFC_INFO UUID_LE(0xd2de1625, 0x382d, 0x417d, \
20                         0x48, 0xa4, 0xef, 0xab, 0xba, 0x8a, 0x12, 0x06)
21
22 static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
23
24 #define MEI_UUID_NFC_HCI UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \
25                         0x94, 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c)
26
27 #define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
28                             0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
29
30 #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
31                         0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
32
33 #define MEI_UUID_IGSC_MKHI UUID_LE(0xE2C2AFA2, 0x3817, 0x4D19, \
34                         0x9D, 0x95, 0x06, 0xB1, 0x6B, 0x58, 0x8A, 0x5D)
35
36 #define MEI_UUID_IGSC_MKHI_FIX UUID_LE(0x46E0C1FB, 0xA546, 0x414F, \
37                         0x91, 0x70, 0xB7, 0xF4, 0x6D, 0x57, 0xB4, 0xAD)
38
39 #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
40                               0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
41
42 #define MEI_UUID_PAVP UUID_LE(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \
43                               0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1)
44
45 #define MEI_UUID_ANY NULL_UUID_LE
46
47 /**
48  * number_of_connections - determine whether an client be on the bus
49  *    according number of connections
50  *    We support only clients:
51  *       1. with single connection
52  *       2. and fixed clients (max_number_of_connections == 0)
53  *
54  * @cldev: me clients device
55  */
56 static void number_of_connections(struct mei_cl_device *cldev)
57 {
58         if (cldev->me_cl->props.max_number_of_connections > 1)
59                 cldev->do_match = 0;
60 }
61
62 /**
63  * blacklist - blacklist a client from the bus
64  *
65  * @cldev: me clients device
66  */
67 static void blacklist(struct mei_cl_device *cldev)
68 {
69         cldev->do_match = 0;
70 }
71
72 /**
73  * whitelist - forcefully whitelist client
74  *
75  * @cldev: me clients device
76  */
77 static void whitelist(struct mei_cl_device *cldev)
78 {
79         cldev->do_match = 1;
80 }
81
82 #define OSTYPE_LINUX    2
83 struct mei_os_ver {
84         __le16 build;
85         __le16 reserved1;
86         u8  os_type;
87         u8  major;
88         u8  minor;
89         u8  reserved2;
90 } __packed;
91
92 #define MKHI_FEATURE_PTT 0x10
93
94 struct mkhi_rule_id {
95         __le16 rule_type;
96         u8 feature_id;
97         u8 reserved;
98 } __packed;
99
100 struct mkhi_fwcaps {
101         struct mkhi_rule_id id;
102         u8 len;
103         u8 data[];
104 } __packed;
105
106 struct mkhi_fw_ver_block {
107         u16 minor;
108         u8 major;
109         u8 platform;
110         u16 buildno;
111         u16 hotfix;
112 } __packed;
113
114 struct mkhi_fw_ver {
115         struct mkhi_fw_ver_block ver[MEI_MAX_FW_VER_BLOCKS];
116 } __packed;
117
118 #define MKHI_FWCAPS_GROUP_ID 0x3
119 #define MKHI_FWCAPS_SET_OS_VER_APP_RULE_CMD 6
120 #define MKHI_GEN_GROUP_ID 0xFF
121 #define MKHI_GEN_GET_FW_VERSION_CMD 0x2
122 struct mkhi_msg_hdr {
123         u8  group_id;
124         u8  command;
125         u8  reserved;
126         u8  result;
127 } __packed;
128
129 struct mkhi_msg {
130         struct mkhi_msg_hdr hdr;
131         u8 data[];
132 } __packed;
133
134 #define MKHI_OSVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \
135                             sizeof(struct mkhi_fwcaps) + \
136                             sizeof(struct mei_os_ver))
137 static int mei_osver(struct mei_cl_device *cldev)
138 {
139         const size_t size = MKHI_OSVER_BUF_LEN;
140         char buf[MKHI_OSVER_BUF_LEN];
141         struct mkhi_msg *req;
142         struct mkhi_fwcaps *fwcaps;
143         struct mei_os_ver *os_ver;
144         unsigned int mode = MEI_CL_IO_TX_BLOCKING | MEI_CL_IO_TX_INTERNAL;
145
146         memset(buf, 0, size);
147
148         req = (struct mkhi_msg *)buf;
149         req->hdr.group_id = MKHI_FWCAPS_GROUP_ID;
150         req->hdr.command = MKHI_FWCAPS_SET_OS_VER_APP_RULE_CMD;
151
152         fwcaps = (struct mkhi_fwcaps *)req->data;
153
154         fwcaps->id.rule_type = 0x0;
155         fwcaps->id.feature_id = MKHI_FEATURE_PTT;
156         fwcaps->len = sizeof(*os_ver);
157         os_ver = (struct mei_os_ver *)fwcaps->data;
158         os_ver->os_type = OSTYPE_LINUX;
159
160         return __mei_cl_send(cldev->cl, buf, size, 0, mode);
161 }
162
163 #define MKHI_FWVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \
164                             sizeof(struct mkhi_fw_ver))
165 #define MKHI_FWVER_LEN(__num) (sizeof(struct mkhi_msg_hdr) + \
166                                sizeof(struct mkhi_fw_ver_block) * (__num))
167 #define MKHI_RCV_TIMEOUT 500 /* receive timeout in msec */
168 static int mei_fwver(struct mei_cl_device *cldev)
169 {
170         char buf[MKHI_FWVER_BUF_LEN];
171         struct mkhi_msg req;
172         struct mkhi_msg *rsp;
173         struct mkhi_fw_ver *fwver;
174         int bytes_recv, ret, i;
175
176         memset(buf, 0, sizeof(buf));
177
178         req.hdr.group_id = MKHI_GEN_GROUP_ID;
179         req.hdr.command = MKHI_GEN_GET_FW_VERSION_CMD;
180
181         ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0,
182                             MEI_CL_IO_TX_BLOCKING);
183         if (ret < 0) {
184                 dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n");
185                 return ret;
186         }
187
188         ret = 0;
189         bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), NULL, 0,
190                                    MKHI_RCV_TIMEOUT);
191         if (bytes_recv < 0 || (size_t)bytes_recv < MKHI_FWVER_LEN(1)) {
192                 /*
193                  * Should be at least one version block,
194                  * error out if nothing found
195                  */
196                 dev_err(&cldev->dev, "Could not read FW version\n");
197                 return -EIO;
198         }
199
200         rsp = (struct mkhi_msg *)buf;
201         fwver = (struct mkhi_fw_ver *)rsp->data;
202         memset(cldev->bus->fw_ver, 0, sizeof(cldev->bus->fw_ver));
203         for (i = 0; i < MEI_MAX_FW_VER_BLOCKS; i++) {
204                 if ((size_t)bytes_recv < MKHI_FWVER_LEN(i + 1))
205                         break;
206                 dev_dbg(&cldev->dev, "FW version%d %d:%d.%d.%d.%d\n",
207                         i, fwver->ver[i].platform,
208                         fwver->ver[i].major, fwver->ver[i].minor,
209                         fwver->ver[i].hotfix, fwver->ver[i].buildno);
210
211                 cldev->bus->fw_ver[i].platform = fwver->ver[i].platform;
212                 cldev->bus->fw_ver[i].major = fwver->ver[i].major;
213                 cldev->bus->fw_ver[i].minor = fwver->ver[i].minor;
214                 cldev->bus->fw_ver[i].hotfix = fwver->ver[i].hotfix;
215                 cldev->bus->fw_ver[i].buildno = fwver->ver[i].buildno;
216         }
217
218         return ret;
219 }
220
221 static void mei_mkhi_fix(struct mei_cl_device *cldev)
222 {
223         int ret;
224
225         /* No need to enable the client if nothing is needed from it */
226         if (!cldev->bus->fw_f_fw_ver_supported &&
227             !cldev->bus->hbm_f_os_supported)
228                 return;
229
230         ret = mei_cldev_enable(cldev);
231         if (ret)
232                 return;
233
234         if (cldev->bus->fw_f_fw_ver_supported) {
235                 ret = mei_fwver(cldev);
236                 if (ret < 0)
237                         dev_err(&cldev->dev, "FW version command failed %d\n",
238                                 ret);
239         }
240
241         if (cldev->bus->hbm_f_os_supported) {
242                 ret = mei_osver(cldev);
243                 if (ret < 0)
244                         dev_err(&cldev->dev, "OS version command failed %d\n",
245                                 ret);
246         }
247         mei_cldev_disable(cldev);
248 }
249
250 static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev)
251 {
252         int ret;
253
254         /* No need to enable the client if nothing is needed from it */
255         if (!cldev->bus->fw_f_fw_ver_supported)
256                 return;
257
258         ret = mei_cldev_enable(cldev);
259         if (ret)
260                 return;
261
262         ret = mei_fwver(cldev);
263         if (ret < 0)
264                 dev_err(&cldev->dev, "FW version command failed %d\n", ret);
265         mei_cldev_disable(cldev);
266 }
267 /**
268  * mei_wd - wd client on the bus, change protocol version
269  *   as the API has changed.
270  *
271  * @cldev: me clients device
272  */
273 #if IS_ENABLED(CONFIG_INTEL_MEI_ME)
274 #include <linux/pci.h>
275 #include "hw-me-regs.h"
276 static void mei_wd(struct mei_cl_device *cldev)
277 {
278         struct pci_dev *pdev = to_pci_dev(cldev->dev.parent);
279
280         if (pdev->device == MEI_DEV_ID_WPT_LP ||
281             pdev->device == MEI_DEV_ID_SPT ||
282             pdev->device == MEI_DEV_ID_SPT_H)
283                 cldev->me_cl->props.protocol_version = 0x2;
284
285         cldev->do_match = 1;
286 }
287 #else
288 static inline void mei_wd(struct mei_cl_device *cldev) {}
289 #endif /* CONFIG_INTEL_MEI_ME */
290
291 struct mei_nfc_cmd {
292         u8 command;
293         u8 status;
294         u16 req_id;
295         u32 reserved;
296         u16 data_size;
297         u8 sub_command;
298         u8 data[];
299 } __packed;
300
301 struct mei_nfc_reply {
302         u8 command;
303         u8 status;
304         u16 req_id;
305         u32 reserved;
306         u16 data_size;
307         u8 sub_command;
308         u8 reply_status;
309         u8 data[];
310 } __packed;
311
312 struct mei_nfc_if_version {
313         u8 radio_version_sw[3];
314         u8 reserved[3];
315         u8 radio_version_hw[3];
316         u8 i2c_addr;
317         u8 fw_ivn;
318         u8 vendor_id;
319         u8 radio_type;
320 } __packed;
321
322
323 #define MEI_NFC_CMD_MAINTENANCE 0x00
324 #define MEI_NFC_SUBCMD_IF_VERSION 0x01
325
326 /* Vendors */
327 #define MEI_NFC_VENDOR_INSIDE 0x00
328 #define MEI_NFC_VENDOR_NXP    0x01
329
330 /* Radio types */
331 #define MEI_NFC_VENDOR_INSIDE_UREAD 0x00
332 #define MEI_NFC_VENDOR_NXP_PN544    0x01
333
334 /**
335  * mei_nfc_if_version - get NFC interface version
336  *
337  * @cl: host client (nfc info)
338  * @ver: NFC interface version to be filled in
339  *
340  * Return: 0 on success; < 0 otherwise
341  */
342 static int mei_nfc_if_version(struct mei_cl *cl,
343                               struct mei_nfc_if_version *ver)
344 {
345         struct mei_device *bus;
346         struct mei_nfc_cmd cmd = {
347                 .command = MEI_NFC_CMD_MAINTENANCE,
348                 .data_size = 1,
349                 .sub_command = MEI_NFC_SUBCMD_IF_VERSION,
350         };
351         struct mei_nfc_reply *reply = NULL;
352         size_t if_version_length;
353         u8 vtag;
354         int bytes_recv, ret;
355
356         bus = cl->dev;
357
358         WARN_ON(mutex_is_locked(&bus->device_lock));
359
360         ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0,
361                             MEI_CL_IO_TX_BLOCKING);
362         if (ret < 0) {
363                 dev_err(bus->dev, "Could not send IF version cmd\n");
364                 return ret;
365         }
366
367         /* to be sure on the stack we alloc memory */
368         if_version_length = sizeof(*reply) + sizeof(*ver);
369
370         reply = kzalloc(if_version_length, GFP_KERNEL);
371         if (!reply)
372                 return -ENOMEM;
373
374         ret = 0;
375         bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag,
376                                    0, 0);
377         if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) {
378                 dev_err(bus->dev, "Could not read IF version\n");
379                 ret = -EIO;
380                 goto err;
381         }
382
383         memcpy(ver, reply->data, sizeof(*ver));
384
385         dev_info(bus->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n",
386                 ver->fw_ivn, ver->vendor_id, ver->radio_type);
387
388 err:
389         kfree(reply);
390         return ret;
391 }
392
393 /**
394  * mei_nfc_radio_name - derive nfc radio name from the interface version
395  *
396  * @ver: NFC radio version
397  *
398  * Return: radio name string
399  */
400 static const char *mei_nfc_radio_name(struct mei_nfc_if_version *ver)
401 {
402
403         if (ver->vendor_id == MEI_NFC_VENDOR_INSIDE) {
404                 if (ver->radio_type == MEI_NFC_VENDOR_INSIDE_UREAD)
405                         return "microread";
406         }
407
408         if (ver->vendor_id == MEI_NFC_VENDOR_NXP) {
409                 if (ver->radio_type == MEI_NFC_VENDOR_NXP_PN544)
410                         return "pn544";
411         }
412
413         return NULL;
414 }
415
416 /**
417  * mei_nfc - The nfc fixup function. The function retrieves nfc radio
418  *    name and set is as device attribute so we can load
419  *    the proper device driver for it
420  *
421  * @cldev: me client device (nfc)
422  */
423 static void mei_nfc(struct mei_cl_device *cldev)
424 {
425         struct mei_device *bus;
426         struct mei_cl *cl;
427         struct mei_me_client *me_cl = NULL;
428         struct mei_nfc_if_version ver;
429         const char *radio_name = NULL;
430         int ret;
431
432         bus = cldev->bus;
433
434         mutex_lock(&bus->device_lock);
435         /* we need to connect to INFO GUID */
436         cl = mei_cl_alloc_linked(bus);
437         if (IS_ERR(cl)) {
438                 ret = PTR_ERR(cl);
439                 cl = NULL;
440                 dev_err(bus->dev, "nfc hook alloc failed %d\n", ret);
441                 goto out;
442         }
443
444         me_cl = mei_me_cl_by_uuid(bus, &mei_nfc_info_guid);
445         if (!me_cl) {
446                 ret = -ENOTTY;
447                 dev_err(bus->dev, "Cannot find nfc info %d\n", ret);
448                 goto out;
449         }
450
451         ret = mei_cl_connect(cl, me_cl, NULL);
452         if (ret < 0) {
453                 dev_err(&cldev->dev, "Can't connect to the NFC INFO ME ret = %d\n",
454                         ret);
455                 goto out;
456         }
457
458         mutex_unlock(&bus->device_lock);
459
460         ret = mei_nfc_if_version(cl, &ver);
461         if (ret)
462                 goto disconnect;
463
464         radio_name = mei_nfc_radio_name(&ver);
465
466         if (!radio_name) {
467                 ret = -ENOENT;
468                 dev_err(&cldev->dev, "Can't get the NFC interface version ret = %d\n",
469                         ret);
470                 goto disconnect;
471         }
472
473         dev_dbg(bus->dev, "nfc radio %s\n", radio_name);
474         strlcpy(cldev->name, radio_name, sizeof(cldev->name));
475
476 disconnect:
477         mutex_lock(&bus->device_lock);
478         if (mei_cl_disconnect(cl) < 0)
479                 dev_err(bus->dev, "Can't disconnect the NFC INFO ME\n");
480
481         mei_cl_flush_queues(cl, NULL);
482
483 out:
484         mei_cl_unlink(cl);
485         mutex_unlock(&bus->device_lock);
486         mei_me_cl_put(me_cl);
487         kfree(cl);
488
489         if (ret)
490                 cldev->do_match = 0;
491
492         dev_dbg(bus->dev, "end of fixup match = %d\n", cldev->do_match);
493 }
494
495 /**
496  * vt_support - enable on bus clients with vtag support
497  *
498  * @cldev: me clients device
499  */
500 static void vt_support(struct mei_cl_device *cldev)
501 {
502         if (cldev->me_cl->props.vt_supported == 1)
503                 cldev->do_match = 1;
504 }
505
506 #define MEI_FIXUP(_uuid, _hook) { _uuid, _hook }
507
508 static struct mei_fixup {
509
510         const uuid_le uuid;
511         void (*hook)(struct mei_cl_device *cldev);
512 } mei_fixups[] = {
513         MEI_FIXUP(MEI_UUID_ANY, number_of_connections),
514         MEI_FIXUP(MEI_UUID_NFC_INFO, blacklist),
515         MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
516         MEI_FIXUP(MEI_UUID_WD, mei_wd),
517         MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
518         MEI_FIXUP(MEI_UUID_IGSC_MKHI, mei_gsc_mkhi_ver),
519         MEI_FIXUP(MEI_UUID_IGSC_MKHI_FIX, mei_gsc_mkhi_ver),
520         MEI_FIXUP(MEI_UUID_HDCP, whitelist),
521         MEI_FIXUP(MEI_UUID_ANY, vt_support),
522         MEI_FIXUP(MEI_UUID_PAVP, whitelist),
523 };
524
525 /**
526  * mei_cl_bus_dev_fixup - run fixup handlers
527  *
528  * @cldev: me client device
529  */
530 void mei_cl_bus_dev_fixup(struct mei_cl_device *cldev)
531 {
532         struct mei_fixup *f;
533         const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
534         size_t i;
535
536         for (i = 0; i < ARRAY_SIZE(mei_fixups); i++) {
537
538                 f = &mei_fixups[i];
539                 if (uuid_le_cmp(f->uuid, MEI_UUID_ANY) == 0 ||
540                     uuid_le_cmp(f->uuid, *uuid) == 0)
541                         f->hook(cldev);
542         }
543 }
544