![]() |
|
|||
0001 // SPDX-License-Identifier: GPL-2.0-only 0002 /* 0003 * Copyright (C) 2021 Intel Corporation 0004 */ 0005 0006 #ifndef __iwl_mei_h__ 0007 #define __iwl_mei_h__ 0008 0009 #include <linux/if_ether.h> 0010 #include <linux/skbuff.h> 0011 #include <linux/ieee80211.h> 0012 0013 /** 0014 * DOC: Introduction 0015 * 0016 * iwlmei is the kernel module that is in charge of the commnunication between 0017 * the iwlwifi driver and the CSME firmware's WLAN driver. This communication 0018 * uses the SAP protocol defined in another file. 0019 * iwlwifi can request or release ownership on the WiFi device through iwlmei. 0020 * iwlmei may notify iwlwifi about certain events: what filter iwlwifi should 0021 * use to passthrough inbound packets to the CSME firmware for example. iwlmei 0022 * may also use iwlwifi to send traffic. This means that we need communication 0023 * from iwlmei to iwlwifi and the other way around. 0024 */ 0025 0026 /** 0027 * DOC: Life cycle 0028 * 0029 * iwlmei exports symbols that are needed by iwlwifi so that iwlmei will always 0030 * be loaded when iwlwifi is alive. iwlwifi registers itself to iwlmei and 0031 * provides the pointers to the functions that iwlmei calls whenever needed. 0032 * iwlwifi calls iwlmei through direct and context-free function calls. 0033 * It is assumed that only one device is accessible to the CSME firmware and 0034 * under the scope of iwlmei so that it is valid not to have any context passed 0035 * to iwlmei's functions. 0036 * 0037 * There are cases in which iwlmei can't access the CSME firmware, because the 0038 * CSME firmware is undergoing a reset, or the mei bus decided to unbind the 0039 * device. In those cases, iwlmei will need not to send requests over the mei 0040 * bus. Instead, it needs to cache the requests from iwlwifi and fulfill them 0041 * when the mei bus is available again. 0042 * 0043 * iwlmei can call iwlwifi as long as iwlwifi is registered to iwlmei. When 0044 * iwlwifi goes down (the PCI device is unbound, or the iwlwifi is unloaded) 0045 * iwlwifi needs to unregister from iwlmei. 0046 */ 0047 0048 /** 0049 * DOC: Memory layout 0050 * 0051 * Since iwlwifi calls iwlmei without any context, iwlmei needs to hold a 0052 * global pointer to its data (which is in the mei client device's private 0053 * data area). If there was no bind on the mei bus, this pointer is NULL and 0054 * iwlmei knows not access to the CSME firmware upon requests from iwlwifi. 0055 * 0056 * iwlmei needs to cache requests from iwlwifi when there is no mei client 0057 * device available (when iwlmei has been removed from the mei bus). In this 0058 * case, all iwlmei's data that resides in the mei client device's private data 0059 * area is unavailable. For this specific case, a separate caching area is 0060 * needed. 0061 */ 0062 0063 /** 0064 * DOC: Concurrency 0065 * 0066 * iwlwifi can call iwlmei at any time. iwlmei will take care to synchronize 0067 * the calls from iwlwifi with its internal flows. iwlwifi must not call iwlmei 0068 * in flows that cannot sleep. Moreover, iwlwifi must not call iwlmei in flows 0069 * that originated from iwlmei. 0070 */ 0071 0072 /** 0073 * DOC: Probe and remove from mei bus driver 0074 * 0075 * When the mei bus driver enumerates its devices, it calls the iwlmei's probe 0076 * function which will send the %SAP_ME_MSG_START message. The probe completes 0077 * before the response (%SAP_ME_MSG_START_OK) is received. This response will 0078 * be handle by the Rx path. Once it arrives, the connection to the CSME 0079 * firmware is considered established and iwlwifi's requests can be treated 0080 * against the CSME firmware. 0081 * 0082 * When the mei bus driver removes the device, iwlmei loses all the data that 0083 * was attached to the mei client device. It clears the global pointer to the 0084 * mei client device since it is not available anymore. This will cause all the 0085 * requests coming from iwlwifi to be cached. This flow takes the global mutex 0086 * to be synchronized with all the requests coming from iwlwifi. 0087 */ 0088 0089 /** 0090 * DOC: Driver load when CSME owns the device 0091 * 0092 * When the driver (iwlwifi) is loaded while CSME owns the device, 0093 * it'll ask CSME to release the device through HW registers. CSME 0094 * will release the device only in the case that there is no connection 0095 * through the mei bus. If there is a mei bus connection, CSME will refuse 0096 * to release the ownership on the device through the HW registers. In that 0097 * case, iwlwifi must first request ownership using the SAP protocol. 0098 * 0099 * Once iwlwifi will request ownership through the SAP protocol, CSME will 0100 * grant the ownership on the device through the HW registers as well. 0101 * In order to request ownership over SAP, we first need to have an interface 0102 * which means that we need to register to mac80211. 0103 * This can't happen before we get the NVM that contains all the capabilities 0104 * of the device. Reading the NVM usually requires the load the firmware, but 0105 * this is impossible as long as we don't have ownership on the device. 0106 * In order to solve this chicken and egg problem, the host driver can get 0107 * the NVM through CSME which owns the device. It can send 0108 * %SAP_MSG_NOTIF_GET_NVM, which will be replied by %SAP_MSG_NOTIF_NVM with 0109 * the NVM's content that the host driver needs. 0110 */ 0111 0112 /** 0113 * DOC: CSME behavior regarding the ownership requests 0114 * 0115 * The ownership requests from the host can come in two different ways: 0116 * - the HW registers in iwl_pcie_set_hw_ready 0117 * - using the Software Arbitration Protocol (SAP) 0118 * 0119 * The host can ask CSME who owns the device with %SAP_MSG_NOTIF_WHO_OWNS_NIC, 0120 * and it can request ownership with %SAP_MSG_NOTIF_HOST_ASKS_FOR_NIC_OWNERSHIP. 0121 * The host will first use %SAP_MSG_NOTIF_WHO_OWNS_NIC to know what state 0122 * CSME is in. In case CSME thinks it owns the device, the host can ask for 0123 * ownership with %SAP_MSG_NOTIF_HOST_ASKS_FOR_NIC_OWNERSHIP. 0124 * 0125 * Here the table that describes CSME's behavior upon ownership request: 0126 * 0127 * +-------------------+------------+--------------+-----------------------------+------------+ 0128 * | State | HW reg bit | Reply for | Event | HW reg bit | 0129 * | | before | WHO_OWNS_NIC | | after | 0130 * +===================+============+==============+=============================+============+ 0131 * | WiAMT not | 0 | Host | HW register or | 0 | 0132 * | operational | Host owner | | HOST_ASKS_FOR_NIC_OWNERSHIP | Host owner | 0133 * +-------------------+------------+--------------+-----------------------------+------------+ 0134 * | Operational & | 1 | N/A | HW register | 0 | 0135 * | SAP down & | CSME owner | | | Host owner | 0136 * | no session active | | | | | 0137 * +-------------------+------------+--------------+-----------------------------+------------+ 0138 * | Operational & | 1 | CSME | HW register | 1 | 0139 * | SAP up | CSME owner | | | CSME owner | 0140 * +-------------------+------------+--------------+-----------------------------+------------+ 0141 * | Operational & | 1 | CSME | HOST_ASKS_FOR_NIC_OWNERSHIP | 0 | 0142 * | SAP up | CSME owner | | | Host owner | 0143 * +-------------------+------------+--------------+-----------------------------+------------+ 0144 */ 0145 0146 /** 0147 * DOC: Driver load when CSME is associated and a session is active 0148 * 0149 * A "session" is active when CSME is associated to an access point and the 0150 * link is used to attach a remote driver or to control the system remotely. 0151 * When a session is active, we want to make sure it won't disconnect when we 0152 * take ownership on the device. 0153 * In this case, the driver can get the device, but it'll need to make 0154 * sure that it'll connect to the exact same AP (same BSSID). 0155 * In order to do so, CSME will send the connection parameters through 0156 * SAP and then the host can check if it can connect to this same AP. 0157 * If yes, it can request ownership through SAP and connect quickly without 0158 * scanning all the channels, but just probing the AP on the channel that 0159 * CSME was connected to. 0160 * In order to signal this specific scenario to iwlwifi, iwlmei will 0161 * immediately require iwlwifi to report RF-Kill to the network stack. This 0162 * RF-Kill will prevent the stack from getting the device, and it has a reason 0163 * that tells the userspace that the device is in RF-Kill because it is not 0164 * owned by the host. Once the userspace has configured the right profile, 0165 * it'll be able to let iwlmei know that it can request ownership over SAP 0166 * which will remove the RF-Kill, and finally allow the host to connect. 0167 * The host has then 3 seconds to connect (including DHCP). Had the host 0168 * failed to connect within those 3 seconds, CSME will take the device back. 0169 */ 0170 0171 /** 0172 * DOC: Datapath 0173 * 0174 * CSME can transmit packets, through the netdev that it gets from the wifi 0175 * driver. It'll send packet in the 802.3 format and simply call 0176 * dev_queue_xmit. 0177 * 0178 * For Rx, iwlmei registers a Rx handler that it attaches to the netdev. iwlmei 0179 * may catch packets and send them to CSME, it can then either drop them so 0180 * that they are invisible to user space, or let them go the user space. 0181 * 0182 * Packets transmitted by the user space do not need to be forwarded to CSME 0183 * with the exception of the DHCP request. In order to know what IP is used 0184 * by the user space, CSME needs to get the DHCP request. See 0185 * iwl_mei_tx_copy_to_csme(). 0186 */ 0187 0188 /** 0189 * enum iwl_mei_nvm_caps - capabilities for MEI NVM 0190 * @MEI_NVM_CAPS_LARI_SUPPORT: Lari is supported 0191 * @MEI_NVM_CAPS_11AX_SUPPORT: 11AX is supported 0192 */ 0193 enum iwl_mei_nvm_caps { 0194 MEI_NVM_CAPS_LARI_SUPPORT = BIT(0), 0195 MEI_NVM_CAPS_11AX_SUPPORT = BIT(1), 0196 }; 0197 0198 /** 0199 * struct iwl_mei_nvm - used to pass the NVM from CSME 0200 * @hw_addr: The MAC address 0201 * @n_hw_addrs: The number of MAC addresses 0202 * @reserved: For alignment. 0203 * @radio_cfg: The radio configuration. 0204 * @caps: See &enum iwl_mei_nvm_caps. 0205 * @nvm_version: The version of the NVM. 0206 * @channels: The data for each channel. 0207 * 0208 * If a field is added, it must correspond to the SAP structure. 0209 */ 0210 struct iwl_mei_nvm { 0211 u8 hw_addr[ETH_ALEN]; 0212 u8 n_hw_addrs; 0213 u8 reserved; 0214 u32 radio_cfg; 0215 u32 caps; 0216 u32 nvm_version; 0217 u32 channels[110]; 0218 }; 0219 0220 /** 0221 * enum iwl_mei_pairwise_cipher - cipher for UCAST key 0222 * @IWL_MEI_CIPHER_NONE: none 0223 * @IWL_MEI_CIPHER_CCMP: ccmp 0224 * @IWL_MEI_CIPHER_GCMP: gcmp 0225 * @IWL_MEI_CIPHER_GCMP_256: gcmp 256 0226 * 0227 * Note that those values are dictated by the CSME firmware API (see sap.h) 0228 */ 0229 enum iwl_mei_pairwise_cipher { 0230 IWL_MEI_CIPHER_NONE = 0, 0231 IWL_MEI_CIPHER_CCMP = 4, 0232 IWL_MEI_CIPHER_GCMP = 8, 0233 IWL_MEI_CIPHER_GCMP_256 = 9, 0234 }; 0235 0236 /** 0237 * enum iwl_mei_akm_auth - a combination of AKM and AUTH method 0238 * @IWL_MEI_AKM_AUTH_OPEN: No encryption 0239 * @IWL_MEI_AKM_AUTH_RSNA: 1X profile 0240 * @IWL_MEI_AKM_AUTH_RSNA_PSK: PSK profile 0241 * @IWL_MEI_AKM_AUTH_SAE: SAE profile 0242 * 0243 * Note that those values are dictated by the CSME firmware API (see sap.h) 0244 */ 0245 enum iwl_mei_akm_auth { 0246 IWL_MEI_AKM_AUTH_OPEN = 0, 0247 IWL_MEI_AKM_AUTH_RSNA = 6, 0248 IWL_MEI_AKM_AUTH_RSNA_PSK = 7, 0249 IWL_MEI_AKM_AUTH_SAE = 9, 0250 }; 0251 0252 /** 0253 * struct iwl_mei_conn_info - connection info 0254 * @lp_state: link protection state 0255 * @auth_mode: authentication mode 0256 * @ssid_len: the length of SSID 0257 * @ssid: the SSID 0258 * @pairwise_cipher: the cipher used for unicast packets 0259 * @channel: the associated channel 0260 * @band: the associated band 0261 * @bssid: the BSSID 0262 */ 0263 struct iwl_mei_conn_info { 0264 u8 lp_state; 0265 u8 auth_mode; 0266 u8 ssid_len; 0267 u8 channel; 0268 u8 band; 0269 u8 pairwise_cipher; 0270 u8 bssid[ETH_ALEN]; 0271 u8 ssid[IEEE80211_MAX_SSID_LEN]; 0272 }; 0273 0274 /** 0275 * struct iwl_mei_colloc_info - collocated AP info 0276 * @channel: the channel of the collocated AP 0277 * @bssid: the BSSID of the collocated AP 0278 */ 0279 struct iwl_mei_colloc_info { 0280 u8 channel; 0281 u8 bssid[ETH_ALEN]; 0282 }; 0283 0284 /* 0285 * struct iwl_mei_ops - driver's operations called by iwlmei 0286 * Operations will not be called more than once concurrently. 0287 * It's not allowed to call iwlmei functions from this context. 0288 * 0289 * @me_conn_status: provide information about CSME's current connection. 0290 * @rfkill: called when the wifi driver should report a change in the rfkill 0291 * status. 0292 * @roaming_forbidden: indicates whether roaming is forbidden. 0293 * @sap_connected: indicate that SAP is now connected. Will be called in case 0294 * the wifi driver registered to iwlmei before SAP connection succeeded or 0295 * when the SAP connection is re-established. 0296 * @nic_stolen: this means that device is no longer available. The device can 0297 * still be used until the callback returns. 0298 */ 0299 struct iwl_mei_ops { 0300 void (*me_conn_status)(void *priv, 0301 const struct iwl_mei_conn_info *conn_info); 0302 void (*rfkill)(void *priv, bool blocked); 0303 void (*roaming_forbidden)(void *priv, bool forbidden); 0304 void (*sap_connected)(void *priv); 0305 void (*nic_stolen)(void *priv); 0306 }; 0307 0308 #if IS_ENABLED(CONFIG_IWLMEI) 0309 0310 /** 0311 * iwl_mei_is_connected() - is the connection to the CSME firmware established? 0312 * 0313 * Return: true if we have a SAP connection 0314 */ 0315 bool iwl_mei_is_connected(void); 0316 0317 /** 0318 * iwl_mei_get_nvm() - returns the NVM for the device 0319 * 0320 * It is the caller's responsibility to free the memory returned 0321 * by this function. 0322 * This function blocks (sleeps) until the NVM is ready. 0323 * 0324 * Return: the NVM as received from CSME 0325 */ 0326 struct iwl_mei_nvm *iwl_mei_get_nvm(void); 0327 0328 /** 0329 * iwl_mei_get_ownership() - request ownership 0330 * 0331 * This function blocks until ownership is granted or timeout expired. 0332 * 0333 * Return: 0 in case we could get ownership on the device 0334 */ 0335 int iwl_mei_get_ownership(void); 0336 0337 /** 0338 * iwl_mei_set_rfkill_state() - set SW and HW RF kill states 0339 * @hw_rfkill: HW RF kill state. 0340 * @sw_rfkill: SW RF kill state. 0341 * 0342 * This function must be called when SW RF kill is issued by the user. 0343 */ 0344 void iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill); 0345 0346 /** 0347 * iwl_mei_set_nic_info() - set mac address 0348 * @mac_address: mac address to set 0349 * @nvm_address: NVM mac adsress to set 0350 * 0351 * This function must be called upon mac address change. 0352 */ 0353 void iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address); 0354 0355 /** 0356 * iwl_mei_set_country_code() - set new country code 0357 * @mcc: the new applied MCC 0358 * 0359 * This function must be called upon country code update 0360 */ 0361 void iwl_mei_set_country_code(u16 mcc); 0362 0363 /** 0364 * iwl_mei_set_power_limit() - set TX power limit 0365 * @power_limit: pointer to an array of 10 elements (le16) represents the power 0366 * restrictions per chain. 0367 * 0368 * This function must be called upon power restrictions change 0369 */ 0370 void iwl_mei_set_power_limit(const __le16 *power_limit); 0371 0372 /** 0373 * iwl_mei_register() - register the wifi driver to iwlmei 0374 * @priv: a pointer to the wifi driver's context. Cannot be NULL. 0375 * @ops: the ops structure. 0376 * 0377 * Return: 0 unless something went wrong. It is illegal to call any 0378 * other API function before this function is called and succeeds. 0379 * 0380 * Only one wifi driver instance (wifi device instance really) 0381 * can register at a time. 0382 */ 0383 int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops); 0384 0385 /** 0386 * iwl_mei_start_unregister() - unregister the wifi driver from iwlmei 0387 * 0388 * From this point on, iwlmei will not used the callbacks provided by 0389 * the driver, but the device is still usable. 0390 */ 0391 void iwl_mei_start_unregister(void); 0392 0393 /** 0394 * iwl_mei_unregister_complete() - complete the unregistration 0395 * 0396 * Must be called after iwl_mei_start_unregister. When this function returns, 0397 * the device is owned by CSME. 0398 */ 0399 void iwl_mei_unregister_complete(void); 0400 0401 /** 0402 * iwl_mei_set_netdev() - sets the netdev for Tx / Rx. 0403 * @netdev: the net_device 0404 * 0405 * The caller should set the netdev to a non-NULL value when the 0406 * interface is added. Packets might be sent to the driver immediately 0407 * afterwards. 0408 * The caller should set the netdev to NULL when the interface is removed. 0409 * This function will call synchronize_net() after setting the netdev to NULL. 0410 * Only when this function returns, can the caller assume that iwlmei will 0411 * no longer inject packets into the netdev's Tx path. 0412 * 0413 * Context: This function can sleep and assumes rtnl_lock is taken. 0414 * The netdev must be set to NULL before iwl_mei_start_unregister() is called. 0415 */ 0416 void iwl_mei_set_netdev(struct net_device *netdev); 0417 0418 /** 0419 * iwl_mei_tx_copy_to_csme() - must be called for each packet sent by 0420 * the wifi driver. 0421 * @skb: the skb sent 0422 * @ivlen: the size of the IV that needs to be skipped after the MAC and 0423 * before the SNAP header. 0424 * 0425 * This function doesn't take any lock, it simply tries to catch DHCP 0426 * packets sent by the wifi driver. If the packet is a DHCP packet, it 0427 * will send it to CSME. This function must not be called for virtual 0428 * interfaces that are not monitored by CSME, meaning it must be called 0429 * only for packets transmitted by the netdevice that was registered 0430 * with iwl_mei_set_netdev(). 0431 */ 0432 void iwl_mei_tx_copy_to_csme(struct sk_buff *skb, unsigned int ivlen); 0433 0434 /** 0435 * iwl_mei_host_associated() - must be called when iwlwifi associated. 0436 * @conn_info: pointer to the connection info structure. 0437 * @colloc_info: pointer to the collocated AP info. This is relevant only in 0438 * case of UHB associated AP, otherwise set to NULL. 0439 */ 0440 void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info, 0441 const struct iwl_mei_colloc_info *colloc_info); 0442 0443 /** 0444 * iwl_mei_host_disassociated() - must be called when iwlwifi disassociated. 0445 */ 0446 void iwl_mei_host_disassociated(void); 0447 0448 /** 0449 * iwl_mei_device_down() - must be called when the device is down 0450 */ 0451 void iwl_mei_device_down(void); 0452 0453 #else 0454 0455 static inline bool iwl_mei_is_connected(void) 0456 { return false; } 0457 0458 static inline struct iwl_mei_nvm *iwl_mei_get_nvm(void) 0459 { return NULL; } 0460 0461 static inline int iwl_mei_get_ownership(void) 0462 { return 0; } 0463 0464 static inline void iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill) 0465 {} 0466 0467 static inline void iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address) 0468 {} 0469 0470 static inline void iwl_mei_set_country_code(u16 mcc) 0471 {} 0472 0473 static inline void iwl_mei_set_power_limit(__le16 *power_limit) 0474 {} 0475 0476 static inline int iwl_mei_register(void *priv, 0477 const struct iwl_mei_ops *ops) 0478 { return 0; } 0479 0480 static inline void iwl_mei_start_unregister(void) 0481 {} 0482 0483 static inline void iwl_mei_unregister_complete(void) 0484 {} 0485 0486 static inline void iwl_mei_set_netdev(struct net_device *netdev) 0487 {} 0488 0489 static inline void iwl_mei_tx_copy_to_csme(struct sk_buff *skb, 0490 unsigned int ivlen) 0491 {} 0492 0493 static inline void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info, 0494 const struct iwl_mei_colloc_info *colloc_info) 0495 {} 0496 0497 static inline void iwl_mei_host_disassociated(void) 0498 {} 0499 0500 static inline void iwl_mei_device_down(void) 0501 {} 0502 0503 #endif /* CONFIG_IWLMEI */ 0504 0505 #endif /* __iwl_mei_h__ */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |