kernel-aes67/drivers/net/wireless/ath/ath12k/ce.h

182 lines
5.2 KiB
C
Raw Permalink Normal View History

wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices ath12k is a new mac80211 driver for Qualcomm Wi-Fi 7 devices, first supporting QCN9274 and WCN7850 PCI devices. QCN9274 supports both AP and station; WCN7850 supports only station mode. Monitor mode is not (yet) supported. Only PCI bus devices are supported. ath12k is forked from an earlier version of ath11k. It was simpler to have a "clean start" for the new generation and not try to share the code with ath11k. This makes maintenance easier and avoids major changes in ath11k, which would have significantly increased the risk of regressions in existing setups. ath12k uses le32 and cpu_to_le32() macros to handle endian conversions, instead of using the firmware byte swap feature utilized by ath11k. There is only one kernel module, named ath12k.ko. Currently ath12k only supports HE mode (IEEE 802.11ax) or older, but work is ongoing to add EHT mode (IEEE 802.11be) support. The size of the driver is ~41 kLOC and 45 files. To make the review easier, this initial version of ath12k does not support Device Tree, debugfs or any other extra features. Those will be added later, after ath12k is accepted to upstream. The driver is build tested by Intel's kernel test robot with both GCC and Clang. Sparse reports no warnings. The driver is mostly free of checkpatch warnings, albeit few of the warnings are omitted on purpose, list of them here: https://github.com/qca/qca-swiss-army-knife/blob/master/tools/scripts/ath12k/ath12k-check#L52 The driver has had multiple authors who are listed in alphabetical order below. Co-developed-by: Balamurugan Selvarajan <quic_bselvara@quicinc.com> Signed-off-by: Balamurugan Selvarajan <quic_bselvara@quicinc.com> Co-developed-by: Baochen Qiang <quic_bqiang@quicinc.com> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> Co-developed-by: Bhagavathi Perumal S <quic_bperumal@quicinc.com> Signed-off-by: Bhagavathi Perumal S <quic_bperumal@quicinc.com> Co-developed-by: Carl Huang <quic_cjhuang@quicinc.com> Signed-off-by: Carl Huang <quic_cjhuang@quicinc.com> Co-developed-by: Jeff Johnson <quic_jjohnson@quicinc.com> Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com> Co-developed-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com> Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com> Co-developed-by: P Praneesh <quic_ppranees@quicinc.com> Signed-off-by: P Praneesh <quic_ppranees@quicinc.com> Co-developed-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> Co-developed-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> Co-developed-by: Sriram R <quic_srirrama@quicinc.com> Signed-off-by: Sriram R <quic_srirrama@quicinc.com> Co-developed-by: Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com> Signed-off-by: Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com> Co-developed-by: Wen Gong <quic_wgong@quicinc.com> Signed-off-by: Wen Gong <quic_wgong@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
2022-11-28 10:09:53 -05:00
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_CE_H
#define ATH12K_CE_H
#define CE_COUNT_MAX 16
/* Byte swap data words */
#define CE_ATTR_BYTE_SWAP_DATA 2
/* no interrupt on copy completion */
#define CE_ATTR_DIS_INTR 8
/* Host software's Copy Engine configuration. */
#define CE_ATTR_FLAGS 0
/* Threshold to poll for tx completion in case of Interrupt disabled CE's */
#define ATH12K_CE_USAGE_THRESHOLD 32
/* Directions for interconnect pipe configuration.
* These definitions may be used during configuration and are shared
* between Host and Target.
*
* Pipe Directions are relative to the Host, so PIPEDIR_IN means
* "coming IN over air through Target to Host" as with a WiFi Rx operation.
* Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
* as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
* Target since things that are "PIPEDIR_OUT" are coming IN to the Target
* over the interconnect.
*/
#define PIPEDIR_NONE 0
#define PIPEDIR_IN 1 /* Target-->Host, WiFi Rx direction */
#define PIPEDIR_OUT 2 /* Host->Target, WiFi Tx direction */
#define PIPEDIR_INOUT 3 /* bidirectional */
#define PIPEDIR_INOUT_H2H 4 /* bidirectional, host to host */
/* CE address/mask */
#define CE_HOST_IE_ADDRESS 0x00A1803C
#define CE_HOST_IE_2_ADDRESS 0x00A18040
#define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS
#define CE_HOST_IE_3_SHIFT 0xC
#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
#define ATH12K_CE_RX_POST_RETRY_JIFFIES 50
struct ath12k_base;
/* Establish a mapping between a service/direction and a pipe.
* Configuration information for a Copy Engine pipe and services.
* Passed from Host to Target through QMI message and must be in
* little endian format.
*/
struct service_to_pipe {
__le32 service_id;
__le32 pipedir;
__le32 pipenum;
};
/* Configuration information for a Copy Engine pipe.
* Passed from Host to Target through QMI message during startup (one per CE).
*
* NOTE: Structure is shared between Host software and Target firmware!
*/
struct ce_pipe_config {
__le32 pipenum;
__le32 pipedir;
__le32 nentries;
__le32 nbytes_max;
__le32 flags;
__le32 reserved;
};
struct ce_attr {
/* CE_ATTR_* values */
unsigned int flags;
/* #entries in source ring - Must be a power of 2 */
unsigned int src_nentries;
/* Max source send size for this CE.
* This is also the minimum size of a destination buffer.
*/
unsigned int src_sz_max;
/* #entries in destination ring - Must be a power of 2 */
unsigned int dest_nentries;
void (*recv_cb)(struct ath12k_base *ab, struct sk_buff *skb);
};
#define CE_DESC_RING_ALIGN 8
struct ath12k_ce_ring {
/* Number of entries in this ring; must be power of 2 */
unsigned int nentries;
unsigned int nentries_mask;
/* For dest ring, this is the next index to be processed
* by software after it was/is received into.
*
* For src ring, this is the last descriptor that was sent
* and completion processed by software.
*
* Regardless of src or dest ring, this is an invariant
* (modulo ring size):
* write index >= read index >= sw_index
*/
unsigned int sw_index;
/* cached copy */
unsigned int write_index;
/* Start of DMA-coherent area reserved for descriptors */
/* Host address space */
void *base_addr_owner_space_unaligned;
/* CE address space */
u32 base_addr_ce_space_unaligned;
/* Actual start of descriptors.
* Aligned to descriptor-size boundary.
* Points into reserved DMA-coherent area, above.
*/
/* Host address space */
void *base_addr_owner_space;
/* CE address space */
u32 base_addr_ce_space;
/* HAL ring id */
u32 hal_ring_id;
/* keep last */
struct sk_buff *skb[];
};
struct ath12k_ce_pipe {
struct ath12k_base *ab;
u16 pipe_num;
unsigned int attr_flags;
unsigned int buf_sz;
unsigned int rx_buf_needed;
void (*send_cb)(struct ath12k_ce_pipe *pipe);
void (*recv_cb)(struct ath12k_base *ab, struct sk_buff *skb);
struct tasklet_struct intr_tq;
struct ath12k_ce_ring *src_ring;
struct ath12k_ce_ring *dest_ring;
struct ath12k_ce_ring *status_ring;
u64 timestamp;
};
struct ath12k_ce {
struct ath12k_ce_pipe ce_pipe[CE_COUNT_MAX];
/* Protects rings of all ce pipes */
spinlock_t ce_lock;
struct ath12k_hp_update_timer hp_timer[CE_COUNT_MAX];
};
extern const struct ce_attr ath12k_host_ce_config_qcn9274[];
extern const struct ce_attr ath12k_host_ce_config_wcn7850[];
void ath12k_ce_cleanup_pipes(struct ath12k_base *ab);
void ath12k_ce_rx_replenish_retry(struct timer_list *t);
void ath12k_ce_per_engine_service(struct ath12k_base *ab, u16 ce_id);
int ath12k_ce_send(struct ath12k_base *ab, struct sk_buff *skb, u8 pipe_id,
u16 transfer_id);
void ath12k_ce_rx_post_buf(struct ath12k_base *ab);
int ath12k_ce_init_pipes(struct ath12k_base *ab);
int ath12k_ce_alloc_pipes(struct ath12k_base *ab);
void ath12k_ce_free_pipes(struct ath12k_base *ab);
int ath12k_ce_get_attr_flags(struct ath12k_base *ab, int ce_id);
void ath12k_ce_poll_send_completed(struct ath12k_base *ab, u8 pipe_id);
void ath12k_ce_get_shadow_config(struct ath12k_base *ab,
u32 **shadow_cfg, u32 *shadow_cfg_len);
#endif