Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2012-2019, Intel Corporation. All rights reserved.
0004  * Intel Management Engine Interface (Intel MEI) Linux driver
0005  */
0006 
0007 #include <linux/export.h>
0008 #include <linux/sched.h>
0009 #include <linux/wait.h>
0010 #include <linux/delay.h>
0011 
0012 #include <linux/mei.h>
0013 
0014 #include "mei_dev.h"
0015 #include "hbm.h"
0016 #include "client.h"
0017 
0018 const char *mei_dev_state_str(int state)
0019 {
0020 #define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
0021     switch (state) {
0022     MEI_DEV_STATE(INITIALIZING);
0023     MEI_DEV_STATE(INIT_CLIENTS);
0024     MEI_DEV_STATE(ENABLED);
0025     MEI_DEV_STATE(RESETTING);
0026     MEI_DEV_STATE(DISABLED);
0027     MEI_DEV_STATE(POWERING_DOWN);
0028     MEI_DEV_STATE(POWER_DOWN);
0029     MEI_DEV_STATE(POWER_UP);
0030     default:
0031         return "unknown";
0032     }
0033 #undef MEI_DEV_STATE
0034 }
0035 
0036 const char *mei_pg_state_str(enum mei_pg_state state)
0037 {
0038 #define MEI_PG_STATE(state) case MEI_PG_##state: return #state
0039     switch (state) {
0040     MEI_PG_STATE(OFF);
0041     MEI_PG_STATE(ON);
0042     default:
0043         return "unknown";
0044     }
0045 #undef MEI_PG_STATE
0046 }
0047 
0048 /**
0049  * mei_fw_status2str - convert fw status registers to printable string
0050  *
0051  * @fw_status:  firmware status
0052  * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
0053  * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
0054  *
0055  * Return: number of bytes written or -EINVAL if buffer is to small
0056  */
0057 ssize_t mei_fw_status2str(struct mei_fw_status *fw_status,
0058               char *buf, size_t len)
0059 {
0060     ssize_t cnt = 0;
0061     int i;
0062 
0063     buf[0] = '\0';
0064 
0065     if (len < MEI_FW_STATUS_STR_SZ)
0066         return -EINVAL;
0067 
0068     for (i = 0; i < fw_status->count; i++)
0069         cnt += scnprintf(buf + cnt, len - cnt, "%08X ",
0070                 fw_status->status[i]);
0071 
0072     /* drop last space */
0073     buf[cnt] = '\0';
0074     return cnt;
0075 }
0076 EXPORT_SYMBOL_GPL(mei_fw_status2str);
0077 
0078 /**
0079  * mei_cancel_work - Cancel mei background jobs
0080  *
0081  * @dev: the device structure
0082  */
0083 void mei_cancel_work(struct mei_device *dev)
0084 {
0085     cancel_work_sync(&dev->reset_work);
0086     cancel_work_sync(&dev->bus_rescan_work);
0087 
0088     cancel_delayed_work_sync(&dev->timer_work);
0089 }
0090 EXPORT_SYMBOL_GPL(mei_cancel_work);
0091 
0092 /**
0093  * mei_reset - resets host and fw.
0094  *
0095  * @dev: the device structure
0096  *
0097  * Return: 0 on success or < 0 if the reset hasn't succeeded
0098  */
0099 int mei_reset(struct mei_device *dev)
0100 {
0101     enum mei_dev_state state = dev->dev_state;
0102     bool interrupts_enabled;
0103     int ret;
0104 
0105     if (state != MEI_DEV_INITIALIZING &&
0106         state != MEI_DEV_DISABLED &&
0107         state != MEI_DEV_POWER_DOWN &&
0108         state != MEI_DEV_POWER_UP) {
0109         char fw_sts_str[MEI_FW_STATUS_STR_SZ];
0110 
0111         mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
0112         dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n",
0113              mei_dev_state_str(state), fw_sts_str);
0114     }
0115 
0116     mei_clear_interrupts(dev);
0117 
0118     /* we're already in reset, cancel the init timer
0119      * if the reset was called due the hbm protocol error
0120      * we need to call it before hw start
0121      * so the hbm watchdog won't kick in
0122      */
0123     mei_hbm_idle(dev);
0124 
0125     /* enter reset flow */
0126     interrupts_enabled = state != MEI_DEV_POWER_DOWN;
0127     mei_set_devstate(dev, MEI_DEV_RESETTING);
0128 
0129     dev->reset_count++;
0130     if (dev->reset_count > MEI_MAX_CONSEC_RESET) {
0131         dev_err(dev->dev, "reset: reached maximal consecutive resets: disabling the device\n");
0132         mei_set_devstate(dev, MEI_DEV_DISABLED);
0133         return -ENODEV;
0134     }
0135 
0136     ret = mei_hw_reset(dev, interrupts_enabled);
0137     /* fall through and remove the sw state even if hw reset has failed */
0138 
0139     /* no need to clean up software state in case of power up */
0140     if (state != MEI_DEV_INITIALIZING && state != MEI_DEV_POWER_UP)
0141         mei_cl_all_disconnect(dev);
0142 
0143     mei_hbm_reset(dev);
0144 
0145     memset(dev->rd_msg_hdr, 0, sizeof(dev->rd_msg_hdr));
0146 
0147     if (ret) {
0148         dev_err(dev->dev, "hw_reset failed ret = %d\n", ret);
0149         return ret;
0150     }
0151 
0152     if (state == MEI_DEV_POWER_DOWN) {
0153         dev_dbg(dev->dev, "powering down: end of reset\n");
0154         mei_set_devstate(dev, MEI_DEV_DISABLED);
0155         return 0;
0156     }
0157 
0158     ret = mei_hw_start(dev);
0159     if (ret) {
0160         dev_err(dev->dev, "hw_start failed ret = %d\n", ret);
0161         return ret;
0162     }
0163 
0164     if (dev->dev_state != MEI_DEV_RESETTING) {
0165         dev_dbg(dev->dev, "wrong state = %d on link start\n", dev->dev_state);
0166         return 0;
0167     }
0168 
0169     dev_dbg(dev->dev, "link is established start sending messages.\n");
0170 
0171     mei_set_devstate(dev, MEI_DEV_INIT_CLIENTS);
0172     ret = mei_hbm_start_req(dev);
0173     if (ret) {
0174         dev_err(dev->dev, "hbm_start failed ret = %d\n", ret);
0175         mei_set_devstate(dev, MEI_DEV_RESETTING);
0176         return ret;
0177     }
0178 
0179     return 0;
0180 }
0181 EXPORT_SYMBOL_GPL(mei_reset);
0182 
0183 /**
0184  * mei_start - initializes host and fw to start work.
0185  *
0186  * @dev: the device structure
0187  *
0188  * Return: 0 on success, <0 on failure.
0189  */
0190 int mei_start(struct mei_device *dev)
0191 {
0192     int ret;
0193 
0194     mutex_lock(&dev->device_lock);
0195 
0196     /* acknowledge interrupt and stop interrupts */
0197     mei_clear_interrupts(dev);
0198 
0199     ret = mei_hw_config(dev);
0200     if (ret)
0201         goto err;
0202 
0203     dev_dbg(dev->dev, "reset in start the mei device.\n");
0204 
0205     dev->reset_count = 0;
0206     do {
0207         mei_set_devstate(dev, MEI_DEV_INITIALIZING);
0208         ret = mei_reset(dev);
0209 
0210         if (ret == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) {
0211             dev_err(dev->dev, "reset failed ret = %d", ret);
0212             goto err;
0213         }
0214     } while (ret);
0215 
0216     if (mei_hbm_start_wait(dev)) {
0217         dev_err(dev->dev, "HBM haven't started");
0218         goto err;
0219     }
0220 
0221     if (!mei_host_is_ready(dev)) {
0222         dev_err(dev->dev, "host is not ready.\n");
0223         goto err;
0224     }
0225 
0226     if (!mei_hw_is_ready(dev)) {
0227         dev_err(dev->dev, "ME is not ready.\n");
0228         goto err;
0229     }
0230 
0231     if (!mei_hbm_version_is_supported(dev)) {
0232         dev_dbg(dev->dev, "MEI start failed.\n");
0233         goto err;
0234     }
0235 
0236     dev_dbg(dev->dev, "link layer has been established.\n");
0237 
0238     mutex_unlock(&dev->device_lock);
0239     return 0;
0240 err:
0241     dev_err(dev->dev, "link layer initialization failed.\n");
0242     mei_set_devstate(dev, MEI_DEV_DISABLED);
0243     mutex_unlock(&dev->device_lock);
0244     return -ENODEV;
0245 }
0246 EXPORT_SYMBOL_GPL(mei_start);
0247 
0248 /**
0249  * mei_restart - restart device after suspend
0250  *
0251  * @dev: the device structure
0252  *
0253  * Return: 0 on success or -ENODEV if the restart hasn't succeeded
0254  */
0255 int mei_restart(struct mei_device *dev)
0256 {
0257     int err;
0258 
0259     mutex_lock(&dev->device_lock);
0260 
0261     mei_set_devstate(dev, MEI_DEV_POWER_UP);
0262     dev->reset_count = 0;
0263 
0264     err = mei_reset(dev);
0265 
0266     mutex_unlock(&dev->device_lock);
0267 
0268     if (err == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) {
0269         dev_err(dev->dev, "device disabled = %d\n", err);
0270         return -ENODEV;
0271     }
0272 
0273     /* try to start again */
0274     if (err)
0275         schedule_work(&dev->reset_work);
0276 
0277 
0278     return 0;
0279 }
0280 EXPORT_SYMBOL_GPL(mei_restart);
0281 
0282 static void mei_reset_work(struct work_struct *work)
0283 {
0284     struct mei_device *dev =
0285         container_of(work, struct mei_device,  reset_work);
0286     int ret;
0287 
0288     mei_clear_interrupts(dev);
0289     mei_synchronize_irq(dev);
0290 
0291     mutex_lock(&dev->device_lock);
0292 
0293     ret = mei_reset(dev);
0294 
0295     mutex_unlock(&dev->device_lock);
0296 
0297     if (dev->dev_state == MEI_DEV_DISABLED) {
0298         dev_err(dev->dev, "device disabled = %d\n", ret);
0299         return;
0300     }
0301 
0302     /* retry reset in case of failure */
0303     if (ret)
0304         schedule_work(&dev->reset_work);
0305 }
0306 
0307 void mei_stop(struct mei_device *dev)
0308 {
0309     dev_dbg(dev->dev, "stopping the device.\n");
0310 
0311     mutex_lock(&dev->device_lock);
0312     mei_set_devstate(dev, MEI_DEV_POWERING_DOWN);
0313     mutex_unlock(&dev->device_lock);
0314     mei_cl_bus_remove_devices(dev);
0315     mutex_lock(&dev->device_lock);
0316     mei_set_devstate(dev, MEI_DEV_POWER_DOWN);
0317     mutex_unlock(&dev->device_lock);
0318 
0319     mei_cancel_work(dev);
0320 
0321     mei_clear_interrupts(dev);
0322     mei_synchronize_irq(dev);
0323 
0324     mutex_lock(&dev->device_lock);
0325 
0326     mei_reset(dev);
0327     /* move device to disabled state unconditionally */
0328     mei_set_devstate(dev, MEI_DEV_DISABLED);
0329 
0330     mutex_unlock(&dev->device_lock);
0331 }
0332 EXPORT_SYMBOL_GPL(mei_stop);
0333 
0334 /**
0335  * mei_write_is_idle - check if the write queues are idle
0336  *
0337  * @dev: the device structure
0338  *
0339  * Return: true of there is no pending write
0340  */
0341 bool mei_write_is_idle(struct mei_device *dev)
0342 {
0343     bool idle = (dev->dev_state == MEI_DEV_ENABLED &&
0344         list_empty(&dev->ctrl_wr_list) &&
0345         list_empty(&dev->write_list)   &&
0346         list_empty(&dev->write_waiting_list));
0347 
0348     dev_dbg(dev->dev, "write pg: is idle[%d] state=%s ctrl=%01d write=%01d wwait=%01d\n",
0349         idle,
0350         mei_dev_state_str(dev->dev_state),
0351         list_empty(&dev->ctrl_wr_list),
0352         list_empty(&dev->write_list),
0353         list_empty(&dev->write_waiting_list));
0354 
0355     return idle;
0356 }
0357 EXPORT_SYMBOL_GPL(mei_write_is_idle);
0358 
0359 /**
0360  * mei_device_init  -- initialize mei_device structure
0361  *
0362  * @dev: the mei device
0363  * @device: the device structure
0364  * @hw_ops: hw operations
0365  */
0366 void mei_device_init(struct mei_device *dev,
0367              struct device *device,
0368              const struct mei_hw_ops *hw_ops)
0369 {
0370     /* setup our list array */
0371     INIT_LIST_HEAD(&dev->file_list);
0372     INIT_LIST_HEAD(&dev->device_list);
0373     INIT_LIST_HEAD(&dev->me_clients);
0374     mutex_init(&dev->device_lock);
0375     init_rwsem(&dev->me_clients_rwsem);
0376     mutex_init(&dev->cl_bus_lock);
0377     init_waitqueue_head(&dev->wait_hw_ready);
0378     init_waitqueue_head(&dev->wait_pg);
0379     init_waitqueue_head(&dev->wait_hbm_start);
0380     dev->dev_state = MEI_DEV_INITIALIZING;
0381     dev->reset_count = 0;
0382 
0383     INIT_LIST_HEAD(&dev->write_list);
0384     INIT_LIST_HEAD(&dev->write_waiting_list);
0385     INIT_LIST_HEAD(&dev->ctrl_wr_list);
0386     INIT_LIST_HEAD(&dev->ctrl_rd_list);
0387     dev->tx_queue_limit = MEI_TX_QUEUE_LIMIT_DEFAULT;
0388 
0389     INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
0390     INIT_WORK(&dev->reset_work, mei_reset_work);
0391     INIT_WORK(&dev->bus_rescan_work, mei_cl_bus_rescan_work);
0392 
0393     bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
0394     dev->open_handle_count = 0;
0395 
0396     /*
0397      * Reserving the first client ID
0398      * 0: Reserved for MEI Bus Message communications
0399      */
0400     bitmap_set(dev->host_clients_map, 0, 1);
0401 
0402     dev->pg_event = MEI_PG_EVENT_IDLE;
0403     dev->ops      = hw_ops;
0404     dev->dev      = device;
0405 }
0406 EXPORT_SYMBOL_GPL(mei_device_init);
0407