162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2021 - 2022 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __iwl_mei_h__ 762306a36Sopenharmony_ci#define __iwl_mei_h__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/if_ether.h> 1062306a36Sopenharmony_ci#include <linux/skbuff.h> 1162306a36Sopenharmony_ci#include <linux/ieee80211.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/** 1462306a36Sopenharmony_ci * DOC: Introduction 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * iwlmei is the kernel module that is in charge of the communication between 1762306a36Sopenharmony_ci * the iwlwifi driver and the CSME firmware's WLAN driver. This communication 1862306a36Sopenharmony_ci * uses the SAP protocol defined in another file. 1962306a36Sopenharmony_ci * iwlwifi can request or release ownership on the WiFi device through iwlmei. 2062306a36Sopenharmony_ci * iwlmei may notify iwlwifi about certain events: what filter iwlwifi should 2162306a36Sopenharmony_ci * use to passthrough inbound packets to the CSME firmware for example. iwlmei 2262306a36Sopenharmony_ci * may also use iwlwifi to send traffic. This means that we need communication 2362306a36Sopenharmony_ci * from iwlmei to iwlwifi and the other way around. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/** 2762306a36Sopenharmony_ci * DOC: Life cycle 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * iwlmei exports symbols that are needed by iwlwifi so that iwlmei will always 3062306a36Sopenharmony_ci * be loaded when iwlwifi is alive. iwlwifi registers itself to iwlmei and 3162306a36Sopenharmony_ci * provides the pointers to the functions that iwlmei calls whenever needed. 3262306a36Sopenharmony_ci * iwlwifi calls iwlmei through direct and context-free function calls. 3362306a36Sopenharmony_ci * It is assumed that only one device is accessible to the CSME firmware and 3462306a36Sopenharmony_ci * under the scope of iwlmei so that it is valid not to have any context passed 3562306a36Sopenharmony_ci * to iwlmei's functions. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * There are cases in which iwlmei can't access the CSME firmware, because the 3862306a36Sopenharmony_ci * CSME firmware is undergoing a reset, or the mei bus decided to unbind the 3962306a36Sopenharmony_ci * device. In those cases, iwlmei will need not to send requests over the mei 4062306a36Sopenharmony_ci * bus. Instead, it needs to cache the requests from iwlwifi and fulfill them 4162306a36Sopenharmony_ci * when the mei bus is available again. 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * iwlmei can call iwlwifi as long as iwlwifi is registered to iwlmei. When 4462306a36Sopenharmony_ci * iwlwifi goes down (the PCI device is unbound, or the iwlwifi is unloaded) 4562306a36Sopenharmony_ci * iwlwifi needs to unregister from iwlmei. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/** 4962306a36Sopenharmony_ci * DOC: Memory layout 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * Since iwlwifi calls iwlmei without any context, iwlmei needs to hold a 5262306a36Sopenharmony_ci * global pointer to its data (which is in the mei client device's private 5362306a36Sopenharmony_ci * data area). If there was no bind on the mei bus, this pointer is NULL and 5462306a36Sopenharmony_ci * iwlmei knows not access to the CSME firmware upon requests from iwlwifi. 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * iwlmei needs to cache requests from iwlwifi when there is no mei client 5762306a36Sopenharmony_ci * device available (when iwlmei has been removed from the mei bus). In this 5862306a36Sopenharmony_ci * case, all iwlmei's data that resides in the mei client device's private data 5962306a36Sopenharmony_ci * area is unavailable. For this specific case, a separate caching area is 6062306a36Sopenharmony_ci * needed. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/** 6462306a36Sopenharmony_ci * DOC: Concurrency 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * iwlwifi can call iwlmei at any time. iwlmei will take care to synchronize 6762306a36Sopenharmony_ci * the calls from iwlwifi with its internal flows. iwlwifi must not call iwlmei 6862306a36Sopenharmony_ci * in flows that cannot sleep. Moreover, iwlwifi must not call iwlmei in flows 6962306a36Sopenharmony_ci * that originated from iwlmei. 7062306a36Sopenharmony_ci */ 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/** 7362306a36Sopenharmony_ci * DOC: Probe and remove from mei bus driver 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * When the mei bus driver enumerates its devices, it calls the iwlmei's probe 7662306a36Sopenharmony_ci * function which will send the %SAP_ME_MSG_START message. The probe completes 7762306a36Sopenharmony_ci * before the response (%SAP_ME_MSG_START_OK) is received. This response will 7862306a36Sopenharmony_ci * be handle by the Rx path. Once it arrives, the connection to the CSME 7962306a36Sopenharmony_ci * firmware is considered established and iwlwifi's requests can be treated 8062306a36Sopenharmony_ci * against the CSME firmware. 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * When the mei bus driver removes the device, iwlmei loses all the data that 8362306a36Sopenharmony_ci * was attached to the mei client device. It clears the global pointer to the 8462306a36Sopenharmony_ci * mei client device since it is not available anymore. This will cause all the 8562306a36Sopenharmony_ci * requests coming from iwlwifi to be cached. This flow takes the global mutex 8662306a36Sopenharmony_ci * to be synchronized with all the requests coming from iwlwifi. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/** 9062306a36Sopenharmony_ci * DOC: Driver load when CSME owns the device 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * When the driver (iwlwifi) is loaded while CSME owns the device, 9362306a36Sopenharmony_ci * it'll ask CSME to release the device through HW registers. CSME 9462306a36Sopenharmony_ci * will release the device only in the case that there is no connection 9562306a36Sopenharmony_ci * through the mei bus. If there is a mei bus connection, CSME will refuse 9662306a36Sopenharmony_ci * to release the ownership on the device through the HW registers. In that 9762306a36Sopenharmony_ci * case, iwlwifi must first request ownership using the SAP protocol. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * Once iwlwifi will request ownership through the SAP protocol, CSME will 10062306a36Sopenharmony_ci * grant the ownership on the device through the HW registers as well. 10162306a36Sopenharmony_ci * In order to request ownership over SAP, we first need to have an interface 10262306a36Sopenharmony_ci * which means that we need to register to mac80211. 10362306a36Sopenharmony_ci * This can't happen before we get the NVM that contains all the capabilities 10462306a36Sopenharmony_ci * of the device. Reading the NVM usually requires the load the firmware, but 10562306a36Sopenharmony_ci * this is impossible as long as we don't have ownership on the device. 10662306a36Sopenharmony_ci * In order to solve this chicken and egg problem, the host driver can get 10762306a36Sopenharmony_ci * the NVM through CSME which owns the device. It can send 10862306a36Sopenharmony_ci * %SAP_MSG_NOTIF_GET_NVM, which will be replied by %SAP_MSG_NOTIF_NVM with 10962306a36Sopenharmony_ci * the NVM's content that the host driver needs. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/** 11362306a36Sopenharmony_ci * DOC: CSME behavior regarding the ownership requests 11462306a36Sopenharmony_ci * 11562306a36Sopenharmony_ci * The ownership requests from the host can come in two different ways: 11662306a36Sopenharmony_ci * - the HW registers in iwl_pcie_set_hw_ready 11762306a36Sopenharmony_ci * - using the Software Arbitration Protocol (SAP) 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * The host can ask CSME who owns the device with %SAP_MSG_NOTIF_WHO_OWNS_NIC, 12062306a36Sopenharmony_ci * and it can request ownership with %SAP_MSG_NOTIF_HOST_ASKS_FOR_NIC_OWNERSHIP. 12162306a36Sopenharmony_ci * The host will first use %SAP_MSG_NOTIF_WHO_OWNS_NIC to know what state 12262306a36Sopenharmony_ci * CSME is in. In case CSME thinks it owns the device, the host can ask for 12362306a36Sopenharmony_ci * ownership with %SAP_MSG_NOTIF_HOST_ASKS_FOR_NIC_OWNERSHIP. 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * Here the table that describes CSME's behavior upon ownership request: 12662306a36Sopenharmony_ci * 12762306a36Sopenharmony_ci * +-------------------+------------+--------------+-----------------------------+------------+ 12862306a36Sopenharmony_ci * | State | HW reg bit | Reply for | Event | HW reg bit | 12962306a36Sopenharmony_ci * | | before | WHO_OWNS_NIC | | after | 13062306a36Sopenharmony_ci * +===================+============+==============+=============================+============+ 13162306a36Sopenharmony_ci * | WiAMT not | 0 | Host | HW register or | 0 | 13262306a36Sopenharmony_ci * | operational | Host owner | | HOST_ASKS_FOR_NIC_OWNERSHIP | Host owner | 13362306a36Sopenharmony_ci * +-------------------+------------+--------------+-----------------------------+------------+ 13462306a36Sopenharmony_ci * | Operational & | 1 | N/A | HW register | 0 | 13562306a36Sopenharmony_ci * | SAP down & | CSME owner | | | Host owner | 13662306a36Sopenharmony_ci * | no session active | | | | | 13762306a36Sopenharmony_ci * +-------------------+------------+--------------+-----------------------------+------------+ 13862306a36Sopenharmony_ci * | Operational & | 1 | CSME | HW register | 1 | 13962306a36Sopenharmony_ci * | SAP up | CSME owner | | | CSME owner | 14062306a36Sopenharmony_ci * +-------------------+------------+--------------+-----------------------------+------------+ 14162306a36Sopenharmony_ci * | Operational & | 1 | CSME | HOST_ASKS_FOR_NIC_OWNERSHIP | 0 | 14262306a36Sopenharmony_ci * | SAP up | CSME owner | | | Host owner | 14362306a36Sopenharmony_ci * +-------------------+------------+--------------+-----------------------------+------------+ 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/** 14762306a36Sopenharmony_ci * DOC: Driver load when CSME is associated and a session is active 14862306a36Sopenharmony_ci * 14962306a36Sopenharmony_ci * A "session" is active when CSME is associated to an access point and the 15062306a36Sopenharmony_ci * link is used to attach a remote driver or to control the system remotely. 15162306a36Sopenharmony_ci * When a session is active, we want to make sure it won't disconnect when we 15262306a36Sopenharmony_ci * take ownership on the device. 15362306a36Sopenharmony_ci * In this case, the driver can get the device, but it'll need to make 15462306a36Sopenharmony_ci * sure that it'll connect to the exact same AP (same BSSID). 15562306a36Sopenharmony_ci * In order to do so, CSME will send the connection parameters through 15662306a36Sopenharmony_ci * SAP and then the host can check if it can connect to this same AP. 15762306a36Sopenharmony_ci * If yes, it can request ownership through SAP and connect quickly without 15862306a36Sopenharmony_ci * scanning all the channels, but just probing the AP on the channel that 15962306a36Sopenharmony_ci * CSME was connected to. 16062306a36Sopenharmony_ci * In order to signal this specific scenario to iwlwifi, iwlmei will 16162306a36Sopenharmony_ci * immediately require iwlwifi to report RF-Kill to the network stack. This 16262306a36Sopenharmony_ci * RF-Kill will prevent the stack from getting the device, and it has a reason 16362306a36Sopenharmony_ci * that tells the userspace that the device is in RF-Kill because it is not 16462306a36Sopenharmony_ci * owned by the host. Once the userspace has configured the right profile, 16562306a36Sopenharmony_ci * it'll be able to let iwlmei know that it can request ownership over SAP 16662306a36Sopenharmony_ci * which will remove the RF-Kill, and finally allow the host to connect. 16762306a36Sopenharmony_ci * The host has then 3 seconds to connect (including DHCP). Had the host 16862306a36Sopenharmony_ci * failed to connect within those 3 seconds, CSME will take the device back. 16962306a36Sopenharmony_ci */ 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci/** 17262306a36Sopenharmony_ci * DOC: Datapath 17362306a36Sopenharmony_ci * 17462306a36Sopenharmony_ci * CSME can transmit packets, through the netdev that it gets from the wifi 17562306a36Sopenharmony_ci * driver. It'll send packet in the 802.3 format and simply call 17662306a36Sopenharmony_ci * dev_queue_xmit. 17762306a36Sopenharmony_ci * 17862306a36Sopenharmony_ci * For Rx, iwlmei registers a Rx handler that it attaches to the netdev. iwlmei 17962306a36Sopenharmony_ci * may catch packets and send them to CSME, it can then either drop them so 18062306a36Sopenharmony_ci * that they are invisible to user space, or let them go the user space. 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * Packets transmitted by the user space do not need to be forwarded to CSME 18362306a36Sopenharmony_ci * with the exception of the DHCP request. In order to know what IP is used 18462306a36Sopenharmony_ci * by the user space, CSME needs to get the DHCP request. See 18562306a36Sopenharmony_ci * iwl_mei_tx_copy_to_csme(). 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci/** 18962306a36Sopenharmony_ci * enum iwl_mei_nvm_caps - capabilities for MEI NVM 19062306a36Sopenharmony_ci * @MEI_NVM_CAPS_LARI_SUPPORT: Lari is supported 19162306a36Sopenharmony_ci * @MEI_NVM_CAPS_11AX_SUPPORT: 11AX is supported 19262306a36Sopenharmony_ci */ 19362306a36Sopenharmony_cienum iwl_mei_nvm_caps { 19462306a36Sopenharmony_ci MEI_NVM_CAPS_LARI_SUPPORT = BIT(0), 19562306a36Sopenharmony_ci MEI_NVM_CAPS_11AX_SUPPORT = BIT(1), 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/** 19962306a36Sopenharmony_ci * struct iwl_mei_nvm - used to pass the NVM from CSME 20062306a36Sopenharmony_ci * @hw_addr: The MAC address 20162306a36Sopenharmony_ci * @n_hw_addrs: The number of MAC addresses 20262306a36Sopenharmony_ci * @reserved: For alignment. 20362306a36Sopenharmony_ci * @radio_cfg: The radio configuration. 20462306a36Sopenharmony_ci * @caps: See &enum iwl_mei_nvm_caps. 20562306a36Sopenharmony_ci * @nvm_version: The version of the NVM. 20662306a36Sopenharmony_ci * @channels: The data for each channel. 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * If a field is added, it must correspond to the SAP structure. 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_cistruct iwl_mei_nvm { 21162306a36Sopenharmony_ci u8 hw_addr[ETH_ALEN]; 21262306a36Sopenharmony_ci u8 n_hw_addrs; 21362306a36Sopenharmony_ci u8 reserved; 21462306a36Sopenharmony_ci u32 radio_cfg; 21562306a36Sopenharmony_ci u32 caps; 21662306a36Sopenharmony_ci u32 nvm_version; 21762306a36Sopenharmony_ci u32 channels[110]; 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/** 22162306a36Sopenharmony_ci * enum iwl_mei_pairwise_cipher - cipher for UCAST key 22262306a36Sopenharmony_ci * @IWL_MEI_CIPHER_NONE: none 22362306a36Sopenharmony_ci * @IWL_MEI_CIPHER_TKIP: tkip 22462306a36Sopenharmony_ci * @IWL_MEI_CIPHER_CCMP: ccmp 22562306a36Sopenharmony_ci * @IWL_MEI_CIPHER_GCMP: gcmp 22662306a36Sopenharmony_ci * @IWL_MEI_CIPHER_GCMP_256: gcmp 256 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * Note that those values are dictated by the CSME firmware API (see sap.h) 22962306a36Sopenharmony_ci */ 23062306a36Sopenharmony_cienum iwl_mei_pairwise_cipher { 23162306a36Sopenharmony_ci IWL_MEI_CIPHER_NONE = 0, 23262306a36Sopenharmony_ci IWL_MEI_CIPHER_TKIP = 2, 23362306a36Sopenharmony_ci IWL_MEI_CIPHER_CCMP = 4, 23462306a36Sopenharmony_ci IWL_MEI_CIPHER_GCMP = 8, 23562306a36Sopenharmony_ci IWL_MEI_CIPHER_GCMP_256 = 9, 23662306a36Sopenharmony_ci}; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/** 23962306a36Sopenharmony_ci * enum iwl_mei_akm_auth - a combination of AKM and AUTH method 24062306a36Sopenharmony_ci * @IWL_MEI_AKM_AUTH_OPEN: No encryption 24162306a36Sopenharmony_ci * @IWL_MEI_AKM_AUTH_RSNA: 1X profile 24262306a36Sopenharmony_ci * @IWL_MEI_AKM_AUTH_RSNA_PSK: PSK profile 24362306a36Sopenharmony_ci * @IWL_MEI_AKM_AUTH_SAE: SAE profile 24462306a36Sopenharmony_ci * 24562306a36Sopenharmony_ci * Note that those values are dictated by the CSME firmware API (see sap.h) 24662306a36Sopenharmony_ci */ 24762306a36Sopenharmony_cienum iwl_mei_akm_auth { 24862306a36Sopenharmony_ci IWL_MEI_AKM_AUTH_OPEN = 0, 24962306a36Sopenharmony_ci IWL_MEI_AKM_AUTH_RSNA = 6, 25062306a36Sopenharmony_ci IWL_MEI_AKM_AUTH_RSNA_PSK = 7, 25162306a36Sopenharmony_ci IWL_MEI_AKM_AUTH_SAE = 9, 25262306a36Sopenharmony_ci}; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci/** 25562306a36Sopenharmony_ci * struct iwl_mei_conn_info - connection info 25662306a36Sopenharmony_ci * @lp_state: link protection state 25762306a36Sopenharmony_ci * @auth_mode: authentication mode 25862306a36Sopenharmony_ci * @ssid_len: the length of SSID 25962306a36Sopenharmony_ci * @ssid: the SSID 26062306a36Sopenharmony_ci * @pairwise_cipher: the cipher used for unicast packets 26162306a36Sopenharmony_ci * @channel: the associated channel 26262306a36Sopenharmony_ci * @band: the associated band 26362306a36Sopenharmony_ci * @bssid: the BSSID 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_cistruct iwl_mei_conn_info { 26662306a36Sopenharmony_ci u8 lp_state; 26762306a36Sopenharmony_ci u8 auth_mode; 26862306a36Sopenharmony_ci u8 ssid_len; 26962306a36Sopenharmony_ci u8 channel; 27062306a36Sopenharmony_ci u8 band; 27162306a36Sopenharmony_ci u8 pairwise_cipher; 27262306a36Sopenharmony_ci u8 bssid[ETH_ALEN]; 27362306a36Sopenharmony_ci u8 ssid[IEEE80211_MAX_SSID_LEN]; 27462306a36Sopenharmony_ci}; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci/** 27762306a36Sopenharmony_ci * struct iwl_mei_colloc_info - collocated AP info 27862306a36Sopenharmony_ci * @channel: the channel of the collocated AP 27962306a36Sopenharmony_ci * @bssid: the BSSID of the collocated AP 28062306a36Sopenharmony_ci */ 28162306a36Sopenharmony_cistruct iwl_mei_colloc_info { 28262306a36Sopenharmony_ci u8 channel; 28362306a36Sopenharmony_ci u8 bssid[ETH_ALEN]; 28462306a36Sopenharmony_ci}; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci/* 28762306a36Sopenharmony_ci * struct iwl_mei_ops - driver's operations called by iwlmei 28862306a36Sopenharmony_ci * Operations will not be called more than once concurrently. 28962306a36Sopenharmony_ci * It's not allowed to call iwlmei functions from this context. 29062306a36Sopenharmony_ci * 29162306a36Sopenharmony_ci * @me_conn_status: provide information about CSME's current connection. 29262306a36Sopenharmony_ci * @rfkill: called when the wifi driver should report a change in the rfkill 29362306a36Sopenharmony_ci * status. 29462306a36Sopenharmony_ci * @roaming_forbidden: indicates whether roaming is forbidden. 29562306a36Sopenharmony_ci * @sap_connected: indicate that SAP is now connected. Will be called in case 29662306a36Sopenharmony_ci * the wifi driver registered to iwlmei before SAP connection succeeded or 29762306a36Sopenharmony_ci * when the SAP connection is re-established. 29862306a36Sopenharmony_ci * @nic_stolen: this means that device is no longer available. The device can 29962306a36Sopenharmony_ci * still be used until the callback returns. 30062306a36Sopenharmony_ci */ 30162306a36Sopenharmony_cistruct iwl_mei_ops { 30262306a36Sopenharmony_ci void (*me_conn_status)(void *priv, 30362306a36Sopenharmony_ci const struct iwl_mei_conn_info *conn_info); 30462306a36Sopenharmony_ci void (*rfkill)(void *priv, bool blocked, bool csme_taking_ownership); 30562306a36Sopenharmony_ci void (*roaming_forbidden)(void *priv, bool forbidden); 30662306a36Sopenharmony_ci void (*sap_connected)(void *priv); 30762306a36Sopenharmony_ci void (*nic_stolen)(void *priv); 30862306a36Sopenharmony_ci}; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IWLMEI) 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/** 31362306a36Sopenharmony_ci * iwl_mei_is_connected() - is the connection to the CSME firmware established? 31462306a36Sopenharmony_ci * 31562306a36Sopenharmony_ci * Return: true if we have a SAP connection 31662306a36Sopenharmony_ci */ 31762306a36Sopenharmony_cibool iwl_mei_is_connected(void); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci/** 32062306a36Sopenharmony_ci * iwl_mei_get_nvm() - returns the NVM for the device 32162306a36Sopenharmony_ci * 32262306a36Sopenharmony_ci * It is the caller's responsibility to free the memory returned 32362306a36Sopenharmony_ci * by this function. 32462306a36Sopenharmony_ci * This function blocks (sleeps) until the NVM is ready. 32562306a36Sopenharmony_ci * 32662306a36Sopenharmony_ci * Return: the NVM as received from CSME 32762306a36Sopenharmony_ci */ 32862306a36Sopenharmony_cistruct iwl_mei_nvm *iwl_mei_get_nvm(void); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci/** 33162306a36Sopenharmony_ci * iwl_mei_get_ownership() - request ownership 33262306a36Sopenharmony_ci * 33362306a36Sopenharmony_ci * This function blocks until ownership is granted or timeout expired. 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * Return: 0 in case we could get ownership on the device 33662306a36Sopenharmony_ci */ 33762306a36Sopenharmony_ciint iwl_mei_get_ownership(void); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci/** 34062306a36Sopenharmony_ci * iwl_mei_set_rfkill_state() - set SW and HW RF kill states 34162306a36Sopenharmony_ci * @hw_rfkill: HW RF kill state. 34262306a36Sopenharmony_ci * @sw_rfkill: SW RF kill state. 34362306a36Sopenharmony_ci * 34462306a36Sopenharmony_ci * This function must be called when SW RF kill is issued by the user. 34562306a36Sopenharmony_ci */ 34662306a36Sopenharmony_civoid iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/** 34962306a36Sopenharmony_ci * iwl_mei_set_nic_info() - set mac address 35062306a36Sopenharmony_ci * @mac_address: mac address to set 35162306a36Sopenharmony_ci * @nvm_address: NVM mac address to set 35262306a36Sopenharmony_ci * 35362306a36Sopenharmony_ci * This function must be called upon mac address change. 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_civoid iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci/** 35862306a36Sopenharmony_ci * iwl_mei_set_country_code() - set new country code 35962306a36Sopenharmony_ci * @mcc: the new applied MCC 36062306a36Sopenharmony_ci * 36162306a36Sopenharmony_ci * This function must be called upon country code update 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_civoid iwl_mei_set_country_code(u16 mcc); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci/** 36662306a36Sopenharmony_ci * iwl_mei_set_power_limit() - set TX power limit 36762306a36Sopenharmony_ci * @power_limit: pointer to an array of 10 elements (le16) represents the power 36862306a36Sopenharmony_ci * restrictions per chain. 36962306a36Sopenharmony_ci * 37062306a36Sopenharmony_ci * This function must be called upon power restrictions change 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_civoid iwl_mei_set_power_limit(const __le16 *power_limit); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci/** 37562306a36Sopenharmony_ci * iwl_mei_register() - register the wifi driver to iwlmei 37662306a36Sopenharmony_ci * @priv: a pointer to the wifi driver's context. Cannot be NULL. 37762306a36Sopenharmony_ci * @ops: the ops structure. 37862306a36Sopenharmony_ci * 37962306a36Sopenharmony_ci * Return: 0 unless something went wrong. It is illegal to call any 38062306a36Sopenharmony_ci * other API function before this function is called and succeeds. 38162306a36Sopenharmony_ci * 38262306a36Sopenharmony_ci * Only one wifi driver instance (wifi device instance really) 38362306a36Sopenharmony_ci * can register at a time. 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_ciint iwl_mei_register(void *priv, const struct iwl_mei_ops *ops); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci/** 38862306a36Sopenharmony_ci * iwl_mei_start_unregister() - unregister the wifi driver from iwlmei 38962306a36Sopenharmony_ci * 39062306a36Sopenharmony_ci * From this point on, iwlmei will not used the callbacks provided by 39162306a36Sopenharmony_ci * the driver, but the device is still usable. 39262306a36Sopenharmony_ci */ 39362306a36Sopenharmony_civoid iwl_mei_start_unregister(void); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci/** 39662306a36Sopenharmony_ci * iwl_mei_unregister_complete() - complete the unregistration 39762306a36Sopenharmony_ci * 39862306a36Sopenharmony_ci * Must be called after iwl_mei_start_unregister. When this function returns, 39962306a36Sopenharmony_ci * the device is owned by CSME. 40062306a36Sopenharmony_ci */ 40162306a36Sopenharmony_civoid iwl_mei_unregister_complete(void); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci/** 40462306a36Sopenharmony_ci * iwl_mei_set_netdev() - sets the netdev for Tx / Rx. 40562306a36Sopenharmony_ci * @netdev: the net_device 40662306a36Sopenharmony_ci * 40762306a36Sopenharmony_ci * The caller should set the netdev to a non-NULL value when the 40862306a36Sopenharmony_ci * interface is added. Packets might be sent to the driver immediately 40962306a36Sopenharmony_ci * afterwards. 41062306a36Sopenharmony_ci * The caller should set the netdev to NULL when the interface is removed. 41162306a36Sopenharmony_ci * This function will call synchronize_net() after setting the netdev to NULL. 41262306a36Sopenharmony_ci * Only when this function returns, can the caller assume that iwlmei will 41362306a36Sopenharmony_ci * no longer inject packets into the netdev's Tx path. 41462306a36Sopenharmony_ci * 41562306a36Sopenharmony_ci * Context: This function can sleep and assumes rtnl_lock is taken. 41662306a36Sopenharmony_ci * The netdev must be set to NULL before iwl_mei_start_unregister() is called. 41762306a36Sopenharmony_ci */ 41862306a36Sopenharmony_civoid iwl_mei_set_netdev(struct net_device *netdev); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci/** 42162306a36Sopenharmony_ci * iwl_mei_tx_copy_to_csme() - must be called for each packet sent by 42262306a36Sopenharmony_ci * the wifi driver. 42362306a36Sopenharmony_ci * @skb: the skb sent 42462306a36Sopenharmony_ci * @ivlen: the size of the IV that needs to be skipped after the MAC and 42562306a36Sopenharmony_ci * before the SNAP header. 42662306a36Sopenharmony_ci * 42762306a36Sopenharmony_ci * This function doesn't take any lock, it simply tries to catch DHCP 42862306a36Sopenharmony_ci * packets sent by the wifi driver. If the packet is a DHCP packet, it 42962306a36Sopenharmony_ci * will send it to CSME. This function must not be called for virtual 43062306a36Sopenharmony_ci * interfaces that are not monitored by CSME, meaning it must be called 43162306a36Sopenharmony_ci * only for packets transmitted by the netdevice that was registered 43262306a36Sopenharmony_ci * with iwl_mei_set_netdev(). 43362306a36Sopenharmony_ci */ 43462306a36Sopenharmony_civoid iwl_mei_tx_copy_to_csme(struct sk_buff *skb, unsigned int ivlen); 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci/** 43762306a36Sopenharmony_ci * iwl_mei_host_associated() - must be called when iwlwifi associated. 43862306a36Sopenharmony_ci * @conn_info: pointer to the connection info structure. 43962306a36Sopenharmony_ci * @colloc_info: pointer to the collocated AP info. This is relevant only in 44062306a36Sopenharmony_ci * case of UHB associated AP, otherwise set to NULL. 44162306a36Sopenharmony_ci */ 44262306a36Sopenharmony_civoid iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info, 44362306a36Sopenharmony_ci const struct iwl_mei_colloc_info *colloc_info); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci/** 44662306a36Sopenharmony_ci * iwl_mei_host_disassociated() - must be called when iwlwifi disassociated. 44762306a36Sopenharmony_ci */ 44862306a36Sopenharmony_civoid iwl_mei_host_disassociated(void); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci/** 45162306a36Sopenharmony_ci * iwl_mei_device_state() - must be called when the device changes up/down state 45262306a36Sopenharmony_ci * @up: true if the device is up, false otherwise. 45362306a36Sopenharmony_ci */ 45462306a36Sopenharmony_civoid iwl_mei_device_state(bool up); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci/** 45762306a36Sopenharmony_ci * iwl_mei_pldr_req() - must be called before loading the fw 45862306a36Sopenharmony_ci * 45962306a36Sopenharmony_ci * Return: 0 if the PLDR flow was successful and the fw can be loaded, negative 46062306a36Sopenharmony_ci * value otherwise. 46162306a36Sopenharmony_ci */ 46262306a36Sopenharmony_ciint iwl_mei_pldr_req(void); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci/** 46562306a36Sopenharmony_ci * iwl_mei_alive_notif() - must be called when alive notificaiton is received 46662306a36Sopenharmony_ci * @success: true if received alive notification, false if waiting for the 46762306a36Sopenharmony_ci * notificaiton timed out. 46862306a36Sopenharmony_ci */ 46962306a36Sopenharmony_civoid iwl_mei_alive_notif(bool success); 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci#else 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_cistatic inline bool iwl_mei_is_connected(void) 47462306a36Sopenharmony_ci{ return false; } 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic inline struct iwl_mei_nvm *iwl_mei_get_nvm(void) 47762306a36Sopenharmony_ci{ return NULL; } 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_cistatic inline int iwl_mei_get_ownership(void) 48062306a36Sopenharmony_ci{ return 0; } 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_cistatic inline void iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill) 48362306a36Sopenharmony_ci{} 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_cistatic inline void iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address) 48662306a36Sopenharmony_ci{} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_cistatic inline void iwl_mei_set_country_code(u16 mcc) 48962306a36Sopenharmony_ci{} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic inline void iwl_mei_set_power_limit(__le16 *power_limit) 49262306a36Sopenharmony_ci{} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic inline int iwl_mei_register(void *priv, 49562306a36Sopenharmony_ci const struct iwl_mei_ops *ops) 49662306a36Sopenharmony_ci{ return 0; } 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_cistatic inline void iwl_mei_start_unregister(void) 49962306a36Sopenharmony_ci{} 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic inline void iwl_mei_unregister_complete(void) 50262306a36Sopenharmony_ci{} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic inline void iwl_mei_set_netdev(struct net_device *netdev) 50562306a36Sopenharmony_ci{} 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_cistatic inline void iwl_mei_tx_copy_to_csme(struct sk_buff *skb, 50862306a36Sopenharmony_ci unsigned int ivlen) 50962306a36Sopenharmony_ci{} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic inline void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info, 51262306a36Sopenharmony_ci const struct iwl_mei_colloc_info *colloc_info) 51362306a36Sopenharmony_ci{} 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_cistatic inline void iwl_mei_host_disassociated(void) 51662306a36Sopenharmony_ci{} 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistatic inline void iwl_mei_device_state(bool up) 51962306a36Sopenharmony_ci{} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic inline int iwl_mei_pldr_req(void) 52262306a36Sopenharmony_ci{ return 0; } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_cistatic inline void iwl_mei_alive_notif(bool success) 52562306a36Sopenharmony_ci{} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci#endif /* CONFIG_IWLMEI */ 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci#endif /* __iwl_mei_h__ */ 530