Skip to content

Commit

Permalink
Merge branch 'wwan-t7xx'
Browse files Browse the repository at this point in the history
Ricardo Martinez says:

====================
net: wwan: t7xx: PCIe driver for MediaTek M.2 modem

t7xx is the PCIe host device driver for Intel 5G 5000 M.2 solution which
is based on MediaTek's T700 modem to provide WWAN connectivity.
The driver uses the WWAN framework infrastructure to create the following
control ports and network interfaces:
* /dev/wwan0mbim0 - Interface conforming to the MBIM protocol.
  Applications like libmbim [1] or Modem Manager [2] from v1.16 onwards
  with [3][4] can use it to enable data communication towards WWAN.
* /dev/wwan0at0 - Interface that supports AT commands.
* wwan0 - Primary network interface for IP traffic.

The main blocks in t7xx driver are:
* PCIe layer - Implements probe, removal, and power management callbacks.
* Port-proxy - Provides a common interface to interact with different types
  of ports such as WWAN ports.
* Modem control & status monitor - Implements the entry point for modem
  initialization, reset and exit, as well as exception handling.
* CLDMA (Control Layer DMA) - Manages the HW used by the port layer to send
  control messages to the modem using MediaTek's CCCI (Cross-Core
  Communication Interface) protocol.
* DPMAIF (Data Plane Modem AP Interface) - Controls the HW that provides
  uplink and downlink queues for the data path. The data exchange takes
  place using circular buffers to share data buffer addresses and metadata
  to describe the packets.
* MHCCIF (Modem Host Cross-Core Interface) - Provides interrupt channels
  for bidirectional event notification such as handshake, exception, PM and
  port enumeration.

The compilation of the t7xx driver is enabled by the CONFIG_MTK_T7XX config
option which depends on CONFIG_WWAN.
This driver was originally developed by MediaTek. Intel adapted t7xx to
the WWAN framework, optimized and refactored the driver source code in close
collaboration with MediaTek. This will enable getting the t7xx driver on the
Approved Vendor List for interested OEM's and ODM's productization plans
with Intel 5G 5000 M.2 solution.

List of contributors:
Amir Hanania <amir.hanania@intel.com>
Andriy Shevchenko <andriy.shevchenko@linux.intel.com>
Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
Dinesh Sharma <dinesh.sharma@intel.com>
Eliot Lee <eliot.lee@intel.com>
Haijun Liu <haijun.liu@mediatek.com>
M Chetan Kumar <m.chetan.kumar@intel.com>
Mika Westerberg <mika.westerberg@linux.intel.com>
Moises Veleta <moises.veleta@intel.com>
Pierre-louis Bossart <pierre-louis.bossart@intel.com>
Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
Ricardo Martinez <ricardo.martinez@linux.intel.com>
Madhusmita Sahu <madhusmita.sahu@intel.com>
Muralidharan Sethuraman <muralidharan.sethuraman@intel.com>
Soumya Prakash Mishra <Soumya.Prakash.Mishra@intel.com>
Sreehari Kancharla <sreehari.kancharla@intel.com>
Suresh Nagaraj <suresh.nagaraj@intel.com>

[1] https://www.freedesktop.org/software/libmbim/
[2] https://www.freedesktop.org/software/ModemManager/
[3] https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/582
[4] https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/523

V8:
- Rebase skb_data_area_size() patch (02).

V7:
- Delete unused macros.
- Avoid duplicated calls to le32_to_cpu().
- Fix 'out of bounds' compilation error.
- Rename port_number to port_count.
- Remove '!!' when the destination variable is a boolean.
- Remove unneeded spinlock around rx_length_th.
- Remove common field from union inside dpmaif_drb struct.
- Use 'goto' for the exit flow in t7xx_pci_enable_sleep().
- Merge CLDMA tgpd and rgpd structs.
- Add comments to clarify skb consumption by ports.
- Introduce skb_data_area_size() helper.
- Declare the port config array as constant.
- Update CLDMA_JUMBO_BUFF_SZ definition when ccci_header
  is introduced by port-proxy patch.
- Update Reviewed-by tags.
- Simplify t7xx_dpmaif_tx_send_skb() and make t7xx_dpmaif_add_skb_to_ring()
  report the tx queue full state early.

V6:
- Remove unneeded initializations and bit masks.
- Remove t7xx_common.h file.
- Add comment to circular linking in GPD list.
- Use min instead of min_t.
- Use int for local indexes instead of short or char.
- Update the commit message in CLDMA patch about dependencies on core patch.
- Add space between contributor name and email address.
- Rename registers with double negatives
  e.g. DIS_ASPM_LOWPWR_CLR_0 -> ENABLE_ASPM_LOWPWR.
- Fix a race condition in pci sleep resource locking.
- Initialize interrupts with t7xx_pcie_mac_set_int() instead of 'clear'.
- Remove duplicate spin_lock_init(&md->exp_lock).
- Remove .ndo_select_queue callback due to singular TX queue.
- Remove call to deprecated netif_rx_any_context().
- Fix include guard name in t7xx_hif_dpmaif.h.
- Remove unused q_num parameter in DPMAIF functions.
- Do not serialize the drb_wr_idx write in t7xx_dpmaif_add_skb_to_ring()
  and the read from t7xx_txq_drb_wr_available().
- Fix potential leak in t7xx_dpmaif_add_skb_to_ring().
- Unionize:
    DRB structs: msg and pd.
    PIT structs: msg and pd.
- Replace list_head & spinlock with skb_buff_head in dpmaif_tx_queue.
- Remove rx_length_th check in TX WWAN port flow.
- Remove wwan_remove_port() from the critical section in WWAN port uninit.
- Use skb_end_pointer() to avoid conditional compilation.
- Simplify the loop in t7xx_port_ctrl_tx() by checking the buffer offset
  instead of calculating the number of required packets.
- Remove the code for unused channel PORT_CH_STATUS_RX.
- Remove bit flags from ports. Ports can check chan_enable instead of the
  PORT_F_RX_ALLOW_DROP flag.
- Use INVALID_SEQ_NUM to identify the first seq number.
- Rename port_static to port_conf and ports_private to ports.
- Implement t7xx_port_send_skb() and t7xx_port_send_ctl_skb() in a layered
  approach to reduce duplicated code and simplify the CCCI header handling.
- Move wwan_port_rx() call from port-proxy to WWAN port.
- Rename t7xx_port_recv_skb() to t7xx_port_enqueue_skb().
- Move control message parsing logic from port-proxy to control port,
  preserve the endianness when parsing the message and make port-proxy
  export a function to enable/disable ports.
- Use flexible arrays for:
    port-proxy ports.
    payload data in t7xx_fsm_event, port_msg, and mtk_runtime_feature.

v5:
- Update Intel's copyright years to 2021-2022.
- Remove circular dependency between DPMAIF HW (07) and HIF (08).
- Keep separate patches for CLDMA (02) and Core (03)
  but improve the code split by decoupling CLDMA from
  modem ops and cleaning up t7xx_common.h.
- Rename ID_CLDMA0/ID_CLDMA1 to CLDMA_ID_AP/CLDMA_ID_MD.
- Consistently use CLDMA's ring_lock to protect tr_ring.
- Free resources first and then print messages.
- Implement suggested name changes.
- Do not explicitly include dev_printk.h.
- Remove redundant dev_err()s.
- Fix possible memory leak during probe.
- Remove infrastructure for legacy interrupts.
- Remove unused macros and variables, including those that
  can be replaced with constants.
- Remove PCIE_MAC_MSIX_MSK_SET macro which is duplicated code.
- Refactor __t7xx_pci_pm_suspend() for clarity.
- Refactor t7xx_cldma_rx_ring_init() and t7xx_cldma_tx_ring_init().
- Do not use & for function callbacks.
- Declare a structure to access skb->cb[] data.
- Use skb_put_data instead of memcpy.
- No need to use kfree_sensitive.
- Use dev_kfree_skb() instead of kfree_skb().
- Refactor t7xx_prepare_device_rt_data() to remove potential leaks,
  avoid unneeded memset and keep rt_data and packet_size updates
  inside the same 'if' block.
- Set port's rx_length_th back to 0 during uninit.
- Remove unneeded 'blocking' parameter from t7xx_cldma_send_skb().
- Return -EIO in t7xx_cldma_send_skb() if the queue is inactive.
- Refactor t7xx_cldma_qs_are_active() to use pci_device_is_present().
- Simplify t7xx_cldma_stop_q() and rename it to t7xx_cldma_stop_all_qs().
- Fix potential leaks in t7xx_cldma_init().
- Improve error handling in fsm_append_event and fsm_routine_starting().
- Propagate return codes from fsm_append_cmd() and t7xx_fsm_append_event().
- Refactor fsm_wait_for_event() to avoid unnecessary sleep.
- Create the WWAN ports and net device only after the modem is in
  the ready state.
- Refactor t7xx_port_proxy_recv_skb() and port_recv_skb().
- Rename t7xx_port_check_rx_seq_num() as t7xx_port_next_rx_seq_num()
  and fix the seq_num logic to handle overflows.
- Declare seq_nums as u16 instead of short.
- Use unsigned int for local indexes.
- Use min_t instead of the ternary operator.
- Refactor the loop in t7xx_dpmaif_rx_data_collect() to avoid a dead
  condition check.
- Use a bitmap (bat_bitmap) instead of an array to keep track of
  the DRB status. Used in t7xx_dpmaif_avail_pkt_bat_cnt().
- Refactor t7xx_dpmaif_tx_send_skb() to protect tx_submit_skb_cnt
  with spinlock and remove the misleading tx_drb_available variable.
- Consolidate bit operations before endianness conversion.
- Use C bit fields in dpmaif_drb_skb struct which is not HW related.
- Add back the que_started check in t7xx_select_tx_queue().
- Create a helper function to get the DRB count.
- Simplify the use of 'usage' during t7xx_ccmni_close().
- Enforce CCMNI MTU selection with BUILD_BUG_ON() instead of a comment.
- Remove t7xx_ccmni_ctrl->capability parameter which remains constant.

v4:
- Implement list_prev_entry_circular() and list_next_entry_circular() macros.
- Remove inline from all c files.
- Define ioread32_poll_timeout_atomic() helper macro.
- Fix return code for WWAN port tx op.
- Allow AT commands fragmentation same as MBIM commands.
- Introduce t7xx_common.h file in the first patch.
- Rename functions and variables as suggested in v3.
- Reduce code duplication by creating fsm_wait_for_event() helper function.
- Remove unneeded dev_err in t7xx_fsm_clr_event().
- Remove unused variable last_state from struct t7xx_fsm_ctl.
- Remove unused variable txq_select_times from struct dpmaif_ctrl.
- Replace ETXTBSY with EBUSY.
- Refactor t7xx_dpmaif_rx_buf_alloc() to remove an unneeded allocation.
- Fix potential leak at t7xx_dpmaif_rx_frag_alloc().
- Simplify return value handling at t7xx_dpmaif_rx_start().
- Add a helper to handle the common part of CCCI header initialization.
- Make sure interrupts are enabled during PM resume.
- Add a parameter to t7xx_fsm_append_cmd() to tell if it is in interrupt context.

v3:
- Avoid unneeded ping-pong changes between patches.
- Use t7xx_ prefix in functions.
- Use t7xx_ prefix in generic structs where mtk_ or ccci prefix was used.
- Update Authors/Contributors header.
- Remove skb pools used for control path.
- Remove skb pools used for RX data path.
- Do not use dedicated TX queue for ACK-only packets.
- Remove __packed attribute from GPD structs.
- Remove the infrastructure for test and debug ports.
- Use the skb control buffer to store metadata.
- Get the IP packet type from RX PIT.
- Merge variable declaration and simple assignments.
- Use preferred coding patterns.
- Remove global variables.
- Declare HW facing structure members as little endian.
- Rename goto tags to describe what is going to be done.
- Do not use variable length arrays.
- Remove unneeded blank lines source code and kdoc headers.
- Use C99 initialization format for port-proxy ports.
- Clean up comments.
- Review included headers.
- Better use of 100 column limit.
- Remove unneeded mb() in CLDMA.
- Remove unneeded spin locks and atomics.
- Handle read_poll_timeout error.
- Use dev_err_ratelimited() where required.
- Fix resource leak when requesting IRQs.
- Use generic DEFAULT_TX_QUEUE_LEN instead custom macro.
- Use ETH_DATA_LEN instead of defining WWAN_DEFAULT_MTU.
- Use sizeof() instead of defines when the size of structures is required.
- Remove unneeded code from netdev:
    No need to configure HW address length
    No need to implement .ndo_change_mtu
    Remove random address generation
- Code simplifications by using kernel provided functions and macros such as:
    module_pci_driver
    PTR_ERR_OR_ZERO
    for_each_set_bit
    pci_device_is_present
    skb_queue_purge
    list_prev_entry
    __ffs64

v2:
- Replace pdev->driver->name with dev_driver_string(&pdev->dev).
- Replace random_ether_addr() with eth_random_addr().
- Update kernel-doc comment for enum data_policy.
- Indicate the driver is 'Supported' instead of 'Maintained'.
- Fix the Signed-of-by and Co-developed-by tags in the patches.
- Added authors and contributors in the top comment of the src files.
====================
  • Loading branch information
David S. Miller committed May 9, 2022
2 parents c908565 + c9933d4 commit 6da3c47
Show file tree
Hide file tree
Showing 38 changed files with 11,345 additions and 0 deletions.
1 change: 1 addition & 0 deletions Documentation/networking/device_drivers/wwan/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Contents:
:maxdepth: 2

iosm
t7xx

.. only:: subproject and html

Expand Down
120 changes: 120 additions & 0 deletions Documentation/networking/device_drivers/wwan/t7xx.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
.. SPDX-License-Identifier: GPL-2.0-only
.. Copyright (C) 2020-21 Intel Corporation
.. _t7xx_driver_doc:

============================================
t7xx driver for MTK PCIe based T700 5G modem
============================================
The t7xx driver is a WWAN PCIe host driver developed for linux or Chrome OS platforms
for data exchange over PCIe interface between Host platform & MediaTek's T700 5G modem.
The driver exposes an interface conforming to the MBIM protocol [1]. Any front end
application (e.g. Modem Manager) could easily manage the MBIM interface to enable
data communication towards WWAN. The driver also provides an interface to interact
with the MediaTek's modem via AT commands.

Basic usage
===========
MBIM & AT functions are inactive when unmanaged. The t7xx driver provides
WWAN port userspace interfaces representing MBIM & AT control channels and does
not play any role in managing their functionality. It is the job of a userspace
application to detect port enumeration and enable MBIM & AT functionalities.

Examples of few such userspace applications are:

- mbimcli (included with the libmbim [2] library), and
- Modem Manager [3]

Management Applications to carry out below required actions for establishing
MBIM IP session:

- open the MBIM control channel
- configure network connection settings
- connect to network
- configure IP network interface

Management Applications to carry out below required actions for send an AT
command and receive response:

- open the AT control channel using a UART tool or a special user tool

Management application development
==================================
The driver and userspace interfaces are described below. The MBIM protocol is
described in [1] Mobile Broadband Interface Model v1.0 Errata-1.

MBIM control channel userspace ABI
----------------------------------

/dev/wwan0mbim0 character device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The driver exposes an MBIM interface to the MBIM function by implementing
MBIM WWAN Port. The userspace end of the control channel pipe is a
/dev/wwan0mbim0 character device. Application shall use this interface for
MBIM protocol communication.

Fragmentation
~~~~~~~~~~~~~
The userspace application is responsible for all control message fragmentation
and defragmentation as per MBIM specification.

/dev/wwan0mbim0 write()
~~~~~~~~~~~~~~~~~~~~~~~
The MBIM control messages from the management application must not exceed the
negotiated control message size.

/dev/wwan0mbim0 read()
~~~~~~~~~~~~~~~~~~~~~~
The management application must accept control messages of up the negotiated
control message size.

MBIM data channel userspace ABI
-------------------------------

wwan0-X network device
~~~~~~~~~~~~~~~~~~~~~~
The t7xx driver exposes IP link interface "wwan0-X" of type "wwan" for IP
traffic. Iproute network utility is used for creating "wwan0-X" network
interface and for associating it with MBIM IP session.

The userspace management application is responsible for creating new IP link
prior to establishing MBIM IP session where the SessionId is greater than 0.

For example, creating new IP link for a MBIM IP session with SessionId 1:

ip link add dev wwan0-1 parentdev wwan0 type wwan linkid 1

The driver will automatically map the "wwan0-1" network device to MBIM IP
session 1.

AT port userspace ABI
----------------------------------

/dev/wwan0at0 character device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The driver exposes an AT port by implementing AT WWAN Port.
The userspace end of the control port is a /dev/wwan0at0 character
device. Application shall use this interface to issue AT commands.

The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification.

References
==========
[1] *MBIM (Mobile Broadband Interface Model) Errata-1*

- https://www.usb.org/document-library/

[2] *libmbim "a glib-based library for talking to WWAN modems and devices which
speak the Mobile Interface Broadband Model (MBIM) protocol"*

- http://www.freedesktop.org/wiki/Software/libmbim/

[3] *Modem Manager "a DBus-activated daemon which controls mobile broadband
(2G/3G/4G/5G) devices and connections"*

- http://www.freedesktop.org/wiki/Software/ModemManager/

[4] *Specification # 27.007 - 3GPP*

- https://www.3gpp.org/DynaReport/27007.htm
11 changes: 11 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -12488,6 +12488,17 @@ S: Maintained
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c

MEDIATEK T7XX 5G WWAN MODEM DRIVER
M: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
M: Intel Corporation <linuxwwan@intel.com>
R: Chiranjeevi Rapolu <chiranjeevi.rapolu@linux.intel.com>
R: Liu Haijun <haijun.liu@mediatek.com>
R: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
R: Ricardo Martinez <ricardo.martinez@linux.intel.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/wwan/t7xx/

MEDIATEK USB3 DRD IP DRIVER
M: Chunfeng Yun <chunfeng.yun@mediatek.com>
L: linux-usb@vger.kernel.org
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/wwan/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ config IOSM

If unsure, say N.

config MTK_T7XX
tristate "MediaTek PCIe 5G WWAN modem T7xx device"
depends on PCI
help
Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device.
Adapts WWAN framework and provides network interface like wwan0
and tty interfaces like wwan0at0 (AT protocol), wwan0mbim0
(MBIM protocol), etc.

To compile this driver as a module, choose M here: the module will be
called mtk_t7xx.

If unsure, say N.

endif # WWAN

endmenu
1 change: 1 addition & 0 deletions drivers/net/wwan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ obj-$(CONFIG_MHI_WWAN_MBIM) += mhi_wwan_mbim.o
obj-$(CONFIG_QCOM_BAM_DMUX) += qcom_bam_dmux.o
obj-$(CONFIG_RPMSG_WWAN_CTRL) += rpmsg_wwan_ctrl.o
obj-$(CONFIG_IOSM) += iosm/
obj-$(CONFIG_MTK_T7XX) += t7xx/
20 changes: 20 additions & 0 deletions drivers/net/wwan/t7xx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: GPL-2.0-only

ccflags-y += -Werror

obj-${CONFIG_MTK_T7XX} := mtk_t7xx.o
mtk_t7xx-y:= t7xx_pci.o \
t7xx_pcie_mac.o \
t7xx_mhccif.o \
t7xx_state_monitor.o \
t7xx_modem_ops.o \
t7xx_cldma.o \
t7xx_hif_cldma.o \
t7xx_port_proxy.o \
t7xx_port_ctrl_msg.o \
t7xx_port_wwan.o \
t7xx_hif_dpmaif.o \
t7xx_hif_dpmaif_tx.o \
t7xx_hif_dpmaif_rx.o \
t7xx_dpmaif.o \
t7xx_netdev.o
Loading

0 comments on commit 6da3c47

Please sign in to comment.