// SPDX-License-Identifier: GPL-2.0-only /* * NXP Wireless LAN device driver: WMM * * Copyright 2011-2020 NXP */ #include "decl.h" #include "ioctl.h" #include "util.h" #include "fw.h" #include "main.h" #include "wmm.h" #include "11n.h" /* Maximum value FW can accept for driver delay in packet transmission */ #define DRV_PKT_DELAY_TO_FW_MAX … #define WMM_QUEUED_PACKET_LOWER_LIMIT … #define WMM_QUEUED_PACKET_UPPER_LIMIT … /* Offset for TOS field in the IP header */ #define IPTOS_OFFSET … static bool disable_tx_amsdu; module_param(disable_tx_amsdu, bool, 0644); /* This table inverses the tos_to_tid operation to get a priority * which is in sequential order, and can be compared. * Use this to compare the priority of two different TIDs. */ const u8 tos_to_tid_inv[] = …; /* WMM information IE */ static const u8 wmm_info_ie[] = …; static const u8 wmm_aci_to_qidx_map[] = …; static u8 tos_to_tid[] = …; static u8 ac_to_tid[4][2] = …; /* * This function debug prints the priority parameters for a WMM AC. */ static void mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) { … } /* * This function allocates a route address list. * * The function also initializes the list with the provided RA. */ static struct mwifiex_ra_list_tbl * mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, const u8 *ra) { … } /* This function returns random no between 16 and 32 to be used as threshold * for no of packets after which BA setup is initiated. */ static u8 mwifiex_get_random_ba_threshold(void) { … } /* * This function allocates and adds a RA list for all TIDs * with the given RA. */ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra) { … } /* * This function sets the WMM queue priorities to their default values. */ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) { … } /* * This function map ACs to TIDs. */ static void mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv) { … } /* * This function initializes WMM priority queues. */ void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, struct ieee_types_wmm_parameter *wmm_ie) { … } /* * This function evaluates whether or not an AC is to be downgraded. * * In case the AC is not enabled, the highest AC is returned that is * enabled and does not require admission control. */ static enum mwifiex_wmm_ac_e mwifiex_wmm_eval_downgrade_ac(struct mwifiex_private *priv, enum mwifiex_wmm_ac_e eval_ac) { … } /* * This function downgrades WMM priority queue. */ void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) { … } /* * This function converts the IP TOS field to an WMM AC * Queue assignment. */ static enum mwifiex_wmm_ac_e mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos) { … } /* * This function evaluates a given TID and downgrades it to a lower * TID if the WMM Parameter IE received from the AP indicates that the * AP is disabled (due to call admission control (ACM bit). Mapping * of TID to AC is taken care of internally. */ u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid) { … } /* * This function initializes the WMM state information and the * WMM data path queues. */ void mwifiex_wmm_init(struct mwifiex_adapter *adapter) { … } int mwifiex_bypass_txlist_empty(struct mwifiex_adapter *adapter) { … } /* * This function checks if WMM Tx queue is empty. */ int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) { … } /* * This function deletes all packets in an RA list node. * * The packet sent completion callback handler are called with * status failure, after they are dequeued to ensure proper * cleanup. The RA list node itself is freed at the end. */ static void mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra_list) { … } /* * This function deletes all packets in an RA list. * * Each nodes in the RA list are freed individually first, and then * the RA list itself is freed. */ static void mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv, struct list_head *ra_list_head) { … } /* * This function deletes all packets in all RA lists. */ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) { … } /* * This function deletes all route addresses from all RA lists. */ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) { … } static int mwifiex_free_ack_frame(int id, void *p, void *data) { … } /* * This function cleans up the Tx and Rx queues. * * Cleanup includes - * - All packets in RA lists * - All entries in Rx reorder table * - All entries in Tx BA stream table * - MPA buffer (if required) * - All RA lists */ void mwifiex_clean_txrx(struct mwifiex_private *priv) { … } /* * This function retrieves a particular RA list node, matching with the * given TID and RA address. */ struct mwifiex_ra_list_tbl * mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, const u8 *ra_addr) { … } void mwifiex_update_ralist_tx_pause(struct mwifiex_private *priv, u8 *mac, u8 tx_pause) { … } /* This function updates non-tdls peer ralist tx_pause while * tdls channel switching */ void mwifiex_update_ralist_tx_pause_in_tdls_cs(struct mwifiex_private *priv, u8 *mac, u8 tx_pause) { … } /* * This function retrieves an RA list node for a given TID and * RA address pair. * * If no such node is found, a new node is added first and then * retrieved. */ struct mwifiex_ra_list_tbl * mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, const u8 *ra_addr) { … } /* * This function deletes RA list nodes for given mac for all TIDs. * Function also decrements TX pending count accordingly. */ void mwifiex_wmm_del_peer_ra_list(struct mwifiex_private *priv, const u8 *ra_addr) { … } /* * This function checks if a particular RA list node exists in a given TID * table index. */ int mwifiex_is_ralist_valid(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra_list, int ptr_index) { … } /* * This function adds a packet to bypass TX queue. * This is special TX queue for packets which can be sent even when port_open * is false. */ void mwifiex_wmm_add_buf_bypass_txqueue(struct mwifiex_private *priv, struct sk_buff *skb) { … } /* * This function adds a packet to WMM queue. * * In disconnected state the packet is immediately dropped and the * packet send completion callback is called with status failure. * * Otherwise, the correct RA list node is located and the packet * is queued at the list tail. */ void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct sk_buff *skb) { … } /* * This function processes the get WMM status command response from firmware. * * The response may contain multiple TLVs - * - AC Queue status TLVs * - Current WMM Parameter IE TLV * - Admission Control action frame TLVs * * This function parses the TLVs and then calls further specific functions * to process any changes in the queue prioritize or state. */ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, const struct host_cmd_ds_command *resp) { … } /* * Callback handler from the command module to allow insertion of a WMM TLV. * * If the BSS we are associating to supports WMM, this function adds the * required WMM Information IE to the association request command buffer in * the form of a Marvell extended IEEE IE. */ u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, u8 **assoc_buf, struct ieee_types_wmm_parameter *wmm_ie, struct ieee80211_ht_cap *ht_cap) { … } /* * This function computes the time delay in the driver queues for a * given packet. * * When the packet is received at the OS/Driver interface, the current * time is set in the packet structure. The difference between the present * time and that received time is computed in this function and limited * based on pre-compiled limits in the driver. */ u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, const struct sk_buff *skb) { … } /* * This function retrieves the highest priority RA list table pointer. */ static struct mwifiex_ra_list_tbl * mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_private **priv, int *tid) { … } /* This functions rotates ra and bss lists so packets are picked round robin. * * After a packet is successfully transmitted, rotate the ra list, so the ra * next to the one transmitted, will come first in the list. This way we pick * the ra' in a round robin fashion. Same applies to bss nodes of equal * priority. * * Function also increments wmm.packets_out counter. */ void mwifiex_rotate_priolists(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra, int tid) { … } /* * This function checks if 11n aggregation is possible. */ static int mwifiex_is_11n_aggragation_possible(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ptr, int max_buf_size) { … } /* * This function sends a single packet to firmware for transmission. */ static void mwifiex_send_single_packet(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ptr, int ptr_index) __releases(&priv->wmm.ra_list_spinlock) { … } /* * This function checks if the first packet in the given RA list * is already processed or not. */ static int mwifiex_is_ptr_processed(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ptr) { … } /* * This function sends a single processed packet to firmware for * transmission. */ static void mwifiex_send_processed_packet(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ptr, int ptr_index) __releases(&priv->wmm.ra_list_spinlock) { … } /* * This function dequeues a packet from the highest priority list * and transmits it. */ static int mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) { … } void mwifiex_process_bypass_tx(struct mwifiex_adapter *adapter) { … } /* * This function transmits the highest priority packet awaiting in the * WMM Queues. */ void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) { … }