Commit 5a44988207ee16b96e5445b8e95ab9881ce310cc

Authored by Tomas Winkler
Committed by Greg Kroah-Hartman
1 parent 4f3afe1d8c

mei: move doc files Documentation/misc-devices/mei

1. move mei.txt, TODO, and the example code under Documentation/misc-devices/mei
2. update the TODO file

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 8 changed files with 710 additions and 706 deletions Side-by-side Diff

Documentation/Makefile
1 1 obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
2 2 filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
3   - pcmcia/ spi/ timers/ watchdog/src/
  3 + pcmcia/ spi/ timers/ watchdog/src/ misc-devices/mei/
Documentation/misc-devices/mei/Makefile
  1 +# kbuild trick to avoid linker error. Can be omitted if a module is built.
  2 +obj- := dummy.o
  3 +
  4 +# List of programs to build
  5 +hostprogs-y := mei-amt-version
  6 +HOSTCFLAGS_mei-amt-version.o += -I$(objtree)/usr/include
  7 +# Tell kbuild to always build the programs
  8 +always := $(hostprogs-y)
Documentation/misc-devices/mei/TODO
  1 +TODO:
  2 + - Cleanup and split the timer function
  3 +Upon Unstaging:
  4 + - Documentation/ioctl/ioctl-number.txt
  5 + - Updated MAINTAINERS
Documentation/misc-devices/mei/mei-amt-version.c
  1 +/******************************************************************************
  2 + * Intel Management Engine Interface (Intel MEI) Linux driver
  3 + * Intel MEI Interface Header
  4 + *
  5 + * This file is provided under a dual BSD/GPLv2 license. When using or
  6 + * redistributing this file, you may do so under either license.
  7 + *
  8 + * GPL LICENSE SUMMARY
  9 + *
  10 + * Copyright(c) 2012 Intel Corporation. All rights reserved.
  11 + *
  12 + * This program is free software; you can redistribute it and/or modify
  13 + * it under the terms of version 2 of the GNU General Public License as
  14 + * published by the Free Software Foundation.
  15 + *
  16 + * This program is distributed in the hope that it will be useful, but
  17 + * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19 + * General Public License for more details.
  20 + *
  21 + * You should have received a copy of the GNU General Public License
  22 + * along with this program; if not, write to the Free Software
  23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  24 + * USA
  25 + *
  26 + * The full GNU General Public License is included in this distribution
  27 + * in the file called LICENSE.GPL.
  28 + *
  29 + * Contact Information:
  30 + * Intel Corporation.
  31 + * linux-mei@linux.intel.com
  32 + * http://www.intel.com
  33 + *
  34 + * BSD LICENSE
  35 + *
  36 + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  37 + * All rights reserved.
  38 + *
  39 + * Redistribution and use in source and binary forms, with or without
  40 + * modification, are permitted provided that the following conditions
  41 + * are met:
  42 + *
  43 + * * Redistributions of source code must retain the above copyright
  44 + * notice, this list of conditions and the following disclaimer.
  45 + * * Redistributions in binary form must reproduce the above copyright
  46 + * notice, this list of conditions and the following disclaimer in
  47 + * the documentation and/or other materials provided with the
  48 + * distribution.
  49 + * * Neither the name Intel Corporation nor the names of its
  50 + * contributors may be used to endorse or promote products derived
  51 + * from this software without specific prior written permission.
  52 + *
  53 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  54 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  55 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  56 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  57 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  58 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  59 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  60 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  61 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  62 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  63 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64 + *
  65 + *****************************************************************************/
  66 +
  67 +#include <stdio.h>
  68 +#include <stdlib.h>
  69 +#include <string.h>
  70 +#include <fcntl.h>
  71 +#include <sys/ioctl.h>
  72 +#include <unistd.h>
  73 +#include <errno.h>
  74 +#include <stdint.h>
  75 +#include <stdbool.h>
  76 +#include <bits/wordsize.h>
  77 +#include <linux/mei.h>
  78 +
  79 +/*****************************************************************************
  80 + * Intel Management Engine Interface
  81 + *****************************************************************************/
  82 +
  83 +#define mei_msg(_me, fmt, ARGS...) do { \
  84 + if (_me->verbose) \
  85 + fprintf(stderr, fmt, ##ARGS); \
  86 +} while (0)
  87 +
  88 +#define mei_err(_me, fmt, ARGS...) do { \
  89 + fprintf(stderr, "Error: " fmt, ##ARGS); \
  90 +} while (0)
  91 +
  92 +struct mei {
  93 + uuid_le guid;
  94 + bool initialized;
  95 + bool verbose;
  96 + unsigned int buf_size;
  97 + unsigned char prot_ver;
  98 + int fd;
  99 +};
  100 +
  101 +static void mei_deinit(struct mei *cl)
  102 +{
  103 + if (cl->fd != -1)
  104 + close(cl->fd);
  105 + cl->fd = -1;
  106 + cl->buf_size = 0;
  107 + cl->prot_ver = 0;
  108 + cl->initialized = false;
  109 +}
  110 +
  111 +static bool mei_init(struct mei *me, const uuid_le *guid,
  112 + unsigned char req_protocol_version, bool verbose)
  113 +{
  114 + int result;
  115 + struct mei_client *cl;
  116 + struct mei_connect_client_data data;
  117 +
  118 + mei_deinit(me);
  119 +
  120 + me->verbose = verbose;
  121 +
  122 + me->fd = open("/dev/mei", O_RDWR);
  123 + if (me->fd == -1) {
  124 + mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
  125 + goto err;
  126 + }
  127 + memcpy(&me->guid, guid, sizeof(*guid));
  128 + memset(&data, 0, sizeof(data));
  129 + me->initialized = true;
  130 +
  131 + memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
  132 + result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
  133 + if (result) {
  134 + mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
  135 + goto err;
  136 + }
  137 + cl = &data.out_client_properties;
  138 + mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
  139 + mei_msg(me, "protocol_version %d\n", cl->protocol_version);
  140 +
  141 + if ((req_protocol_version > 0) &&
  142 + (cl->protocol_version != req_protocol_version)) {
  143 + mei_err(me, "Intel MEI protocol version not supported\n");
  144 + goto err;
  145 + }
  146 +
  147 + me->buf_size = cl->max_msg_length;
  148 + me->prot_ver = cl->protocol_version;
  149 +
  150 + return true;
  151 +err:
  152 + mei_deinit(me);
  153 + return false;
  154 +}
  155 +
  156 +static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
  157 + ssize_t len, unsigned long timeout)
  158 +{
  159 + ssize_t rc;
  160 +
  161 + mei_msg(me, "call read length = %zd\n", len);
  162 +
  163 + rc = read(me->fd, buffer, len);
  164 + if (rc < 0) {
  165 + mei_err(me, "read failed with status %zd %s\n",
  166 + rc, strerror(errno));
  167 + mei_deinit(me);
  168 + } else {
  169 + mei_msg(me, "read succeeded with result %zd\n", rc);
  170 + }
  171 + return rc;
  172 +}
  173 +
  174 +static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer,
  175 + ssize_t len, unsigned long timeout)
  176 +{
  177 + struct timeval tv;
  178 + ssize_t written;
  179 + ssize_t rc;
  180 + fd_set set;
  181 +
  182 + tv.tv_sec = timeout / 1000;
  183 + tv.tv_usec = (timeout % 1000) * 1000000;
  184 +
  185 + mei_msg(me, "call write length = %zd\n", len);
  186 +
  187 + written = write(me->fd, buffer, len);
  188 + if (written < 0) {
  189 + rc = -errno;
  190 + mei_err(me, "write failed with status %zd %s\n",
  191 + written, strerror(errno));
  192 + goto out;
  193 + }
  194 +
  195 + FD_ZERO(&set);
  196 + FD_SET(me->fd, &set);
  197 + rc = select(me->fd + 1 , &set, NULL, NULL, &tv);
  198 + if (rc > 0 && FD_ISSET(me->fd, &set)) {
  199 + mei_msg(me, "write success\n");
  200 + } else if (rc == 0) {
  201 + mei_err(me, "write failed on timeout with status\n");
  202 + goto out;
  203 + } else { /* rc < 0 */
  204 + mei_err(me, "write failed on select with status %zd\n", rc);
  205 + goto out;
  206 + }
  207 +
  208 + rc = written;
  209 +out:
  210 + if (rc < 0)
  211 + mei_deinit(me);
  212 +
  213 + return rc;
  214 +}
  215 +
  216 +/***************************************************************************
  217 + * Intel Advanced Management Technolgy ME Client
  218 + ***************************************************************************/
  219 +
  220 +#define AMT_MAJOR_VERSION 1
  221 +#define AMT_MINOR_VERSION 1
  222 +
  223 +#define AMT_STATUS_SUCCESS 0x0
  224 +#define AMT_STATUS_INTERNAL_ERROR 0x1
  225 +#define AMT_STATUS_NOT_READY 0x2
  226 +#define AMT_STATUS_INVALID_AMT_MODE 0x3
  227 +#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
  228 +
  229 +#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000
  230 +#define AMT_STATUS_SDK_RESOURCES 0x1004
  231 +
  232 +
  233 +#define AMT_BIOS_VERSION_LEN 65
  234 +#define AMT_VERSIONS_NUMBER 50
  235 +#define AMT_UNICODE_STRING_LEN 20
  236 +
  237 +struct amt_unicode_string {
  238 + uint16_t length;
  239 + char string[AMT_UNICODE_STRING_LEN];
  240 +} __attribute__((packed));
  241 +
  242 +struct amt_version_type {
  243 + struct amt_unicode_string description;
  244 + struct amt_unicode_string version;
  245 +} __attribute__((packed));
  246 +
  247 +struct amt_version {
  248 + uint8_t major;
  249 + uint8_t minor;
  250 +} __attribute__((packed));
  251 +
  252 +struct amt_code_versions {
  253 + uint8_t bios[AMT_BIOS_VERSION_LEN];
  254 + uint32_t count;
  255 + struct amt_version_type versions[AMT_VERSIONS_NUMBER];
  256 +} __attribute__((packed));
  257 +
  258 +/***************************************************************************
  259 + * Intel Advanced Management Technolgy Host Interface
  260 + ***************************************************************************/
  261 +
  262 +struct amt_host_if_msg_header {
  263 + struct amt_version version;
  264 + uint16_t _reserved;
  265 + uint32_t command;
  266 + uint32_t length;
  267 +} __attribute__((packed));
  268 +
  269 +struct amt_host_if_resp_header {
  270 + struct amt_host_if_msg_header header;
  271 + uint32_t status;
  272 + unsigned char data[0];
  273 +} __attribute__((packed));
  274 +
  275 +const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \
  276 + 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
  277 +
  278 +#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A
  279 +#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
  280 +
  281 +const struct amt_host_if_msg_header CODE_VERSION_REQ = {
  282 + .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
  283 + ._reserved = 0,
  284 + .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
  285 + .length = 0
  286 +};
  287 +
  288 +
  289 +struct amt_host_if {
  290 + struct mei mei_cl;
  291 + unsigned long send_timeout;
  292 + bool initialized;
  293 +};
  294 +
  295 +
  296 +static bool amt_host_if_init(struct amt_host_if *acmd,
  297 + unsigned long send_timeout, bool verbose)
  298 +{
  299 + acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
  300 + acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose);
  301 + return acmd->initialized;
  302 +}
  303 +
  304 +static void amt_host_if_deinit(struct amt_host_if *acmd)
  305 +{
  306 + mei_deinit(&acmd->mei_cl);
  307 + acmd->initialized = false;
  308 +}
  309 +
  310 +static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
  311 +{
  312 + uint32_t status = AMT_STATUS_SUCCESS;
  313 + struct amt_code_versions *code_ver;
  314 + size_t code_ver_len;
  315 + uint32_t ver_type_cnt;
  316 + uint32_t len;
  317 + uint32_t i;
  318 +
  319 + code_ver = (struct amt_code_versions *)resp->data;
  320 + /* length - sizeof(status) */
  321 + code_ver_len = resp->header.length - sizeof(uint32_t);
  322 + ver_type_cnt = code_ver_len -
  323 + sizeof(code_ver->bios) -
  324 + sizeof(code_ver->count);
  325 + if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
  326 + status = AMT_STATUS_INTERNAL_ERROR;
  327 + goto out;
  328 + }
  329 +
  330 + for (i = 0; i < code_ver->count; i++) {
  331 + len = code_ver->versions[i].description.length;
  332 +
  333 + if (len > AMT_UNICODE_STRING_LEN) {
  334 + status = AMT_STATUS_INTERNAL_ERROR;
  335 + goto out;
  336 + }
  337 +
  338 + len = code_ver->versions[i].version.length;
  339 + if (code_ver->versions[i].version.string[len] != '\0' ||
  340 + len != strlen(code_ver->versions[i].version.string)) {
  341 + status = AMT_STATUS_INTERNAL_ERROR;
  342 + goto out;
  343 + }
  344 + }
  345 +out:
  346 + return status;
  347 +}
  348 +
  349 +static uint32_t amt_verify_response_header(uint32_t command,
  350 + const struct amt_host_if_msg_header *resp_hdr,
  351 + uint32_t response_size)
  352 +{
  353 + if (response_size < sizeof(struct amt_host_if_resp_header)) {
  354 + return AMT_STATUS_INTERNAL_ERROR;
  355 + } else if (response_size != (resp_hdr->length +
  356 + sizeof(struct amt_host_if_msg_header))) {
  357 + return AMT_STATUS_INTERNAL_ERROR;
  358 + } else if (resp_hdr->command != command) {
  359 + return AMT_STATUS_INTERNAL_ERROR;
  360 + } else if (resp_hdr->_reserved != 0) {
  361 + return AMT_STATUS_INTERNAL_ERROR;
  362 + } else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
  363 + resp_hdr->version.minor < AMT_MINOR_VERSION) {
  364 + return AMT_STATUS_INTERNAL_ERROR;
  365 + }
  366 + return AMT_STATUS_SUCCESS;
  367 +}
  368 +
  369 +static uint32_t amt_host_if_call(struct amt_host_if *acmd,
  370 + const unsigned char *command, ssize_t command_sz,
  371 + uint8_t **read_buf, uint32_t rcmd,
  372 + unsigned int expected_sz)
  373 +{
  374 + uint32_t in_buf_sz;
  375 + uint32_t out_buf_sz;
  376 + ssize_t written;
  377 + uint32_t status;
  378 + struct amt_host_if_resp_header *msg_hdr;
  379 +
  380 + in_buf_sz = acmd->mei_cl.buf_size;
  381 + *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
  382 + if (*read_buf == NULL)
  383 + return AMT_STATUS_SDK_RESOURCES;
  384 + memset(*read_buf, 0, in_buf_sz);
  385 + msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
  386 +
  387 + written = mei_send_msg(&acmd->mei_cl,
  388 + command, command_sz, acmd->send_timeout);
  389 + if (written != command_sz)
  390 + return AMT_STATUS_INTERNAL_ERROR;
  391 +
  392 + out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
  393 + if (out_buf_sz <= 0)
  394 + return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
  395 +
  396 + status = msg_hdr->status;
  397 + if (status != AMT_STATUS_SUCCESS)
  398 + return status;
  399 +
  400 + status = amt_verify_response_header(rcmd,
  401 + &msg_hdr->header, out_buf_sz);
  402 + if (status != AMT_STATUS_SUCCESS)
  403 + return status;
  404 +
  405 + if (expected_sz && expected_sz != out_buf_sz)
  406 + return AMT_STATUS_INTERNAL_ERROR;
  407 +
  408 + return AMT_STATUS_SUCCESS;
  409 +}
  410 +
  411 +
  412 +static uint32_t amt_get_code_versions(struct amt_host_if *cmd,
  413 + struct amt_code_versions *versions)
  414 +{
  415 + struct amt_host_if_resp_header *response = NULL;
  416 + uint32_t status;
  417 +
  418 + status = amt_host_if_call(cmd,
  419 + (const unsigned char *)&CODE_VERSION_REQ,
  420 + sizeof(CODE_VERSION_REQ),
  421 + (uint8_t **)&response,
  422 + AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
  423 +
  424 + if (status != AMT_STATUS_SUCCESS)
  425 + goto out;
  426 +
  427 + status = amt_verify_code_versions(response);
  428 + if (status != AMT_STATUS_SUCCESS)
  429 + goto out;
  430 +
  431 + memcpy(versions, response->data, sizeof(struct amt_code_versions));
  432 +out:
  433 + if (response != NULL)
  434 + free(response);
  435 +
  436 + return status;
  437 +}
  438 +
  439 +/************************** end of amt_host_if_command ***********************/
  440 +int main(int argc, char **argv)
  441 +{
  442 + struct amt_code_versions ver;
  443 + struct amt_host_if acmd;
  444 + unsigned int i;
  445 + uint32_t status;
  446 + int ret;
  447 + bool verbose;
  448 +
  449 + verbose = (argc > 1 && strcmp(argv[1], "-v") == 0);
  450 +
  451 + if (!amt_host_if_init(&acmd, 5000, verbose)) {
  452 + ret = 1;
  453 + goto out;
  454 + }
  455 +
  456 + status = amt_get_code_versions(&acmd, &ver);
  457 +
  458 + amt_host_if_deinit(&acmd);
  459 +
  460 + switch (status) {
  461 + case AMT_STATUS_HOST_IF_EMPTY_RESPONSE:
  462 + printf("Intel AMT: DISABLED\n");
  463 + ret = 0;
  464 + break;
  465 + case AMT_STATUS_SUCCESS:
  466 + printf("Intel AMT: ENABLED\n");
  467 + for (i = 0; i < ver.count; i++) {
  468 + printf("%s:\t%s\n", ver.versions[i].description.string,
  469 + ver.versions[i].version.string);
  470 + }
  471 + ret = 0;
  472 + break;
  473 + default:
  474 + printf("An error has occurred\n");
  475 + ret = 1;
  476 + break;
  477 + }
  478 +
  479 +out:
  480 + return ret;
  481 +}
Documentation/misc-devices/mei/mei.txt
  1 +Intel(R) Management Engine Interface (Intel(R) MEI)
  2 +=======================
  3 +
  4 +Introduction
  5 +=======================
  6 +
  7 +The Intel Management Engine (Intel ME) is an isolated and protected computing
  8 +resource (Co-processor) residing inside certain Intel chipsets. The Intel ME
  9 +provides support for computer/IT management features. The feature set
  10 +depends on the Intel chipset SKU.
  11 +
  12 +The Intel Management Engine Interface (Intel MEI, previously known as HECI)
  13 +is the interface between the Host and Intel ME. This interface is exposed
  14 +to the host as a PCI device. The Intel MEI Driver is in charge of the
  15 +communication channel between a host application and the Intel ME feature.
  16 +
  17 +Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and
  18 +each client has its own protocol. The protocol is message-based with a
  19 +header and payload up to 512 bytes.
  20 +
  21 +Prominent usage of the Intel ME Interface is to communicate with Intel(R)
  22 +Active Management Technology (Intel AMT)implemented in firmware running on
  23 +the Intel ME.
  24 +
  25 +Intel AMT provides the ability to manage a host remotely out-of-band (OOB)
  26 +even when the operating system running on the host processor has crashed or
  27 +is in a sleep state.
  28 +
  29 +Some examples of Intel AMT usage are:
  30 + - Monitoring hardware state and platform components
  31 + - Remote power off/on (useful for green computing or overnight IT
  32 + maintenance)
  33 + - OS updates
  34 + - Storage of useful platform information such as software assets
  35 + - Built-in hardware KVM
  36 + - Selective network isolation of Ethernet and IP protocol flows based
  37 + on policies set by a remote management console
  38 + - IDE device redirection from remote management console
  39 +
  40 +Intel AMT (OOB) communication is based on SOAP (deprecated
  41 +starting with Release 6.0) over HTTP/S or WS-Management protocol over
  42 +HTTP/S that are received from a remote management console application.
  43 +
  44 +For more information about Intel AMT:
  45 +http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
  46 +
  47 +Intel MEI Driver
  48 +=======================
  49 +
  50 +The driver exposes a misc device called /dev/mei.
  51 +
  52 +An application maintains communication with an Intel ME feature while
  53 +/dev/mei is open. The binding to a specific features is performed by calling
  54 +MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
  55 +The number of instances of an Intel ME feature that can be opened
  56 +at the same time depends on the Intel ME feature, but most of the
  57 +features allow only a single instance.
  58 +
  59 +The Intel AMT Host Interface (Intel AMTHI) feature supports multiple
  60 +simultaneous user applications. Therefore, the Intel MEI driver handles
  61 +this internally by maintaining request queues for the applications.
  62 +
  63 +The driver is oblivious to data that is passed between firmware feature
  64 +and host application.
  65 +
  66 +Because some of the Intel ME features can change the system
  67 +configuration, the driver by default allows only a privileged
  68 +user to access it.
  69 +
  70 +A code snippet for an application communicating with
  71 +Intel AMTHI client:
  72 + struct mei_connect_client_data data;
  73 + fd = open(MEI_DEVICE);
  74 +
  75 + data.d.in_client_uuid = AMTHI_UUID;
  76 +
  77 + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);
  78 +
  79 + printf("Ver=%d, MaxLen=%ld\n",
  80 + data.d.in_client_uuid.protocol_version,
  81 + data.d.in_client_uuid.max_msg_length);
  82 +
  83 + [...]
  84 +
  85 + write(fd, amthi_req_data, amthi_req_data_len);
  86 +
  87 + [...]
  88 +
  89 + read(fd, &amthi_res_data, amthi_res_data_len);
  90 +
  91 + [...]
  92 + close(fd);
  93 +
  94 +IOCTL:
  95 +======
  96 +The Intel MEI Driver supports the following IOCTL command:
  97 + IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client).
  98 +
  99 + usage:
  100 + struct mei_connect_client_data clientData;
  101 + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData);
  102 +
  103 + inputs:
  104 + mei_connect_client_data struct contain the following
  105 + input field:
  106 +
  107 + in_client_uuid - UUID of the FW Feature that needs
  108 + to connect to.
  109 + outputs:
  110 + out_client_properties - Client Properties: MTU and Protocol Version.
  111 +
  112 + error returns:
  113 + EINVAL Wrong IOCTL Number
  114 + ENODEV Device or Connection is not initialized or ready.
  115 + (e.g. Wrong UUID)
  116 + ENOMEM Unable to allocate memory to client internal data.
  117 + EFAULT Fatal Error (e.g. Unable to access user input data)
  118 + EBUSY Connection Already Open
  119 +
  120 + Notes:
  121 + max_msg_length (MTU) in client properties describes the maximum
  122 + data that can be sent or received. (e.g. if MTU=2K, can send
  123 + requests up to bytes 2k and received responses upto 2k bytes).
  124 +
  125 +Intel ME Applications:
  126 +==============
  127 +
  128 +1) Intel Local Management Service (Intel LMS)
  129 +
  130 + Applications running locally on the platform communicate with Intel AMT Release
  131 + 2.0 and later releases in the same way that network applications do via SOAP
  132 + over HTTP (deprecated starting with Release 6.0) or with WS-Management over
  133 + SOAP over HTTP. This means that some Intel AMT features can be accessed from a
  134 + local application using the same network interface as a remote application
  135 + communicating with Intel AMT over the network.
  136 +
  137 + When a local application sends a message addressed to the local Intel AMT host
  138 + name, the Intel LMS, which listens for traffic directed to the host name,
  139 + intercepts the message and routes it to the Intel MEI.
  140 + For more information:
  141 + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
  142 + Under "About Intel AMT" => "Local Access"
  143 +
  144 + For downloading Intel LMS:
  145 + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
  146 +
  147 + The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS
  148 + firmware feature using a defined UUID and then communicates with the feature
  149 + using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol).
  150 + The protocol is used to maintain multiple sessions with Intel AMT from a
  151 + single application.
  152 +
  153 + See the protocol specification in the Intel AMT Software Development Kit(SDK)
  154 + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
  155 + Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)"
  156 + => "Information for Intel(R) vPro(TM) Gateway Developers"
  157 + => "Description of the Intel AMT Port Forwarding (APF)Protocol"
  158 +
  159 + 2) Intel AMT Remote configuration using a Local Agent
  160 + A Local Agent enables IT personnel to configure Intel AMT out-of-the-box
  161 + without requiring installing additional data to enable setup. The remote
  162 + configuration process may involve an ISV-developed remote configuration
  163 + agent that runs on the host.
  164 + For more information:
  165 + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
  166 + Under "Setup and Configuration of Intel AMT" =>
  167 + "SDK Tools Supporting Setup and Configuration" =>
  168 + "Using the Local Agent Sample"
  169 +
  170 + An open source Intel AMT configuration utility, implementing a local agent
  171 + that accesses the Intel MEI driver, can be found here:
  172 + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
  173 +
  174 +
  175 +Intel AMT OS Health Watchdog:
  176 +=============================
  177 +The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
  178 +Whenever the OS hangs or crashes, Intel AMT will send an event
  179 +to any subscriber to this event. This mechanism means that
  180 +IT knows when a platform crashes even when there is a hard failure on the host.
  181 +
  182 +The Intel AMT Watchdog is composed of two parts:
  183 + 1) Firmware feature - receives the heartbeats
  184 + and sends an event when the heartbeats stop.
  185 + 2) Intel MEI driver - connects to the watchdog feature, configures the
  186 + watchdog and sends the heartbeats.
  187 +
  188 +The Intel MEI driver uses the kernel watchdog to configure the Intel AMT
  189 +Watchdog and to send heartbeats to it. The default timeout of the
  190 +watchdog is 120 seconds.
  191 +
  192 +If the Intel AMT Watchdog feature does not exist (i.e. the connection failed),
  193 +the Intel MEI driver will disable the sending of heartbeats.
  194 +
  195 +Supported Chipsets:
  196 +==================
  197 +7 Series Chipset Family
  198 +6 Series Chipset Family
  199 +5 Series Chipset Family
  200 +4 Series Chipset Family
  201 +Mobile 4 Series Chipset Family
  202 +ICH9
  203 +82946GZ/GL
  204 +82G35 Express
  205 +82Q963/Q965
  206 +82P965/G965
  207 +Mobile PM965/GM965
  208 +Mobile GME965/GLE960
  209 +82Q35 Express
  210 +82G33/G31/P35/P31 Express
  211 +82Q33 Express
  212 +82X38/X48 Express
  213 +
  214 +---
  215 +linux-mei@linux.intel.com
drivers/misc/mei/TODO
1   -TODO:
2   - - Cleanup and split the timer function
3   -Upon Unstaging:
4   - - Documentation/ioctl/ioctl-number.txt
5   - - move mei.txt under Documentation/mei/
6   - - move mei-amt-version.c under Documentation/mei
7   - - add hostprogs-y for mei-amt-version.c
8   - - drop mei_version.h
9   - - Updated MAINTAINERS
drivers/misc/mei/mei-amt-version.c
1   -/******************************************************************************
2   - * Intel Management Engine Interface (Intel MEI) Linux driver
3   - * Intel MEI Interface Header
4   - *
5   - * This file is provided under a dual BSD/GPLv2 license. When using or
6   - * redistributing this file, you may do so under either license.
7   - *
8   - * GPL LICENSE SUMMARY
9   - *
10   - * Copyright(c) 2012 Intel Corporation. All rights reserved.
11   - *
12   - * This program is free software; you can redistribute it and/or modify
13   - * it under the terms of version 2 of the GNU General Public License as
14   - * published by the Free Software Foundation.
15   - *
16   - * This program is distributed in the hope that it will be useful, but
17   - * WITHOUT ANY WARRANTY; without even the implied warranty of
18   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19   - * General Public License for more details.
20   - *
21   - * You should have received a copy of the GNU General Public License
22   - * along with this program; if not, write to the Free Software
23   - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24   - * USA
25   - *
26   - * The full GNU General Public License is included in this distribution
27   - * in the file called LICENSE.GPL.
28   - *
29   - * Contact Information:
30   - * Intel Corporation.
31   - * linux-mei@linux.intel.com
32   - * http://www.intel.com
33   - *
34   - * BSD LICENSE
35   - *
36   - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
37   - * All rights reserved.
38   - *
39   - * Redistribution and use in source and binary forms, with or without
40   - * modification, are permitted provided that the following conditions
41   - * are met:
42   - *
43   - * * Redistributions of source code must retain the above copyright
44   - * notice, this list of conditions and the following disclaimer.
45   - * * Redistributions in binary form must reproduce the above copyright
46   - * notice, this list of conditions and the following disclaimer in
47   - * the documentation and/or other materials provided with the
48   - * distribution.
49   - * * Neither the name Intel Corporation nor the names of its
50   - * contributors may be used to endorse or promote products derived
51   - * from this software without specific prior written permission.
52   - *
53   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54   - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55   - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56   - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57   - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59   - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60   - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61   - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62   - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
63   - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64   - *
65   - *****************************************************************************/
66   -
67   -#include <stdio.h>
68   -#include <stdlib.h>
69   -#include <string.h>
70   -#include <fcntl.h>
71   -#include <sys/ioctl.h>
72   -#include <unistd.h>
73   -#include <errno.h>
74   -#include <stdint.h>
75   -#include <stdbool.h>
76   -#include <bits/wordsize.h>
77   -#include <linux/mei.h>
78   -
79   -/*****************************************************************************
80   - * Intel Management Engine Interface
81   - *****************************************************************************/
82   -
83   -#define mei_msg(_me, fmt, ARGS...) do { \
84   - if (_me->verbose) \
85   - fprintf(stderr, fmt, ##ARGS); \
86   -} while (0)
87   -
88   -#define mei_err(_me, fmt, ARGS...) do { \
89   - fprintf(stderr, "Error: " fmt, ##ARGS); \
90   -} while (0)
91   -
92   -struct mei {
93   - uuid_le guid;
94   - bool initialized;
95   - bool verbose;
96   - unsigned int buf_size;
97   - unsigned char prot_ver;
98   - int fd;
99   -};
100   -
101   -static void mei_deinit(struct mei *cl)
102   -{
103   - if (cl->fd != -1)
104   - close(cl->fd);
105   - cl->fd = -1;
106   - cl->buf_size = 0;
107   - cl->prot_ver = 0;
108   - cl->initialized = false;
109   -}
110   -
111   -static bool mei_init(struct mei *me, const uuid_le *guid,
112   - unsigned char req_protocol_version, bool verbose)
113   -{
114   - int result;
115   - struct mei_client *cl;
116   - struct mei_connect_client_data data;
117   -
118   - mei_deinit(me);
119   -
120   - me->verbose = verbose;
121   -
122   - me->fd = open("/dev/mei", O_RDWR);
123   - if (me->fd == -1) {
124   - mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
125   - goto err;
126   - }
127   - memcpy(&me->guid, guid, sizeof(*guid));
128   - memset(&data, 0, sizeof(data));
129   - me->initialized = true;
130   -
131   - memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
132   - result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
133   - if (result) {
134   - mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
135   - goto err;
136   - }
137   - cl = &data.out_client_properties;
138   - mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
139   - mei_msg(me, "protocol_version %d\n", cl->protocol_version);
140   -
141   - if ((req_protocol_version > 0) &&
142   - (cl->protocol_version != req_protocol_version)) {
143   - mei_err(me, "Intel MEI protocol version not supported\n");
144   - goto err;
145   - }
146   -
147   - me->buf_size = cl->max_msg_length;
148   - me->prot_ver = cl->protocol_version;
149   -
150   - return true;
151   -err:
152   - mei_deinit(me);
153   - return false;
154   -}
155   -
156   -static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
157   - ssize_t len, unsigned long timeout)
158   -{
159   - ssize_t rc;
160   -
161   - mei_msg(me, "call read length = %zd\n", len);
162   -
163   - rc = read(me->fd, buffer, len);
164   - if (rc < 0) {
165   - mei_err(me, "read failed with status %zd %s\n",
166   - rc, strerror(errno));
167   - mei_deinit(me);
168   - } else {
169   - mei_msg(me, "read succeeded with result %zd\n", rc);
170   - }
171   - return rc;
172   -}
173   -
174   -static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer,
175   - ssize_t len, unsigned long timeout)
176   -{
177   - struct timeval tv;
178   - ssize_t written;
179   - ssize_t rc;
180   - fd_set set;
181   -
182   - tv.tv_sec = timeout / 1000;
183   - tv.tv_usec = (timeout % 1000) * 1000000;
184   -
185   - mei_msg(me, "call write length = %zd\n", len);
186   -
187   - written = write(me->fd, buffer, len);
188   - if (written < 0) {
189   - rc = -errno;
190   - mei_err(me, "write failed with status %zd %s\n",
191   - written, strerror(errno));
192   - goto out;
193   - }
194   -
195   - FD_ZERO(&set);
196   - FD_SET(me->fd, &set);
197   - rc = select(me->fd + 1 , &set, NULL, NULL, &tv);
198   - if (rc > 0 && FD_ISSET(me->fd, &set)) {
199   - mei_msg(me, "write success\n");
200   - } else if (rc == 0) {
201   - mei_err(me, "write failed on timeout with status\n");
202   - goto out;
203   - } else { /* rc < 0 */
204   - mei_err(me, "write failed on select with status %zd\n", rc);
205   - goto out;
206   - }
207   -
208   - rc = written;
209   -out:
210   - if (rc < 0)
211   - mei_deinit(me);
212   -
213   - return rc;
214   -}
215   -
216   -/***************************************************************************
217   - * Intel Advanced Management Technolgy ME Client
218   - ***************************************************************************/
219   -
220   -#define AMT_MAJOR_VERSION 1
221   -#define AMT_MINOR_VERSION 1
222   -
223   -#define AMT_STATUS_SUCCESS 0x0
224   -#define AMT_STATUS_INTERNAL_ERROR 0x1
225   -#define AMT_STATUS_NOT_READY 0x2
226   -#define AMT_STATUS_INVALID_AMT_MODE 0x3
227   -#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
228   -
229   -#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000
230   -#define AMT_STATUS_SDK_RESOURCES 0x1004
231   -
232   -
233   -#define AMT_BIOS_VERSION_LEN 65
234   -#define AMT_VERSIONS_NUMBER 50
235   -#define AMT_UNICODE_STRING_LEN 20
236   -
237   -struct amt_unicode_string {
238   - uint16_t length;
239   - char string[AMT_UNICODE_STRING_LEN];
240   -} __attribute__((packed));
241   -
242   -struct amt_version_type {
243   - struct amt_unicode_string description;
244   - struct amt_unicode_string version;
245   -} __attribute__((packed));
246   -
247   -struct amt_version {
248   - uint8_t major;
249   - uint8_t minor;
250   -} __attribute__((packed));
251   -
252   -struct amt_code_versions {
253   - uint8_t bios[AMT_BIOS_VERSION_LEN];
254   - uint32_t count;
255   - struct amt_version_type versions[AMT_VERSIONS_NUMBER];
256   -} __attribute__((packed));
257   -
258   -/***************************************************************************
259   - * Intel Advanced Management Technolgy Host Interface
260   - ***************************************************************************/
261   -
262   -struct amt_host_if_msg_header {
263   - struct amt_version version;
264   - uint16_t _reserved;
265   - uint32_t command;
266   - uint32_t length;
267   -} __attribute__((packed));
268   -
269   -struct amt_host_if_resp_header {
270   - struct amt_host_if_msg_header header;
271   - uint32_t status;
272   - unsigned char data[0];
273   -} __attribute__((packed));
274   -
275   -const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \
276   - 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
277   -
278   -#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A
279   -#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
280   -
281   -const struct amt_host_if_msg_header CODE_VERSION_REQ = {
282   - .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
283   - ._reserved = 0,
284   - .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
285   - .length = 0
286   -};
287   -
288   -
289   -struct amt_host_if {
290   - struct mei mei_cl;
291   - unsigned long send_timeout;
292   - bool initialized;
293   -};
294   -
295   -
296   -static bool amt_host_if_init(struct amt_host_if *acmd,
297   - unsigned long send_timeout, bool verbose)
298   -{
299   - acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
300   - acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose);
301   - return acmd->initialized;
302   -}
303   -
304   -static void amt_host_if_deinit(struct amt_host_if *acmd)
305   -{
306   - mei_deinit(&acmd->mei_cl);
307   - acmd->initialized = false;
308   -}
309   -
310   -static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
311   -{
312   - uint32_t status = AMT_STATUS_SUCCESS;
313   - struct amt_code_versions *code_ver;
314   - size_t code_ver_len;
315   - uint32_t ver_type_cnt;
316   - uint32_t len;
317   - uint32_t i;
318   -
319   - code_ver = (struct amt_code_versions *)resp->data;
320   - /* length - sizeof(status) */
321   - code_ver_len = resp->header.length - sizeof(uint32_t);
322   - ver_type_cnt = code_ver_len -
323   - sizeof(code_ver->bios) -
324   - sizeof(code_ver->count);
325   - if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
326   - status = AMT_STATUS_INTERNAL_ERROR;
327   - goto out;
328   - }
329   -
330   - for (i = 0; i < code_ver->count; i++) {
331   - len = code_ver->versions[i].description.length;
332   -
333   - if (len > AMT_UNICODE_STRING_LEN) {
334   - status = AMT_STATUS_INTERNAL_ERROR;
335   - goto out;
336   - }
337   -
338   - len = code_ver->versions[i].version.length;
339   - if (code_ver->versions[i].version.string[len] != '\0' ||
340   - len != strlen(code_ver->versions[i].version.string)) {
341   - status = AMT_STATUS_INTERNAL_ERROR;
342   - goto out;
343   - }
344   - }
345   -out:
346   - return status;
347   -}
348   -
349   -static uint32_t amt_verify_response_header(uint32_t command,
350   - const struct amt_host_if_msg_header *resp_hdr,
351   - uint32_t response_size)
352   -{
353   - if (response_size < sizeof(struct amt_host_if_resp_header)) {
354   - return AMT_STATUS_INTERNAL_ERROR;
355   - } else if (response_size != (resp_hdr->length +
356   - sizeof(struct amt_host_if_msg_header))) {
357   - return AMT_STATUS_INTERNAL_ERROR;
358   - } else if (resp_hdr->command != command) {
359   - return AMT_STATUS_INTERNAL_ERROR;
360   - } else if (resp_hdr->_reserved != 0) {
361   - return AMT_STATUS_INTERNAL_ERROR;
362   - } else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
363   - resp_hdr->version.minor < AMT_MINOR_VERSION) {
364   - return AMT_STATUS_INTERNAL_ERROR;
365   - }
366   - return AMT_STATUS_SUCCESS;
367   -}
368   -
369   -static uint32_t amt_host_if_call(struct amt_host_if *acmd,
370   - const unsigned char *command, ssize_t command_sz,
371   - uint8_t **read_buf, uint32_t rcmd,
372   - unsigned int expected_sz)
373   -{
374   - uint32_t in_buf_sz;
375   - uint32_t out_buf_sz;
376   - ssize_t written;
377   - uint32_t status;
378   - struct amt_host_if_resp_header *msg_hdr;
379   -
380   - in_buf_sz = acmd->mei_cl.buf_size;
381   - *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
382   - if (*read_buf == NULL)
383   - return AMT_STATUS_SDK_RESOURCES;
384   - memset(*read_buf, 0, in_buf_sz);
385   - msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
386   -
387   - written = mei_send_msg(&acmd->mei_cl,
388   - command, command_sz, acmd->send_timeout);
389   - if (written != command_sz)
390   - return AMT_STATUS_INTERNAL_ERROR;
391   -
392   - out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
393   - if (out_buf_sz <= 0)
394   - return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
395   -
396   - status = msg_hdr->status;
397   - if (status != AMT_STATUS_SUCCESS)
398   - return status;
399   -
400   - status = amt_verify_response_header(rcmd,
401   - &msg_hdr->header, out_buf_sz);
402   - if (status != AMT_STATUS_SUCCESS)
403   - return status;
404   -
405   - if (expected_sz && expected_sz != out_buf_sz)
406   - return AMT_STATUS_INTERNAL_ERROR;
407   -
408   - return AMT_STATUS_SUCCESS;
409   -}
410   -
411   -
412   -static uint32_t amt_get_code_versions(struct amt_host_if *cmd,
413   - struct amt_code_versions *versions)
414   -{
415   - struct amt_host_if_resp_header *response = NULL;
416   - uint32_t status;
417   -
418   - status = amt_host_if_call(cmd,
419   - (const unsigned char *)&CODE_VERSION_REQ,
420   - sizeof(CODE_VERSION_REQ),
421   - (uint8_t **)&response,
422   - AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
423   -
424   - if (status != AMT_STATUS_SUCCESS)
425   - goto out;
426   -
427   - status = amt_verify_code_versions(response);
428   - if (status != AMT_STATUS_SUCCESS)
429   - goto out;
430   -
431   - memcpy(versions, response->data, sizeof(struct amt_code_versions));
432   -out:
433   - if (response != NULL)
434   - free(response);
435   -
436   - return status;
437   -}
438   -
439   -/************************** end of amt_host_if_command ***********************/
440   -int main(int argc, char **argv)
441   -{
442   - struct amt_code_versions ver;
443   - struct amt_host_if acmd;
444   - unsigned int i;
445   - uint32_t status;
446   - int ret;
447   - bool verbose;
448   -
449   - verbose = (argc > 1 && strcmp(argv[1], "-v") == 0);
450   -
451   - if (!amt_host_if_init(&acmd, 5000, verbose)) {
452   - ret = 1;
453   - goto out;
454   - }
455   -
456   - status = amt_get_code_versions(&acmd, &ver);
457   -
458   - amt_host_if_deinit(&acmd);
459   -
460   - switch (status) {
461   - case AMT_STATUS_HOST_IF_EMPTY_RESPONSE:
462   - printf("Intel AMT: DISABLED\n");
463   - ret = 0;
464   - break;
465   - case AMT_STATUS_SUCCESS:
466   - printf("Intel AMT: ENABLED\n");
467   - for (i = 0; i < ver.count; i++) {
468   - printf("%s:\t%s\n", ver.versions[i].description.string,
469   - ver.versions[i].version.string);
470   - }
471   - ret = 0;
472   - break;
473   - default:
474   - printf("An error has occurred\n");
475   - ret = 1;
476   - break;
477   - }
478   -
479   -out:
480   - return ret;
481   -}
drivers/misc/mei/mei.txt
1   -Intel(R) Management Engine Interface (Intel(R) MEI)
2   -=======================
3   -
4   -Introduction
5   -=======================
6   -
7   -The Intel Management Engine (Intel ME) is an isolated and protected computing
8   -resource (Co-processor) residing inside certain Intel chipsets. The Intel ME
9   -provides support for computer/IT management features. The feature set
10   -depends on the Intel chipset SKU.
11   -
12   -The Intel Management Engine Interface (Intel MEI, previously known as HECI)
13   -is the interface between the Host and Intel ME. This interface is exposed
14   -to the host as a PCI device. The Intel MEI Driver is in charge of the
15   -communication channel between a host application and the Intel ME feature.
16   -
17   -Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and
18   -each client has its own protocol. The protocol is message-based with a
19   -header and payload up to 512 bytes.
20   -
21   -Prominent usage of the Intel ME Interface is to communicate with Intel(R)
22   -Active Management Technology (Intel AMT)implemented in firmware running on
23   -the Intel ME.
24   -
25   -Intel AMT provides the ability to manage a host remotely out-of-band (OOB)
26   -even when the operating system running on the host processor has crashed or
27   -is in a sleep state.
28   -
29   -Some examples of Intel AMT usage are:
30   - - Monitoring hardware state and platform components
31   - - Remote power off/on (useful for green computing or overnight IT
32   - maintenance)
33   - - OS updates
34   - - Storage of useful platform information such as software assets
35   - - Built-in hardware KVM
36   - - Selective network isolation of Ethernet and IP protocol flows based
37   - on policies set by a remote management console
38   - - IDE device redirection from remote management console
39   -
40   -Intel AMT (OOB) communication is based on SOAP (deprecated
41   -starting with Release 6.0) over HTTP/S or WS-Management protocol over
42   -HTTP/S that are received from a remote management console application.
43   -
44   -For more information about Intel AMT:
45   -http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
46   -
47   -Intel MEI Driver
48   -=======================
49   -
50   -The driver exposes a misc device called /dev/mei.
51   -
52   -An application maintains communication with an Intel ME feature while
53   -/dev/mei is open. The binding to a specific features is performed by calling
54   -MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
55   -The number of instances of an Intel ME feature that can be opened
56   -at the same time depends on the Intel ME feature, but most of the
57   -features allow only a single instance.
58   -
59   -The Intel AMT Host Interface (Intel AMTHI) feature supports multiple
60   -simultaneous user applications. Therefore, the Intel MEI driver handles
61   -this internally by maintaining request queues for the applications.
62   -
63   -The driver is oblivious to data that is passed between firmware feature
64   -and host application.
65   -
66   -Because some of the Intel ME features can change the system
67   -configuration, the driver by default allows only a privileged
68   -user to access it.
69   -
70   -A code snippet for an application communicating with
71   -Intel AMTHI client:
72   - struct mei_connect_client_data data;
73   - fd = open(MEI_DEVICE);
74   -
75   - data.d.in_client_uuid = AMTHI_UUID;
76   -
77   - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);
78   -
79   - printf("Ver=%d, MaxLen=%ld\n",
80   - data.d.in_client_uuid.protocol_version,
81   - data.d.in_client_uuid.max_msg_length);
82   -
83   - [...]
84   -
85   - write(fd, amthi_req_data, amthi_req_data_len);
86   -
87   - [...]
88   -
89   - read(fd, &amthi_res_data, amthi_res_data_len);
90   -
91   - [...]
92   - close(fd);
93   -
94   -IOCTL:
95   -======
96   -The Intel MEI Driver supports the following IOCTL command:
97   - IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client).
98   -
99   - usage:
100   - struct mei_connect_client_data clientData;
101   - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData);
102   -
103   - inputs:
104   - mei_connect_client_data struct contain the following
105   - input field:
106   -
107   - in_client_uuid - UUID of the FW Feature that needs
108   - to connect to.
109   - outputs:
110   - out_client_properties - Client Properties: MTU and Protocol Version.
111   -
112   - error returns:
113   - EINVAL Wrong IOCTL Number
114   - ENODEV Device or Connection is not initialized or ready.
115   - (e.g. Wrong UUID)
116   - ENOMEM Unable to allocate memory to client internal data.
117   - EFAULT Fatal Error (e.g. Unable to access user input data)
118   - EBUSY Connection Already Open
119   -
120   - Notes:
121   - max_msg_length (MTU) in client properties describes the maximum
122   - data that can be sent or received. (e.g. if MTU=2K, can send
123   - requests up to bytes 2k and received responses upto 2k bytes).
124   -
125   -Intel ME Applications:
126   -==============
127   -
128   -1) Intel Local Management Service (Intel LMS)
129   -
130   - Applications running locally on the platform communicate with Intel AMT Release
131   - 2.0 and later releases in the same way that network applications do via SOAP
132   - over HTTP (deprecated starting with Release 6.0) or with WS-Management over
133   - SOAP over HTTP. This means that some Intel AMT features can be accessed from a
134   - local application using the same network interface as a remote application
135   - communicating with Intel AMT over the network.
136   -
137   - When a local application sends a message addressed to the local Intel AMT host
138   - name, the Intel LMS, which listens for traffic directed to the host name,
139   - intercepts the message and routes it to the Intel MEI.
140   - For more information:
141   - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
142   - Under "About Intel AMT" => "Local Access"
143   -
144   - For downloading Intel LMS:
145   - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
146   -
147   - The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS
148   - firmware feature using a defined UUID and then communicates with the feature
149   - using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol).
150   - The protocol is used to maintain multiple sessions with Intel AMT from a
151   - single application.
152   -
153   - See the protocol specification in the Intel AMT Software Development Kit(SDK)
154   - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
155   - Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)"
156   - => "Information for Intel(R) vPro(TM) Gateway Developers"
157   - => "Description of the Intel AMT Port Forwarding (APF)Protocol"
158   -
159   - 2) Intel AMT Remote configuration using a Local Agent
160   - A Local Agent enables IT personnel to configure Intel AMT out-of-the-box
161   - without requiring installing additional data to enable setup. The remote
162   - configuration process may involve an ISV-developed remote configuration
163   - agent that runs on the host.
164   - For more information:
165   - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
166   - Under "Setup and Configuration of Intel AMT" =>
167   - "SDK Tools Supporting Setup and Configuration" =>
168   - "Using the Local Agent Sample"
169   -
170   - An open source Intel AMT configuration utility, implementing a local agent
171   - that accesses the Intel MEI driver, can be found here:
172   - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
173   -
174   -
175   -Intel AMT OS Health Watchdog:
176   -=============================
177   -The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
178   -Whenever the OS hangs or crashes, Intel AMT will send an event
179   -to any subscriber to this event. This mechanism means that
180   -IT knows when a platform crashes even when there is a hard failure on the host.
181   -
182   -The Intel AMT Watchdog is composed of two parts:
183   - 1) Firmware feature - receives the heartbeats
184   - and sends an event when the heartbeats stop.
185   - 2) Intel MEI driver - connects to the watchdog feature, configures the
186   - watchdog and sends the heartbeats.
187   -
188   -The Intel MEI driver uses the kernel watchdog to configure the Intel AMT
189   -Watchdog and to send heartbeats to it. The default timeout of the
190   -watchdog is 120 seconds.
191   -
192   -If the Intel AMT Watchdog feature does not exist (i.e. the connection failed),
193   -the Intel MEI driver will disable the sending of heartbeats.
194   -
195   -Supported Chipsets:
196   -==================
197   -7 Series Chipset Family
198   -6 Series Chipset Family
199   -5 Series Chipset Family
200   -4 Series Chipset Family
201   -Mobile 4 Series Chipset Family
202   -ICH9
203   -82946GZ/GL
204   -82G35 Express
205   -82Q963/Q965
206   -82P965/G965
207   -Mobile PM965/GM965
208   -Mobile GME965/GLE960
209   -82Q35 Express
210   -82G33/G31/P35/P31 Express
211   -82Q33 Express
212   -82X38/X48 Express
213   -
214   ----
215   -linux-mei@linux.intel.com