Commit 15e4123b authored by David S. Miller's avatar David S. Miller

Merge branch 'xgene-net'

Iyappan Subramanian says:

====================
drivers: net: xgene: Fix crash for backward compatibility

This patch set fixes the following issues that were reported during regression.

Patch 1,2 : Adds backward compatibility with the older firmware (<= 1.13.28).
Patch 3   : Use separate hardware resources (descriptor ring, prefetch buffer)
	   that are not shared with the firmware
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9fd3d3a4 bdd330f0
...@@ -599,7 +599,7 @@ menet: ethernet@17020000 { ...@@ -599,7 +599,7 @@ menet: ethernet@17020000 {
compatible = "apm,xgene-enet"; compatible = "apm,xgene-enet";
status = "disabled"; status = "disabled";
reg = <0x0 0x17020000 0x0 0xd100>, reg = <0x0 0x17020000 0x0 0xd100>,
<0x0 0X17030000 0x0 0X400>, <0x0 0X17030000 0x0 0Xc300>,
<0x0 0X10000000 0x0 0X200>; <0x0 0X10000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd"; reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x3c 0x4>; interrupts = <0x0 0x3c 0x4>;
...@@ -624,9 +624,9 @@ menetphy: menetphy@3 { ...@@ -624,9 +624,9 @@ menetphy: menetphy@3 {
sgenet0: ethernet@1f210000 { sgenet0: ethernet@1f210000 {
compatible = "apm,xgene-enet"; compatible = "apm,xgene-enet";
status = "disabled"; status = "disabled";
reg = <0x0 0x1f210000 0x0 0x10000>, reg = <0x0 0x1f210000 0x0 0xd100>,
<0x0 0x1f200000 0x0 0X10000>, <0x0 0x1f200000 0x0 0Xc300>,
<0x0 0x1B000000 0x0 0X20000>; <0x0 0x1B000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd"; reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0xA0 0x4>; interrupts = <0x0 0xA0 0x4>;
dma-coherent; dma-coherent;
...@@ -639,7 +639,7 @@ xgenet: ethernet@1f610000 { ...@@ -639,7 +639,7 @@ xgenet: ethernet@1f610000 {
compatible = "apm,xgene-enet"; compatible = "apm,xgene-enet";
status = "disabled"; status = "disabled";
reg = <0x0 0x1f610000 0x0 0xd100>, reg = <0x0 0x1f610000 0x0 0xd100>,
<0x0 0x1f600000 0x0 0X400>, <0x0 0x1f600000 0x0 0Xc300>,
<0x0 0x18000000 0x0 0X200>; <0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd"; reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x60 0x4>; interrupts = <0x0 0x60 0x4>;
......
...@@ -575,10 +575,24 @@ static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata) ...@@ -575,10 +575,24 @@ static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN); xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
} }
static void xgene_enet_reset(struct xgene_enet_pdata *pdata) bool xgene_ring_mgr_init(struct xgene_enet_pdata *p)
{
if (!ioread32(p->ring_csr_addr + CLKEN_ADDR))
return false;
if (ioread32(p->ring_csr_addr + SRST_ADDR))
return false;
return true;
}
static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
{ {
u32 val; u32 val;
if (!xgene_ring_mgr_init(pdata))
return -ENODEV;
clk_prepare_enable(pdata->clk); clk_prepare_enable(pdata->clk);
clk_disable_unprepare(pdata->clk); clk_disable_unprepare(pdata->clk);
clk_prepare_enable(pdata->clk); clk_prepare_enable(pdata->clk);
...@@ -590,6 +604,8 @@ static void xgene_enet_reset(struct xgene_enet_pdata *pdata) ...@@ -590,6 +604,8 @@ static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
val |= SCAN_AUTO_INCR; val |= SCAN_AUTO_INCR;
MGMT_CLOCK_SEL_SET(&val, 1); MGMT_CLOCK_SEL_SET(&val, 1);
xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val); xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
return 0;
} }
static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata) static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
......
...@@ -104,6 +104,9 @@ enum xgene_enet_rm { ...@@ -104,6 +104,9 @@ enum xgene_enet_rm {
#define BLOCK_ETH_MAC_OFFSET 0x0000 #define BLOCK_ETH_MAC_OFFSET 0x0000
#define BLOCK_ETH_MAC_CSR_OFFSET 0x2800 #define BLOCK_ETH_MAC_CSR_OFFSET 0x2800
#define CLKEN_ADDR 0xc208
#define SRST_ADDR 0xc200
#define MAC_ADDR_REG_OFFSET 0x00 #define MAC_ADDR_REG_OFFSET 0x00
#define MAC_COMMAND_REG_OFFSET 0x04 #define MAC_COMMAND_REG_OFFSET 0x04
#define MAC_WRITE_REG_OFFSET 0x08 #define MAC_WRITE_REG_OFFSET 0x08
...@@ -318,6 +321,7 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring, ...@@ -318,6 +321,7 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata); int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata);
void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata); void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata);
bool xgene_ring_mgr_init(struct xgene_enet_pdata *p);
extern struct xgene_mac_ops xgene_gmac_ops; extern struct xgene_mac_ops xgene_gmac_ops;
extern struct xgene_port_ops xgene_gport_ops; extern struct xgene_port_ops xgene_gport_ops;
......
...@@ -639,9 +639,9 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev) ...@@ -639,9 +639,9 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
struct device *dev = ndev_to_dev(ndev); struct device *dev = ndev_to_dev(ndev);
struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring; struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring;
struct xgene_enet_desc_ring *buf_pool = NULL; struct xgene_enet_desc_ring *buf_pool = NULL;
u8 cpu_bufnum = 0, eth_bufnum = 0; u8 cpu_bufnum = 0, eth_bufnum = START_ETH_BUFNUM;
u8 bp_bufnum = 0x20; u8 bp_bufnum = START_BP_BUFNUM;
u16 ring_id, ring_num = 0; u16 ring_id, ring_num = START_RING_NUM;
int ret; int ret;
/* allocate rx descriptor ring */ /* allocate rx descriptor ring */
...@@ -852,7 +852,9 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata) ...@@ -852,7 +852,9 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
u16 dst_ring_num; u16 dst_ring_num;
int ret; int ret;
pdata->port_ops->reset(pdata); ret = pdata->port_ops->reset(pdata);
if (ret)
return ret;
ret = xgene_enet_create_desc_rings(ndev); ret = xgene_enet_create_desc_rings(ndev);
if (ret) { if (ret) {
...@@ -954,6 +956,7 @@ static int xgene_enet_probe(struct platform_device *pdev) ...@@ -954,6 +956,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
return ret; return ret;
err: err:
unregister_netdev(ndev);
free_netdev(ndev); free_netdev(ndev);
return ret; return ret;
} }
......
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
#define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN) #define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
#define NUM_PKT_BUF 64 #define NUM_PKT_BUF 64
#define NUM_BUFPOOL 32 #define NUM_BUFPOOL 32
#define START_ETH_BUFNUM 2
#define START_BP_BUFNUM 0x22
#define START_RING_NUM 8
#define PHY_POLL_LINK_ON (10 * HZ) #define PHY_POLL_LINK_ON (10 * HZ)
#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5) #define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
...@@ -83,7 +86,7 @@ struct xgene_mac_ops { ...@@ -83,7 +86,7 @@ struct xgene_mac_ops {
}; };
struct xgene_port_ops { struct xgene_port_ops {
void (*reset)(struct xgene_enet_pdata *pdata); int (*reset)(struct xgene_enet_pdata *pdata);
void (*cle_bypass)(struct xgene_enet_pdata *pdata, void (*cle_bypass)(struct xgene_enet_pdata *pdata,
u32 dst_ring_num, u16 bufpool_id); u32 dst_ring_num, u16 bufpool_id);
void (*shutdown)(struct xgene_enet_pdata *pdata); void (*shutdown)(struct xgene_enet_pdata *pdata);
......
...@@ -311,14 +311,19 @@ static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *p) ...@@ -311,14 +311,19 @@ static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *p)
xgene_sgmac_rxtx(p, TX_EN, false); xgene_sgmac_rxtx(p, TX_EN, false);
} }
static void xgene_enet_reset(struct xgene_enet_pdata *p) static int xgene_enet_reset(struct xgene_enet_pdata *p)
{ {
if (!xgene_ring_mgr_init(p))
return -ENODEV;
clk_prepare_enable(p->clk); clk_prepare_enable(p->clk);
clk_disable_unprepare(p->clk); clk_disable_unprepare(p->clk);
clk_prepare_enable(p->clk); clk_prepare_enable(p->clk);
xgene_enet_ecc_init(p); xgene_enet_ecc_init(p);
xgene_enet_config_ring_if_assoc(p); xgene_enet_config_ring_if_assoc(p);
return 0;
} }
static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p, static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p,
......
...@@ -252,14 +252,19 @@ static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata) ...@@ -252,14 +252,19 @@ static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata)
xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTTFEN); xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTTFEN);
} }
static void xgene_enet_reset(struct xgene_enet_pdata *pdata) static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
{ {
if (!xgene_ring_mgr_init(pdata))
return -ENODEV;
clk_prepare_enable(pdata->clk); clk_prepare_enable(pdata->clk);
clk_disable_unprepare(pdata->clk); clk_disable_unprepare(pdata->clk);
clk_prepare_enable(pdata->clk); clk_prepare_enable(pdata->clk);
xgene_enet_ecc_init(pdata); xgene_enet_ecc_init(pdata);
xgene_enet_config_ring_if_assoc(pdata); xgene_enet_config_ring_if_assoc(pdata);
return 0;
} }
static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata, static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment