| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * |
|---|
| 3 | + * Copyright (c) 2013-2020, Intel Corporation. All rights reserved. |
|---|
| 3 | 4 | * Intel Management Engine Interface (Intel MEI) Linux driver |
|---|
| 4 | | - * Copyright (c) 2003-2018, 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 | | - * |
|---|
| 15 | 5 | */ |
|---|
| 16 | 6 | |
|---|
| 17 | 7 | #include <linux/kernel.h> |
|---|
| 18 | 8 | #include <linux/sched.h> |
|---|
| 19 | 9 | #include <linux/module.h> |
|---|
| 20 | | -#include <linux/moduleparam.h> |
|---|
| 21 | 10 | #include <linux/device.h> |
|---|
| 22 | 11 | #include <linux/slab.h> |
|---|
| 23 | 12 | #include <linux/uuid.h> |
|---|
| .. | .. |
|---|
| 41 | 30 | #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \ |
|---|
| 42 | 31 | 0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb) |
|---|
| 43 | 32 | |
|---|
| 33 | +#define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \ |
|---|
| 34 | + 0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04) |
|---|
| 35 | + |
|---|
| 44 | 36 | #define MEI_UUID_ANY NULL_UUID_LE |
|---|
| 45 | 37 | |
|---|
| 46 | 38 | /** |
|---|
| .. | .. |
|---|
| 54 | 46 | */ |
|---|
| 55 | 47 | static void number_of_connections(struct mei_cl_device *cldev) |
|---|
| 56 | 48 | { |
|---|
| 57 | | - dev_dbg(&cldev->dev, "running hook %s\n", __func__); |
|---|
| 58 | | - |
|---|
| 59 | 49 | if (cldev->me_cl->props.max_number_of_connections > 1) |
|---|
| 60 | 50 | cldev->do_match = 0; |
|---|
| 61 | 51 | } |
|---|
| .. | .. |
|---|
| 67 | 57 | */ |
|---|
| 68 | 58 | static void blacklist(struct mei_cl_device *cldev) |
|---|
| 69 | 59 | { |
|---|
| 70 | | - dev_dbg(&cldev->dev, "running hook %s\n", __func__); |
|---|
| 71 | | - |
|---|
| 72 | 60 | cldev->do_match = 0; |
|---|
| 61 | +} |
|---|
| 62 | + |
|---|
| 63 | +/** |
|---|
| 64 | + * whitelist - forcefully whitelist client |
|---|
| 65 | + * |
|---|
| 66 | + * @cldev: me clients device |
|---|
| 67 | + */ |
|---|
| 68 | +static void whitelist(struct mei_cl_device *cldev) |
|---|
| 69 | +{ |
|---|
| 70 | + cldev->do_match = 1; |
|---|
| 73 | 71 | } |
|---|
| 74 | 72 | |
|---|
| 75 | 73 | #define OSTYPE_LINUX 2 |
|---|
| .. | .. |
|---|
| 93 | 91 | struct mkhi_fwcaps { |
|---|
| 94 | 92 | struct mkhi_rule_id id; |
|---|
| 95 | 93 | u8 len; |
|---|
| 96 | | - u8 data[0]; |
|---|
| 94 | + u8 data[]; |
|---|
| 97 | 95 | } __packed; |
|---|
| 98 | 96 | |
|---|
| 99 | 97 | struct mkhi_fw_ver_block { |
|---|
| .. | .. |
|---|
| 121 | 119 | |
|---|
| 122 | 120 | struct mkhi_msg { |
|---|
| 123 | 121 | struct mkhi_msg_hdr hdr; |
|---|
| 124 | | - u8 data[0]; |
|---|
| 122 | + u8 data[]; |
|---|
| 125 | 123 | } __packed; |
|---|
| 126 | 124 | |
|---|
| 127 | 125 | #define MKHI_OSVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \ |
|---|
| .. | .. |
|---|
| 161 | 159 | static int mei_fwver(struct mei_cl_device *cldev) |
|---|
| 162 | 160 | { |
|---|
| 163 | 161 | char buf[MKHI_FWVER_BUF_LEN]; |
|---|
| 164 | | - struct mkhi_msg *req; |
|---|
| 162 | + struct mkhi_msg req; |
|---|
| 163 | + struct mkhi_msg *rsp; |
|---|
| 165 | 164 | struct mkhi_fw_ver *fwver; |
|---|
| 166 | 165 | int bytes_recv, ret, i; |
|---|
| 167 | 166 | |
|---|
| 168 | 167 | memset(buf, 0, sizeof(buf)); |
|---|
| 169 | 168 | |
|---|
| 170 | | - req = (struct mkhi_msg *)buf; |
|---|
| 171 | | - req->hdr.group_id = MKHI_GEN_GROUP_ID; |
|---|
| 172 | | - req->hdr.command = MKHI_GEN_GET_FW_VERSION_CMD; |
|---|
| 169 | + req.hdr.group_id = MKHI_GEN_GROUP_ID; |
|---|
| 170 | + req.hdr.command = MKHI_GEN_GET_FW_VERSION_CMD; |
|---|
| 173 | 171 | |
|---|
| 174 | | - ret = __mei_cl_send(cldev->cl, buf, sizeof(struct mkhi_msg_hdr), |
|---|
| 172 | + ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), |
|---|
| 175 | 173 | MEI_CL_IO_TX_BLOCKING); |
|---|
| 176 | 174 | if (ret < 0) { |
|---|
| 177 | 175 | dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); |
|---|
| .. | .. |
|---|
| 190 | 188 | return -EIO; |
|---|
| 191 | 189 | } |
|---|
| 192 | 190 | |
|---|
| 193 | | - fwver = (struct mkhi_fw_ver *)req->data; |
|---|
| 191 | + rsp = (struct mkhi_msg *)buf; |
|---|
| 192 | + fwver = (struct mkhi_fw_ver *)rsp->data; |
|---|
| 194 | 193 | memset(cldev->bus->fw_ver, 0, sizeof(cldev->bus->fw_ver)); |
|---|
| 195 | 194 | for (i = 0; i < MEI_MAX_FW_VER_BLOCKS; i++) { |
|---|
| 196 | 195 | if ((size_t)bytes_recv < MKHI_FWVER_LEN(i + 1)) |
|---|
| .. | .. |
|---|
| 252 | 251 | { |
|---|
| 253 | 252 | struct pci_dev *pdev = to_pci_dev(cldev->dev.parent); |
|---|
| 254 | 253 | |
|---|
| 255 | | - dev_dbg(&cldev->dev, "running hook %s\n", __func__); |
|---|
| 256 | 254 | if (pdev->device == MEI_DEV_ID_WPT_LP || |
|---|
| 257 | 255 | pdev->device == MEI_DEV_ID_SPT || |
|---|
| 258 | 256 | pdev->device == MEI_DEV_ID_SPT_H) |
|---|
| .. | .. |
|---|
| 332 | 330 | |
|---|
| 333 | 331 | WARN_ON(mutex_is_locked(&bus->device_lock)); |
|---|
| 334 | 332 | |
|---|
| 335 | | - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd), |
|---|
| 336 | | - MEI_CL_IO_TX_BLOCKING); |
|---|
| 333 | + ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING); |
|---|
| 337 | 334 | if (ret < 0) { |
|---|
| 338 | 335 | dev_err(bus->dev, "Could not send IF version cmd\n"); |
|---|
| 339 | 336 | return ret; |
|---|
| 340 | 337 | } |
|---|
| 341 | 338 | |
|---|
| 342 | 339 | /* to be sure on the stack we alloc memory */ |
|---|
| 343 | | - if_version_length = sizeof(struct mei_nfc_reply) + |
|---|
| 344 | | - sizeof(struct mei_nfc_if_version); |
|---|
| 340 | + if_version_length = sizeof(*reply) + sizeof(*ver); |
|---|
| 345 | 341 | |
|---|
| 346 | 342 | reply = kzalloc(if_version_length, GFP_KERNEL); |
|---|
| 347 | 343 | if (!reply) |
|---|
| .. | .. |
|---|
| 355 | 351 | goto err; |
|---|
| 356 | 352 | } |
|---|
| 357 | 353 | |
|---|
| 358 | | - memcpy(ver, reply->data, sizeof(struct mei_nfc_if_version)); |
|---|
| 354 | + memcpy(ver, reply->data, sizeof(*ver)); |
|---|
| 359 | 355 | |
|---|
| 360 | 356 | dev_info(bus->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", |
|---|
| 361 | 357 | ver->fw_ivn, ver->vendor_id, ver->radio_type); |
|---|
| .. | .. |
|---|
| 405 | 401 | int ret; |
|---|
| 406 | 402 | |
|---|
| 407 | 403 | bus = cldev->bus; |
|---|
| 408 | | - |
|---|
| 409 | | - dev_dbg(&cldev->dev, "running hook %s\n", __func__); |
|---|
| 410 | 404 | |
|---|
| 411 | 405 | mutex_lock(&bus->device_lock); |
|---|
| 412 | 406 | /* we need to connect to INFO GUID */ |
|---|
| .. | .. |
|---|
| 469 | 463 | dev_dbg(bus->dev, "end of fixup match = %d\n", cldev->do_match); |
|---|
| 470 | 464 | } |
|---|
| 471 | 465 | |
|---|
| 466 | +/** |
|---|
| 467 | + * vt_support - enable on bus clients with vtag support |
|---|
| 468 | + * |
|---|
| 469 | + * @cldev: me clients device |
|---|
| 470 | + */ |
|---|
| 471 | +static void vt_support(struct mei_cl_device *cldev) |
|---|
| 472 | +{ |
|---|
| 473 | + if (cldev->me_cl->props.vt_supported == 1) |
|---|
| 474 | + cldev->do_match = 1; |
|---|
| 475 | +} |
|---|
| 476 | + |
|---|
| 472 | 477 | #define MEI_FIXUP(_uuid, _hook) { _uuid, _hook } |
|---|
| 473 | 478 | |
|---|
| 474 | 479 | static struct mei_fixup { |
|---|
| .. | .. |
|---|
| 481 | 486 | MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc), |
|---|
| 482 | 487 | MEI_FIXUP(MEI_UUID_WD, mei_wd), |
|---|
| 483 | 488 | MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix), |
|---|
| 489 | + MEI_FIXUP(MEI_UUID_HDCP, whitelist), |
|---|
| 490 | + MEI_FIXUP(MEI_UUID_ANY, vt_support), |
|---|
| 484 | 491 | }; |
|---|
| 485 | 492 | |
|---|
| 486 | 493 | /** |
|---|