Commit d27553c1 authored by Jinjian Song's avatar Jinjian Song Committed by David S. Miller
Browse files

net: wwan: t7xx: Infrastructure for early port configuration

To support cases such as FW update or Core dump, the t7xx
device is capable of signaling the host that a special port
needs to be created before the handshake phase.

Adds the infrastructure required to create the early ports
which also requires a different configuration of CLDMA queues.

Base on the v5 patch version of follow series:
'net: wwan: t7xx: fw flashing & coredump support'
(https://patchwork.kernel.org/project/netdevbpf/patch/3777bb382f4b0395cb594a602c5c79dbab86c9e0.1674307425.git.m.chetan.kumar@linux.intel.com/

)

Signed-off-by: default avatarJinjian Song <jinjian.song@fibocom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 409c38d4
Loading
Loading
Loading
Loading
+32 −15
Original line number Diff line number Diff line
@@ -57,8 +57,6 @@
#define CHECK_Q_STOP_TIMEOUT_US		1000000
#define CHECK_Q_STOP_STEP_US		10000

#define CLDMA_JUMBO_BUFF_SZ		(63 * 1024 + sizeof(struct ccci_header))

static void md_cd_queue_struct_reset(struct cldma_queue *queue, struct cldma_ctrl *md_ctrl,
				     enum mtk_txrx tx_rx, unsigned int index)
{
@@ -161,7 +159,7 @@ static int t7xx_cldma_gpd_rx_from_q(struct cldma_queue *queue, int budget, bool
		skb_reset_tail_pointer(skb);
		skb_put(skb, le16_to_cpu(gpd->data_buff_len));

		ret = md_ctrl->recv_skb(queue, skb);
		ret = queue->recv_skb(queue, skb);
		/* Break processing, will try again later */
		if (ret < 0)
			return ret;
@@ -897,13 +895,13 @@ static void t7xx_cldma_hw_start_send(struct cldma_ctrl *md_ctrl, int qno,

/**
 * t7xx_cldma_set_recv_skb() - Set the callback to handle RX packets.
 * @md_ctrl: CLDMA context structure.
 * @queue: CLDMA queue.
 * @recv_skb: Receiving skb callback.
 */
void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl,
void t7xx_cldma_set_recv_skb(struct cldma_queue *queue,
			     int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb))
{
	md_ctrl->recv_skb = recv_skb;
	queue->recv_skb = recv_skb;
}

/**
@@ -993,6 +991,28 @@ int t7xx_cldma_send_skb(struct cldma_ctrl *md_ctrl, int qno, struct sk_buff *skb
	return ret;
}

static void t7xx_cldma_adjust_config(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id)
{
	int qno;

	for (qno = 0; qno < CLDMA_RXQ_NUM; qno++) {
		md_ctrl->rx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ;
		t7xx_cldma_set_recv_skb(&md_ctrl->rxq[qno], t7xx_port_proxy_recv_skb);
	}

	md_ctrl->rx_ring[CLDMA_RXQ_NUM - 1].pkt_size = CLDMA_JUMBO_BUFF_SZ;

	for (qno = 0; qno < CLDMA_TXQ_NUM; qno++)
		md_ctrl->tx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ;

	if (cfg_id == CLDMA_DEDICATED_Q_CFG) {
		md_ctrl->tx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
		md_ctrl->rx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
		t7xx_cldma_set_recv_skb(&md_ctrl->rxq[CLDMA_Q_IDX_DUMP],
					t7xx_port_proxy_recv_skb_from_dedicated_queue);
	}
}

static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
{
	char dma_pool_name[32];
@@ -1018,16 +1038,9 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
			dev_err(md_ctrl->dev, "control TX ring init fail\n");
			goto err_free_tx_ring;
		}

		md_ctrl->tx_ring[i].pkt_size = CLDMA_MTU;
	}

	for (j = 0; j < CLDMA_RXQ_NUM; j++) {
		md_ctrl->rx_ring[j].pkt_size = CLDMA_MTU;

		if (j == CLDMA_RXQ_NUM - 1)
			md_ctrl->rx_ring[j].pkt_size = CLDMA_JUMBO_BUFF_SZ;

		ret = t7xx_cldma_rx_ring_init(md_ctrl, &md_ctrl->rx_ring[j]);
		if (ret) {
			dev_err(md_ctrl->dev, "Control RX ring init fail\n");
@@ -1094,6 +1107,7 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev)
{
	struct device *dev = &t7xx_dev->pdev->dev;
	struct cldma_ctrl *md_ctrl;
	int qno;

	md_ctrl = devm_kzalloc(dev, sizeof(*md_ctrl), GFP_KERNEL);
	if (!md_ctrl)
@@ -1102,7 +1116,9 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev)
	md_ctrl->t7xx_dev = t7xx_dev;
	md_ctrl->dev = dev;
	md_ctrl->hif_id = hif_id;
	md_ctrl->recv_skb = t7xx_cldma_default_recv_skb;
	for (qno = 0; qno < CLDMA_RXQ_NUM; qno++)
		md_ctrl->rxq[qno].recv_skb = t7xx_cldma_default_recv_skb;

	t7xx_hw_info_init(md_ctrl);
	t7xx_dev->md->md_ctrl[hif_id] = md_ctrl;
	return 0;
@@ -1332,9 +1348,10 @@ int t7xx_cldma_init(struct cldma_ctrl *md_ctrl)
	return -ENOMEM;
}

void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl)
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id)
{
	t7xx_cldma_late_release(md_ctrl);
	t7xx_cldma_adjust_config(md_ctrl, cfg_id);
	t7xx_cldma_late_init(md_ctrl);
}

+13 −5
Original line number Diff line number Diff line
@@ -31,6 +31,10 @@
#include "t7xx_cldma.h"
#include "t7xx_pci.h"

#define CLDMA_JUMBO_BUFF_SZ		(63 * 1024 + sizeof(struct ccci_header))
#define CLDMA_SHARED_Q_BUFF_SZ		3584
#define CLDMA_DEDICATED_Q_BUFF_SZ	2048

/**
 * enum cldma_id - Identifiers for CLDMA HW units.
 * @CLDMA_ID_MD: Modem control channel.
@@ -55,6 +59,11 @@ struct cldma_gpd {
	__le16 not_used2;
};

enum cldma_cfg {
	CLDMA_SHARED_Q_CFG,
	CLDMA_DEDICATED_Q_CFG,
};

struct cldma_request {
	struct cldma_gpd *gpd;	/* Virtual address for CPU */
	dma_addr_t gpd_addr;	/* Physical address for DMA */
@@ -82,6 +91,7 @@ struct cldma_queue {
	wait_queue_head_t req_wq;	/* Only for TX */
	struct workqueue_struct *worker;
	struct work_struct cldma_work;
	int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb);
};

struct cldma_ctrl {
@@ -101,24 +111,22 @@ struct cldma_ctrl {
	struct md_pm_entity *pm_entity;
	struct t7xx_cldma_hw hw_info;
	bool is_late_init;
	int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb);
};

#define CLDMA_Q_IDX_DUMP	1
#define GPD_FLAGS_HWO		BIT(0)
#define GPD_FLAGS_IOC		BIT(7)
#define GPD_DMAPOOL_ALIGN	16

#define CLDMA_MTU		3584	/* 3.5kB */

int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev);
void t7xx_cldma_hif_hw_init(struct cldma_ctrl *md_ctrl);
int t7xx_cldma_init(struct cldma_ctrl *md_ctrl);
void t7xx_cldma_exit(struct cldma_ctrl *md_ctrl);
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl);
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id);
void t7xx_cldma_start(struct cldma_ctrl *md_ctrl);
int t7xx_cldma_stop(struct cldma_ctrl *md_ctrl);
void t7xx_cldma_reset(struct cldma_ctrl *md_ctrl);
void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl,
void t7xx_cldma_set_recv_skb(struct cldma_queue *queue,
			     int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb));
int t7xx_cldma_send_skb(struct cldma_ctrl *md_ctrl, int qno, struct sk_buff *skb);
void t7xx_cldma_stop_all_qs(struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx);
+5 −3
Original line number Diff line number Diff line
@@ -535,7 +535,7 @@ static void t7xx_md_hk_wq(struct work_struct *work)

	/* Clear the HS2 EXIT event appended in core_reset() */
	t7xx_fsm_clr_event(ctl, FSM_EVENT_MD_HS2_EXIT);
	t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD]);
	t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD], CLDMA_SHARED_Q_CFG);
	t7xx_cldma_start(md->md_ctrl[CLDMA_ID_MD]);
	t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_FOR_HS2);
	md->core_md.handshake_ongoing = true;
@@ -550,7 +550,7 @@ static void t7xx_ap_hk_wq(struct work_struct *work)
	 /* Clear the HS2 EXIT event appended in t7xx_core_reset(). */
	t7xx_fsm_clr_event(ctl, FSM_EVENT_AP_HS2_EXIT);
	t7xx_cldma_stop(md->md_ctrl[CLDMA_ID_AP]);
	t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP]);
	t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP], CLDMA_SHARED_Q_CFG);
	t7xx_cldma_start(md->md_ctrl[CLDMA_ID_AP]);
	md->core_ap.handshake_ongoing = true;
	t7xx_core_hk_handler(md, &md->core_ap, ctl, FSM_EVENT_AP_HS2, FSM_EVENT_AP_HS2_EXIT);
@@ -764,6 +764,7 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev)

void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev)
{
	enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode);
	struct t7xx_modem *md = t7xx_dev->md;

	t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT);
@@ -771,6 +772,7 @@ void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev)
	if (!md->md_init_finish)
		return;

	if (mode != T7XX_RESET && mode != T7XX_UNKNOWN)
		t7xx_fsm_append_cmd(md->fsm_ctl, FSM_CMD_PRE_STOP, FSM_CMD_FLAG_WAIT_FOR_COMPLETION);
	t7xx_port_proxy_uninit(md->port_prox);
	t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_AP]);
+1 −1
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ static int t7xx_pci_pm_init(struct t7xx_pci_dev *t7xx_dev)
	pm_runtime_set_autosuspend_delay(&pdev->dev, PM_AUTOSUSPEND_MS);
	pm_runtime_use_autosuspend(&pdev->dev);

	return t7xx_wait_pm_config(t7xx_dev);
	return 0;
}

void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev)
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ enum port_ch {
	PORT_CH_DSS6_TX = 0x20df,
	PORT_CH_DSS7_RX = 0x20e0,
	PORT_CH_DSS7_TX = 0x20e1,

	PORT_CH_UNIMPORTANT = 0xffff,
};

struct t7xx_port;
@@ -135,11 +137,13 @@ struct t7xx_port {
	};
};

int t7xx_get_port_mtu(struct t7xx_port *port);
struct sk_buff *t7xx_port_alloc_skb(int payload);
struct sk_buff *t7xx_ctrl_alloc_skb(int payload);
int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb);
int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
		       unsigned int ex_msg);
int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb);
int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
			   unsigned int ex_msg);

Loading