Skip to content

Commit

Permalink
Merge branch 'xgene-next'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Aug 13, 2016
2 parents 1c23876 + 5ac6caa commit 2ce66f9
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 40 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/boot/dts/apm/apm-mustang.dts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

&xgenet {
status = "ok";
rxlos-gpios = <&sbgpio 12 1>;
};

&mmc0 {
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/boot/dts/apm/apm-storm.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/apm/xgene/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
17 changes: 12 additions & 5 deletions drivers/net/ethernet/apm/xgene/xgene_enet_cle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/ethernet/apm/xgene/xgene_enet_cle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 9 additions & 9 deletions drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
break;
}

if (!np) {
netdev_dbg(ndev, "No phy-handle found in DT\n");
return -ENODEV;
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;
}

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;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
73 changes: 54 additions & 19 deletions drivers/net/ethernet/apm/xgene/xgene_enet_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)) {
Expand All @@ -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));
Expand All @@ -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);
}
}
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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. */
Expand All @@ -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;

Expand Down Expand Up @@ -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]);
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -1688,11 +1725,9 @@ static int xgene_enet_probe(struct platform_device *pdev)
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();
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/apm/xgene/xgene_enet_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit 2ce66f9

Please sign in to comment.