162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2021, MediaTek Inc. 462306a36Sopenharmony_ci * Copyright (c) 2021-2022, Intel Corporation. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Authors: 762306a36Sopenharmony_ci * Haijun Liu <haijun.liu@mediatek.com> 862306a36Sopenharmony_ci * Moises Veleta <moises.veleta@intel.com> 962306a36Sopenharmony_ci * Ricardo Martinez <ricardo.martinez@linux.intel.com> 1062306a36Sopenharmony_ci * Sreehari Kancharla <sreehari.kancharla@intel.com> 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Contributors: 1362306a36Sopenharmony_ci * Amir Hanania <amir.hanania@intel.com> 1462306a36Sopenharmony_ci * Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com> 1562306a36Sopenharmony_ci * Eliot Lee <eliot.lee@intel.com> 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#ifndef __T7XX_HIF_CLDMA_H__ 1962306a36Sopenharmony_ci#define __T7XX_HIF_CLDMA_H__ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/bits.h> 2262306a36Sopenharmony_ci#include <linux/device.h> 2362306a36Sopenharmony_ci#include <linux/dmapool.h> 2462306a36Sopenharmony_ci#include <linux/pci.h> 2562306a36Sopenharmony_ci#include <linux/skbuff.h> 2662306a36Sopenharmony_ci#include <linux/spinlock.h> 2762306a36Sopenharmony_ci#include <linux/wait.h> 2862306a36Sopenharmony_ci#include <linux/workqueue.h> 2962306a36Sopenharmony_ci#include <linux/types.h> 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#include "t7xx_cldma.h" 3262306a36Sopenharmony_ci#include "t7xx_pci.h" 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/** 3562306a36Sopenharmony_ci * enum cldma_id - Identifiers for CLDMA HW units. 3662306a36Sopenharmony_ci * @CLDMA_ID_MD: Modem control channel. 3762306a36Sopenharmony_ci * @CLDMA_ID_AP: Application Processor control channel. 3862306a36Sopenharmony_ci * @CLDMA_NUM: Number of CLDMA HW units available. 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_cienum cldma_id { 4162306a36Sopenharmony_ci CLDMA_ID_MD, 4262306a36Sopenharmony_ci CLDMA_ID_AP, 4362306a36Sopenharmony_ci CLDMA_NUM 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct cldma_gpd { 4762306a36Sopenharmony_ci u8 flags; 4862306a36Sopenharmony_ci u8 not_used1; 4962306a36Sopenharmony_ci __le16 rx_data_allow_len; 5062306a36Sopenharmony_ci __le32 next_gpd_ptr_h; 5162306a36Sopenharmony_ci __le32 next_gpd_ptr_l; 5262306a36Sopenharmony_ci __le32 data_buff_bd_ptr_h; 5362306a36Sopenharmony_ci __le32 data_buff_bd_ptr_l; 5462306a36Sopenharmony_ci __le16 data_buff_len; 5562306a36Sopenharmony_ci __le16 not_used2; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct cldma_request { 5962306a36Sopenharmony_ci struct cldma_gpd *gpd; /* Virtual address for CPU */ 6062306a36Sopenharmony_ci dma_addr_t gpd_addr; /* Physical address for DMA */ 6162306a36Sopenharmony_ci struct sk_buff *skb; 6262306a36Sopenharmony_ci dma_addr_t mapped_buff; 6362306a36Sopenharmony_ci struct list_head entry; 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistruct cldma_ring { 6762306a36Sopenharmony_ci struct list_head gpd_ring; /* Ring of struct cldma_request */ 6862306a36Sopenharmony_ci unsigned int length; /* Number of struct cldma_request */ 6962306a36Sopenharmony_ci int pkt_size; 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct cldma_queue { 7362306a36Sopenharmony_ci struct cldma_ctrl *md_ctrl; 7462306a36Sopenharmony_ci enum mtk_txrx dir; 7562306a36Sopenharmony_ci unsigned int index; 7662306a36Sopenharmony_ci struct cldma_ring *tr_ring; 7762306a36Sopenharmony_ci struct cldma_request *tr_done; 7862306a36Sopenharmony_ci struct cldma_request *rx_refill; 7962306a36Sopenharmony_ci struct cldma_request *tx_next; 8062306a36Sopenharmony_ci int budget; /* Same as ring buffer size by default */ 8162306a36Sopenharmony_ci spinlock_t ring_lock; 8262306a36Sopenharmony_ci wait_queue_head_t req_wq; /* Only for TX */ 8362306a36Sopenharmony_ci struct workqueue_struct *worker; 8462306a36Sopenharmony_ci struct work_struct cldma_work; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistruct cldma_ctrl { 8862306a36Sopenharmony_ci enum cldma_id hif_id; 8962306a36Sopenharmony_ci struct device *dev; 9062306a36Sopenharmony_ci struct t7xx_pci_dev *t7xx_dev; 9162306a36Sopenharmony_ci struct cldma_queue txq[CLDMA_TXQ_NUM]; 9262306a36Sopenharmony_ci struct cldma_queue rxq[CLDMA_RXQ_NUM]; 9362306a36Sopenharmony_ci unsigned short txq_active; 9462306a36Sopenharmony_ci unsigned short rxq_active; 9562306a36Sopenharmony_ci unsigned short txq_started; 9662306a36Sopenharmony_ci spinlock_t cldma_lock; /* Protects CLDMA structure */ 9762306a36Sopenharmony_ci /* Assumes T/R GPD/BD/SPD have the same size */ 9862306a36Sopenharmony_ci struct dma_pool *gpd_dmapool; 9962306a36Sopenharmony_ci struct cldma_ring tx_ring[CLDMA_TXQ_NUM]; 10062306a36Sopenharmony_ci struct cldma_ring rx_ring[CLDMA_RXQ_NUM]; 10162306a36Sopenharmony_ci struct md_pm_entity *pm_entity; 10262306a36Sopenharmony_ci struct t7xx_cldma_hw hw_info; 10362306a36Sopenharmony_ci bool is_late_init; 10462306a36Sopenharmony_ci int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb); 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci#define GPD_FLAGS_HWO BIT(0) 10862306a36Sopenharmony_ci#define GPD_FLAGS_IOC BIT(7) 10962306a36Sopenharmony_ci#define GPD_DMAPOOL_ALIGN 16 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define CLDMA_MTU 3584 /* 3.5kB */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciint t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev); 11462306a36Sopenharmony_civoid t7xx_cldma_hif_hw_init(struct cldma_ctrl *md_ctrl); 11562306a36Sopenharmony_ciint t7xx_cldma_init(struct cldma_ctrl *md_ctrl); 11662306a36Sopenharmony_civoid t7xx_cldma_exit(struct cldma_ctrl *md_ctrl); 11762306a36Sopenharmony_civoid t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl); 11862306a36Sopenharmony_civoid t7xx_cldma_start(struct cldma_ctrl *md_ctrl); 11962306a36Sopenharmony_ciint t7xx_cldma_stop(struct cldma_ctrl *md_ctrl); 12062306a36Sopenharmony_civoid t7xx_cldma_reset(struct cldma_ctrl *md_ctrl); 12162306a36Sopenharmony_civoid t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl, 12262306a36Sopenharmony_ci int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb)); 12362306a36Sopenharmony_ciint t7xx_cldma_send_skb(struct cldma_ctrl *md_ctrl, int qno, struct sk_buff *skb); 12462306a36Sopenharmony_civoid t7xx_cldma_stop_all_qs(struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx); 12562306a36Sopenharmony_civoid t7xx_cldma_clear_all_qs(struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#endif /* __T7XX_HIF_CLDMA_H__ */ 128