netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support
@ 2023-01-06 16:26 m.chetan.kumar
  2023-01-06 16:26 ` [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA m.chetan.kumar
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:26 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek

From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

This patch series brings-in the support for FM350 wwan device firmware
flashing & coredump collection using devlink interface.

Below is the high level description of individual patches.
Refer to individual patch commit message for details.

PATCH1:  Enables AP CLDMA communication for firmware flashing &
coredump collection.

PATCH2: Enables the infrastructure & queue configuration required
for early ports enumeration.

PATCH3: Implements device reset and rescan logic required to enter
or exit fastboot mode.

PATCH4: Implements devlink interface & uses the fastboot protocol for
fw flashing and coredump collection.

PATCH5: t7xx devlink commands documentation.

Version History:
================
v3: Repost the series by setting format.thread git-config option to
    shallow as suggested by Brandeburg, Jesse.
v2: Address review comments given by Jarvinen, Ilpo Johannes and
    Sergey Ryazanov. Refer to Individual patches on v2 changes.
v1: Initial Version.

Haijun Liu (1):
  net: wwan: t7xx: Add AP CLDMA

M Chetan Kumar (4):
  net: wwan: t7xx: Infrastructure for early port configuration
  net: wwan: t7xx: PCIe reset rescan
  net: wwan: t7xx: Enable devlink based fw flashing and coredump
    collection
  net: wwan: t7xx: Devlink documentation

 Documentation/networking/devlink/index.rst |   1 +
 Documentation/networking/devlink/t7xx.rst  | 161 +++++
 drivers/net/wwan/Kconfig                   |   1 +
 drivers/net/wwan/t7xx/Makefile             |   5 +-
 drivers/net/wwan/t7xx/t7xx_hif_cldma.c     |  64 +-
 drivers/net/wwan/t7xx/t7xx_hif_cldma.h     |  20 +-
 drivers/net/wwan/t7xx/t7xx_mhccif.h        |   1 +
 drivers/net/wwan/t7xx/t7xx_modem_ops.c     |  81 ++-
 drivers/net/wwan/t7xx/t7xx_modem_ops.h     |   2 +
 drivers/net/wwan/t7xx/t7xx_pci.c           |  72 ++-
 drivers/net/wwan/t7xx/t7xx_pci.h           |   2 +
 drivers/net/wwan/t7xx/t7xx_pci_rescan.c    |  96 +++
 drivers/net/wwan/t7xx/t7xx_pci_rescan.h    |  28 +
 drivers/net/wwan/t7xx/t7xx_port.h          |  12 +-
 drivers/net/wwan/t7xx/t7xx_port_ap_msg.c   |  78 +++
 drivers/net/wwan/t7xx/t7xx_port_ap_msg.h   |  11 +
 drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c |   8 +-
 drivers/net/wwan/t7xx/t7xx_port_devlink.c  | 665 +++++++++++++++++++++
 drivers/net/wwan/t7xx/t7xx_port_devlink.h  |  86 +++
 drivers/net/wwan/t7xx/t7xx_port_proxy.c    | 135 ++++-
 drivers/net/wwan/t7xx/t7xx_port_proxy.h    |  16 +-
 drivers/net/wwan/t7xx/t7xx_port_wwan.c     |  25 +-
 drivers/net/wwan/t7xx/t7xx_reg.h           |  32 +-
 drivers/net/wwan/t7xx/t7xx_state_monitor.c | 134 ++++-
 drivers/net/wwan/t7xx/t7xx_state_monitor.h |   3 +
 25 files changed, 1634 insertions(+), 105 deletions(-)
 create mode 100644 Documentation/networking/devlink/t7xx.rst
 create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.h
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.h
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.h

--
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA
  2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
@ 2023-01-06 16:26 ` m.chetan.kumar
  2023-01-06 17:56   ` Jesse Brandeburg
  2023-01-06 16:26 ` [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration m.chetan.kumar
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:26 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek,
	Madhusmita Sahu, Moises Veleta

From: Haijun Liu <haijun.liu@mediatek.com>

The t7xx device contains two Cross Layer DMA (CLDMA) interfaces to
communicate with AP and Modem processors respectively. So far only
MD-CLDMA was being used, this patch enables AP-CLDMA.

Rename small Application Processor (sAP) to AP.

Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Moises Veleta <moises.veleta@linux.intel.com>
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
--
v3:
 * No Change.
v2:
 * Reuse handshake_wq for AP work.
 * Remove AP trace port tx/rx channel id.
 * Rename t7xx_md_port_conf to t7xx_port_conf.
---
 drivers/net/wwan/t7xx/t7xx_hif_cldma.c     | 17 +++--
 drivers/net/wwan/t7xx/t7xx_hif_cldma.h     |  2 +-
 drivers/net/wwan/t7xx/t7xx_mhccif.h        |  1 +
 drivers/net/wwan/t7xx/t7xx_modem_ops.c     | 76 +++++++++++++++++-----
 drivers/net/wwan/t7xx/t7xx_modem_ops.h     |  2 +
 drivers/net/wwan/t7xx/t7xx_port.h          |  6 +-
 drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c |  8 ++-
 drivers/net/wwan/t7xx/t7xx_port_proxy.c    | 18 ++++-
 drivers/net/wwan/t7xx/t7xx_reg.h           |  2 +-
 drivers/net/wwan/t7xx/t7xx_state_monitor.c | 13 +++-
 drivers/net/wwan/t7xx/t7xx_state_monitor.h |  2 +
 11 files changed, 116 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
index aec3a18d44bd..4f56d8cc0aea 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
@@ -1066,13 +1066,18 @@ static void t7xx_hw_info_init(struct cldma_ctrl *md_ctrl)
 	struct t7xx_cldma_hw *hw_info = &md_ctrl->hw_info;
 	u32 phy_ao_base, phy_pd_base;
 
-	if (md_ctrl->hif_id != CLDMA_ID_MD)
-		return;
-
-	phy_ao_base = CLDMA1_AO_BASE;
-	phy_pd_base = CLDMA1_PD_BASE;
-	hw_info->phy_interrupt_id = CLDMA1_INT;
 	hw_info->hw_mode = MODE_BIT_64;
+
+	if (md_ctrl->hif_id == CLDMA_ID_MD) {
+		phy_ao_base = CLDMA1_AO_BASE;
+		phy_pd_base = CLDMA1_PD_BASE;
+		hw_info->phy_interrupt_id = CLDMA1_INT;
+	} else {
+		phy_ao_base = CLDMA0_AO_BASE;
+		phy_pd_base = CLDMA0_PD_BASE;
+		hw_info->phy_interrupt_id = CLDMA0_INT;
+	}
+
 	hw_info->ap_ao_base = t7xx_pcie_addr_transfer(pbase->pcie_ext_reg_base,
 						      pbase->pcie_dev_reg_trsl_addr, phy_ao_base);
 	hw_info->ap_pdn_base = t7xx_pcie_addr_transfer(pbase->pcie_ext_reg_base,
diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
index 47a35e552da7..4410bac6993a 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
@@ -34,7 +34,7 @@
 /**
  * enum cldma_id - Identifiers for CLDMA HW units.
  * @CLDMA_ID_MD: Modem control channel.
- * @CLDMA_ID_AP: Application Processor control channel (not used at the moment).
+ * @CLDMA_ID_AP: Application Processor control channel.
  * @CLDMA_NUM:   Number of CLDMA HW units available.
  */
 enum cldma_id {
diff --git a/drivers/net/wwan/t7xx/t7xx_mhccif.h b/drivers/net/wwan/t7xx/t7xx_mhccif.h
index 209b386bc088..20c50dce9fc3 100644
--- a/drivers/net/wwan/t7xx/t7xx_mhccif.h
+++ b/drivers/net/wwan/t7xx/t7xx_mhccif.h
@@ -25,6 +25,7 @@
 			 D2H_INT_EXCEPTION_CLEARQ_DONE |	\
 			 D2H_INT_EXCEPTION_ALLQ_RESET |		\
 			 D2H_INT_PORT_ENUM |			\
+			 D2H_INT_ASYNC_AP_HK |			\
 			 D2H_INT_ASYNC_MD_HK)
 
 void t7xx_mhccif_mask_set(struct t7xx_pci_dev *t7xx_dev, u32 val);
diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
index 7d0f5e4f0a78..24e7d491468e 100644
--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
@@ -44,6 +44,7 @@
 #include "t7xx_state_monitor.h"
 
 #define RT_ID_MD_PORT_ENUM	0
+#define RT_ID_AP_PORT_ENUM	1
 /* Modem feature query identification code - "ICCC" */
 #define MD_FEATURE_QUERY_ID	0x49434343
 
@@ -298,6 +299,7 @@ static void t7xx_md_exception(struct t7xx_modem *md, enum hif_ex_stage stage)
 	}
 
 	t7xx_cldma_exception(md->md_ctrl[CLDMA_ID_MD], stage);
+	t7xx_cldma_exception(md->md_ctrl[CLDMA_ID_AP], stage);
 
 	if (stage == HIF_EX_INIT)
 		t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_EXCEPTION_ACK);
@@ -426,7 +428,7 @@ static int t7xx_parse_host_rt_data(struct t7xx_fsm_ctl *ctl, struct t7xx_sys_inf
 		if (ft_spt_st != MTK_FEATURE_MUST_BE_SUPPORTED)
 			return -EINVAL;
 
-		if (i == RT_ID_MD_PORT_ENUM)
+		if (i == RT_ID_MD_PORT_ENUM || i == RT_ID_AP_PORT_ENUM)
 			t7xx_port_enum_msg_handler(ctl->md, rt_feature->data);
 	}
 
@@ -456,12 +458,12 @@ static int t7xx_core_reset(struct t7xx_modem *md)
 	return 0;
 }
 
-static void t7xx_core_hk_handler(struct t7xx_modem *md, struct t7xx_fsm_ctl *ctl,
+static void t7xx_core_hk_handler(struct t7xx_modem *md, struct t7xx_sys_info *core_info,
+				 struct t7xx_fsm_ctl *ctl,
 				 enum t7xx_fsm_event_state event_id,
 				 enum t7xx_fsm_event_state err_detect)
 {
 	struct t7xx_fsm_event *event = NULL, *event_next;
-	struct t7xx_sys_info *core_info = &md->core_md;
 	struct device *dev = &md->t7xx_dev->pdev->dev;
 	unsigned long flags;
 	int ret;
@@ -531,19 +533,33 @@ static void t7xx_md_hk_wq(struct work_struct *work)
 	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;
-	t7xx_core_hk_handler(md, ctl, FSM_EVENT_MD_HS2, FSM_EVENT_MD_HS2_EXIT);
+	t7xx_core_hk_handler(md, &md->core_md, ctl, FSM_EVENT_MD_HS2, FSM_EVENT_MD_HS2_EXIT);
+}
+
+static void t7xx_ap_hk_wq(struct work_struct *work)
+{
+	struct t7xx_modem *md = container_of(work, struct t7xx_modem, ap_handshake_work);
+	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;
+
+	 /* 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_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);
 }
 
 void t7xx_md_event_notify(struct t7xx_modem *md, enum md_event_id evt_id)
 {
 	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;
-	void __iomem *mhccif_base;
 	unsigned int int_sta;
 	unsigned long flags;
 
 	switch (evt_id) {
 	case FSM_PRE_START:
-		t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM);
+		t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM | D2H_INT_ASYNC_MD_HK |
+						   D2H_INT_ASYNC_AP_HK);
 		break;
 
 	case FSM_START:
@@ -556,16 +572,26 @@ void t7xx_md_event_notify(struct t7xx_modem *md, enum md_event_id evt_id)
 			ctl->exp_flg = true;
 			md->exp_id &= ~D2H_INT_EXCEPTION_INIT;
 			md->exp_id &= ~D2H_INT_ASYNC_MD_HK;
+			md->exp_id &= ~D2H_INT_ASYNC_AP_HK;
 		} else if (ctl->exp_flg) {
 			md->exp_id &= ~D2H_INT_ASYNC_MD_HK;
-		} else if (md->exp_id & D2H_INT_ASYNC_MD_HK) {
-			queue_work(md->handshake_wq, &md->handshake_work);
-			md->exp_id &= ~D2H_INT_ASYNC_MD_HK;
-			mhccif_base = md->t7xx_dev->base_addr.mhccif_rc_base;
-			iowrite32(D2H_INT_ASYNC_MD_HK, mhccif_base + REG_EP2RC_SW_INT_ACK);
-			t7xx_mhccif_mask_set(md->t7xx_dev, D2H_INT_ASYNC_MD_HK);
+			md->exp_id &= ~D2H_INT_ASYNC_AP_HK;
 		} else {
-			t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_ASYNC_MD_HK);
+			void __iomem *mhccif_base = md->t7xx_dev->base_addr.mhccif_rc_base;
+
+			if (md->exp_id & D2H_INT_ASYNC_MD_HK) {
+				queue_work(md->handshake_wq, &md->handshake_work);
+				md->exp_id &= ~D2H_INT_ASYNC_MD_HK;
+				iowrite32(D2H_INT_ASYNC_MD_HK, mhccif_base + REG_EP2RC_SW_INT_ACK);
+				t7xx_mhccif_mask_set(md->t7xx_dev, D2H_INT_ASYNC_MD_HK);
+			}
+
+			if (md->exp_id & D2H_INT_ASYNC_AP_HK) {
+				queue_work(md->handshake_wq, &md->ap_handshake_work);
+				md->exp_id &= ~D2H_INT_ASYNC_AP_HK;
+				iowrite32(D2H_INT_ASYNC_AP_HK, mhccif_base + REG_EP2RC_SW_INT_ACK);
+				t7xx_mhccif_mask_set(md->t7xx_dev, D2H_INT_ASYNC_AP_HK);
+			}
 		}
 		spin_unlock_irqrestore(&md->exp_lock, flags);
 
@@ -578,6 +604,7 @@ void t7xx_md_event_notify(struct t7xx_modem *md, enum md_event_id evt_id)
 
 	case FSM_READY:
 		t7xx_mhccif_mask_set(md->t7xx_dev, D2H_INT_ASYNC_MD_HK);
+		t7xx_mhccif_mask_set(md->t7xx_dev, D2H_INT_ASYNC_AP_HK);
 		break;
 
 	default:
@@ -629,6 +656,12 @@ static struct t7xx_modem *t7xx_md_alloc(struct t7xx_pci_dev *t7xx_dev)
 	md->core_md.feature_set[RT_ID_MD_PORT_ENUM] &= ~FEATURE_MSK;
 	md->core_md.feature_set[RT_ID_MD_PORT_ENUM] |=
 		FIELD_PREP(FEATURE_MSK, MTK_FEATURE_MUST_BE_SUPPORTED);
+
+	INIT_WORK(&md->ap_handshake_work, t7xx_ap_hk_wq);
+	md->core_ap.feature_set[RT_ID_AP_PORT_ENUM] &= ~FEATURE_MSK;
+	md->core_ap.feature_set[RT_ID_AP_PORT_ENUM] |=
+		FIELD_PREP(FEATURE_MSK, MTK_FEATURE_MUST_BE_SUPPORTED);
+
 	return md;
 }
 
@@ -640,6 +673,7 @@ int t7xx_md_reset(struct t7xx_pci_dev *t7xx_dev)
 	md->exp_id = 0;
 	t7xx_fsm_reset(md);
 	t7xx_cldma_reset(md->md_ctrl[CLDMA_ID_MD]);
+	t7xx_cldma_reset(md->md_ctrl[CLDMA_ID_AP]);
 	t7xx_port_proxy_reset(md->port_prox);
 	md->md_init_finish = true;
 	return t7xx_core_reset(md);
@@ -669,6 +703,10 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev)
 	if (ret)
 		goto err_destroy_hswq;
 
+	ret = t7xx_cldma_alloc(CLDMA_ID_AP, t7xx_dev);
+	if (ret)
+		goto err_destroy_hswq;
+
 	ret = t7xx_fsm_init(md);
 	if (ret)
 		goto err_destroy_hswq;
@@ -681,12 +719,16 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev)
 	if (ret)
 		goto err_uninit_ccmni;
 
-	ret = t7xx_port_proxy_init(md);
+	ret = t7xx_cldma_init(md->md_ctrl[CLDMA_ID_AP]);
 	if (ret)
 		goto err_uninit_md_cldma;
 
+	ret = t7xx_port_proxy_init(md);
+	if (ret)
+		goto err_uninit_ap_cldma;
+
 	ret = t7xx_fsm_append_cmd(md->fsm_ctl, FSM_CMD_START, 0);
-	if (ret) /* fsm_uninit flushes cmd queue */
+	if (ret) /* t7xx_fsm_uninit() flushes cmd queue */
 		goto err_uninit_proxy;
 
 	t7xx_md_sys_sw_init(t7xx_dev);
@@ -696,6 +738,9 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev)
 err_uninit_proxy:
 	t7xx_port_proxy_uninit(md->port_prox);
 
+err_uninit_ap_cldma:
+	t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_AP]);
+
 err_uninit_md_cldma:
 	t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_MD]);
 
@@ -722,6 +767,7 @@ void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev)
 
 	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]);
 	t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_MD]);
 	t7xx_ccmni_exit(t7xx_dev);
 	t7xx_fsm_uninit(md);
diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.h b/drivers/net/wwan/t7xx/t7xx_modem_ops.h
index 7469ed636ae8..abe633cf7adc 100644
--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.h
+++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.h
@@ -66,10 +66,12 @@ struct t7xx_modem {
 	struct cldma_ctrl		*md_ctrl[CLDMA_NUM];
 	struct t7xx_pci_dev		*t7xx_dev;
 	struct t7xx_sys_info		core_md;
+	struct t7xx_sys_info		core_ap;
 	bool				md_init_finish;
 	bool				rgu_irq_asserted;
 	struct workqueue_struct		*handshake_wq;
 	struct work_struct		handshake_work;
+	struct work_struct		ap_handshake_work;
 	struct t7xx_fsm_ctl		*fsm_ctl;
 	struct port_proxy		*port_prox;
 	unsigned int			exp_id;
diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h
index 8ea9079af997..4ae8a00a8532 100644
--- a/drivers/net/wwan/t7xx/t7xx_port.h
+++ b/drivers/net/wwan/t7xx/t7xx_port.h
@@ -36,9 +36,13 @@
 /* Channel ID and Message ID definitions.
  * The channel number consists of peer_id(15:12) , channel_id(11:0)
  * peer_id:
- * 0:reserved, 1: to sAP, 2: to MD
+ * 0:reserved, 1: to AP, 2: to MD
  */
 enum port_ch {
+	/* to AP */
+	PORT_CH_AP_CONTROL_RX = 0x1000,
+	PORT_CH_AP_CONTROL_TX = 0x1001,
+
 	/* to MD */
 	PORT_CH_CONTROL_RX = 0x2000,
 	PORT_CH_CONTROL_TX = 0x2001,
diff --git a/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c b/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c
index 68430b130a67..ae632ef96698 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c
@@ -167,8 +167,12 @@ static int control_msg_handler(struct t7xx_port *port, struct sk_buff *skb)
 	case CTL_ID_HS2_MSG:
 		skb_pull(skb, sizeof(*ctrl_msg_h));
 
-		if (port_conf->rx_ch == PORT_CH_CONTROL_RX) {
-			ret = t7xx_fsm_append_event(ctl, FSM_EVENT_MD_HS2, skb->data,
+		if (port_conf->rx_ch == PORT_CH_CONTROL_RX ||
+		    port_conf->rx_ch == PORT_CH_AP_CONTROL_RX) {
+			int event = port_conf->rx_ch == PORT_CH_CONTROL_RX ?
+				    FSM_EVENT_MD_HS2 : FSM_EVENT_AP_HS2;
+
+			ret = t7xx_fsm_append_event(ctl, event, skb->data,
 						    le32_to_cpu(ctrl_msg_h->data_length));
 			if (ret)
 				dev_err(port->dev, "Failed to append Handshake 2 event");
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
index 894b1d11b2c9..274846d39fbf 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
@@ -48,7 +48,7 @@
 	     i < (proxy)->port_count;		\
 	     i++, (p) = &(proxy)->ports[i])
 
-static const struct t7xx_port_conf t7xx_md_port_conf[] = {
+static const struct t7xx_port_conf t7xx_port_conf[] = {
 	{
 		.tx_ch = PORT_CH_UART2_TX,
 		.rx_ch = PORT_CH_UART2_RX,
@@ -89,6 +89,14 @@ static const struct t7xx_port_conf t7xx_md_port_conf[] = {
 		.path_id = CLDMA_ID_MD,
 		.ops = &ctl_port_ops,
 		.name = "t7xx_ctrl",
+	}, {
+		.tx_ch = PORT_CH_AP_CONTROL_TX,
+		.rx_ch = PORT_CH_AP_CONTROL_RX,
+		.txq_index = Q_IDX_CTRL,
+		.rxq_index = Q_IDX_CTRL,
+		.path_id = CLDMA_ID_AP,
+		.ops = &ctl_port_ops,
+		.name = "t7xx_ap_ctrl",
 	},
 };
 
@@ -428,6 +436,9 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
 		if (port_conf->tx_ch == PORT_CH_CONTROL_TX)
 			md->core_md.ctl_port = port;
 
+		if (port_conf->tx_ch == PORT_CH_AP_CONTROL_TX)
+			md->core_ap.ctl_port = port;
+
 		port->t7xx_dev = md->t7xx_dev;
 		port->dev = &md->t7xx_dev->pdev->dev;
 		spin_lock_init(&port->port_update_lock);
@@ -442,7 +453,7 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
 
 static int t7xx_proxy_alloc(struct t7xx_modem *md)
 {
-	unsigned int port_count = ARRAY_SIZE(t7xx_md_port_conf);
+	unsigned int port_count = ARRAY_SIZE(t7xx_port_conf);
 	struct device *dev = &md->t7xx_dev->pdev->dev;
 	struct port_proxy *port_prox;
 	int i;
@@ -456,7 +467,7 @@ static int t7xx_proxy_alloc(struct t7xx_modem *md)
 	port_prox->dev = dev;
 
 	for (i = 0; i < port_count; i++)
-		port_prox->ports[i].port_conf = &t7xx_md_port_conf[i];
+		port_prox->ports[i].port_conf = &t7xx_port_conf[i];
 
 	port_prox->port_count = port_count;
 	t7xx_proxy_init_all_ports(md);
@@ -481,6 +492,7 @@ int t7xx_port_proxy_init(struct t7xx_modem *md)
 	if (ret)
 		return ret;
 
+	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_AP], t7xx_port_proxy_recv_skb);
 	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb);
 	return 0;
 }
diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h
index 7c1b81091a0f..c41d7d094c08 100644
--- a/drivers/net/wwan/t7xx/t7xx_reg.h
+++ b/drivers/net/wwan/t7xx/t7xx_reg.h
@@ -56,7 +56,7 @@
 #define D2H_INT_RESUME_ACK			BIT(12)
 #define D2H_INT_SUSPEND_ACK_AP			BIT(13)
 #define D2H_INT_RESUME_ACK_AP			BIT(14)
-#define D2H_INT_ASYNC_SAP_HK			BIT(15)
+#define D2H_INT_ASYNC_AP_HK			BIT(15)
 #define D2H_INT_ASYNC_MD_HK			BIT(16)
 
 /* Register base */
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 0bcca08ff2bd..80edb8e75a6a 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -285,8 +285,9 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl)
 	t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_FOR_HS1);
 	t7xx_md_event_notify(md, FSM_START);
 
-	wait_event_interruptible_timeout(ctl->async_hk_wq, md->core_md.ready || ctl->exp_flg,
-					 HZ * 60);
+	wait_event_interruptible_timeout(ctl->async_hk_wq,
+					 (md->core_md.ready && md->core_ap.ready) ||
+					  ctl->exp_flg, HZ * 60);
 	dev = &md->t7xx_dev->pdev->dev;
 
 	if (ctl->exp_flg)
@@ -297,6 +298,13 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl)
 		if (md->core_md.handshake_ongoing)
 			t7xx_fsm_append_event(ctl, FSM_EVENT_MD_HS2_EXIT, NULL, 0);
 
+		fsm_routine_exception(ctl, NULL, EXCEPTION_HS_TIMEOUT);
+		return -ETIMEDOUT;
+	} else if (!md->core_ap.ready) {
+		dev_err(dev, "AP handshake timeout\n");
+		if (md->core_ap.handshake_ongoing)
+			t7xx_fsm_append_event(ctl, FSM_EVENT_AP_HS2_EXIT, NULL, 0);
+
 		fsm_routine_exception(ctl, NULL, EXCEPTION_HS_TIMEOUT);
 		return -ETIMEDOUT;
 	}
@@ -335,6 +343,7 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
 		return;
 	}
 
+	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
 	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
 	fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl));
 }
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
index b1af0259d4c5..b6e76f3903c8 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
@@ -38,10 +38,12 @@ enum t7xx_fsm_state {
 enum t7xx_fsm_event_state {
 	FSM_EVENT_INVALID,
 	FSM_EVENT_MD_HS2,
+	FSM_EVENT_AP_HS2,
 	FSM_EVENT_MD_EX,
 	FSM_EVENT_MD_EX_REC_OK,
 	FSM_EVENT_MD_EX_PASS,
 	FSM_EVENT_MD_HS2_EXIT,
+	FSM_EVENT_AP_HS2_EXIT,
 	FSM_EVENT_MAX
 };
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration
  2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
  2023-01-06 16:26 ` [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA m.chetan.kumar
@ 2023-01-06 16:26 ` m.chetan.kumar
  2023-01-06 18:31   ` Jesse Brandeburg
  2023-01-06 16:27 ` [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan m.chetan.kumar
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:26 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek,
	Madhusmita Sahu

From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

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.

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

Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
--
v3:
 * No Change.
v2:
 * Move recv_skb handler to cldma_queue.
 * Drop cldma_queue_type.
 * Restore prototype of t7xx_port_send_raw_skb().
 * Remove PORT_CFG_ID_INVALID check in t7xx_port_proxy_set_cfg().
 * Add space before */.
 * Drop unnecessary logs.
 * Use WARN_ON on early port.
 * Use new MISC_DEV_STATUS_INVALID instead of MISC_DEV_STATUS.
 * Use macros instead of const identifiers.
 * Change ports member type from pointer to array type.
 * Prefix LK_EVENT_XX with MISC prefix.
 * Use t7xx prefix for device_stage enums.
 * Correct log messages.
 * Don’t override pkt_size for non-download port under dedicated Queue.
 * Drop cldma_txq_rxq_ids.
 * Use macro for txq/rxq index.
 * Use warn_on for rxq_idx comparison.
 * Drop t7xx_port_proxy_get_port_by_name().
 * Replace fsm poll with read_poll_timeout().
 * Use "\n" consistently across log message.
 * Remove local var _dev prefixes in fsm_routine_start().
 * Use max_t.
---
 drivers/net/wwan/t7xx/t7xx_hif_cldma.c     | 47 ++++++++----
 drivers/net/wwan/t7xx/t7xx_hif_cldma.h     | 18 +++--
 drivers/net/wwan/t7xx/t7xx_modem_ops.c     |  4 +-
 drivers/net/wwan/t7xx/t7xx_port.h          |  4 +
 drivers/net/wwan/t7xx/t7xx_port_proxy.c    | 89 +++++++++++++++++++---
 drivers/net/wwan/t7xx/t7xx_port_proxy.h    | 12 ++-
 drivers/net/wwan/t7xx/t7xx_port_wwan.c     |  3 +-
 drivers/net/wwan/t7xx/t7xx_reg.h           | 24 +++++-
 drivers/net/wwan/t7xx/t7xx_state_monitor.c | 86 ++++++++++++++++++---
 drivers/net/wwan/t7xx/t7xx_state_monitor.h |  1 +
 10 files changed, 237 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
index 4f56d8cc0aea..12c9e9cba74a 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
@@ -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;
@@ -1331,9 +1347,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);
 }
 
diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
index 4410bac6993a..5453cfecbe19 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h
@@ -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);
diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
index 24e7d491468e..cbd65aa48721 100644
--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
@@ -529,7 +529,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;
@@ -544,7 +544,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);
diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h
index 4ae8a00a8532..09acb1ef144d 100644
--- a/drivers/net/wwan/t7xx/t7xx_port.h
+++ b/drivers/net/wwan/t7xx/t7xx_port.h
@@ -75,6 +75,8 @@ enum port_ch {
 	PORT_CH_DSS6_TX = 0x20df,
 	PORT_CH_DSS7_RX = 0x20e0,
 	PORT_CH_DSS7_TX = 0x20e1,
+
+	PORT_CH_ID_UNIMPORTANT = 0xffff,
 };
 
 struct t7xx_port;
@@ -135,9 +137,11 @@ 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_raw_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_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
index 274846d39fbf..b457e8da098e 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
@@ -100,6 +100,18 @@ static const struct t7xx_port_conf t7xx_port_conf[] = {
 	},
 };
 
+static struct t7xx_port_conf t7xx_early_port_conf[] = {
+	{
+		.tx_ch = PORT_CH_ID_UNIMPORTANT,
+		.rx_ch = PORT_CH_ID_UNIMPORTANT,
+		.txq_index = CLDMA_Q_IDX_DUMP,
+		.rxq_index = CLDMA_Q_IDX_DUMP,
+		.txq_exp_index = CLDMA_Q_IDX_DUMP,
+		.rxq_exp_index = CLDMA_Q_IDX_DUMP,
+		.path_id = CLDMA_ID_AP,
+	},
+};
+
 static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch)
 {
 	const struct t7xx_port_conf *port_conf;
@@ -214,7 +226,17 @@ int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
 	return 0;
 }
 
-static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
+int t7xx_get_port_mtu(struct t7xx_port *port)
+{
+	enum cldma_id path_id = port->port_conf->path_id;
+	int tx_qno = t7xx_port_get_queue_no(port);
+	struct cldma_ctrl *md_ctrl;
+
+	md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
+	return md_ctrl->tx_ring[tx_qno].pkt_size;
+}
+
+int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
 {
 	enum cldma_id path_id = port->port_conf->path_id;
 	struct cldma_ctrl *md_ctrl;
@@ -329,6 +351,30 @@ static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
 	}
 }
 
+int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb)
+{
+	struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
+	struct port_proxy *port_prox = t7xx_dev->md->port_prox;
+	const struct t7xx_port_conf *port_conf;
+	struct t7xx_port *port;
+	int ret;
+
+	port = &port_prox->ports[0];
+	if (WARN_ON(port->port_conf->rxq_index != queue->index)) {
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
+
+	port_conf = port->port_conf;
+	ret = port_conf->ops->recv_skb(port, skb);
+	if (ret < 0 && ret != -ENOBUFS) {
+		dev_err(port->dev, "drop on RX ch %d, %d\n", port_conf->rx_ch, ret);
+		dev_kfree_skb_any(skb);
+	}
+
+	return ret;
+}
+
 static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev,
 						   struct cldma_queue *queue, u16 channel)
 {
@@ -359,7 +405,7 @@ static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev
  ** 0		- Packet consumed.
  ** -ERROR	- Failed to process skb.
  */
-static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb)
+int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb)
 {
 	struct ccci_header *ccci_h = (struct ccci_header *)skb->data;
 	struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
@@ -451,26 +497,47 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
 	t7xx_proxy_setup_ch_mapping(port_prox);
 }
 
+void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id)
+{
+	struct port_proxy *port_prox = md->port_prox;
+	const struct t7xx_port_conf *port_conf;
+	u32 port_count;
+	int i;
+
+	t7xx_port_proxy_uninit(port_prox);
+
+	if (cfg_id == PORT_CFG_ID_EARLY) {
+		port_conf = t7xx_early_port_conf;
+		port_count = ARRAY_SIZE(t7xx_early_port_conf);
+	} else {
+		port_conf = t7xx_port_conf;
+		port_count = ARRAY_SIZE(t7xx_port_conf);
+	}
+
+	for (i = 0; i < port_count; i++)
+		port_prox->ports[i].port_conf = &port_conf[i];
+
+	port_prox->cfg_id = cfg_id;
+	port_prox->port_count = port_count;
+	t7xx_proxy_init_all_ports(md);
+}
+
 static int t7xx_proxy_alloc(struct t7xx_modem *md)
 {
+	u32 early_port_count = ARRAY_SIZE(t7xx_early_port_conf);
 	unsigned int port_count = ARRAY_SIZE(t7xx_port_conf);
 	struct device *dev = &md->t7xx_dev->pdev->dev;
 	struct port_proxy *port_prox;
-	int i;
 
-	port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * port_count,
-				 GFP_KERNEL);
+	port_count = max_t(u32, port_count, early_port_count);
+	port_prox = devm_kzalloc(dev, struct_size(port_prox, ports, port_count), GFP_KERNEL);
 	if (!port_prox)
 		return -ENOMEM;
 
 	md->port_prox = port_prox;
 	port_prox->dev = dev;
+	t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_EARLY);
 
-	for (i = 0; i < port_count; i++)
-		port_prox->ports[i].port_conf = &t7xx_port_conf[i];
-
-	port_prox->port_count = port_count;
-	t7xx_proxy_init_all_ports(md);
 	return 0;
 }
 
@@ -492,8 +559,6 @@ int t7xx_port_proxy_init(struct t7xx_modem *md)
 	if (ret)
 		return ret;
 
-	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_AP], t7xx_port_proxy_recv_skb);
-	t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb);
 	return 0;
 }
 
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
index 81d059fbc0fb..0f3fb53259b7 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
@@ -31,12 +31,19 @@
 #define RX_QUEUE_MAXLEN		32
 #define CTRL_QUEUE_MAXLEN	16
 
+enum port_cfg_id {
+	PORT_CFG_ID_INVALID,
+	PORT_CFG_ID_NORMAL,
+	PORT_CFG_ID_EARLY,
+};
+
 struct port_proxy {
 	int			port_count;
 	struct list_head	rx_ch_ports[PORT_CH_ID_MASK + 1];
 	struct list_head	queue_ports[CLDMA_NUM][MTK_QUEUES];
 	struct device		*dev;
-	struct t7xx_port	ports[];
+	enum port_cfg_id	cfg_id;
+	struct t7xx_port        ports[];
 };
 
 struct ccci_header {
@@ -98,5 +105,8 @@ void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int
 int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg);
 int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id,
 				       bool en_flag);
+void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id);
+int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb);
+int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb);
 
 #endif /* __T7XX_PORT_PROXY_H__ */
diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c
index 24bd21942403..33fa8c22598a 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c
@@ -54,7 +54,7 @@ static void t7xx_port_ctrl_stop(struct wwan_port *port)
 static int t7xx_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
 {
 	struct t7xx_port *port_private = wwan_port_get_drvdata(port);
-	size_t len, offset, chunk_len = 0, txq_mtu = CLDMA_MTU;
+	size_t len, offset, chunk_len = 0, txq_mtu;
 	const struct t7xx_port_conf *port_conf;
 	struct t7xx_fsm_ctl *ctl;
 	enum md_state md_state;
@@ -72,6 +72,7 @@ static int t7xx_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
 		return -ENODEV;
 	}
 
+	txq_mtu = t7xx_get_port_mtu(port_private);
 	for (offset = 0; offset < len; offset += chunk_len) {
 		struct sk_buff *skb_ccci;
 		int ret;
diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h
index c41d7d094c08..44352cd02460 100644
--- a/drivers/net/wwan/t7xx/t7xx_reg.h
+++ b/drivers/net/wwan/t7xx/t7xx_reg.h
@@ -102,10 +102,28 @@ enum t7xx_pm_resume_state {
 };
 
 #define T7XX_PCIE_MISC_DEV_STATUS		0x0d1c
-#define MISC_STAGE_MASK				GENMASK(2, 0)
-#define MISC_RESET_TYPE_PLDR			BIT(26)
 #define MISC_RESET_TYPE_FLDR			BIT(27)
-#define LINUX_STAGE				4
+#define MISC_RESET_TYPE_PLDR			BIT(26)
+#define MISC_DEV_STATUS_MASK			GENMASK(15, 0)
+#define MISC_DEV_STATUS_INVALID			GENMASK(15, 0)
+#define MISC_LK_EVENT_MASK			GENMASK(11, 8)
+
+enum lk_event_id {
+	LK_EVENT_NORMAL = 0,
+	LK_EVENT_CREATE_PD_PORT = 1,
+	LK_EVENT_CREATE_POST_DL_PORT = 2,
+	LK_EVENT_RESET = 7,
+};
+
+#define MISC_STAGE_MASK				GENMASK(2, 0)
+
+enum t7xx_device_stage {
+	T7XX_DEV_STAGE_INIT = 0,
+	T7XX_DEV_STAGE_BROM_PRE = 1,
+	T7XX_DEV_STAGE_BROM_POST = 2,
+	T7XX_DEV_STAGE_LK = 3,
+	T7XX_DEV_STAGE_LINUX = 4,
+};
 
 #define T7XX_PCIE_RESOURCE_STATUS		0x0d28
 #define T7XX_PCIE_RESOURCE_STS_MSK		GENMASK(4, 0)
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 80edb8e75a6a..76fb5d57d4d7 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -206,6 +206,34 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm
 		fsm_finish_command(ctl, cmd, 0);
 }
 
+static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status)
+{
+	struct t7xx_modem *md = ctl->md;
+	struct cldma_ctrl *md_ctrl;
+	enum lk_event_id lk_event;
+	struct device *dev;
+
+	dev = &md->t7xx_dev->pdev->dev;
+	lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status);
+	switch (lk_event) {
+	case LK_EVENT_NORMAL:
+	case LK_EVENT_RESET:
+		break;
+
+	case LK_EVENT_CREATE_PD_PORT:
+		md_ctrl = md->md_ctrl[CLDMA_ID_AP];
+		t7xx_cldma_hif_hw_init(md_ctrl);
+		t7xx_cldma_stop(md_ctrl);
+		t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG);
+		t7xx_cldma_start(md_ctrl);
+		break;
+
+	default:
+		dev_err(dev, "Invalid LK event %d\n", lk_event);
+		break;
+	}
+}
+
 static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl)
 {
 	ctl->curr_state = FSM_STATE_STOPPED;
@@ -317,8 +345,9 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl)
 static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd)
 {
 	struct t7xx_modem *md = ctl->md;
-	u32 dev_status;
-	int ret;
+	struct device *dev;
+	u32 status, stage;
+	int ret = 0;
 
 	if (!md)
 		return;
@@ -329,23 +358,55 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
 		return;
 	}
 
+	dev = &md->t7xx_dev->pdev->dev;
 	ctl->curr_state = FSM_STATE_PRE_START;
 	t7xx_md_event_notify(md, FSM_PRE_START);
 
-	ret = read_poll_timeout(ioread32, dev_status,
-				(dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 2000000,
-				false, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS);
+	ret = read_poll_timeout(ioread32, status,
+				((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LINUX) ||
+				((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LK), 100000,
+				20000000, false, IREG_BASE(md->t7xx_dev) +
+				T7XX_PCIE_MISC_DEV_STATUS);
+
 	if (ret) {
-		struct device *dev = &md->t7xx_dev->pdev->dev;
+		ret = -ETIMEDOUT;
+		dev_err(dev, "read poll %d\n", ret);
+		goto finish_command;
+	}
 
-		fsm_finish_command(ctl, cmd, -ETIMEDOUT);
-		dev_err(dev, "Invalid device status 0x%lx\n", dev_status & MISC_STAGE_MASK);
-		return;
+	if (status != ctl->prev_status) {
+		stage = FIELD_GET(MISC_STAGE_MASK, status);
+		switch (stage) {
+		case T7XX_DEV_STAGE_INIT:
+		case T7XX_DEV_STAGE_BROM_PRE:
+		case T7XX_DEV_STAGE_BROM_POST:
+			dev_info(dev, "BROM_STAGE Entered\n");
+			ret = t7xx_fsm_append_cmd(ctl, FSM_CMD_START, 0);
+			break;
+
+		case T7XX_DEV_STAGE_LK:
+			dev_info(dev, "LK_STAGE Entered\n");
+			t7xx_lk_stage_event_handling(ctl, status);
+			break;
+
+		case T7XX_DEV_STAGE_LINUX:
+			dev_info(dev, "LINUX_STAGE Entered\n");
+			t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
+			t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
+			t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM |
+					     D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK);
+			t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL);
+			ret = fsm_routine_starting(ctl);
+			break;
+
+		default:
+			break;
+		}
+		ctl->prev_status = status;
 	}
 
-	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
-	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
-	fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl));
+finish_command:
+	fsm_finish_command(ctl, cmd, ret);
 }
 
 static int fsm_main_thread(void *data)
@@ -516,6 +577,7 @@ void t7xx_fsm_reset(struct t7xx_modem *md)
 	fsm_flush_event_cmd_qs(ctl);
 	ctl->curr_state = FSM_STATE_STOPPED;
 	ctl->exp_flg = false;
+	ctl->prev_status = 0;
 }
 
 int t7xx_fsm_init(struct t7xx_modem *md)
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
index b6e76f3903c8..5e8012567ba1 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
@@ -96,6 +96,7 @@ struct t7xx_fsm_ctl {
 	bool			exp_flg;
 	spinlock_t		notifier_lock;		/* Protects notifier list */
 	struct list_head	notifier_list;
+	u32                     prev_status;
 };
 
 struct t7xx_fsm_event {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan
  2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
  2023-01-06 16:26 ` [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA m.chetan.kumar
  2023-01-06 16:26 ` [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration m.chetan.kumar
@ 2023-01-06 16:27 ` m.chetan.kumar
  2023-01-06 18:42   ` Jesse Brandeburg
  2023-01-06 16:27 ` [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection m.chetan.kumar
  2023-01-06 16:28 ` [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation m.chetan.kumar
  4 siblings, 1 reply; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:27 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek,
	Madhusmita Sahu

From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

PCI rescan module implements "rescan work queue".
In firmware flashing or coredump collection procedure
WWAN device is programmed to boot in fastboot mode and
a work item is scheduled for removal & detection.

The WWAN device is reset using APCI call as part driver
removal flow. Work queue rescans pci bus at fixed interval
for device detection, later when device is detect work queue
exits.

Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
--
v3:
 * No Change.
v2:
 * Drop empty line inside critical sections.
 * Correct log message.
 * Correct logic inside t7xx_always_match().
 * Drop hp_enable changes.
 * Drop g_ prefix from t7xx_rescan_ctx.
 * Use tab before comment in struct decl.
 * Remove extra white space.
 * Drop modem exception state check.
 * Crit section newlines.
 * Remove unnecessary header files inclusion.
 * Drop spinlock around reset and rescan flow.
---
 drivers/net/wwan/t7xx/Makefile          |  3 +-
 drivers/net/wwan/t7xx/t7xx_modem_ops.c  |  3 +
 drivers/net/wwan/t7xx/t7xx_pci.c        | 56 ++++++++++++++-
 drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 96 +++++++++++++++++++++++++
 drivers/net/wwan/t7xx/t7xx_pci_rescan.h | 28 ++++++++
 5 files changed, 184 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.h

diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile
index 268ff9e87e5b..ba5c607404a4 100644
--- a/drivers/net/wwan/t7xx/Makefile
+++ b/drivers/net/wwan/t7xx/Makefile
@@ -17,7 +17,8 @@ mtk_t7xx-y:=	t7xx_pci.o \
 		t7xx_hif_dpmaif_tx.o \
 		t7xx_hif_dpmaif_rx.o  \
 		t7xx_dpmaif.o \
-		t7xx_netdev.o
+		t7xx_netdev.o \
+		t7xx_pci_rescan.o
 
 mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \
 		t7xx_port_trace.o \
diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
index cbd65aa48721..2fcaea4694ba 100644
--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
@@ -37,6 +37,7 @@
 #include "t7xx_modem_ops.h"
 #include "t7xx_netdev.h"
 #include "t7xx_pci.h"
+#include "t7xx_pci_rescan.h"
 #include "t7xx_pcie_mac.h"
 #include "t7xx_port.h"
 #include "t7xx_port_proxy.h"
@@ -194,6 +195,8 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data)
 
 	msleep(RGU_RESET_DELAY_MS);
 	t7xx_reset_device_via_pmic(t7xx_dev);
+	t7xx_rescan_queue_work(t7xx_dev->pdev);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c
index 871f2a27a398..1e953ec7dd00 100644
--- a/drivers/net/wwan/t7xx/t7xx_pci.c
+++ b/drivers/net/wwan/t7xx/t7xx_pci.c
@@ -38,6 +38,7 @@
 #include "t7xx_mhccif.h"
 #include "t7xx_modem_ops.h"
 #include "t7xx_pci.h"
+#include "t7xx_pci_rescan.h"
 #include "t7xx_pcie_mac.h"
 #include "t7xx_reg.h"
 #include "t7xx_state_monitor.h"
@@ -715,6 +716,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		return ret;
 	}
 
+	t7xx_rescan_done();
 	t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
 	t7xx_pcie_mac_interrupts_en(t7xx_dev);
 
@@ -754,7 +756,59 @@ static struct pci_driver t7xx_pci_driver = {
 	.shutdown = t7xx_pci_shutdown,
 };
 
-module_pci_driver(t7xx_pci_driver);
+static int __init t7xx_pci_init(void)
+{
+	int ret;
+
+	t7xx_pci_dev_rescan();
+	ret = t7xx_rescan_init();
+	if (ret) {
+		pr_err("Failed to init t7xx rescan work\n");
+		return ret;
+	}
+
+	return pci_register_driver(&t7xx_pci_driver);
+}
+module_init(t7xx_pci_init);
+
+static int t7xx_always_match(struct device *dev, const void *data)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	const struct pci_device_id *id = data;
+
+	if (pci_match_id(id, pdev))
+		return 1;
+
+	return 0;
+}
+
+static void __exit t7xx_pci_cleanup(void)
+{
+	int remove_flag = 0;
+	struct device *dev;
+
+	dev = driver_find_device(&t7xx_pci_driver.driver, NULL, &t7xx_pci_table[0],
+				 t7xx_always_match);
+	if (dev) {
+		pr_debug("unregister t7xx PCIe driver while device is still exist.\n");
+		put_device(dev);
+		remove_flag = 1;
+	} else {
+		pr_debug("no t7xx PCIe driver found.\n");
+	}
+
+	pci_lock_rescan_remove();
+	pci_unregister_driver(&t7xx_pci_driver);
+	pci_unlock_rescan_remove();
+
+	t7xx_rescan_deinit();
+	if (remove_flag) {
+		pr_debug("remove t7xx PCI device\n");
+		pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
+	}
+}
+
+module_exit(t7xx_pci_cleanup);
 
 MODULE_AUTHOR("MediaTek Inc");
 MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
new file mode 100644
index 000000000000..67f13c035846
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, MediaTek Inc.
+ * Copyright (c) 2021-2023, Intel Corporation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":t7xx:%s: " fmt, __func__
+#define dev_fmt(fmt) "t7xx: " fmt
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+#include "t7xx_pci.h"
+#include "t7xx_pci_rescan.h"
+
+static struct remove_rescan_context t7xx_rescan_ctx;
+
+void t7xx_pci_dev_rescan(void)
+{
+	struct pci_bus *b = NULL;
+
+	pci_lock_rescan_remove();
+	while ((b = pci_find_next_bus(b)))
+		pci_rescan_bus(b);
+	pci_unlock_rescan_remove();
+}
+
+void t7xx_rescan_done(void)
+{
+	if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
+		atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
+		pr_debug("Rescan probe\n");
+	} else {
+		pr_debug("Init probe\n");
+	}
+}
+
+static void t7xx_remove_rescan(struct work_struct *work)
+{
+	int num_retries = RESCAN_RETRIES;
+	struct pci_dev *pdev;
+
+	atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
+	pdev = t7xx_rescan_ctx.dev;
+
+	if (pdev) {
+		pci_stop_and_remove_bus_device_locked(pdev);
+		pr_debug("start remove and rescan flow\n");
+	}
+
+	do {
+		t7xx_pci_dev_rescan();
+
+		if (atomic_read(&t7xx_rescan_ctx.rescan_done))
+			break;
+
+		msleep(DELAY_RESCAN_MTIME);
+	} while (num_retries--);
+}
+
+void t7xx_rescan_queue_work(struct pci_dev *pdev)
+{
+	if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
+		dev_err(&pdev->dev, "Rescan failed\n");
+		return;
+	}
+
+	t7xx_rescan_ctx.dev = pdev;
+	queue_work(t7xx_rescan_ctx.pcie_rescan_wq, &t7xx_rescan_ctx.service_task);
+}
+
+int t7xx_rescan_init(void)
+{
+	atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
+	t7xx_rescan_ctx.dev = NULL;
+
+	t7xx_rescan_ctx.pcie_rescan_wq = create_singlethread_workqueue(MTK_RESCAN_WQ);
+	if (!t7xx_rescan_ctx.pcie_rescan_wq) {
+		pr_err("Failed to create workqueue: %s\n", MTK_RESCAN_WQ);
+		return -ENOMEM;
+	}
+
+	INIT_WORK(&t7xx_rescan_ctx.service_task, t7xx_remove_rescan);
+
+	return 0;
+}
+
+void t7xx_rescan_deinit(void)
+{
+	t7xx_rescan_ctx.dev = NULL;
+	atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
+	cancel_work_sync(&t7xx_rescan_ctx.service_task);
+	destroy_workqueue(t7xx_rescan_ctx.pcie_rescan_wq);
+}
diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
new file mode 100644
index 000000000000..80b25c44151c
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2021, MediaTek Inc.
+ * Copyright (c) 2021-2023, Intel Corporation.
+ */
+
+#ifndef __T7XX_PCI_RESCAN_H__
+#define __T7XX_PCI_RESCAN_H__
+
+#define MTK_RESCAN_WQ "mtk_rescan_wq"
+
+#define DELAY_RESCAN_MTIME 1000
+#define RESCAN_RETRIES 35
+
+struct remove_rescan_context {
+	struct work_struct service_task;
+	struct workqueue_struct *pcie_rescan_wq;
+	struct pci_dev *dev;
+	atomic_t rescan_done;
+};
+
+void t7xx_pci_dev_rescan(void);
+void t7xx_rescan_queue_work(struct pci_dev *pdev);
+int t7xx_rescan_init(void);
+void t7xx_rescan_deinit(void);
+void t7xx_rescan_done(void);
+
+#endif	/* __T7XX_PCI_RESCAN_H__ */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection
  2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
                   ` (2 preceding siblings ...)
  2023-01-06 16:27 ` [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan m.chetan.kumar
@ 2023-01-06 16:27 ` m.chetan.kumar
  2023-01-06 18:50   ` Jesse Brandeburg
  2023-01-06 16:28 ` [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation m.chetan.kumar
  4 siblings, 1 reply; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:27 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek,
	Mishra Soumya Prakash

From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

Adds support for t7xx wwan device firmware flashing & coredump collection
using devlink.

1> Driver Registers with Devlink framework.
2> Implements devlink ops flash_update callback that programs modem fw.
3> Creates region & snapshot required for device coredump log collection.

On early detection of wwan device in fastboot mode driver sets up CLDMA0 HW
tx/rx queues for raw data transfer and then registers to devlink framework.
On user space application issuing command for firmware update the driver
sends fastboot flash command & firmware to program NAND.

In flashing procedure the fastboot command & response are exchanged between
driver and device. Once firmware flashing is success completion status is
reported to user space application.

Below is the devlink command usage for firmware flashing

$devlink dev flash pci/$BDF file ABC.img component ABC

Note: ABC.img is the firmware to be programmed to "ABC" partition.

In case of coredump collection when wwan device encounters an exception
it reboots & stays in fastboot mode for coredump collection by host driver.
On detecting exception state driver collects the core dump, creates the
devlink region & reports an event to user space application for dump
collection. The user space application invokes devlink region read command
for dump collection.

Below are the devlink commands used for coredump collection.

devlink region new pci/$BDF/mr_dump
devlink region read pci/$BDF/mr_dump snapshot $ID address $ADD length $LEN
devlink region del pci/$BDF/mr_dump snapshot $ID

Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
Signed-off-by: Mishra Soumya Prakash <soumya.prakash.mishra@intel.com>
--
v3:
 * No Change.
v2:
 * Remove devlink pointer inside the port state container.
 * Rename t7xx_devlink_region_list to t7xx_devlink_region_infos &
   use region index in initialization.
 * Change t7xx_devlink_region_infos to const.
 * Handle remaining packet data if the buffer is less than the skb data.
 * Drop t7xx_devlink_fb_send_buffer(), push fragmentation logic to
   t7xx_devlink_port_write().
 * Add "\n" to log message.
 * Move mrdump_region allocation to devlink initialization.
 * Drop snprintf for CTS command fill.
 * Drop intermediate mdata buffer & zipsize.
 * For mcmd use strcmp instead of strncmp.
 * Drop set_fastboot_dl instead use devlink param for fastboot operational mode.
 * Drop unnecessary logs.
 * Change t7xx_devlink_create_region to t7xx_devlink_create_regions.
 * Use BUILD_BUG_ON on array size checks.
 * Use ARRAY_SIZE inside loop.
 * Correct indentation.
 * Drop odd empty line.
 * Push common devlink initialization code to t7xx_devlink_init.
 * Use skb_queue_purge instead of running loop to free skbs.
 * Change t7xx_regions index to enums.
 * Remove dev in devlink container.
 * Refactor struct to separate out devlink static and dynamic data structs.
 * Use min_t.
 * Drop unnecessary var assginment during initialization.
 * Change while() to for().
 * Correct size check.
 * Rename result to ret.
 * Clean-up error handling path in t7xx_devlink_fb_get_core & t7xx_devlink_fb_dump_log.
 * Drop __func__ in log message.
 * Change NOTY to NOTIFY.
 * Push channel enable or disable cb to port proxy.
 * Use array index in t7xx_devlink_region_list initialization.
 * Drop t7xx_port_proxy_get_port_by_name() instead access port name directly via port_prox.
 * Drop udev based event reporting logic.
 * Drop get_core prefix in goto label.
 * Remove unnessary header files.
 * Allocate memory for mrdump_region->buf inside get_core.
 * Remove 'region->buf' in t7xx_devlink_region_snapshot.
 * Destroy workqueue on following error case in 'devlink_init'.
 * Remove useless checks(dl->mode) and condition(dl->wq).
 * Support devlink component versioning.
 * Kconfig changes to select devlink.
---
 drivers/net/wwan/Kconfig                   |   1 +
 drivers/net/wwan/t7xx/Makefile             |   4 +-
 drivers/net/wwan/t7xx/t7xx_pci.c           |  16 +-
 drivers/net/wwan/t7xx/t7xx_pci.h           |   2 +
 drivers/net/wwan/t7xx/t7xx_port.h          |   2 +
 drivers/net/wwan/t7xx/t7xx_port_ap_msg.c   |  78 +++
 drivers/net/wwan/t7xx/t7xx_port_ap_msg.h   |  11 +
 drivers/net/wwan/t7xx/t7xx_port_devlink.c  | 665 +++++++++++++++++++++
 drivers/net/wwan/t7xx/t7xx_port_devlink.h  |  86 +++
 drivers/net/wwan/t7xx/t7xx_port_proxy.c    |  32 +
 drivers/net/wwan/t7xx/t7xx_port_proxy.h    |   4 +
 drivers/net/wwan/t7xx/t7xx_port_wwan.c     |  22 +-
 drivers/net/wwan/t7xx/t7xx_reg.h           |   6 +
 drivers/net/wwan/t7xx/t7xx_state_monitor.c |  37 +-
 14 files changed, 940 insertions(+), 26 deletions(-)
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.h
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.c
 create mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.h

diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
index 410b0245114e..dd7a9883c1ff 100644
--- a/drivers/net/wwan/Kconfig
+++ b/drivers/net/wwan/Kconfig
@@ -108,6 +108,7 @@ config IOSM
 config MTK_T7XX
 	tristate "MediaTek PCIe 5G WWAN modem T7xx device"
 	depends on PCI
+	select NET_DEVLINK
 	select RELAY if WWAN_DEBUGFS
 	help
 	  Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device.
diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile
index ba5c607404a4..c3f1520b3c49 100644
--- a/drivers/net/wwan/t7xx/Makefile
+++ b/drivers/net/wwan/t7xx/Makefile
@@ -18,7 +18,9 @@ mtk_t7xx-y:=	t7xx_pci.o \
 		t7xx_hif_dpmaif_rx.o  \
 		t7xx_dpmaif.o \
 		t7xx_netdev.o \
-		t7xx_pci_rescan.o
+		t7xx_pci_rescan.o \
+		t7xx_port_devlink.o \
+		t7xx_port_ap_msg.o
 
 mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \
 		t7xx_port_trace.o \
diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c
index 1e953ec7dd00..2b714b8efb81 100644
--- a/drivers/net/wwan/t7xx/t7xx_pci.c
+++ b/drivers/net/wwan/t7xx/t7xx_pci.c
@@ -40,6 +40,7 @@
 #include "t7xx_pci.h"
 #include "t7xx_pci_rescan.h"
 #include "t7xx_pcie_mac.h"
+#include "t7xx_port_devlink.h"
 #include "t7xx_reg.h"
 #include "t7xx_state_monitor.h"
 
@@ -107,7 +108,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)
@@ -704,16 +705,20 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	t7xx_pci_infracfg_ao_calc(t7xx_dev);
 	t7xx_mhccif_init(t7xx_dev);
 
-	ret = t7xx_md_init(t7xx_dev);
+	ret = t7xx_devlink_register(t7xx_dev);
 	if (ret)
 		return ret;
 
+	ret = t7xx_md_init(t7xx_dev);
+	if (ret)
+		goto err_devlink_unregister;
+
 	t7xx_pcie_mac_interrupts_dis(t7xx_dev);
 
 	ret = t7xx_interrupt_init(t7xx_dev);
 	if (ret) {
 		t7xx_md_exit(t7xx_dev);
-		return ret;
+		goto err_devlink_unregister;
 	}
 
 	t7xx_rescan_done();
@@ -721,6 +726,10 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	t7xx_pcie_mac_interrupts_en(t7xx_dev);
 
 	return 0;
+
+err_devlink_unregister:
+	t7xx_devlink_unregister(t7xx_dev);
+	return ret;
 }
 
 static void t7xx_pci_remove(struct pci_dev *pdev)
@@ -730,6 +739,7 @@ static void t7xx_pci_remove(struct pci_dev *pdev)
 
 	t7xx_dev = pci_get_drvdata(pdev);
 	t7xx_md_exit(t7xx_dev);
+	t7xx_devlink_unregister(t7xx_dev);
 
 	for (i = 0; i < EXT_INT_NUM; i++) {
 		if (!t7xx_dev->intr_handler[i])
diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h
index 112efa534eac..44a8a5034696 100644
--- a/drivers/net/wwan/t7xx/t7xx_pci.h
+++ b/drivers/net/wwan/t7xx/t7xx_pci.h
@@ -59,6 +59,7 @@ typedef irqreturn_t (*t7xx_intr_callback)(int irq, void *param);
  * @md_pm_lock: protects PCIe sleep lock
  * @sleep_disable_count: PCIe L1.2 lock counter
  * @sleep_lock_acquire: indicates that sleep has been disabled
+ * @dl: devlink struct
  */
 struct t7xx_pci_dev {
 	t7xx_intr_callback	intr_handler[EXT_INT_NUM];
@@ -81,6 +82,7 @@ struct t7xx_pci_dev {
 #ifdef CONFIG_WWAN_DEBUGFS
 	struct dentry		*debugfs_dir;
 #endif
+	struct t7xx_devlink     *dl;
 };
 
 enum t7xx_pm_id {
diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h
index 09acb1ef144d..dfa7ad2a9796 100644
--- a/drivers/net/wwan/t7xx/t7xx_port.h
+++ b/drivers/net/wwan/t7xx/t7xx_port.h
@@ -42,6 +42,8 @@ enum port_ch {
 	/* to AP */
 	PORT_CH_AP_CONTROL_RX = 0x1000,
 	PORT_CH_AP_CONTROL_TX = 0x1001,
+	PORT_CH_AP_MSG_RX = 0x101E,
+	PORT_CH_AP_MSG_TX = 0x101F,
 
 	/* to MD */
 	PORT_CH_CONTROL_RX = 0x2000,
diff --git a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c
new file mode 100644
index 000000000000..241a179f2e3f
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023, Intel Corporation.
+ */
+
+#include "t7xx_port.h"
+#include "t7xx_port_ap_msg.h"
+#include "t7xx_port_devlink.h"
+#include "t7xx_port_proxy.h"
+#include "t7xx_state_monitor.h"
+
+int t7xx_port_ap_msg_tx(struct t7xx_port *port, char *buff, size_t len)
+{
+	const struct t7xx_port_conf *port_conf;
+	size_t offset, chunk_len = 0, txq_mtu;
+	struct t7xx_fsm_ctl *ctl;
+	struct sk_buff *skb_ccci;
+	enum md_state md_state;
+	int ret;
+
+	if (!len || !port->chan_enable)
+		return -EINVAL;
+
+	port_conf = port->port_conf;
+	ctl = port->t7xx_dev->md->fsm_ctl;
+	md_state = t7xx_fsm_get_md_state(ctl);
+	if (md_state == MD_STATE_WAITING_FOR_HS1 || md_state == MD_STATE_WAITING_FOR_HS2) {
+		dev_warn(port->dev, "Cannot write to %s port when md_state=%d\n",
+			 port_conf->name, md_state);
+		return -ENODEV;
+	}
+
+	txq_mtu = t7xx_get_port_mtu(port);
+	for (offset = 0; offset < len; offset += chunk_len) {
+		chunk_len = min(len - offset, txq_mtu - sizeof(struct ccci_header));
+		skb_ccci = t7xx_port_alloc_skb(chunk_len);
+		if (!skb_ccci)
+			return -ENOMEM;
+
+		skb_put_data(skb_ccci, buff + offset, chunk_len);
+		ret = t7xx_port_send_skb(port, skb_ccci, 0, 0);
+		if (ret) {
+			dev_kfree_skb_any(skb_ccci);
+			dev_err(port->dev, "Write error on %s port, %d\n",
+				port_conf->name, ret);
+			return ret;
+		}
+	}
+
+	return len;
+}
+
+static int t7xx_port_ap_msg_init(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+
+	port->rx_length_th = T7XX_MAX_QUEUE_LENGTH;
+	dl->status = T7XX_DEVLINK_IDLE;
+	dl->port = port;
+
+	return 0;
+}
+
+static void t7xx_port_ap_msg_uninit(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+
+	dl->mode = T7XX_NORMAL_MODE;
+	skb_queue_purge(&port->rx_skb_list);
+}
+
+struct port_ops ap_msg_port_ops = {
+	.init = &t7xx_port_ap_msg_init,
+	.recv_skb = &t7xx_port_enqueue_skb,
+	.uninit = &t7xx_port_ap_msg_uninit,
+	.enable_chl = &t7xx_port_enable_chl,
+	.disable_chl = &t7xx_port_disable_chl,
+};
diff --git a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h
new file mode 100644
index 000000000000..4838d87d86cf
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023, Intel Corporation.
+ */
+
+#ifndef __T7XX_PORT_AP_MSG_H__
+#define __T7XX_PORT_AP_MSG_H__
+
+int t7xx_port_ap_msg_tx(struct t7xx_port *port, char *buff, size_t len);
+
+#endif /* __T7XX_PORT_AP_MSG_H__ */
diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c
new file mode 100644
index 000000000000..80e772afd26e
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c
@@ -0,0 +1,665 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023, Intel Corporation.
+ */
+
+#include <linux/vmalloc.h>
+
+#include "t7xx_hif_cldma.h"
+#include "t7xx_pci_rescan.h"
+#include "t7xx_port.h"
+#include "t7xx_port_ap_msg.h"
+#include "t7xx_port_devlink.h"
+#include "t7xx_port_proxy.h"
+#include "t7xx_state_monitor.h"
+
+static struct t7xx_devlink_region_info t7xx_devlink_region_infos[] = {
+	[T7XX_MRDUMP_INDEX] = {"mr_dump", T7XX_MRDUMP_SIZE},
+	[T7XX_LKDUMP_INDEX] = {"lk_dump", T7XX_LKDUMP_SIZE},
+};
+
+static int t7xx_devlink_port_read(struct t7xx_port *port, char *buf, size_t count)
+{
+	struct sk_buff *skb;
+	int ret, read_len;
+
+	spin_lock_irq(&port->rx_wq.lock);
+	if (skb_queue_empty(&port->rx_skb_list)) {
+		ret = wait_event_interruptible_locked_irq(port->rx_wq,
+							  !skb_queue_empty(&port->rx_skb_list));
+		if (ret == -ERESTARTSYS) {
+			spin_unlock_irq(&port->rx_wq.lock);
+			return -EINTR;
+		}
+	}
+	skb = skb_dequeue(&port->rx_skb_list);
+	spin_unlock_irq(&port->rx_wq.lock);
+
+	read_len = min_t(size_t, count, skb->len);
+	memcpy(buf, skb->data, read_len);
+
+	if (read_len < skb->len) {
+		skb_pull(skb, read_len);
+		skb_queue_head(&port->rx_skb_list, skb);
+	} else {
+		consume_skb(skb);
+	}
+
+	return read_len;
+}
+
+static int t7xx_devlink_port_write(struct t7xx_port *port, const char *buf, size_t count)
+{
+	const struct t7xx_port_conf *port_conf = port->port_conf;
+	size_t actual = count, len, offset = 0;
+	struct sk_buff *skb;
+	int ret, txq_mtu;
+
+	txq_mtu = t7xx_get_port_mtu(port);
+	if (txq_mtu < 0)
+		return -EINVAL;
+
+	while (actual) {
+		len = min_t(size_t, actual, txq_mtu);
+		skb = __dev_alloc_skb(len, GFP_KERNEL);
+		if (!skb)
+			return -ENOMEM;
+
+		skb_put_data(skb, buf + offset, len);
+		ret = t7xx_port_send_raw_skb(port, skb);
+		if (ret) {
+			dev_err(port->dev, "write error on %s, size: %zu, ret: %d\n",
+				port_conf->name, len, ret);
+			dev_kfree_skb(skb);
+			return ret;
+		}
+
+		offset += len;
+		actual -= len;
+	}
+
+	return count;
+}
+
+static int t7xx_devlink_fb_handle_response(struct t7xx_port *port, char *data)
+{
+	char status[T7XX_FB_RESPONSE_SIZE + 1];
+	int ret = 0, index, read_bytes;
+
+	for (index = 0; index < T7XX_FB_RESP_COUNT; index++) {
+		read_bytes = t7xx_devlink_port_read(port, status, T7XX_FB_RESPONSE_SIZE);
+		if (read_bytes < 0) {
+			dev_err(port->dev, "status read interrupted\n");
+			ret = -EIO;
+			break;
+		}
+
+		status[read_bytes] = '\0';
+		dev_dbg(port->dev, "raw response from device: %s\n", status);
+		if (!strncmp(status, T7XX_FB_RESP_INFO, strlen(T7XX_FB_RESP_INFO))) {
+			break;
+		} else if (!strncmp(status, T7XX_FB_RESP_OKAY, strlen(T7XX_FB_RESP_OKAY))) {
+			break;
+		} else if (!strncmp(status, T7XX_FB_RESP_FAIL, strlen(T7XX_FB_RESP_FAIL))) {
+			ret = -EPROTO;
+			break;
+		} else if (!strncmp(status, T7XX_FB_RESP_DATA, strlen(T7XX_FB_RESP_DATA))) {
+			if (data)
+				snprintf(data, T7XX_FB_RESPONSE_SIZE, "%s",
+					 status + strlen(T7XX_FB_RESP_DATA));
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int t7xx_devlink_fb_raw_command(char *cmd, struct t7xx_port *port, char *data)
+{
+	int ret, cmd_size = strlen(cmd);
+
+	if (cmd_size > T7XX_FB_COMMAND_SIZE) {
+		dev_err(port->dev, "command length %d is long\n", cmd_size);
+		return -EINVAL;
+	}
+
+	if (cmd_size != t7xx_devlink_port_write(port, cmd, cmd_size)) {
+		dev_err(port->dev, "raw command = %s write failed\n", cmd);
+		return -EIO;
+	}
+
+	dev_dbg(port->dev, "raw command = %s written to the device\n", cmd);
+	ret = t7xx_devlink_fb_handle_response(port, data);
+	if (ret)
+		dev_err(port->dev, "raw command = %s response FAILURE:%d\n", cmd, ret);
+
+	return ret;
+}
+
+static int t7xx_devlink_fb_download_command(struct t7xx_port *port, size_t size)
+{
+	char download_command[T7XX_FB_COMMAND_SIZE];
+
+	snprintf(download_command, sizeof(download_command), "%s:%08zx",
+		 T7XX_FB_CMD_DOWNLOAD, size);
+	return t7xx_devlink_fb_raw_command(download_command, port, NULL);
+}
+
+static int t7xx_devlink_fb_download(struct t7xx_port *port, const u8 *buf, size_t size)
+{
+	int ret;
+
+	if (!size)
+		return -EINVAL;
+
+	ret = t7xx_devlink_fb_download_command(port, size);
+	if (ret)
+		return ret;
+
+	ret = t7xx_devlink_port_write(port, buf, size);
+	if (ret < 0)
+		return ret;
+
+	return t7xx_devlink_fb_handle_response(port, NULL);
+}
+
+static int t7xx_devlink_fb_flash(struct t7xx_port *port, const char *cmd)
+{
+	char flash_command[T7XX_FB_COMMAND_SIZE];
+
+	snprintf(flash_command, sizeof(flash_command), "%s:%s", T7XX_FB_CMD_FLASH, cmd);
+	return t7xx_devlink_fb_raw_command(flash_command, port, NULL);
+}
+
+static int t7xx_devlink_get_part_ver_fb_mode(struct t7xx_port *port, const char *cmd, char *data)
+{
+	char req_command[T7XX_FB_COMMAND_SIZE];
+
+	snprintf(req_command, sizeof(req_command), "%s:%s", T7XX_FB_CMD_GET_VER, cmd);
+	return t7xx_devlink_fb_raw_command(req_command, port, data);
+}
+
+static int t7xx_devlink_get_part_ver_norm_mode(struct t7xx_port *port, const char *cmd, char *data)
+{
+	char req_command[T7XX_FB_COMMAND_SIZE];
+	int len;
+
+	len = snprintf(req_command, sizeof(req_command), "%s:%s", T7XX_FB_CMD_GET_VER, cmd);
+	t7xx_port_ap_msg_tx(port, req_command, len);
+
+	return t7xx_devlink_fb_handle_response(port, data);
+}
+
+static int t7xx_devlink_fb_flash_partition(struct t7xx_port *port, const char *partition,
+					   const u8 *buf, size_t size)
+{
+	int ret;
+
+	ret = t7xx_devlink_fb_download(port, buf, size);
+	if (ret < 0)
+		return ret;
+
+	return t7xx_devlink_fb_flash(port, partition);
+}
+
+static int t7xx_devlink_fb_get_core(struct t7xx_port *port)
+{
+	u32 mrd_mb = T7XX_MRDUMP_SIZE / (1024 * 1024);
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+	char mcmd[T7XX_FB_MCMD_SIZE + 1];
+	size_t offset_dlen = 0;
+	int clen, dlen, ret;
+
+	dl->regions[T7XX_MRDUMP_INDEX].buf = vmalloc(dl->regions[T7XX_MRDUMP_INDEX].info->size);
+	if (!dl->regions[T7XX_MRDUMP_INDEX].buf)
+		return -ENOMEM;
+
+	set_bit(T7XX_MRDUMP_STATUS, &dl->status);
+	ret = t7xx_devlink_fb_raw_command(T7XX_FB_CMD_OEM_MRDUMP, port, NULL);
+	if (ret) {
+		dev_err(port->dev, "%s command failed\n", T7XX_FB_CMD_OEM_MRDUMP);
+		goto free_mem;
+	}
+
+	while (dl->regions[T7XX_MRDUMP_INDEX].info->size > offset_dlen) {
+		clen = t7xx_devlink_port_read(port, mcmd, sizeof(mcmd) - 1);
+		mcmd[clen] = '\0';
+		if (clen == strlen(T7XX_FB_CMD_RTS) && (!strcmp(mcmd, T7XX_FB_CMD_RTS))) {
+			memset(mcmd, 0, sizeof(mcmd));
+			if (t7xx_devlink_port_write(port, T7XX_FB_CMD_CTS, strlen(T7XX_FB_CMD_CTS))
+						    != strlen(T7XX_FB_CMD_CTS)) {
+				dev_err(port->dev, "write for _CTS failed:%zu\n",
+					strlen(T7XX_FB_CMD_CTS));
+				goto free_mem;
+			}
+
+			dlen = t7xx_devlink_port_read(port, dl->regions[T7XX_MRDUMP_INDEX].buf +
+						      offset_dlen, T7XX_FB_MDATA_SIZE);
+			if (dlen <= 0) {
+				dev_err(port->dev, "read data error(%d)\n", dlen);
+				ret = -EPROTO;
+				goto free_mem;
+			}
+			offset_dlen += dlen;
+
+			if (t7xx_devlink_port_write(port, T7XX_FB_CMD_FIN, strlen(T7XX_FB_CMD_FIN))
+						    != strlen(T7XX_FB_CMD_FIN)) {
+				dev_err(port->dev, "_FIN failed, (Read %05zu:%05zu)\n",
+					strlen(T7XX_FB_CMD_FIN), offset_dlen);
+				ret = -EPROTO;
+				goto free_mem;
+			}
+			continue;
+		} else if ((clen == strlen(T7XX_FB_RESP_MRDUMP_DONE)) &&
+			   (!strcmp(mcmd, T7XX_FB_RESP_MRDUMP_DONE))) {
+			dev_dbg(port->dev, "%s! size:%zd\n", T7XX_FB_RESP_MRDUMP_DONE, offset_dlen);
+			clear_bit(T7XX_MRDUMP_STATUS, &dl->status);
+			return 0;
+		}
+		dev_err(port->dev, "getcore protocol error (read len %05d, response %s)\n",
+			clen, mcmd);
+		ret = -EPROTO;
+		goto free_mem;
+	}
+
+	dev_err(port->dev, "mrdump exceeds %uMB size. Discarded!\n", mrd_mb);
+
+free_mem:
+	vfree(dl->regions[T7XX_MRDUMP_INDEX].buf);
+	clear_bit(T7XX_MRDUMP_STATUS, &dl->status);
+	return ret;
+}
+
+static int t7xx_devlink_fb_dump_log(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+	struct t7xx_devlink_region *lkdump_region;
+	char rsp[T7XX_FB_RESPONSE_SIZE];
+	int dlen, datasize = 0, ret;
+	size_t offset = 0;
+
+	if (dl->status != T7XX_DEVLINK_IDLE) {
+		dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n");
+		return -EBUSY;
+	}
+
+	set_bit(T7XX_LKDUMP_STATUS, &dl->status);
+	ret = t7xx_devlink_fb_raw_command(T7XX_FB_CMD_OEM_LKDUMP, port, rsp);
+	if (ret) {
+		dev_err(port->dev, "%s command returns failure\n", T7XX_FB_CMD_OEM_LKDUMP);
+		clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+		return ret;
+	}
+
+	ret = kstrtoint(rsp, 16, &datasize);
+	if (ret) {
+		dev_err(port->dev, "kstrtoint error!\n");
+		clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+		return ret;
+	}
+
+	lkdump_region = &dl->regions[T7XX_LKDUMP_INDEX];
+	if (datasize > lkdump_region->info->size) {
+		dev_err(port->dev, "lkdump size is more than %dKB. Discarded!\n",
+			T7XX_LKDUMP_SIZE / 1024);
+		clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+		return -EPROTO;
+	}
+
+	lkdump_region->buf = vmalloc(lkdump_region->info->size);
+	if (!lkdump_region->buf) {
+		clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+		return -ENOMEM;
+	}
+
+	while (datasize > 0) {
+		dlen = t7xx_devlink_port_read(port, lkdump_region->buf + offset, datasize);
+		if (dlen <= 0) {
+			dev_err(port->dev, "lkdump read error ret = %d\n", dlen);
+			clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+			return -EPROTO;
+		}
+
+		datasize -= dlen;
+		offset += dlen;
+	}
+
+	dev_dbg(port->dev, "LKDUMP DONE! size:%zd\n", offset);
+	clear_bit(T7XX_LKDUMP_STATUS, &dl->status);
+	return t7xx_devlink_fb_handle_response(port, NULL);
+}
+
+static int t7xx_devlink_flash_update(struct devlink *devlink,
+				     struct devlink_flash_update_params *params,
+				     struct netlink_ext_ack *extack)
+{
+	struct t7xx_devlink *dl = devlink_priv(devlink);
+	const char *component = params->component;
+	const struct firmware *fw = params->fw;
+	struct t7xx_port *port;
+	int ret;
+
+	if (dl->mode != T7XX_FB_DL_MODE) {
+		dev_err(&dl->t7xx_dev->pdev->dev, "Modem is not in fastboot download mode!\n");
+		ret = -EPERM;
+		goto err_out;
+	}
+
+	if (dl->status != T7XX_DEVLINK_IDLE) {
+		dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n");
+		ret = -EBUSY;
+		goto err_out;
+	}
+
+	if (!component || !fw->data) {
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	set_bit(T7XX_FLASH_STATUS, &dl->status);
+	port = dl->port;
+	dev_dbg(port->dev, "flash partition name:%s binary size:%zu\n", component, fw->size);
+	ret = t7xx_devlink_fb_flash_partition(port, component, fw->data, fw->size);
+	if (ret) {
+		devlink_flash_update_status_notify(devlink, "flashing failure!",
+						   params->component, 0, 0);
+	} else {
+		devlink_flash_update_status_notify(devlink, "flashing success!",
+						   params->component, 0, 0);
+	}
+	clear_bit(T7XX_FLASH_STATUS, &dl->status);
+
+err_out:
+	return ret;
+}
+
+enum t7xx_devlink_param_id {
+	T7XX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+	T7XX_DEVLINK_PARAM_ID_FASTBOOT,
+};
+
+static const struct devlink_param t7xx_devlink_params[] = {
+	DEVLINK_PARAM_DRIVER(T7XX_DEVLINK_PARAM_ID_FASTBOOT,
+			     "fastboot", DEVLINK_PARAM_TYPE_BOOL,
+			     BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
+			     NULL, NULL, NULL),
+};
+
+bool t7xx_devlink_param_get_fastboot(struct devlink *devlink)
+{
+	union devlink_param_value saved_value;
+
+	devlink_param_driverinit_value_get(devlink, T7XX_DEVLINK_PARAM_ID_FASTBOOT,
+					   &saved_value);
+	return saved_value.vbool;
+}
+
+static int t7xx_devlink_reload_down(struct devlink *devlink, bool netns_change,
+				    enum devlink_reload_action action,
+				    enum devlink_reload_limit limit,
+				    struct netlink_ext_ack *extack)
+{
+	struct t7xx_devlink *dl = devlink_priv(devlink);
+
+	switch (action) {
+	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
+		return 0;
+	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
+		if (!dl->mode)
+			return -EPERM;
+		return t7xx_devlink_fb_raw_command(T7XX_FB_CMD_REBOOT, dl->port, NULL);
+	default:
+		/* Unsupported action should not get to this function */
+		return -EOPNOTSUPP;
+	}
+}
+
+static int t7xx_devlink_reload_up(struct devlink *devlink,
+				  enum devlink_reload_action action,
+				  enum devlink_reload_limit limit,
+				  u32 *actions_performed,
+				  struct netlink_ext_ack *extack)
+{
+	struct t7xx_devlink *dl = devlink_priv(devlink);
+	*actions_performed = BIT(action);
+	switch (action) {
+	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
+	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
+		t7xx_rescan_queue_work(dl->t7xx_dev->pdev);
+		return 0;
+	default:
+		/* Unsupported action should not get to this function */
+		return -EOPNOTSUPP;
+	}
+}
+
+static int t7xx_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
+				 struct netlink_ext_ack *extack)
+{
+	struct t7xx_devlink *dl = devlink_priv(devlink);
+	char *part_name, *ver, *part_no, *data;
+	int ret, total_part, i, ver_len;
+	struct t7xx_port *port;
+
+	port = dl->port;
+	port->port_conf->ops->enable_chl(port);
+
+	if (dl->status != T7XX_DEVLINK_IDLE) {
+		dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n");
+		return -EBUSY;
+	}
+
+	data = kzalloc(T7XX_FB_RESPONSE_SIZE, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	set_bit(T7XX_GET_INFO, &dl->status);
+	if (dl->mode == T7XX_FB_DL_MODE)
+		ret = t7xx_devlink_get_part_ver_fb_mode(port, "", data);
+	else
+		ret = t7xx_devlink_get_part_ver_norm_mode(port, "", data);
+
+	if (ret < 0)
+		goto err_clear_bit;
+
+	part_no = strsep(&data, ",");
+	if (kstrtoint(part_no, 16, &total_part)) {
+		dev_err(&dl->t7xx_dev->pdev->dev, "kstrtoint error!\n");
+		ret = -EINVAL;
+		goto err_clear_bit;
+	}
+
+	for (i = 0; i < total_part; i++) {
+		part_name = strsep(&data, ",");
+		ver = strsep(&data, ",");
+		ver_len = strlen(ver);
+		if (ver[ver_len - 2] == 0x5C && ver[ver_len - 1] == 0x6E)
+			ver[ver_len - 4] = '\0';
+		ret = devlink_info_version_running_put_ext(req, part_name, ver,
+							   DEVLINK_INFO_VERSION_TYPE_COMPONENT);
+	}
+
+err_clear_bit:
+	clear_bit(T7XX_GET_INFO, &dl->status);
+	kfree(data);
+	return ret;
+}
+
+/* Call back function for devlink ops */
+static const struct devlink_ops devlink_flash_ops = {
+	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
+	.flash_update = t7xx_devlink_flash_update,
+	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
+	.info_get = t7xx_devlink_info_get,
+	.reload_down = t7xx_devlink_reload_down,
+	.reload_up = t7xx_devlink_reload_up,
+};
+
+static int t7xx_devlink_region_snapshot(struct devlink *dl, const struct devlink_region_ops *ops,
+					struct netlink_ext_ack *extack, u8 **data)
+{
+	struct t7xx_devlink *t7xx_dl = devlink_priv(dl);
+	struct t7xx_devlink_region *region = ops->priv;
+	struct t7xx_port *port = t7xx_dl->port;
+	u8 *snapshot_mem;
+
+	if (t7xx_dl->status != T7XX_DEVLINK_IDLE)
+		return -EBUSY;
+
+	if (!strncmp(ops->name, "mr_dump", strlen("mr_dump"))) {
+		snapshot_mem = vmalloc(region->info->size);
+		memcpy(snapshot_mem, region->buf, region->info->size);
+		*data = snapshot_mem;
+	} else if (!strncmp(ops->name, "lk_dump", strlen("lk_dump"))) {
+		int ret;
+
+		ret = t7xx_devlink_fb_dump_log(port);
+		if (ret)
+			return ret;
+
+		*data = region->buf;
+	}
+
+	return 0;
+}
+
+/* To create regions for dump files */
+static int t7xx_devlink_create_regions(struct t7xx_devlink *dl)
+{
+	int ret, i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(t7xx_devlink_region_infos) > ARRAY_SIZE(dl->regions));
+	for (i = 0; i < ARRAY_SIZE(t7xx_devlink_region_infos); i++) {
+		dl->regions[i].info = &t7xx_devlink_region_infos[i];
+		dl->regions[i].ops.name = dl->regions[i].info->name;
+		dl->regions[i].ops.snapshot = t7xx_devlink_region_snapshot;
+		dl->regions[i].ops.destructor = vfree;
+		dl->regions[i].dlreg = devlink_region_create(dl->ctx, &dl->regions[i].ops,
+							     T7XX_MAX_SNAPSHOTS,
+							     t7xx_devlink_region_infos[i].size);
+		if (IS_ERR(dl->regions[i].dlreg)) {
+			ret = PTR_ERR(dl->regions[i].dlreg);
+			dev_err(dl->port->dev, "devlink region fail,err %d\n", ret);
+			for ( ; i >= 0; i--)
+				devlink_region_destroy(dl->regions[i].dlreg);
+
+			return ret;
+		}
+
+		dl->regions[i].ops.priv = &dl->regions[i];
+	}
+
+	return 0;
+}
+
+int t7xx_devlink_register(struct t7xx_pci_dev *t7xx_dev)
+{
+	union devlink_param_value value;
+	struct devlink *dl_ctx;
+
+	dl_ctx = devlink_alloc(&devlink_flash_ops, sizeof(struct t7xx_devlink),
+			       &t7xx_dev->pdev->dev);
+	if (!dl_ctx)
+		return -ENOMEM;
+
+	t7xx_dev->dl = devlink_priv(dl_ctx);
+	t7xx_dev->dl->ctx = dl_ctx;
+	t7xx_dev->dl->t7xx_dev = t7xx_dev;
+	devlink_params_register(dl_ctx, t7xx_devlink_params, ARRAY_SIZE(t7xx_devlink_params));
+	value.vbool = false;
+	devlink_param_driverinit_value_set(dl_ctx, T7XX_DEVLINK_PARAM_ID_FASTBOOT, value);
+	devlink_set_features(dl_ctx, DEVLINK_F_RELOAD);
+	devlink_register(dl_ctx);
+
+	return 0;
+}
+
+void t7xx_devlink_unregister(struct t7xx_pci_dev *t7xx_dev)
+{
+	struct devlink *dl_ctx = t7xx_dev->dl->ctx;
+
+	devlink_unregister(dl_ctx);
+	devlink_params_unregister(dl_ctx, t7xx_devlink_params, ARRAY_SIZE(t7xx_devlink_params));
+	devlink_free(dl_ctx);
+}
+
+static void t7xx_devlink_work(struct work_struct *work)
+{
+	struct t7xx_devlink *dl;
+
+	dl = container_of(work, struct t7xx_devlink, ws);
+	t7xx_devlink_fb_get_core(dl->port);
+}
+
+/**
+ * t7xx_devlink_init - Initialize devlink to t7xx driver
+ * @port: Pointer to port structure
+ *
+ * Returns: 0 on success and error values on failure
+ */
+static int t7xx_devlink_init(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+	struct workqueue_struct *dl_wq;
+	int rc;
+
+	dl_wq = create_workqueue("t7xx_devlink");
+	if (!dl_wq) {
+		dev_err(port->dev, "create_workqueue failed\n");
+		return -ENODATA;
+	}
+
+	INIT_WORK(&dl->ws, t7xx_devlink_work);
+	port->rx_length_th = T7XX_MAX_QUEUE_LENGTH;
+
+	dl->mode = T7XX_NORMAL_MODE;
+	dl->status = T7XX_DEVLINK_IDLE;
+	dl->wq = dl_wq;
+	dl->port = port;
+
+	rc = t7xx_devlink_create_regions(dl);
+	if (rc) {
+		destroy_workqueue(dl->wq);
+		dev_err(port->dev, "devlink region creation failed, rc %d\n", rc);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void t7xx_devlink_uninit(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+	int i;
+
+	vfree(dl->regions[T7XX_MRDUMP_INDEX].buf);
+
+	dl->mode = T7XX_NORMAL_MODE;
+	destroy_workqueue(dl->wq);
+
+	BUILD_BUG_ON(ARRAY_SIZE(t7xx_devlink_region_infos) > ARRAY_SIZE(dl->regions));
+	for (i = 0; i < ARRAY_SIZE(t7xx_devlink_region_infos); ++i)
+		devlink_region_destroy(dl->regions[i].dlreg);
+
+	skb_queue_purge(&port->rx_skb_list);
+}
+
+static int t7xx_devlink_enable_chl(struct t7xx_port *port)
+{
+	struct t7xx_devlink *dl = port->t7xx_dev->dl;
+
+	t7xx_port_enable_chl(port);
+	if (dl->mode == T7XX_FB_DUMP_MODE)
+		queue_work(dl->wq, &dl->ws);
+
+	return 0;
+}
+
+struct port_ops devlink_port_ops = {
+	.init = &t7xx_devlink_init,
+	.recv_skb = &t7xx_port_enqueue_skb,
+	.uninit = &t7xx_devlink_uninit,
+	.enable_chl = &t7xx_devlink_enable_chl,
+	.disable_chl = &t7xx_port_disable_chl,
+};
diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.h b/drivers/net/wwan/t7xx/t7xx_port_devlink.h
new file mode 100644
index 000000000000..4074004110b8
--- /dev/null
+++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023, Intel Corporation.
+ */
+
+#ifndef __T7XX_PORT_DEVLINK_H__
+#define __T7XX_PORT_DEVLINK_H__
+
+#include <net/devlink.h>
+#include <linux/string.h>
+
+#include "t7xx_pci.h"
+
+#define T7XX_MAX_QUEUE_LENGTH 32
+#define T7XX_FB_COMMAND_SIZE  64
+#define T7XX_FB_RESPONSE_SIZE 512
+#define T7XX_FB_MCMD_SIZE     64
+#define T7XX_FB_MDATA_SIZE    1024
+#define T7XX_FB_RESP_COUNT    30
+
+#define T7XX_FB_CMD_RTS          "_RTS"
+#define T7XX_FB_CMD_CTS          "_CTS"
+#define T7XX_FB_CMD_FIN          "_FIN"
+#define T7XX_FB_CMD_OEM_MRDUMP   "oem mrdump"
+#define T7XX_FB_CMD_OEM_LKDUMP   "oem dump_pllk_log"
+#define T7XX_FB_CMD_DOWNLOAD     "download"
+#define T7XX_FB_CMD_FLASH        "flash"
+#define T7XX_FB_CMD_REBOOT       "reboot"
+#define T7XX_FB_RESP_MRDUMP_DONE "MRDUMP08_DONE"
+#define T7XX_FB_RESP_OKAY        "OKAY"
+#define T7XX_FB_RESP_FAIL        "FAIL"
+#define T7XX_FB_RESP_DATA        "DATA"
+#define T7XX_FB_RESP_INFO        "INFO"
+#define T7XX_FB_CMD_GET_VER      "get_version"
+
+#define T7XX_FB_EVENT_SIZE      50
+
+#define T7XX_MAX_SNAPSHOTS  1
+#define T7XX_MRDUMP_SIZE    (160 * 1024 * 1024)
+#define T7XX_LKDUMP_SIZE    (256 * 1024)
+#define T7XX_TOTAL_REGIONS  2
+
+#define T7XX_FLASH_STATUS   0
+#define T7XX_MRDUMP_STATUS  1
+#define T7XX_LKDUMP_STATUS  2
+#define T7XX_GET_INFO       3
+#define T7XX_DEVLINK_IDLE   0
+
+#define T7XX_NORMAL_MODE    0
+#define T7XX_FB_DL_MODE     1
+#define T7XX_FB_DUMP_MODE   2
+
+/* Internal region indexes */
+enum t7xx_regions {
+	T7XX_MRDUMP_INDEX,
+	T7XX_LKDUMP_INDEX,
+};
+
+struct t7xx_devlink_region_info {
+	const char *name;
+	size_t size;
+};
+
+struct t7xx_devlink_region {
+	struct t7xx_devlink_region_info *info;
+	struct devlink_region_ops ops;
+	struct devlink_region *dlreg;
+	void *buf;
+};
+
+struct t7xx_devlink {
+	struct t7xx_devlink_region regions[T7XX_TOTAL_REGIONS];
+	struct t7xx_pci_dev *t7xx_dev;
+	struct workqueue_struct *wq;
+	struct t7xx_port *port;
+	struct work_struct ws;
+	struct devlink *ctx;
+	unsigned long status;
+	u8 mode;
+};
+
+bool t7xx_devlink_param_get_fastboot(struct devlink *devlink);
+int t7xx_devlink_register(struct t7xx_pci_dev *t7xx_dev);
+void t7xx_devlink_unregister(struct t7xx_pci_dev *t7xx_dev);
+
+#endif /*__T7XX_PORT_DEVLINK_H__*/
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
index b457e8da098e..5cc03a5a9bcc 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c
@@ -40,6 +40,7 @@
 #define Q_IDX_CTRL			0
 #define Q_IDX_MBIM			2
 #define Q_IDX_AT_CMD			5
+#define Q_IDX_AP_MSG			2
 
 #define INVALID_SEQ_NUM			GENMASK(15, 0)
 
@@ -97,7 +98,18 @@ static const struct t7xx_port_conf t7xx_port_conf[] = {
 		.path_id = CLDMA_ID_AP,
 		.ops = &ctl_port_ops,
 		.name = "t7xx_ap_ctrl",
+	}, {
+		.tx_ch = PORT_CH_AP_MSG_TX,
+		.rx_ch = PORT_CH_AP_MSG_RX,
+		.txq_index = Q_IDX_AP_MSG,
+		.rxq_index = Q_IDX_AP_MSG,
+		.txq_exp_index = Q_IDX_AP_MSG,
+		.rxq_exp_index = Q_IDX_AP_MSG,
+		.path_id = CLDMA_ID_AP,
+		.ops = &ap_msg_port_ops,
+		.name = "ap_msg",
 	},
+
 };
 
 static struct t7xx_port_conf t7xx_early_port_conf[] = {
@@ -109,6 +121,8 @@ static struct t7xx_port_conf t7xx_early_port_conf[] = {
 		.txq_exp_index = CLDMA_Q_IDX_DUMP,
 		.rxq_exp_index = CLDMA_Q_IDX_DUMP,
 		.path_id = CLDMA_ID_AP,
+		.ops = &devlink_port_ops,
+		.name = "devlink",
 	},
 };
 
@@ -325,6 +339,24 @@ int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int
 	return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
 }
 
+int t7xx_port_enable_chl(struct t7xx_port *port)
+{
+	spin_lock(&port->port_update_lock);
+	port->chan_enable = true;
+	spin_unlock(&port->port_update_lock);
+
+	return 0;
+}
+
+int t7xx_port_disable_chl(struct t7xx_port *port)
+{
+	spin_lock(&port->port_update_lock);
+	port->chan_enable = false;
+	spin_unlock(&port->port_update_lock);
+
+	return 0;
+}
+
 static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
 {
 	struct t7xx_port *port;
diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
index 0f3fb53259b7..b86594ed0458 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h
+++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
@@ -93,6 +93,8 @@ struct ctrl_msg_header {
 /* Port operations mapping */
 extern struct port_ops wwan_sub_port_ops;
 extern struct port_ops ctl_port_ops;
+extern struct port_ops devlink_port_ops;
+extern struct port_ops ap_msg_port_ops;
 
 #ifdef CONFIG_WWAN_DEBUGFS
 extern struct port_ops t7xx_trace_port_ops;
@@ -108,5 +110,7 @@ int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned in
 void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id);
 int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb);
 int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb);
+int t7xx_port_enable_chl(struct t7xx_port *port);
+int t7xx_port_disable_chl(struct t7xx_port *port);
 
 #endif /* __T7XX_PORT_PROXY_H__ */
diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c
index 33fa8c22598a..183dc6e97760 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c
@@ -134,24 +134,6 @@ static int t7xx_port_wwan_recv_skb(struct t7xx_port *port, struct sk_buff *skb)
 	return 0;
 }
 
-static int t7xx_port_wwan_enable_chl(struct t7xx_port *port)
-{
-	spin_lock(&port->port_update_lock);
-	port->chan_enable = true;
-	spin_unlock(&port->port_update_lock);
-
-	return 0;
-}
-
-static int t7xx_port_wwan_disable_chl(struct t7xx_port *port)
-{
-	spin_lock(&port->port_update_lock);
-	port->chan_enable = false;
-	spin_unlock(&port->port_update_lock);
-
-	return 0;
-}
-
 static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int state)
 {
 	const struct t7xx_port_conf *port_conf = port->port_conf;
@@ -171,7 +153,7 @@ struct port_ops wwan_sub_port_ops = {
 	.init = t7xx_port_wwan_init,
 	.recv_skb = t7xx_port_wwan_recv_skb,
 	.uninit = t7xx_port_wwan_uninit,
-	.enable_chl = t7xx_port_wwan_enable_chl,
-	.disable_chl = t7xx_port_wwan_disable_chl,
+	.enable_chl = t7xx_port_enable_chl,
+	.disable_chl = t7xx_port_disable_chl,
 	.md_state_notify = t7xx_port_wwan_md_state_notify,
 };
diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h
index 44352cd02460..d19f2b810f8e 100644
--- a/drivers/net/wwan/t7xx/t7xx_reg.h
+++ b/drivers/net/wwan/t7xx/t7xx_reg.h
@@ -101,12 +101,18 @@ enum t7xx_pm_resume_state {
 	PM_RESUME_REG_STATE_L2_EXP,
 };
 
+enum host_event_e {
+	HOST_EVENT_INIT = 0,
+	FASTBOOT_DL_NOTIFY = 0x3,
+};
+
 #define T7XX_PCIE_MISC_DEV_STATUS		0x0d1c
 #define MISC_RESET_TYPE_FLDR			BIT(27)
 #define MISC_RESET_TYPE_PLDR			BIT(26)
 #define MISC_DEV_STATUS_MASK			GENMASK(15, 0)
 #define MISC_DEV_STATUS_INVALID			GENMASK(15, 0)
 #define MISC_LK_EVENT_MASK			GENMASK(11, 8)
+#define HOST_EVENT_MASK			GENMASK(31, 28)
 
 enum lk_event_id {
 	LK_EVENT_NORMAL = 0,
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 76fb5d57d4d7..8008e64773c6 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -37,6 +37,7 @@
 #include "t7xx_modem_ops.h"
 #include "t7xx_pci.h"
 #include "t7xx_pcie_mac.h"
+#include "t7xx_port_devlink.h"
 #include "t7xx_port_proxy.h"
 #include "t7xx_reg.h"
 #include "t7xx_state_monitor.h"
@@ -206,11 +207,22 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm
 		fsm_finish_command(ctl, cmd, 0);
 }
 
+static void t7xx_host_event_notify(struct t7xx_modem *md, unsigned int event_id)
+{
+	u32 value;
+
+	value = ioread32(IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS);
+	value &= ~HOST_EVENT_MASK;
+	value |= FIELD_PREP(HOST_EVENT_MASK, event_id);
+	iowrite32(value, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS);
+}
+
 static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status)
 {
 	struct t7xx_modem *md = ctl->md;
 	struct cldma_ctrl *md_ctrl;
 	enum lk_event_id lk_event;
+	struct t7xx_port *port;
 	struct device *dev;
 
 	dev = &md->t7xx_dev->pdev->dev;
@@ -221,10 +233,21 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int
 		break;
 
 	case LK_EVENT_CREATE_PD_PORT:
+	case LK_EVENT_CREATE_POST_DL_PORT:
 		md_ctrl = md->md_ctrl[CLDMA_ID_AP];
 		t7xx_cldma_hif_hw_init(md_ctrl);
 		t7xx_cldma_stop(md_ctrl);
 		t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG);
+		port = ctl->md->t7xx_dev->dl->port;
+		if (WARN_ON(!port))
+			return;
+
+		if (lk_event == LK_EVENT_CREATE_PD_PORT)
+			md->t7xx_dev->dl->mode = T7XX_FB_DUMP_MODE;
+		else
+			md->t7xx_dev->dl->mode = T7XX_FB_DL_MODE;
+
+		port->port_conf->ops->enable_chl(port);
 		t7xx_cldma_start(md_ctrl);
 		break;
 
@@ -271,13 +294,23 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma
 	t7xx_cldma_stop(md_ctrl);
 
 	if (!ctl->md->rgu_irq_asserted) {
+		if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx))
+			t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY);
+
 		t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP);
 		/* Wait for the DRM disable to take effect */
 		msleep(FSM_DRM_DISABLE_DELAY_MS);
 
-		err = t7xx_acpi_fldr_func(t7xx_dev);
-		if (err)
+		if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) {
+			/* Do not try fldr because device will always wait for
+			 * MHCCIF bit 13 in fastboot download flow.
+			 */
 			t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET);
+		} else {
+			err = t7xx_acpi_fldr_func(t7xx_dev);
+			if (err)
+				t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET);
+		}
 	}
 
 	fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl));
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation
  2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
                   ` (3 preceding siblings ...)
  2023-01-06 16:27 ` [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection m.chetan.kumar
@ 2023-01-06 16:28 ` m.chetan.kumar
  2023-01-06 18:37   ` Jesse Brandeburg
  2023-01-09  3:48   ` Bagas Sanjaya
  4 siblings, 2 replies; 16+ messages in thread
From: m.chetan.kumar @ 2023-01-06 16:28 UTC (permalink / raw)
  To: netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	m.chetan.kumar, matthias.bgg, linux-arm-kernel, linux-mediatek,
	linux-doc, jiri, corbet

From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>

Document the t7xx devlink commands usage for fw flashing &
coredump collection.

Refer to t7xx.rst file for details.

Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
--
v3:
 * No Change.
v2:
 * Documentation correction.
 * Add param details.
---
 Documentation/networking/devlink/index.rst |   1 +
 Documentation/networking/devlink/t7xx.rst  | 161 +++++++++++++++++++++
 2 files changed, 162 insertions(+)
 create mode 100644 Documentation/networking/devlink/t7xx.rst

diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index fee4d3968309..0c4f5961e78f 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -66,3 +66,4 @@ parameters, info versions, and other features it supports.
    prestera
    iosm
    octeontx2
+   t7xx
diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
new file mode 100644
index 000000000000..de220878ad76
--- /dev/null
+++ b/Documentation/networking/devlink/t7xx.rst
@@ -0,0 +1,161 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+====================
+t7xx devlink support
+====================
+
+This document describes the devlink features implemented by the ``t7xx``
+device driver.
+
+Parameters
+==========
+The ``t7xx_driver`` driver implements the following driver-specific parameters.
+
+.. list-table:: Driver-specific parameters implemented
+   :widths: 5 5 5 85
+
+   * - Name
+     - Type
+     - Mode
+     - Description
+   * - ``fastboot``
+     - boolean
+     - driverinit
+     - Set this param to enter fastboot mode.
+
+Flash Update
+============
+
+The ``t7xx`` driver implements the flash update using the ``devlink-flash``
+interface.
+
+The driver uses DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT to identify the type of
+firmware image that need to be programmed upon the request by user space application.
+
+The supported list of firmware image types is described below.
+
+.. list-table:: Firmware Image types
+    :widths: 15 85
+
+    * - Name
+      - Description
+    * - ``preloader``
+      - The first-stage bootloader image
+    * - ``loader_ext1``
+      - Preloader extension image
+    * - ``tee1``
+      - ARM trusted firmware and TEE (Trusted Execution Environment) image
+    * - ``lk``
+      - The second-stage bootloader image
+    * - ``spmfw``
+      - MediaTek in-house ASIC for power management image
+    * - ``sspm_1``
+      - MediaTek in-house ASIC for power management under secure world image
+    * - ``mcupm_1``
+      - MediaTek in-house ASIC for cpu power management image
+    * - ``dpm_1``
+      - MediaTek in-house ASIC for dram power management image
+    * - ``boot``
+      - The kernel and dtb image
+    * - ``rootfs``
+      - Root filesystem image
+    * - ``md1img``
+      - Modem image
+    * - ``md1dsp``
+      - Modem DSP image
+    * - ``mcf1``
+      - Modem OTA image (Modem Configuration Framework) for operators
+    * - ``mcf2``
+      - Modem OTA image (Modem Configuration Framework) for OEM vendors
+    * - ``mcf3``
+      - Modem OTA image (other usage) for OEM configurations
+
+``t7xx`` driver uses fastboot protocol for fw flashing. In the fw flashing
+procedure, fastboot command & response are exchanged between driver and wwan
+device.
+
+The wwan device is put into fastboot mode via devlink reload command, by
+passing "driver_reinit" action.
+
+$ devlink dev reload pci/0000:$bdf action driver_reinit
+
+Upon completion of fw flashing or coredump collection the wwan device is
+reset to normal mode using devlink reload command, by passing "fw_activate"
+action.
+
+$ devlink dev reload pci/0000:$bdf action fw_activate
+
+Flash Commands:
+===============
+
+$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
+
+$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
+
+$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
+
+$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
+
+$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
+
+$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
+
+$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
+
+$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
+
+$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
+
+$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
+
+$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
+
+$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
+
+$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
+
+$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
+
+$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
+
+Note: Component selects the partition type to be programmed.
+
+Regions
+=======
+
+The ``t7xx`` driver supports core dump collection when device encounters
+an exception. When wwan device encounters an exception, a snapshot of device
+internal data will be taken by the driver using fastboot commands.
+
+Following regions are accessed for device internal data.
+
+.. list-table:: Regions implemented
+    :widths: 15 85
+
+    * - Name
+      - Description
+    * - ``mr_dump``
+      - The detailed modem component logs are captured in this region
+    * - ``lk_dump``
+      - This region dumps the current snapshot of lk
+
+
+Region commands
+===============
+
+$ devlink region show
+
+
+$ devlink region new mr_dump
+
+$ devlink region read mr_dump snapshot 0 address 0 length $len
+
+$ devlink region del mr_dump snapshot 0
+
+$ devlink region new lk_dump
+
+$ devlink region read lk_dump snapshot 0 address 0 length $len
+
+$ devlink region del lk_dump snapshot 0
+
+Note: $len is actual len to be dumped.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA
  2023-01-06 16:26 ` [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA m.chetan.kumar
@ 2023-01-06 17:56   ` Jesse Brandeburg
  0 siblings, 0 replies; 16+ messages in thread
From: Jesse Brandeburg @ 2023-01-06 17:56 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, Madhusmita Sahu,
	Moises Veleta

On 1/6/2023 8:26 AM, m.chetan.kumar@linux.intel.com wrote:
> From: Haijun Liu <haijun.liu@mediatek.com>
> 
> The t7xx device contains two Cross Layer DMA (CLDMA) interfaces to
> communicate with AP and Modem processors respectively. So far only
> MD-CLDMA was being used, this patch enables AP-CLDMA.
> 
> Rename small Application Processor (sAP) to AP.
> 
> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
> Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Moises Veleta <moises.veleta@linux.intel.com>
> Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> --
> v3:
>   * No Change.
> v2:
>   * Reuse handshake_wq for AP work.
>   * Remove AP trace port tx/rx channel id.
>   * Rename t7xx_md_port_conf to t7xx_port_conf.

Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration
  2023-01-06 16:26 ` [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration m.chetan.kumar
@ 2023-01-06 18:31   ` Jesse Brandeburg
  2023-01-08 14:07     ` Kumar, M Chetan
  0 siblings, 1 reply; 16+ messages in thread
From: Jesse Brandeburg @ 2023-01-06 18:31 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, Madhusmita Sahu

On 1/6/2023 8:26 AM, m.chetan.kumar@linux.intel.com wrote:
> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> 
> 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.
> 
> This patch adds the infrastructure required to create the
> early ports which also requires a different configuration of
> CLDMA queues.

nit: use imperative voice in your commit messages: no "this patch".
instead:
"Add the infrastructure..."

> 
> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
> Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
> Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> --
> v3:
>   * No Change.
> v2:
>   * Move recv_skb handler to cldma_queue.
>   * Drop cldma_queue_type.
>   * Restore prototype of t7xx_port_send_raw_skb().
>   * Remove PORT_CFG_ID_INVALID check in t7xx_port_proxy_set_cfg().
>   * Add space before */.
>   * Drop unnecessary logs.
>   * Use WARN_ON on early port.
>   * Use new MISC_DEV_STATUS_INVALID instead of MISC_DEV_STATUS.
>   * Use macros instead of const identifiers.
>   * Change ports member type from pointer to array type.
>   * Prefix LK_EVENT_XX with MISC prefix.
>   * Use t7xx prefix for device_stage enums.
>   * Correct log messages.
>   * Don’t override pkt_size for non-download port under dedicated Queue.
>   * Drop cldma_txq_rxq_ids.
>   * Use macro for txq/rxq index.
>   * Use warn_on for rxq_idx comparison.
>   * Drop t7xx_port_proxy_get_port_by_name().
>   * Replace fsm poll with read_poll_timeout().
>   * Use "\n" consistently across log message.
>   * Remove local var _dev prefixes in fsm_routine_start().
>   * Use max_t.

...


> diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h
> index c41d7d094c08..44352cd02460 100644
> --- a/drivers/net/wwan/t7xx/t7xx_reg.h
> +++ b/drivers/net/wwan/t7xx/t7xx_reg.h
> @@ -102,10 +102,28 @@ enum t7xx_pm_resume_state {
>   };
>   
>   #define T7XX_PCIE_MISC_DEV_STATUS		0x0d1c
> -#define MISC_STAGE_MASK				GENMASK(2, 0)
> -#define MISC_RESET_TYPE_PLDR			BIT(26)
>   #define MISC_RESET_TYPE_FLDR			BIT(27)
> -#define LINUX_STAGE				4
> +#define MISC_RESET_TYPE_PLDR			BIT(26)
> +#define MISC_DEV_STATUS_MASK			GENMASK(15, 0)
> +#define MISC_DEV_STATUS_INVALID			GENMASK(15, 0)

I don't see any uses of this, even though it's mentioned in the commit 
message. The only reason I looked was because it was weird to have 
DEV_STATUS_MASK and STATUS_INVALID be the same values, is that correct?


> +#define MISC_LK_EVENT_MASK			GENMASK(11, 8)
> +
> +enum lk_event_id {
> +	LK_EVENT_NORMAL = 0,
> +	LK_EVENT_CREATE_PD_PORT = 1,
> +	LK_EVENT_CREATE_POST_DL_PORT = 2,
> +	LK_EVENT_RESET = 7,
> +};
> +
> +#define MISC_STAGE_MASK				GENMASK(2, 0)
> +
> +enum t7xx_device_stage {
> +	T7XX_DEV_STAGE_INIT = 0,
> +	T7XX_DEV_STAGE_BROM_PRE = 1,
> +	T7XX_DEV_STAGE_BROM_POST = 2,
> +	T7XX_DEV_STAGE_LK = 3,
> +	T7XX_DEV_STAGE_LINUX = 4,
> +};
>   
>   #define T7XX_PCIE_RESOURCE_STATUS		0x0d28
>   #define T7XX_PCIE_RESOURCE_STS_MSK		GENMASK(4, 0)
> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> index 80edb8e75a6a..76fb5d57d4d7 100644
> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> @@ -206,6 +206,34 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm
>   		fsm_finish_command(ctl, cmd, 0);
>   }
>   
> +static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status)
> +{
> +	struct t7xx_modem *md = ctl->md;
> +	struct cldma_ctrl *md_ctrl;
> +	enum lk_event_id lk_event;
> +	struct device *dev;
> +
> +	dev = &md->t7xx_dev->pdev->dev;
> +	lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status);
> +	switch (lk_event) {
> +	case LK_EVENT_NORMAL:
> +	case LK_EVENT_RESET:
> +		break;
> +
> +	case LK_EVENT_CREATE_PD_PORT:
> +		md_ctrl = md->md_ctrl[CLDMA_ID_AP];
> +		t7xx_cldma_hif_hw_init(md_ctrl);
> +		t7xx_cldma_stop(md_ctrl);
> +		t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG);
> +		t7xx_cldma_start(md_ctrl);
> +		break;
> +
> +	default:
> +		dev_err(dev, "Invalid LK event %d\n", lk_event);
> +		break;
> +	}
> +}
> +
>   static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl)
>   {
>   	ctl->curr_state = FSM_STATE_STOPPED;
> @@ -317,8 +345,9 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl)
>   static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd)
>   {
>   	struct t7xx_modem *md = ctl->md;
> -	u32 dev_status;
> -	int ret;
> +	struct device *dev;
> +	u32 status, stage;
> +	int ret = 0;
>   
>   	if (!md)
>   		return;
> @@ -329,23 +358,55 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
>   		return;
>   	}
>   
> +	dev = &md->t7xx_dev->pdev->dev;
>   	ctl->curr_state = FSM_STATE_PRE_START;
>   	t7xx_md_event_notify(md, FSM_PRE_START);
>   
> -	ret = read_poll_timeout(ioread32, dev_status,
> -				(dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 2000000,
> -				false, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS);
> +	ret = read_poll_timeout(ioread32, status,
> +				((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LINUX) ||
> +				((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LK), 100000,
> +				20000000, false, IREG_BASE(md->t7xx_dev) +
> +				T7XX_PCIE_MISC_DEV_STATUS);
> +
>   	if (ret) {
> -		struct device *dev = &md->t7xx_dev->pdev->dev;
> +		ret = -ETIMEDOUT;
> +		dev_err(dev, "read poll %d\n", ret);
> +		goto finish_command;
> +	}
>   
> -		fsm_finish_command(ctl, cmd, -ETIMEDOUT);
> -		dev_err(dev, "Invalid device status 0x%lx\n", dev_status & MISC_STAGE_MASK);
> -		return;
> +	if (status != ctl->prev_status) {
> +		stage = FIELD_GET(MISC_STAGE_MASK, status);

if stage is only used down here you can declare it locally. cppcheck has 
a check that will find these for you.

> +		switch (stage) {
> +		case T7XX_DEV_STAGE_INIT:
> +		case T7XX_DEV_STAGE_BROM_PRE:
> +		case T7XX_DEV_STAGE_BROM_POST:
> +			dev_info(dev, "BROM_STAGE Entered\n");
> +			ret = t7xx_fsm_append_cmd(ctl, FSM_CMD_START, 0);
> +			break;
> +
> +		case T7XX_DEV_STAGE_LK:
> +			dev_info(dev, "LK_STAGE Entered\n");
> +			t7xx_lk_stage_event_handling(ctl, status);
> +			break;
> +
> +		case T7XX_DEV_STAGE_LINUX:
> +			dev_info(dev, "LINUX_STAGE Entered\n");
> +			t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
> +			t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
> +			t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM |
> +					     D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK);
> +			t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL);
> +			ret = fsm_routine_starting(ctl);
> +			break;
> +
> +		default:
> +			break;
> +		}
> +		ctl->prev_status = status;
>   	}
>   
> -	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
> -	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
> -	fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl));
> +finish_command:
> +	fsm_finish_command(ctl, cmd, ret);
>   }
>   
>   static int fsm_main_thread(void *data)
> @@ -516,6 +577,7 @@ void t7xx_fsm_reset(struct t7xx_modem *md)
>   	fsm_flush_event_cmd_qs(ctl);
>   	ctl->curr_state = FSM_STATE_STOPPED;
>   	ctl->exp_flg = false;
> +	ctl->prev_status = 0;
>   }
>   
>   int t7xx_fsm_init(struct t7xx_modem *md)
> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
> index b6e76f3903c8..5e8012567ba1 100644
> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
> @@ -96,6 +96,7 @@ struct t7xx_fsm_ctl {
>   	bool			exp_flg;
>   	spinlock_t		notifier_lock;		/* Protects notifier list */
>   	struct list_head	notifier_list;
> +	u32                     prev_status;
>   };
>   
>   struct t7xx_fsm_event {


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation
  2023-01-06 16:28 ` [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation m.chetan.kumar
@ 2023-01-06 18:37   ` Jesse Brandeburg
  2023-01-08 14:20     ` Kumar, M Chetan
  2023-01-09  3:48   ` Bagas Sanjaya
  1 sibling, 1 reply; 16+ messages in thread
From: Jesse Brandeburg @ 2023-01-06 18:37 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, linux-doc, jiri,
	corbet

On 1/6/2023 8:28 AM, m.chetan.kumar@linux.intel.com wrote:
> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> 
> Document the t7xx devlink commands usage for fw flashing &

it would make the documentation easier and faster to read if you just 
spelled out fw as firmware.

> coredump collection.
> 
> Refer to t7xx.rst file for details.
> 
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
> --
> v3:
>   * No Change.
> v2:
>   * Documentation correction.
>   * Add param details.
> ---
>   Documentation/networking/devlink/index.rst |   1 +
>   Documentation/networking/devlink/t7xx.rst  | 161 +++++++++++++++++++++
>   2 files changed, 162 insertions(+)
>   create mode 100644 Documentation/networking/devlink/t7xx.rst
> 
> diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
> index fee4d3968309..0c4f5961e78f 100644
> --- a/Documentation/networking/devlink/index.rst
> +++ b/Documentation/networking/devlink/index.rst
> @@ -66,3 +66,4 @@ parameters, info versions, and other features it supports.
>      prestera
>      iosm
>      octeontx2
> +   t7xx
> diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
> new file mode 100644
> index 000000000000..de220878ad76
> --- /dev/null
> +++ b/Documentation/networking/devlink/t7xx.rst
> @@ -0,0 +1,161 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +====================
> +t7xx devlink support
> +====================
> +
> +This document describes the devlink features implemented by the ``t7xx``
> +device driver.
> +
> +Parameters
> +==========
> +The ``t7xx_driver`` driver implements the following driver-specific parameters.
> +
> +.. list-table:: Driver-specific parameters implemented
> +   :widths: 5 5 5 85
> +
> +   * - Name
> +     - Type
> +     - Mode
> +     - Description
> +   * - ``fastboot``
> +     - boolean
> +     - driverinit
> +     - Set this param to enter fastboot mode.
> +
> +Flash Update
> +============
> +
> +The ``t7xx`` driver implements the flash update using the ``devlink-flash``
> +interface.
> +
> +The driver uses DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT to identify the type of
> +firmware image that need to be programmed upon the request by user space application.
> +
> +The supported list of firmware image types is described below.
> +
> +.. list-table:: Firmware Image types
> +    :widths: 15 85
> +
> +    * - Name
> +      - Description
> +    * - ``preloader``
> +      - The first-stage bootloader image
> +    * - ``loader_ext1``
> +      - Preloader extension image
> +    * - ``tee1``
> +      - ARM trusted firmware and TEE (Trusted Execution Environment) image
> +    * - ``lk``
> +      - The second-stage bootloader image
> +    * - ``spmfw``
> +      - MediaTek in-house ASIC for power management image
> +    * - ``sspm_1``
> +      - MediaTek in-house ASIC for power management under secure world image
> +    * - ``mcupm_1``
> +      - MediaTek in-house ASIC for cpu power management image
> +    * - ``dpm_1``
> +      - MediaTek in-house ASIC for dram power management image
> +    * - ``boot``
> +      - The kernel and dtb image
> +    * - ``rootfs``
> +      - Root filesystem image
> +    * - ``md1img``
> +      - Modem image
> +    * - ``md1dsp``
> +      - Modem DSP image
> +    * - ``mcf1``
> +      - Modem OTA image (Modem Configuration Framework) for operators
> +    * - ``mcf2``
> +      - Modem OTA image (Modem Configuration Framework) for OEM vendors
> +    * - ``mcf3``
> +      - Modem OTA image (other usage) for OEM configurations
> +
> +``t7xx`` driver uses fastboot protocol for fw flashing. In the fw flashing

it would make the documentation easier and faster to read if you just 
spelled out fw as firmware.

> +procedure, fastboot command & response are exchanged between driver and wwan
> +device.
> +
> +The wwan device is put into fastboot mode via devlink reload command, by
> +passing "driver_reinit" action.
> +
> +$ devlink dev reload pci/0000:$bdf action driver_reinit
> +
> +Upon completion of fw flashing or coredump collection the wwan device is
> +reset to normal mode using devlink reload command, by passing "fw_activate"
> +action.
> +
> +$ devlink dev reload pci/0000:$bdf action fw_activate
> +
> +Flash Commands:
> +===============
> +
> +$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
> +
> +$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
> +
> +$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
> +
> +$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
> +
> +$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
> +
> +$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
> +
> +$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
> +
> +$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
> +
> +$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
> +
> +$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
> +
> +$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
> +
> +$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
> +
> +Note: Component selects the partition type to be programmed.
> +
> +Regions
> +=======
> +
> +The ``t7xx`` driver supports core dump collection when device encounters
> +an exception. When wwan device encounters an exception, a snapshot of device
> +internal data will be taken by the driver using fastboot commands.
> +
> +Following regions are accessed for device internal data.
> +
> +.. list-table:: Regions implemented
> +    :widths: 15 85
> +
> +    * - Name
> +      - Description
> +    * - ``mr_dump``
> +      - The detailed modem component logs are captured in this region
> +    * - ``lk_dump``
> +      - This region dumps the current snapshot of lk
> +
> +
> +Region commands
> +===============
> +
> +$ devlink region show
> +
> +
> +$ devlink region new mr_dump
> +
> +$ devlink region read mr_dump snapshot 0 address 0 length $len
> +
> +$ devlink region del mr_dump snapshot 0
> +
> +$ devlink region new lk_dump
> +
> +$ devlink region read lk_dump snapshot 0 address 0 length $len
> +
> +$ devlink region del lk_dump snapshot 0
> +
> +Note: $len is actual len to be dumped.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan
  2023-01-06 16:27 ` [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan m.chetan.kumar
@ 2023-01-06 18:42   ` Jesse Brandeburg
  2023-01-08 14:14     ` Kumar, M Chetan
  0 siblings, 1 reply; 16+ messages in thread
From: Jesse Brandeburg @ 2023-01-06 18:42 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, Madhusmita Sahu

On 1/6/2023 8:27 AM, m.chetan.kumar@linux.intel.com wrote:
> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> 
> PCI rescan module implements "rescan work queue".
> In firmware flashing or coredump collection procedure
> WWAN device is programmed to boot in fastboot mode and
> a work item is scheduled for removal & detection.
> 
> The WWAN device is reset using APCI call as part driver
> removal flow. Work queue rescans pci bus at fixed interval
> for device detection, later when device is detect work queue
> exits.
> 
> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
> Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
> Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
> --
> v3:
>   * No Change.
> v2:
>   * Drop empty line inside critical sections.
>   * Correct log message.
>   * Correct logic inside t7xx_always_match().
>   * Drop hp_enable changes.
>   * Drop g_ prefix from t7xx_rescan_ctx.
>   * Use tab before comment in struct decl.
>   * Remove extra white space.
>   * Drop modem exception state check.
>   * Crit section newlines.
>   * Remove unnecessary header files inclusion.
>   * Drop spinlock around reset and rescan flow.
> ---
>   drivers/net/wwan/t7xx/Makefile          |  3 +-
>   drivers/net/wwan/t7xx/t7xx_modem_ops.c  |  3 +
>   drivers/net/wwan/t7xx/t7xx_pci.c        | 56 ++++++++++++++-
>   drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 96 +++++++++++++++++++++++++
>   drivers/net/wwan/t7xx/t7xx_pci_rescan.h | 28 ++++++++
>   5 files changed, 184 insertions(+), 2 deletions(-)
>   create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.c
>   create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.h
> 
> diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile
> index 268ff9e87e5b..ba5c607404a4 100644
> --- a/drivers/net/wwan/t7xx/Makefile
> +++ b/drivers/net/wwan/t7xx/Makefile
> @@ -17,7 +17,8 @@ mtk_t7xx-y:=	t7xx_pci.o \
>   		t7xx_hif_dpmaif_tx.o \
>   		t7xx_hif_dpmaif_rx.o  \
>   		t7xx_dpmaif.o \
> -		t7xx_netdev.o
> +		t7xx_netdev.o \
> +		t7xx_pci_rescan.o
>   
>   mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \
>   		t7xx_port_trace.o \
> diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
> index cbd65aa48721..2fcaea4694ba 100644
> --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
> +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
> @@ -37,6 +37,7 @@
>   #include "t7xx_modem_ops.h"
>   #include "t7xx_netdev.h"
>   #include "t7xx_pci.h"
> +#include "t7xx_pci_rescan.h"
>   #include "t7xx_pcie_mac.h"
>   #include "t7xx_port.h"
>   #include "t7xx_port_proxy.h"
> @@ -194,6 +195,8 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data)
>   
>   	msleep(RGU_RESET_DELAY_MS);
>   	t7xx_reset_device_via_pmic(t7xx_dev);
> +	t7xx_rescan_queue_work(t7xx_dev->pdev);
> +
>   	return IRQ_HANDLED;
>   }
>   
> diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c
> index 871f2a27a398..1e953ec7dd00 100644
> --- a/drivers/net/wwan/t7xx/t7xx_pci.c
> +++ b/drivers/net/wwan/t7xx/t7xx_pci.c
> @@ -38,6 +38,7 @@
>   #include "t7xx_mhccif.h"
>   #include "t7xx_modem_ops.h"
>   #include "t7xx_pci.h"
> +#include "t7xx_pci_rescan.h"
>   #include "t7xx_pcie_mac.h"
>   #include "t7xx_reg.h"
>   #include "t7xx_state_monitor.h"
> @@ -715,6 +716,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>   		return ret;
>   	}
>   
> +	t7xx_rescan_done();
>   	t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
>   	t7xx_pcie_mac_interrupts_en(t7xx_dev);
>   
> @@ -754,7 +756,59 @@ static struct pci_driver t7xx_pci_driver = {
>   	.shutdown = t7xx_pci_shutdown,
>   };
>   
> -module_pci_driver(t7xx_pci_driver);
> +static int __init t7xx_pci_init(void)
> +{
> +	int ret;
> +
> +	t7xx_pci_dev_rescan();
> +	ret = t7xx_rescan_init();
> +	if (ret) {
> +		pr_err("Failed to init t7xx rescan work\n");
> +		return ret;
> +	}
> +
> +	return pci_register_driver(&t7xx_pci_driver);
> +}
> +module_init(t7xx_pci_init);
> +
> +static int t7xx_always_match(struct device *dev, const void *data)
> +{
> +	struct pci_dev *pdev = to_pci_dev(dev);
> +	const struct pci_device_id *id = data;
> +
> +	if (pci_match_id(id, pdev))
> +		return 1;
> +
> +	return 0;
> +}
> +
> +static void __exit t7xx_pci_cleanup(void)
> +{
> +	int remove_flag = 0;
> +	struct device *dev;
> +
> +	dev = driver_find_device(&t7xx_pci_driver.driver, NULL, &t7xx_pci_table[0],
> +				 t7xx_always_match);
> +	if (dev) {
> +		pr_debug("unregister t7xx PCIe driver while device is still exist.\n");

nit: s/is still exist/still exists/

> +		put_device(dev);
> +		remove_flag = 1;
> +	} else {
> +		pr_debug("no t7xx PCIe driver found.\n");
> +	}
> +
> +	pci_lock_rescan_remove();
> +	pci_unregister_driver(&t7xx_pci_driver);
> +	pci_unlock_rescan_remove();
> +
> +	t7xx_rescan_deinit();
> +	if (remove_flag) {
> +		pr_debug("remove t7xx PCI device\n");
> +		pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
> +	}
> +}
> +
> +module_exit(t7xx_pci_cleanup);
>   
>   MODULE_AUTHOR("MediaTek Inc");
>   MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
> diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
> new file mode 100644
> index 000000000000..67f13c035846
> --- /dev/null
> +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
> @@ -0,0 +1,96 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021, MediaTek Inc.
> + * Copyright (c) 2021-2023, Intel Corporation.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ":t7xx:%s: " fmt, __func__
> +#define dev_fmt(fmt) "t7xx: " fmt
> +
> +#include <linux/delay.h>
> +#include <linux/pci.h>
> +#include <linux/spinlock.h>
> +#include <linux/workqueue.h>
> +
> +#include "t7xx_pci.h"
> +#include "t7xx_pci_rescan.h"
> +
> +static struct remove_rescan_context t7xx_rescan_ctx;
> +
> +void t7xx_pci_dev_rescan(void)
> +{
> +	struct pci_bus *b = NULL;
> +
> +	pci_lock_rescan_remove();
> +	while ((b = pci_find_next_bus(b)))
> +		pci_rescan_bus(b);
> +	pci_unlock_rescan_remove();
> +}
> +
> +void t7xx_rescan_done(void)
> +{
> +	if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
> +		atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
> +		pr_debug("Rescan probe\n");
> +	} else {
> +		pr_debug("Init probe\n");
> +	}
> +}
> +
> +static void t7xx_remove_rescan(struct work_struct *work)
> +{
> +	int num_retries = RESCAN_RETRIES;
> +	struct pci_dev *pdev;
> +
> +	atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
> +	pdev = t7xx_rescan_ctx.dev;
> +
> +	if (pdev) {
> +		pci_stop_and_remove_bus_device_locked(pdev);
> +		pr_debug("start remove and rescan flow\n");
> +	}
> +
> +	do {
> +		t7xx_pci_dev_rescan();
> +
> +		if (atomic_read(&t7xx_rescan_ctx.rescan_done))
> +			break;
> +
> +		msleep(DELAY_RESCAN_MTIME);
> +	} while (num_retries--);
> +}
> +
> +void t7xx_rescan_queue_work(struct pci_dev *pdev)
> +{
> +	if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
> +		dev_err(&pdev->dev, "Rescan failed\n");
> +		return;
> +	}
> +
> +	t7xx_rescan_ctx.dev = pdev;
> +	queue_work(t7xx_rescan_ctx.pcie_rescan_wq, &t7xx_rescan_ctx.service_task);
> +}
> +
> +int t7xx_rescan_init(void)
> +{
> +	atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
> +	t7xx_rescan_ctx.dev = NULL;
> +
> +	t7xx_rescan_ctx.pcie_rescan_wq = create_singlethread_workqueue(MTK_RESCAN_WQ);
> +	if (!t7xx_rescan_ctx.pcie_rescan_wq) {
> +		pr_err("Failed to create workqueue: %s\n", MTK_RESCAN_WQ);
> +		return -ENOMEM;
> +	}
> +
> +	INIT_WORK(&t7xx_rescan_ctx.service_task, t7xx_remove_rescan);
> +
> +	return 0;
> +}
> +
> +void t7xx_rescan_deinit(void)
> +{
> +	t7xx_rescan_ctx.dev = NULL;
> +	atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
> +	cancel_work_sync(&t7xx_rescan_ctx.service_task);
> +	destroy_workqueue(t7xx_rescan_ctx.pcie_rescan_wq);
> +}
> diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
> new file mode 100644
> index 000000000000..80b25c44151c
> --- /dev/null
> +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0-only
> + *
> + * Copyright (c) 2021, MediaTek Inc.
> + * Copyright (c) 2021-2023, Intel Corporation.
> + */
> +
> +#ifndef __T7XX_PCI_RESCAN_H__
> +#define __T7XX_PCI_RESCAN_H__
> +
> +#define MTK_RESCAN_WQ "mtk_rescan_wq"
> +
> +#define DELAY_RESCAN_MTIME 1000
> +#define RESCAN_RETRIES 35
> +
> +struct remove_rescan_context {
> +	struct work_struct service_task;
> +	struct workqueue_struct *pcie_rescan_wq;
> +	struct pci_dev *dev;
> +	atomic_t rescan_done;
> +};
> +
> +void t7xx_pci_dev_rescan(void);
> +void t7xx_rescan_queue_work(struct pci_dev *pdev);
> +int t7xx_rescan_init(void);
> +void t7xx_rescan_deinit(void);
> +void t7xx_rescan_done(void);
> +
> +#endif	/* __T7XX_PCI_RESCAN_H__ */


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection
  2023-01-06 16:27 ` [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection m.chetan.kumar
@ 2023-01-06 18:50   ` Jesse Brandeburg
  0 siblings, 0 replies; 16+ messages in thread
From: Jesse Brandeburg @ 2023-01-06 18:50 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek,
	Mishra Soumya Prakash

On 1/6/2023 8:27 AM, m.chetan.kumar@linux.intel.com wrote:
> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> 
> Adds support for t7xx wwan device firmware flashing & coredump collection
> using devlink.
> 
> 1> Driver Registers with Devlink framework.
> 2> Implements devlink ops flash_update callback that programs modem fw.
> 3> Creates region & snapshot required for device coredump log collection.
> 
> On early detection of wwan device in fastboot mode driver sets up CLDMA0 HW
> tx/rx queues for raw data transfer and then registers to devlink framework.
> On user space application issuing command for firmware update the driver
> sends fastboot flash command & firmware to program NAND.
> 
> In flashing procedure the fastboot command & response are exchanged between
> driver and device. Once firmware flashing is success completion status is
> reported to user space application.
> 
> Below is the devlink command usage for firmware flashing
> 
> $devlink dev flash pci/$BDF file ABC.img component ABC
> 
> Note: ABC.img is the firmware to be programmed to "ABC" partition.
> 
> In case of coredump collection when wwan device encounters an exception
> it reboots & stays in fastboot mode for coredump collection by host driver.
> On detecting exception state driver collects the core dump, creates the
> devlink region & reports an event to user space application for dump
> collection. The user space application invokes devlink region read command
> for dump collection.
> 
> Below are the devlink commands used for coredump collection.
> 
> devlink region new pci/$BDF/mr_dump
> devlink region read pci/$BDF/mr_dump snapshot $ID address $ADD length $LEN
> devlink region del pci/$BDF/mr_dump snapshot $ID
> 
> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
> Signed-off-by: Devegowda Chandrashekar <chandrashekar.devegowda@intel.com>
> Signed-off-by: Mishra Soumya Prakash <soumya.prakash.mishra@intel.com>
> --
> v3:
>   * No Change.
> v2:
>   * Remove devlink pointer inside the port state container.
>   * Rename t7xx_devlink_region_list to t7xx_devlink_region_infos &
>     use region index in initialization.
>   * Change t7xx_devlink_region_infos to const.
>   * Handle remaining packet data if the buffer is less than the skb data.
>   * Drop t7xx_devlink_fb_send_buffer(), push fragmentation logic to
>     t7xx_devlink_port_write().
>   * Add "\n" to log message.
>   * Move mrdump_region allocation to devlink initialization.
>   * Drop snprintf for CTS command fill.
>   * Drop intermediate mdata buffer & zipsize.
>   * For mcmd use strcmp instead of strncmp.
>   * Drop set_fastboot_dl instead use devlink param for fastboot operational mode.
>   * Drop unnecessary logs.
>   * Change t7xx_devlink_create_region to t7xx_devlink_create_regions.
>   * Use BUILD_BUG_ON on array size checks.
>   * Use ARRAY_SIZE inside loop.
>   * Correct indentation.
>   * Drop odd empty line.
>   * Push common devlink initialization code to t7xx_devlink_init.
>   * Use skb_queue_purge instead of running loop to free skbs.
>   * Change t7xx_regions index to enums.
>   * Remove dev in devlink container.
>   * Refactor struct to separate out devlink static and dynamic data structs.
>   * Use min_t.
>   * Drop unnecessary var assginment during initialization.
>   * Change while() to for().
>   * Correct size check.
>   * Rename result to ret.
>   * Clean-up error handling path in t7xx_devlink_fb_get_core & t7xx_devlink_fb_dump_log.
>   * Drop __func__ in log message.
>   * Change NOTY to NOTIFY.
>   * Push channel enable or disable cb to port proxy.
>   * Use array index in t7xx_devlink_region_list initialization.
>   * Drop t7xx_port_proxy_get_port_by_name() instead access port name directly via port_prox.
>   * Drop udev based event reporting logic.
>   * Drop get_core prefix in goto label.
>   * Remove unnessary header files.
>   * Allocate memory for mrdump_region->buf inside get_core.
>   * Remove 'region->buf' in t7xx_devlink_region_snapshot.
>   * Destroy workqueue on following error case in 'devlink_init'.
>   * Remove useless checks(dl->mode) and condition(dl->wq).
>   * Support devlink component versioning.
>   * Kconfig changes to select devlink.

LGTM, but I wouldn't mind having someone with more devlink flash 
experience review.

Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration
  2023-01-06 18:31   ` Jesse Brandeburg
@ 2023-01-08 14:07     ` Kumar, M Chetan
  0 siblings, 0 replies; 16+ messages in thread
From: Kumar, M Chetan @ 2023-01-08 14:07 UTC (permalink / raw)
  To: Jesse Brandeburg, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, Madhusmita Sahu

Hi Jesse,
Thank you for the feedback.

On 1/7/2023 12:01 AM, Jesse Brandeburg wrote:
> On 1/6/2023 8:26 AM, m.chetan.kumar@linux.intel.com wrote:
>> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>>
>> 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.
>>
>> This patch adds the infrastructure required to create the
>> early ports which also requires a different configuration of
>> CLDMA queues.
> 
> nit: use imperative voice in your commit messages: no "this patch".
> instead:
> "Add the infrastructure..."

Sure. Will correct it.

> 
>>
>> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
>> Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
>> Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
>> Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
>> Signed-off-by: Devegowda Chandrashekar 
>> <chandrashekar.devegowda@intel.com>
>> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>> -- 
>> v3:
>>   * No Change.
>> v2:
>>   * Move recv_skb handler to cldma_queue.
>>   * Drop cldma_queue_type.
>>   * Restore prototype of t7xx_port_send_raw_skb().
>>   * Remove PORT_CFG_ID_INVALID check in t7xx_port_proxy_set_cfg().
>>   * Add space before */.
>>   * Drop unnecessary logs.
>>   * Use WARN_ON on early port.
>>   * Use new MISC_DEV_STATUS_INVALID instead of MISC_DEV_STATUS.
>>   * Use macros instead of const identifiers.
>>   * Change ports member type from pointer to array type.
>>   * Prefix LK_EVENT_XX with MISC prefix.
>>   * Use t7xx prefix for device_stage enums.
>>   * Correct log messages.
>>   * Don’t override pkt_size for non-download port under dedicated Queue.
>>   * Drop cldma_txq_rxq_ids.
>>   * Use macro for txq/rxq index.
>>   * Use warn_on for rxq_idx comparison.
>>   * Drop t7xx_port_proxy_get_port_by_name().
>>   * Replace fsm poll with read_poll_timeout().
>>   * Use "\n" consistently across log message.
>>   * Remove local var _dev prefixes in fsm_routine_start().
>>   * Use max_t.
> 
> ...
> 
> 
>> diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h 
>> b/drivers/net/wwan/t7xx/t7xx_reg.h
>> index c41d7d094c08..44352cd02460 100644
>> --- a/drivers/net/wwan/t7xx/t7xx_reg.h
>> +++ b/drivers/net/wwan/t7xx/t7xx_reg.h
>> @@ -102,10 +102,28 @@ enum t7xx_pm_resume_state {
>>   };
>>   #define T7XX_PCIE_MISC_DEV_STATUS        0x0d1c
>> -#define MISC_STAGE_MASK                GENMASK(2, 0)
>> -#define MISC_RESET_TYPE_PLDR            BIT(26)
>>   #define MISC_RESET_TYPE_FLDR            BIT(27)
>> -#define LINUX_STAGE                4
>> +#define MISC_RESET_TYPE_PLDR            BIT(26)
>> +#define MISC_DEV_STATUS_MASK            GENMASK(15, 0)
>> +#define MISC_DEV_STATUS_INVALID            GENMASK(15, 0)
> 
> I don't see any uses of this, even though it's mentioned in the commit 
> message. The only reason I looked was because it was weird to have 
> DEV_STATUS_MASK and STATUS_INVALID be the same values, is that correct?

Both are unused. Will drop it.

> 
> 
>> +#define MISC_LK_EVENT_MASK            GENMASK(11, 8)
>> +
>> +enum lk_event_id {
>> +    LK_EVENT_NORMAL = 0,
>> +    LK_EVENT_CREATE_PD_PORT = 1,
>> +    LK_EVENT_CREATE_POST_DL_PORT = 2,
>> +    LK_EVENT_RESET = 7,
>> +};
>> +
>> +#define MISC_STAGE_MASK                GENMASK(2, 0)
>> +
>> +enum t7xx_device_stage {
>> +    T7XX_DEV_STAGE_INIT = 0,
>> +    T7XX_DEV_STAGE_BROM_PRE = 1,
>> +    T7XX_DEV_STAGE_BROM_POST = 2,
>> +    T7XX_DEV_STAGE_LK = 3,
>> +    T7XX_DEV_STAGE_LINUX = 4,
>> +};
>>   #define T7XX_PCIE_RESOURCE_STATUS        0x0d28
>>   #define T7XX_PCIE_RESOURCE_STS_MSK        GENMASK(4, 0)
>> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c 
>> b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
>> index 80edb8e75a6a..76fb5d57d4d7 100644
>> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
>> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
>> @@ -206,6 +206,34 @@ static void fsm_routine_exception(struct 
>> t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm
>>           fsm_finish_command(ctl, cmd, 0);
>>   }
>> +static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, 
>> unsigned int status)
>> +{
>> +    struct t7xx_modem *md = ctl->md;
>> +    struct cldma_ctrl *md_ctrl;
>> +    enum lk_event_id lk_event;
>> +    struct device *dev;
>> +
>> +    dev = &md->t7xx_dev->pdev->dev;
>> +    lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status);
>> +    switch (lk_event) {
>> +    case LK_EVENT_NORMAL:
>> +    case LK_EVENT_RESET:
>> +        break;
>> +
>> +    case LK_EVENT_CREATE_PD_PORT:
>> +        md_ctrl = md->md_ctrl[CLDMA_ID_AP];
>> +        t7xx_cldma_hif_hw_init(md_ctrl);
>> +        t7xx_cldma_stop(md_ctrl);
>> +        t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG);
>> +        t7xx_cldma_start(md_ctrl);
>> +        break;
>> +
>> +    default:
>> +        dev_err(dev, "Invalid LK event %d\n", lk_event);
>> +        break;
>> +    }
>> +}
>> +
>>   static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl)
>>   {
>>       ctl->curr_state = FSM_STATE_STOPPED;
>> @@ -317,8 +345,9 @@ static int fsm_routine_starting(struct 
>> t7xx_fsm_ctl *ctl)
>>   static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct 
>> t7xx_fsm_command *cmd)
>>   {
>>       struct t7xx_modem *md = ctl->md;
>> -    u32 dev_status;
>> -    int ret;
>> +    struct device *dev;
>> +    u32 status, stage;
>> +    int ret = 0;
>>       if (!md)
>>           return;
>> @@ -329,23 +358,55 @@ static void fsm_routine_start(struct 
>> t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
>>           return;
>>       }
>> +    dev = &md->t7xx_dev->pdev->dev;
>>       ctl->curr_state = FSM_STATE_PRE_START;
>>       t7xx_md_event_notify(md, FSM_PRE_START);
>> -    ret = read_poll_timeout(ioread32, dev_status,
>> -                (dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 
>> 2000000,
>> -                false, IREG_BASE(md->t7xx_dev) + 
>> T7XX_PCIE_MISC_DEV_STATUS);
>> +    ret = read_poll_timeout(ioread32, status,
>> +                ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LINUX) ||
>> +                ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LK), 
>> 100000,
>> +                20000000, false, IREG_BASE(md->t7xx_dev) +
>> +                T7XX_PCIE_MISC_DEV_STATUS);
>> +
>>       if (ret) {
>> -        struct device *dev = &md->t7xx_dev->pdev->dev;
>> +        ret = -ETIMEDOUT;
>> +        dev_err(dev, "read poll %d\n", ret);
>> +        goto finish_command;
>> +    }
>> -        fsm_finish_command(ctl, cmd, -ETIMEDOUT);
>> -        dev_err(dev, "Invalid device status 0x%lx\n", dev_status & 
>> MISC_STAGE_MASK);
>> -        return;
>> +    if (status != ctl->prev_status) {
>> +        stage = FIELD_GET(MISC_STAGE_MASK, status);
> 
> if stage is only used down here you can declare it locally. cppcheck has 
> a check that will find these for you.

Ok. Will consider it.

> 
>> +        switch (stage) {
>> +        case T7XX_DEV_STAGE_INIT:
>> +        case T7XX_DEV_STAGE_BROM_PRE:
>> +        case T7XX_DEV_STAGE_BROM_POST:
>> +            dev_info(dev, "BROM_STAGE Entered\n");
>> +            ret = t7xx_fsm_append_cmd(ctl, FSM_CMD_START, 0);
>> +            break;
>> +
>> +        case T7XX_DEV_STAGE_LK:
>> +            dev_info(dev, "LK_STAGE Entered\n");
>> +            t7xx_lk_stage_event_handling(ctl, status);
>> +            break;
>> +
>> +        case T7XX_DEV_STAGE_LINUX:
>> +            dev_info(dev, "LINUX_STAGE Entered\n");
>> +            t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
>> +            t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
>> +            t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM |
>> +                         D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK);
>> +            t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL);
>> +            ret = fsm_routine_starting(ctl);
>> +            break;
>> +
>> +        default:
>> +            break;
>> +        }
>> +        ctl->prev_status = status;
>>       }
>> -    t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
>> -    t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
>> -    fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl));
>> +finish_command:
>> +    fsm_finish_command(ctl, cmd, ret);
>>   }
>>   static int fsm_main_thread(void *data)
>> @@ -516,6 +577,7 @@ void t7xx_fsm_reset(struct t7xx_modem *md)
>>       fsm_flush_event_cmd_qs(ctl);
>>       ctl->curr_state = FSM_STATE_STOPPED;
>>       ctl->exp_flg = false;
>> +    ctl->prev_status = 0;
>>   }
>>   int t7xx_fsm_init(struct t7xx_modem *md)
>> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h 
>> b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
>> index b6e76f3903c8..5e8012567ba1 100644
>> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
>> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
>> @@ -96,6 +96,7 @@ struct t7xx_fsm_ctl {
>>       bool            exp_flg;
>>       spinlock_t        notifier_lock;        /* Protects notifier 
>> list */
>>       struct list_head    notifier_list;
>> +    u32                     prev_status;
>>   };
>>   struct t7xx_fsm_event {
> 

-- 
Chetan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan
  2023-01-06 18:42   ` Jesse Brandeburg
@ 2023-01-08 14:14     ` Kumar, M Chetan
  0 siblings, 0 replies; 16+ messages in thread
From: Kumar, M Chetan @ 2023-01-08 14:14 UTC (permalink / raw)
  To: Jesse Brandeburg, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, Madhusmita Sahu

On 1/7/2023 12:12 AM, Jesse Brandeburg wrote:
> On 1/6/2023 8:27 AM, m.chetan.kumar@linux.intel.com wrote:
>> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>>
>> PCI rescan module implements "rescan work queue".
>> In firmware flashing or coredump collection procedure
>> WWAN device is programmed to boot in fastboot mode and
>> a work item is scheduled for removal & detection.
>>
>> The WWAN device is reset using APCI call as part driver
>> removal flow. Work queue rescans pci bus at fixed interval
>> for device detection, later when device is detect work queue
>> exits.
>>
>> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
>> Co-developed-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
>> Signed-off-by: Madhusmita Sahu <madhusmita.sahu@intel.com>
>> Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
>> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>> Signed-off-by: Devegowda Chandrashekar 
>> <chandrashekar.devegowda@intel.com>
>> -- 
>> v3:
>>   * No Change.
>> v2:
>>   * Drop empty line inside critical sections.
>>   * Correct log message.
>>   * Correct logic inside t7xx_always_match().
>>   * Drop hp_enable changes.
>>   * Drop g_ prefix from t7xx_rescan_ctx.
>>   * Use tab before comment in struct decl.
>>   * Remove extra white space.
>>   * Drop modem exception state check.
>>   * Crit section newlines.
>>   * Remove unnecessary header files inclusion.
>>   * Drop spinlock around reset and rescan flow.
>> ---
>>   drivers/net/wwan/t7xx/Makefile          |  3 +-
>>   drivers/net/wwan/t7xx/t7xx_modem_ops.c  |  3 +
>>   drivers/net/wwan/t7xx/t7xx_pci.c        | 56 ++++++++++++++-
>>   drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 96 +++++++++++++++++++++++++
>>   drivers/net/wwan/t7xx/t7xx_pci_rescan.h | 28 ++++++++
>>   5 files changed, 184 insertions(+), 2 deletions(-)
>>   create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.c
>>   create mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.h
>>
>> diff --git a/drivers/net/wwan/t7xx/Makefile 
>> b/drivers/net/wwan/t7xx/Makefile
>> index 268ff9e87e5b..ba5c607404a4 100644
>> --- a/drivers/net/wwan/t7xx/Makefile
>> +++ b/drivers/net/wwan/t7xx/Makefile
>> @@ -17,7 +17,8 @@ mtk_t7xx-y:=    t7xx_pci.o \
>>           t7xx_hif_dpmaif_tx.o \
>>           t7xx_hif_dpmaif_rx.o  \
>>           t7xx_dpmaif.o \
>> -        t7xx_netdev.o
>> +        t7xx_netdev.o \
>> +        t7xx_pci_rescan.o
>>   mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \
>>           t7xx_port_trace.o \
>> diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c 
>> b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
>> index cbd65aa48721..2fcaea4694ba 100644
>> --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
>> +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
>> @@ -37,6 +37,7 @@
>>   #include "t7xx_modem_ops.h"
>>   #include "t7xx_netdev.h"
>>   #include "t7xx_pci.h"
>> +#include "t7xx_pci_rescan.h"
>>   #include "t7xx_pcie_mac.h"
>>   #include "t7xx_port.h"
>>   #include "t7xx_port_proxy.h"
>> @@ -194,6 +195,8 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, 
>> void *data)
>>       msleep(RGU_RESET_DELAY_MS);
>>       t7xx_reset_device_via_pmic(t7xx_dev);
>> +    t7xx_rescan_queue_work(t7xx_dev->pdev);
>> +
>>       return IRQ_HANDLED;
>>   }
>> diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c 
>> b/drivers/net/wwan/t7xx/t7xx_pci.c
>> index 871f2a27a398..1e953ec7dd00 100644
>> --- a/drivers/net/wwan/t7xx/t7xx_pci.c
>> +++ b/drivers/net/wwan/t7xx/t7xx_pci.c
>> @@ -38,6 +38,7 @@
>>   #include "t7xx_mhccif.h"
>>   #include "t7xx_modem_ops.h"
>>   #include "t7xx_pci.h"
>> +#include "t7xx_pci_rescan.h"
>>   #include "t7xx_pcie_mac.h"
>>   #include "t7xx_reg.h"
>>   #include "t7xx_state_monitor.h"
>> @@ -715,6 +716,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, 
>> const struct pci_device_id *id)
>>           return ret;
>>       }
>> +    t7xx_rescan_done();
>>       t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
>>       t7xx_pcie_mac_interrupts_en(t7xx_dev);
>> @@ -754,7 +756,59 @@ static struct pci_driver t7xx_pci_driver = {
>>       .shutdown = t7xx_pci_shutdown,
>>   };
>> -module_pci_driver(t7xx_pci_driver);
>> +static int __init t7xx_pci_init(void)
>> +{
>> +    int ret;
>> +
>> +    t7xx_pci_dev_rescan();
>> +    ret = t7xx_rescan_init();
>> +    if (ret) {
>> +        pr_err("Failed to init t7xx rescan work\n");
>> +        return ret;
>> +    }
>> +
>> +    return pci_register_driver(&t7xx_pci_driver);
>> +}
>> +module_init(t7xx_pci_init);
>> +
>> +static int t7xx_always_match(struct device *dev, const void *data)
>> +{
>> +    struct pci_dev *pdev = to_pci_dev(dev);
>> +    const struct pci_device_id *id = data;
>> +
>> +    if (pci_match_id(id, pdev))
>> +        return 1;
>> +
>> +    return 0;
>> +}
>> +
>> +static void __exit t7xx_pci_cleanup(void)
>> +{
>> +    int remove_flag = 0;
>> +    struct device *dev;
>> +
>> +    dev = driver_find_device(&t7xx_pci_driver.driver, NULL, 
>> &t7xx_pci_table[0],
>> +                 t7xx_always_match);
>> +    if (dev) {
>> +        pr_debug("unregister t7xx PCIe driver while device is still 
>> exist.\n");
> 
> nit: s/is still exist/still exists/

Ok, will correct it.

> 
>> +        put_device(dev);
>> +        remove_flag = 1;
>> +    } else {
>> +        pr_debug("no t7xx PCIe driver found.\n");
>> +    }
>> +
>> +    pci_lock_rescan_remove();
>> +    pci_unregister_driver(&t7xx_pci_driver);
>> +    pci_unlock_rescan_remove();
>> +
>> +    t7xx_rescan_deinit();
>> +    if (remove_flag) {
>> +        pr_debug("remove t7xx PCI device\n");
>> +        pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
>> +    }
>> +}
>> +
>> +module_exit(t7xx_pci_cleanup);
>>   MODULE_AUTHOR("MediaTek Inc");
>>   MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
>> diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c 
>> b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
>> new file mode 100644
>> index 000000000000..67f13c035846
>> --- /dev/null
>> +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c
>> @@ -0,0 +1,96 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2021, MediaTek Inc.
>> + * Copyright (c) 2021-2023, Intel Corporation.
>> + */
>> +
>> +#define pr_fmt(fmt) KBUILD_MODNAME ":t7xx:%s: " fmt, __func__
>> +#define dev_fmt(fmt) "t7xx: " fmt
>> +
>> +#include <linux/delay.h>
>> +#include <linux/pci.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/workqueue.h>
>> +
>> +#include "t7xx_pci.h"
>> +#include "t7xx_pci_rescan.h"
>> +
>> +static struct remove_rescan_context t7xx_rescan_ctx;
>> +
>> +void t7xx_pci_dev_rescan(void)
>> +{
>> +    struct pci_bus *b = NULL;
>> +
>> +    pci_lock_rescan_remove();
>> +    while ((b = pci_find_next_bus(b)))
>> +        pci_rescan_bus(b);
>> +    pci_unlock_rescan_remove();
>> +}
>> +
>> +void t7xx_rescan_done(void)
>> +{
>> +    if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
>> +        atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
>> +        pr_debug("Rescan probe\n");
>> +    } else {
>> +        pr_debug("Init probe\n");
>> +    }
>> +}
>> +
>> +static void t7xx_remove_rescan(struct work_struct *work)
>> +{
>> +    int num_retries = RESCAN_RETRIES;
>> +    struct pci_dev *pdev;
>> +
>> +    atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
>> +    pdev = t7xx_rescan_ctx.dev;
>> +
>> +    if (pdev) {
>> +        pci_stop_and_remove_bus_device_locked(pdev);
>> +        pr_debug("start remove and rescan flow\n");
>> +    }
>> +
>> +    do {
>> +        t7xx_pci_dev_rescan();
>> +
>> +        if (atomic_read(&t7xx_rescan_ctx.rescan_done))
>> +            break;
>> +
>> +        msleep(DELAY_RESCAN_MTIME);
>> +    } while (num_retries--);
>> +}
>> +
>> +void t7xx_rescan_queue_work(struct pci_dev *pdev)
>> +{
>> +    if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) {
>> +        dev_err(&pdev->dev, "Rescan failed\n");
>> +        return;
>> +    }
>> +
>> +    t7xx_rescan_ctx.dev = pdev;
>> +    queue_work(t7xx_rescan_ctx.pcie_rescan_wq, 
>> &t7xx_rescan_ctx.service_task);
>> +}
>> +
>> +int t7xx_rescan_init(void)
>> +{
>> +    atomic_set(&t7xx_rescan_ctx.rescan_done, 1);
>> +    t7xx_rescan_ctx.dev = NULL;
>> +
>> +    t7xx_rescan_ctx.pcie_rescan_wq = 
>> create_singlethread_workqueue(MTK_RESCAN_WQ);
>> +    if (!t7xx_rescan_ctx.pcie_rescan_wq) {
>> +        pr_err("Failed to create workqueue: %s\n", MTK_RESCAN_WQ);
>> +        return -ENOMEM;
>> +    }
>> +
>> +    INIT_WORK(&t7xx_rescan_ctx.service_task, t7xx_remove_rescan);
>> +
>> +    return 0;
>> +}
>> +
>> +void t7xx_rescan_deinit(void)
>> +{
>> +    t7xx_rescan_ctx.dev = NULL;
>> +    atomic_set(&t7xx_rescan_ctx.rescan_done, 0);
>> +    cancel_work_sync(&t7xx_rescan_ctx.service_task);
>> +    destroy_workqueue(t7xx_rescan_ctx.pcie_rescan_wq);
>> +}
>> diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h 
>> b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
>> new file mode 100644
>> index 000000000000..80b25c44151c
>> --- /dev/null
>> +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h
>> @@ -0,0 +1,28 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only
>> + *
>> + * Copyright (c) 2021, MediaTek Inc.
>> + * Copyright (c) 2021-2023, Intel Corporation.
>> + */
>> +
>> +#ifndef __T7XX_PCI_RESCAN_H__
>> +#define __T7XX_PCI_RESCAN_H__
>> +
>> +#define MTK_RESCAN_WQ "mtk_rescan_wq"
>> +
>> +#define DELAY_RESCAN_MTIME 1000
>> +#define RESCAN_RETRIES 35
>> +
>> +struct remove_rescan_context {
>> +    struct work_struct service_task;
>> +    struct workqueue_struct *pcie_rescan_wq;
>> +    struct pci_dev *dev;
>> +    atomic_t rescan_done;
>> +};
>> +
>> +void t7xx_pci_dev_rescan(void);
>> +void t7xx_rescan_queue_work(struct pci_dev *pdev);
>> +int t7xx_rescan_init(void);
>> +void t7xx_rescan_deinit(void);
>> +void t7xx_rescan_done(void);
>> +
>> +#endif    /* __T7XX_PCI_RESCAN_H__ */
> 

-- 
Chetan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation
  2023-01-06 18:37   ` Jesse Brandeburg
@ 2023-01-08 14:20     ` Kumar, M Chetan
  0 siblings, 0 replies; 16+ messages in thread
From: Kumar, M Chetan @ 2023-01-08 14:20 UTC (permalink / raw)
  To: Jesse Brandeburg, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, linux-doc, jiri,
	corbet

On 1/7/2023 12:07 AM, Jesse Brandeburg wrote:
> On 1/6/2023 8:28 AM, m.chetan.kumar@linux.intel.com wrote:
>> From: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>>
>> Document the t7xx devlink commands usage for fw flashing &
> 
> it would make the documentation easier and faster to read if you just 
> spelled out fw as firmware.

Sure. Will correct all such instances.

> 
>> coredump collection.
>>
>> Refer to t7xx.rst file for details.
>>
>> Signed-off-by: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
>> Signed-off-by: Devegowda Chandrashekar 
>> <chandrashekar.devegowda@intel.com>
>> -- 
>> v3:
>>   * No Change.
>> v2:
>>   * Documentation correction.
>>   * Add param details.
>> ---
>>   Documentation/networking/devlink/index.rst |   1 +
>>   Documentation/networking/devlink/t7xx.rst  | 161 +++++++++++++++++++++
>>   2 files changed, 162 insertions(+)
>>   create mode 100644 Documentation/networking/devlink/t7xx.rst
>>
>> diff --git a/Documentation/networking/devlink/index.rst 
>> b/Documentation/networking/devlink/index.rst
>> index fee4d3968309..0c4f5961e78f 100644
>> --- a/Documentation/networking/devlink/index.rst
>> +++ b/Documentation/networking/devlink/index.rst
>> @@ -66,3 +66,4 @@ parameters, info versions, and other features it 
>> supports.
>>      prestera
>>      iosm
>>      octeontx2
>> +   t7xx
>> diff --git a/Documentation/networking/devlink/t7xx.rst 
>> b/Documentation/networking/devlink/t7xx.rst
>> new file mode 100644
>> index 000000000000..de220878ad76
>> --- /dev/null
>> +++ b/Documentation/networking/devlink/t7xx.rst
>> @@ -0,0 +1,161 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +====================
>> +t7xx devlink support
>> +====================
>> +
>> +This document describes the devlink features implemented by the ``t7xx``
>> +device driver.
>> +
>> +Parameters
>> +==========
>> +The ``t7xx_driver`` driver implements the following driver-specific 
>> parameters.
>> +
>> +.. list-table:: Driver-specific parameters implemented
>> +   :widths: 5 5 5 85
>> +
>> +   * - Name
>> +     - Type
>> +     - Mode
>> +     - Description
>> +   * - ``fastboot``
>> +     - boolean
>> +     - driverinit
>> +     - Set this param to enter fastboot mode.
>> +
>> +Flash Update
>> +============
>> +
>> +The ``t7xx`` driver implements the flash update using the 
>> ``devlink-flash``
>> +interface.
>> +
>> +The driver uses DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT to identify 
>> the type of
>> +firmware image that need to be programmed upon the request by user 
>> space application.
>> +
>> +The supported list of firmware image types is described below.
>> +
>> +.. list-table:: Firmware Image types
>> +    :widths: 15 85
>> +
>> +    * - Name
>> +      - Description
>> +    * - ``preloader``
>> +      - The first-stage bootloader image
>> +    * - ``loader_ext1``
>> +      - Preloader extension image
>> +    * - ``tee1``
>> +      - ARM trusted firmware and TEE (Trusted Execution Environment) 
>> image
>> +    * - ``lk``
>> +      - The second-stage bootloader image
>> +    * - ``spmfw``
>> +      - MediaTek in-house ASIC for power management image
>> +    * - ``sspm_1``
>> +      - MediaTek in-house ASIC for power management under secure 
>> world image
>> +    * - ``mcupm_1``
>> +      - MediaTek in-house ASIC for cpu power management image
>> +    * - ``dpm_1``
>> +      - MediaTek in-house ASIC for dram power management image
>> +    * - ``boot``
>> +      - The kernel and dtb image
>> +    * - ``rootfs``
>> +      - Root filesystem image
>> +    * - ``md1img``
>> +      - Modem image
>> +    * - ``md1dsp``
>> +      - Modem DSP image
>> +    * - ``mcf1``
>> +      - Modem OTA image (Modem Configuration Framework) for operators
>> +    * - ``mcf2``
>> +      - Modem OTA image (Modem Configuration Framework) for OEM vendors
>> +    * - ``mcf3``
>> +      - Modem OTA image (other usage) for OEM configurations
>> +
>> +``t7xx`` driver uses fastboot protocol for fw flashing. In the fw 
>> flashing
> 
> it would make the documentation easier and faster to read if you just 
> spelled out fw as firmware.
> 
>> +procedure, fastboot command & response are exchanged between driver 
>> and wwan
>> +device.
>> +
>> +The wwan device is put into fastboot mode via devlink reload command, by
>> +passing "driver_reinit" action.
>> +
>> +$ devlink dev reload pci/0000:$bdf action driver_reinit
>> +
>> +Upon completion of fw flashing or coredump collection the wwan device is
>> +reset to normal mode using devlink reload command, by passing 
>> "fw_activate"
>> +action.
>> +
>> +$ devlink dev reload pci/0000:$bdf action fw_activate
>> +
>> +Flash Commands:
>> +===============
>> +
>> +$ devlink dev flash pci/0000:$bdf file 
>> preloader_k6880v1_mdot2_datacard.bin component "preloader"
>> +
>> +$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img 
>> component "loader_ext1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
>> +
>> +$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component 
>> "spmfw"
>> +
>> +$ devlink dev flash pci/0000:$bdf file sspm-verified.img component 
>> "sspm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component 
>> "mcupm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file dpm-verified.img component 
>> "dpm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file boot-verified.img component 
>> "boot"
>> +
>> +$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
>> +
>> +$ devlink dev flash pci/0000:$bdf file modem-verified.img component 
>> "md1img"
>> +
>> +$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component 
>> "md1dsp"
>> +
>> +$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
>> +
>> +$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
>> +
>> +Note: Component selects the partition type to be programmed.
>> +
>> +Regions
>> +=======
>> +
>> +The ``t7xx`` driver supports core dump collection when device encounters
>> +an exception. When wwan device encounters an exception, a snapshot of 
>> device
>> +internal data will be taken by the driver using fastboot commands.
>> +
>> +Following regions are accessed for device internal data.
>> +
>> +.. list-table:: Regions implemented
>> +    :widths: 15 85
>> +
>> +    * - Name
>> +      - Description
>> +    * - ``mr_dump``
>> +      - The detailed modem component logs are captured in this region
>> +    * - ``lk_dump``
>> +      - This region dumps the current snapshot of lk
>> +
>> +
>> +Region commands
>> +===============
>> +
>> +$ devlink region show
>> +
>> +
>> +$ devlink region new mr_dump
>> +
>> +$ devlink region read mr_dump snapshot 0 address 0 length $len
>> +
>> +$ devlink region del mr_dump snapshot 0
>> +
>> +$ devlink region new lk_dump
>> +
>> +$ devlink region read lk_dump snapshot 0 address 0 length $len
>> +
>> +$ devlink region del lk_dump snapshot 0
>> +
>> +Note: $len is actual len to be dumped.
> 

-- 
Chetan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation
  2023-01-06 16:28 ` [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation m.chetan.kumar
  2023-01-06 18:37   ` Jesse Brandeburg
@ 2023-01-09  3:48   ` Bagas Sanjaya
  2023-01-09 16:07     ` Kumar, M Chetan
  1 sibling, 1 reply; 16+ messages in thread
From: Bagas Sanjaya @ 2023-01-09  3:48 UTC (permalink / raw)
  To: m.chetan.kumar, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, linux-doc, jiri,
	corbet

[-- Attachment #1: Type: text/plain, Size: 8999 bytes --]

On Fri, Jan 06, 2023 at 09:58:06PM +0530, m.chetan.kumar@linux.intel.com wrote:
> Refer to t7xx.rst file for details.

Above line is unnecessary.

> +The wwan device is put into fastboot mode via devlink reload command, by
> +passing "driver_reinit" action.
> +
> +$ devlink dev reload pci/0000:$bdf action driver_reinit
> +
> +Upon completion of fw flashing or coredump collection the wwan device is
> +reset to normal mode using devlink reload command, by passing "fw_activate"
> +action.
> +
> +$ devlink dev reload pci/0000:$bdf action fw_activate

Personally I prefer to put command-line explanations below the actual
command:

---- >8 ----

diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
index de220878ad7649..24f9e0ee69bffb 100644
--- a/Documentation/networking/devlink/t7xx.rst
+++ b/Documentation/networking/devlink/t7xx.rst
@@ -74,17 +74,21 @@ The supported list of firmware image types is described below.
 procedure, fastboot command & response are exchanged between driver and wwan
 device.
 
+::
+
+  $ devlink dev reload pci/0000:$bdf action driver_reinit
+
 The wwan device is put into fastboot mode via devlink reload command, by
 passing "driver_reinit" action.
 
-$ devlink dev reload pci/0000:$bdf action driver_reinit
+::
+
+  $ devlink dev reload pci/0000:$bdf action fw_activate
 
 Upon completion of fw flashing or coredump collection the wwan device is
 reset to normal mode using devlink reload command, by passing "fw_activate"
 action.
 
-$ devlink dev reload pci/0000:$bdf action fw_activate
-
 Flash Commands:
 ===============
 

However, I find it's odd to jump from firmware image type list directly to
devlink usage. Perhaps the latter should be put into the following section
below?

I also find that there is minor inconsistency of keyword formatting, so I
have to inline-code the uninlined remainings:

---- >8 ----

diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
index 24f9e0ee69bffb..d8feefe116c978 100644
--- a/Documentation/networking/devlink/t7xx.rst
+++ b/Documentation/networking/devlink/t7xx.rst
@@ -29,7 +29,7 @@ Flash Update
 The ``t7xx`` driver implements the flash update using the ``devlink-flash``
 interface.
 
-The driver uses DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT to identify the type of
+The driver uses ``DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT`` to identify the type of
 firmware image that need to be programmed upon the request by user space application.
 
 The supported list of firmware image types is described below.
@@ -79,14 +79,14 @@ device.
   $ devlink dev reload pci/0000:$bdf action driver_reinit
 
 The wwan device is put into fastboot mode via devlink reload command, by
-passing "driver_reinit" action.
+passing ``driver_reinit`` action.
 
 ::
 
   $ devlink dev reload pci/0000:$bdf action fw_activate
 
 Upon completion of fw flashing or coredump collection the wwan device is
-reset to normal mode using devlink reload command, by passing "fw_activate"
+reset to normal mode using devlink reload command, by passing ``fw_activate``
 action.
 
 Flash Commands:
 
> +
> +Flash Commands:
> +===============

Trim the unneeded trailing colon on the section title.

> +
> +$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
> +
> +$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
> +
> +$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
> +
> +$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
> +
> +$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
> +
> +$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
> +
> +$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
> +
> +$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
> +
> +$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
> +
> +$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
> +
> +$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
> +
> +$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
> +
> +$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
> +
> <snipped>...
> +Region commands
> +===============
> +
> +$ devlink region show
> +
> +
> +$ devlink region new mr_dump
> +
> +$ devlink region read mr_dump snapshot 0 address 0 length $len
> +
> +$ devlink region del mr_dump snapshot 0
> +
> +$ devlink region new lk_dump
> +
> +$ devlink region read lk_dump snapshot 0 address 0 length $len
> +
> +$ devlink region del lk_dump snapshot 0
> +
> +Note: $len is actual len to be dumped.

Please briefly describe these devlink commands.

Also, wrap them in literal code blocks:

---- >8 ----

diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
index d8feefe116c978..1ba3ba4680e721 100644
--- a/Documentation/networking/devlink/t7xx.rst
+++ b/Documentation/networking/devlink/t7xx.rst
@@ -92,35 +92,65 @@ action.
 Flash Commands:
 ===============
 
-$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
+::
 
-$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
+  $ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
 
-$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
+::
 
-$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
+  $ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
 
-$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
+::
 
-$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
+  $ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
 
-$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
+::
 
-$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
+  $ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
 
-$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
+::
 
-$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
+  $ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
 
-$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
+::
 
-$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
+  $ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
 
-$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
+::
 
-$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
+  $ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
 
-$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
+::
+
+  $ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
+
+::
+
+  $ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
 
 Note: Component selects the partition type to be programmed.
 
@@ -147,19 +177,31 @@ Following regions are accessed for device internal data.
 Region commands
 ===============
 
-$ devlink region show
+::
+  $ devlink region show
 
+::
 
-$ devlink region new mr_dump
+  $ devlink region new mr_dump
 
-$ devlink region read mr_dump snapshot 0 address 0 length $len
+::
 
-$ devlink region del mr_dump snapshot 0
+  $ devlink region read mr_dump snapshot 0 address 0 length $len
 
-$ devlink region new lk_dump
+::
 
-$ devlink region read lk_dump snapshot 0 address 0 length $len
+  $ devlink region del mr_dump snapshot 0
 
-$ devlink region del lk_dump snapshot 0
+::
+
+  $ devlink region new lk_dump
+
+::
+
+  $ devlink region read lk_dump snapshot 0 address 0 length $len
+
+::
+
+  $ devlink region del lk_dump snapshot 0
 
 Note: $len is actual len to be dumped.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation
  2023-01-09  3:48   ` Bagas Sanjaya
@ 2023-01-09 16:07     ` Kumar, M Chetan
  0 siblings, 0 replies; 16+ messages in thread
From: Kumar, M Chetan @ 2023-01-09 16:07 UTC (permalink / raw)
  To: Bagas Sanjaya, netdev
  Cc: kuba, davem, johannes, ryazanov.s.a, loic.poulain, ilpo.jarvinen,
	ricardo.martinez, chiranjeevi.rapolu, haijun.liu, edumazet,
	pabeni, linuxwwan, linuxwwan_5g, chandrashekar.devegowda,
	matthias.bgg, linux-arm-kernel, linux-mediatek, linux-doc, jiri,
	corbet

Hi Bagas,
Thank you for the feedback.

On 1/9/2023 9:18 AM, Bagas Sanjaya wrote:
> On Fri, Jan 06, 2023 at 09:58:06PM +0530, m.chetan.kumar@linux.intel.com wrote:
>> Refer to t7xx.rst file for details.
> 
> Above line is unnecessary.

Ok. Will drop it.

> 
>> +The wwan device is put into fastboot mode via devlink reload command, by
>> +passing "driver_reinit" action.
>> +
>> +$ devlink dev reload pci/0000:$bdf action driver_reinit
>> +
>> +Upon completion of fw flashing or coredump collection the wwan device is
>> +reset to normal mode using devlink reload command, by passing "fw_activate"
>> +action.
>> +
>> +$ devlink dev reload pci/0000:$bdf action fw_activate
> 
> Personally I prefer to put command-line explanations below the actual
> command:

Sure. Will keep explanation under the command.

> 
> ---- >8 ----
> 
> diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
> index de220878ad7649..24f9e0ee69bffb 100644
> --- a/Documentation/networking/devlink/t7xx.rst
> +++ b/Documentation/networking/devlink/t7xx.rst
> @@ -74,17 +74,21 @@ The supported list of firmware image types is described below.
>   procedure, fastboot command & response are exchanged between driver and wwan
>   device.
>   
> +::
> +
> +  $ devlink dev reload pci/0000:$bdf action driver_reinit
> +
>   The wwan device is put into fastboot mode via devlink reload command, by
>   passing "driver_reinit" action.
>   
> -$ devlink dev reload pci/0000:$bdf action driver_reinit
> +::
> +
> +  $ devlink dev reload pci/0000:$bdf action fw_activate
>   
>   Upon completion of fw flashing or coredump collection the wwan device is
>   reset to normal mode using devlink reload command, by passing "fw_activate"
>   action.
>   
> -$ devlink dev reload pci/0000:$bdf action fw_activate
> -
>   Flash Commands:
>   ===============
>   
> 
> However, I find it's odd to jump from firmware image type list directly to
> devlink usage. Perhaps the latter should be put into the following section
> below?

Ok. Will move image type list under Flash Commands.

> 
> I also find that there is minor inconsistency of keyword formatting, so I
> have to inline-code the uninlined remainings:

Ok. Will correct it.

> 
> ---- >8 ----
> 
> diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
> index 24f9e0ee69bffb..d8feefe116c978 100644
> --- a/Documentation/networking/devlink/t7xx.rst
> +++ b/Documentation/networking/devlink/t7xx.rst
> @@ -29,7 +29,7 @@ Flash Update
>   The ``t7xx`` driver implements the flash update using the ``devlink-flash``
>   interface.
>   
> -The driver uses DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT to identify the type of
> +The driver uses ``DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT`` to identify the type of
>   firmware image that need to be programmed upon the request by user space application.
>   
>   The supported list of firmware image types is described below.
> @@ -79,14 +79,14 @@ device.
>     $ devlink dev reload pci/0000:$bdf action driver_reinit
>   
>   The wwan device is put into fastboot mode via devlink reload command, by
> -passing "driver_reinit" action.
> +passing ``driver_reinit`` action.
>   
>   ::
>   
>     $ devlink dev reload pci/0000:$bdf action fw_activate
>   
>   Upon completion of fw flashing or coredump collection the wwan device is
> -reset to normal mode using devlink reload command, by passing "fw_activate"
> +reset to normal mode using devlink reload command, by passing ``fw_activate``
>   action.
>   
>   Flash Commands:
>   
>> +
>> +Flash Commands:
>> +===============
> 
> Trim the unneeded trailing colon on the section title.

Ok. will drop it.

> 
>> +
>> +$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
>> +
>> +$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
>> +
>> +$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
>> +
>> +$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
>> +
>> +$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
>> +
>> +$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
>> +
>> +$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
>> +
>> +$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
>> +
>> +$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
>> +
>> +$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
>> +
>> <snipped>...
>> +Region commands
>> +===============
>> +
>> +$ devlink region show
>> +
>> +
>> +$ devlink region new mr_dump
>> +
>> +$ devlink region read mr_dump snapshot 0 address 0 length $len
>> +
>> +$ devlink region del mr_dump snapshot 0
>> +
>> +$ devlink region new lk_dump
>> +
>> +$ devlink region read lk_dump snapshot 0 address 0 length $len
>> +
>> +$ devlink region del lk_dump snapshot 0
>> +
>> +Note: $len is actual len to be dumped.
> 
> Please briefly describe these devlink commands.

Ok. Will add some explanations.

> 
> Also, wrap them in literal code blocks:
> 
> ---- >8 ----
> 
> diff --git a/Documentation/networking/devlink/t7xx.rst b/Documentation/networking/devlink/t7xx.rst
> index d8feefe116c978..1ba3ba4680e721 100644
> --- a/Documentation/networking/devlink/t7xx.rst
> +++ b/Documentation/networking/devlink/t7xx.rst
> @@ -92,35 +92,65 @@ action.
>   Flash Commands:
>   ===============
>   
> -$ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
> +  $ devlink dev flash pci/0000:$bdf file preloader_k6880v1_mdot2_datacard.bin component "preloader"
>   
> -$ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
> +  $ devlink dev flash pci/0000:$bdf file loader_ext-verified.img component "loader_ext1"
>   
> -$ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
> +  $ devlink dev flash pci/0000:$bdf file tee-verified.img component "tee1"
>   
> -$ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
> +  $ devlink dev flash pci/0000:$bdf file lk-verified.img component "lk"
>   
> -$ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
> +  $ devlink dev flash pci/0000:$bdf file spmfw-verified.img component "spmfw"
>   
> -$ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
> +  $ devlink dev flash pci/0000:$bdf file sspm-verified.img component "sspm_1"
>   
> -$ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
> +::
>   
> -$ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
> +  $ devlink dev flash pci/0000:$bdf file mcupm-verified.img component "mcupm_1"
>   
> -$ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file dpm-verified.img component "dpm_1"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file boot-verified.img component "boot"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file root.squashfs component "rootfs"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file modem-verified.img component "md1img"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file dsp-verified.bin component "md1dsp"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file OP_OTA.img component "mcf1"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file OEM_OTA.img component "mcf2"
> +
> +::
> +
> +  $ devlink dev flash pci/0000:$bdf file DEV_OTA.img component "mcf3"
>   
>   Note: Component selects the partition type to be programmed.
>   
> @@ -147,19 +177,31 @@ Following regions are accessed for device internal data.
>   Region commands
>   ===============
>   
> -$ devlink region show
> +::
> +  $ devlink region show
>   
> +::
>   
> -$ devlink region new mr_dump
> +  $ devlink region new mr_dump
>   
> -$ devlink region read mr_dump snapshot 0 address 0 length $len
> +::
>   
> -$ devlink region del mr_dump snapshot 0
> +  $ devlink region read mr_dump snapshot 0 address 0 length $len
>   
> -$ devlink region new lk_dump
> +::
>   
> -$ devlink region read lk_dump snapshot 0 address 0 length $len
> +  $ devlink region del mr_dump snapshot 0
>   
> -$ devlink region del lk_dump snapshot 0
> +::
> +
> +  $ devlink region new lk_dump
> +
> +::
> +
> +  $ devlink region read lk_dump snapshot 0 address 0 length $len
> +
> +::
> +
> +  $ devlink region del lk_dump snapshot 0
>   
>   Note: $len is actual len to be dumped.
> 
> Thanks.
> 

Thanks for the inline-code. Will follow the suggested format for 
documentation.

-- 
Chetan

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-01-09 16:08 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-06 16:26 [PATCH v3 net-next 0/5] net: wwan: t7xx: fw flashing & coredump support m.chetan.kumar
2023-01-06 16:26 ` [PATCH v3 net-next 1/5] net: wwan: t7xx: Add AP CLDMA m.chetan.kumar
2023-01-06 17:56   ` Jesse Brandeburg
2023-01-06 16:26 ` [PATCH v3 net-next 2/5] net: wwan: t7xx: Infrastructure for early port configuration m.chetan.kumar
2023-01-06 18:31   ` Jesse Brandeburg
2023-01-08 14:07     ` Kumar, M Chetan
2023-01-06 16:27 ` [PATCH v3 net-next 3/5] net: wwan: t7xx: PCIe reset rescan m.chetan.kumar
2023-01-06 18:42   ` Jesse Brandeburg
2023-01-08 14:14     ` Kumar, M Chetan
2023-01-06 16:27 ` [PATCH v3 net-next 4/5] net: wwan: t7xx: Enable devlink based fw flashing and coredump collection m.chetan.kumar
2023-01-06 18:50   ` Jesse Brandeburg
2023-01-06 16:28 ` [PATCH v3 net-next 5/5] net: wwan: t7xx: Devlink documentation m.chetan.kumar
2023-01-06 18:37   ` Jesse Brandeburg
2023-01-08 14:20     ` Kumar, M Chetan
2023-01-09  3:48   ` Bagas Sanjaya
2023-01-09 16:07     ` Kumar, M Chetan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).