Skip to content

Commit

Permalink
Merge branch 'xgene'
Browse files Browse the repository at this point in the history
Iyappan Subramanian says:

====================
Add 10GbE support to APM X-Gene SoC ethernet driver

Adding 10GbE support to APM X-Gene SoC ethernet driver.

v4: Address comments from v3
* dtb: resolved merge conflict for the net tree

v3: Address comments from v2
* dtb: changed to use all-zeros for the mac address

v2: Address comments from v1
* created preparatory patch to review before adding new functionality
* dtb: updated to use tabs consistently

v1:
* Initial version
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 10, 2014
2 parents 38b3629 + 41aace6 commit 2403077
Show file tree
Hide file tree
Showing 12 changed files with 566 additions and 75 deletions.
4 changes: 3 additions & 1 deletion Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ APM X-Gene SoC Ethernet nodes
Ethernet nodes are defined to describe on-chip ethernet interfaces in
APM X-Gene SoC.

Required properties:
Required properties for all the ethernet interfaces:
- compatible: Should be "apm,xgene-enet"
- reg: Address and length of the register set for the device. It contains the
information of registers in the same order as described by reg-names
Expand All @@ -15,6 +15,8 @@ Required properties:
- clocks: Reference to the clock entry.
- local-mac-address: MAC address assigned to this device
- phy-connection-type: Interface type between ethernet device and PHY device

Required properties for ethernet interfaces that have external PHY:
- phy-handle: Reference to a PHY node connected to this device

- mdio: Device tree subnode with the following required properties:
Expand Down
1 change: 0 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,6 @@ F: net/appletalk/
APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
M: Iyappan Subramanian <isubramanian@apm.com>
M: Keyur Chudgar <kchudgar@apm.com>
M: Ravi Patel <rapatel@apm.com>
S: Supported
F: drivers/net/ethernet/apm/xgene/
F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Expand Down
4 changes: 4 additions & 0 deletions arch/arm64/boot/dts/apm-mustang.dts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@
&menet {
status = "ok";
};

&xgenet {
status = "ok";
};
29 changes: 27 additions & 2 deletions arch/arm64/boot/dts/apm-storm.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@
clock-output-names = "menetclk";
};

xge0clk: xge0clk@1f61c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
clocks = <&socplldiv2 0>;
reg = <0x0 0x1f61c000 0x0 0x1000>;
reg-names = "csr-reg";
csr-mask = <0x3>;
clock-output-names = "xge0clk";
};

sataphy1clk: sataphy1clk@1f21c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
Expand Down Expand Up @@ -420,7 +430,8 @@
interrupts = <0x0 0x3c 0x4>;
dma-coherent;
clocks = <&menetclk 0>;
local-mac-address = [00 01 73 00 00 01];
/* mac address will be overwritten by the bootloader */
local-mac-address = [00 00 00 00 00 00];
phy-connection-type = "rgmii";
phy-handle = <&menetphy>;
mdio {
Expand All @@ -435,12 +446,26 @@
};
};

xgenet: ethernet@1f610000 {
compatible = "apm,xgene-enet";
status = "disabled";
reg = <0x0 0x1f610000 0x0 0xd100>,
<0x0 0x1f600000 0x0 0X400>,
<0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x60 0x4>;
dma-coherent;
clocks = <&xge0clk 0>;
/* mac address will be overwritten by the bootloader */
local-mac-address = [00 00 00 00 00 00];
phy-connection-type = "xgmii";
};

rng: rng@10520000 {
compatible = "apm,xgene-rng";
reg = <0x0 0x10520000 0x0 0x100>;
interrupts = <0x0 0x41 0x4>;
clocks = <&rngpkaclk 0>;
};

};
};
3 changes: 2 additions & 1 deletion drivers/net/ethernet/apm/xgene/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
# Makefile for APM X-Gene Ethernet Driver.
#

xgene-enet-objs := xgene_enet_hw.o xgene_enet_main.o xgene_enet_ethtool.o
xgene-enet-objs := xgene_enet_hw.o xgene_enet_xgmac.o \
xgene_enet_main.o xgene_enet_ethtool.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
28 changes: 22 additions & 6 deletions drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,37 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct phy_device *phydev = pdata->phy_dev;

if (phydev == NULL)
return -ENODEV;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
if (phydev == NULL)
return -ENODEV;

return phy_ethtool_gset(phydev, cmd);
return phy_ethtool_gset(phydev, cmd);
}

cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
cmd->advertising = cmd->supported;
ethtool_cmd_speed_set(cmd, SPEED_10000);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_FIBRE;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = AUTONEG_DISABLE;

return 0;
}

static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct phy_device *phydev = pdata->phy_dev;

if (phydev == NULL)
return -ENODEV;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
if (phydev == NULL)
return -ENODEV;

return phy_ethtool_sset(phydev, cmd);
}

return phy_ethtool_sset(phydev, cmd);
return -EINVAL;
}

static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
Expand Down
44 changes: 30 additions & 14 deletions drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata,
return data;
}

void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
{
u32 addr0, addr1;
u8 *dev_addr = pdata->ndev->dev_addr;
Expand Down Expand Up @@ -436,13 +436,13 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
return 0;
}

void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
{
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
}

void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
{
u32 value, mc2;
u32 intf_ctl, rgmii;
Expand All @@ -456,7 +456,7 @@ void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
xgene_enet_rd_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl);
xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii);

switch (speed) {
switch (pdata->phy_speed) {
case SPEED_10:
ENET_INTERFACE_MODE2_SET(&mc2, 1);
CFG_MACMODE_SET(&icm0, 0);
Expand Down Expand Up @@ -525,8 +525,8 @@ static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, val);
}

void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
u32 dst_ring_num, u16 bufpool_id)
static void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
u32 dst_ring_num, u16 bufpool_id)
{
u32 cb;
u32 fpsel;
Expand All @@ -544,39 +544,39 @@ void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
xgene_enet_wr_csr(pdata, CLE_BYPASS_REG1_0_ADDR, cb);
}

void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
static void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;

xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
}

void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
static void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;

xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
}

void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
static void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;

xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
}

void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;

xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
}

void xgene_enet_reset(struct xgene_enet_pdata *pdata)
static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
{
u32 val;

Expand All @@ -593,7 +593,7 @@ void xgene_enet_reset(struct xgene_enet_pdata *pdata)
xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
}

void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
{
clk_disable_unprepare(pdata->clk);
}
Expand Down Expand Up @@ -627,10 +627,10 @@ static void xgene_enet_adjust_link(struct net_device *ndev)

if (phydev->link) {
if (pdata->phy_speed != phydev->speed) {
xgene_gmac_init(pdata, phydev->speed);
pdata->phy_speed = phydev->speed;
xgene_gmac_init(pdata);
xgene_gmac_rx_enable(pdata);
xgene_gmac_tx_enable(pdata);
pdata->phy_speed = phydev->speed;
phy_print_status(phydev);
}
} else {
Expand Down Expand Up @@ -726,3 +726,19 @@ void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)
mdiobus_free(pdata->mdio_bus);
pdata->mdio_bus = NULL;
}

struct xgene_mac_ops xgene_gmac_ops = {
.init = xgene_gmac_init,
.reset = xgene_gmac_reset,
.rx_enable = xgene_gmac_rx_enable,
.tx_enable = xgene_gmac_tx_enable,
.rx_disable = xgene_gmac_rx_disable,
.tx_disable = xgene_gmac_tx_disable,
.set_mac_addr = xgene_gmac_set_mac_addr,
};

struct xgene_port_ops xgene_gport_ops = {
.reset = xgene_enet_reset,
.cle_bypass = xgene_enet_cle_bypass,
.shutdown = xgene_gport_shutdown,
};
30 changes: 8 additions & 22 deletions drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
return (val & GENMASK(end, start)) >> start;
}

enum xgene_enet_rm {
RM0,
RM3 = 3
};

#define CSR_RING_ID 0x0008
#define OVERWRITE BIT(31)
#define IS_BUFFER_POOL BIT(20)
Expand All @@ -52,7 +57,6 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
#define CSR_RING_WR_BASE 0x0070
#define NUM_RING_CONFIG 5
#define BUFPOOL_MODE 3
#define RM3 3
#define INC_DEC_CMD_ADDR 0x002c
#define UDP_HDR_SIZE 2
#define BUF_LEN_CODE_2K 0x5000
Expand Down Expand Up @@ -94,11 +98,9 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)

#define BLOCK_ETH_CSR_OFFSET 0x2000
#define BLOCK_ETH_RING_IF_OFFSET 0x9000
#define BLOCK_ETH_CLKRST_CSR_OFFSET 0xC000
#define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000

#define BLOCK_ETH_MAC_OFFSET 0x0000
#define BLOCK_ETH_STATS_OFFSET 0x0014
#define BLOCK_ETH_MAC_CSR_OFFSET 0x2800

#define MAC_ADDR_REG_OFFSET 0x00
Expand All @@ -107,12 +109,6 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
#define MAC_READ_REG_OFFSET 0x0c
#define MAC_COMMAND_DONE_REG_OFFSET 0x10

#define STAT_ADDR_REG_OFFSET 0x00
#define STAT_COMMAND_REG_OFFSET 0x04
#define STAT_WRITE_REG_OFFSET 0x08
#define STAT_READ_REG_OFFSET 0x0c
#define STAT_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 Expand Up @@ -318,20 +314,10 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
struct xgene_enet_pdata *pdata,
enum xgene_enet_err_code status);

void xgene_enet_reset(struct xgene_enet_pdata *priv);
void xgene_gmac_reset(struct xgene_enet_pdata *priv);
void xgene_gmac_init(struct xgene_enet_pdata *priv, int speed);
void xgene_gmac_tx_enable(struct xgene_enet_pdata *priv);
void xgene_gmac_rx_enable(struct xgene_enet_pdata *priv);
void xgene_gmac_tx_disable(struct xgene_enet_pdata *priv);
void xgene_gmac_rx_disable(struct xgene_enet_pdata *priv);
void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata);
void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
u32 dst_ring_num, u16 bufpool_id);
void xgene_gport_shutdown(struct xgene_enet_pdata *priv);
void xgene_gmac_get_tx_stats(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);

extern struct xgene_mac_ops xgene_gmac_ops;
extern struct xgene_port_ops xgene_gport_ops;

#endif /* __XGENE_ENET_HW_H__ */
Loading

0 comments on commit 2403077

Please sign in to comment.