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

Commit b9f4991e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: stmmac: Support multiple IPA channels"

parents 78bb0d13 05af4110
Loading
Loading
Loading
Loading
+60 −15
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/ipv6.h>
#include <linux/rtnetlink.h>
#include <linux/if_vlan.h>
#include <linux/msm_eth.h>

#include "stmmac.h"
#include "stmmac_platform.h"
@@ -159,6 +160,13 @@ u16 dwmac_qcom_select_queue(
			txqueue_select = ALL_OTHER_TX_TRAFFIC_IPA_DISABLED;
	}

	/* use better macro, cannot afford function call here */
	if (ipa_enabled && (txqueue_select == IPA_DMA_TX_CH_BE ||
			    txqueue_select == IPA_DMA_TX_CH_CV2X)) {
		ETHQOSERR("TX Channel [%d] is not a valid for SW path\n",
			  txqueue_select);
		WARN_ON(1);
	}
	ETHQOSDBG("tx_queue %d\n", txqueue_select);
	return txqueue_select;
}
@@ -1539,15 +1547,11 @@ static void setup_config_registers(struct qcom_ethqos *ethqos,
	if (mode > DISABLE_LOOPBACK && !qcom_ethqos_is_phy_link_up(ethqos)) {
		/*If Link is Down & need to enable Loopback*/
		ETHQOSDBG("Link is down . manual ipa setting up\n");
		if (priv->tx_queue[IPA_DMA_TX_CH].skip_sw)
			ethqos_ipa_offload_event_handler(priv,
							 EV_PHY_LINK_UP);
		ethqos_ipa_offload_event_handler(priv, EV_PHY_LINK_UP);
	} else if (mode == DISABLE_LOOPBACK &&
			  !qcom_ethqos_is_phy_link_up(ethqos)) {
		ETHQOSDBG("Disable request since link was down disable ipa\n");
		if (priv->tx_queue[IPA_DMA_TX_CH].skip_sw)
			ethqos_ipa_offload_event_handler(priv,
							 EV_PHY_LINK_DOWN);
		ethqos_ipa_offload_event_handler(priv, EV_PHY_LINK_DOWN);
	}

	if (priv->dev->phydev->speed != SPEED_UNKNOWN)
@@ -2358,12 +2362,23 @@ bool qcom_ethqos_ipa_enabled(void)
static ssize_t ethqos_read_dev_emac(struct file *filp, char __user *buf,
				    size_t count, loff_t *f_pos)
{
	unsigned int len = 0;
	char *temp_buf;
	ssize_t ret_cnt = 0;
	struct eth_msg_meta msg;
	u8 status = 0;

	ret_cnt = simple_read_from_buffer(buf, count, f_pos, temp_buf, len);
	return ret_cnt;
	memset(&msg, 0,  sizeof(struct eth_msg_meta));

	if (pethqos && pethqos->ipa_enabled)
		ethqos_ipa_offload_event_handler(
			&status, EV_QTI_GET_CONN_STATUS);

	msg.msg_type = status;

	ETHQOSDBG("status %02x\n", status);
	ETHQOSDBG("msg.msg_type %02x\n", msg.msg_type);
	ETHQOSDBG("msg.rsvd %02x\n", msg.rsvd);
	ETHQOSDBG("msg.msg_len %d\n", msg.msg_len);

	return copy_to_user(buf, &msg, sizeof(struct eth_msg_meta));
}

static ssize_t ethqos_write_dev_emac(struct file *file,
@@ -2385,6 +2400,7 @@ static ssize_t ethqos_write_dev_emac(struct file *file,
		ETHQOSERR("emac string is too long - count=%u\n", count);
		return -EFAULT;
	}

	memset(in_buf, 0,  sizeof(in_buf));
	ret = copy_from_user(in_buf, user_buf, count);

@@ -2485,10 +2501,42 @@ static void ethqos_get_qoe_dt(struct qcom_ethqos *ethqos,
	}
}

static DECLARE_WAIT_QUEUE_HEAD(dev_emac_wait);
#ifdef CONFIG_ETH_IPA_OFFLOAD
void ethqos_wakeup_dev_emac_queue(void)
{
	ETHQOSDBG("\n");
	wake_up_interruptible(&dev_emac_wait);
}
#endif

static unsigned int ethqos_poll_dev_emac(struct file *file, poll_table *wait)
{
	int mask = 0;
	int update = 0;

	ETHQOSDBG("\n");

	poll_wait(file, &dev_emac_wait, wait);

	if (pethqos && pethqos->ipa_enabled && pethqos->cv2x_mode)
		ethqos_ipa_offload_event_handler(
			&update, EV_QTI_CHECK_CONN_UPDATE);

	if (update)
		mask = POLLIN | POLLRDNORM;

	ETHQOSDBG("mask %d\n", mask);

	return mask;
}

static const struct file_operations emac_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = ethqos_read_dev_emac,
	.write = ethqos_write_dev_emac,
	.poll = ethqos_poll_dev_emac,
};

static int ethqos_create_emac_device_node(dev_t *emac_dev_t,
@@ -2946,12 +2994,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
					       &ethqos->emac_class,
					       "emac");
	}

#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;
	ethqos_ipa_offload_event_handler(ethqos, EV_PROBE_INIT);
	priv->hw->mac->map_mtl_to_dma(priv->hw, 0, 1); //change
#endif

#ifdef CONFIG_MSM_BOOT_TIME_MARKER
+4 −6
Original line number Diff line number Diff line
@@ -374,9 +374,9 @@ enum current_phy_state {
#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_MASK (unsigned long)(0x7)

#define RGMII_GPIO_CFG_TX_INT_WR_MASK (unsigned long)(0xfff9ffff)
#define RGMII_GPIO_CFG_TX_INT_WR_MASK (unsigned long)(0xfff1ffff)

#define RGMII_GPIO_CFG_TX_INT_UDFWR(data) do {\
	unsigned long v;\
@@ -388,13 +388,13 @@ enum current_phy_state {

#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_WR_MASK (unsigned long)(0xFFCFFFFF)

#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));\
	((data & RGMII_GPIO_CFG_RX_INT_MASK) << 20));\
	RGMII_IO_MACRO_CONFIG_RGWR(v);\
} while (0)

@@ -631,8 +631,6 @@ u16 dwmac_qcom_select_queue(
#define PTP_UDP_EV_PORT 0x013F
#define PTP_UDP_GEN_PORT 0x0140

#define IPA_DMA_TX_CH 0
#define IPA_DMA_RX_CH 0

#define CV2X_TAG_TX_CHANNEL 3
#define QMI_TAG_TX_CHANNEL 2
+24 −4
Original line number Diff line number Diff line
@@ -13,11 +13,10 @@
#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 ETH_DEV_NAME_LEN 16
#define ETH_DEV_ADDR_LEN 8

#define QTAG_VLAN_ETH_TYPE_OFFSET 16
#define QTAG_UCP_FIELD_OFFSET 14
@@ -35,9 +34,26 @@
		    buf1[QTAG_ETH_TYPE_OFFSET + 1]));\
} while (0)

enum ipa_queue_type {
	IPA_QUEUE_BE = 0x0,
	IPA_QUEUE_CV2X,
	IPA_QUEUE_MAX,
};

enum ipa_intr_route_type {
	IPA_INTR_ROUTE_HW = 0x0,
	IPA_INTR_ROUTE_DB,
	IPA_INTR_ROUTE_MAX,
};

#define IPA_DMA_RX_CH_BE 0
#define IPA_DMA_TX_CH_BE 0
#define IPA_DMA_RX_CH_CV2X 3
#define IPA_DMA_TX_CH_CV2X 3

#ifdef CONFIG_ETH_IPA_OFFLOAD
void ethqos_ipa_offload_event_handler(void *data, int ev);
void ethqos_wakeup_dev_emac_queue(void);
#else
static inline void ethqos_ipa_offload_event_handler(void *data, int ev)
{
@@ -58,6 +74,10 @@ static inline void ethqos_ipa_offload_event_handler(void *data, int ev)
#define EV_USR_SUSPEND (EV_DPM_RESUME + 1)
#define EV_USR_RESUME (EV_USR_SUSPEND + 1)
#define EV_IPA_OFFLOAD_REMOVE (EV_USR_RESUME + 1)
#define EV_IPA_OFFLOAD_MAX (EV_IPA_OFFLOAD_REMOVE + 1)
#define EV_QTI_GET_CONN_STATUS (EV_IPA_OFFLOAD_REMOVE + 1)
#define EV_QTI_CHECK_CONN_UPDATE (EV_QTI_GET_CONN_STATUS + 1)
#define EV_IPA_HANDLE_RX_INTR (EV_QTI_CHECK_CONN_UPDATE + 1)
#define EV_IPA_HANDLE_TX_INTR (EV_IPA_HANDLE_RX_INTR + 1)
#define EV_IPA_OFFLOAD_MAX (EV_IPA_HANDLE_TX_INTR + 1)

#endif
+1431 −793

File changed.

Preview size limit exceeded, changes collapsed.

+79 −37
Original line number Diff line number Diff line
@@ -20,22 +20,6 @@
#define IPA_LOCK() mutex_lock(&eth_ipa_ctx.ipa_lock)
#define IPA_UNLOCK() mutex_unlock(&eth_ipa_ctx.ipa_lock)

static char * const IPA_OFFLOAD_EVENT_string[] = {
	"EV_INVALID",
	"EV_DEV_OPEN",
	"EV_DEV_CLOSE",
	"EV_IPA_READY",
	"EV_IPA_UC_READY",
	"EV_PHY_LINK_UP",
	"EV_PHY_LINK_DOWN",
	"EV_DPM_SUSPEND",
	"EV_DPM_RESUME",
	"EV_USR_SUSPEND",
	"EV_USR_RESUME",
	"EV_IPA_OFFLOAD_MAX"
};


#define GET_VALUE(data, lbit, lbit2, hbit) ((data >> lbit) & \
		(~(~0 << (hbit - lbit2 + 1))))

@@ -64,22 +48,29 @@ static char * const IPA_OFFLOAD_EVENT_string[] = {

#define GET_RX_CURRENT_RCVD_LAST_DESC_INDEX(start_index, offset, desc_cnt)\
		(desc_cnt - 1)
#define GET_RX_DESC_IDX(QINX, desc)\
	(((desc) - eth_ipa_ctx.rx_queue->rx_desc_dma_addrs[0]) / \
#define GET_RX_DESC_IDX(type, desc)\
	(((desc) - eth_ipa_ctx.rx_queue[type]->rx_desc_dma_addrs[0]) / \
	 (sizeof(struct dma_desc)))

#define GET_TX_DESC_IDX(QINX, desc)\
	(((desc) - eth_ipa_ctx.tx_queue->tx_desc_dma_addrs[0]) / \
#define GET_TX_DESC_IDX(type, desc)\
	(((desc) - eth_ipa_ctx.tx_queue[type]->tx_desc_dma_addrs[0]) / \
	 (sizeof(struct dma_desc)))

#define DMA_CR0_RGOFFADDR ((BASE_ADDRESS + 0x1100))
#define DMA_CR3_RGOFFADDR ((BASE_ADDRESS + 0x1280))
#define DMA_CR4_RGOFFADDR ((BASE_ADDRESS + 0x1300))

#define ETHQOS_ETH_FRAME_LEN_IPA ((1 << 11)) /*IPA can support 2KB max length*/
/* IPA can support 2KB max length */
#define ETHQOS_ETH_FRAME_LEN_IPA_BE ((1 << 11))
#define ETHQOS_ETH_FRAME_LEN_IPA_CV2X ((1 << 11))

#define IPA_TX_DESC_CNT 128 /*Default TX desc count to 128 for IPA offload*/
#define IPA_RX_DESC_CNT 128 /*Default RX desc count to 128 for IPA offload*/
/* Default desc count */
#define IPA_TX_DESC_CNT_BE	128
#define IPA_RX_DESC_CNT_BE	128
#define IPA_TX_DESC_CNT_CV2X 128
#define IPA_RX_DESC_CNT_CV2X 128

#define  BASE_ADDRESS (ethqos->ioaddr)
#define  BASE_ADDRESS (eth_ipa_ctx.ethqos->ioaddr)

#define DMA_TDRLR_RGOFFADDR (BASE_ADDRESS + 0x112c)

@@ -581,13 +572,13 @@ struct ethqos_tx_queue {

	void **ipa_tx_buff_pool_va_addrs_base;

	dma_addr_t *ipa_tx_buff_pool_pa_addrs_base;
	dma_addr_t ipa_tx_buff_pool_pa_addrs_base_dmahndl;
	dma_addr_t *ipa_tx_pa_addrs_base;
	dma_addr_t ipa_tx_pa_addrs_base_dmahndl;

	dma_addr_t *skb_dma;		/* dma address of skb */
	struct sk_buff **skb;	/* virtual address of skb */
	unsigned short *len;	/* length of first skb */
	phys_addr_t *ipa_tx_buff_phy_addr; /* physical address of ipa TX buff */
	phys_addr_t *ipa_tx_phy_addr; /* physical address of ipa TX buff */
};

struct ethqos_rx_queue {
@@ -599,8 +590,8 @@ struct ethqos_rx_queue {

	void **ipa_rx_buff_pool_va_addrs_base;

	dma_addr_t *ipa_rx_buff_pool_pa_addrs_base;
	dma_addr_t ipa_rx_buff_pool_pa_addrs_base_dmahndl;
	dma_addr_t *ipa_rx_pa_addrs_base;
	dma_addr_t ipa_rx_pa_addrs_base_dmahndl;

	dma_addr_t *skb_dma;		/* dma address of skb */
	struct sk_buff **skb;	/* virtual address of skb */
@@ -656,15 +647,60 @@ struct ethqos_ipa_stats {
};

struct ethqos_prv_ipa_data {
	struct ethqos_tx_queue *tx_queue;
	struct ethqos_rx_queue *rx_queue;
	bool queue_enabled[IPA_QUEUE_MAX];
	struct ethqos_tx_queue *tx_queue[IPA_QUEUE_MAX];
	struct ethqos_rx_queue *rx_queue[IPA_QUEUE_MAX];

	void __iomem *uc_db_rx_addr[IPA_QUEUE_MAX];
	void __iomem *uc_db_tx_addr[IPA_QUEUE_MAX];
	u32 ipa_client_hndl[IPA_QUEUE_MAX];

	/* desc count */
	u32 ipa_dma_tx_desc_cnt[IPA_QUEUE_MAX];
	u32 ipa_dma_rx_desc_cnt[IPA_QUEUE_MAX];

	/* intr moderation count only for RX */
	/* TX is taken care by IPA */
	u32 rx_intr_mod_cnt[IPA_QUEUE_MAX];

	/* interrupt routing mode */
	enum ipa_intr_route_type tx_intr_route_mode[IPA_QUEUE_MAX];
	enum ipa_intr_route_type rx_intr_route_mode[IPA_QUEUE_MAX];

	/* queue/chan number*/
	u8 tx_queue_num[IPA_QUEUE_MAX];
	u8 rx_queue_num[IPA_QUEUE_MAX];

	/* buffer lens */
	u32 buf_len[IPA_QUEUE_MAX];

	/* ipa cb for rx exception packets */
	ipa_notify_cb ipa_notify_cb[IPA_QUEUE_MAX];

	/* IPA protocol */
	u32 ipa_proto[IPA_QUEUE_MAX];

	/* IPA client enums prod/cons */
	u32 tx_client[IPA_QUEUE_MAX];
	u32 rx_client[IPA_QUEUE_MAX];

	/* rx channel reg base ptr */
	phys_addr_t rx_reg_base_ptr_pa[IPA_QUEUE_MAX];

	/* tx channel reg base ptr */
	phys_addr_t tx_reg_base_ptr_pa[IPA_QUEUE_MAX];

	/* set if ipa_send_message is needed for a queue type */
	bool need_send_msg[IPA_QUEUE_MAX];

	/* network device name*/
	char netdev_name[IPA_QUEUE_MAX][ETH_DEV_NAME_LEN];

	phys_addr_t uc_db_rx_addr;
	phys_addr_t uc_db_tx_addr;
	u32 ipa_client_hndl;
	/* network device index */
	u8 netdev_index[IPA_QUEUE_MAX];

	u32 ipa_dma_tx_desc_cnt;
	u32 ipa_dma_rx_desc_cnt;
	/* network device addr */
	u8 netdev_addr[IPA_QUEUE_MAX][ETH_ALEN];

	/* IPA state variables */
	/* State of EMAC HW initialization */
@@ -677,6 +713,8 @@ struct ethqos_prv_ipa_data {
	bool ipa_offload_init;
	/* State of IPA pipes connection */
	bool ipa_offload_conn;
	/* State of IPA pipes connection previously */
	bool ipa_offload_conn_prev;
	/* State of debugfs creation */
	bool ipa_debugfs_exists;
	/* State of IPA offload suspended by user */
@@ -695,9 +733,13 @@ struct ethqos_prv_ipa_data {
	struct dentry *debugfs_ipa_stats;
	struct dentry *debugfs_dma_stats;
	struct dentry *debugfs_suspend_ipa_offload;
	struct ethqos_ipa_stats ipa_stats;
	struct ethqos_ipa_stats ipa_stats[IPA_QUEUE_MAX];

	struct qcom_ethqos *ethqos;
};

static void ntn_ipa_notify_cb_be(
	void *priv, enum ipa_dp_evt_type evt, unsigned long data);
static void ntn_ipa_notify_cb_cv2x(
	void *priv, enum ipa_dp_evt_type evt, unsigned long data);
#endif
Loading