Merge branch 'xgene-next'
Iyappan Subramanian says: ==================== Fix warning and issues This patch set fixes the following warning and issues, 1. Fix compiler warnings - drivers: net: xgene: Fix compiler warnings 2. unmap DMA memory on xgene_Enet_delete_bufpoool() - drivers: net: xgene: fix: Add dma_unmap_single 3. Delete descriptor rings and buffer pools on error - drivers: net: xgene: fix: Delete descriptor rings and buffer pools 4. Fix error desconstruction on probe() - drivers: net: xgene: Fix error deconstruction path 5. Fix RSS indirection table fields - drivers: net: xgene: Fix RSS indirection table fields 6. Change the port init sequence as per hardware specification - drivers: net: xgene: Change port init sequence 7. Fix link not recovered after link is down issue - drivers: net: xgene: XFI PCS reset when link is down 8. Fix link up is reported when no SFP+ module is plugged in issue - drivers: net: xgene: Poll link status via GPIO - dtb: xgene: Add rxlos-gpios property - Documentation: dtb: xgene: Add rxlos GPIO mapping 9. Fix backward compatibility when used with older driver - drivers: net: xgene: Fix backward compatibility - dtb: xgene: Fix backward compatibility v2: Address review comments from v1 - Fixed compiler warnings - Removed kbuild fix patch, since Arnd submitted the same - Changed Kconfig to select GPIOLIB (to fix kbuild warning) - Added rxlos-gpio documentation - Fixed backward compatibility with older driver v1: - Initial version ==================== Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Tested-by: Fushen Chen <fchen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
2ce66f9c65
|
@ -47,6 +47,9 @@ Optional properties:
|
|||
Valid values are between 0 to 7, that maps to
|
||||
273, 589, 899, 1222, 1480, 1806, 2147, 2464 ps
|
||||
Default value is 2, which corresponds to 899 ps
|
||||
- rxlos-gpios: Input gpio from SFP+ module to indicate availability of
|
||||
incoming signal.
|
||||
|
||||
|
||||
Example:
|
||||
menetclk: menetclk {
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
|
||||
&xgenet {
|
||||
status = "ok";
|
||||
rxlos-gpios = <&sbgpio 12 1>;
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
|
|
|
@ -923,7 +923,7 @@
|
|||
/* mac address will be overwritten by the bootloader */
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
phy-connection-type = "rgmii";
|
||||
phy-handle = <&menet0phy>,<&menetphy>;
|
||||
phy-handle = <&menetphy>,<&menet0phy>;
|
||||
mdio {
|
||||
compatible = "apm,xgene-mdio";
|
||||
#address-cells = <1>;
|
||||
|
|
|
@ -4,6 +4,7 @@ config NET_XGENE
|
|||
depends on ARCH_XGENE || COMPILE_TEST
|
||||
select PHYLIB
|
||||
select MDIO_XGENE
|
||||
select GPIOLIB
|
||||
help
|
||||
This is the Ethernet driver for the on-chip ethernet interface on the
|
||||
APM X-Gene SoC.
|
||||
|
|
|
@ -32,12 +32,19 @@ static void xgene_cle_sband_to_hw(u8 frag, enum xgene_cle_prot_version ver,
|
|||
SET_VAL(SB_HDRLEN, len);
|
||||
}
|
||||
|
||||
static void xgene_cle_idt_to_hw(u32 dstqid, u32 fpsel,
|
||||
static void xgene_cle_idt_to_hw(struct xgene_enet_pdata *pdata,
|
||||
u32 dstqid, u32 fpsel,
|
||||
u32 nfpsel, u32 *idt_reg)
|
||||
{
|
||||
*idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
|
||||
SET_VAL(IDT_FPSEL, fpsel) |
|
||||
SET_VAL(IDT_NFPSEL, nfpsel);
|
||||
if (pdata->enet_id == XGENE_ENET1) {
|
||||
*idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
|
||||
SET_VAL(IDT_FPSEL1, fpsel) |
|
||||
SET_VAL(IDT_NFPSEL1, nfpsel);
|
||||
} else {
|
||||
*idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
|
||||
SET_VAL(IDT_FPSEL, fpsel) |
|
||||
SET_VAL(IDT_NFPSEL, nfpsel);
|
||||
}
|
||||
}
|
||||
|
||||
static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
|
||||
|
@ -344,7 +351,7 @@ static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata)
|
|||
nfpsel = 0;
|
||||
idt_reg = 0;
|
||||
|
||||
xgene_cle_idt_to_hw(dstqid, fpsel, nfpsel, &idt_reg);
|
||||
xgene_cle_idt_to_hw(pdata, dstqid, fpsel, nfpsel, &idt_reg);
|
||||
ret = xgene_cle_dram_wr(&pdata->cle, &idt_reg, 1, i,
|
||||
RSS_IDT, CLE_CMD_WR);
|
||||
if (ret)
|
||||
|
|
|
@ -196,9 +196,13 @@ enum xgene_cle_ptree_dbptrs {
|
|||
#define IDT_DSTQID_POS 0
|
||||
#define IDT_DSTQID_LEN 12
|
||||
#define IDT_FPSEL_POS 12
|
||||
#define IDT_FPSEL_LEN 4
|
||||
#define IDT_NFPSEL_POS 16
|
||||
#define IDT_NFPSEL_LEN 4
|
||||
#define IDT_FPSEL_LEN 5
|
||||
#define IDT_NFPSEL_POS 17
|
||||
#define IDT_NFPSEL_LEN 5
|
||||
#define IDT_FPSEL1_POS 12
|
||||
#define IDT_FPSEL1_LEN 4
|
||||
#define IDT_NFPSEL1_POS 16
|
||||
#define IDT_NFPSEL1_LEN 4
|
||||
|
||||
struct xgene_cle_ptree_branch {
|
||||
bool valid;
|
||||
|
|
|
@ -761,18 +761,18 @@ int xgene_enet_phy_connect(struct net_device *ndev)
|
|||
if (dev->of_node) {
|
||||
for (i = 0 ; i < 2; i++) {
|
||||
np = of_parse_phandle(dev->of_node, "phy-handle", i);
|
||||
if (np)
|
||||
|
||||
if (!np)
|
||||
continue;
|
||||
|
||||
phy_dev = of_phy_connect(ndev, np,
|
||||
&xgene_enet_adjust_link,
|
||||
0, pdata->phy_mode);
|
||||
of_node_put(np);
|
||||
if (phy_dev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!np) {
|
||||
netdev_dbg(ndev, "No phy-handle found in DT\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_dev = of_phy_connect(ndev, np, &xgene_enet_adjust_link,
|
||||
0, pdata->phy_mode);
|
||||
of_node_put(np);
|
||||
if (!phy_dev) {
|
||||
netdev_err(ndev, "Could not connect to PHY\n");
|
||||
return -ENODEV;
|
||||
|
|
|
@ -124,6 +124,12 @@ enum xgene_enet_rm {
|
|||
#define MAC_READ_REG_OFFSET 0x0c
|
||||
#define MAC_COMMAND_DONE_REG_OFFSET 0x10
|
||||
|
||||
#define PCS_ADDR_REG_OFFSET 0x00
|
||||
#define PCS_COMMAND_REG_OFFSET 0x04
|
||||
#define PCS_WRITE_REG_OFFSET 0x08
|
||||
#define PCS_READ_REG_OFFSET 0x0c
|
||||
#define PCS_COMMAND_DONE_REG_OFFSET 0x10
|
||||
|
||||
#define MII_MGMT_CONFIG_ADDR 0x20
|
||||
#define MII_MGMT_COMMAND_ADDR 0x24
|
||||
#define MII_MGMT_ADDRESS_ADDR 0x28
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include "xgene_enet_main.h"
|
||||
#include "xgene_enet_hw.h"
|
||||
#include "xgene_enet_sgmac.h"
|
||||
|
@ -72,7 +73,6 @@ static int xgene_enet_refill_bufpool(struct xgene_enet_desc_ring *buf_pool,
|
|||
skb = netdev_alloc_skb_ip_align(ndev, len);
|
||||
if (unlikely(!skb))
|
||||
return -ENOMEM;
|
||||
buf_pool->rx_skb[tail] = skb;
|
||||
|
||||
dma_addr = dma_map_single(dev, skb->data, len, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dev, dma_addr)) {
|
||||
|
@ -81,6 +81,8 @@ static int xgene_enet_refill_bufpool(struct xgene_enet_desc_ring *buf_pool,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf_pool->rx_skb[tail] = skb;
|
||||
|
||||
raw_desc->m1 = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
|
||||
SET_VAL(BUFDATALEN, bufdatalen) |
|
||||
SET_BIT(COHERENT));
|
||||
|
@ -102,12 +104,21 @@ static u8 xgene_enet_hdr_len(const void *data)
|
|||
|
||||
static void xgene_enet_delete_bufpool(struct xgene_enet_desc_ring *buf_pool)
|
||||
{
|
||||
struct device *dev = ndev_to_dev(buf_pool->ndev);
|
||||
struct xgene_enet_raw_desc16 *raw_desc;
|
||||
dma_addr_t dma_addr;
|
||||
int i;
|
||||
|
||||
/* Free up the buffers held by hardware */
|
||||
for (i = 0; i < buf_pool->slots; i++) {
|
||||
if (buf_pool->rx_skb[i])
|
||||
if (buf_pool->rx_skb[i]) {
|
||||
dev_kfree_skb_any(buf_pool->rx_skb[i]);
|
||||
|
||||
raw_desc = &buf_pool->raw_desc16[i];
|
||||
dma_addr = GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1));
|
||||
dma_unmap_single(dev, dma_addr, XGENE_ENET_MAX_MTU,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +463,6 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
|||
struct xgene_enet_raw_desc *raw_desc)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
struct xgene_enet_pdata *pdata;
|
||||
struct device *dev;
|
||||
struct xgene_enet_desc_ring *buf_pool;
|
||||
u32 datalen, skb_index;
|
||||
|
@ -461,7 +471,6 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
|
|||
int ret = 0;
|
||||
|
||||
ndev = rx_ring->ndev;
|
||||
pdata = netdev_priv(ndev);
|
||||
dev = ndev_to_dev(rx_ring->ndev);
|
||||
buf_pool = rx_ring->buf_pool;
|
||||
|
||||
|
@ -1312,6 +1321,18 @@ static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void xgene_enet_gpiod_get(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct device *dev = &pdata->pdev->dev;
|
||||
|
||||
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
|
||||
return;
|
||||
|
||||
pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
|
||||
if (IS_ERR(pdata->sfp_rdy))
|
||||
pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);
|
||||
}
|
||||
|
||||
static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
@ -1401,6 +1422,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
xgene_enet_gpiod_get(pdata);
|
||||
|
||||
pdata->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(pdata->clk)) {
|
||||
/* Firmware may have set up the clock already. */
|
||||
|
@ -1425,6 +1448,7 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
|
|||
} else {
|
||||
pdata->mcx_mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET;
|
||||
pdata->mcx_mac_csr_addr = base_addr + BLOCK_AXG_MAC_CSR_OFFSET;
|
||||
pdata->pcs_addr = base_addr + BLOCK_PCS_OFFSET;
|
||||
}
|
||||
pdata->rx_buff_cnt = NUM_PKT_BUF;
|
||||
|
||||
|
@ -1454,10 +1478,8 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
|
|||
buf_pool = pdata->rx_ring[i]->buf_pool;
|
||||
xgene_enet_init_bufpool(buf_pool);
|
||||
ret = xgene_enet_refill_bufpool(buf_pool, pdata->rx_buff_cnt);
|
||||
if (ret) {
|
||||
xgene_enet_delete_desc_rings(pdata);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
|
||||
|
@ -1474,7 +1496,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
|
|||
ret = pdata->cle_ops->cle_init(pdata);
|
||||
if (ret) {
|
||||
netdev_err(ndev, "Preclass Tree init error\n");
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
|
||||
|
@ -1484,6 +1506,10 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
|
|||
pdata->mac_ops->init(pdata);
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
xgene_enet_delete_desc_rings(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
|
||||
|
@ -1631,8 +1657,8 @@ static int xgene_enet_probe(struct platform_device *pdev)
|
|||
}
|
||||
#endif
|
||||
if (!pdata->enet_id) {
|
||||
free_netdev(ndev);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = xgene_enet_get_resources(pdata);
|
||||
|
@ -1655,7 +1681,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
|
|||
|
||||
ret = xgene_enet_init_hw(pdata);
|
||||
if (ret)
|
||||
goto err_netdev;
|
||||
goto err;
|
||||
|
||||
link_state = pdata->mac_ops->link_state;
|
||||
if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
|
||||
|
@ -1665,21 +1691,32 @@ static int xgene_enet_probe(struct platform_device *pdev)
|
|||
ret = xgene_enet_mdio_config(pdata);
|
||||
else
|
||||
INIT_DELAYED_WORK(&pdata->link_work, link_state);
|
||||
|
||||
if (ret)
|
||||
goto err1;
|
||||
}
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
xgene_enet_napi_add(pdata);
|
||||
ret = register_netdev(ndev);
|
||||
if (ret) {
|
||||
netdev_err(ndev, "Failed to register netdev\n");
|
||||
goto err;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_netdev:
|
||||
unregister_netdev(ndev);
|
||||
err2:
|
||||
/*
|
||||
* If necessary, free_netdev() will call netif_napi_del() and undo
|
||||
* the effects of xgene_enet_napi_add()'s calls to netif_napi_add().
|
||||
*/
|
||||
|
||||
if (pdata->mdio_driver)
|
||||
xgene_enet_phy_disconnect(pdata);
|
||||
else if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
|
||||
xgene_enet_mdio_remove(pdata);
|
||||
err1:
|
||||
xgene_enet_delete_desc_rings(pdata);
|
||||
err:
|
||||
free_netdev(ndev);
|
||||
return ret;
|
||||
|
@ -1688,11 +1725,9 @@ err:
|
|||
static int xgene_enet_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct xgene_enet_pdata *pdata;
|
||||
const struct xgene_mac_ops *mac_ops;
|
||||
struct net_device *ndev;
|
||||
|
||||
pdata = platform_get_drvdata(pdev);
|
||||
mac_ops = pdata->mac_ops;
|
||||
ndev = pdata->ndev;
|
||||
|
||||
rtnl_lock();
|
||||
|
|
|
@ -196,6 +196,7 @@ struct xgene_enet_pdata {
|
|||
void __iomem *mcx_mac_addr;
|
||||
void __iomem *mcx_mac_csr_addr;
|
||||
void __iomem *base_addr;
|
||||
void __iomem *pcs_addr;
|
||||
void __iomem *ring_csr_addr;
|
||||
void __iomem *ring_cmd_addr;
|
||||
int phy_mode;
|
||||
|
@ -216,6 +217,7 @@ struct xgene_enet_pdata {
|
|||
u8 tx_delay;
|
||||
u8 rx_delay;
|
||||
bool mdio_driver;
|
||||
struct gpio_desc *sfp_rdy;
|
||||
};
|
||||
|
||||
struct xgene_indirect_ctl {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
#include "xgene_enet_main.h"
|
||||
#include "xgene_enet_hw.h"
|
||||
#include "xgene_enet_xgmac.h"
|
||||
|
@ -84,6 +86,21 @@ static void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata,
|
|||
wr_addr);
|
||||
}
|
||||
|
||||
static void xgene_enet_wr_pcs(struct xgene_enet_pdata *pdata,
|
||||
u32 wr_addr, u32 wr_data)
|
||||
{
|
||||
void __iomem *addr, *wr, *cmd, *cmd_done;
|
||||
|
||||
addr = pdata->pcs_addr + PCS_ADDR_REG_OFFSET;
|
||||
wr = pdata->pcs_addr + PCS_WRITE_REG_OFFSET;
|
||||
cmd = pdata->pcs_addr + PCS_COMMAND_REG_OFFSET;
|
||||
cmd_done = pdata->pcs_addr + PCS_COMMAND_DONE_REG_OFFSET;
|
||||
|
||||
if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
|
||||
netdev_err(pdata->ndev, "PCS write failed, addr: %04x\n",
|
||||
wr_addr);
|
||||
}
|
||||
|
||||
static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
|
||||
u32 offset, u32 *val)
|
||||
{
|
||||
|
@ -122,6 +139,7 @@ static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
|
||||
u32 rd_addr, u32 *rd_data)
|
||||
{
|
||||
|
@ -137,6 +155,21 @@ static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
|
|||
rd_addr);
|
||||
}
|
||||
|
||||
static void xgene_enet_rd_pcs(struct xgene_enet_pdata *pdata,
|
||||
u32 rd_addr, u32 *rd_data)
|
||||
{
|
||||
void __iomem *addr, *rd, *cmd, *cmd_done;
|
||||
|
||||
addr = pdata->pcs_addr + PCS_ADDR_REG_OFFSET;
|
||||
rd = pdata->pcs_addr + PCS_READ_REG_OFFSET;
|
||||
cmd = pdata->pcs_addr + PCS_COMMAND_REG_OFFSET;
|
||||
cmd_done = pdata->pcs_addr + PCS_COMMAND_DONE_REG_OFFSET;
|
||||
|
||||
if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
|
||||
netdev_err(pdata->ndev, "PCS read failed, addr: %04x\n",
|
||||
rd_addr);
|
||||
}
|
||||
|
||||
static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct net_device *ndev = pdata->ndev;
|
||||
|
@ -171,6 +204,15 @@ static void xgene_xgmac_reset(struct xgene_enet_pdata *pdata)
|
|||
xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, 0);
|
||||
}
|
||||
|
||||
static void xgene_pcs_reset(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
xgene_enet_rd_pcs(pdata, PCS_CONTROL_1, &data);
|
||||
xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data | PCS_CTRL_PCS_RST);
|
||||
xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data & ~PCS_CTRL_PCS_RST);
|
||||
}
|
||||
|
||||
static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
u32 addr0, addr1;
|
||||
|
@ -216,12 +258,12 @@ static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
|
|||
data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
|
||||
xgene_enet_wr_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, data);
|
||||
|
||||
xgene_enet_wr_csr(pdata, XG_CFG_BYPASS_ADDR, RESUME_TX);
|
||||
xgene_enet_wr_csr(pdata, XGENET_RX_DV_GATE_REG_0_ADDR, 0);
|
||||
xgene_enet_rd_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, &data);
|
||||
data |= BIT(12);
|
||||
xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, data);
|
||||
xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x82);
|
||||
xgene_enet_wr_csr(pdata, XGENET_RX_DV_GATE_REG_0_ADDR, 0);
|
||||
xgene_enet_wr_csr(pdata, XG_CFG_BYPASS_ADDR, RESUME_TX);
|
||||
}
|
||||
|
||||
static void xgene_xgmac_rx_enable(struct xgene_enet_pdata *pdata)
|
||||
|
@ -359,14 +401,17 @@ static void xgene_enet_link_state(struct work_struct *work)
|
|||
{
|
||||
struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
|
||||
struct xgene_enet_pdata, link_work);
|
||||
struct gpio_desc *sfp_rdy = pdata->sfp_rdy;
|
||||
struct net_device *ndev = pdata->ndev;
|
||||
u32 link_status, poll_interval;
|
||||
|
||||
link_status = xgene_enet_link_status(pdata);
|
||||
if (link_status && !IS_ERR(sfp_rdy) && !gpiod_get_value(sfp_rdy))
|
||||
link_status = 0;
|
||||
|
||||
if (link_status) {
|
||||
if (!netif_carrier_ok(ndev)) {
|
||||
netif_carrier_on(ndev);
|
||||
xgene_xgmac_init(pdata);
|
||||
xgene_xgmac_rx_enable(pdata);
|
||||
xgene_xgmac_tx_enable(pdata);
|
||||
netdev_info(ndev, "Link is Up - 10Gbps\n");
|
||||
|
@ -380,6 +425,8 @@ static void xgene_enet_link_state(struct work_struct *work)
|
|||
netdev_info(ndev, "Link is Down\n");
|
||||
}
|
||||
poll_interval = PHY_POLL_LINK_OFF;
|
||||
|
||||
xgene_pcs_reset(pdata);
|
||||
}
|
||||
|
||||
schedule_delayed_work(&pdata->link_work, poll_interval);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define X2_BLOCK_ETH_MAC_CSR_OFFSET 0x3000
|
||||
#define BLOCK_AXG_MAC_OFFSET 0x0800
|
||||
#define BLOCK_AXG_MAC_CSR_OFFSET 0x2000
|
||||
#define BLOCK_PCS_OFFSET 0x3800
|
||||
|
||||
#define XGENET_CONFIG_REG_ADDR 0x20
|
||||
#define XGENET_SRST_ADDR 0x00
|
||||
|
@ -72,6 +73,9 @@
|
|||
#define XG_MCX_ICM_CONFIG0_REG_0_ADDR 0x00e0
|
||||
#define XG_MCX_ICM_CONFIG2_REG_0_ADDR 0x00e8
|
||||
|
||||
#define PCS_CONTROL_1 0x0000
|
||||
#define PCS_CTRL_PCS_RST BIT(15)
|
||||
|
||||
extern const struct xgene_mac_ops xgene_xgmac_ops;
|
||||
extern const struct xgene_port_ops xgene_xgport_ops;
|
||||
|
||||
|
|
Loading…
Reference in New Issue