net: dwc-xlgmac: Initial driver for DesignWare Enterprise Ethernet
Synopsys provides a new DesignWare Core Enterprise Ethernet MAC IP (DWC-XLGMAC) for Ethernet designs. It is compliant with the IEEE 802.3-2012 specifications, including IEEE 802.3ba and consortium specifications. This patch provides the initial 25G/40G/50G/100G Ethernet driver for Synopsys XLGMAC IP Prototyping Kit. Signed-off-by: Jie Deng <jiedeng@synopsys.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
24d79ce0dc
commit
65e0ace2c5
|
@ -11068,6 +11068,12 @@ F: include/linux/dma/dw.h
|
|||
F: include/linux/platform_data/dma-dw.h
|
||||
F: drivers/dma/dw/
|
||||
|
||||
SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
|
||||
M: Jie Deng <jiedeng@synopsys.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/synopsys/
|
||||
|
||||
SYNOPSYS DESIGNWARE I2C DRIVER
|
||||
M: Jarkko Nikula <jarkko.nikula@linux.intel.com>
|
||||
R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
|
|
|
@ -180,5 +180,6 @@ source "drivers/net/ethernet/via/Kconfig"
|
|||
source "drivers/net/ethernet/wiznet/Kconfig"
|
||||
source "drivers/net/ethernet/xilinx/Kconfig"
|
||||
source "drivers/net/ethernet/xircom/Kconfig"
|
||||
source "drivers/net/ethernet/synopsys/Kconfig"
|
||||
|
||||
endif # ETHERNET
|
||||
|
|
|
@ -91,3 +91,4 @@ obj-$(CONFIG_NET_VENDOR_VIA) += via/
|
|||
obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
|
||||
obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
|
||||
obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
|
||||
obj-$(CONFIG_NET_VENDOR_SYNOPSYS) += synopsys/
|
||||
|
|
41
drivers/net/ethernet/synopsys/Kconfig
Normal file
41
drivers/net/ethernet/synopsys/Kconfig
Normal file
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Synopsys network device configuration
|
||||
#
|
||||
|
||||
config NET_VENDOR_SYNOPSYS
|
||||
bool "Synopsys devices"
|
||||
default y
|
||||
---help---
|
||||
If you have a network (Ethernet) device belonging to this class, say Y.
|
||||
|
||||
Note that the answer to this question doesn't directly affect the
|
||||
kernel: saying N will just cause the configurator to skip all
|
||||
the questions about Synopsys devices. If you say Y, you will be asked
|
||||
for your specific device in the following questions.
|
||||
|
||||
if NET_VENDOR_SYNOPSYS
|
||||
|
||||
config DWC_XLGMAC
|
||||
tristate "Synopsys DWC Enterprise Ethernet (XLGMAC) driver support"
|
||||
depends on HAS_IOMEM && HAS_DMA
|
||||
select BITREVERSE
|
||||
select CRC32
|
||||
---help---
|
||||
This driver supports the Synopsys DesignWare Cores Enterprise
|
||||
Ethernet (dwc-xlgmac).
|
||||
|
||||
if DWC_XLGMAC
|
||||
|
||||
config DWC_XLGMAC_PCI
|
||||
tristate "XLGMAC PCI bus support"
|
||||
depends on DWC_XLGMAC && PCI
|
||||
---help---
|
||||
This selects the pci bus support for the dwc-xlgmac driver.
|
||||
This driver was tested on Synopsys XLGMAC IP Prototyping Kit.
|
||||
|
||||
If you have a controller with this interface, say Y or M here.
|
||||
If unsure, say N.
|
||||
|
||||
endif # DWC_XLGMAC
|
||||
|
||||
endif # NET_VENDOR_SYNOPSYS
|
9
drivers/net/ethernet/synopsys/Makefile
Normal file
9
drivers/net/ethernet/synopsys/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Makefile for the Synopsys network device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_DWC_XLGMAC) += dwc-xlgmac.o
|
||||
dwc-xlgmac-objs := dwc-xlgmac-net.o dwc-xlgmac-desc.o \
|
||||
dwc-xlgmac-hw.o dwc-xlgmac-common.o
|
||||
|
||||
dwc-xlgmac-$(CONFIG_DWC_XLGMAC_PCI) += dwc-xlgmac-pci.o
|
736
drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
Normal file
736
drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
Normal file
|
@ -0,0 +1,736 @@
|
|||
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||||
*
|
||||
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.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 Synopsys DWC XLGMAC software driver and associated documentation
|
||||
* (hereinafter the "Software") is an unsupported proprietary work of
|
||||
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||||
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||||
* Licensed Product under any End User Software License Agreement or
|
||||
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||||
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||||
* in the SOFTWARE may be the trademarks of their respective owners.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "dwc-xlgmac.h"
|
||||
#include "dwc-xlgmac-reg.h"
|
||||
|
||||
static int debug = -1;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "DWC ethernet debug level (0=none,...,16=all)");
|
||||
static const u32 default_msg_level = (NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
|
||||
NETIF_MSG_IFUP);
|
||||
|
||||
static unsigned char dev_addr[6] = {0, 0x55, 0x7b, 0xb5, 0x7d, 0xf7};
|
||||
|
||||
static void xlgmac_read_mac_addr(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct net_device *netdev = pdata->netdev;
|
||||
|
||||
/* Currently it uses a static mac address for test */
|
||||
memcpy(pdata->mac_addr, dev_addr, netdev->addr_len);
|
||||
}
|
||||
|
||||
static void xlgmac_default_config(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
pdata->tx_osp_mode = DMA_OSP_ENABLE;
|
||||
pdata->tx_sf_mode = MTL_TSF_ENABLE;
|
||||
pdata->rx_sf_mode = MTL_RSF_DISABLE;
|
||||
pdata->pblx8 = DMA_PBL_X8_ENABLE;
|
||||
pdata->tx_pbl = DMA_PBL_32;
|
||||
pdata->rx_pbl = DMA_PBL_32;
|
||||
pdata->tx_threshold = MTL_TX_THRESHOLD_128;
|
||||
pdata->rx_threshold = MTL_RX_THRESHOLD_128;
|
||||
pdata->tx_pause = 1;
|
||||
pdata->rx_pause = 1;
|
||||
pdata->phy_speed = SPEED_25000;
|
||||
pdata->sysclk_rate = XLGMAC_SYSCLOCK;
|
||||
|
||||
strlcpy(pdata->drv_name, XLGMAC_DRV_NAME, sizeof(pdata->drv_name));
|
||||
strlcpy(pdata->drv_ver, XLGMAC_DRV_VERSION, sizeof(pdata->drv_ver));
|
||||
}
|
||||
|
||||
static void xlgmac_init_all_ops(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
xlgmac_init_desc_ops(&pdata->desc_ops);
|
||||
xlgmac_init_hw_ops(&pdata->hw_ops);
|
||||
}
|
||||
|
||||
static int xlgmac_init(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_hw_ops *hw_ops = &pdata->hw_ops;
|
||||
struct net_device *netdev = pdata->netdev;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* Set default configuration data */
|
||||
xlgmac_default_config(pdata);
|
||||
|
||||
/* Set irq, base_addr, MAC address, */
|
||||
netdev->irq = pdata->dev_irq;
|
||||
netdev->base_addr = (unsigned long)pdata->mac_regs;
|
||||
xlgmac_read_mac_addr(pdata);
|
||||
memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len);
|
||||
|
||||
/* Set all the function pointers */
|
||||
xlgmac_init_all_ops(pdata);
|
||||
|
||||
/* Issue software reset to device */
|
||||
hw_ops->exit(pdata);
|
||||
|
||||
/* Populate the hardware features */
|
||||
xlgmac_get_all_hw_features(pdata);
|
||||
xlgmac_print_all_hw_features(pdata);
|
||||
|
||||
/* TODO: Set the PHY mode to XLGMII */
|
||||
|
||||
/* Set the DMA mask */
|
||||
ret = dma_set_mask_and_coherent(pdata->dev,
|
||||
DMA_BIT_MASK(pdata->hw_feat.dma_width));
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "dma_set_mask_and_coherent failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Channel and ring params initializtion
|
||||
* pdata->channel_count;
|
||||
* pdata->tx_ring_count;
|
||||
* pdata->rx_ring_count;
|
||||
* pdata->tx_desc_count;
|
||||
* pdata->rx_desc_count;
|
||||
*/
|
||||
BUILD_BUG_ON_NOT_POWER_OF_2(XLGMAC_TX_DESC_CNT);
|
||||
pdata->tx_desc_count = XLGMAC_TX_DESC_CNT;
|
||||
if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
|
||||
dev_err(pdata->dev, "tx descriptor count (%d) is not valid\n",
|
||||
pdata->tx_desc_count);
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
BUILD_BUG_ON_NOT_POWER_OF_2(XLGMAC_RX_DESC_CNT);
|
||||
pdata->rx_desc_count = XLGMAC_RX_DESC_CNT;
|
||||
if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
|
||||
dev_err(pdata->dev, "rx descriptor count (%d) is not valid\n",
|
||||
pdata->rx_desc_count);
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(),
|
||||
pdata->hw_feat.tx_ch_cnt);
|
||||
pdata->tx_ring_count = min_t(unsigned int, pdata->tx_ring_count,
|
||||
pdata->hw_feat.tx_q_cnt);
|
||||
pdata->tx_q_count = pdata->tx_ring_count;
|
||||
ret = netif_set_real_num_tx_queues(netdev, pdata->tx_q_count);
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "error setting real tx queue count\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->rx_ring_count = min_t(unsigned int,
|
||||
netif_get_num_default_rss_queues(),
|
||||
pdata->hw_feat.rx_ch_cnt);
|
||||
pdata->rx_ring_count = min_t(unsigned int, pdata->rx_ring_count,
|
||||
pdata->hw_feat.rx_q_cnt);
|
||||
pdata->rx_q_count = pdata->rx_ring_count;
|
||||
ret = netif_set_real_num_rx_queues(netdev, pdata->rx_q_count);
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "error setting real rx queue count\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->channel_count =
|
||||
max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
|
||||
|
||||
/* Initialize RSS hash key and lookup table */
|
||||
netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key));
|
||||
|
||||
for (i = 0; i < XLGMAC_RSS_MAX_TABLE_SIZE; i++)
|
||||
pdata->rss_table[i] = XLGMAC_SET_REG_BITS(
|
||||
pdata->rss_table[i],
|
||||
MAC_RSSDR_DMCH_POS,
|
||||
MAC_RSSDR_DMCH_LEN,
|
||||
i % pdata->rx_ring_count);
|
||||
|
||||
pdata->rss_options = XLGMAC_SET_REG_BITS(
|
||||
pdata->rss_options,
|
||||
MAC_RSSCR_IP2TE_POS,
|
||||
MAC_RSSCR_IP2TE_LEN, 1);
|
||||
pdata->rss_options = XLGMAC_SET_REG_BITS(
|
||||
pdata->rss_options,
|
||||
MAC_RSSCR_TCP4TE_POS,
|
||||
MAC_RSSCR_TCP4TE_LEN, 1);
|
||||
pdata->rss_options = XLGMAC_SET_REG_BITS(
|
||||
pdata->rss_options,
|
||||
MAC_RSSCR_UDP4TE_POS,
|
||||
MAC_RSSCR_UDP4TE_LEN, 1);
|
||||
|
||||
/* Set device operations */
|
||||
netdev->netdev_ops = xlgmac_get_netdev_ops();
|
||||
|
||||
/* Set device features */
|
||||
if (pdata->hw_feat.tso) {
|
||||
netdev->hw_features = NETIF_F_TSO;
|
||||
netdev->hw_features |= NETIF_F_TSO6;
|
||||
netdev->hw_features |= NETIF_F_SG;
|
||||
netdev->hw_features |= NETIF_F_IP_CSUM;
|
||||
netdev->hw_features |= NETIF_F_IPV6_CSUM;
|
||||
} else if (pdata->hw_feat.tx_coe) {
|
||||
netdev->hw_features = NETIF_F_IP_CSUM;
|
||||
netdev->hw_features |= NETIF_F_IPV6_CSUM;
|
||||
}
|
||||
|
||||
if (pdata->hw_feat.rx_coe) {
|
||||
netdev->hw_features |= NETIF_F_RXCSUM;
|
||||
netdev->hw_features |= NETIF_F_GRO;
|
||||
}
|
||||
|
||||
if (pdata->hw_feat.rss)
|
||||
netdev->hw_features |= NETIF_F_RXHASH;
|
||||
|
||||
netdev->vlan_features |= netdev->hw_features;
|
||||
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
|
||||
if (pdata->hw_feat.sa_vlan_ins)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
|
||||
if (pdata->hw_feat.vlhash)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
|
||||
netdev->features |= netdev->hw_features;
|
||||
pdata->netdev_features = netdev->features;
|
||||
|
||||
netdev->priv_flags |= IFF_UNICAST_FLT;
|
||||
|
||||
/* Use default watchdog timeout */
|
||||
netdev->watchdog_timeo = 0;
|
||||
|
||||
/* Tx coalesce parameters initialization */
|
||||
pdata->tx_usecs = XLGMAC_INIT_DMA_TX_USECS;
|
||||
pdata->tx_frames = XLGMAC_INIT_DMA_TX_FRAMES;
|
||||
|
||||
/* Rx coalesce parameters initialization */
|
||||
pdata->rx_riwt = hw_ops->usec_to_riwt(pdata, XLGMAC_INIT_DMA_RX_USECS);
|
||||
pdata->rx_usecs = XLGMAC_INIT_DMA_RX_USECS;
|
||||
pdata->rx_frames = XLGMAC_INIT_DMA_RX_FRAMES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xlgmac_drv_probe(struct device *dev, struct xlgmac_resources *res)
|
||||
{
|
||||
struct xlgmac_pdata *pdata;
|
||||
struct net_device *netdev;
|
||||
int ret;
|
||||
|
||||
netdev = alloc_etherdev_mq(sizeof(struct xlgmac_pdata),
|
||||
XLGMAC_MAX_DMA_CHANNELS);
|
||||
|
||||
if (!netdev) {
|
||||
dev_err(dev, "alloc_etherdev failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SET_NETDEV_DEV(netdev, dev);
|
||||
dev_set_drvdata(dev, netdev);
|
||||
pdata = netdev_priv(netdev);
|
||||
pdata->dev = dev;
|
||||
pdata->netdev = netdev;
|
||||
|
||||
pdata->dev_irq = res->irq;
|
||||
pdata->mac_regs = res->addr;
|
||||
|
||||
mutex_init(&pdata->rss_mutex);
|
||||
pdata->msg_enable = netif_msg_init(debug, default_msg_level);
|
||||
|
||||
ret = xlgmac_init(pdata);
|
||||
if (ret) {
|
||||
dev_err(dev, "xlgmac init failed\n");
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
ret = register_netdev(netdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "net device registration failed\n");
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_netdev:
|
||||
free_netdev(netdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xlgmac_drv_remove(struct device *dev)
|
||||
{
|
||||
struct net_device *netdev = dev_get_drvdata(dev);
|
||||
|
||||
unregister_netdev(netdev);
|
||||
free_netdev(netdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
unsigned int idx,
|
||||
unsigned int count,
|
||||
unsigned int flag)
|
||||
{
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
struct xlgmac_dma_desc *dma_desc;
|
||||
|
||||
while (count--) {
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, idx);
|
||||
dma_desc = desc_data->dma_desc;
|
||||
|
||||
netdev_dbg(pdata->netdev, "TX: dma_desc=%p, dma_desc_addr=%pad\n",
|
||||
desc_data->dma_desc, &desc_data->dma_desc_addr);
|
||||
netdev_dbg(pdata->netdev,
|
||||
"TX_NORMAL_DESC[%d %s] = %08x:%08x:%08x:%08x\n", idx,
|
||||
(flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
|
||||
le32_to_cpu(dma_desc->desc0),
|
||||
le32_to_cpu(dma_desc->desc1),
|
||||
le32_to_cpu(dma_desc->desc2),
|
||||
le32_to_cpu(dma_desc->desc3));
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
unsigned int idx)
|
||||
{
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
struct xlgmac_dma_desc *dma_desc;
|
||||
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, idx);
|
||||
dma_desc = desc_data->dma_desc;
|
||||
|
||||
netdev_dbg(pdata->netdev, "RX: dma_desc=%p, dma_desc_addr=%pad\n",
|
||||
desc_data->dma_desc, &desc_data->dma_desc_addr);
|
||||
netdev_dbg(pdata->netdev,
|
||||
"RX_NORMAL_DESC[%d RX BY DEVICE] = %08x:%08x:%08x:%08x\n",
|
||||
idx,
|
||||
le32_to_cpu(dma_desc->desc0),
|
||||
le32_to_cpu(dma_desc->desc1),
|
||||
le32_to_cpu(dma_desc->desc2),
|
||||
le32_to_cpu(dma_desc->desc3));
|
||||
}
|
||||
|
||||
void xlgmac_print_pkt(struct net_device *netdev,
|
||||
struct sk_buff *skb, bool tx_rx)
|
||||
{
|
||||
struct ethhdr *eth = (struct ethhdr *)skb->data;
|
||||
unsigned char *buf = skb->data;
|
||||
unsigned char buffer[128];
|
||||
unsigned int i, j;
|
||||
|
||||
netdev_dbg(netdev, "\n************** SKB dump ****************\n");
|
||||
|
||||
netdev_dbg(netdev, "%s packet of %d bytes\n",
|
||||
(tx_rx ? "TX" : "RX"), skb->len);
|
||||
|
||||
netdev_dbg(netdev, "Dst MAC addr: %pM\n", eth->h_dest);
|
||||
netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source);
|
||||
netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto));
|
||||
|
||||
for (i = 0, j = 0; i < skb->len;) {
|
||||
j += snprintf(buffer + j, sizeof(buffer) - j, "%02hhx",
|
||||
buf[i++]);
|
||||
|
||||
if ((i % 32) == 0) {
|
||||
netdev_dbg(netdev, " %#06x: %s\n", i - 32, buffer);
|
||||
j = 0;
|
||||
} else if ((i % 16) == 0) {
|
||||
buffer[j++] = ' ';
|
||||
buffer[j++] = ' ';
|
||||
} else if ((i % 4) == 0) {
|
||||
buffer[j++] = ' ';
|
||||
}
|
||||
}
|
||||
if (i % 32)
|
||||
netdev_dbg(netdev, " %#06x: %s\n", i - (i % 32), buffer);
|
||||
|
||||
netdev_dbg(netdev, "\n************** SKB dump ****************\n");
|
||||
}
|
||||
|
||||
void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_hw_features *hw_feat = &pdata->hw_feat;
|
||||
unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
|
||||
|
||||
mac_hfr0 = readl(pdata->mac_regs + MAC_HWF0R);
|
||||
mac_hfr1 = readl(pdata->mac_regs + MAC_HWF1R);
|
||||
mac_hfr2 = readl(pdata->mac_regs + MAC_HWF2R);
|
||||
|
||||
memset(hw_feat, 0, sizeof(*hw_feat));
|
||||
|
||||
hw_feat->version = readl(pdata->mac_regs + MAC_VR);
|
||||
|
||||
/* Hardware feature register 0 */
|
||||
hw_feat->phyifsel = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_PHYIFSEL_POS,
|
||||
MAC_HWF0R_PHYIFSEL_LEN);
|
||||
hw_feat->vlhash = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_VLHASH_POS,
|
||||
MAC_HWF0R_VLHASH_LEN);
|
||||
hw_feat->sma = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_SMASEL_POS,
|
||||
MAC_HWF0R_SMASEL_LEN);
|
||||
hw_feat->rwk = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_RWKSEL_POS,
|
||||
MAC_HWF0R_RWKSEL_LEN);
|
||||
hw_feat->mgk = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_MGKSEL_POS,
|
||||
MAC_HWF0R_MGKSEL_LEN);
|
||||
hw_feat->mmc = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_MMCSEL_POS,
|
||||
MAC_HWF0R_MMCSEL_LEN);
|
||||
hw_feat->aoe = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_ARPOFFSEL_POS,
|
||||
MAC_HWF0R_ARPOFFSEL_LEN);
|
||||
hw_feat->ts = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_TSSEL_POS,
|
||||
MAC_HWF0R_TSSEL_LEN);
|
||||
hw_feat->eee = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_EEESEL_POS,
|
||||
MAC_HWF0R_EEESEL_LEN);
|
||||
hw_feat->tx_coe = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_TXCOESEL_POS,
|
||||
MAC_HWF0R_TXCOESEL_LEN);
|
||||
hw_feat->rx_coe = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_RXCOESEL_POS,
|
||||
MAC_HWF0R_RXCOESEL_LEN);
|
||||
hw_feat->addn_mac = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_ADDMACADRSEL_POS,
|
||||
MAC_HWF0R_ADDMACADRSEL_LEN);
|
||||
hw_feat->ts_src = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_TSSTSSEL_POS,
|
||||
MAC_HWF0R_TSSTSSEL_LEN);
|
||||
hw_feat->sa_vlan_ins = XLGMAC_GET_REG_BITS(mac_hfr0,
|
||||
MAC_HWF0R_SAVLANINS_POS,
|
||||
MAC_HWF0R_SAVLANINS_LEN);
|
||||
|
||||
/* Hardware feature register 1 */
|
||||
hw_feat->rx_fifo_size = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_RXFIFOSIZE_POS,
|
||||
MAC_HWF1R_RXFIFOSIZE_LEN);
|
||||
hw_feat->tx_fifo_size = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_TXFIFOSIZE_POS,
|
||||
MAC_HWF1R_TXFIFOSIZE_LEN);
|
||||
hw_feat->adv_ts_hi = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_ADVTHWORD_POS,
|
||||
MAC_HWF1R_ADVTHWORD_LEN);
|
||||
hw_feat->dma_width = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_ADDR64_POS,
|
||||
MAC_HWF1R_ADDR64_LEN);
|
||||
hw_feat->dcb = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_DCBEN_POS,
|
||||
MAC_HWF1R_DCBEN_LEN);
|
||||
hw_feat->sph = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_SPHEN_POS,
|
||||
MAC_HWF1R_SPHEN_LEN);
|
||||
hw_feat->tso = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_TSOEN_POS,
|
||||
MAC_HWF1R_TSOEN_LEN);
|
||||
hw_feat->dma_debug = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_DBGMEMA_POS,
|
||||
MAC_HWF1R_DBGMEMA_LEN);
|
||||
hw_feat->rss = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_RSSEN_POS,
|
||||
MAC_HWF1R_RSSEN_LEN);
|
||||
hw_feat->tc_cnt = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_NUMTC_POS,
|
||||
MAC_HWF1R_NUMTC_LEN);
|
||||
hw_feat->hash_table_size = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_HASHTBLSZ_POS,
|
||||
MAC_HWF1R_HASHTBLSZ_LEN);
|
||||
hw_feat->l3l4_filter_num = XLGMAC_GET_REG_BITS(mac_hfr1,
|
||||
MAC_HWF1R_L3L4FNUM_POS,
|
||||
MAC_HWF1R_L3L4FNUM_LEN);
|
||||
|
||||
/* Hardware feature register 2 */
|
||||
hw_feat->rx_q_cnt = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_RXQCNT_POS,
|
||||
MAC_HWF2R_RXQCNT_LEN);
|
||||
hw_feat->tx_q_cnt = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_TXQCNT_POS,
|
||||
MAC_HWF2R_TXQCNT_LEN);
|
||||
hw_feat->rx_ch_cnt = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_RXCHCNT_POS,
|
||||
MAC_HWF2R_RXCHCNT_LEN);
|
||||
hw_feat->tx_ch_cnt = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_TXCHCNT_POS,
|
||||
MAC_HWF2R_TXCHCNT_LEN);
|
||||
hw_feat->pps_out_num = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_PPSOUTNUM_POS,
|
||||
MAC_HWF2R_PPSOUTNUM_LEN);
|
||||
hw_feat->aux_snap_num = XLGMAC_GET_REG_BITS(mac_hfr2,
|
||||
MAC_HWF2R_AUXSNAPNUM_POS,
|
||||
MAC_HWF2R_AUXSNAPNUM_LEN);
|
||||
|
||||
/* Translate the Hash Table size into actual number */
|
||||
switch (hw_feat->hash_table_size) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
hw_feat->hash_table_size = 64;
|
||||
break;
|
||||
case 2:
|
||||
hw_feat->hash_table_size = 128;
|
||||
break;
|
||||
case 3:
|
||||
hw_feat->hash_table_size = 256;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Translate the address width setting into actual number */
|
||||
switch (hw_feat->dma_width) {
|
||||
case 0:
|
||||
hw_feat->dma_width = 32;
|
||||
break;
|
||||
case 1:
|
||||
hw_feat->dma_width = 40;
|
||||
break;
|
||||
case 2:
|
||||
hw_feat->dma_width = 48;
|
||||
break;
|
||||
default:
|
||||
hw_feat->dma_width = 32;
|
||||
}
|
||||
|
||||
/* The Queue, Channel and TC counts are zero based so increment them
|
||||
* to get the actual number
|
||||
*/
|
||||
hw_feat->rx_q_cnt++;
|
||||
hw_feat->tx_q_cnt++;
|
||||
hw_feat->rx_ch_cnt++;
|
||||
hw_feat->tx_ch_cnt++;
|
||||
hw_feat->tc_cnt++;
|
||||
}
|
||||
|
||||
void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
char *str = NULL;
|
||||
|
||||
XLGMAC_PR("\n");
|
||||
XLGMAC_PR("=====================================================\n");
|
||||
XLGMAC_PR("\n");
|
||||
XLGMAC_PR("HW support following features\n");
|
||||
XLGMAC_PR("\n");
|
||||
/* HW Feature Register0 */
|
||||
XLGMAC_PR("VLAN Hash Filter Selected : %s\n",
|
||||
pdata->hw_feat.vlhash ? "YES" : "NO");
|
||||
XLGMAC_PR("SMA (MDIO) Interface : %s\n",
|
||||
pdata->hw_feat.sma ? "YES" : "NO");
|
||||
XLGMAC_PR("PMT Remote Wake-up Packet Enable : %s\n",
|
||||
pdata->hw_feat.rwk ? "YES" : "NO");
|
||||
XLGMAC_PR("PMT Magic Packet Enable : %s\n",
|
||||
pdata->hw_feat.mgk ? "YES" : "NO");
|
||||
XLGMAC_PR("RMON/MMC Module Enable : %s\n",
|
||||
pdata->hw_feat.mmc ? "YES" : "NO");
|
||||
XLGMAC_PR("ARP Offload Enabled : %s\n",
|
||||
pdata->hw_feat.aoe ? "YES" : "NO");
|
||||
XLGMAC_PR("IEEE 1588-2008 Timestamp Enabled : %s\n",
|
||||
pdata->hw_feat.ts ? "YES" : "NO");
|
||||
XLGMAC_PR("Energy Efficient Ethernet Enabled : %s\n",
|
||||
pdata->hw_feat.eee ? "YES" : "NO");
|
||||
XLGMAC_PR("Transmit Checksum Offload Enabled : %s\n",
|
||||
pdata->hw_feat.tx_coe ? "YES" : "NO");
|
||||
XLGMAC_PR("Receive Checksum Offload Enabled : %s\n",
|
||||
pdata->hw_feat.rx_coe ? "YES" : "NO");
|
||||
XLGMAC_PR("Additional MAC Addresses 1-31 Selected : %s\n",
|
||||
pdata->hw_feat.addn_mac ? "YES" : "NO");
|
||||
|
||||
switch (pdata->hw_feat.ts_src) {
|
||||
case 0:
|
||||
str = "RESERVED";
|
||||
break;
|
||||
case 1:
|
||||
str = "INTERNAL";
|
||||
break;
|
||||
case 2:
|
||||
str = "EXTERNAL";
|
||||
break;
|
||||
case 3:
|
||||
str = "BOTH";
|
||||
break;
|
||||
}
|
||||
XLGMAC_PR("Timestamp System Time Source : %s\n", str);
|
||||
|
||||
XLGMAC_PR("Source Address or VLAN Insertion Enable : %s\n",
|
||||
pdata->hw_feat.sa_vlan_ins ? "YES" : "NO");
|
||||
|
||||
/* HW Feature Register1 */
|
||||
switch (pdata->hw_feat.rx_fifo_size) {
|
||||
case 0:
|
||||
str = "128 bytes";
|
||||
break;
|
||||
case 1:
|
||||
str = "256 bytes";
|
||||
break;
|
||||
case 2:
|
||||
str = "512 bytes";
|
||||
break;
|
||||
case 3:
|
||||
str = "1 KBytes";
|
||||
break;
|
||||
case 4:
|
||||
str = "2 KBytes";
|
||||
break;
|
||||
case 5:
|
||||
str = "4 KBytes";
|
||||
break;
|
||||
case 6:
|
||||
str = "8 KBytes";
|
||||
break;
|
||||
case 7:
|
||||
str = "16 KBytes";
|
||||
break;
|
||||
case 8:
|
||||
str = "32 kBytes";
|
||||
break;
|
||||
case 9:
|
||||
str = "64 KBytes";
|
||||
break;
|
||||
case 10:
|
||||
str = "128 KBytes";
|
||||
break;
|
||||
case 11:
|
||||
str = "256 KBytes";
|
||||
break;
|
||||
default:
|
||||
str = "RESERVED";
|
||||
}
|
||||
XLGMAC_PR("MTL Receive FIFO Size : %s\n", str);
|
||||
|
||||
switch (pdata->hw_feat.tx_fifo_size) {
|
||||
case 0:
|
||||
str = "128 bytes";
|
||||
break;
|
||||
case 1:
|
||||
str = "256 bytes";
|
||||
break;
|
||||
case 2:
|
||||
str = "512 bytes";
|
||||
break;
|
||||
case 3:
|
||||
str = "1 KBytes";
|
||||
break;
|
||||
case 4:
|
||||
str = "2 KBytes";
|
||||
break;
|
||||
case 5:
|
||||
str = "4 KBytes";
|
||||
break;
|
||||
case 6:
|
||||
str = "8 KBytes";
|
||||
break;
|
||||
case 7:
|
||||
str = "16 KBytes";
|
||||
break;
|
||||
case 8:
|
||||
str = "32 kBytes";
|
||||
break;
|
||||
case 9:
|
||||
str = "64 KBytes";
|
||||
break;
|
||||
case 10:
|
||||
str = "128 KBytes";
|
||||
break;
|
||||
case 11:
|
||||
str = "256 KBytes";
|
||||
break;
|
||||
default:
|
||||
str = "RESERVED";
|
||||
}
|
||||
XLGMAC_PR("MTL Transmit FIFO Size : %s\n", str);
|
||||
|
||||
XLGMAC_PR("IEEE 1588 High Word Register Enable : %s\n",
|
||||
pdata->hw_feat.adv_ts_hi ? "YES" : "NO");
|
||||
XLGMAC_PR("Address width : %u\n",
|
||||
pdata->hw_feat.dma_width);
|
||||
XLGMAC_PR("DCB Feature Enable : %s\n",
|
||||
pdata->hw_feat.dcb ? "YES" : "NO");
|
||||
XLGMAC_PR("Split Header Feature Enable : %s\n",
|
||||
pdata->hw_feat.sph ? "YES" : "NO");
|
||||
XLGMAC_PR("TCP Segmentation Offload Enable : %s\n",
|
||||
pdata->hw_feat.tso ? "YES" : "NO");
|
||||
XLGMAC_PR("DMA Debug Registers Enabled : %s\n",
|
||||
pdata->hw_feat.dma_debug ? "YES" : "NO");
|
||||
XLGMAC_PR("RSS Feature Enabled : %s\n",
|
||||
pdata->hw_feat.rss ? "YES" : "NO");
|
||||
XLGMAC_PR("Number of Traffic classes : %u\n",
|
||||
(pdata->hw_feat.tc_cnt));
|
||||
XLGMAC_PR("Hash Table Size : %u\n",
|
||||
pdata->hw_feat.hash_table_size);
|
||||
XLGMAC_PR("Total number of L3 or L4 Filters : %u\n",
|
||||
pdata->hw_feat.l3l4_filter_num);
|
||||
|
||||
/* HW Feature Register2 */
|
||||
XLGMAC_PR("Number of MTL Receive Queues : %u\n",
|
||||
pdata->hw_feat.rx_q_cnt);
|
||||
XLGMAC_PR("Number of MTL Transmit Queues : %u\n",
|
||||
pdata->hw_feat.tx_q_cnt);
|
||||
XLGMAC_PR("Number of DMA Receive Channels : %u\n",
|
||||
pdata->hw_feat.rx_ch_cnt);
|
||||
XLGMAC_PR("Number of DMA Transmit Channels : %u\n",
|
||||
pdata->hw_feat.tx_ch_cnt);
|
||||
|
||||
switch (pdata->hw_feat.pps_out_num) {
|
||||
case 0:
|
||||
str = "No PPS output";
|
||||
break;
|
||||
case 1:
|
||||
str = "1 PPS output";
|
||||
break;
|
||||
case 2:
|
||||
str = "2 PPS output";
|
||||
break;
|
||||
case 3:
|
||||
str = "3 PPS output";
|
||||
break;
|
||||
case 4:
|
||||
str = "4 PPS output";
|
||||
break;
|
||||
default:
|
||||
str = "RESERVED";
|
||||
}
|
||||
XLGMAC_PR("Number of PPS Outputs : %s\n", str);
|
||||
|
||||
switch (pdata->hw_feat.aux_snap_num) {
|
||||
case 0:
|
||||
str = "No auxiliary input";
|
||||
break;
|
||||
case 1:
|
||||
str = "1 auxiliary input";
|
||||
break;
|
||||
case 2:
|
||||
str = "2 auxiliary input";
|
||||
break;
|
||||
case 3:
|
||||
str = "3 auxiliary input";
|
||||
break;
|
||||
case 4:
|
||||
str = "4 auxiliary input";
|
||||
break;
|
||||
default:
|
||||
str = "RESERVED";
|
||||
}
|
||||
XLGMAC_PR("Number of Auxiliary Snapshot Inputs : %s", str);
|
||||
|
||||
XLGMAC_PR("\n");
|
||||
XLGMAC_PR("=====================================================\n");
|
||||
XLGMAC_PR("\n");
|
||||
}
|
648
drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c
Normal file
648
drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c
Normal file
|
@ -0,0 +1,648 @@
|
|||
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||||
*
|
||||
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.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 Synopsys DWC XLGMAC software driver and associated documentation
|
||||
* (hereinafter the "Software") is an unsupported proprietary work of
|
||||
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||||
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||||
* Licensed Product under any End User Software License Agreement or
|
||||
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||||
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||||
* in the SOFTWARE may be the trademarks of their respective owners.
|
||||
*/
|
||||
|
||||
#include "dwc-xlgmac.h"
|
||||
#include "dwc-xlgmac-reg.h"
|
||||
|
||||
static void xlgmac_unmap_desc_data(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_desc_data *desc_data)
|
||||
{
|
||||
if (desc_data->skb_dma) {
|
||||
if (desc_data->mapped_as_page) {
|
||||
dma_unmap_page(pdata->dev, desc_data->skb_dma,
|
||||
desc_data->skb_dma_len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dma_unmap_single(pdata->dev, desc_data->skb_dma,
|
||||
desc_data->skb_dma_len, DMA_TO_DEVICE);
|
||||
}
|
||||
desc_data->skb_dma = 0;
|
||||
desc_data->skb_dma_len = 0;
|
||||
}
|
||||
|
||||
if (desc_data->skb) {
|
||||
dev_kfree_skb_any(desc_data->skb);
|
||||
desc_data->skb = NULL;
|
||||
}
|
||||
|
||||
if (desc_data->rx.hdr.pa.pages)
|
||||
put_page(desc_data->rx.hdr.pa.pages);
|
||||
|
||||
if (desc_data->rx.hdr.pa_unmap.pages) {
|
||||
dma_unmap_page(pdata->dev, desc_data->rx.hdr.pa_unmap.pages_dma,
|
||||
desc_data->rx.hdr.pa_unmap.pages_len,
|
||||
DMA_FROM_DEVICE);
|
||||
put_page(desc_data->rx.hdr.pa_unmap.pages);
|
||||
}
|
||||
|
||||
if (desc_data->rx.buf.pa.pages)
|
||||
put_page(desc_data->rx.buf.pa.pages);
|
||||
|
||||
if (desc_data->rx.buf.pa_unmap.pages) {
|
||||
dma_unmap_page(pdata->dev, desc_data->rx.buf.pa_unmap.pages_dma,
|
||||
desc_data->rx.buf.pa_unmap.pages_len,
|
||||
DMA_FROM_DEVICE);
|
||||
put_page(desc_data->rx.buf.pa_unmap.pages);
|
||||
}
|
||||
|
||||
memset(&desc_data->tx, 0, sizeof(desc_data->tx));
|
||||
memset(&desc_data->rx, 0, sizeof(desc_data->rx));
|
||||
|
||||
desc_data->mapped_as_page = 0;
|
||||
|
||||
if (desc_data->state_saved) {
|
||||
desc_data->state_saved = 0;
|
||||
desc_data->state.skb = NULL;
|
||||
desc_data->state.len = 0;
|
||||
desc_data->state.error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void xlgmac_free_ring(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring)
|
||||
{
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
unsigned int i;
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
if (ring->desc_data_head) {
|
||||
for (i = 0; i < ring->dma_desc_count; i++) {
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, i);
|
||||
xlgmac_unmap_desc_data(pdata, desc_data);
|
||||
}
|
||||
|
||||
kfree(ring->desc_data_head);
|
||||
ring->desc_data_head = NULL;
|
||||
}
|
||||
|
||||
if (ring->rx_hdr_pa.pages) {
|
||||
dma_unmap_page(pdata->dev, ring->rx_hdr_pa.pages_dma,
|
||||
ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE);
|
||||
put_page(ring->rx_hdr_pa.pages);
|
||||
|
||||
ring->rx_hdr_pa.pages = NULL;
|
||||
ring->rx_hdr_pa.pages_len = 0;
|
||||
ring->rx_hdr_pa.pages_offset = 0;
|
||||
ring->rx_hdr_pa.pages_dma = 0;
|
||||
}
|
||||
|
||||
if (ring->rx_buf_pa.pages) {
|
||||
dma_unmap_page(pdata->dev, ring->rx_buf_pa.pages_dma,
|
||||
ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE);
|
||||
put_page(ring->rx_buf_pa.pages);
|
||||
|
||||
ring->rx_buf_pa.pages = NULL;
|
||||
ring->rx_buf_pa.pages_len = 0;
|
||||
ring->rx_buf_pa.pages_offset = 0;
|
||||
ring->rx_buf_pa.pages_dma = 0;
|
||||
}
|
||||
|
||||
if (ring->dma_desc_head) {
|
||||
dma_free_coherent(pdata->dev,
|
||||
(sizeof(struct xlgmac_dma_desc) *
|
||||
ring->dma_desc_count),
|
||||
ring->dma_desc_head,
|
||||
ring->dma_desc_head_addr);
|
||||
ring->dma_desc_head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int xlgmac_init_ring(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
unsigned int dma_desc_count)
|
||||
{
|
||||
if (!ring)
|
||||
return 0;
|
||||
|
||||
/* Descriptors */
|
||||
ring->dma_desc_count = dma_desc_count;
|
||||
ring->dma_desc_head = dma_alloc_coherent(pdata->dev,
|
||||
(sizeof(struct xlgmac_dma_desc) *
|
||||
dma_desc_count),
|
||||
&ring->dma_desc_head_addr,
|
||||
GFP_KERNEL);
|
||||
if (!ring->dma_desc_head)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Array of descriptor data */
|
||||
ring->desc_data_head = kcalloc(dma_desc_count,
|
||||
sizeof(struct xlgmac_desc_data),
|
||||
GFP_KERNEL);
|
||||
if (!ring->desc_data_head)
|
||||
return -ENOMEM;
|
||||
|
||||
netif_dbg(pdata, drv, pdata->netdev,
|
||||
"dma_desc_head=%p, dma_desc_head_addr=%pad, desc_data_head=%p\n",
|
||||
ring->dma_desc_head,
|
||||
&ring->dma_desc_head_addr,
|
||||
ring->desc_data_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xlgmac_free_rings(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_channel *channel;
|
||||
unsigned int i;
|
||||
|
||||
if (!pdata->channel_head)
|
||||
return;
|
||||
|
||||
channel = pdata->channel_head;
|
||||
for (i = 0; i < pdata->channel_count; i++, channel++) {
|
||||
xlgmac_free_ring(pdata, channel->tx_ring);
|
||||
xlgmac_free_ring(pdata, channel->rx_ring);
|
||||
}
|
||||
}
|
||||
|
||||
static int xlgmac_alloc_rings(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_channel *channel;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
channel = pdata->channel_head;
|
||||
for (i = 0; i < pdata->channel_count; i++, channel++) {
|
||||
netif_dbg(pdata, drv, pdata->netdev, "%s - Tx ring:\n",
|
||||
channel->name);
|
||||
|
||||
ret = xlgmac_init_ring(pdata, channel->tx_ring,
|
||||
pdata->tx_desc_count);
|
||||
|
||||
if (ret) {
|
||||
netdev_alert(pdata->netdev,
|
||||
"error initializing Tx ring");
|
||||
goto err_init_ring;
|
||||
}
|
||||
|
||||
netif_dbg(pdata, drv, pdata->netdev, "%s - Rx ring:\n",
|
||||
channel->name);
|
||||
|
||||
ret = xlgmac_init_ring(pdata, channel->rx_ring,
|
||||
pdata->rx_desc_count);
|
||||
if (ret) {
|
||||
netdev_alert(pdata->netdev,
|
||||
"error initializing Rx ring\n");
|
||||
goto err_init_ring;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_init_ring:
|
||||
xlgmac_free_rings(pdata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xlgmac_free_channels(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
if (!pdata->channel_head)
|
||||
return;
|
||||
|
||||
kfree(pdata->channel_head->tx_ring);
|
||||
pdata->channel_head->tx_ring = NULL;
|
||||
|
||||
kfree(pdata->channel_head->rx_ring);
|
||||
pdata->channel_head->rx_ring = NULL;
|
||||
|
||||
kfree(pdata->channel_head);
|
||||
|
||||
pdata->channel_head = NULL;
|
||||
pdata->channel_count = 0;
|
||||
}
|
||||
|
||||
static int xlgmac_alloc_channels(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_channel *channel_head, *channel;
|
||||
struct xlgmac_ring *tx_ring, *rx_ring;
|
||||
int ret = -ENOMEM;
|
||||
unsigned int i;
|
||||
|
||||
channel_head = kcalloc(pdata->channel_count,
|
||||
sizeof(struct xlgmac_channel), GFP_KERNEL);
|
||||
if (!channel_head)
|
||||
return ret;
|
||||
|
||||
netif_dbg(pdata, drv, pdata->netdev,
|
||||
"channel_head=%p\n", channel_head);
|
||||
|
||||
tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xlgmac_ring),
|
||||
GFP_KERNEL);
|
||||
if (!tx_ring)
|
||||
goto err_tx_ring;
|
||||
|
||||
rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xlgmac_ring),
|
||||
GFP_KERNEL);
|
||||
if (!rx_ring)
|
||||
goto err_rx_ring;
|
||||
|
||||
for (i = 0, channel = channel_head; i < pdata->channel_count;
|
||||
i++, channel++) {
|
||||
snprintf(channel->name, sizeof(channel->name), "channel-%u", i);
|
||||
channel->pdata = pdata;
|
||||
channel->queue_index = i;
|
||||
channel->dma_regs = pdata->mac_regs + DMA_CH_BASE +
|
||||
(DMA_CH_INC * i);
|
||||
|
||||
if (pdata->per_channel_irq) {
|
||||
/* Get the per DMA interrupt */
|
||||
ret = pdata->channel_irq[i];
|
||||
if (ret < 0) {
|
||||
netdev_err(pdata->netdev,
|
||||
"get_irq %u failed\n",
|
||||
i + 1);
|
||||
goto err_irq;
|
||||
}
|
||||
channel->dma_irq = ret;
|
||||
}
|
||||
|
||||
if (i < pdata->tx_ring_count)
|
||||
channel->tx_ring = tx_ring++;
|
||||
|
||||
if (i < pdata->rx_ring_count)
|
||||
channel->rx_ring = rx_ring++;
|
||||
|
||||
netif_dbg(pdata, drv, pdata->netdev,
|
||||
"%s: dma_regs=%p, tx_ring=%p, rx_ring=%p\n",
|
||||
channel->name, channel->dma_regs,
|
||||
channel->tx_ring, channel->rx_ring);
|
||||
}
|
||||
|
||||
pdata->channel_head = channel_head;
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
kfree(rx_ring);
|
||||
|
||||
err_rx_ring:
|
||||
kfree(tx_ring);
|
||||
|
||||
err_tx_ring:
|
||||
kfree(channel_head);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xlgmac_free_channels_and_rings(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
xlgmac_free_rings(pdata);
|
||||
|
||||
xlgmac_free_channels(pdata);
|
||||
}
|
||||
|
||||
static int xlgmac_alloc_channels_and_rings(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xlgmac_alloc_channels(pdata);
|
||||
if (ret)
|
||||
goto err_alloc;
|
||||
|
||||
ret = xlgmac_alloc_rings(pdata);
|
||||
if (ret)
|
||||
goto err_alloc;
|
||||
|
||||
return 0;
|
||||
|
||||
err_alloc:
|
||||
xlgmac_free_channels_and_rings(pdata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xlgmac_alloc_pages(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_page_alloc *pa,
|
||||
gfp_t gfp, int order)
|
||||
{
|
||||
struct page *pages = NULL;
|
||||
dma_addr_t pages_dma;
|
||||
int ret;
|
||||
|
||||
/* Try to obtain pages, decreasing order if necessary */
|
||||
gfp |= __GFP_COLD | __GFP_COMP | __GFP_NOWARN;
|
||||
while (order >= 0) {
|
||||
pages = alloc_pages(gfp, order);
|
||||
if (pages)
|
||||
break;
|
||||
|
||||
order--;
|
||||
}
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Map the pages */
|
||||
pages_dma = dma_map_page(pdata->dev, pages, 0,
|
||||
PAGE_SIZE << order, DMA_FROM_DEVICE);
|
||||
ret = dma_mapping_error(pdata->dev, pages_dma);
|
||||
if (ret) {
|
||||
put_page(pages);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pa->pages = pages;
|
||||
pa->pages_len = PAGE_SIZE << order;
|
||||
pa->pages_offset = 0;
|
||||
pa->pages_dma = pages_dma;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xlgmac_set_buffer_data(struct xlgmac_buffer_data *bd,
|
||||
struct xlgmac_page_alloc *pa,
|
||||
unsigned int len)
|
||||
{
|
||||
get_page(pa->pages);
|
||||
bd->pa = *pa;
|
||||
|
||||
bd->dma_base = pa->pages_dma;
|
||||
bd->dma_off = pa->pages_offset;
|
||||
bd->dma_len = len;
|
||||
|
||||
pa->pages_offset += len;
|
||||
if ((pa->pages_offset + len) > pa->pages_len) {
|
||||
/* This data descriptor is responsible for unmapping page(s) */
|
||||
bd->pa_unmap = *pa;
|
||||
|
||||
/* Get a new allocation next time */
|
||||
pa->pages = NULL;
|
||||
pa->pages_len = 0;
|
||||
pa->pages_offset = 0;
|
||||
pa->pages_dma = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int xlgmac_map_rx_buffer(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
struct xlgmac_desc_data *desc_data)
|
||||
{
|
||||
int order, ret;
|
||||
|
||||
if (!ring->rx_hdr_pa.pages) {
|
||||
ret = xlgmac_alloc_pages(pdata, &ring->rx_hdr_pa,
|
||||
GFP_ATOMIC, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ring->rx_buf_pa.pages) {
|
||||
order = max_t(int, PAGE_ALLOC_COSTLY_ORDER - 1, 0);
|
||||
ret = xlgmac_alloc_pages(pdata, &ring->rx_buf_pa,
|
||||
GFP_ATOMIC, order);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set up the header page info */
|
||||
xlgmac_set_buffer_data(&desc_data->rx.hdr, &ring->rx_hdr_pa,
|
||||
XLGMAC_SKB_ALLOC_SIZE);
|
||||
|
||||
/* Set up the buffer page info */
|
||||
xlgmac_set_buffer_data(&desc_data->rx.buf, &ring->rx_buf_pa,
|
||||
pdata->rx_buf_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xlgmac_tx_desc_init(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_hw_ops *hw_ops = &pdata->hw_ops;
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
struct xlgmac_dma_desc *dma_desc;
|
||||
struct xlgmac_channel *channel;
|
||||
struct xlgmac_ring *ring;
|
||||
dma_addr_t dma_desc_addr;
|
||||
unsigned int i, j;
|
||||
|
||||
channel = pdata->channel_head;
|
||||
for (i = 0; i < pdata->channel_count; i++, channel++) {
|
||||
ring = channel->tx_ring;
|
||||
if (!ring)
|
||||
break;
|
||||
|
||||
dma_desc = ring->dma_desc_head;
|
||||
dma_desc_addr = ring->dma_desc_head_addr;
|
||||
|
||||
for (j = 0; j < ring->dma_desc_count; j++) {
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, j);
|
||||
|
||||
desc_data->dma_desc = dma_desc;
|
||||
desc_data->dma_desc_addr = dma_desc_addr;
|
||||
|
||||
dma_desc++;
|
||||
dma_desc_addr += sizeof(struct xlgmac_dma_desc);
|
||||
}
|
||||
|
||||
ring->cur = 0;
|
||||
ring->dirty = 0;
|
||||
memset(&ring->tx, 0, sizeof(ring->tx));
|
||||
|
||||
hw_ops->tx_desc_init(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void xlgmac_rx_desc_init(struct xlgmac_pdata *pdata)
|
||||
{
|
||||
struct xlgmac_hw_ops *hw_ops = &pdata->hw_ops;
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
struct xlgmac_dma_desc *dma_desc;
|
||||
struct xlgmac_channel *channel;
|
||||
struct xlgmac_ring *ring;
|
||||
dma_addr_t dma_desc_addr;
|
||||
unsigned int i, j;
|
||||
|
||||
channel = pdata->channel_head;
|
||||
for (i = 0; i < pdata->channel_count; i++, channel++) {
|
||||
ring = channel->rx_ring;
|
||||
if (!ring)
|
||||
break;
|
||||
|
||||
dma_desc = ring->dma_desc_head;
|
||||
dma_desc_addr = ring->dma_desc_head_addr;
|
||||
|
||||
for (j = 0; j < ring->dma_desc_count; j++) {
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, j);
|
||||
|
||||
desc_data->dma_desc = dma_desc;
|
||||
desc_data->dma_desc_addr = dma_desc_addr;
|
||||
|
||||
if (xlgmac_map_rx_buffer(pdata, ring, desc_data))
|
||||
break;
|
||||
|
||||
dma_desc++;
|
||||
dma_desc_addr += sizeof(struct xlgmac_dma_desc);
|
||||
}
|
||||
|
||||
ring->cur = 0;
|
||||
ring->dirty = 0;
|
||||
|
||||
hw_ops->rx_desc_init(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static int xlgmac_map_tx_skb(struct xlgmac_channel *channel,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct xlgmac_pdata *pdata = channel->pdata;
|
||||
struct xlgmac_ring *ring = channel->tx_ring;
|
||||
unsigned int start_index, cur_index;
|
||||
struct xlgmac_desc_data *desc_data;
|
||||
unsigned int offset, datalen, len;
|
||||
struct xlgmac_pkt_info *pkt_info;
|
||||
struct skb_frag_struct *frag;
|
||||
unsigned int tso, vlan;
|
||||
dma_addr_t skb_dma;
|
||||
unsigned int i;
|
||||
|
||||
offset = 0;
|
||||
start_index = ring->cur;
|
||||
cur_index = ring->cur;
|
||||
|
||||
pkt_info = &ring->pkt_info;
|
||||
pkt_info->desc_count = 0;
|
||||
pkt_info->length = 0;
|
||||
|
||||
tso = XLGMAC_GET_REG_BITS(pkt_info->attributes,
|
||||
TX_PACKET_ATTRIBUTES_TSO_ENABLE_POS,
|
||||
TX_PACKET_ATTRIBUTES_TSO_ENABLE_LEN);
|
||||
vlan = XLGMAC_GET_REG_BITS(pkt_info->attributes,
|
||||
TX_PACKET_ATTRIBUTES_VLAN_CTAG_POS,
|
||||
TX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN);
|
||||
|
||||
/* Save space for a context descriptor if needed */
|
||||
if ((tso && (pkt_info->mss != ring->tx.cur_mss)) ||
|
||||
(vlan && (pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag)))
|
||||
cur_index++;
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
|
||||
|
||||
if (tso) {
|
||||
/* Map the TSO header */
|
||||
skb_dma = dma_map_single(pdata->dev, skb->data,
|
||||
pkt_info->header_len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(pdata->dev, skb_dma)) {
|
||||
netdev_alert(pdata->netdev, "dma_map_single failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
desc_data->skb_dma = skb_dma;
|
||||
desc_data->skb_dma_len = pkt_info->header_len;
|
||||
netif_dbg(pdata, tx_queued, pdata->netdev,
|
||||
"skb header: index=%u, dma=%pad, len=%u\n",
|
||||
cur_index, &skb_dma, pkt_info->header_len);
|
||||
|
||||
offset = pkt_info->header_len;
|
||||
|
||||
pkt_info->length += pkt_info->header_len;
|
||||
|
||||
cur_index++;
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
|
||||
}
|
||||
|
||||
/* Map the (remainder of the) packet */
|
||||
for (datalen = skb_headlen(skb) - offset; datalen; ) {
|
||||
len = min_t(unsigned int, datalen, XLGMAC_TX_MAX_BUF_SIZE);
|
||||
|
||||
skb_dma = dma_map_single(pdata->dev, skb->data + offset, len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(pdata->dev, skb_dma)) {
|
||||
netdev_alert(pdata->netdev, "dma_map_single failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
desc_data->skb_dma = skb_dma;
|
||||
desc_data->skb_dma_len = len;
|
||||
netif_dbg(pdata, tx_queued, pdata->netdev,
|
||||
"skb data: index=%u, dma=%pad, len=%u\n",
|
||||
cur_index, &skb_dma, len);
|
||||
|
||||
datalen -= len;
|
||||
offset += len;
|
||||
|
||||
pkt_info->length += len;
|
||||
|
||||
cur_index++;
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
|
||||
}
|
||||
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
netif_dbg(pdata, tx_queued, pdata->netdev,
|
||||
"mapping frag %u\n", i);
|
||||
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
offset = 0;
|
||||
|
||||
for (datalen = skb_frag_size(frag); datalen; ) {
|
||||
len = min_t(unsigned int, datalen,
|
||||
XLGMAC_TX_MAX_BUF_SIZE);
|
||||
|
||||
skb_dma = skb_frag_dma_map(pdata->dev, frag, offset,
|
||||
len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(pdata->dev, skb_dma)) {
|
||||
netdev_alert(pdata->netdev,
|
||||
"skb_frag_dma_map failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
desc_data->skb_dma = skb_dma;
|
||||
desc_data->skb_dma_len = len;
|
||||
desc_data->mapped_as_page = 1;
|
||||
netif_dbg(pdata, tx_queued, pdata->netdev,
|
||||
"skb frag: index=%u, dma=%pad, len=%u\n",
|
||||
cur_index, &skb_dma, len);
|
||||
|
||||
datalen -= len;
|
||||
offset += len;
|
||||
|
||||
pkt_info->length += len;
|
||||
|
||||
cur_index++;
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the skb address in the last entry. We always have some data
|
||||
* that has been mapped so desc_data is always advanced past the last
|
||||
* piece of mapped data - use the entry pointed to by cur_index - 1.
|
||||
*/
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, cur_index - 1);
|
||||
desc_data->skb = skb;
|
||||
|
||||
/* Save the number of descriptor entries used */
|
||||
pkt_info->desc_count = cur_index - start_index;
|
||||
|
||||
return pkt_info->desc_count;
|
||||
|
||||
err_out:
|
||||
while (start_index < cur_index) {
|
||||
desc_data = XLGMAC_GET_DESC_DATA(ring, start_index++);
|
||||
xlgmac_unmap_desc_data(pdata, desc_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops)
|
||||
{
|
||||
desc_ops->alloc_channles_and_rings = xlgmac_alloc_channels_and_rings;
|
||||
desc_ops->free_channels_and_rings = xlgmac_free_channels_and_rings;
|
||||
desc_ops->map_tx_skb = xlgmac_map_tx_skb;
|
||||
desc_ops->map_rx_buffer = xlgmac_map_rx_buffer;
|
||||
desc_ops->unmap_desc_data = xlgmac_unmap_desc_data;
|
||||
desc_ops->tx_desc_init = xlgmac_tx_desc_init;
|
||||
desc_ops->rx_desc_init = xlgmac_rx_desc_init;
|
||||
}
|
3146
drivers/net/ethernet/synopsys/dwc-xlgmac-hw.c
Normal file
3146
drivers/net/ethernet/synopsys/dwc-xlgmac-hw.c
Normal file
File diff suppressed because it is too large
Load diff
1334
drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
Normal file
1334
drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
Normal file
File diff suppressed because it is too large
Load diff
80
drivers/net/ethernet/synopsys/dwc-xlgmac-pci.c
Normal file
80
drivers/net/ethernet/synopsys/dwc-xlgmac-pci.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||||
*
|
||||
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.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 Synopsys DWC XLGMAC software driver and associated documentation
|
||||
* (hereinafter the "Software") is an unsupported proprietary work of
|
||||
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||||
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||||
* Licensed Product under any End User Software License Agreement or
|
||||
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||||
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||||
* in the SOFTWARE may be the trademarks of their respective owners.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "dwc-xlgmac.h"
|
||||
#include "dwc-xlgmac-reg.h"
|
||||
|
||||
static int xlgmac_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
|
||||
{
|
||||
struct device *dev = &pcidev->dev;
|
||||
struct xlgmac_resources res;
|
||||
int i, ret;
|
||||
|
||||
ret = pcim_enable_device(pcidev);
|
||||
if (ret) {
|
||||
dev_err(dev, "ERROR: failed to enable device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
|
||||
if (pci_resource_len(pcidev, i) == 0)
|
||||
continue;
|
||||
ret = pcim_iomap_regions(pcidev, BIT(i), XLGMAC_DRV_NAME);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
|
||||
pci_set_master(pcidev);
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res.irq = pcidev->irq;
|
||||
res.addr = pcim_iomap_table(pcidev)[i];
|
||||
|
||||
return xlgmac_drv_probe(&pcidev->dev, &res);
|
||||
}
|
||||
|
||||
static void xlgmac_remove(struct pci_dev *pcidev)
|
||||
{
|
||||
xlgmac_drv_remove(&pcidev->dev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id xlgmac_pci_tbl[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0x7302) },
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, xlgmac_pci_tbl);
|
||||
|
||||
static struct pci_driver xlgmac_pci_driver = {
|
||||
.name = XLGMAC_DRV_NAME,
|
||||
.id_table = xlgmac_pci_tbl,
|
||||
.probe = xlgmac_probe,
|
||||
.remove = xlgmac_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(xlgmac_pci_driver);
|
||||
|
||||
MODULE_DESCRIPTION(XLGMAC_DRV_DESC);
|
||||
MODULE_VERSION(XLGMAC_DRV_VERSION);
|
||||
MODULE_AUTHOR("Jie Deng <jiedeng@synopsys.com>");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
746
drivers/net/ethernet/synopsys/dwc-xlgmac-reg.h
Normal file
746
drivers/net/ethernet/synopsys/dwc-xlgmac-reg.h
Normal file
|
@ -0,0 +1,746 @@
|
|||
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||||
*
|
||||
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.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 Synopsys DWC XLGMAC software driver and associated documentation
|
||||
* (hereinafter the "Software") is an unsupported proprietary work of
|
||||
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||||
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||||
* Licensed Product under any End User Software License Agreement or
|
||||
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||||
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||||
* in the SOFTWARE may be the trademarks of their respective owners.
|
||||
*/
|
||||
|
||||
#ifndef __DWC_XLGMAC_REG_H__
|
||||
#define __DWC_XLGMAC_REG_H__
|
||||
|
||||
/* MAC register offsets */
|
||||
#define MAC_TCR 0x0000
|
||||
#define MAC_RCR 0x0004
|
||||
#define MAC_PFR 0x0008
|
||||
#define MAC_HTR0 0x0010
|
||||
#define MAC_VLANTR 0x0050
|
||||
#define MAC_VLANHTR 0x0058
|
||||
#define MAC_VLANIR 0x0060
|
||||
#define MAC_Q0TFCR 0x0070
|
||||
#define MAC_RFCR 0x0090
|
||||
#define MAC_RQC0R 0x00a0
|
||||
#define MAC_RQC1R 0x00a4
|
||||
#define MAC_RQC2R 0x00a8
|
||||
#define MAC_RQC3R 0x00ac
|
||||
#define MAC_ISR 0x00b0
|
||||
#define MAC_IER 0x00b4
|
||||
#define MAC_VR 0x0110
|
||||
#define MAC_HWF0R 0x011c
|
||||
#define MAC_HWF1R 0x0120
|
||||
#define MAC_HWF2R 0x0124
|
||||
#define MAC_MACA0HR 0x0300
|
||||
#define MAC_MACA0LR 0x0304
|
||||
#define MAC_MACA1HR 0x0308
|
||||
#define MAC_MACA1LR 0x030c
|
||||
#define MAC_RSSCR 0x0c80
|
||||
#define MAC_RSSAR 0x0c88
|
||||
#define MAC_RSSDR 0x0c8c
|
||||
|
||||
#define MAC_QTFCR_INC 4
|
||||
#define MAC_MACA_INC 4
|
||||
#define MAC_HTR_INC 4
|
||||
#define MAC_RQC2_INC 4
|
||||
#define MAC_RQC2_Q_PER_REG 4
|
||||
|
||||
/* MAC register entry bit positions and sizes */
|
||||
#define MAC_HWF0R_ADDMACADRSEL_POS 18
|
||||
#define MAC_HWF0R_ADDMACADRSEL_LEN 5
|
||||
#define MAC_HWF0R_ARPOFFSEL_POS 9
|
||||
#define MAC_HWF0R_ARPOFFSEL_LEN 1
|
||||
#define MAC_HWF0R_EEESEL_POS 13
|
||||
#define MAC_HWF0R_EEESEL_LEN 1
|
||||
#define MAC_HWF0R_PHYIFSEL_POS 1
|
||||
#define MAC_HWF0R_PHYIFSEL_LEN 2
|
||||
#define MAC_HWF0R_MGKSEL_POS 7
|
||||
#define MAC_HWF0R_MGKSEL_LEN 1
|
||||
#define MAC_HWF0R_MMCSEL_POS 8
|
||||
#define MAC_HWF0R_MMCSEL_LEN 1
|
||||
#define MAC_HWF0R_RWKSEL_POS 6
|
||||
#define MAC_HWF0R_RWKSEL_LEN 1
|
||||
#define MAC_HWF0R_RXCOESEL_POS 16
|
||||
#define MAC_HWF0R_RXCOESEL_LEN 1
|
||||
#define MAC_HWF0R_SAVLANINS_POS 27
|
||||
#define MAC_HWF0R_SAVLANINS_LEN 1
|
||||
#define MAC_HWF0R_SMASEL_POS 5
|
||||
#define MAC_HWF0R_SMASEL_LEN 1
|
||||
#define MAC_HWF0R_TSSEL_POS 12
|
||||
#define MAC_HWF0R_TSSEL_LEN 1
|
||||
#define MAC_HWF0R_TSSTSSEL_POS 25
|
||||
#define MAC_HWF0R_TSSTSSEL_LEN 2
|
||||
#define MAC_HWF0R_TXCOESEL_POS 14
|
||||
#define MAC_HWF0R_TXCOESEL_LEN 1
|
||||
#define MAC_HWF0R_VLHASH_POS 4
|
||||
#define MAC_HWF0R_VLHASH_LEN 1
|
||||
#define MAC_HWF1R_ADDR64_POS 14
|
||||
#define MAC_HWF1R_ADDR64_LEN 2
|
||||
#define MAC_HWF1R_ADVTHWORD_POS 13
|
||||
#define MAC_HWF1R_ADVTHWORD_LEN 1
|
||||
#define MAC_HWF1R_DBGMEMA_POS 19
|
||||
#define MAC_HWF1R_DBGMEMA_LEN 1
|
||||
#define MAC_HWF1R_DCBEN_POS 16
|
||||
#define MAC_HWF1R_DCBEN_LEN 1
|
||||
#define MAC_HWF1R_HASHTBLSZ_POS 24
|
||||
#define MAC_HWF1R_HASHTBLSZ_LEN 3
|
||||
#define MAC_HWF1R_L3L4FNUM_POS 27
|
||||
#define MAC_HWF1R_L3L4FNUM_LEN 4
|
||||
#define MAC_HWF1R_NUMTC_POS 21
|
||||
#define MAC_HWF1R_NUMTC_LEN 3
|
||||
#define MAC_HWF1R_RSSEN_POS 20
|
||||
#define MAC_HWF1R_RSSEN_LEN 1
|
||||
#define MAC_HWF1R_RXFIFOSIZE_POS 0
|
||||
#define MAC_HWF1R_RXFIFOSIZE_LEN 5
|
||||
#define MAC_HWF1R_SPHEN_POS 17
|
||||
#define MAC_HWF1R_SPHEN_LEN 1
|
||||
#define MAC_HWF1R_TSOEN_POS 18
|
||||
#define MAC_HWF1R_TSOEN_LEN 1
|
||||
#define MAC_HWF1R_TXFIFOSIZE_POS 6
|
||||
#define MAC_HWF1R_TXFIFOSIZE_LEN 5
|
||||
#define MAC_HWF2R_AUXSNAPNUM_POS 28
|
||||
#define MAC_HWF2R_AUXSNAPNUM_LEN 3
|
||||
#define MAC_HWF2R_PPSOUTNUM_POS 24
|
||||
#define MAC_HWF2R_PPSOUTNUM_LEN 3
|
||||
#define MAC_HWF2R_RXCHCNT_POS 12
|
||||
#define MAC_HWF2R_RXCHCNT_LEN 4
|
||||
#define MAC_HWF2R_RXQCNT_POS 0
|
||||
#define MAC_HWF2R_RXQCNT_LEN 4
|
||||
#define MAC_HWF2R_TXCHCNT_POS 18
|
||||
#define MAC_HWF2R_TXCHCNT_LEN 4
|
||||
#define MAC_HWF2R_TXQCNT_POS 6
|
||||
#define MAC_HWF2R_TXQCNT_LEN 4
|
||||
#define MAC_IER_TSIE_POS 12
|
||||
#define MAC_IER_TSIE_LEN 1
|
||||
#define MAC_ISR_MMCRXIS_POS 9
|
||||
#define MAC_ISR_MMCRXIS_LEN 1
|
||||
#define MAC_ISR_MMCTXIS_POS 10
|
||||
#define MAC_ISR_MMCTXIS_LEN 1
|
||||
#define MAC_ISR_PMTIS_POS 4
|
||||
#define MAC_ISR_PMTIS_LEN 1
|
||||
#define MAC_ISR_TSIS_POS 12
|
||||
#define MAC_ISR_TSIS_LEN 1
|
||||
#define MAC_MACA1HR_AE_POS 31
|
||||
#define MAC_MACA1HR_AE_LEN 1
|
||||
#define MAC_PFR_HMC_POS 2
|
||||
#define MAC_PFR_HMC_LEN 1
|
||||
#define MAC_PFR_HPF_POS 10
|
||||
#define MAC_PFR_HPF_LEN 1
|
||||
#define MAC_PFR_HUC_POS 1
|
||||
#define MAC_PFR_HUC_LEN 1
|
||||
#define MAC_PFR_PM_POS 4
|
||||
#define MAC_PFR_PM_LEN 1
|
||||
#define MAC_PFR_PR_POS 0
|
||||
#define MAC_PFR_PR_LEN 1
|
||||
#define MAC_PFR_VTFE_POS 16
|
||||
#define MAC_PFR_VTFE_LEN 1
|
||||
#define MAC_Q0TFCR_PT_POS 16
|
||||
#define MAC_Q0TFCR_PT_LEN 16
|
||||
#define MAC_Q0TFCR_TFE_POS 1
|
||||
#define MAC_Q0TFCR_TFE_LEN 1
|
||||
#define MAC_RCR_ACS_POS 1
|
||||
#define MAC_RCR_ACS_LEN 1
|
||||
#define MAC_RCR_CST_POS 2
|
||||
#define MAC_RCR_CST_LEN 1
|
||||
#define MAC_RCR_DCRCC_POS 3
|
||||
#define MAC_RCR_DCRCC_LEN 1
|
||||
#define MAC_RCR_HDSMS_POS 12
|
||||
#define MAC_RCR_HDSMS_LEN 3
|
||||
#define MAC_RCR_IPC_POS 9
|
||||
#define MAC_RCR_IPC_LEN 1
|
||||
#define MAC_RCR_JE_POS 8
|
||||
#define MAC_RCR_JE_LEN 1
|
||||
#define MAC_RCR_LM_POS 10
|
||||
#define MAC_RCR_LM_LEN 1
|
||||
#define MAC_RCR_RE_POS 0
|
||||
#define MAC_RCR_RE_LEN 1
|
||||
#define MAC_RFCR_PFCE_POS 8
|
||||
#define MAC_RFCR_PFCE_LEN 1
|
||||
#define MAC_RFCR_RFE_POS 0
|
||||
#define MAC_RFCR_RFE_LEN 1
|
||||
#define MAC_RFCR_UP_POS 1
|
||||
#define MAC_RFCR_UP_LEN 1
|
||||
#define MAC_RQC0R_RXQ0EN_POS 0
|
||||
#define MAC_RQC0R_RXQ0EN_LEN 2
|
||||
#define MAC_RSSAR_ADDRT_POS 2
|
||||
#define MAC_RSSAR_ADDRT_LEN 1
|
||||
#define MAC_RSSAR_CT_POS 1
|
||||
#define MAC_RSSAR_CT_LEN 1
|
||||
#define MAC_RSSAR_OB_POS 0
|
||||
#define MAC_RSSAR_OB_LEN 1
|
||||
#define MAC_RSSAR_RSSIA_POS 8
|
||||
#define MAC_RSSAR_RSSIA_LEN 8
|
||||
#define MAC_RSSCR_IP2TE_POS 1
|
||||
#define MAC_RSSCR_IP2TE_LEN 1
|
||||
#define MAC_RSSCR_RSSE_POS 0
|
||||
#define MAC_RSSCR_RSSE_LEN 1
|
||||
#define MAC_RSSCR_TCP4TE_POS 2
|
||||
#define MAC_RSSCR_TCP4TE_LEN 1
|
||||
#define MAC_RSSCR_UDP4TE_POS 3
|
||||
#define MAC_RSSCR_UDP4TE_LEN 1
|
||||
#define MAC_RSSDR_DMCH_POS 0
|
||||
#define MAC_RSSDR_DMCH_LEN 4
|
||||
#define MAC_TCR_SS_POS 28
|
||||
#define MAC_TCR_SS_LEN 3
|
||||
#define MAC_TCR_TE_POS 0
|
||||
#define MAC_TCR_TE_LEN 1
|
||||
#define MAC_VLANHTR_VLHT_POS 0
|
||||
#define MAC_VLANHTR_VLHT_LEN 16
|
||||
#define MAC_VLANIR_VLTI_POS 20
|
||||
#define MAC_VLANIR_VLTI_LEN 1
|
||||
#define MAC_VLANIR_CSVL_POS 19
|
||||
#define MAC_VLANIR_CSVL_LEN 1
|
||||
#define MAC_VLANTR_DOVLTC_POS 20
|
||||
#define MAC_VLANTR_DOVLTC_LEN 1
|
||||
#define MAC_VLANTR_ERSVLM_POS 19
|
||||
#define MAC_VLANTR_ERSVLM_LEN 1
|
||||
#define MAC_VLANTR_ESVL_POS 18
|
||||
#define MAC_VLANTR_ESVL_LEN 1
|
||||
#define MAC_VLANTR_ETV_POS 16
|
||||
#define MAC_VLANTR_ETV_LEN 1
|
||||
#define MAC_VLANTR_EVLS_POS 21
|
||||
#define MAC_VLANTR_EVLS_LEN 2
|
||||
#define MAC_VLANTR_EVLRXS_POS 24
|
||||
#define MAC_VLANTR_EVLRXS_LEN 1
|
||||
#define MAC_VLANTR_VL_POS 0
|
||||
#define MAC_VLANTR_VL_LEN 16
|
||||
#define MAC_VLANTR_VTHM_POS 25
|
||||
#define MAC_VLANTR_VTHM_LEN 1
|
||||
#define MAC_VLANTR_VTIM_POS 17
|
||||
#define MAC_VLANTR_VTIM_LEN 1
|
||||
#define MAC_VR_DEVID_POS 8
|
||||
#define MAC_VR_DEVID_LEN 8
|
||||
#define MAC_VR_SNPSVER_POS 0
|
||||
#define MAC_VR_SNPSVER_LEN 8
|
||||
#define MAC_VR_USERVER_POS 16
|
||||
#define MAC_VR_USERVER_LEN 8
|
||||
|
||||
/* MMC register offsets */
|
||||
#define MMC_CR 0x0800
|
||||
#define MMC_RISR 0x0804
|
||||
#define MMC_TISR 0x0808
|
||||
#define MMC_RIER 0x080c
|
||||
#define MMC_TIER 0x0810
|
||||
#define MMC_TXOCTETCOUNT_GB_LO 0x0814
|
||||
#define MMC_TXFRAMECOUNT_GB_LO 0x081c
|
||||
#define MMC_TXBROADCASTFRAMES_G_LO 0x0824
|
||||
#define MMC_TXMULTICASTFRAMES_G_LO 0x082c
|
||||
#define MMC_TX64OCTETS_GB_LO 0x0834
|
||||
#define MMC_TX65TO127OCTETS_GB_LO 0x083c
|
||||
#define MMC_TX128TO255OCTETS_GB_LO 0x0844
|
||||
#define MMC_TX256TO511OCTETS_GB_LO 0x084c
|
||||
#define MMC_TX512TO1023OCTETS_GB_LO 0x0854
|
||||
#define MMC_TX1024TOMAXOCTETS_GB_LO 0x085c
|
||||
#define MMC_TXUNICASTFRAMES_GB_LO 0x0864
|
||||
#define MMC_TXMULTICASTFRAMES_GB_LO 0x086c
|
||||
#define MMC_TXBROADCASTFRAMES_GB_LO 0x0874
|
||||
#define MMC_TXUNDERFLOWERROR_LO 0x087c
|
||||
#define MMC_TXOCTETCOUNT_G_LO 0x0884
|
||||
#define MMC_TXFRAMECOUNT_G_LO 0x088c
|
||||
#define MMC_TXPAUSEFRAMES_LO 0x0894
|
||||
#define MMC_TXVLANFRAMES_G_LO 0x089c
|
||||
#define MMC_RXFRAMECOUNT_GB_LO 0x0900
|
||||
#define MMC_RXOCTETCOUNT_GB_LO 0x0908
|
||||
#define MMC_RXOCTETCOUNT_G_LO 0x0910
|
||||
#define MMC_RXBROADCASTFRAMES_G_LO 0x0918
|
||||
#define MMC_RXMULTICASTFRAMES_G_LO 0x0920
|
||||
#define MMC_RXCRCERROR_LO 0x0928
|
||||
#define MMC_RXRUNTERROR 0x0930
|
||||
#define MMC_RXJABBERERROR 0x0934
|
||||
#define MMC_RXUNDERSIZE_G 0x0938
|
||||
#define MMC_RXOVERSIZE_G 0x093c
|
||||
#define MMC_RX64OCTETS_GB_LO 0x0940
|
||||
#define MMC_RX65TO127OCTETS_GB_LO 0x0948
|
||||
#define MMC_RX128TO255OCTETS_GB_LO 0x0950
|
||||
#define MMC_RX256TO511OCTETS_GB_LO 0x0958
|
||||
#define MMC_RX512TO1023OCTETS_GB_LO 0x0960
|
||||
#define MMC_RX1024TOMAXOCTETS_GB_LO 0x0968
|
||||
#define MMC_RXUNICASTFRAMES_G_LO 0x0970
|
||||
#define MMC_RXLENGTHERROR_LO 0x0978
|
||||
#define MMC_RXOUTOFRANGETYPE_LO 0x0980
|
||||
#define MMC_RXPAUSEFRAMES_LO 0x0988
|
||||
#define MMC_RXFIFOOVERFLOW_LO 0x0990
|
||||
#define MMC_RXVLANFRAMES_GB_LO 0x0998
|
||||
#define MMC_RXWATCHDOGERROR 0x09a0
|
||||
|
||||
/* MMC register entry bit positions and sizes */
|
||||
#define MMC_CR_CR_POS 0
|
||||
#define MMC_CR_CR_LEN 1
|
||||
#define MMC_CR_CSR_POS 1
|
||||
#define MMC_CR_CSR_LEN 1
|
||||
#define MMC_CR_ROR_POS 2
|
||||
#define MMC_CR_ROR_LEN 1
|
||||
#define MMC_CR_MCF_POS 3
|
||||
#define MMC_CR_MCF_LEN 1
|
||||
#define MMC_CR_MCT_POS 4
|
||||
#define MMC_CR_MCT_LEN 2
|
||||
#define MMC_RIER_ALL_INTERRUPTS_POS 0
|
||||
#define MMC_RIER_ALL_INTERRUPTS_LEN 23
|
||||
#define MMC_RISR_RXFRAMECOUNT_GB_POS 0
|
||||
#define MMC_RISR_RXFRAMECOUNT_GB_LEN 1
|
||||
#define MMC_RISR_RXOCTETCOUNT_GB_POS 1
|
||||
#define MMC_RISR_RXOCTETCOUNT_GB_LEN 1
|
||||
#define MMC_RISR_RXOCTETCOUNT_G_POS 2
|
||||
#define MMC_RISR_RXOCTETCOUNT_G_LEN 1
|
||||
#define MMC_RISR_RXBROADCASTFRAMES_G_POS 3
|
||||
#define MMC_RISR_RXBROADCASTFRAMES_G_LEN 1
|
||||
#define MMC_RISR_RXMULTICASTFRAMES_G_POS 4
|
||||
#define MMC_RISR_RXMULTICASTFRAMES_G_LEN 1
|
||||
#define MMC_RISR_RXCRCERROR_POS 5
|
||||
#define MMC_RISR_RXCRCERROR_LEN 1
|
||||
#define MMC_RISR_RXRUNTERROR_POS 6
|
||||
#define MMC_RISR_RXRUNTERROR_LEN 1
|
||||
#define MMC_RISR_RXJABBERERROR_POS 7
|
||||
#define MMC_RISR_RXJABBERERROR_LEN 1
|
||||
#define MMC_RISR_RXUNDERSIZE_G_POS 8
|
||||
#define MMC_RISR_RXUNDERSIZE_G_LEN 1
|
||||
#define MMC_RISR_RXOVERSIZE_G_POS 9
|
||||
#define MMC_RISR_RXOVERSIZE_G_LEN 1
|
||||
#define MMC_RISR_RX64OCTETS_GB_POS 10
|
||||
#define MMC_RISR_RX64OCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RX65TO127OCTETS_GB_POS 11
|
||||
#define MMC_RISR_RX65TO127OCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RX128TO255OCTETS_GB_POS 12
|
||||
#define MMC_RISR_RX128TO255OCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RX256TO511OCTETS_GB_POS 13
|
||||
#define MMC_RISR_RX256TO511OCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RX512TO1023OCTETS_GB_POS 14
|
||||
#define MMC_RISR_RX512TO1023OCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RX1024TOMAXOCTETS_GB_POS 15
|
||||
#define MMC_RISR_RX1024TOMAXOCTETS_GB_LEN 1
|
||||
#define MMC_RISR_RXUNICASTFRAMES_G_POS 16
|
||||
#define MMC_RISR_RXUNICASTFRAMES_G_LEN 1
|
||||
#define MMC_RISR_RXLENGTHERROR_POS 17
|
||||
#define MMC_RISR_RXLENGTHERROR_LEN 1
|
||||
#define MMC_RISR_RXOUTOFRANGETYPE_POS 18
|
||||
#define MMC_RISR_RXOUTOFRANGETYPE_LEN 1
|
||||
#define MMC_RISR_RXPAUSEFRAMES_POS 19
|
||||
#define MMC_RISR_RXPAUSEFRAMES_LEN 1
|
||||
#define MMC_RISR_RXFIFOOVERFLOW_POS 20
|
||||
#define MMC_RISR_RXFIFOOVERFLOW_LEN 1
|
||||
#define MMC_RISR_RXVLANFRAMES_GB_POS 21
|
||||
#define MMC_RISR_RXVLANFRAMES_GB_LEN 1
|
||||
#define MMC_RISR_RXWATCHDOGERROR_POS 22
|
||||
#define MMC_RISR_RXWATCHDOGERROR_LEN 1
|
||||
#define MMC_TIER_ALL_INTERRUPTS_POS 0
|
||||
#define MMC_TIER_ALL_INTERRUPTS_LEN 18
|
||||
#define MMC_TISR_TXOCTETCOUNT_GB_POS 0
|
||||
#define MMC_TISR_TXOCTETCOUNT_GB_LEN 1
|
||||
#define MMC_TISR_TXFRAMECOUNT_GB_POS 1
|
||||
#define MMC_TISR_TXFRAMECOUNT_GB_LEN 1
|
||||
#define MMC_TISR_TXBROADCASTFRAMES_G_POS 2
|
||||
#define MMC_TISR_TXBROADCASTFRAMES_G_LEN 1
|
||||
#define MMC_TISR_TXMULTICASTFRAMES_G_POS 3
|
||||
#define MMC_TISR_TXMULTICASTFRAMES_G_LEN 1
|
||||
#define MMC_TISR_TX64OCTETS_GB_POS 4
|
||||
#define MMC_TISR_TX64OCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TX65TO127OCTETS_GB_POS 5
|
||||
#define MMC_TISR_TX65TO127OCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TX128TO255OCTETS_GB_POS 6
|
||||
#define MMC_TISR_TX128TO255OCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TX256TO511OCTETS_GB_POS 7
|
||||
#define MMC_TISR_TX256TO511OCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TX512TO1023OCTETS_GB_POS 8
|
||||
#define MMC_TISR_TX512TO1023OCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TX1024TOMAXOCTETS_GB_POS 9
|
||||
#define MMC_TISR_TX1024TOMAXOCTETS_GB_LEN 1
|
||||
#define MMC_TISR_TXUNICASTFRAMES_GB_POS 10
|
||||
#define MMC_TISR_TXUNICASTFRAMES_GB_LEN 1
|
||||
#define MMC_TISR_TXMULTICASTFRAMES_GB_POS 11
|
||||
#define MMC_TISR_TXMULTICASTFRAMES_GB_LEN 1
|
||||
#define MMC_TISR_TXBROADCASTFRAMES_GB_POS 12
|
||||
#define MMC_TISR_TXBROADCASTFRAMES_GB_LEN 1
|
||||
#define MMC_TISR_TXUNDERFLOWERROR_POS 13
|
||||
#define MMC_TISR_TXUNDERFLOWERROR_LEN 1
|
||||
#define MMC_TISR_TXOCTETCOUNT_G_POS 14
|
||||
#define MMC_TISR_TXOCTETCOUNT_G_LEN 1
|
||||
#define MMC_TISR_TXFRAMECOUNT_G_POS 15
|
||||
#define MMC_TISR_TXFRAMECOUNT_G_LEN 1
|
||||
#define MMC_TISR_TXPAUSEFRAMES_POS 16
|
||||
#define MMC_TISR_TXPAUSEFRAMES_LEN 1
|
||||
#define MMC_TISR_TXVLANFRAMES_G_POS 17
|
||||
#define MMC_TISR_TXVLANFRAMES_G_LEN 1
|
||||
|
||||
/* MTL register offsets */
|
||||
#define MTL_OMR 0x1000
|
||||
#define MTL_FDDR 0x1010
|
||||
#define MTL_RQDCM0R 0x1030
|
||||
|
||||
#define MTL_RQDCM_INC 4
|
||||
#define MTL_RQDCM_Q_PER_REG 4
|
||||
|
||||
/* MTL register entry bit positions and sizes */
|
||||
#define MTL_OMR_ETSALG_POS 5
|
||||
#define MTL_OMR_ETSALG_LEN 2
|
||||
#define MTL_OMR_RAA_POS 2
|
||||
#define MTL_OMR_RAA_LEN 1
|
||||
|
||||
/* MTL queue register offsets
|
||||
* Multiple queues can be active. The first queue has registers
|
||||
* that begin at 0x1100. Each subsequent queue has registers that
|
||||
* are accessed using an offset of 0x80 from the previous queue.
|
||||
*/
|
||||
#define MTL_Q_BASE 0x1100
|
||||
#define MTL_Q_INC 0x80
|
||||
|
||||
#define MTL_Q_TQOMR 0x00
|
||||
#define MTL_Q_RQOMR 0x40
|
||||
#define MTL_Q_RQDR 0x48
|
||||
#define MTL_Q_RQFCR 0x50
|
||||
#define MTL_Q_IER 0x70
|
||||
#define MTL_Q_ISR 0x74
|
||||
|
||||
/* MTL queue register entry bit positions and sizes */
|
||||
#define MTL_Q_RQDR_PRXQ_POS 16
|
||||
#define MTL_Q_RQDR_PRXQ_LEN 14
|
||||
#define MTL_Q_RQDR_RXQSTS_POS 4
|
||||
#define MTL_Q_RQDR_RXQSTS_LEN 2
|
||||
#define MTL_Q_RQFCR_RFA_POS 1
|
||||
#define MTL_Q_RQFCR_RFA_LEN 6
|
||||
#define MTL_Q_RQFCR_RFD_POS 17
|
||||
#define MTL_Q_RQFCR_RFD_LEN 6
|
||||
#define MTL_Q_RQOMR_EHFC_POS 7
|
||||
#define MTL_Q_RQOMR_EHFC_LEN 1
|
||||
#define MTL_Q_RQOMR_RQS_POS 16
|
||||
#define MTL_Q_RQOMR_RQS_LEN 9
|
||||
#define MTL_Q_RQOMR_RSF_POS 5
|
||||
#define MTL_Q_RQOMR_RSF_LEN 1
|
||||
#define MTL_Q_RQOMR_FEP_POS 4
|
||||
#define MTL_Q_RQOMR_FEP_LEN 1
|
||||
#define MTL_Q_RQOMR_FUP_POS 3
|
||||
#define MTL_Q_RQOMR_FUP_LEN 1
|
||||
#define MTL_Q_RQOMR_RTC_POS 0
|
||||
#define MTL_Q_RQOMR_RTC_LEN 2
|
||||
#define MTL_Q_TQOMR_FTQ_POS 0
|
||||
#define MTL_Q_TQOMR_FTQ_LEN 1
|
||||
#define MTL_Q_TQOMR_Q2TCMAP_POS 8
|
||||
#define MTL_Q_TQOMR_Q2TCMAP_LEN 3
|
||||
#define MTL_Q_TQOMR_TQS_POS 16
|
||||
#define MTL_Q_TQOMR_TQS_LEN 10
|
||||
#define MTL_Q_TQOMR_TSF_POS 1
|
||||
#define MTL_Q_TQOMR_TSF_LEN 1
|
||||
#define MTL_Q_TQOMR_TTC_POS 4
|
||||
#define MTL_Q_TQOMR_TTC_LEN 3
|
||||
#define MTL_Q_TQOMR_TXQEN_POS 2
|
||||
#define MTL_Q_TQOMR_TXQEN_LEN 2
|
||||
|
||||
/* MTL queue register value */
|
||||
#define MTL_RSF_DISABLE 0x00
|
||||
#define MTL_RSF_ENABLE 0x01
|
||||
#define MTL_TSF_DISABLE 0x00
|
||||
#define MTL_TSF_ENABLE 0x01
|
||||
|
||||
#define MTL_RX_THRESHOLD_64 0x00
|
||||
#define MTL_RX_THRESHOLD_96 0x02
|
||||
#define MTL_RX_THRESHOLD_128 0x03
|
||||
#define MTL_TX_THRESHOLD_64 0x00
|
||||
#define MTL_TX_THRESHOLD_96 0x02
|
||||
#define MTL_TX_THRESHOLD_128 0x03
|
||||
#define MTL_TX_THRESHOLD_192 0x04
|
||||
#define MTL_TX_THRESHOLD_256 0x05
|
||||
#define MTL_TX_THRESHOLD_384 0x06
|
||||
#define MTL_TX_THRESHOLD_512 0x07
|
||||
|
||||
#define MTL_ETSALG_WRR 0x00
|
||||
#define MTL_ETSALG_WFQ 0x01
|
||||
#define MTL_ETSALG_DWRR 0x02
|
||||
#define MTL_RAA_SP 0x00
|
||||
#define MTL_RAA_WSP 0x01
|
||||
|
||||
#define MTL_Q_DISABLED 0x00
|
||||
#define MTL_Q_ENABLED 0x02
|
||||
|
||||
#define MTL_RQDCM0R_Q0MDMACH 0x0
|
||||
#define MTL_RQDCM0R_Q1MDMACH 0x00000100
|
||||
#define MTL_RQDCM0R_Q2MDMACH 0x00020000
|
||||
#define MTL_RQDCM0R_Q3MDMACH 0x03000000
|
||||
#define MTL_RQDCM1R_Q4MDMACH 0x00000004
|
||||
#define MTL_RQDCM1R_Q5MDMACH 0x00000500
|
||||
#define MTL_RQDCM1R_Q6MDMACH 0x00060000
|
||||
#define MTL_RQDCM1R_Q7MDMACH 0x07000000
|
||||
#define MTL_RQDCM2R_Q8MDMACH 0x00000008
|
||||
#define MTL_RQDCM2R_Q9MDMACH 0x00000900
|
||||
#define MTL_RQDCM2R_Q10MDMACH 0x000A0000
|
||||
#define MTL_RQDCM2R_Q11MDMACH 0x0B000000
|
||||
|
||||
/* MTL traffic class register offsets
|
||||
* Multiple traffic classes can be active. The first class has registers
|
||||
* that begin at 0x1100. Each subsequent queue has registers that
|
||||
* are accessed using an offset of 0x80 from the previous queue.
|
||||
*/
|
||||
#define MTL_TC_BASE MTL_Q_BASE
|
||||
#define MTL_TC_INC MTL_Q_INC
|
||||
|
||||
#define MTL_TC_ETSCR 0x10
|
||||
#define MTL_TC_ETSSR 0x14
|
||||
#define MTL_TC_QWR 0x18
|
||||
|
||||
/* MTL traffic class register entry bit positions and sizes */
|
||||
#define MTL_TC_ETSCR_TSA_POS 0
|
||||
#define MTL_TC_ETSCR_TSA_LEN 2
|
||||
#define MTL_TC_QWR_QW_POS 0
|
||||
#define MTL_TC_QWR_QW_LEN 21
|
||||
|
||||
/* MTL traffic class register value */
|
||||
#define MTL_TSA_SP 0x00
|
||||
#define MTL_TSA_ETS 0x02
|
||||
|
||||
/* DMA register offsets */
|
||||
#define DMA_MR 0x3000
|
||||
#define DMA_SBMR 0x3004
|
||||
#define DMA_ISR 0x3008
|
||||
#define DMA_DSR0 0x3020
|
||||
#define DMA_DSR1 0x3024
|
||||
|
||||
/* DMA register entry bit positions and sizes */
|
||||
#define DMA_ISR_MACIS_POS 17
|
||||
#define DMA_ISR_MACIS_LEN 1
|
||||
#define DMA_ISR_MTLIS_POS 16
|
||||
#define DMA_ISR_MTLIS_LEN 1
|
||||
#define DMA_MR_SWR_POS 0
|
||||
#define DMA_MR_SWR_LEN 1
|
||||
#define DMA_SBMR_EAME_POS 11
|
||||
#define DMA_SBMR_EAME_LEN 1
|
||||
#define DMA_SBMR_BLEN_64_POS 5
|
||||
#define DMA_SBMR_BLEN_64_LEN 1
|
||||
#define DMA_SBMR_BLEN_128_POS 6
|
||||
#define DMA_SBMR_BLEN_128_LEN 1
|
||||
#define DMA_SBMR_BLEN_256_POS 7
|
||||
#define DMA_SBMR_BLEN_256_LEN 1
|
||||
#define DMA_SBMR_UNDEF_POS 0
|
||||
#define DMA_SBMR_UNDEF_LEN 1
|
||||
|
||||
/* DMA register values */
|
||||
#define DMA_DSR_RPS_LEN 4
|
||||
#define DMA_DSR_TPS_LEN 4
|
||||
#define DMA_DSR_Q_LEN (DMA_DSR_RPS_LEN + DMA_DSR_TPS_LEN)
|
||||
#define DMA_DSR0_TPS_START 12
|
||||
#define DMA_DSRX_FIRST_QUEUE 3
|
||||
#define DMA_DSRX_INC 4
|
||||
#define DMA_DSRX_QPR 4
|
||||
#define DMA_DSRX_TPS_START 4
|
||||
#define DMA_TPS_STOPPED 0x00
|
||||
#define DMA_TPS_SUSPENDED 0x06
|
||||
|
||||
/* DMA channel register offsets
|
||||
* Multiple channels can be active. The first channel has registers
|
||||
* that begin at 0x3100. Each subsequent channel has registers that
|
||||
* are accessed using an offset of 0x80 from the previous channel.
|
||||
*/
|
||||
#define DMA_CH_BASE 0x3100
|
||||
#define DMA_CH_INC 0x80
|
||||
|
||||
#define DMA_CH_CR 0x00
|
||||
#define DMA_CH_TCR 0x04
|
||||
#define DMA_CH_RCR 0x08
|
||||
#define DMA_CH_TDLR_HI 0x10
|
||||
#define DMA_CH_TDLR_LO 0x14
|
||||
#define DMA_CH_RDLR_HI 0x18
|
||||
#define DMA_CH_RDLR_LO 0x1c
|
||||
#define DMA_CH_TDTR_LO 0x24
|
||||
#define DMA_CH_RDTR_LO 0x2c
|
||||
#define DMA_CH_TDRLR 0x30
|
||||
#define DMA_CH_RDRLR 0x34
|
||||
#define DMA_CH_IER 0x38
|
||||
#define DMA_CH_RIWT 0x3c
|
||||
#define DMA_CH_SR 0x60
|
||||
|
||||
/* DMA channel register entry bit positions and sizes */
|
||||
#define DMA_CH_CR_PBLX8_POS 16
|
||||
#define DMA_CH_CR_PBLX8_LEN 1
|
||||
#define DMA_CH_CR_SPH_POS 24
|
||||
#define DMA_CH_CR_SPH_LEN 1
|
||||
#define DMA_CH_IER_AIE_POS 15
|
||||
#define DMA_CH_IER_AIE_LEN 1
|
||||
#define DMA_CH_IER_FBEE_POS 12
|
||||
#define DMA_CH_IER_FBEE_LEN 1
|
||||
#define DMA_CH_IER_NIE_POS 16
|
||||
#define DMA_CH_IER_NIE_LEN 1
|
||||
#define DMA_CH_IER_RBUE_POS 7
|
||||
#define DMA_CH_IER_RBUE_LEN 1
|
||||
#define DMA_CH_IER_RIE_POS 6
|
||||
#define DMA_CH_IER_RIE_LEN 1
|
||||
#define DMA_CH_IER_RSE_POS 8
|
||||
#define DMA_CH_IER_RSE_LEN 1
|
||||
#define DMA_CH_IER_TBUE_POS 2
|
||||
#define DMA_CH_IER_TBUE_LEN 1
|
||||
#define DMA_CH_IER_TIE_POS 0
|
||||
#define DMA_CH_IER_TIE_LEN 1
|
||||
#define DMA_CH_IER_TXSE_POS 1
|
||||
#define DMA_CH_IER_TXSE_LEN 1
|
||||
#define DMA_CH_RCR_PBL_POS 16
|
||||
#define DMA_CH_RCR_PBL_LEN 6
|
||||
#define DMA_CH_RCR_RBSZ_POS 1
|
||||
#define DMA_CH_RCR_RBSZ_LEN 14
|
||||
#define DMA_CH_RCR_SR_POS 0
|
||||
#define DMA_CH_RCR_SR_LEN 1
|
||||
#define DMA_CH_RIWT_RWT_POS 0
|
||||
#define DMA_CH_RIWT_RWT_LEN 8
|
||||
#define DMA_CH_SR_FBE_POS 12
|
||||
#define DMA_CH_SR_FBE_LEN 1
|
||||
#define DMA_CH_SR_RBU_POS 7
|
||||
#define DMA_CH_SR_RBU_LEN 1
|
||||
#define DMA_CH_SR_RI_POS 6
|
||||
#define DMA_CH_SR_RI_LEN 1
|
||||
#define DMA_CH_SR_RPS_POS 8
|
||||
#define DMA_CH_SR_RPS_LEN 1
|
||||
#define DMA_CH_SR_TBU_POS 2
|
||||
#define DMA_CH_SR_TBU_LEN 1
|
||||
#define DMA_CH_SR_TI_POS 0
|
||||
#define DMA_CH_SR_TI_LEN 1
|
||||
#define DMA_CH_SR_TPS_POS 1
|
||||
#define DMA_CH_SR_TPS_LEN 1
|
||||
#define DMA_CH_TCR_OSP_POS 4
|
||||
#define DMA_CH_TCR_OSP_LEN 1
|
||||
#define DMA_CH_TCR_PBL_POS 16
|
||||
#define DMA_CH_TCR_PBL_LEN 6
|
||||
#define DMA_CH_TCR_ST_POS 0
|
||||
#define DMA_CH_TCR_ST_LEN 1
|
||||
#define DMA_CH_TCR_TSE_POS 12
|
||||
#define DMA_CH_TCR_TSE_LEN 1
|
||||
|
||||
/* DMA channel register values */
|
||||
#define DMA_OSP_DISABLE 0x00
|
||||
#define DMA_OSP_ENABLE 0x01
|
||||
#define DMA_PBL_1 1
|
||||
#define DMA_PBL_2 2
|
||||
#define DMA_PBL_4 4
|
||||
#define DMA_PBL_8 8
|
||||
#define DMA_PBL_16 16
|
||||
#define DMA_PBL_32 32
|
||||
#define DMA_PBL_64 64
|
||||
#define DMA_PBL_128 128
|
||||
#define DMA_PBL_256 256
|
||||
#define DMA_PBL_X8_DISABLE 0x00
|
||||
#define DMA_PBL_X8_ENABLE 0x01
|
||||
|
||||
/* Descriptor/Packet entry bit positions and sizes */
|
||||
#define RX_PACKET_ERRORS_CRC_POS 2
|
||||
#define RX_PACKET_ERRORS_CRC_LEN 1
|
||||
#define RX_PACKET_ERRORS_FRAME_POS 3
|
||||
#define RX_PACKET_ERRORS_FRAME_LEN 1
|
||||
#define RX_PACKET_ERRORS_LENGTH_POS 0
|
||||
#define RX_PACKET_ERRORS_LENGTH_LEN 1
|
||||
#define RX_PACKET_ERRORS_OVERRUN_POS 1
|
||||
#define RX_PACKET_ERRORS_OVERRUN_LEN 1
|
||||
|
||||
#define RX_PACKET_ATTRIBUTES_CSUM_DONE_POS 0
|
||||
#define RX_PACKET_ATTRIBUTES_CSUM_DONE_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_POS 1
|
||||
#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_POS 2
|
||||
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_POS 3
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_POS 4
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_POS 5
|
||||
#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_LEN 1
|
||||
#define RX_PACKET_ATTRIBUTES_RSS_HASH_POS 6
|
||||
#define RX_PACKET_ATTRIBUTES_RSS_HASH_LEN 1
|
||||
|
||||
#define RX_NORMAL_DESC0_OVT_POS 0
|
||||
#define RX_NORMAL_DESC0_OVT_LEN 16
|
||||
#define RX_NORMAL_DESC2_HL_POS 0
|
||||
#define RX_NORMAL_DESC2_HL_LEN 10
|
||||
#define RX_NORMAL_DESC3_CDA_POS 27
|
||||
#define RX_NORMAL_DESC3_CDA_LEN 1
|
||||
#define RX_NORMAL_DESC3_CTXT_POS 30
|
||||
#define RX_NORMAL_DESC3_CTXT_LEN 1
|
||||
#define RX_NORMAL_DESC3_ES_POS 15
|
||||
#define RX_NORMAL_DESC3_ES_LEN 1
|
||||
#define RX_NORMAL_DESC3_ETLT_POS 16
|
||||
#define RX_NORMAL_DESC3_ETLT_LEN 4
|
||||
#define RX_NORMAL_DESC3_FD_POS 29
|
||||
#define RX_NORMAL_DESC3_FD_LEN 1
|
||||
#define RX_NORMAL_DESC3_INTE_POS 30
|
||||
#define RX_NORMAL_DESC3_INTE_LEN 1
|
||||
#define RX_NORMAL_DESC3_L34T_POS 20
|
||||
#define RX_NORMAL_DESC3_L34T_LEN 4
|
||||
#define RX_NORMAL_DESC3_LD_POS 28
|
||||
#define RX_NORMAL_DESC3_LD_LEN 1
|
||||
#define RX_NORMAL_DESC3_OWN_POS 31
|
||||
#define RX_NORMAL_DESC3_OWN_LEN 1
|
||||
#define RX_NORMAL_DESC3_PL_POS 0
|
||||
#define RX_NORMAL_DESC3_PL_LEN 14
|
||||
#define RX_NORMAL_DESC3_RSV_POS 26
|
||||
#define RX_NORMAL_DESC3_RSV_LEN 1
|
||||
|
||||
#define RX_DESC3_L34T_IPV4_TCP 1
|
||||
#define RX_DESC3_L34T_IPV4_UDP 2
|
||||
#define RX_DESC3_L34T_IPV4_ICMP 3
|
||||
#define RX_DESC3_L34T_IPV6_TCP 9
|
||||
#define RX_DESC3_L34T_IPV6_UDP 10
|
||||
#define RX_DESC3_L34T_IPV6_ICMP 11
|
||||
|
||||
#define RX_CONTEXT_DESC3_TSA_POS 4
|
||||
#define RX_CONTEXT_DESC3_TSA_LEN 1
|
||||
#define RX_CONTEXT_DESC3_TSD_POS 6
|
||||
#define RX_CONTEXT_DESC3_TSD_LEN 1
|
||||
|
||||
#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_POS 0
|
||||
#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_LEN 1
|
||||
#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_POS 1
|
||||
#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_LEN 1
|
||||
#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_POS 2
|
||||
#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN 1
|
||||
#define TX_PACKET_ATTRIBUTES_PTP_POS 3
|
||||
#define TX_PACKET_ATTRIBUTES_PTP_LEN 1
|
||||
|
||||
#define TX_CONTEXT_DESC2_MSS_POS 0
|
||||
#define TX_CONTEXT_DESC2_MSS_LEN 15
|
||||
#define TX_CONTEXT_DESC3_CTXT_POS 30
|
||||
#define TX_CONTEXT_DESC3_CTXT_LEN 1
|
||||
#define TX_CONTEXT_DESC3_TCMSSV_POS 26
|
||||
#define TX_CONTEXT_DESC3_TCMSSV_LEN 1
|
||||
#define TX_CONTEXT_DESC3_VLTV_POS 16
|
||||
#define TX_CONTEXT_DESC3_VLTV_LEN 1
|
||||
#define TX_CONTEXT_DESC3_VT_POS 0
|
||||
#define TX_CONTEXT_DESC3_VT_LEN 16
|
||||
|
||||
#define TX_NORMAL_DESC2_HL_B1L_POS 0
|
||||
#define TX_NORMAL_DESC2_HL_B1L_LEN 14
|
||||
#define TX_NORMAL_DESC2_IC_POS 31
|
||||
#define TX_NORMAL_DESC2_IC_LEN 1
|
||||
#define TX_NORMAL_DESC2_TTSE_POS 30
|
||||
#define TX_NORMAL_DESC2_TTSE_LEN 1
|
||||
#define TX_NORMAL_DESC2_VTIR_POS 14
|
||||
#define TX_NORMAL_DESC2_VTIR_LEN 2
|
||||
#define TX_NORMAL_DESC3_CIC_POS 16
|
||||
#define TX_NORMAL_DESC3_CIC_LEN 2
|
||||
#define TX_NORMAL_DESC3_CPC_POS 26
|
||||
#define TX_NORMAL_DESC3_CPC_LEN 2
|
||||
#define TX_NORMAL_DESC3_CTXT_POS 30
|
||||
#define TX_NORMAL_DESC3_CTXT_LEN 1
|
||||
#define TX_NORMAL_DESC3_FD_POS 29
|
||||
#define TX_NORMAL_DESC3_FD_LEN 1
|
||||
#define TX_NORMAL_DESC3_FL_POS 0
|
||||
#define TX_NORMAL_DESC3_FL_LEN 15
|
||||
#define TX_NORMAL_DESC3_LD_POS 28
|
||||
#define TX_NORMAL_DESC3_LD_LEN 1
|
||||
#define TX_NORMAL_DESC3_OWN_POS 31
|
||||
#define TX_NORMAL_DESC3_OWN_LEN 1
|
||||
#define TX_NORMAL_DESC3_TCPHDRLEN_POS 19
|
||||
#define TX_NORMAL_DESC3_TCPHDRLEN_LEN 4
|
||||
#define TX_NORMAL_DESC3_TCPPL_POS 0
|
||||
#define TX_NORMAL_DESC3_TCPPL_LEN 18
|
||||
#define TX_NORMAL_DESC3_TSE_POS 18
|
||||
#define TX_NORMAL_DESC3_TSE_LEN 1
|
||||
|
||||
#define TX_NORMAL_DESC2_VLAN_INSERT 0x2
|
||||
|
||||
#define XLGMAC_MTL_REG(pdata, n, reg) \
|
||||
((pdata)->mac_regs + MTL_Q_BASE + ((n) * MTL_Q_INC) + (reg))
|
||||
|
||||
#define XLGMAC_DMA_REG(channel, reg) ((channel)->dma_regs + (reg))
|
||||
|
||||
#endif /* __DWC_XLGMAC_REG_H__ */
|
651
drivers/net/ethernet/synopsys/dwc-xlgmac.h
Normal file
651
drivers/net/ethernet/synopsys/dwc-xlgmac.h
Normal file
|
@ -0,0 +1,651 @@
|
|||
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||||
*
|
||||
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.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 Synopsys DWC XLGMAC software driver and associated documentation
|
||||
* (hereinafter the "Software") is an unsupported proprietary work of
|
||||
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||||
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||||
* Licensed Product under any End User Software License Agreement or
|
||||
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||||
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||||
* in the SOFTWARE may be the trademarks of their respective owners.
|
||||
*/
|
||||
|
||||
#ifndef __DWC_XLGMAC_H__
|
||||
#define __DWC_XLGMAC_H__
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/timecounter.h>
|
||||
|
||||
#define XLGMAC_DRV_NAME "dwc-xlgmac"
|
||||
#define XLGMAC_DRV_VERSION "1.0.0"
|
||||
#define XLGMAC_DRV_DESC "Synopsys DWC XLGMAC Driver"
|
||||
|
||||
/* Descriptor related parameters */
|
||||
#define XLGMAC_TX_DESC_CNT 1024
|
||||
#define XLGMAC_TX_DESC_MIN_FREE (XLGMAC_TX_DESC_CNT >> 3)
|
||||
#define XLGMAC_TX_DESC_MAX_PROC (XLGMAC_TX_DESC_CNT >> 1)
|
||||
#define XLGMAC_RX_DESC_CNT 1024
|
||||
#define XLGMAC_RX_DESC_MAX_DIRTY (XLGMAC_RX_DESC_CNT >> 3)
|
||||
|
||||
/* Descriptors required for maximum contiguous TSO/GSO packet */
|
||||
#define XLGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / XLGMAC_TX_MAX_BUF_SIZE) + 1)
|
||||
|
||||
/* Maximum possible descriptors needed for a SKB */
|
||||
#define XLGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + XLGMAC_TX_MAX_SPLIT + 2)
|
||||
|
||||
#define XLGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
|
||||
#define XLGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
|
||||
#define XLGMAC_RX_BUF_ALIGN 64
|
||||
|
||||
/* Maximum Size for Splitting the Header Data
|
||||
* Keep in sync with SKB_ALLOC_SIZE
|
||||
* 3'b000: 64 bytes, 3'b001: 128 bytes
|
||||
* 3'b010: 256 bytes, 3'b011: 512 bytes
|
||||
* 3'b100: 1023 bytes , 3'b101'3'b111: Reserved
|
||||
*/
|
||||
#define XLGMAC_SPH_HDSMS_SIZE 3
|
||||
#define XLGMAC_SKB_ALLOC_SIZE 512
|
||||
|
||||
#define XLGMAC_MAX_FIFO 81920
|
||||
|
||||
#define XLGMAC_MAX_DMA_CHANNELS 16
|
||||
#define XLGMAC_DMA_STOP_TIMEOUT 5
|
||||
#define XLGMAC_DMA_INTERRUPT_MASK 0x31c7
|
||||
|
||||
/* Default coalescing parameters */
|
||||
#define XLGMAC_INIT_DMA_TX_USECS 1000
|
||||
#define XLGMAC_INIT_DMA_TX_FRAMES 25
|
||||
#define XLGMAC_INIT_DMA_RX_USECS 30
|
||||
#define XLGMAC_INIT_DMA_RX_FRAMES 25
|
||||
|
||||
/* Flow control queue count */
|
||||
#define XLGMAC_MAX_FLOW_CONTROL_QUEUES 8
|
||||
|
||||
/* System clock is 125 MHz */
|
||||
#define XLGMAC_SYSCLOCK 125000000
|
||||
|
||||
/* Maximum MAC address hash table size (256 bits = 8 bytes) */
|
||||
#define XLGMAC_MAC_HASH_TABLE_SIZE 8
|
||||
|
||||
/* Receive Side Scaling */
|
||||
#define XLGMAC_RSS_HASH_KEY_SIZE 40
|
||||
#define XLGMAC_RSS_MAX_TABLE_SIZE 256
|
||||
#define XLGMAC_RSS_LOOKUP_TABLE_TYPE 0
|
||||
#define XLGMAC_RSS_HASH_KEY_TYPE 1
|
||||
|
||||
#define XLGMAC_STD_PACKET_MTU 1500
|
||||
#define XLGMAC_JUMBO_PACKET_MTU 9000
|
||||
|
||||
/* Helper macro for descriptor handling
|
||||
* Always use XLGMAC_GET_DESC_DATA to access the descriptor data
|
||||
*/
|
||||
#define XLGMAC_GET_DESC_DATA(ring, idx) ({ \
|
||||
typeof(ring) _ring = (ring); \
|
||||
((_ring)->desc_data_head + \
|
||||
((idx) & ((_ring)->dma_desc_count - 1))); \
|
||||
})
|
||||
|
||||
#define XLGMAC_GET_REG_BITS(var, pos, len) ({ \
|
||||
typeof(pos) _pos = (pos); \
|
||||
typeof(len) _len = (len); \
|
||||
((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
|
||||
})
|
||||
|
||||
#define XLGMAC_GET_REG_BITS_LE(var, pos, len) ({ \
|
||||
typeof(pos) _pos = (pos); \
|
||||
typeof(len) _len = (len); \
|
||||
typeof(var) _var = le32_to_cpu((var)); \
|
||||
((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
|
||||
})
|
||||
|
||||
#define XLGMAC_SET_REG_BITS(var, pos, len, val) ({ \
|
||||
typeof(var) _var = (var); \
|
||||
typeof(pos) _pos = (pos); \
|
||||
typeof(len) _len = (len); \
|
||||
typeof(val) _val = (val); \
|
||||
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
|
||||
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
|
||||
})
|
||||
|
||||
#define XLGMAC_SET_REG_BITS_LE(var, pos, len, val) ({ \
|
||||
typeof(var) _var = (var); \
|
||||
typeof(pos) _pos = (pos); \
|
||||
typeof(len) _len = (len); \
|
||||
typeof(val) _val = (val); \
|
||||
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
|
||||
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
|
||||
cpu_to_le32(_var); \
|
||||
})
|
||||
|
||||
struct xlgmac_pdata;
|
||||
|
||||
enum xlgmac_int {
|
||||
XLGMAC_INT_DMA_CH_SR_TI,
|
||||
XLGMAC_INT_DMA_CH_SR_TPS,
|
||||
XLGMAC_INT_DMA_CH_SR_TBU,
|
||||
XLGMAC_INT_DMA_CH_SR_RI,
|
||||
XLGMAC_INT_DMA_CH_SR_RBU,
|
||||
XLGMAC_INT_DMA_CH_SR_RPS,
|
||||
XLGMAC_INT_DMA_CH_SR_TI_RI,
|
||||
XLGMAC_INT_DMA_CH_SR_FBE,
|
||||
XLGMAC_INT_DMA_ALL,
|
||||
};
|
||||
|
||||
struct xlgmac_stats {
|
||||
/* MMC TX counters */
|
||||
u64 txoctetcount_gb;
|
||||
u64 txframecount_gb;
|
||||
u64 txbroadcastframes_g;
|
||||
u64 txmulticastframes_g;
|
||||
u64 tx64octets_gb;
|
||||
u64 tx65to127octets_gb;
|
||||
u64 tx128to255octets_gb;
|
||||
u64 tx256to511octets_gb;
|
||||
u64 tx512to1023octets_gb;
|
||||
u64 tx1024tomaxoctets_gb;
|
||||
u64 txunicastframes_gb;
|
||||
u64 txmulticastframes_gb;
|
||||
u64 txbroadcastframes_gb;
|
||||
u64 txunderflowerror;
|
||||
u64 txoctetcount_g;
|
||||
u64 txframecount_g;
|
||||
u64 txpauseframes;
|
||||
u64 txvlanframes_g;
|
||||
|
||||
/* MMC RX counters */
|
||||
u64 rxframecount_gb;
|
||||
u64 rxoctetcount_gb;
|
||||
u64 rxoctetcount_g;
|
||||
u64 rxbroadcastframes_g;
|
||||
u64 rxmulticastframes_g;
|
||||
u64 rxcrcerror;
|
||||
u64 rxrunterror;
|
||||
u64 rxjabbererror;
|
||||
u64 rxundersize_g;
|
||||
u64 rxoversize_g;
|
||||
u64 rx64octets_gb;
|
||||
u64 rx65to127octets_gb;
|
||||
u64 rx128to255octets_gb;
|
||||
u64 rx256to511octets_gb;
|
||||
u64 rx512to1023octets_gb;
|
||||
u64 rx1024tomaxoctets_gb;
|
||||
u64 rxunicastframes_g;
|
||||
u64 rxlengtherror;
|
||||
u64 rxoutofrangetype;
|
||||
u64 rxpauseframes;
|
||||
u64 rxfifooverflow;
|
||||
u64 rxvlanframes_gb;
|
||||
u64 rxwatchdogerror;
|
||||
|
||||
/* Extra counters */
|
||||
u64 tx_tso_packets;
|
||||
u64 rx_split_header_packets;
|
||||
u64 rx_buffer_unavailable;
|
||||
};
|
||||
|
||||
struct xlgmac_ring_buf {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t skb_dma;
|
||||
unsigned int skb_len;
|
||||
};
|
||||
|
||||
/* Common Tx and Rx DMA hardware descriptor */
|
||||
struct xlgmac_dma_desc {
|
||||
__le32 desc0;
|
||||
__le32 desc1;
|
||||
__le32 desc2;
|
||||
__le32 desc3;
|
||||
};
|
||||
|
||||
/* Page allocation related values */
|
||||
struct xlgmac_page_alloc {
|
||||
struct page *pages;
|
||||
unsigned int pages_len;
|
||||
unsigned int pages_offset;
|
||||
|
||||
dma_addr_t pages_dma;
|
||||
};
|
||||
|
||||
/* Ring entry buffer data */
|
||||
struct xlgmac_buffer_data {
|
||||
struct xlgmac_page_alloc pa;
|
||||
struct xlgmac_page_alloc pa_unmap;
|
||||
|
||||
dma_addr_t dma_base;
|
||||
unsigned long dma_off;
|
||||
unsigned int dma_len;
|
||||
};
|
||||
|
||||
/* Tx-related desc data */
|
||||
struct xlgmac_tx_desc_data {
|
||||
unsigned int packets; /* BQL packet count */
|
||||
unsigned int bytes; /* BQL byte count */
|
||||
};
|
||||
|
||||
/* Rx-related desc data */
|
||||
struct xlgmac_rx_desc_data {
|
||||
struct xlgmac_buffer_data hdr; /* Header locations */
|
||||
struct xlgmac_buffer_data buf; /* Payload locations */
|
||||
|
||||
unsigned short hdr_len; /* Length of received header */
|
||||
unsigned short len; /* Length of received packet */
|
||||
};
|
||||
|
||||
struct xlgmac_pkt_info {
|
||||
struct sk_buff *skb;
|
||||
|
||||
unsigned int attributes;
|
||||
|
||||
unsigned int errors;
|
||||
|
||||
/* descriptors needed for this packet */
|
||||
unsigned int desc_count;
|
||||
unsigned int length;
|
||||
|
||||
unsigned int tx_packets;
|
||||
unsigned int tx_bytes;
|
||||
|
||||
unsigned int header_len;
|
||||
unsigned int tcp_header_len;
|
||||
unsigned int tcp_payload_len;
|
||||
unsigned short mss;
|
||||
|
||||
unsigned short vlan_ctag;
|
||||
|
||||
u64 rx_tstamp;
|
||||
|
||||
u32 rss_hash;
|
||||
enum pkt_hash_types rss_hash_type;
|
||||
};
|
||||
|
||||
struct xlgmac_desc_data {
|
||||
/* dma_desc: Virtual address of descriptor
|
||||
* dma_desc_addr: DMA address of descriptor
|
||||
*/
|
||||
struct xlgmac_dma_desc *dma_desc;
|
||||
dma_addr_t dma_desc_addr;
|
||||
|
||||
/* skb: Virtual address of SKB
|
||||
* skb_dma: DMA address of SKB data
|
||||
* skb_dma_len: Length of SKB DMA area
|
||||
*/
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t skb_dma;
|
||||
unsigned int skb_dma_len;
|
||||
|
||||
/* Tx/Rx -related data */
|
||||
struct xlgmac_tx_desc_data tx;
|
||||
struct xlgmac_rx_desc_data rx;
|
||||
|
||||
unsigned int mapped_as_page;
|
||||
|
||||
/* Incomplete receive save location. If the budget is exhausted
|
||||
* or the last descriptor (last normal descriptor or a following
|
||||
* context descriptor) has not been DMA'd yet the current state
|
||||
* of the receive processing needs to be saved.
|
||||
*/
|
||||
unsigned int state_saved;
|
||||
struct {
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
unsigned int error;
|
||||
} state;
|
||||
};
|
||||
|
||||
struct xlgmac_ring {
|
||||
/* Per packet related information */
|
||||
struct xlgmac_pkt_info pkt_info;
|
||||
|
||||
/* Virtual/DMA addresses of DMA descriptor list and the total count */
|
||||
struct xlgmac_dma_desc *dma_desc_head;
|
||||
dma_addr_t dma_desc_head_addr;
|
||||
unsigned int dma_desc_count;
|
||||
|
||||
/* Array of descriptor data corresponding the DMA descriptor
|
||||
* (always use the XLGMAC_GET_DESC_DATA macro to access this data)
|
||||
*/
|
||||
struct xlgmac_desc_data *desc_data_head;
|
||||
|
||||
/* Page allocation for RX buffers */
|
||||
struct xlgmac_page_alloc rx_hdr_pa;
|
||||
struct xlgmac_page_alloc rx_buf_pa;
|
||||
|
||||
/* Ring index values
|
||||
* cur - Tx: index of descriptor to be used for current transfer
|
||||
* Rx: index of descriptor to check for packet availability
|
||||
* dirty - Tx: index of descriptor to check for transfer complete
|
||||
* Rx: index of descriptor to check for buffer reallocation
|
||||
*/
|
||||
unsigned int cur;
|
||||
unsigned int dirty;
|
||||
|
||||
/* Coalesce frame count used for interrupt bit setting */
|
||||
unsigned int coalesce_count;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int xmit_more;
|
||||
unsigned int queue_stopped;
|
||||
unsigned short cur_mss;
|
||||
unsigned short cur_vlan_ctag;
|
||||
} tx;
|
||||
};
|
||||
} ____cacheline_aligned;
|
||||
|
||||
struct xlgmac_channel {
|
||||
char name[16];
|
||||
|
||||
/* Address of private data area for device */
|
||||
struct xlgmac_pdata *pdata;
|
||||
|
||||
/* Queue index and base address of queue's DMA registers */
|
||||
unsigned int queue_index;
|
||||
void __iomem *dma_regs;
|
||||
|
||||
/* Per channel interrupt irq number */
|
||||
int dma_irq;
|
||||
char dma_irq_name[IFNAMSIZ + 32];
|
||||
|
||||
/* Netdev related settings */
|
||||
struct napi_struct napi;
|
||||
|
||||
unsigned int saved_ier;
|
||||
|
||||
unsigned int tx_timer_active;
|
||||
struct timer_list tx_timer;
|
||||
|
||||
struct xlgmac_ring *tx_ring;
|
||||
struct xlgmac_ring *rx_ring;
|
||||
} ____cacheline_aligned;
|
||||
|
||||
struct xlgmac_desc_ops {
|
||||
int (*alloc_channles_and_rings)(struct xlgmac_pdata *pdata);
|
||||
void (*free_channels_and_rings)(struct xlgmac_pdata *pdata);
|
||||
int (*map_tx_skb)(struct xlgmac_channel *channel,
|
||||
struct sk_buff *skb);
|
||||
int (*map_rx_buffer)(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
struct xlgmac_desc_data *desc_data);
|
||||
void (*unmap_desc_data)(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_desc_data *desc_data);
|
||||
void (*tx_desc_init)(struct xlgmac_pdata *pdata);
|
||||
void (*rx_desc_init)(struct xlgmac_pdata *pdata);
|
||||
};
|
||||
|
||||
struct xlgmac_hw_ops {
|
||||
int (*init)(struct xlgmac_pdata *pdata);
|
||||
int (*exit)(struct xlgmac_pdata *pdata);
|
||||
|
||||
int (*tx_complete)(struct xlgmac_dma_desc *dma_desc);
|
||||
|
||||
void (*enable_tx)(struct xlgmac_pdata *pdata);
|
||||
void (*disable_tx)(struct xlgmac_pdata *pdata);
|
||||
void (*enable_rx)(struct xlgmac_pdata *pdata);
|
||||
void (*disable_rx)(struct xlgmac_pdata *pdata);
|
||||
|
||||
int (*enable_int)(struct xlgmac_channel *channel,
|
||||
enum xlgmac_int int_id);
|
||||
int (*disable_int)(struct xlgmac_channel *channel,
|
||||
enum xlgmac_int int_id);
|
||||
void (*dev_xmit)(struct xlgmac_channel *channel);
|
||||
int (*dev_read)(struct xlgmac_channel *channel);
|
||||
|
||||
int (*set_mac_address)(struct xlgmac_pdata *pdata, u8 *addr);
|
||||
int (*config_rx_mode)(struct xlgmac_pdata *pdata);
|
||||
int (*enable_rx_csum)(struct xlgmac_pdata *pdata);
|
||||
int (*disable_rx_csum)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For MII speed configuration */
|
||||
int (*set_xlgmii_25000_speed)(struct xlgmac_pdata *pdata);
|
||||
int (*set_xlgmii_40000_speed)(struct xlgmac_pdata *pdata);
|
||||
int (*set_xlgmii_50000_speed)(struct xlgmac_pdata *pdata);
|
||||
int (*set_xlgmii_100000_speed)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For descriptor related operation */
|
||||
void (*tx_desc_init)(struct xlgmac_channel *channel);
|
||||
void (*rx_desc_init)(struct xlgmac_channel *channel);
|
||||
void (*tx_desc_reset)(struct xlgmac_desc_data *desc_data);
|
||||
void (*rx_desc_reset)(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_desc_data *desc_data,
|
||||
unsigned int index);
|
||||
int (*is_last_desc)(struct xlgmac_dma_desc *dma_desc);
|
||||
int (*is_context_desc)(struct xlgmac_dma_desc *dma_desc);
|
||||
void (*tx_start_xmit)(struct xlgmac_channel *channel,
|
||||
struct xlgmac_ring *ring);
|
||||
|
||||
/* For Flow Control */
|
||||
int (*config_tx_flow_control)(struct xlgmac_pdata *pdata);
|
||||
int (*config_rx_flow_control)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For Vlan related config */
|
||||
int (*enable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
|
||||
int (*disable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
|
||||
int (*enable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
|
||||
int (*disable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
|
||||
int (*update_vlan_hash_table)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For RX coalescing */
|
||||
int (*config_rx_coalesce)(struct xlgmac_pdata *pdata);
|
||||
int (*config_tx_coalesce)(struct xlgmac_pdata *pdata);
|
||||
unsigned int (*usec_to_riwt)(struct xlgmac_pdata *pdata,
|
||||
unsigned int usec);
|
||||
unsigned int (*riwt_to_usec)(struct xlgmac_pdata *pdata,
|
||||
unsigned int riwt);
|
||||
|
||||
/* For RX and TX threshold config */
|
||||
int (*config_rx_threshold)(struct xlgmac_pdata *pdata,
|
||||
unsigned int val);
|
||||
int (*config_tx_threshold)(struct xlgmac_pdata *pdata,
|
||||
unsigned int val);
|
||||
|
||||
/* For RX and TX Store and Forward Mode config */
|
||||
int (*config_rsf_mode)(struct xlgmac_pdata *pdata,
|
||||
unsigned int val);
|
||||
int (*config_tsf_mode)(struct xlgmac_pdata *pdata,
|
||||
unsigned int val);
|
||||
|
||||
/* For TX DMA Operate on Second Frame config */
|
||||
int (*config_osp_mode)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For RX and TX PBL config */
|
||||
int (*config_rx_pbl_val)(struct xlgmac_pdata *pdata);
|
||||
int (*get_rx_pbl_val)(struct xlgmac_pdata *pdata);
|
||||
int (*config_tx_pbl_val)(struct xlgmac_pdata *pdata);
|
||||
int (*get_tx_pbl_val)(struct xlgmac_pdata *pdata);
|
||||
int (*config_pblx8)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For MMC statistics */
|
||||
void (*rx_mmc_int)(struct xlgmac_pdata *pdata);
|
||||
void (*tx_mmc_int)(struct xlgmac_pdata *pdata);
|
||||
void (*read_mmc_stats)(struct xlgmac_pdata *pdata);
|
||||
|
||||
/* For Receive Side Scaling */
|
||||
int (*enable_rss)(struct xlgmac_pdata *pdata);
|
||||
int (*disable_rss)(struct xlgmac_pdata *pdata);
|
||||
int (*set_rss_hash_key)(struct xlgmac_pdata *pdata,
|
||||
const u8 *key);
|
||||
int (*set_rss_lookup_table)(struct xlgmac_pdata *pdata,
|
||||
const u32 *table);
|
||||
};
|
||||
|
||||
/* This structure contains flags that indicate what hardware features
|
||||
* or configurations are present in the device.
|
||||
*/
|
||||
struct xlgmac_hw_features {
|
||||
/* HW Version */
|
||||
unsigned int version;
|
||||
|
||||
/* HW Feature Register0 */
|
||||
unsigned int phyifsel; /* PHY interface support */
|
||||
unsigned int vlhash; /* VLAN Hash Filter */
|
||||
unsigned int sma; /* SMA(MDIO) Interface */
|
||||
unsigned int rwk; /* PMT remote wake-up packet */
|
||||
unsigned int mgk; /* PMT magic packet */
|
||||
unsigned int mmc; /* RMON module */
|
||||
unsigned int aoe; /* ARP Offload */
|
||||
unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */
|
||||
unsigned int eee; /* Energy Efficient Ethernet */
|
||||
unsigned int tx_coe; /* Tx Checksum Offload */
|
||||
unsigned int rx_coe; /* Rx Checksum Offload */
|
||||
unsigned int addn_mac; /* Additional MAC Addresses */
|
||||
unsigned int ts_src; /* Timestamp Source */
|
||||
unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
|
||||
|
||||
/* HW Feature Register1 */
|
||||
unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
|
||||
unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
|
||||
unsigned int adv_ts_hi; /* Advance Timestamping High Word */
|
||||
unsigned int dma_width; /* DMA width */
|
||||
unsigned int dcb; /* DCB Feature */
|
||||
unsigned int sph; /* Split Header Feature */
|
||||
unsigned int tso; /* TCP Segmentation Offload */
|
||||
unsigned int dma_debug; /* DMA Debug Registers */
|
||||
unsigned int rss; /* Receive Side Scaling */
|
||||
unsigned int tc_cnt; /* Number of Traffic Classes */
|
||||
unsigned int hash_table_size; /* Hash Table Size */
|
||||
unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
|
||||
|
||||
/* HW Feature Register2 */
|
||||
unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
|
||||
unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
|
||||
unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
|
||||
unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
|
||||
unsigned int pps_out_num; /* Number of PPS outputs */
|
||||
unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
|
||||
};
|
||||
|
||||
struct xlgmac_resources {
|
||||
void __iomem *addr;
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct xlgmac_pdata {
|
||||
struct net_device *netdev;
|
||||
struct device *dev;
|
||||
|
||||
struct xlgmac_hw_ops hw_ops;
|
||||
struct xlgmac_desc_ops desc_ops;
|
||||
|
||||
/* Device statistics */
|
||||
struct xlgmac_stats stats;
|
||||
|
||||
u32 msg_enable;
|
||||
|
||||
/* MAC registers base */
|
||||
void __iomem *mac_regs;
|
||||
|
||||
/* Hardware features of the device */
|
||||
struct xlgmac_hw_features hw_feat;
|
||||
|
||||
struct work_struct restart_work;
|
||||
|
||||
/* Rings for Tx/Rx on a DMA channel */
|
||||
struct xlgmac_channel *channel_head;
|
||||
unsigned int channel_count;
|
||||
unsigned int tx_ring_count;
|
||||
unsigned int rx_ring_count;
|
||||
unsigned int tx_desc_count;
|
||||
unsigned int rx_desc_count;
|
||||
unsigned int tx_q_count;
|
||||
unsigned int rx_q_count;
|
||||
|
||||
/* Tx/Rx common settings */
|
||||
unsigned int pblx8;
|
||||
|
||||
/* Tx settings */
|
||||
unsigned int tx_sf_mode;
|
||||
unsigned int tx_threshold;
|
||||
unsigned int tx_pbl;
|
||||
unsigned int tx_osp_mode;
|
||||
|
||||
/* Rx settings */
|
||||
unsigned int rx_sf_mode;
|
||||
unsigned int rx_threshold;
|
||||
unsigned int rx_pbl;
|
||||
|
||||
/* Tx coalescing settings */
|
||||
unsigned int tx_usecs;
|
||||
unsigned int tx_frames;
|
||||
|
||||
/* Rx coalescing settings */
|
||||
unsigned int rx_riwt;
|
||||
unsigned int rx_usecs;
|
||||
unsigned int rx_frames;
|
||||
|
||||
/* Current Rx buffer size */
|
||||
unsigned int rx_buf_size;
|
||||
|
||||
/* Flow control settings */
|
||||
unsigned int tx_pause;
|
||||
unsigned int rx_pause;
|
||||
|
||||
/* Device interrupt number */
|
||||
int dev_irq;
|
||||
unsigned int per_channel_irq;
|
||||
int channel_irq[XLGMAC_MAX_DMA_CHANNELS];
|
||||
|
||||
/* Netdev related settings */
|
||||
unsigned char mac_addr[ETH_ALEN];
|
||||
netdev_features_t netdev_features;
|
||||
struct napi_struct napi;
|
||||
|
||||
/* Filtering support */
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
|
||||
/* Device clocks */
|
||||
unsigned long sysclk_rate;
|
||||
|
||||
/* RSS addressing mutex */
|
||||
struct mutex rss_mutex;
|
||||
|
||||
/* Receive Side Scaling settings */
|
||||
u8 rss_key[XLGMAC_RSS_HASH_KEY_SIZE];
|
||||
u32 rss_table[XLGMAC_RSS_MAX_TABLE_SIZE];
|
||||
u32 rss_options;
|
||||
|
||||
int phy_speed;
|
||||
|
||||
char drv_name[32];
|
||||
char drv_ver[32];
|
||||
};
|
||||
|
||||
void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops);
|
||||
void xlgmac_init_hw_ops(struct xlgmac_hw_ops *hw_ops);
|
||||
const struct net_device_ops *xlgmac_get_netdev_ops(void);
|
||||
void xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
unsigned int idx,
|
||||
unsigned int count,
|
||||
unsigned int flag);
|
||||
void xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata,
|
||||
struct xlgmac_ring *ring,
|
||||
unsigned int idx);
|
||||
void xlgmac_print_pkt(struct net_device *netdev,
|
||||
struct sk_buff *skb, bool tx_rx);
|
||||
void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata);
|
||||
void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata);
|
||||
int xlgmac_drv_probe(struct device *dev,
|
||||
struct xlgmac_resources *res);
|
||||
int xlgmac_drv_remove(struct device *dev);
|
||||
|
||||
/* For debug prints */
|
||||
#ifdef XLGMAC_DEBUG
|
||||
#define XLGMAC_PR(fmt, args...) \
|
||||
pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args)
|
||||
#else
|
||||
#define XLGMAC_PR(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __DWC_XLGMAC_H__ */
|
Loading…
Reference in a new issue