Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit affa71ab authored by Sneh Shah's avatar Sneh Shah
Browse files

net: stmmac: Add support for IPA offload



Add functionality for IPA offload to support HW path acceleration.

Change-Id: I5bde438c0d935cdc3d4b04e4f029458ed5084243
Signed-off-by: default avatarSneh Shah <snehshah@codeaurora.org>
parent 11ae02d0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -107,6 +107,16 @@ config DWMAC_QCOM_ETHQOS
	  This selects the Qualcomm Technologies, Inc. ETHQOS glue layer support for the
	  stmmac device driver.

config ETHQOS_IPA_OFFLOAD
	bool "IPA ETHQOS offload support"
	depends on DWMAC_QCOM_ETHQOS && IPA3
	default n
	help
	  Support for the Qualcomm Technologies, Inc. ETH IPA offload support.
	  This enables ethernet ipa offload for IP traffic to reduce
	  the cpu load during E2E IP traffic. This is done by using HW accelaration
	  path.

config DWMAC_ROCKCHIP
	tristate "Rockchip dwmac support"
	default ARCH_ROCKCHIP
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-gpio.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-pps.o
obj-$(CONFIG_ETHQOS_IPA_OFFLOAD)	+= dwmac-qcom-ipa.o
obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-altr-socfpga.o
obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
@@ -28,6 +29,7 @@ stmmac-platform-objs:= stmmac_platform.o
dwmac-altr-socfpga-objs := altr_tse_pcs.o dwmac-socfpga.o

ccflags-$(CONFIG_PTP_1588_CLOCK)+=-DCONFIG_PTPSUPPORT_OBJ
ccflags-$(CONFIG_ETHQOS_IPA_OFFLOAD)+=-DCONFIG_ETH_IPA_OFFLOAD

obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
stmmac-pci-objs:= stmmac_pci.o
+28 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "stmmac_platform.h"
#include "dwmac-qcom-ethqos.h"
#include "stmmac_ptp.h"
#include "dwmac-qcom-ipa-offload.h"

static unsigned long tlmm_central_base_addr;
bool phy_intr_en;
@@ -838,6 +839,21 @@ static int ethqos_create_debugfs(struct qcom_ethqos *ethqos)
	return -ENOMEM;
}

static void ethqos_emac_mem_base(struct qcom_ethqos *ethqos)
{
	struct resource *resource = NULL;
	int ret = 0;

	resource = platform_get_resource(ethqos->pdev, IORESOURCE_MEM, 0);
	if (!resource) {
		ETHQOSERR("get emac-base resource failed\n");
		ret = -ENODEV;
		return;
	}
	ethqos->emac_mem_base = resource->start;
	ethqos->emac_mem_size = resource_size(resource);
}

static void emac_emb_smmu_exit(void)
{
	if (emac_emb_smmu_ctx.valid) {
@@ -1147,6 +1163,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
	struct stmmac_resources stmmac_res;
	struct qcom_ethqos *ethqos;
	struct resource *res;
	struct net_device *ndev;
	struct stmmac_priv *priv;
	int ret;

	ipc_emac_log_ctxt = ipc_log_context_create(IPCLOG_STATE_PAGES,
@@ -1228,7 +1246,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)

	ethqos->emac_ver = rgmii_readl(ethqos,
				       EMAC_I0_EMAC_CORE_HW_VERSION_RGOFFADDR);

	ethqos->ioaddr = (&stmmac_res)->addr;
	ethqos_update_rgmii_tx_drv_strength(ethqos);

	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
@@ -1259,8 +1277,17 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
			  qcom_ethqos_qmp_mailbox_work);
		queue_work(system_wq, &ethqos->qmp_mailbox_work);
	}
	ethqos_emac_mem_base(ethqos);
	pethqos = ethqos;
	ethqos_create_debugfs(ethqos);

	ndev = dev_get_drvdata(&ethqos->pdev->dev);
	priv = netdev_priv(ndev);
#ifdef CONFIG_ETH_IPA_OFFLOAD
	ethqos->ipa_enabled = true;
	priv->rx_queue[IPA_DMA_RX_CH].skip_sw = true;
	priv->tx_queue[IPA_DMA_TX_CH].skip_sw = true;
#endif
	return ret;

err_clk:
+47 −1
Original line number Diff line number Diff line
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -267,6 +267,46 @@ enum IO_MACRO_PHY_MODE {
		MII_MODE
};

#define RGMII_IO_BASE_ADDRESS ethqos->rgmii_base

#define RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET (0x00000000)

#define RGMII_IO_MACRO_CONFIG_RGWR(data)\
	writel_relaxed(data, RGMII_IO_MACRO_CONFIG_RGOFFADDR)

#define RGMII_IO_MACRO_CONFIG_RGOFFADDR \
	(RGMII_IO_BASE_ADDRESS + RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET)

#define RX_CONTEXT_DESC_RDES3_OWN_MLF_WR(ptr, data)\
	SET_BITS(0x1f, 0x1f, ptr, data)

#define RGMII_IO_MACRO_CONFIG_RGRD(data)\
	((data) = (readl_relaxed((RGMII_IO_MACRO_CONFIG_RGOFFADDR))))

#define RGMII_GPIO_CFG_TX_INT_MASK (unsigned long)(0x3)

#define RGMII_GPIO_CFG_TX_INT_WR_MASK (unsigned long)(0xfff9ffff)

#define RGMII_GPIO_CFG_TX_INT_UDFWR(data) do {\
	unsigned long v;\
	RGMII_IO_MACRO_CONFIG_RGRD(v);\
	v = ((v & RGMII_GPIO_CFG_TX_INT_WR_MASK) | \
	((data & RGMII_GPIO_CFG_TX_INT_MASK) << 17));\
	RGMII_IO_MACRO_CONFIG_RGWR(v);\
} while (0)

#define RGMII_GPIO_CFG_RX_INT_MASK (unsigned long)(0x3)

#define RGMII_GPIO_CFG_RX_INT_WR_MASK (unsigned long)(0xffe7ffff)

#define RGMII_GPIO_CFG_RX_INT_UDFWR(data) do {\
	unsigned long v;\
	RGMII_IO_MACRO_CONFIG_RGRD(v);\
	v = ((v & RGMII_GPIO_CFG_RX_INT_WR_MASK) | \
	((data & RGMII_GPIO_CFG_RX_INT_MASK) << 19));\
	RGMII_IO_MACRO_CONFIG_RGWR(v);\
} while (0)

struct ethqos_emac_por {
	unsigned int offset;
	unsigned int value;
@@ -293,6 +333,7 @@ static const struct ethqos_emac_por emac_v2_3_2_por[] = {
struct qcom_ethqos {
	struct platform_device *pdev;
	void __iomem *rgmii_base;
	void __iomem *ioaddr;

	struct msm_bus_scale_pdata *bus_scale_vec;
	u32 bus_hdl;
@@ -352,6 +393,11 @@ struct qcom_ethqos {
	struct mbox_client *qmp_mbox_client;
	struct work_struct qmp_mailbox_work;
	int disable_ctile_pc;

	u32 emac_mem_base;
	u32 emac_mem_size;

	bool ipa_enabled;
};

struct pps_cfg {
+62 −0
Original line number Diff line number Diff line
/* Copyright (c) 2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef	_DWMAC_QCOM_ETH_IPA_OFFLOAD_H
#define	_DWMAC_QCOM_ETH_IPA_OFFLOAD_H

#define IPA_DMA_RX_CH 0
#define IPA_DMA_TX_CH 0

#define ALL_OTHER_TX_TRAFFIC_IPA_DISABLED 0
#define ALL_OTHER_TRAFFIC_TX_CHANNEL 1

#define QTAG_VLAN_ETH_TYPE_OFFSET 16
#define QTAG_UCP_FIELD_OFFSET 14
#define QTAG_ETH_TYPE_OFFSET 12
#define PTP_UDP_EV_PORT 0x013F
#define PTP_UDP_GEN_PORT 0x0140

#define GET_ETH_TYPE(buf, ethtype) do { \
	unsigned char *buf1 = buf;\
	ethtype = (((((u16)buf1[QTAG_ETH_TYPE_OFFSET] << 8) | \
		   buf1[QTAG_ETH_TYPE_OFFSET + 1]) == ETH_P_8021Q) ? \
		   (((u16)buf1[QTAG_VLAN_ETH_TYPE_OFFSET] << 8) | \
		   buf1[QTAG_VLAN_ETH_TYPE_OFFSET + 1]) : \
		   (((u16)buf1[QTAG_ETH_TYPE_OFFSET] << 8) | \
		    buf1[QTAG_ETH_TYPE_OFFSET + 1]));\
} while (0)

enum  IPA_OFFLOAD_EVENT {
	EV_INVALID = 0,
	EV_DEV_OPEN = 1,
	EV_DEV_CLOSE = 2,
	EV_IPA_READY = 3,
	EV_IPA_UC_READY = 4,
	EV_PHY_LINK_UP = 5,
	EV_PHY_LINK_DOWN = 6,
	EV_DPM_SUSPEND = 7,
	EV_DPM_RESUME = 8,
	EV_USR_SUSPEND = 9,
	EV_USR_RESUME = 10,
	EV_IPA_OFFLOAD_MAX = 11,
	EV_IPA_OFFLOAD_REMOVE = 12,
};

#ifdef CONFIG_ETH_IPA_OFFLOAD
void ethqos_ipa_offload_event_handler(void *data, int ev);
#else
static inline void ethqos_ipa_offload_event_handler(void *data, int ev)
{
}
#endif

#endif
Loading