Commit 217e606b authored by David S. Miller's avatar David S. Miller

Merge branch 'apm_xgene'

Iyappan Subramanian says:

====================
net: Add APM X-Gene SoC Ethernet driver support

Adding APM X-Gene SoC Ethernet driver.

v10: Address comments from v9 review
* Documentation: aligned descriptions
* simplified struct platform_driver initialization
* fixed xgene_enet_mdio_config error path
* fixed xgene_enet_init_hw error path
* removed statistics spin_lock as it is not required
* changed raw_desc fields to type __le64
* defined helper macros for set/get raw_descriptor fields

v9: Address comments from v8 review
* changed to direct read/write, byteswap into raw descriptor
* fixed xgene_enet_create_desc_ring() error handling
* removed references to IS_ERR_OR_NULL
* disabled half duplex on phy_devce supported/advertising
* simplified xgene_enet_adjust_link() function
* fixed sparse tool compilation warnings

v8: Address comments from v7 review
* changed angle bracket to double quotes in header file include.

v7: Address comments from v6 review
* fixed skb memory leak when dma_map_single fails in xmit.

v6: Address comments from v5 review
* added basic ethtool support
* added ndo_get_stats64 call back
* deleted priting Rx error messages
* renamed set_bits to xgene_set_bits to fix kbuild error (make ARCH=powerpc)

v5: Address comments from v4 review
* Documentation: Added phy-handle, reg-names and changed mdio part
* dtb: Added reg-names supplemental property
* changed platform_get_resource to platform_get_resource_byname
* added separate tx/rx set_desc/get_desc functions to do raw_write/raw_read
* removed set_desc/get_desc table lookup logic
* added error handling logic based on per packet descriptor bits
* added software managed Rx packet and error counters
* added busy wait for register read/writes
* changed mdio_bus->id to avoid conflict
* fixed mdio_bus leak in case of mdio_config error
* changed phy reg hard coded value to MII_BMSR
* changed phy addr hard coded value to phy_device->addr
* added paranthesis around macro arguments
* converted helper macros to inline functions
* changed use of goto's only to common work such as cleanup

v4: Address comments from v3 review
* MAINTAINERS: changed status to supported
* Kconfig: made default to no
* changed to bool data type wherever applicable
* cleaned up single bit set and masking code
* removed statistics counters masking
* removed unnecessary OOM message printing
* fixed dma_map_single and dma_unmap_single size parameter
* changed set bits macro body using new set_bits function

v3: Address comments from v2 review
* cleaned up set_desc and get_desc functions
* added dtb mdio node and phy-handle subnode
* renamed dtb phy-mode to phy-connection-type
* added of_phy_connect call to connec to PHY
* added empty line after last local variable declaration
* removed type casting when not required
* removed inline keyword from source files
* removed CONFIG_CPU_BIG_ENDIAN ifdef

v2
* Completely redesigned ethernet driver
* Added support to work with big endian kernel
* Renamed dtb phyid entry to phy_addr
* Changed dtb local-mac-address entry to byte string format
* Renamed dtb eth8clk entry to menetclk

v1
* Initial version
====================
Signed-off-by: default avatarIyappan Subramanian <isubramanian@apm.com>
Signed-off-by: default avatarRavi Patel <rapatel@apm.com>
Signed-off-by: default avatarKeyur Chudgar <kchudgar@apm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f00439e2 e6ad7673
APM X-Gene SoC Ethernet nodes
Ethernet nodes are defined to describe on-chip ethernet interfaces in
APM X-Gene SoC.
Required properties:
- 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
- reg-names: Should contain the register set names
- "enet_csr": Ethernet control and status register address space
- "ring_csr": Descriptor ring control and status register address space
- "ring_cmd": Descriptor ring command register address space
- interrupts: Ethernet main interrupt
- 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
- phy-handle: Reference to a PHY node connected to this device
- mdio: Device tree subnode with the following required properties:
- compatible: Must be "apm,xgene-mdio".
- #address-cells: Must be <1>.
- #size-cells: Must be <0>.
For the phy on the mdio bus, there must be a node with the following fields:
- compatible: PHY identifier. Please refer ./phy.txt for the format.
- reg: The ID number for the phy.
Optional properties:
- status: Should be "ok" or "disabled" for enabled/disabled. Default is "ok".
Example:
menetclk: menetclk {
compatible = "apm,xgene-device-clock";
clock-output-names = "menetclk";
status = "ok";
};
menet: ethernet@17020000 {
compatible = "apm,xgene-enet";
status = "disabled";
reg = <0x0 0x17020000 0x0 0xd100>,
<0x0 0X17030000 0x0 0X400>,
<0x0 0X10000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x3c 0x4>;
clocks = <&menetclk 0>;
local-mac-address = [00 01 73 00 00 01];
phy-connection-type = "rgmii";
phy-handle = <&menetphy>;
mdio {
compatible = "apm,xgene-mdio";
#address-cells = <1>;
#size-cells = <0>;
menetphy: menetphy@3 {
compatible = "ethernet-phy-id001c.c915";
reg = <0x3>;
};
};
};
/* Board-specific peripheral configurations */
&menet {
status = "ok";
};
...@@ -719,6 +719,14 @@ S: Maintained ...@@ -719,6 +719,14 @@ S: Maintained
F: drivers/net/appletalk/ F: drivers/net/appletalk/
F: net/appletalk/ 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
APTINA CAMERA SENSOR PLL APTINA CAMERA SENSOR PLL
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com> M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
......
...@@ -28,3 +28,7 @@ memory { ...@@ -28,3 +28,7 @@ memory {
&serial0 { &serial0 {
status = "ok"; status = "ok";
}; };
&menet {
status = "ok";
};
...@@ -167,14 +167,13 @@ ethclk: ethclk { ...@@ -167,14 +167,13 @@ ethclk: ethclk {
clock-output-names = "ethclk"; clock-output-names = "ethclk";
}; };
eth8clk: eth8clk { menetclk: menetclk {
compatible = "apm,xgene-device-clock"; compatible = "apm,xgene-device-clock";
#clock-cells = <1>; #clock-cells = <1>;
clocks = <&ethclk 0>; clocks = <&ethclk 0>;
clock-names = "eth8clk";
reg = <0x0 0x1702C000 0x0 0x1000>; reg = <0x0 0x1702C000 0x0 0x1000>;
reg-names = "csr-reg"; reg-names = "csr-reg";
clock-output-names = "eth8clk"; clock-output-names = "menetclk";
}; };
sataphy1clk: sataphy1clk@1f21c000 { sataphy1clk: sataphy1clk@1f21c000 {
...@@ -397,5 +396,30 @@ rtc: rtc@10510000 { ...@@ -397,5 +396,30 @@ rtc: rtc@10510000 {
#clock-cells = <1>; #clock-cells = <1>;
clocks = <&rtcclk 0>; clocks = <&rtcclk 0>;
}; };
menet: ethernet@17020000 {
compatible = "apm,xgene-enet";
status = "disabled";
reg = <0x0 0x17020000 0x0 0xd100>,
<0x0 0X17030000 0x0 0X400>,
<0x0 0X10000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x3c 0x4>;
dma-coherent;
clocks = <&menetclk 0>;
local-mac-address = [00 01 73 00 00 01];
phy-connection-type = "rgmii";
phy-handle = <&menetphy>;
mdio {
compatible = "apm,xgene-mdio";
#address-cells = <1>;
#size-cells = <0>;
menetphy: menetphy@3 {
compatible = "ethernet-phy-id001c.c915";
reg = <0x3>;
};
};
};
}; };
}; };
...@@ -24,6 +24,7 @@ source "drivers/net/ethernet/allwinner/Kconfig" ...@@ -24,6 +24,7 @@ source "drivers/net/ethernet/allwinner/Kconfig"
source "drivers/net/ethernet/alteon/Kconfig" source "drivers/net/ethernet/alteon/Kconfig"
source "drivers/net/ethernet/altera/Kconfig" source "drivers/net/ethernet/altera/Kconfig"
source "drivers/net/ethernet/amd/Kconfig" source "drivers/net/ethernet/amd/Kconfig"
source "drivers/net/ethernet/apm/Kconfig"
source "drivers/net/ethernet/apple/Kconfig" source "drivers/net/ethernet/apple/Kconfig"
source "drivers/net/ethernet/arc/Kconfig" source "drivers/net/ethernet/arc/Kconfig"
source "drivers/net/ethernet/atheros/Kconfig" source "drivers/net/ethernet/atheros/Kconfig"
......
...@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ ...@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/
obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
obj-$(CONFIG_ALTERA_TSE) += altera/ obj-$(CONFIG_ALTERA_TSE) += altera/
obj-$(CONFIG_NET_VENDOR_AMD) += amd/ obj-$(CONFIG_NET_VENDOR_AMD) += amd/
obj-$(CONFIG_NET_XGENE) += apm/
obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
obj-$(CONFIG_NET_VENDOR_ARC) += arc/ obj-$(CONFIG_NET_VENDOR_ARC) += arc/
obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
......
source "drivers/net/ethernet/apm/xgene/Kconfig"
#
# Makefile for APM X-GENE Ethernet driver.
#
obj-$(CONFIG_NET_XGENE) += xgene/
config NET_XGENE
tristate "APM X-Gene SoC Ethernet Driver"
select PHYLIB
help
This is the Ethernet driver for the on-chip ethernet interface on the
APM X-Gene SoC.
To compile this driver as a module, choose M here. This module will
be called xgene_enet.
#
# Makefile for APM X-Gene Ethernet Driver.
#
xgene-enet-objs := xgene_enet_hw.o xgene_enet_main.o xgene_enet_ethtool.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
/* Applied Micro X-Gene SoC Ethernet Driver
*
* Copyright (c) 2014, Applied Micro Circuits Corporation
* Authors: Iyappan Subramanian <isubramanian@apm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/ethtool.h>
#include "xgene_enet_main.h"
struct xgene_gstrings_stats {
char name[ETH_GSTRING_LEN];
int offset;
};
#define XGENE_STAT(m) { #m, offsetof(struct xgene_enet_pdata, stats.m) }
static const struct xgene_gstrings_stats gstrings_stats[] = {
XGENE_STAT(rx_packets),
XGENE_STAT(tx_packets),
XGENE_STAT(rx_bytes),
XGENE_STAT(tx_bytes),
XGENE_STAT(rx_errors),
XGENE_STAT(tx_errors),
XGENE_STAT(rx_length_errors),
XGENE_STAT(rx_crc_errors),
XGENE_STAT(rx_frame_errors),
XGENE_STAT(rx_fifo_errors)
};
#define XGENE_STATS_LEN ARRAY_SIZE(gstrings_stats)
static void xgene_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct platform_device *pdev = pdata->pdev;
strcpy(info->driver, "xgene_enet");
strcpy(info->version, XGENE_DRV_VERSION);
snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A");
sprintf(info->bus_info, "%s", pdev->name);
}
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;
return phy_ethtool_gset(phydev, cmd);
}
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;
return phy_ethtool_sset(phydev, cmd);
}
static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
{
int i;
u8 *p = data;
if (stringset != ETH_SS_STATS)
return;
for (i = 0; i < XGENE_STATS_LEN; i++) {
memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
}
static int xgene_get_sset_count(struct net_device *ndev, int sset)
{
if (sset != ETH_SS_STATS)
return -EINVAL;
return XGENE_STATS_LEN;
}
static void xgene_get_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *dummy,
u64 *data)
{
void *pdata = netdev_priv(ndev);
int i;
for (i = 0; i < XGENE_STATS_LEN; i++)
*data++ = *(u64 *)(pdata + gstrings_stats[i].offset);
}
static const struct ethtool_ops xgene_ethtool_ops = {
.get_drvinfo = xgene_get_drvinfo,
.get_settings = xgene_get_settings,
.set_settings = xgene_set_settings,
.get_link = ethtool_op_get_link,
.get_strings = xgene_get_strings,
.get_sset_count = xgene_get_sset_count,
.get_ethtool_stats = xgene_get_ethtool_stats
};
void xgene_enet_set_ethtool_ops(struct net_device *ndev)
{
ndev->ethtool_ops = &xgene_ethtool_ops;
}
This diff is collapsed.
/* Applied Micro X-Gene SoC Ethernet Driver
*
* Copyright (c) 2014, Applied Micro Circuits Corporation
* Authors: Iyappan Subramanian <isubramanian@apm.com>
* Ravi Patel <rapatel@apm.com>
* Keyur Chudgar <kchudgar@apm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __XGENE_ENET_HW_H__
#define __XGENE_ENET_HW_H__
#include "xgene_enet_main.h"
struct xgene_enet_pdata;
struct xgene_enet_stats;
/* clears and then set bits */
static inline void xgene_set_bits(u32 *dst, u32 val, u32 start, u32 len)
{
u32 end = start + len - 1;
u32 mask = GENMASK(end, start);
*dst &= ~mask;
*dst |= (val << start) & mask;
}
static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
{
return (val & GENMASK(end, start)) >> start;
}
#define CSR_RING_ID 0x0008
#define OVERWRITE BIT(31)
#define IS_BUFFER_POOL BIT(20)
#define PREFETCH_BUF_EN BIT(21)
#define CSR_RING_ID_BUF 0x000c
#define CSR_RING_NE_INT_MODE 0x017c
#define CSR_RING_CONFIG 0x006c
#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
#define CREATE_MASK(pos, len) GENMASK((pos)+(len)-1, (pos))
#define CREATE_MASK_ULL(pos, len) GENMASK_ULL((pos)+(len)-1, (pos))
/* Empty slot soft signature */
#define EMPTY_SLOT_INDEX 1
#define EMPTY_SLOT ~0ULL
#define WORK_DESC_SIZE 32
#define BUFPOOL_DESC_SIZE 16
#define RING_OWNER_MASK GENMASK(9, 6)
#define RING_BUFNUM_MASK GENMASK(5, 0)
#define SELTHRSH_POS 3
#define SELTHRSH_LEN 3
#define RINGADDRL_POS 5
#define RINGADDRL_LEN 27
#define RINGADDRH_POS 0
#define RINGADDRH_LEN 6
#define RINGSIZE_POS 23
#define RINGSIZE_LEN 3
#define RINGTYPE_POS 19
#define RINGTYPE_LEN 2
#define RINGMODE_POS 20
#define RINGMODE_LEN 3
#define RECOMTIMEOUTL_POS 28
#define RECOMTIMEOUTL_LEN 3
#define RECOMTIMEOUTH_POS 0
#define RECOMTIMEOUTH_LEN 2
#define NUMMSGSINQ_POS 1
#define NUMMSGSINQ_LEN 16
#define ACCEPTLERR BIT(19)
#define QCOHERENT BIT(4)
#define RECOMBBUF BIT(27)
#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
#define MAC_COMMAND_REG_OFFSET 0x04
#define MAC_WRITE_REG_OFFSET 0x08
#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
#define MII_MGMT_CONTROL_ADDR 0x2c
#define MII_MGMT_STATUS_ADDR 0x30
#define MII_MGMT_INDICATORS_ADDR 0x34
#define BUSY_MASK BIT(0)
#define READ_CYCLE_MASK BIT(0)
#define PHY_CONTROL_SET(dst, val) xgene_set_bits(dst, val, 0, 16)
#define ENET_SPARE_CFG_REG_ADDR 0x0750
#define RSIF_CONFIG_REG_ADDR 0x0010
#define RSIF_RAM_DBG_REG0_ADDR 0x0048
#define RGMII_REG_0_ADDR 0x07e0
#define CFG_LINK_AGGR_RESUME_0_ADDR 0x07c8
#define DEBUG_REG_ADDR 0x0700
#define CFG_BYPASS_ADDR 0x0294
#define CLE_BYPASS_REG0_0_ADDR 0x0490
#define CLE_BYPASS_REG1_0_ADDR 0x0494
#define CFG_RSIF_FPBUFF_TIMEOUT_EN BIT(31)
#define RESUME_TX BIT(0)
#define CFG_SPEED_1250 BIT(24)
#define TX_PORT0 BIT(0)
#define CFG_BYPASS_UNISEC_TX BIT(2)
#define CFG_BYPASS_UNISEC_RX BIT(1)
#define CFG_CLE_BYPASS_EN0 BIT(31)
#define CFG_TXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 29, 3)
#define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2)
#define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12)
#define CFG_CLE_FPSEL0_SET(dst, val) xgene_set_bits(dst, val, 16, 4)
#define CFG_MACMODE_SET(dst, val) xgene_set_bits(dst, val, 18, 2)
#define CFG_WAITASYNCRD_SET(dst, val) xgene_set_bits(dst, val, 0, 16)
#define ICM_CONFIG0_REG_0_ADDR 0x0400
#define ICM_CONFIG2_REG_0_ADDR 0x0410
#define RX_DV_GATE_REG_0_ADDR 0x05fc
#define TX_DV_GATE_EN0 BIT(2)
#define RX_DV_GATE_EN0 BIT(1)
#define RESUME_RX0 BIT(0)
#define ENET_CFGSSQMIWQASSOC_ADDR 0xe0
#define ENET_CFGSSQMIFPQASSOC_ADDR 0xdc
#define ENET_CFGSSQMIQMLITEFPQASSOC_ADDR 0xf0
#define ENET_CFGSSQMIQMLITEWQASSOC_ADDR 0xf4
#define ENET_CFG_MEM_RAM_SHUTDOWN_ADDR 0x70
#define ENET_BLOCK_MEM_RDY_ADDR 0x74
#define MAC_CONFIG_1_ADDR 0x00
#define MAC_CONFIG_2_ADDR 0x04
#define MAX_FRAME_LEN_ADDR 0x10
#define INTERFACE_CONTROL_ADDR 0x38
#define STATION_ADDR0_ADDR 0x40
#define STATION_ADDR1_ADDR 0x44
#define PHY_ADDR_SET(dst, val) xgene_set_bits(dst, val, 8, 5)
#define REG_ADDR_SET(dst, val) xgene_set_bits(dst, val, 0, 5)
#define ENET_INTERFACE_MODE2_SET(dst, val) xgene_set_bits(dst, val, 8, 2)
#define MGMT_CLOCK_SEL_SET(dst, val) xgene_set_bits(dst, val, 0, 3)
#define SOFT_RESET1 BIT(31)
#define TX_EN BIT(0)
#define RX_EN BIT(2)
#define ENET_LHD_MODE BIT(25)
#define ENET_GHD_MODE BIT(26)
#define FULL_DUPLEX2 BIT(0)
#define SCAN_AUTO_INCR BIT(5)
#define TBYT_ADDR 0x38
#define TPKT_ADDR 0x39
#define TDRP_ADDR 0x45
#define TFCS_ADDR 0x47
#define TUND_ADDR 0x4a
#define TSO_IPPROTO_TCP 1
#define FULL_DUPLEX 2
#define USERINFO_POS 0
#define USERINFO_LEN 32
#define FPQNUM_POS 32
#define FPQNUM_LEN 12
#define LERR_POS 60
#define LERR_LEN 3
#define STASH_POS 52
#define STASH_LEN 2
#define BUFDATALEN_POS 48
#define BUFDATALEN_LEN 12
#define DATAADDR_POS 0
#define DATAADDR_LEN 42
#define COHERENT_POS 63
#define HENQNUM_POS 48
#define HENQNUM_LEN 12
#define TYPESEL_POS 44
#define TYPESEL_LEN 4
#define ETHHDR_POS 12
#define ETHHDR_LEN 8
#define IC_POS 35 /* Insert CRC */
#define TCPHDR_POS 0
#define TCPHDR_LEN 6
#define IPHDR_POS 6
#define IPHDR_LEN 6
#define EC_POS 22 /* Enable checksum */
#define EC_LEN 1
#define IS_POS 24 /* IP protocol select */
#define IS_LEN 1
#define TYPE_ETH_WORK_MESSAGE_POS 44
struct xgene_enet_raw_desc {
__le64 m0;
__le64 m1;
__le64 m2;
__le64 m3;
};
struct xgene_enet_raw_desc16 {
__le64 m0;
__le64 m1;
};
static inline void xgene_enet_mark_desc_slot_empty(void *desc_slot_ptr)
{
__le64 *desc_slot = desc_slot_ptr;
desc_slot[EMPTY_SLOT_INDEX] = cpu_to_le64(EMPTY_SLOT);
}
static inline bool xgene_enet_is_desc_slot_empty(void *desc_slot_ptr)
{
__le64 *desc_slot = desc_slot_ptr;
return (desc_slot[EMPTY_SLOT_INDEX] == cpu_to_le64(EMPTY_SLOT));
}
enum xgene_enet_ring_cfgsize {
RING_CFGSIZE_512B,
RING_CFGSIZE_2KB,
RING_CFGSIZE_16KB,
RING_CFGSIZE_64KB,
RING_CFGSIZE_512KB,
RING_CFGSIZE_INVALID
};
enum xgene_enet_ring_type {
RING_DISABLED,
RING_REGULAR,
RING_BUFPOOL
};
enum xgene_ring_owner {
RING_OWNER_ETH0,
RING_OWNER_CPU = 15,
RING_OWNER_INVALID
};
enum xgene_enet_ring_bufnum {
RING_BUFNUM_REGULAR = 0x0,
RING_BUFNUM_BUFPOOL = 0x20,
RING_BUFNUM_INVALID
};
enum xgene_enet_cmd {
XGENE_ENET_WR_CMD = BIT(31),
XGENE_ENET_RD_CMD = BIT(30)
};
enum xgene_enet_err_code {
HBF_READ_DATA = 3,
HBF_LL_READ = 4,
BAD_WORK_MSG = 6,
BUFPOOL_TIMEOUT = 15,
INGRESS_CRC = 16,
INGRESS_CHECKSUM = 17,
INGRESS_TRUNC_FRAME = 18,
INGRESS_PKT_LEN = 19,
INGRESS_PKT_UNDER = 20,
INGRESS_FIFO_OVERRUN = 21,
INGRESS_CHECKSUM_COMPUTE = 26,
ERR_CODE_INVALID
};
static inline enum xgene_ring_owner xgene_enet_ring_owner(u16 id)
{
return (id & RING_OWNER_MASK) >> 6;
}
static inline u8 xgene_enet_ring_bufnum(u16 id)
{
return id & RING_BUFNUM_MASK;
}
static inline bool xgene_enet_is_bufpool(u16 id)
{
return ((id & RING_BUFNUM_MASK) >= 0x20) ? true : false;
}
static inline u16 xgene_enet_get_numslots(u16 id, u32 size)
{
bool is_bufpool = xgene_enet_is_bufpool(id);
return (is_bufpool) ? size / BUFPOOL_DESC_SIZE :
size / WORK_DESC_SIZE;
}
struct xgene_enet_desc_ring *xgene_enet_setup_ring(
struct xgene_enet_desc_ring *ring);
void xgene_enet_clear_ring(struct xgene_enet_desc_ring *ring);
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);
#endif /* __XGENE_ENET_HW_H__ */
This diff is collapsed.
/* Applied Micro X-Gene SoC Ethernet Driver
*
* Copyright (c) 2014, Applied Micro Circuits Corporation
* Authors: Iyappan Subramanian <isubramanian@apm.com>
* Ravi Patel <rapatel@apm.com>
* Keyur Chudgar <kchudgar@apm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __XGENE_ENET_MAIN_H__
#define __XGENE_ENET_MAIN_H__
#include <linux/clk.h>
#include <linux/of_platform.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/module.h>
#include <net/ip.h>
#include <linux/prefetch.h>
#include <linux/if_vlan.h>
#include <linux/phy.h>
#include "xgene_enet_hw.h"
#define XGENE_DRV_VERSION "v1.0"
#define XGENE_ENET_MAX_MTU 1536
#define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
#define NUM_PKT_BUF 64
#define NUM_BUFPOOL 32
/* software context of a descriptor ring */
struct xgene_enet_desc_ring {
struct net_device *ndev;
u16 id;
u16 num;
u16 head;
u16 tail;
u16 slots;
u16 irq;
u32 size;
u32 state[NUM_RING_CONFIG];
void __iomem *cmd_base;
void __iomem *cmd;
dma_addr_t dma;
u16 dst_ring_num;
u8 nbufpool;
struct sk_buff *(*rx_skb);
struct sk_buff *(*cp_skb);
enum xgene_enet_ring_cfgsize cfgsize;
struct xgene_enet_desc_ring *cp_ring;
struct xgene_enet_desc_ring *buf_pool;
struct napi_struct napi;
union {
void *desc_addr;
struct xgene_enet_raw_desc *raw_desc;
struct xgene_enet_raw_desc16 *raw_desc16;
};
};
/* ethernet private data */
struct xgene_enet_pdata {
struct net_device *ndev;
struct mii_bus *mdio_bus;
struct phy_device *phy_dev;
int phy_speed;
struct clk *clk;
struct platform_device *pdev;
struct xgene_enet_desc_ring *tx_ring;
struct xgene_enet_desc_ring *rx_ring;
char *dev_name;
u32 rx_buff_cnt;
u32 tx_qcnt_hi;
u32 cp_qcnt_hi;
u32 cp_qcnt_low;
u32 rx_irq;
void __iomem *eth_csr_addr;
void __iomem *eth_ring_if_addr;
void __iomem *eth_diag_csr_addr;
void __iomem *mcx_mac_addr;
void __iomem *mcx_stats_addr;
void __iomem *mcx_mac_csr_addr;
void __iomem *base_addr;
void __iomem *ring_csr_addr;
void __iomem *ring_cmd_addr;
u32 phy_addr;
int phy_mode;
u32 speed;
u16 rm;
struct rtnl_link_stats64 stats;
};
/* Set the specified value into a bit-field defined by its starting position
* and length within a single u64.
*/
static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val)
{
return (val & ((1ULL << len) - 1)) << pos;
}
#define SET_VAL(field, val) \
xgene_enet_set_field_value(field ## _POS, field ## _LEN, val)
#define SET_BIT(field) \
xgene_enet_set_field_value(field ## _POS, 1, 1)
/* Get the value from a bit-field defined by its starting position
* and length within the specified u64.
*/
static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
{
return (src >> pos) & ((1ULL << len) - 1);
}
#define GET_VAL(field, src) \
xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
static inline struct device *ndev_to_dev(struct net_device *ndev)
{
return ndev->dev.parent;
}
void xgene_enet_set_ethtool_ops(struct net_device *netdev);
#endif /* __XGENE_ENET_MAIN_H__ */
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