mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Revert "Merge branch 'wwan-t7xx-fw-flashing-and-coredump-support'"
This reverts commit5417197dd5, reversing changes made to0630f64d25. Reverting to allow addressing review comments. Link: https://lore.kernel.org/all/4c5dbea0-52a9-1c3d-7547-00ea54c90550@linux.intel.com/ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -67,4 +67,3 @@ parameters, info versions, and other features it supports.
|
||||
prestera
|
||||
iosm
|
||||
octeontx2
|
||||
t7xx
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================
|
||||
t7xx devlink support
|
||||
====================
|
||||
|
||||
This document describes the devlink features implemented by the ``t7xx``
|
||||
device driver.
|
||||
|
||||
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's & response's 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 "value" represents 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 components log 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.
|
||||
@@ -108,7 +108,6 @@ config IOSM
|
||||
config MTK_T7XX
|
||||
tristate "MediaTek PCIe 5G WWAN modem T7xx device"
|
||||
depends on PCI
|
||||
select NET_DEVLINK
|
||||
help
|
||||
Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device.
|
||||
Adapts WWAN framework and provides network interface like wwan0
|
||||
|
||||
@@ -17,7 +17,4 @@ mtk_t7xx-y:= t7xx_pci.o \
|
||||
t7xx_hif_dpmaif_tx.o \
|
||||
t7xx_hif_dpmaif_rx.o \
|
||||
t7xx_dpmaif.o \
|
||||
t7xx_netdev.o \
|
||||
t7xx_pci_rescan.o \
|
||||
t7xx_uevent.o \
|
||||
t7xx_port_devlink.o
|
||||
t7xx_netdev.o
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#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)
|
||||
{
|
||||
@@ -991,34 +993,6 @@ allow_sleep:
|
||||
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;
|
||||
md_ctrl->rxq[qno].q_type = CLDMA_SHARED_Q;
|
||||
}
|
||||
|
||||
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;
|
||||
md_ctrl->txq[qno].q_type = CLDMA_SHARED_Q;
|
||||
}
|
||||
|
||||
if (cfg_id == CLDMA_DEDICATED_Q_CFG) {
|
||||
md_ctrl->rxq[DOWNLOAD_PORT_ID].q_type = CLDMA_DEDICATED_Q;
|
||||
md_ctrl->txq[DOWNLOAD_PORT_ID].q_type = CLDMA_DEDICATED_Q;
|
||||
md_ctrl->tx_ring[DOWNLOAD_PORT_ID].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
|
||||
md_ctrl->rx_ring[DOWNLOAD_PORT_ID].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
|
||||
md_ctrl->rxq[DUMP_PORT_ID].q_type = CLDMA_DEDICATED_Q;
|
||||
md_ctrl->txq[DUMP_PORT_ID].q_type = CLDMA_DEDICATED_Q;
|
||||
md_ctrl->tx_ring[DUMP_PORT_ID].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
|
||||
md_ctrl->rx_ring[DUMP_PORT_ID].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ;
|
||||
}
|
||||
}
|
||||
|
||||
static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
|
||||
{
|
||||
char dma_pool_name[32];
|
||||
@@ -1047,6 +1021,11 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
|
||||
}
|
||||
|
||||
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");
|
||||
@@ -1085,18 +1064,13 @@ 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,
|
||||
@@ -1350,10 +1324,9 @@ err_workqueue:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id)
|
||||
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl)
|
||||
{
|
||||
t7xx_cldma_late_release(md_ctrl);
|
||||
t7xx_cldma_adjust_config(md_ctrl, cfg_id);
|
||||
t7xx_cldma_late_init(md_ctrl);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +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.
|
||||
* @CLDMA_ID_AP: Application Processor control channel.
|
||||
* @CLDMA_ID_AP: Application Processor control channel (not used at the moment).
|
||||
* @CLDMA_NUM: Number of CLDMA HW units available.
|
||||
*/
|
||||
enum cldma_id {
|
||||
@@ -59,16 +55,6 @@ struct cldma_gpd {
|
||||
__le16 not_used2;
|
||||
};
|
||||
|
||||
enum cldma_queue_type {
|
||||
CLDMA_SHARED_Q,
|
||||
CLDMA_DEDICATED_Q,
|
||||
};
|
||||
|
||||
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 */
|
||||
@@ -91,7 +77,6 @@ struct cldma_queue {
|
||||
struct cldma_request *tr_done;
|
||||
struct cldma_request *rx_refill;
|
||||
struct cldma_request *tx_next;
|
||||
enum cldma_queue_type q_type;
|
||||
int budget; /* Same as ring buffer size by default */
|
||||
spinlock_t ring_lock;
|
||||
wait_queue_head_t req_wq; /* Only for TX */
|
||||
@@ -119,20 +104,17 @@ struct cldma_ctrl {
|
||||
int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb);
|
||||
};
|
||||
|
||||
enum cldma_txq_rxq_port_id {
|
||||
DOWNLOAD_PORT_ID = 0,
|
||||
DUMP_PORT_ID = 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, enum cldma_cfg cfg_id);
|
||||
void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl);
|
||||
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);
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
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);
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#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"
|
||||
@@ -45,7 +44,6 @@
|
||||
#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
|
||||
|
||||
@@ -193,10 +191,6 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data)
|
||||
|
||||
msleep(RGU_RESET_DELAY_MS);
|
||||
t7xx_reset_device_via_pmic(t7xx_dev);
|
||||
|
||||
if (!t7xx_dev->hp_enable)
|
||||
t7xx_rescan_queue_work(t7xx_dev->pdev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -302,7 +296,6 @@ 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);
|
||||
@@ -431,7 +424,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 || i == RT_ID_AP_PORT_ENUM)
|
||||
if (i == RT_ID_MD_PORT_ENUM)
|
||||
t7xx_port_enum_msg_handler(ctl->md, rt_feature->data);
|
||||
}
|
||||
|
||||
@@ -461,12 +454,12 @@ static int t7xx_core_reset(struct t7xx_modem *md)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void t7xx_core_hk_handler(struct t7xx_modem *md, struct t7xx_sys_info *core_info,
|
||||
struct t7xx_fsm_ctl *ctl,
|
||||
static void t7xx_core_hk_handler(struct t7xx_modem *md, 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;
|
||||
@@ -532,37 +525,23 @@ 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], CLDMA_SHARED_Q_CFG);
|
||||
t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD]);
|
||||
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, &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], 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);
|
||||
t7xx_core_hk_handler(md, ctl, FSM_EVENT_MD_HS2, FSM_EVENT_MD_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 | D2H_INT_ASYNC_MD_HK |
|
||||
D2H_INT_ASYNC_AP_HK);
|
||||
t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM);
|
||||
break;
|
||||
|
||||
case FSM_START:
|
||||
@@ -575,26 +554,16 @@ 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;
|
||||
md->exp_id &= ~D2H_INT_ASYNC_AP_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);
|
||||
} else {
|
||||
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->ap_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);
|
||||
}
|
||||
t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_ASYNC_MD_HK);
|
||||
}
|
||||
spin_unlock_irqrestore(&md->exp_lock, flags);
|
||||
|
||||
@@ -607,7 +576,6 @@ 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:
|
||||
@@ -659,19 +627,6 @@ 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);
|
||||
|
||||
md->ap_handshake_wq = alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI,
|
||||
0, "ap_hk_wq");
|
||||
if (!md->ap_handshake_wq) {
|
||||
destroy_workqueue(md->handshake_wq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -683,7 +638,6 @@ 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);
|
||||
@@ -713,10 +667,6 @@ 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;
|
||||
@@ -729,16 +679,12 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev)
|
||||
if (ret)
|
||||
goto err_uninit_ccmni;
|
||||
|
||||
ret = t7xx_cldma_init(md->md_ctrl[CLDMA_ID_AP]);
|
||||
ret = t7xx_port_proxy_init(md);
|
||||
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) /* t7xx_fsm_uninit() flushes cmd queue */
|
||||
if (ret) /* fsm_uninit flushes cmd queue */
|
||||
goto err_uninit_proxy;
|
||||
|
||||
t7xx_md_sys_sw_init(t7xx_dev);
|
||||
@@ -748,9 +694,6 @@ 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]);
|
||||
|
||||
@@ -762,7 +705,6 @@ err_uninit_fsm:
|
||||
|
||||
err_destroy_hswq:
|
||||
destroy_workqueue(md->handshake_wq);
|
||||
destroy_workqueue(md->ap_handshake_wq);
|
||||
dev_err(&t7xx_dev->pdev->dev, "Modem init failed\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -778,10 +720,8 @@ 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);
|
||||
destroy_workqueue(md->handshake_wq);
|
||||
destroy_workqueue(md->ap_handshake_wq);
|
||||
}
|
||||
|
||||
@@ -66,13 +66,10 @@ 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 workqueue_struct *ap_handshake_wq;
|
||||
struct work_struct ap_handshake_work;
|
||||
struct t7xx_fsm_ctl *fsm_ctl;
|
||||
struct port_proxy *port_prox;
|
||||
unsigned int exp_id;
|
||||
|
||||
@@ -38,9 +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_port_devlink.h"
|
||||
#include "t7xx_reg.h"
|
||||
#include "t7xx_state_monitor.h"
|
||||
|
||||
@@ -705,33 +703,22 @@ 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_devlink_register(t7xx_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = t7xx_md_init(t7xx_dev);
|
||||
if (ret)
|
||||
goto err_devlink_unregister;
|
||||
return ret;
|
||||
|
||||
t7xx_pcie_mac_interrupts_dis(t7xx_dev);
|
||||
|
||||
ret = t7xx_interrupt_init(t7xx_dev);
|
||||
if (ret) {
|
||||
t7xx_md_exit(t7xx_dev);
|
||||
goto err_devlink_unregister;
|
||||
return ret;
|
||||
}
|
||||
|
||||
t7xx_rescan_done();
|
||||
t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
|
||||
t7xx_pcie_mac_interrupts_en(t7xx_dev);
|
||||
if (!t7xx_dev->hp_enable)
|
||||
pci_ignore_hotplug(pdev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_devlink_unregister:
|
||||
t7xx_devlink_unregister(t7xx_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void t7xx_pci_remove(struct pci_dev *pdev)
|
||||
@@ -741,7 +728,6 @@ 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])
|
||||
@@ -768,52 +754,7 @@ static struct pci_driver t7xx_pci_driver = {
|
||||
.shutdown = t7xx_pci_shutdown,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
return dev->parent->fwnode == data;
|
||||
}
|
||||
|
||||
static void __exit t7xx_pci_cleanup(void)
|
||||
{
|
||||
int remove_flag = 0;
|
||||
struct device *dev;
|
||||
|
||||
dev = driver_find_device(&t7xx_pci_driver.driver, NULL, NULL, 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_pci_driver(t7xx_pci_driver);
|
||||
|
||||
MODULE_AUTHOR("MediaTek Inc");
|
||||
MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
|
||||
|
||||
@@ -59,7 +59,6 @@ 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];
|
||||
@@ -70,7 +69,6 @@ struct t7xx_pci_dev {
|
||||
struct t7xx_modem *md;
|
||||
struct t7xx_ccmni_ctrl *ccmni_ctlb;
|
||||
bool rgu_pci_irq_en;
|
||||
bool hp_enable;
|
||||
|
||||
/* Low Power Items */
|
||||
struct list_head md_pm_entities;
|
||||
@@ -80,7 +78,6 @@ struct t7xx_pci_dev {
|
||||
spinlock_t md_pm_lock; /* Protects PCI resource lock */
|
||||
unsigned int sleep_disable_count;
|
||||
struct completion sleep_lock_acquire;
|
||||
struct t7xx_devlink *dl;
|
||||
};
|
||||
|
||||
enum t7xx_pm_id {
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, MediaTek Inc.
|
||||
* Copyright (c) 2021-2022, 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 g_mtk_rescan_context;
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&g_mtk_rescan_context.dev_lock, flags);
|
||||
if (g_mtk_rescan_context.rescan_done == 0) {
|
||||
pr_debug("this is a rescan probe\n");
|
||||
g_mtk_rescan_context.rescan_done = 1;
|
||||
} else {
|
||||
pr_debug("this is a init probe\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
}
|
||||
|
||||
static void t7xx_remove_rescan(struct work_struct *work)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
int num_retries = RESCAN_RETRIES;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&g_mtk_rescan_context.dev_lock, flags);
|
||||
g_mtk_rescan_context.rescan_done = 0;
|
||||
pdev = g_mtk_rescan_context.dev;
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
|
||||
if (pdev) {
|
||||
pci_stop_and_remove_bus_device_locked(pdev);
|
||||
pr_debug("start remove and rescan flow\n");
|
||||
}
|
||||
|
||||
do {
|
||||
t7xx_pci_dev_rescan();
|
||||
spin_lock_irqsave(&g_mtk_rescan_context.dev_lock, flags);
|
||||
if (g_mtk_rescan_context.rescan_done) {
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
msleep(DELAY_RESCAN_MTIME);
|
||||
} while (num_retries--);
|
||||
}
|
||||
|
||||
void t7xx_rescan_queue_work(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
dev_info(&pdev->dev, "start queue_mtk_rescan_work\n");
|
||||
spin_lock_irqsave(&g_mtk_rescan_context.dev_lock, flags);
|
||||
if (!g_mtk_rescan_context.rescan_done) {
|
||||
dev_err(&pdev->dev, "rescan failed because last rescan undone\n");
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
g_mtk_rescan_context.dev = pdev;
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
queue_work(g_mtk_rescan_context.pcie_rescan_wq, &g_mtk_rescan_context.service_task);
|
||||
}
|
||||
|
||||
int t7xx_rescan_init(void)
|
||||
{
|
||||
spin_lock_init(&g_mtk_rescan_context.dev_lock);
|
||||
g_mtk_rescan_context.rescan_done = 1;
|
||||
g_mtk_rescan_context.dev = NULL;
|
||||
g_mtk_rescan_context.pcie_rescan_wq = create_singlethread_workqueue(MTK_RESCAN_WQ);
|
||||
if (!g_mtk_rescan_context.pcie_rescan_wq) {
|
||||
pr_err("Failed to create workqueue: %s\n", MTK_RESCAN_WQ);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_WORK(&g_mtk_rescan_context.service_task, t7xx_remove_rescan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void t7xx_rescan_deinit(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&g_mtk_rescan_context.dev_lock, flags);
|
||||
g_mtk_rescan_context.rescan_done = 0;
|
||||
g_mtk_rescan_context.dev = NULL;
|
||||
spin_unlock_irqrestore(&g_mtk_rescan_context.dev_lock, flags);
|
||||
cancel_work_sync(&g_mtk_rescan_context.service_task);
|
||||
destroy_workqueue(g_mtk_rescan_context.pcie_rescan_wq);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2021, MediaTek Inc.
|
||||
* Copyright (c) 2021-2022, 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;
|
||||
spinlock_t dev_lock; /* protects device */
|
||||
struct pci_dev *dev;
|
||||
int 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__ */
|
||||
@@ -36,15 +36,9 @@
|
||||
/* 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 AP, 2: to MD
|
||||
* 0:reserved, 1: to sAP, 2: to MD
|
||||
*/
|
||||
enum port_ch {
|
||||
/* to AP */
|
||||
PORT_CH_AP_CONTROL_RX = 0x1000,
|
||||
PORT_CH_AP_CONTROL_TX = 0x1001,
|
||||
PORT_CH_AP_LOG_RX = 0x1008,
|
||||
PORT_CH_AP_LOG_TX = 0x1009,
|
||||
|
||||
/* to MD */
|
||||
PORT_CH_CONTROL_RX = 0x2000,
|
||||
PORT_CH_CONTROL_TX = 0x2001,
|
||||
@@ -100,7 +94,6 @@ struct t7xx_port_conf {
|
||||
struct port_ops *ops;
|
||||
char *name;
|
||||
enum wwan_port_type port_type;
|
||||
bool is_early_port;
|
||||
};
|
||||
|
||||
struct t7xx_port {
|
||||
@@ -129,14 +122,11 @@ struct t7xx_port {
|
||||
int rx_length_th;
|
||||
bool chan_enable;
|
||||
struct task_struct *thread;
|
||||
struct t7xx_devlink *dl;
|
||||
};
|
||||
|
||||
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,
|
||||
|
||||
@@ -167,12 +167,8 @@ 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 ||
|
||||
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,
|
||||
if (port_conf->rx_ch == PORT_CH_CONTROL_RX) {
|
||||
ret = t7xx_fsm_append_event(ctl, FSM_EVENT_MD_HS2, skb->data,
|
||||
le32_to_cpu(ctrl_msg_h->data_length));
|
||||
if (ret)
|
||||
dev_err(port->dev, "Failed to append Handshake 2 event");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,85 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __T7XX_PORT_DEVLINK_H__
|
||||
#define __T7XX_PORT_DEVLINK_H__
|
||||
|
||||
#include <net/devlink.h>
|
||||
|
||||
#include "t7xx_pci.h"
|
||||
|
||||
#define T7XX_MAX_QUEUE_LENGTH 32
|
||||
#define T7XX_FB_COMMAND_SIZE 64
|
||||
#define T7XX_FB_RESPONSE_SIZE 64
|
||||
#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_EVENT_SIZE 50
|
||||
|
||||
#define T7XX_MAX_SNAPSHOTS 1
|
||||
#define T7XX_MAX_REGION_NAME_LENGTH 20
|
||||
#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_DEVLINK_IDLE 0
|
||||
|
||||
#define T7XX_FB_NO_MODE 0
|
||||
#define T7XX_FB_DL_MODE 1
|
||||
#define T7XX_FB_DUMP_MODE 2
|
||||
|
||||
#define T7XX_MRDUMP_INDEX 0
|
||||
#define T7XX_LKDUMP_INDEX 1
|
||||
|
||||
struct t7xx_devlink_work {
|
||||
struct work_struct work;
|
||||
struct t7xx_port *port;
|
||||
};
|
||||
|
||||
struct t7xx_devlink_region_info {
|
||||
char region_name[T7XX_MAX_REGION_NAME_LENGTH];
|
||||
u32 default_size;
|
||||
u32 actual_size;
|
||||
u32 entry;
|
||||
u8 *dump;
|
||||
};
|
||||
|
||||
struct t7xx_devlink {
|
||||
struct t7xx_pci_dev *mtk_dev;
|
||||
struct t7xx_port *port;
|
||||
struct device *dev;
|
||||
struct devlink *dl_ctx;
|
||||
struct t7xx_devlink_work *dl_work;
|
||||
struct workqueue_struct *dl_wq;
|
||||
struct t7xx_devlink_region_info *dl_region_info[T7XX_TOTAL_REGIONS];
|
||||
struct devlink_region_ops dl_region_ops[T7XX_TOTAL_REGIONS];
|
||||
struct devlink_region *dl_region[T7XX_TOTAL_REGIONS];
|
||||
u8 mode;
|
||||
unsigned long status;
|
||||
int set_fastboot_dl;
|
||||
};
|
||||
|
||||
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__*/
|
||||
@@ -77,29 +77,6 @@ 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",
|
||||
},
|
||||
};
|
||||
|
||||
static struct t7xx_port_conf t7xx_early_port_conf[] = {
|
||||
{
|
||||
.tx_ch = 0xffff,
|
||||
.rx_ch = 0xffff,
|
||||
.txq_index = 1,
|
||||
.rxq_index = 1,
|
||||
.txq_exp_index = 1,
|
||||
.rxq_exp_index = 1,
|
||||
.path_id = CLDMA_ID_AP,
|
||||
.is_early_port = true,
|
||||
.ops = &devlink_port_ops,
|
||||
.name = "ttyDUMP",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -217,17 +194,7 @@ int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
static 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;
|
||||
@@ -342,26 +309,6 @@ static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
|
||||
}
|
||||
}
|
||||
|
||||
static int t7xx_port_proxy_recv_skb_from_queue(struct t7xx_pci_dev *t7xx_dev,
|
||||
struct cldma_queue *queue, struct sk_buff *skb)
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
@@ -383,22 +330,6 @@ static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct t7xx_port *t7xx_port_proxy_get_port_by_name(struct port_proxy *port_prox, char *port_name)
|
||||
{
|
||||
const struct t7xx_port_conf *port_conf;
|
||||
struct t7xx_port *port;
|
||||
int i;
|
||||
|
||||
for_each_proxy_port(i, port, port_prox) {
|
||||
port_conf = port->port_conf;
|
||||
|
||||
if (!strncmp(port_conf->name, port_name, strlen(port_conf->name)))
|
||||
return port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* t7xx_port_proxy_recv_skb() - Dispatch received skb.
|
||||
* @queue: CLDMA queue.
|
||||
@@ -419,9 +350,6 @@ static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *s
|
||||
u16 seq_num, channel;
|
||||
int ret;
|
||||
|
||||
if (queue->q_type == CLDMA_DEDICATED_Q)
|
||||
return t7xx_port_proxy_recv_skb_from_queue(t7xx_dev, queue, skb);
|
||||
|
||||
channel = FIELD_GET(CCCI_H_CHN_FLD, le32_to_cpu(ccci_h->status));
|
||||
if (t7xx_fsm_get_md_state(ctl) == MD_STATE_INVALID) {
|
||||
dev_err_ratelimited(dev, "Packet drop on channel 0x%x, modem not ready\n", channel);
|
||||
@@ -436,8 +364,7 @@ static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *s
|
||||
|
||||
seq_num = t7xx_port_next_rx_seq_num(port, ccci_h);
|
||||
port_conf = port->port_conf;
|
||||
if (!port->port_conf->is_early_port)
|
||||
skb_pull(skb, sizeof(*ccci_h));
|
||||
skb_pull(skb, sizeof(*ccci_h));
|
||||
|
||||
ret = port_conf->ops->recv_skb(port, skb);
|
||||
/* Error indicates to try again later */
|
||||
@@ -489,12 +416,8 @@ 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;
|
||||
port->dl = md->t7xx_dev->dl;
|
||||
spin_lock_init(&port->port_update_lock);
|
||||
port->chan_enable = false;
|
||||
|
||||
@@ -505,58 +428,26 @@ 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;
|
||||
struct device *dev = port_prox->dev;
|
||||
unsigned int port_count;
|
||||
struct t7xx_port *port;
|
||||
int i;
|
||||
|
||||
if (port_prox->cfg_id == cfg_id)
|
||||
return;
|
||||
|
||||
if (port_prox->cfg_id != PORT_CFG_ID_INVALID) {
|
||||
for_each_proxy_port(i, port, port_prox)
|
||||
port->port_conf->ops->uninit(port);
|
||||
|
||||
devm_kfree(dev, port_prox->ports);
|
||||
}
|
||||
|
||||
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_md_port_conf;
|
||||
port_count = ARRAY_SIZE(t7xx_md_port_conf);
|
||||
}
|
||||
|
||||
port_prox->ports = devm_kzalloc(dev, sizeof(struct t7xx_port) * port_count, GFP_KERNEL);
|
||||
if (!port_prox->ports)
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned int port_count = ARRAY_SIZE(t7xx_md_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), GFP_KERNEL);
|
||||
port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * 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_md_port_conf[i];
|
||||
|
||||
port_prox->port_count = port_count;
|
||||
t7xx_proxy_init_all_ports(md);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -578,7 +469,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;
|
||||
}
|
||||
|
||||
@@ -31,19 +31,12 @@
|
||||
#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;
|
||||
enum port_cfg_id cfg_id;
|
||||
struct t7xx_port *ports;
|
||||
struct t7xx_port ports[];
|
||||
};
|
||||
|
||||
struct ccci_header {
|
||||
@@ -93,7 +86,6 @@ 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;
|
||||
|
||||
void t7xx_port_proxy_reset(struct port_proxy *port_prox);
|
||||
void t7xx_port_proxy_uninit(struct port_proxy *port_prox);
|
||||
@@ -102,7 +94,5 @@ 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);
|
||||
struct t7xx_port *t7xx_port_proxy_get_port_by_name(struct port_proxy *port_prox, char *port_name);
|
||||
void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id);
|
||||
|
||||
#endif /* __T7XX_PORT_PROXY_H__ */
|
||||
|
||||
@@ -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;
|
||||
size_t len, offset, chunk_len = 0, txq_mtu = CLDMA_MTU;
|
||||
const struct t7xx_port_conf *port_conf;
|
||||
struct t7xx_fsm_ctl *ctl;
|
||||
enum md_state md_state;
|
||||
@@ -72,7 +72,6 @@ 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;
|
||||
@@ -156,12 +155,6 @@ static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int
|
||||
{
|
||||
const struct t7xx_port_conf *port_conf = port->port_conf;
|
||||
|
||||
if (state == MD_STATE_EXCEPTION) {
|
||||
if (port->wwan_port)
|
||||
wwan_port_txoff(port->wwan_port);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state != MD_STATE_READY)
|
||||
return;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user