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

Commit 2bb295f3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-hisilicon-Add-support-for-HI13X1-to-hip04_eth'



Jiangfeng Xiao says:

====================
net: hisilicon: Add support for HI13X1 to hip04_eth

The main purpose of this patch series is to extend the
hip04_eth driver to support HI13X1_GMAC.

The offset and bitmap of some registers of HI13X1_GMAC
are different from hip04_eth common soc. In addition,
the definition of send descriptor and parsing descriptor
are different from hip04_eth common soc. So the macro
of the register offset is redefined to adapt the HI13X1_GMAC.

Clean up the sparse warning by the way.

Change since v1:
* Add a cover letter.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 03a49a14 d413779c
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ Required properties:
	phandle, specifies a reference to the syscon ppe node
	port, port number connected to the controller
	channel, recv channel start from channel * number (RX_DESC_NUM)
	group, field in the pkg desc, in general, it is the same as the port.
- phy-mode: see ethernet.txt [1].

Optional properties:
@@ -66,7 +67,7 @@ Example:
		reg = <0x28b0000 0x10000>;
		interrupts = <0 413 4>;
		phy-mode = "mii";
		port-handle = <&ppe 31 0>;
		port-handle = <&ppe 31 0 31>;
	};

	ge0: ethernet@2800000 {
@@ -74,7 +75,7 @@ Example:
		reg = <0x2800000 0x10000>;
		interrupts = <0 402 4>;
		phy-mode = "sgmii";
		port-handle = <&ppe 0 1>;
		port-handle = <&ppe 0 1 0>;
		phy-handle = <&phy0>;
	};

@@ -83,6 +84,6 @@ Example:
		reg = <0x2880000 0x10000>;
		interrupts = <0 410 4>;
		phy-mode = "sgmii";
		port-handle = <&ppe 8 2>;
		port-handle = <&ppe 8 2 8>;
		phy-handle = <&phy1>;
	};
+10 −0
Original line number Diff line number Diff line
@@ -46,6 +46,16 @@ config HIP04_ETH
	  If you wish to compile a kernel for a hardware with hisilicon p04 SoC and
	  want to use the internal ethernet then you should answer Y to this.

config HI13X1_GMAC
	bool "Hisilicon HI13X1 Network Device Support"
	depends on HIP04_ETH
	help
	  If you wish to compile a kernel for a hardware with hisilicon hi13x1_gamc
	  then you should answer Y to this. This makes this driver suitable for use
	  on certain boards such as the HI13X1.

	  If you are unsure, say N.

config HNS_MDIO
	tristate
	select PHYLIB
+122 −20
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

#define SC_PPE_RESET_DREQ		0x026C

#define PPE_CFG_RX_ADDR			0x100
#define PPE_CFG_POOL_GRP		0x300
#define PPE_CFG_RX_BUF_SIZE		0x400
@@ -33,10 +35,23 @@
#define GE_MODE_CHANGE_REG		0x1b4
#define GE_RECV_CONTROL_REG		0x1e0
#define GE_STATION_MAC_ADDRESS		0x210
#define PPE_CFG_CPU_ADD_ADDR		0x580
#define PPE_CFG_MAX_FRAME_LEN_REG	0x408

#define PPE_CFG_BUS_CTRL_REG		0x424
#define PPE_CFG_RX_CTRL_REG		0x428

#if defined(CONFIG_HI13X1_GMAC)
#define PPE_CFG_CPU_ADD_ADDR		0x6D0
#define PPE_CFG_MAX_FRAME_LEN_REG	0x500
#define PPE_CFG_RX_PKT_MODE_REG		0x504
#define PPE_CFG_QOS_VMID_GEN		0x520
#define PPE_CFG_RX_PKT_INT		0x740
#define PPE_INTEN			0x700
#define PPE_INTSTS			0x708
#define PPE_RINT			0x704
#define PPE_CFG_STS_MODE		0x880
#else
#define PPE_CFG_CPU_ADD_ADDR		0x580
#define PPE_CFG_MAX_FRAME_LEN_REG	0x408
#define PPE_CFG_RX_PKT_MODE_REG		0x438
#define PPE_CFG_QOS_VMID_GEN		0x500
#define PPE_CFG_RX_PKT_INT		0x538
@@ -44,8 +59,12 @@
#define PPE_INTSTS			0x608
#define PPE_RINT			0x604
#define PPE_CFG_STS_MODE		0x700
#endif /* CONFIG_HI13X1_GMAC */

#define PPE_HIS_RX_PKT_CNT		0x804

#define RESET_DREQ_ALL			0xffffffff

/* REG_INTERRUPT */
#define RCV_INT				BIT(10)
#define RCV_NOBUF			BIT(8)
@@ -57,8 +76,15 @@
/* TX descriptor config */
#define TX_FREE_MEM			BIT(0)
#define TX_READ_ALLOC_L3		BIT(1)
#define TX_FINISH_CACHE_INV		BIT(2)
#if defined(CONFIG_HI13X1_GMAC)
#define TX_CLEAR_WB			BIT(7)
#define TX_RELEASE_TO_PPE		BIT(4)
#define TX_FINISH_CACHE_INV		BIT(6)
#define TX_POOL_SHIFT			16
#else
#define TX_CLEAR_WB			BIT(4)
#define TX_FINISH_CACHE_INV		BIT(2)
#endif
#define TX_L3_CHECKSUM			BIT(5)
#define TX_LOOP_BACK			BIT(11)

@@ -93,18 +119,35 @@
#define GE_RX_PORT_EN			BIT(1)
#define GE_TX_PORT_EN			BIT(2)

#define PPE_CFG_STS_RX_PKT_CNT_RC	BIT(12)

#define PPE_CFG_RX_PKT_ALIGN		BIT(18)
#define PPE_CFG_QOS_VMID_MODE		BIT(14)

#if defined(CONFIG_HI13X1_GMAC)
#define PPE_CFG_QOS_VMID_GRP_SHIFT	4
#define PPE_CFG_RX_CTRL_ALIGN_SHIFT	7
#define PPE_CFG_STS_RX_PKT_CNT_RC	BIT(0)
#define PPE_CFG_QOS_VMID_MODE		BIT(15)
#define PPE_CFG_BUS_LOCAL_REL		(BIT(9) | BIT(15) | BIT(19) | BIT(23))

/* buf unit size is cache_line_size, which is 64, so the shift is 6 */
#define PPE_BUF_SIZE_SHIFT		6
#define PPE_TX_BUF_HOLD			BIT(31)
#define CACHE_LINE_MASK			0x3F
#else
#define PPE_CFG_QOS_VMID_GRP_SHIFT	8
#define PPE_CFG_RX_CTRL_ALIGN_SHIFT	11
#define PPE_CFG_STS_RX_PKT_CNT_RC	BIT(12)
#define PPE_CFG_QOS_VMID_MODE		BIT(14)
#define PPE_CFG_BUS_LOCAL_REL		BIT(14)

/* buf unit size is 1, so the shift is 6 */
#define PPE_BUF_SIZE_SHIFT		0
#define PPE_TX_BUF_HOLD			0
#endif /* CONFIG_HI13X1_GMAC */

#define PPE_CFG_RX_FIFO_FSFU		BIT(11)
#define PPE_CFG_RX_DEPTH_SHIFT		16
#define PPE_CFG_RX_START_SHIFT		0
#define PPE_CFG_RX_CTRL_ALIGN_SHIFT	11

#define PPE_CFG_BUS_LOCAL_REL		BIT(14)
#define PPE_CFG_BUS_BIG_ENDIEN		BIT(0)

#define RX_DESC_NUM			128
@@ -128,26 +171,50 @@
#define HIP04_MIN_TX_COALESCE_FRAMES	100

struct tx_desc {
#if defined(CONFIG_HI13X1_GMAC)
	u32 reserved1[2];
	u32 send_addr;
	u16 send_size;
	u16 data_offset;
	u32 reserved2[7];
	u32 cfg;
	u32 wb_addr;
	u32 reserved3[3];
#else
	u32 send_addr;
	u32 send_size;
	u32 next_addr;
	u32 cfg;
	u32 wb_addr;
#endif
} __aligned(64);

struct rx_desc {
#if defined(CONFIG_HI13X1_GMAC)
	u32 reserved1[3];
	u16 pkt_len;
	u16 reserved_16;
	u32 reserved2[6];
	u32 pkt_err;
	u32 reserved3[5];
#else
	u16 reserved_16;
	u16 pkt_len;
	u32 reserve1[3];
	u32 pkt_err;
	u32 reserve2[4];
#endif
};

struct hip04_priv {
	void __iomem *base;
#if defined(CONFIG_HI13X1_GMAC)
	void __iomem *sysctrl_base;
#endif
	int phy_mode;
	int chan;
	unsigned int port;
	unsigned int group;
	unsigned int speed;
	unsigned int duplex;
	unsigned int reg_inten;
@@ -221,6 +288,13 @@ static void hip04_config_port(struct net_device *ndev, u32 speed, u32 duplex)
	writel_relaxed(val, priv->base + GE_MODE_CHANGE_REG);
}

static void hip04_reset_dreq(struct hip04_priv *priv)
{
#if defined(CONFIG_HI13X1_GMAC)
	writel_relaxed(RESET_DREQ_ALL, priv->sysctrl_base + SC_PPE_RESET_DREQ);
#endif
}

static void hip04_reset_ppe(struct hip04_priv *priv)
{
	u32 val, tmp, timeout = 0;
@@ -241,14 +315,14 @@ static void hip04_config_fifo(struct hip04_priv *priv)
	val |= PPE_CFG_STS_RX_PKT_CNT_RC;
	writel_relaxed(val, priv->base + PPE_CFG_STS_MODE);

	val = BIT(priv->port);
	val = BIT(priv->group);
	regmap_write(priv->map, priv->port * 4 + PPE_CFG_POOL_GRP, val);

	val = priv->port << PPE_CFG_QOS_VMID_GRP_SHIFT;
	val = priv->group << PPE_CFG_QOS_VMID_GRP_SHIFT;
	val |= PPE_CFG_QOS_VMID_MODE;
	writel_relaxed(val, priv->base + PPE_CFG_QOS_VMID_GEN);

	val = RX_BUF_SIZE;
	val = RX_BUF_SIZE >> PPE_BUF_SIZE_SHIFT;
	regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_BUF_SIZE, val);

	val = RX_DESC_NUM << PPE_CFG_RX_DEPTH_SHIFT;
@@ -285,8 +359,10 @@ static void hip04_config_fifo(struct hip04_priv *priv)
	val |= GE_RX_STRIP_PAD | GE_RX_PAD_EN;
	writel_relaxed(val, priv->base + GE_RECV_CONTROL_REG);

#ifndef CONFIG_HI13X1_GMAC
	val = GE_AUTO_NEG_CTL;
	writel_relaxed(val, priv->base + GE_TX_LOCAL_PAGE_REG);
#endif
}

static void hip04_mac_enable(struct net_device *ndev)
@@ -329,12 +405,18 @@ static void hip04_mac_disable(struct net_device *ndev)

static void hip04_set_xmit_desc(struct hip04_priv *priv, dma_addr_t phys)
{
	writel(phys, priv->base + PPE_CFG_CPU_ADD_ADDR);
	u32 val;

	val = phys >> PPE_BUF_SIZE_SHIFT | PPE_TX_BUF_HOLD;
	writel(val, priv->base + PPE_CFG_CPU_ADD_ADDR);
}

static void hip04_set_recv_desc(struct hip04_priv *priv, dma_addr_t phys)
{
	regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, phys);
	u32 val;

	val = phys >> PPE_BUF_SIZE_SHIFT;
	regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, val);
}

static u32 hip04_recv_cnt(struct hip04_priv *priv)
@@ -442,11 +524,20 @@ hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)

	priv->tx_skb[tx_head] = skb;
	priv->tx_phys[tx_head] = phys;
	desc->send_addr = cpu_to_be32(phys);
	desc->send_size = cpu_to_be32(skb->len);
	desc->cfg = cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV);

	desc->send_size = (__force u32)cpu_to_be32(skb->len);
#if defined(CONFIG_HI13X1_GMAC)
	desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV
		| TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT);
	desc->data_offset = (__force u32)cpu_to_be32(phys & CACHE_LINE_MASK);
	desc->send_addr =  (__force u32)cpu_to_be32(phys & ~CACHE_LINE_MASK);
#else
	desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV);
	desc->send_addr = (__force u32)cpu_to_be32(phys);
#endif
	phys = priv->tx_desc_dma + tx_head * sizeof(struct tx_desc);
	desc->wb_addr = cpu_to_be32(phys);
	desc->wb_addr = (__force u32)cpu_to_be32(phys +
		offsetof(struct tx_desc, send_addr));
	skb_tx_timestamp(skb);

	hip04_set_xmit_desc(priv, phys);
@@ -507,8 +598,8 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
		priv->rx_phys[priv->rx_head] = 0;

		desc = (struct rx_desc *)skb->data;
		len = be16_to_cpu(desc->pkt_len);
		err = be32_to_cpu(desc->pkt_err);
		len = be16_to_cpu((__force __be16)desc->pkt_len);
		err = be32_to_cpu((__force __be32)desc->pkt_err);

		if (0 == len) {
			dev_kfree_skb_any(skb);
@@ -828,7 +919,16 @@ static int hip04_mac_probe(struct platform_device *pdev)
		goto init_fail;
	}

	ret = of_parse_phandle_with_fixed_args(node, "port-handle", 2, 0, &arg);
#if defined(CONFIG_HI13X1_GMAC)
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	priv->sysctrl_base = devm_ioremap_resource(d, res);
	if (IS_ERR(priv->sysctrl_base)) {
		ret = PTR_ERR(priv->sysctrl_base);
		goto init_fail;
	}
#endif

	ret = of_parse_phandle_with_fixed_args(node, "port-handle", 3, 0, &arg);
	if (ret < 0) {
		dev_warn(d, "no port-handle\n");
		goto init_fail;
@@ -836,6 +936,7 @@ static int hip04_mac_probe(struct platform_device *pdev)

	priv->port = arg.args[0];
	priv->chan = arg.args[1] * RX_DESC_NUM;
	priv->group = arg.args[2];

	hrtimer_init(&priv->tx_coalesce_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

@@ -896,6 +997,7 @@ static int hip04_mac_probe(struct platform_device *pdev)
	ndev->irq = irq;
	netif_napi_add(ndev, &priv->napi, hip04_rx_poll, NAPI_POLL_WEIGHT);

	hip04_reset_dreq(priv);
	hip04_reset_ppe(priv);
	if (priv->phy_mode == PHY_INTERFACE_MODE_MII)
		hip04_config_port(ndev, SPEED_100, DUPLEX_FULL);