diff options
-rw-r--r-- | Documentation/networking/device_drivers/wwan/t7xx.rst | 47 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_modem_ops.c | 1 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_pci.c | 58 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_pci.h | 1 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port.h | 3 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_proxy.c | 51 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_proxy.h | 1 | ||||
-rw-r--r-- | drivers/net/wwan/t7xx/t7xx_port_wwan.c | 8 |
8 files changed, 157 insertions, 13 deletions
diff --git a/Documentation/networking/device_drivers/wwan/t7xx.rst b/Documentation/networking/device_drivers/wwan/t7xx.rst index f346f5f85f15..4cf777c341cd 100644 --- a/Documentation/networking/device_drivers/wwan/t7xx.rst +++ b/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -67,6 +67,28 @@ Write from userspace to set the device mode. :: $ echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode +t7xx_debug_ports +---------------- +The sysfs interface provides userspace with access to enable/disable the debug +ports, this interface supports read and write operations. + +Debug port status: + +- ``1`` represents enable debug ports +- ``0`` represents disable debug ports + +Currently supported debug ports (ADB/MIPC). + +Read from userspace to get the current debug ports status. + +:: + $ cat /sys/bus/pci/devices/${bdf}/t7xx_debug_ports + +Write from userspace to set the debug ports status. + +:: + $ echo 1 > /sys/bus/pci/devices/${bdf}/t7xx_debug_ports + Management application development ================================== The driver and userspace interfaces are described below. The MBIM protocol is @@ -139,6 +161,25 @@ Please note that driver needs to be reloaded to export /dev/wwan0fastboot0 port, because device needs a cold reset after enter ``fastboot_switching`` mode. +ADB port userspace ABI +---------------------- + +/dev/wwan0adb0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a ADB protocol interface by implementing ADB WWAN Port. +The userspace end of the ADB channel pipe is a /dev/wwan0adb0 character device. +Application shall use this interface for ADB protocol communication. + +MIPC port userspace ABI +----------------------- + +/dev/wwan0mipc0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a diagnostic interface by implementing MIPC (Modem +Information Process Center) WWAN Port. The userspace end of the MIPC channel +pipe is a /dev/wwan0mipc0 character device. +Application shall use this interface for MTK modem diagnostic communication. + The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification. References @@ -164,3 +205,9 @@ speak the Mobile Interface Broadband Model (MBIM) protocol"* [5] *fastboot "a mechanism for communicating with bootloaders"* - https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md + +[6] *ADB (Android Debug Bridge) "a mechanism to keep track of Android devices +and emulators instances connected to or running on a given host developer +machine with ADB protocol"* + +- https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/README.md diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 79f17100f70b..7968e208dd37 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -198,6 +198,7 @@ int t7xx_reset_device(struct t7xx_pci_dev *t7xx_dev, enum reset_type type) pci_save_state(t7xx_dev->pdev); t7xx_pci_reprobe_early(t7xx_dev); t7xx_mode_update(t7xx_dev, T7XX_RESET); + WRITE_ONCE(t7xx_dev->debug_ports_show, false); if (type == FLDR) { ret = t7xx_acpi_reset(t7xx_dev, "_RST"); diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index e556e5bd49ab..7b8c17b029c7 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -41,6 +41,7 @@ #include "t7xx_pcie_mac.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" +#include "t7xx_port_proxy.h" #define T7XX_PCI_IREG_BASE 0 #define T7XX_PCI_EREG_BASE 2 @@ -120,13 +121,58 @@ static ssize_t t7xx_mode_show(struct device *dev, static DEVICE_ATTR_RW(t7xx_mode); -static struct attribute *t7xx_mode_attr[] = { +static ssize_t t7xx_debug_ports_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + bool show; + int ret; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + ret = kstrtobool(buf, &show); + if (ret < 0) + return ret; + + t7xx_proxy_debug_ports_show(t7xx_dev, show); + WRITE_ONCE(t7xx_dev->debug_ports_show, show); + + return count; +}; + +static ssize_t t7xx_debug_ports_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + bool show; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + show = READ_ONCE(t7xx_dev->debug_ports_show); + + return sysfs_emit(buf, "%d\n", show); +} + +static DEVICE_ATTR_RW(t7xx_debug_ports); + +static struct attribute *t7xx_attr[] = { &dev_attr_t7xx_mode.attr, + &dev_attr_t7xx_debug_ports.attr, NULL }; -static const struct attribute_group t7xx_mode_attribute_group = { - .attrs = t7xx_mode_attr, +static const struct attribute_group t7xx_attribute_group = { + .attrs = t7xx_attr, }; void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode) @@ -839,7 +885,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pcie_mac_interrupts_dis(t7xx_dev); ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); if (ret) goto err_md_exit; @@ -855,7 +901,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_remove_group: sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); err_md_exit: t7xx_md_exit(t7xx_dev); @@ -870,7 +916,7 @@ static void t7xx_pci_remove(struct pci_dev *pdev) t7xx_dev = pci_get_drvdata(pdev); sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); t7xx_md_exit(t7xx_dev); for (i = 0; i < EXT_INT_NUM; i++) { diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index cd8ea17c2644..b25d867e72d2 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.h +++ b/drivers/net/wwan/t7xx/t7xx_pci.h @@ -94,6 +94,7 @@ struct t7xx_pci_dev { struct dentry *debugfs_dir; #endif u32 mode; + bool debug_ports_show; }; enum t7xx_pm_id { diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index f74d3bab810d..9f5d6d288c97 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_ADB_RX = 0x100a, + PORT_CH_AP_ADB_TX = 0x100b, /* to MD */ PORT_CH_CONTROL_RX = 0x2000, @@ -100,6 +102,7 @@ struct t7xx_port_conf { struct port_ops *ops; char *name; enum wwan_port_type port_type; + bool debug; }; struct t7xx_port { diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 35743e7de0c3..4fc131f9632f 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -38,7 +38,8 @@ #include "t7xx_state_monitor.h" #define Q_IDX_CTRL 0 -#define Q_IDX_MBIM 2 +#define Q_IDX_MBIM_MIPC 2 +#define Q_IDX_ADB 3 #define Q_IDX_AT_CMD 5 #define INVALID_SEQ_NUM GENMASK(15, 0) @@ -66,8 +67,8 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { }, { .tx_ch = PORT_CH_MBIM_TX, .rx_ch = PORT_CH_MBIM_RX, - .txq_index = Q_IDX_MBIM, - .rxq_index = Q_IDX_MBIM, + .txq_index = Q_IDX_MBIM_MIPC, + .rxq_index = Q_IDX_MBIM_MIPC, .path_id = CLDMA_ID_MD, .ops = &wwan_sub_port_ops, .name = "MBIM", @@ -100,7 +101,27 @@ 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_ADB_TX, + .rx_ch = PORT_CH_AP_ADB_RX, + .txq_index = Q_IDX_ADB, + .rxq_index = Q_IDX_ADB, + .path_id = CLDMA_ID_AP, + .ops = &wwan_sub_port_ops, + .name = "adb", + .port_type = WWAN_PORT_ADB, + .debug = true, + }, { + .tx_ch = PORT_CH_MIPC_TX, + .rx_ch = PORT_CH_MIPC_RX, + .txq_index = Q_IDX_MBIM_MIPC, + .rxq_index = Q_IDX_MBIM_MIPC, + .path_id = CLDMA_ID_MD, + .ops = &wwan_sub_port_ops, + .name = "mipc", + .port_type = WWAN_PORT_MIPC, + .debug = true, + } }; static const struct t7xx_port_conf t7xx_early_port_conf[] = { @@ -505,13 +526,33 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md) spin_lock_init(&port->port_update_lock); port->chan_enable = false; - if (port_conf->ops && port_conf->ops->init) + if (!port_conf->debug && + port_conf->ops && + port_conf->ops->init) port_conf->ops->init(port); } t7xx_proxy_setup_ch_mapping(port_prox); } +void t7xx_proxy_debug_ports_show(struct t7xx_pci_dev *t7xx_dev, bool show) +{ + struct port_proxy *port_prox = t7xx_dev->md->port_prox; + struct t7xx_port *port; + int i; + + for_each_proxy_port(i, port, port_prox) { + const struct t7xx_port_conf *port_conf = port->port_conf; + + if (port_conf->debug && port_conf->ops) { + if (show && port_conf->ops->init) + port_conf->ops->init(port); + else if (!show && port_conf->ops->uninit) + port_conf->ops->uninit(port); + } + } +} + void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id) { struct port_proxy *port_prox = md->port_prox; diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h index 7f5706811445..f0918b36e899 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h @@ -98,6 +98,7 @@ extern struct port_ops ctl_port_ops; extern struct port_ops t7xx_trace_port_ops; #endif +void t7xx_proxy_debug_ports_show(struct t7xx_pci_dev *t7xx_dev, bool show); void t7xx_port_proxy_reset(struct port_proxy *port_prox); void t7xx_port_proxy_uninit(struct port_proxy *port_prox); int t7xx_port_proxy_init(struct t7xx_modem *md); diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c index 4b23ba693f3f..7fc569565ff9 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c +++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c @@ -169,7 +169,9 @@ static int t7xx_port_wwan_init(struct t7xx_port *port) { const struct t7xx_port_conf *port_conf = port->port_conf; - if (port_conf->port_type == WWAN_PORT_FASTBOOT) + if (port_conf->port_type == WWAN_PORT_FASTBOOT || + port_conf->port_type == WWAN_PORT_ADB || + port_conf->port_type == WWAN_PORT_MIPC) t7xx_port_wwan_create(port); port->rx_length_th = RX_QUEUE_MAXLEN; @@ -224,7 +226,9 @@ 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 (port_conf->port_type == WWAN_PORT_FASTBOOT) + if (port_conf->port_type == WWAN_PORT_FASTBOOT || + port_conf->port_type == WWAN_PORT_ADB || + port_conf->port_type == WWAN_PORT_MIPC) return; if (state != MD_STATE_READY) |