148cc2f5eSHaijun Liu /* SPDX-License-Identifier: GPL-2.0-only 248cc2f5eSHaijun Liu * 348cc2f5eSHaijun Liu * Copyright (c) 2021, MediaTek Inc. 448cc2f5eSHaijun Liu * Copyright (c) 2021-2022, Intel Corporation. 548cc2f5eSHaijun Liu * 648cc2f5eSHaijun Liu * Authors: 748cc2f5eSHaijun Liu * Haijun Liu <haijun.liu@mediatek.com> 848cc2f5eSHaijun Liu * Moises Veleta <moises.veleta@intel.com> 948cc2f5eSHaijun Liu * Ricardo Martinez <ricardo.martinez@linux.intel.com> 1048cc2f5eSHaijun Liu * 1148cc2f5eSHaijun Liu * Contributors: 1248cc2f5eSHaijun Liu * Amir Hanania <amir.hanania@intel.com> 1348cc2f5eSHaijun Liu * Andy Shevchenko <andriy.shevchenko@linux.intel.com> 1448cc2f5eSHaijun Liu * Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> 1548cc2f5eSHaijun Liu * Eliot Lee <eliot.lee@intel.com> 1648cc2f5eSHaijun Liu */ 1748cc2f5eSHaijun Liu 1848cc2f5eSHaijun Liu #ifndef __T7XX_PORT_H__ 1948cc2f5eSHaijun Liu #define __T7XX_PORT_H__ 2048cc2f5eSHaijun Liu 2148cc2f5eSHaijun Liu #include <linux/bits.h> 2248cc2f5eSHaijun Liu #include <linux/device.h> 2348cc2f5eSHaijun Liu #include <linux/mutex.h> 2448cc2f5eSHaijun Liu #include <linux/sched.h> 2548cc2f5eSHaijun Liu #include <linux/skbuff.h> 2648cc2f5eSHaijun Liu #include <linux/spinlock.h> 2748cc2f5eSHaijun Liu #include <linux/types.h> 2848cc2f5eSHaijun Liu #include <linux/wait.h> 2948cc2f5eSHaijun Liu #include <linux/wwan.h> 3048cc2f5eSHaijun Liu 3148cc2f5eSHaijun Liu #include "t7xx_hif_cldma.h" 3248cc2f5eSHaijun Liu #include "t7xx_pci.h" 3348cc2f5eSHaijun Liu 3448cc2f5eSHaijun Liu #define PORT_CH_ID_MASK GENMASK(7, 0) 3548cc2f5eSHaijun Liu 3648cc2f5eSHaijun Liu /* Channel ID and Message ID definitions. 3748cc2f5eSHaijun Liu * The channel number consists of peer_id(15:12) , channel_id(11:0) 3848cc2f5eSHaijun Liu * peer_id: 39*ba2274dcSJose Ignacio Tornos Martinez * 0:reserved, 1: to AP, 2: to MD 4048cc2f5eSHaijun Liu */ 4148cc2f5eSHaijun Liu enum port_ch { 42*ba2274dcSJose Ignacio Tornos Martinez /* to AP */ 43*ba2274dcSJose Ignacio Tornos Martinez PORT_CH_AP_CONTROL_RX = 0x1000, 44*ba2274dcSJose Ignacio Tornos Martinez PORT_CH_AP_CONTROL_TX = 0x1001, 45*ba2274dcSJose Ignacio Tornos Martinez 4648cc2f5eSHaijun Liu /* to MD */ 4748cc2f5eSHaijun Liu PORT_CH_CONTROL_RX = 0x2000, 4848cc2f5eSHaijun Liu PORT_CH_CONTROL_TX = 0x2001, 4948cc2f5eSHaijun Liu PORT_CH_UART1_RX = 0x2006, /* META */ 5048cc2f5eSHaijun Liu PORT_CH_UART1_TX = 0x2008, 5148cc2f5eSHaijun Liu PORT_CH_UART2_RX = 0x200a, /* AT */ 5248cc2f5eSHaijun Liu PORT_CH_UART2_TX = 0x200c, 5348cc2f5eSHaijun Liu PORT_CH_MD_LOG_RX = 0x202a, /* MD logging */ 5448cc2f5eSHaijun Liu PORT_CH_MD_LOG_TX = 0x202b, 5548cc2f5eSHaijun Liu PORT_CH_LB_IT_RX = 0x203e, /* Loop back test */ 5648cc2f5eSHaijun Liu PORT_CH_LB_IT_TX = 0x203f, 5748cc2f5eSHaijun Liu PORT_CH_STATUS_RX = 0x2043, /* Status events */ 5848cc2f5eSHaijun Liu PORT_CH_MIPC_RX = 0x20ce, /* MIPC */ 5948cc2f5eSHaijun Liu PORT_CH_MIPC_TX = 0x20cf, 6048cc2f5eSHaijun Liu PORT_CH_MBIM_RX = 0x20d0, 6148cc2f5eSHaijun Liu PORT_CH_MBIM_TX = 0x20d1, 6248cc2f5eSHaijun Liu PORT_CH_DSS0_RX = 0x20d2, 6348cc2f5eSHaijun Liu PORT_CH_DSS0_TX = 0x20d3, 6448cc2f5eSHaijun Liu PORT_CH_DSS1_RX = 0x20d4, 6548cc2f5eSHaijun Liu PORT_CH_DSS1_TX = 0x20d5, 6648cc2f5eSHaijun Liu PORT_CH_DSS2_RX = 0x20d6, 6748cc2f5eSHaijun Liu PORT_CH_DSS2_TX = 0x20d7, 6848cc2f5eSHaijun Liu PORT_CH_DSS3_RX = 0x20d8, 6948cc2f5eSHaijun Liu PORT_CH_DSS3_TX = 0x20d9, 7048cc2f5eSHaijun Liu PORT_CH_DSS4_RX = 0x20da, 7148cc2f5eSHaijun Liu PORT_CH_DSS4_TX = 0x20db, 7248cc2f5eSHaijun Liu PORT_CH_DSS5_RX = 0x20dc, 7348cc2f5eSHaijun Liu PORT_CH_DSS5_TX = 0x20dd, 7448cc2f5eSHaijun Liu PORT_CH_DSS6_RX = 0x20de, 7548cc2f5eSHaijun Liu PORT_CH_DSS6_TX = 0x20df, 7648cc2f5eSHaijun Liu PORT_CH_DSS7_RX = 0x20e0, 7748cc2f5eSHaijun Liu PORT_CH_DSS7_TX = 0x20e1, 7848cc2f5eSHaijun Liu }; 7948cc2f5eSHaijun Liu 8048cc2f5eSHaijun Liu struct t7xx_port; 8148cc2f5eSHaijun Liu struct port_ops { 8248cc2f5eSHaijun Liu int (*init)(struct t7xx_port *port); 8348cc2f5eSHaijun Liu int (*recv_skb)(struct t7xx_port *port, struct sk_buff *skb); 8448cc2f5eSHaijun Liu void (*md_state_notify)(struct t7xx_port *port, unsigned int md_state); 8548cc2f5eSHaijun Liu void (*uninit)(struct t7xx_port *port); 8648cc2f5eSHaijun Liu int (*enable_chl)(struct t7xx_port *port); 8748cc2f5eSHaijun Liu int (*disable_chl)(struct t7xx_port *port); 8848cc2f5eSHaijun Liu }; 8948cc2f5eSHaijun Liu 9048cc2f5eSHaijun Liu struct t7xx_port_conf { 9148cc2f5eSHaijun Liu enum port_ch tx_ch; 9248cc2f5eSHaijun Liu enum port_ch rx_ch; 9348cc2f5eSHaijun Liu unsigned char txq_index; 9448cc2f5eSHaijun Liu unsigned char rxq_index; 9548cc2f5eSHaijun Liu unsigned char txq_exp_index; 9648cc2f5eSHaijun Liu unsigned char rxq_exp_index; 9748cc2f5eSHaijun Liu enum cldma_id path_id; 9848cc2f5eSHaijun Liu struct port_ops *ops; 9948cc2f5eSHaijun Liu char *name; 10048cc2f5eSHaijun Liu enum wwan_port_type port_type; 10148cc2f5eSHaijun Liu }; 10248cc2f5eSHaijun Liu 10348cc2f5eSHaijun Liu struct t7xx_port { 10448cc2f5eSHaijun Liu /* Members not initialized in definition */ 10548cc2f5eSHaijun Liu const struct t7xx_port_conf *port_conf; 10648cc2f5eSHaijun Liu struct t7xx_pci_dev *t7xx_dev; 10748cc2f5eSHaijun Liu struct device *dev; 10848cc2f5eSHaijun Liu u16 seq_nums[2]; /* TX/RX sequence numbers */ 10948cc2f5eSHaijun Liu atomic_t usage_cnt; 11048cc2f5eSHaijun Liu struct list_head entry; 11148cc2f5eSHaijun Liu struct list_head queue_entry; 11248cc2f5eSHaijun Liu /* TX and RX flows are asymmetric since ports are multiplexed on 11348cc2f5eSHaijun Liu * queues. 11448cc2f5eSHaijun Liu * 11548cc2f5eSHaijun Liu * TX: data blocks are sent directly to a queue. Each port 11648cc2f5eSHaijun Liu * does not maintain a TX list; instead, they only provide 11748cc2f5eSHaijun Liu * a wait_queue_head for blocking writes. 11848cc2f5eSHaijun Liu * 11948cc2f5eSHaijun Liu * RX: Each port uses a RX list to hold packets, 12048cc2f5eSHaijun Liu * allowing the modem to dispatch RX packet as quickly as possible. 12148cc2f5eSHaijun Liu */ 12248cc2f5eSHaijun Liu struct sk_buff_head rx_skb_list; 12348cc2f5eSHaijun Liu spinlock_t port_update_lock; /* Protects port configuration */ 12448cc2f5eSHaijun Liu wait_queue_head_t rx_wq; 12548cc2f5eSHaijun Liu int rx_length_th; 12648cc2f5eSHaijun Liu bool chan_enable; 12748cc2f5eSHaijun Liu struct task_struct *thread; 128fece7a8cSM Chetan Kumar union { 129fece7a8cSM Chetan Kumar struct { 130fece7a8cSM Chetan Kumar struct wwan_port *wwan_port; 131fece7a8cSM Chetan Kumar } wwan; 1323349e4a4SM Chetan Kumar struct { 1333349e4a4SM Chetan Kumar struct rchan *relaych; 1343349e4a4SM Chetan Kumar } log; 135fece7a8cSM Chetan Kumar }; 13648cc2f5eSHaijun Liu }; 13748cc2f5eSHaijun Liu 13848cc2f5eSHaijun Liu struct sk_buff *t7xx_port_alloc_skb(int payload); 139da45d256SHaijun Liu struct sk_buff *t7xx_ctrl_alloc_skb(int payload); 14048cc2f5eSHaijun Liu int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb); 14148cc2f5eSHaijun Liu int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header, 14248cc2f5eSHaijun Liu unsigned int ex_msg); 143da45d256SHaijun Liu int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg, 144da45d256SHaijun Liu unsigned int ex_msg); 14548cc2f5eSHaijun Liu 14648cc2f5eSHaijun Liu #endif /* __T7XX_PORT_H__ */ 147