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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
2bb295f3a5
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue