Back to home page

OSCL-LXR

 
 

    


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__ */