// SPDX-License-Identifier: GPL-2.0-only /* * NXP Wireless LAN device driver: commands and events * * Copyright 2011-2020 NXP */ #include <asm/unaligned.h> #include "decl.h" #include "ioctl.h" #include "util.h" #include "fw.h" #include "main.h" #include "wmm.h" #include "11n.h" static void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); /* * This function initializes a command node. * * The actual allocation of the node is not done by this function. It only * initiates a node by filling it with default parameters. Similarly, * allocation of the different buffers used (IOCTL buffer, data buffer) are * not done by this function either. */ static void mwifiex_init_cmd_node(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node, u32 cmd_no, void *data_buf, bool sync) { … } /* * This function returns a command node from the free queue depending upon * availability. */ static struct cmd_ctrl_node * mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) { … } /* * This function cleans up a command node. * * The function resets the fields including the buffer pointers. * This function does not try to free the buffers. They must be * freed before calling this function. * * This function will however call the receive completion callback * in case a response buffer is still available before resetting * the pointer. */ static void mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { … } /* * This function returns a command to the command free queue. * * The function also calls the completion callback if required, before * cleaning the command node and re-inserting it into the free queue. */ static void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { … } /* This function reuses a command node. */ void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { … } /* * This function sends a host command to the firmware. * * The function copies the host command into the driver command * buffer, which will be transferred to the firmware later by the * main thread. */ static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, struct mwifiex_ds_misc_cmd *pcmd_ptr) { … } /* * This function downloads a command to the firmware. * * The function performs sanity tests, sets the command sequence * number and size, converts the header fields to CPU format before * sending. Afterwards, it logs the command ID and action for debugging * and sets up the command timeout timer. */ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node) { … } /* * This function downloads a sleep confirm command to the firmware. * * The function performs sanity tests, sets the command sequence * number and size, converts the header fields to CPU format before * sending. * * No responses are needed for sleep confirm command. */ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) { … } /* * This function allocates the command buffers and links them to * the command free queue. * * The driver uses a pre allocated number of command buffers, which * are created at driver initializations and freed at driver cleanup. * Every command needs to obtain a command buffer from this pool before * it can be issued. The command free queue lists the command buffers * currently free to use, while the command pending queue lists the * command buffers already in use and awaiting handling. Command buffers * are returned to the free queue after use. */ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) { … } /* * This function frees the command buffers. * * The function calls the completion callback for all the command * buffers that still have response buffers associated with them. */ void mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter) { … } /* * This function handles events generated by firmware. * * Event body of events received from firmware are not used (though they are * saved), only the event ID is used. Some events are re-invoked by * the driver, with a new event body. * * After processing, the function calls the completion callback * for cleanup. */ int mwifiex_process_event(struct mwifiex_adapter *adapter) { … } /* * This function prepares a command and send it to the firmware. * * Preparation includes - * - Sanity tests to make sure the card is still present or the FW * is not reset * - Getting a new command node from the command free queue * - Initializing the command node for default parameters * - Fill up the non-default parameters and buffer pointers * - Add the command to pending queue */ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync) { … } /* * This function queues a command to the command pending queue. * * This in effect adds the command to the command list to be executed. * Exit PS command is handled specially, by placing it always to the * front of the command queue. */ void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { … } /* * This function executes the next command in command pending queue. * * This function will fail if a command is already in processing stage, * otherwise it will dequeue the first command from the command pending * queue and send to the firmware. * * If the device is currently in host sleep mode, any commands, except the * host sleep configuration command will de-activate the host sleep. For PS * mode, the function will put the firmware back to sleep if applicable. */ int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter) { … } /* * This function handles the command response. * * After processing, the function cleans the command node and puts * it back to the command free queue. */ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) { … } /* * This function handles the timeout of command sending. * * It will re-send the same command again. */ void mwifiex_cmd_timeout_func(struct timer_list *t) { … } void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter) { … } /* * This function cancels all the pending commands. * * The current command, all commands in command pending queue and all scan * commands in scan pending queue are cancelled. All the completion callbacks * are called with failure status to ensure cleanup. */ void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) { … } /* * This function cancels all pending commands that matches with * the given IOCTL request. * * Both the current command buffer and the pending command queue are * searched for matching IOCTL request. The completion callback of * the matched command is called with failure status to ensure cleanup. * In case of scan commands, all pending commands in scan pending queue * are cancelled. */ static void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { … } /* * This function sends the sleep confirm command to firmware, if * possible. * * The sleep confirm command cannot be issued if command response, * data response or event response is awaiting handling, or if we * are in the middle of sending a command, or expecting a command * response. */ void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) { … } /* * This function sends a Host Sleep activated event to applications. * * This event is generated by the driver, with a blank event body. */ void mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated) { … } /* * This function handles the command response of a Host Sleep configuration * command. * * Handling includes changing the header fields into CPU format * and setting the current host sleep activation status in driver. * * In case host sleep status change, the function generates an event to * notify the applications. */ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { … } /* * This function wakes up the adapter and generates a Host Sleep * cancel event on receiving the power up interrupt. */ void mwifiex_process_hs_config(struct mwifiex_adapter *adapter) { … } EXPORT_SYMBOL_GPL(…); /* * This function handles the command response of a sleep confirm command. * * The function sets the card state to SLEEP if the response indicates success. */ void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, u8 *pbuf, u32 upld_len) { … } EXPORT_SYMBOL_GPL(…); /* * This function prepares an enhanced power mode command. * * This function can be used to disable power save or to configure * power save with auto PS or STA PS or auto deep sleep. * * Preparation includes - * - Setting command ID, action and proper size * - Setting Power Save bitmap, PS parameters TLV, PS mode TLV, * auto deep sleep TLV (as required) * - Ensuring correct endian-ness */ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, struct mwifiex_ds_auto_ds *auto_ds) { … } /* * This function handles the command response of an enhanced power mode * command. * * Handling includes changing the header fields into CPU format * and setting the current enhanced power mode in driver. */ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, struct mwifiex_ds_pm_cfg *pm_cfg) { … } /* * This function prepares command to get hardware specifications. * * Preparation includes - * - Setting command ID, action and proper size * - Setting permanent address parameter * - Ensuring correct endian-ness */ int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd) { … } /* * This function handles the command response of get hardware * specifications. * * Handling includes changing the header fields into CPU format * and saving/updating the following parameters in driver - * - Firmware capability information * - Firmware band settings * - Ad-hoc start band and channel * - Ad-hoc 11n activation status * - Firmware release number * - Number of antennas * - Hardware address * - Hardware interface version * - Firmware version * - Region code * - 11n capabilities * - MCS support fields * - MP end port */ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { … } /* This function handles the command response of hs wakeup reason * command. */ int mwifiex_ret_wakeup_reason(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, struct host_cmd_ds_wakeup_reason *wakeup_reason) { … }