blob: ee291210ae49a891f5765a0e0d93b19a1a5d86f6 [file] [log] [blame]
/* Copyright (c) 2017-2019, The Linux Foundation. All rights
* reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This file contain content copied from Synopsis driver,
* provided under the license below
*/
/* =========================================================================
* The Synopsys DWC ETHER QOS Software Driver and documentation (hereinafter
* "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 Licensed Product under
* any End User Software License Agreement or Agreement for Licensed Product
* with Synopsys or any supplement thereto. Permission is hereby granted,
* free of charge, to any person obtaining a copy of this software annotated
* with this license and the Software, to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* ========================================================================= */
#ifndef __DWC_ETH_QOS__YHEADER__
#define __DWC_ETH_QOS__YHEADER__
/* VLAN ids range for IPA offload */
#define MIN_VLAN_ID 1
#define MAX_VLAN_ID 4094
/* OS Specific declarations and definitions */
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/cdev.h>
#include <linux/msm-bus.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/highmem.h>
#include <linux/proc_fs.h>
#include <linux/in.h>
#include <linux/ctype.h>
#include <linux/version.h>
#include <linux/ptrace.h>
#include <linux/dma-mapping.h>
#include <asm/dma-iommu.h>
#include <linux/iommu.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/bitops.h>
#include <linux/mii.h>
#include <asm/processor.h>
#include <asm/dma.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <net/checksum.h>
#include <linux/tcp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#ifdef DWC_INET_LRO
#include <linux/inet_lro.h>
#endif
#include <linux/semaphore.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/phy.h>
#include <linux/mdio.h>
#include <linux/micrel_phy.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define DWC_ETH_QOS_ENABLE_VLAN_TAG
#include <linux/if_vlan.h>
#endif
/* for PPT */
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/clocksource.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
#include <linux/timecompare.h>
#endif
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/mailbox_client.h>
#include <linux/mailbox/qmp.h>
#include <linux/mailbox_controller.h>
#include <linux/ipc_logging.h>
#include <linux/inetdevice.h>
#include <net/inet_common.h>
#include <net/ipv6.h>
#include <linux/inet.h>
#include <asm/uaccess.h>
#ifdef CONFIG_MSM_BOOT_TIME_MARKER
#include <soc/qcom/boot_stats.h>
#endif
/* QOS Version Control Macros */
/* #define DWC_ETH_QOS_VER_4_0 */
/* Default Configuration is for QOS version 4.1 and above */
/* Macro definitions*/
#include <asm-generic/errno.h>
extern void *ipc_emac_log_ctxt;
#define IPCLOG_STATE_PAGES 50
#define __FILENAME__ (strrchr(__FILE__, '/') ? \
strrchr(__FILE__, '/') + 1 : __FILE__)
#ifdef CONFIG_PGTEST_OBJ
#define DWC_ETH_QOS_CONFIG_PGTEST
#endif
#ifdef CONFIG_PTPSUPPORT_OBJ
#define DWC_ETH_QOS_CONFIG_PTP
#endif
#ifdef CONFIG_DEBUGFS_OBJ
#define DWC_ETH_QOS_CONFIG_DEBUGFS
#endif
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
#define DWC_ETH_QOS_DA_SA 12
#define DWC_ETH_QOS_TYPE 2
#define DWC_ETH_QOS_VLAN_TAG 4
#define DWC_ETH_QOS_ETH_HDR_AVB (DWC_ETH_QOS_DA_SA + \
DWC_ETH_QOS_TYPE + \
DWC_ETH_QOS_VLAN_TAG)
#define DWC_ETH_QOS_PG_FRAME_SIZE (pdata->dev->mtu + DWC_ETH_QOS_ETH_HDR_AVB)
#define DWC_ETH_QOS_AVTYPE 0x22f0
#endif /* end of DWC_ETH_QOS_CONFIG_PGTEST */
/* NOTE: Uncomment below line for TX and RX DESCRIPTOR DUMP in KERNEL LOG */
/* #define DWC_ETH_QOS_ENABLE_TX_DESC_DUMP */
/* #define DWC_ETH_QOS_ENABLE_RX_DESC_DUMP */
/* NOTE: Uncomment below line for TX and RX PACKET DUMP in KERNEL LOG */
/* #define DWC_ETH_QOS_ENABLE_TX_PKT_DUMP */
/* #define DWC_ETH_QOS_ENABLE_RX_PKT_DUMP */
/* Uncomment below macro definitions for testing corresponding IP features in driver */
#define DWC_ETH_QOS_QUEUE_SELECT_ALGO
/* #define DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT */
/* #define DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT_HALFDUPLEX */
/* #define DWC_ETH_QOS_TXPOLLING_MODE_ENABLE */
/* #define DWC_ETH_QOS_COPYBREAK_ENABLED */
#ifdef DWC_ETH_QOS_CONFIG_PTP
#undef DWC_ETH_QOS_TXPOLLING_MODE_ENABLE
#endif
/* Uncomment below macro to enable Double VLAN support. */
/* #define DWC_ETH_QOS_ENABLE_DVLAN */
/* Uncomment below macro to test EEE feature Tx path with
* no EEE supported PHY card
* */
/* #define DWC_ETH_QOS_CUSTOMIZED_EEE_TEST */
#ifdef DWC_ETH_QOS_CUSTOMIZED_EEE_TEST
#undef DWC_ETH_QOS_TXPOLLING_MODE_ENABLE
#endif
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
#undef DWC_ETH_QOS_TXPOLLING_MODE_ENABLE
#endif
#ifdef DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT_HALFDUPLEX
#define DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT
#endif
#ifdef DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT
#undef DWC_ETH_QOS_TXPOLLING_MODE_ENABLE
#endif
/* #define PER_CH_INT */
/* NOTE: Uncomment below line for function trace log messages in KERNEL LOG */
/* #define YDEBUG */
/* #define YDEBUG_PG */
/* #define YDEBUG_MDIO */
/* #define YDEBUG_PTP */
/* #define YDEBUG_FILTER */
/* #define YDEBUG_EEE */
#define Y_TRUE 1
#define Y_FALSE 0
#define Y_SUCCESS 0
#define Y_FAILURE 1
#define Y_INV_WR 1
#define Y_INV_RD 2
#define Y_INV_ARG 3
#define Y_MAX_THRD_XEEDED 4
/* The following macros map error macros to POSIX errno values */
#define ERR_READ_TIMEOUT ETIME
#define ERR_WRITE_TIMEOUT ETIME
#define ERR_FIFO_READ_FAILURE EIO
#define ERR_FIFO_WRITE_FAILURE EIO
#define ERR_READ_OVRFLW ENOBUFS
#define ERR_READ_UNDRFLW ENODATA
#define ERR_WRITE_OVRFLW ENOBUFS
#define ERR_WRITE_UNDRFLW ENODATA
/* Helper macros for STANDARD VIRTUAL register handling */
#define GET_TX_ERROR_COUNTERS_PTR (&pdata->tx_error_counters)
#define GET_RX_ERROR_COUNTERS_PTR (&pdata->rx_error_counters)
#define GET_RX_PKT_FEATURES_PTR (&pdata->rx_pkt_features)
#define GET_TX_PKT_FEATURES_PTR (&pdata->tx_pkt_features)
#define MASK (0x1ULL << 0 | \
0x13c7ULL << 32)
#define MAC_MASK (0x10ULL << 0)
#define IPA_TX_DESC_CNT 128 /*Increase the TX desc count to 128 for IPA offload*/
#define IPA_RX_DESC_CNT 128 /*Increase the RX desc count to 128 for IPA offload*/
#define TX_DESC_CNT 256
#define RX_DESC_CNT 256
#define MIN_RX_DESC_CNT 16
#define TX_BUF_SIZE 1536
#define RX_BUF_SIZE 1568
#define DWC_ETH_QOS_MAX_LRO_DESC 16
#define DWC_ETH_QOS_MAX_LRO_AGGR 32
#define MIN_PACKET_SIZE 60
/*
#ifdef DWC_ETH_QOS_ENABLE_VLAN_TAG
#define MAX_PACKET_SIZE VLAN_ETH_FRAME_LEN
#else
#define MAX_PACKET_SIZE 1514
#endif
*/
/* RX header size for split header */
#define DWC_ETH_QOS_HDR_SIZE_64B 64 /* 64 bytes */
#define DWC_ETH_QOS_HDR_SIZE_128B 128 /* 128 bytes */
#define DWC_ETH_QOS_HDR_SIZE_256B 256 /* 256 bytes */
#define DWC_ETH_QOS_HDR_SIZE_512B 512 /* 512 bytes */
#define DWC_ETH_QOS_HDR_SIZE_1024B 1024 /* 1024 bytes */
#define DWC_ETH_QOS_MAX_HDR_SIZE DWC_ETH_QOS_HDR_SIZE_256B
#define MAX_MULTICAST_LIST 14
#define RX_DESC_DATA_LENGTH_LBIT 0
#define RX_DESC_DATA_LENGTH 0x7fff
#define DWC_ETH_QOS_TX_FLAGS_IP_PKT 0x00000001
#define DWC_ETH_QOS_TX_FLAGS_TCP_PKT 0x00000002
#define DEV_NAME "DWC_ETH_QOS"
#define DEV_ADDRESS 0xffffffff
#define DEV_REG_MMAP_SIZE 0x14e8
#define VENDOR_ID 0x16C3
#define DEVICE_ID_HAPS_6X 0x7101
#define DEVICE_ID_HAPS_DX 0x7102
#define PCI_BAR_NO 0
#define COMPLETE_BAR 0
/* MII/GMII register offset */
#define DWC_ETH_QOS_AUTO_NEGO_NP 0x0007
#define DWC_ETH_QOS_PHY_CTL 0x0010
#define DWC_ETH_QOS_PHY_STS 0x0011
#define DWC_ETH_QOS_PHY_INTR_EN 0x0012
#define DWC_ETH_QOS_PHY_INTR_STATUS 0x0013
#define DWC_ETH_QOS_PHY_RX_DELAY 0x00
#define DWC_ETH_QOS_PHY_TX_DELAY 0x05
#define DWC_ETH_QOS_PHY_SMART_SPEED 0x14
#define DWC_ETH_QOS_PHY_RX_DELAY_WR_MASK (ULONG)(0x7fff)
#define DWC_ETH_QOS_PHY_RX_DELAY_MASK 0x1
#define DWC_ETH_QOS_PHY_TX_DELAY_WR_MASK (ULONG)(0xfeff)
#define DWC_ETH_QOS_PHY_TX_DELAY_MASK 0x1
#define ENABLE_RX_DELAY 0x1
#define DISABLE_RX_DELAY 0x0
#define ENABLE_TX_DELAY 0x1
#define DISABLE_TX_DELAY 0x0
#define DWC_ETH_QOS_PHY_DEBUG_PORT_ADDR_OFFSET 0x1d
#define DWC_ETH_QOS_PHY_DEBUG_PORT_DATAPORT 0x1e
#define DWC_ETH_QOS_MICREL_PHY_DEBUG_PORT_ADDR_OFFSET 0x0d
#define DWC_ETH_QOS_MICREL_PHY_DEBUG_PORT_DATAPORT 0x0e
#define DWC_ETH_QOS_MICREL_PHY_DEBUG_MMD_DEV_ADDR 0x2
#define DWC_ETH_QOS_MICREL_PHY_INTCS 0x1b
#define DWC_ETH_QOS_MICREL_PHY_CTL 0x1f
#define DWC_ETH_QOS_MICREL_INTR_LEVEL 0x4000
#define DWC_ETH_QOS_BASIC_STATUS 0x0001
#define LINK_STATE_MASK 0x4
#define AUTONEG_STATE_MASK 0x20
/* Hibernation mode in AR8035 */
#define DWC_ETH_QOS_PHY_HIB_CTRL 0x0B
#define DWC_ETH_QOS_PHY_HIB_CTRL_PS_HIB_EN_WR_MASK 0xFFFF7FFF
#define DWC_ETH_QOS_PHY_HIB_CTRL_PS_HIB_EN_MASK 0x1
#define LINK_DOWN_STATE 0x800
#define LINK_UP_STATE 0x400
#define PHY_WOL 0x1
#define AUTO_NEG_ERROR 0x8000
#define LINK_UP 1
#define LINK_DOWN 0
#define ENABLE_PHY_INTERRUPTS 0xcc00
#define MICREL_LINK_UP_INTR_STATUS BIT(0)
/* Default MTL queue operation mode values */
#define DWC_ETH_QOS_Q_DISABLED 0x0
#define DWC_ETH_QOS_Q_AVB 0x1
#define DWC_ETH_QOS_Q_DCB 0x2
#define DWC_ETH_QOS_Q_GENERIC DWC_ETH_QOS_Q_DCB
/* Driver PMT macros */
#define DWC_ETH_QOS_DRIVER_CONTEXT 1
#define DWC_ETH_QOS_IOCTL_CONTEXT 2
#define DWC_ETH_QOS_MAGIC_WAKEUP BIT(0)
#define DWC_ETH_QOS_REMOTE_WAKEUP BIT(1)
#define DWC_ETH_QOS_PHY_INTR_WAKEUP BIT(2)
#define DWC_ETH_QOS_EMAC_INTR_WAKEUP BIT(3)
#define DWC_ETH_QOS_POWER_DOWN_TYPE(x) \
((x->power_down_type & DWC_ETH_QOS_MAGIC_WAKEUP) ? \
"Magic packet" : \
((x->power_down_type & DWC_ETH_QOS_REMOTE_WAKEUP) ? \
"Remote wakeup packet" : \
((x->power_down_type & DWC_ETH_QOS_PHY_INTR_WAKEUP) ? \
"WoL or Link Status interrupt from PHY" : \
((x->power_down_type & DWC_ETH_QOS_EMAC_INTR_WAKEUP) ? \
"EMAC interrupt" : \
"<error>"))))
#define DWC_ETH_QOS_MAC_ADDR_LEN 6
#define DWC_ETH_QOS_MAC_ADDR_STR_LEN 18
#ifndef DWC_ETH_QOS_ENABLE_VLAN_TAG
#define VLAN_HLEN 0
#endif
#define PADDING_ISSUE (2*8)
#define DWC_ETH_QOS_ETH_FRAME_LEN (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN + PADDING_ISSUE)
#define DWC_ETH_QOS_ETH_FRAME_LEN_IPA ((1<<11) + PADDING_ISSUE) /*IPA can support 2KB max pkt length*/
#define FIFO_SIZE_B(x) (x)
#define FIFO_SIZE_KB(x) (x * 1024)
/* #define DWC_ETH_QOS_MAX_DATA_PER_TX_BUF (1 << 13)*/ /* 8 KB Maximum data per buffer pointer(in Bytes) */
#define DWC_ETH_QOS_MAX_DATA_PER_TX_BUF BIT(12) /* for testing purpose: 4 KB Maximum data per buffer pointer(in Bytes) */
#define DWC_ETH_QOS_MAX_DATA_PER_TXD (DWC_ETH_QOS_MAX_DATA_PER_TX_BUF * 2) /* Maxmimum data per descriptor(in Bytes) */
#define DWC_ETH_QOS_MAX_SUPPORTED_MTU 16380
#define DWC_ETH_QOS_MAX_GPSL 9000 /* Default maximum Gaint Packet Size Limit */
#define DWC_ETH_QOS_MIN_SUPPORTED_MTU (ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN)
#define DWC_ETH_QOS_RDESC3_OWN 0x80000000
#define DWC_ETH_QOS_RDESC3_FD 0x20000000
#define DWC_ETH_QOS_RDESC3_LD 0x10000000
#define DWC_ETH_QOS_RDESC3_RS2V 0x08000000
#define DWC_ETH_QOS_RDESC3_RS1V 0x04000000
#define DWC_ETH_QOS_RDESC3_RS0V 0x02000000
#define DWC_ETH_QOS_RDESC3_LT 0x00070000
#define DWC_ETH_QOS_RDESC3_ES 0x00008000
#define DWC_ETH_QOS_RDESC3_PL 0x00007FFF
/* Receive ERRORs */
#define DWC_ETH_QOS_RDESC3_DRIBBLE_ERR 0x80000
#define DWC_ETH_QOS_RDESC3_RECEIVE_ERR 0x100000
#define DWC_ETH_QOS_RDESC3_OVERFLOW_ERR 0x200000
#define DWC_ETH_QOS_RDESC3_WTO_ERR 0x400000
#define DWC_ETH_QOS_RDESC3_GAINT_PKT_ERR 0x800000
#define DWC_ETH_QOS_RDESC3_CRC_ERR 0x1000000
#define DWC_ETH_QOS_RDESC2_HL 0x000003FF
#define DWC_ETH_QOS_RDESC1_PT 0x00000007 /* Payload type */
#define DWC_ETH_QOS_RDESC1_PT_TCP 0x00000002 /* Payload type = TCP */
/* Maximum size of pkt that is copied to a new buffer on receive */
#define DWC_ETH_QOS_COPYBREAK_DEFAULT 256
#define DWC_ETH_QOS_SYSCLOCK 250000000 /* System clock is 250MHz */
#define DWC_ETH_QOS_SYSTIMEPERIOD 4 /* System time period is 4ns */
#define DWC_ETH_QOS_DEFAULT_PTP_CLOCK 96000000
#define DWC_ETH_QOS_DEFAULT_LPASS_PPS_FREQUENCY 19200000
#define DWC_ETH_QOS_TX_QUEUE_CNT (pdata->tx_queue_cnt)
#define DWC_ETH_QOS_RX_QUEUE_CNT (pdata->rx_queue_cnt)
#define DWC_ETH_QOS_QUEUE_CNT min(DWC_ETH_QOS_TX_QUEUE_CNT, DWC_ETH_QOS_RX_QUEUE_CNT)
#define DWC_ETH_QOS_TXQ_CNT 5
#define DWC_ETH_QOS_RXQ_CNT 4
/* PPS */
#define AVB_CLASS_A_POLL_DEV_NODE_NAME "avb_class_a_intr"
#define AVB_CLASS_B_POLL_DEV_NODE_NAME "avb_class_b_intr"
#define DWC_ETH_QOS_PPS_STOP 0
#define DWC_ETH_QOS_PPS_START 1
#define DWC_ETH_QOS_PPS_CH_0 0
#define DWC_ETH_QOS_PPS_CH_1 1
#define DWC_ETH_QOS_PPS_CH_2 2
#define DWC_ETH_QOS_PPS_CH_3 3
/* Helper macros for TX descriptor handling */
#define GET_TX_QUEUE_PTR(QINX) (&pdata->tx_queue[(QINX)])
#define GET_TX_DESC_PTR(QINX, DINX) (pdata->tx_queue[(QINX)].tx_desc_data.tx_desc_ptrs[(DINX)])
#define GET_TX_DESC_DMA_ADDR(QINX, DINX) (pdata->tx_queue[(QINX)].tx_desc_data.tx_desc_dma_addrs[(DINX)])
/* Add IPA specific Macros to access the DMA and virtual address to be provided to IPA uC*/
#define GET_TX_BUFF_DMA_ADDR(chInx, dInx) (pdata->tx_queue[(chInx)].tx_desc_data.ipa_tx_buff_pool_pa_addrs_base[(dInx)])
#define GET_TX_BUFF_LOGICAL_ADDR(chInx, dInx) (pdata->tx_queue[(chInx)].tx_desc_data.ipa_tx_buff_pool_va_addrs_base[(dInx)])
#define GET_TX_BUFF_POOL_BASE_ADRR(chInx) (pdata->tx_queue[(chInx)].tx_desc_data.ipa_tx_buff_pool_pa_addrs_base)
#define GET_TX_BUFF_POOL_BASE_PADRR(chInx) (pdata->tx_queue[(chInx)].tx_desc_data.ipa_tx_buff_pool_pa_addrs_base_dma_handle)
#define GET_TX_BUFF_POOL_BASE_ADRR_SIZE(chInx) (sizeof(dma_addr_t) * pdata->tx_queue[chInx].desc_cnt)
#define GET_TX_WRAPPER_DESC(QINX) (&pdata->tx_queue[(QINX)].tx_desc_data)
#define GET_TX_BUF_PTR(QINX, DINX) (pdata->tx_queue[(QINX)].tx_desc_data.tx_buf_ptrs[(DINX)])
#define INCR_TX_DESC_INDEX(inx, offset, desc_cnt) do {\
(inx) += (offset);\
if ((inx) >= (desc_cnt))\
(inx) = ((inx) - (desc_cnt));\
} while (0)
#define DECR_TX_DESC_INDEX(inx, desc_cnt) do {\
(inx)--;\
if ((inx) < 0)\
(inx) = (desc_cnt + (inx));\
} while (0)
#define INCR_TX_LOCAL_INDEX(inx, offset, desc_cnt)\
(((inx) + (offset)) >= desc_cnt ?\
((inx) + (offset) - desc_cnt) : ((inx) + (offset)))
#define GET_CURRENT_XFER_DESC_CNT(QINX) (pdata->tx_queue[(QINX)].tx_desc_data.packet_count)
#define GET_TX_CURRENT_XFER_LAST_DESC_INDEX(QINX, start_index, offset, desc_cnt)\
(GET_CURRENT_XFER_DESC_CNT((QINX)) == 0) ? (desc_cnt - 1) :\
((GET_CURRENT_XFER_DESC_CNT((QINX)) == 1) ? (INCR_TX_LOCAL_INDEX((start_index), (offset), (desc_cnt))) :\
INCR_TX_LOCAL_INDEX((start_index), (GET_CURRENT_XFER_DESC_CNT((QINX)) + (offset) - 1), (desc_cnt))) \
#define GET_TX_TOT_LEN(buffer, start_index, packet_count, total_len, desc_cnt) do {\
int i, pkt_idx = (start_index);\
for (i = 0; i < (packet_count); i++) {\
(total_len) += ((buffer)[pkt_idx].len + (buffer)[pkt_idx].len2);\
pkt_idx = INCR_TX_LOCAL_INDEX(pkt_idx, 1, desc_cnt);\
} \
} while (0)
/* Helper macros for RX descriptor handling */
#define GET_RX_QUEUE_PTR(QINX) (&pdata->rx_queue[(QINX)])
#define GET_RX_DESC_PTR(QINX, DINX) (pdata->rx_queue[(QINX)].rx_desc_data.rx_desc_ptrs[(DINX)])
#define GET_RX_DESC_DMA_ADDR(QINX, DINX) (pdata->rx_queue[(QINX)].rx_desc_data.rx_desc_dma_addrs[(DINX)])
/* Add IPA specific Macros to access the DMA address to be provided to IPA uC*/
#define GET_RX_BUFF_DMA_ADDR(QINX, DINX) (pdata->rx_queue[(QINX)].rx_desc_data.ipa_rx_buff_pool_pa_addrs_base[(DINX)])
#define GET_RX_BUFF_LOGICAL_ADDR(QINX, DINX) (pdata->rx_queue[(QINX)].rx_desc_data.ipa_rx_buff_pool_va_addrs_base[(DINX)])
#define GET_RX_BUFF_POOL_BASE_ADRR(QINX) (pdata->rx_queue[(QINX)].rx_desc_data.ipa_rx_buff_pool_pa_addrs_base)
#define GET_RX_BUFF_POOL_BASE_PADRR(chInx) (pdata->rx_queue[(chInx)].rx_desc_data.ipa_rx_buff_pool_pa_addrs_base_dma_handle)
#define GET_RX_BUFF_POOL_BASE_ADRR_SIZE(chInx) (sizeof(dma_addr_t) * pdata->rx_queue[chInx].desc_cnt)
#define GET_RX_WRAPPER_DESC(QINX) (&pdata->rx_queue[(QINX)].rx_desc_data)
#define GET_RX_BUF_PTR(QINX, DINX) (pdata->rx_queue[(QINX)].rx_desc_data.rx_buf_ptrs[(DINX)])
#define INCR_RX_DESC_INDEX(inx, offset, desc_cnt) do {\
(inx) += (offset);\
if ((inx) >= desc_cnt)\
(inx) = ((inx) - desc_cnt);\
} while (0)
#define DECR_RX_DESC_INDEX(inx, desc_cnt) do {\
(inx)--;\
if ((inx) < 0)\
(inx) = (desc_cnt + (inx));\
} while (0)
#define INCR_RX_LOCAL_INDEX(inx, offset, desc_cnt)\
(((inx) + (offset)) >= desc_cnt ?\
((inx) + (offset) - desc_cnt) : ((inx) + (offset)))
#define GET_CURRENT_RCVD_DESC_CNT(QINX) (pdata->rx_queue[(QINX)].rx_desc_data.pkt_received)
#define GET_RX_CURRENT_RCVD_LAST_DESC_INDEX(start_index, offset, desc_cnt) (desc_cnt - 1)
#define GET_TX_DESC_IDX(QINX, desc) (((desc) - GET_TX_DESC_DMA_ADDR((QINX), 0)) / (sizeof(struct s_TX_NORMAL_DESC)))
#define GET_RX_DESC_IDX(QINX, desc) (((desc) - GET_RX_DESC_DMA_ADDR((QINX), 0)) / (sizeof(struct s_RX_NORMAL_DESC)))
/* Helper macro for handling coalesce parameters via ethtool */
/* Obtained by trial and error */
#define DWC_ETH_QOS_OPTIMAL_DMA_RIWT_USEC 124
/* Max delay before RX interrupt after a pkt is received Max
* delay in usecs is 1020 for 62.5MHz device clock */
#define DWC_ETH_QOS_MAX_DMA_RIWT 0xff
/* Max no of pkts to be received before an RX interrupt */
#define DWC_ETH_QOS_RX_MAX_FRAMES 16
#define DMA_SBUS_AXI_PBL_MASK 0xFE
/* Helper macros for handling receive error */
#define DWC_ETH_QOS_RX_LENGTH_ERR 0x00000001
#define DWC_ETH_QOS_RX_BUF_OVERFLOW_ERR 0x00000002
#define DWC_ETH_QOS_RX_CRC_ERR 0x00000004
#define DWC_ETH_QOS_RX_FRAME_ERR 0x00000008
#define DWC_ETH_QOS_RX_FIFO_OVERFLOW_ERR 0x00000010
#define DWC_ETH_QOS_RX_MISSED_PKT_ERR 0x00000020
#define DWC_ETH_QOS_RX_CHECKSUM_DONE 0x00000001
#define DWC_ETH_QOS_RX_VLAN_PKT 0x00000002
/* MAC Time stamp contorl reg bit fields */
#define MAC_TCR_TSENA 0x00000001 /* Enable timestamp */
#define MAC_TCR_TSCFUPDT 0x00000002 /* Enable Fine Timestamp Update */
#define MAC_TCR_TSENALL 0x00000100 /* Enable timestamping for all packets */
#define MAC_TCR_TSCTRLSSR 0x00000200 /* Enable Timestamp Digitla Contorl (1ns accuracy )*/
#define MAC_TCR_TSVER2ENA 0x00000400 /* Enable PTP packet processing for Version 2 Formate */
#define MAC_TCR_TSIPENA 0x00000800 /* Enable processing of PTP over Ethernet Packets */
#define MAC_TCR_TSIPV6ENA 0x00001000 /* Enable processing of PTP Packets sent over IPv6-UDP Packets */
#define MAC_TCR_TSIPV4ENA 0x00002000 /* Enable processing of PTP Packets sent over IPv4-UDP Packets */
#define MAC_TCR_TSEVENTENA 0x00004000 /* Enable Timestamp Snapshot for Event Messages */
#define MAC_TCR_TSMASTERENA 0x00008000 /* Enable snapshot for Message Relevant to Master */
#define MAC_TCR_SNAPTYPSEL_1 0x00010000 /* select PTP packets for taking snapshots */
#define MAC_TCR_SNAPTYPSEL_2 0x00020000
#define MAC_TCR_SNAPTYPSEL_3 0x00030000
#define MAC_TCR_AV8021ASMEN 0x10000000 /* Enable AV 802.1AS Mode */
/* PTP Offloading control register bits (MAC_PTO_control)*/
#define MAC_PTOCR_PTOEN 0x00000001 /* PTP offload Enable */
#define MAC_PTOCR_ASYNCEN 0x00000002 /* Automatic PTP Sync message enable */
#define MAC_PTOCR_APDREQEN 0x00000004 /* Automatic PTP Pdelay_Req message enable */
/* Hash Table Reg count */
#define DWC_ETH_QOS_HTR_CNT (pdata->max_hash_table_size / 32)
/* For handling VLAN filtering */
#define DWC_ETH_QOS_VLAN_FILTERING_EN_DIS 0
#define DWC_ETH_QOS_VLAN_PERFECT_FILTERING 0
#define DWC_ETH_QOS_VLAN_HASH_FILTERING 1
#define DWC_ETH_QOS_VLAN_INVERSE_MATCHING 0
/* For handling differnet PHY interfaces */
#define DWC_ETH_QOS_GMII_MII 0x0
#define DWC_ETH_QOS_RGMII 0x1
#define DWC_ETH_QOS_SGMII 0x2
#define DWC_ETH_QOS_TBI 0x3
#define DWC_ETH_QOS_RMII 0x4
#define DWC_ETH_QOS_RTBI 0x5
#define DWC_ETH_QOS_SMII 0x6
#define DWC_ETH_QOS_REVMII 0x7
/* for EEE */
#define DWC_ETH_QOS_DEFAULT_LPI_LS_TIMER 0x3E8 /* 1000 in decimal */
#define DWC_ETH_QOS_DEFAULT_LPI_TWT_TIMER 0x11 /* Typical 17uS */
#define DWC_ETH_QOS_DEFAULT_LPI_LPIET_TIMER 0x1FFFF /* 131071uS=131.071mS */
#define DWC_ETH_QOS_DEFAULT_LPI_TIMER 1000 /* LPI Tx local expiration time in msec */
#define DWC_ETH_QOS_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
/* Error and status macros defined below */
#define E_DMA_SR_TPS 6
#define E_DMA_SR_TBU 7
#define E_DMA_SR_RBU 8
#define E_DMA_SR_RPS 9
#define S_DMA_SR_RWT 2
#define E_DMA_SR_FBE 10
#define S_MAC_ISR_PMTIS 11
#define QTAG_VLAN_ETH_TYPE_OFFSET 16
#define QTAG_UCP_FIELD_OFFSET 14
#define QTAG_ETH_TYPE_OFFSET 12
#define PTP_UDP_EV_PORT 0x013F
#define PTP_UDP_GEN_PORT 0x0140
#define GET_ETH_TYPE(buf) \
((((u16)buf[QTAG_ETH_TYPE_OFFSET]<<8) | \
buf[QTAG_ETH_TYPE_OFFSET+1]) == ETH_P_8021Q)?\
(((u16)buf[QTAG_VLAN_ETH_TYPE_OFFSET]<<8) | \
buf[QTAG_VLAN_ETH_TYPE_OFFSET+1]): \
(((u16)buf[QTAG_ETH_TYPE_OFFSET]<<8) | \
buf[QTAG_ETH_TYPE_OFFSET+1]);
#define GET_VLAN_UCP(buf) \
(((u16)buf[QTAG_UCP_FIELD_OFFSET]<<8) \
| buf[QTAG_UCP_FIELD_OFFSET+1]);
#define VLAN_TAG_UCP_SHIFT 13
#define CLASS_A_TRAFFIC_UCP 3
#define CLASS_A_TRAFFIC_TX_CHANNEL 3
#define CLASS_B_TRAFFIC_UCP 2
#define CLASS_B_TRAFFIC_TX_CHANNEL 2
#define NON_TAGGED_IP_TRAFFIC_TX_CHANNEL 1
#define ALL_OTHER_TRAFFIC_TX_CHANNEL 1
#define TX_IOC_MODEATION_IP_TRAFFIC 16
#define ALL_OTHER_TX_TRAFFIC_IPA_DISABLED 0
#define DEFAULT_INT_MOD 1
#define AVB_INT_MOD 8
#define IP_PKT_INT_MOD 32
#define PTP_INT_MOD 1
#define DMA_TX_CH0 0
#define DMA_TX_CH1 1
#define DMA_TX_CH2 2
#define DMA_TX_CH3 3
#define DMA_TX_CH4 4
#define DMA_RX_CH0 0
#define DMA_RX_CH1 1
#define DMA_RX_CH2 2
#define DMA_RX_CH3 3
#define IPA_DMA_TX_CH 0
#define IPA_DMA_RX_CH 0
#define IPA_RX_TO_DMA_CH_MAP_NUM BIT(0);
#define EMAC_GDSC_EMAC_NAME "gdsc_emac"
#define EMAC_VREG_RGMII_NAME "vreg_rgmii"
#define EMAC_VREG_EMAC_PHY_NAME "vreg_emac_phy"
#define EMAC_VREG_RGMII_IO_PADS_NAME "vreg_rgmii_io_pads"
#define EMAC_GPIO_PHY_INTR_REDIRECT_NAME "qcom,phy-intr-redirect"
#define EMAC_GPIO_PHY_RESET_NAME "qcom,phy-reset"
/* The values used in gpio_set_value() are boolean, zero for low, nonzero for high.*/
#define PHY_RESET_GPIO_LOW 0
#define PHY_RESET_GPIO_HIGH 1
#define VOTE_IDX_0MBPS 0
#define VOTE_IDX_10MBPS 1
#define VOTE_IDX_100MBPS 2
#define VOTE_IDX_1000MBPS 3
/* AHB clock vote is same for 1000/100Mbps and set to 133MHz */
#define CLOCK_AHB_MHZ 133
/* Clock rates for various modes */
#define RGMII_1000_NOM_CLK_FREQ (250 * 1000 * 1000UL)
#define RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ (50 * 1000 * 1000UL)
#define RGMII_NON_ID_MODE_100_LOW_SVS_CLK_FREQ (25 * 1000 * 1000UL)
#define RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ (5 * 1000 * 1000UL)
#define RGMII_NON_ID_MODE_10_LOW_SVS_CLK_FREQ (2.5 * 1000 * 1000UL)
#define RMII_100_LOW_SVS_CLK_FREQ (50 * 1000 * 1000UL)
#define RMII_10_LOW_SVS_CLK_FREQ (50 * 1000 * 1000UL)
#define MII_100_LOW_SVS_CLK_FREQ (25 * 1000 * 1000UL)
#define MII_10_LOW_SVS_CLK_FREQ (2.5 * 1000 * 1000UL)
#define MAX_QMP_MSG_SIZE 96
#define NAPI_PER_QUEUE_POLL_BUDGET 64
/**
* enum emac_hw_core_version - EMAC hardware core version type
* @EMAC_HW_None: EMAC hardware version not defined
* @EMAC_HW_v2_0_0: EMAC core version 2.0.0.
* @EMAC_HW_v2_1_0: EMAC core version 2.1.0.
* @EMAC_HW_v2_1_1: EMAC core version 2.1.1.
* @EMAC_HW_v2_1_2: EMAC core version 2.1.2.
* @EMAC_HW_v2_2_0: EMAC core version 2.2.0.
* @EMAC_HW_v2_3_0: EMAC core version 2.3.0.
* @EMAC_HW_v2_3_1: EMAC core version 2.3.1.
* @EMAC_HW_v2_3_2: EMAC core version 2.3.2.
*/
#define EMAC_HW_None 0
#define EMAC_HW_v2_0_0 1
#define EMAC_HW_v2_1_0 2
#define EMAC_HW_v2_1_1 3
#define EMAC_HW_v2_1_2 4
#define EMAC_HW_v2_2_0 5
#define EMAC_HW_v2_3_0 6
#define EMAC_HW_v2_3_1 7
#define EMAC_HW_v2_3_2 8
#define EMAC_HW_vMAX 9
/* C data types typedefs */
typedef unsigned short BOOL;
typedef char CHAR;
typedef char *CHARP;
typedef double DOUBLE;
typedef double *DOUBLEP;
typedef float FLOAT;
typedef float *FLOATP;
typedef int INT;
typedef int *INTP;
typedef long LONG;
typedef long *LONGP;
typedef short SHORT;
typedef short *SHORTP;
typedef unsigned int UINT;
typedef unsigned int *UINTP;
typedef unsigned char UCHAR;
typedef unsigned char *UCHARP;
typedef unsigned long ULONG;
typedef unsigned long *ULONGP;
typedef unsigned long long ULONG_LONG;
typedef unsigned short USHORT;
typedef unsigned short *USHORTP;
typedef void VOID;
typedef void *VOIDP;
struct s_RX_CONTEXT_DESC {
UINT RDES0;
UINT RDES1;
UINT RDES2;
UINT RDES3;
};
typedef struct s_RX_CONTEXT_DESC t_RX_CONTEXT_DESC;
struct s_TX_CONTEXT_DESC {
UINT TDES0;
UINT TDES1;
UINT TDES2;
UINT TDES3;
};
typedef struct s_TX_CONTEXT_DESC t_TX_CONTEXT_DESC;
struct s_RX_NORMAL_DESC {
UINT RDES0;
UINT RDES1;
UINT RDES2;
UINT RDES3;
};
typedef struct s_RX_NORMAL_DESC t_RX_NORMAL_DESC;
struct s_TX_NORMAL_DESC {
UINT TDES0;
UINT TDES1;
UINT TDES2;
UINT TDES3;
};
typedef struct s_TX_NORMAL_DESC t_TX_NORMAL_DESC;
struct s_tx_error_counters {
UINT tx_errors;
};
typedef struct s_tx_error_counters t_tx_error_counters;
struct s_rx_error_counters {
UINT rx_errors;
};
typedef struct s_rx_error_counters t_rx_error_counters;
struct s_rx_pkt_features {
UINT pkt_attributes;
UINT vlan_tag;
};
typedef struct s_rx_pkt_features t_rx_pkt_features;
struct s_tx_pkt_features {
UINT pkt_attributes;
UINT vlan_tag;
ULONG mss;
ULONG hdr_len;
ULONG pay_len;
UCHAR ipcss;
UCHAR ipcso;
USHORT ipcse;
UCHAR tucss;
UCHAR tucso;
USHORT tucse;
UINT pkt_type;
ULONG tcp_udp_hdr_len;
};
typedef struct s_tx_pkt_features t_tx_pkt_features;
typedef enum {
EDWC_ETH_QOS_DMA_ISR_DC0IS,
EDWC_ETH_QOS_DMA_SR0_TI,
EDWC_ETH_QOS_DMA_SR0_TPS,
EDWC_ETH_QOS_DMA_SR0_TBU,
EDWC_ETH_QOS_DMA_SR0_RI,
EDWC_ETH_QOS_DMA_SR0_RBU,
EDWC_ETH_QOS_DMA_SR0_RPS,
EDWC_ETH_QOS_DMA_SR0_FBE,
EDWC_ETH_QOS_ALL
} e_DWC_ETH_QOS_int_id;
typedef enum {
EDWC_ETH_QOS_256 = 0x0,
EDWC_ETH_QOS_512 = 0x1,
EDWC_ETH_QOS_1K = 0x3,
EDWC_ETH_QOS_2K = 0x7,
EDWC_ETH_QOS_4K = 0xf,
EDWC_ETH_QOS_8K = 0x1f,
EDWC_ETH_QOS_16K = 0x3f,
EDWC_ETH_QOS_32K = 0x7f
} EDWC_ETH_QOS_MTL_FIFO_SIZE;
/* do forward declaration of private data structure */
struct DWC_ETH_QOS_prv_data;
struct DWC_ETH_QOS_tx_wrapper_descriptor;
struct hw_if_struct {
INT(*tx_complete) (struct s_TX_NORMAL_DESC *);
INT(*tx_window_error) (struct s_TX_NORMAL_DESC *);
INT(*tx_aborted_error) (struct s_TX_NORMAL_DESC *);
INT(*tx_carrier_lost_error) (struct s_TX_NORMAL_DESC *);
INT(*tx_fifo_underrun) (struct s_TX_NORMAL_DESC *);
INT(*tx_get_collision_count) (struct s_TX_NORMAL_DESC *);
INT(*tx_handle_aborted_error) (struct s_TX_NORMAL_DESC *);
INT(*tx_update_fifo_threshold) (struct s_TX_NORMAL_DESC *);
/*tx threshold config */
INT(*tx_config_threshold) (UINT);
INT(*set_promiscuous_mode) (VOID);
INT(*set_all_multicast_mode) (VOID);
INT(*set_multicast_list_mode) (VOID);
INT(*set_unicast_mode) (VOID);
INT(*enable_rx_csum) (void);
INT(*disable_rx_csum) (void);
INT(*get_rx_csum_status) (void);
INT(*read_phy_regs) (INT, INT, INT *);
INT(*write_phy_regs) (INT, INT, INT);
INT(*set_full_duplex) (VOID);
INT(*set_half_duplex) (VOID);
INT(*set_mii_speed_100) (VOID);
INT(*set_mii_speed_10) (VOID);
INT(*set_gmii_speed) (VOID);
/* for PMT */
INT(*start_dma_rx) (UINT);
INT(*stop_dma_rx) (UINT);
INT(*start_dma_tx) (UINT);
INT(*stop_dma_tx) (UINT);
INT(*start_mac_tx_rx) (VOID);
INT(*stop_mac_tx_rx) (VOID);
INT(*init) (struct DWC_ETH_QOS_prv_data *);
INT(*exit) (void);
INT(*init_offload) (struct DWC_ETH_QOS_prv_data *);
INT(*exit_offload) (void);
INT(*enable_int) (e_DWC_ETH_QOS_int_id);
INT(*disable_int) (e_DWC_ETH_QOS_int_id);
void (*pre_xmit)(struct DWC_ETH_QOS_prv_data *, UINT, UINT);
void (*dev_read)(struct DWC_ETH_QOS_prv_data *, UINT QINX);
void (*tx_desc_init)(struct DWC_ETH_QOS_prv_data *, UINT QINX);
void (*rx_desc_init)(struct DWC_ETH_QOS_prv_data *, UINT QINX);
void (*rx_desc_reset)(UINT, struct DWC_ETH_QOS_prv_data *,
UINT, UINT QINX);
INT(*tx_desc_reset) (UINT, struct DWC_ETH_QOS_prv_data *, UINT QINX);
/* last tx segmnet reports the tx status */
INT(*get_tx_desc_ls) (struct s_TX_NORMAL_DESC *);
INT(*get_tx_desc_ctxt) (struct s_TX_NORMAL_DESC *);
void (*update_rx_tail_ptr)(unsigned int QINX, unsigned int dma_addr);
/* for FLOW ctrl */
INT(*enable_rx_flow_ctrl) (VOID);
INT(*disable_rx_flow_ctrl) (VOID);
INT(*enable_tx_flow_ctrl) (UINT);
INT(*disable_tx_flow_ctrl) (UINT);
/* for PMT operations */
INT(*enable_magic_pmt) (VOID);
INT(*disable_magic_pmt) (VOID);
INT(*enable_remote_pmt) (VOID);
INT(*disable_remote_pmt) (VOID);
INT(*configure_rwk_filter) (UINT *, UINT);
/* for RX watchdog timer */
INT(*config_rx_watchdog) (UINT, u32 riwt);
/* for RX and TX threshold config */
INT(*config_rx_threshold) (UINT ch_no, UINT val);
INT(*config_tx_threshold) (UINT ch_no, UINT val);
/* for RX and TX Store and Forward Mode config */
INT(*config_rsf_mode) (UINT ch_no, UINT val);
INT(*config_tsf_mode) (UINT ch_no, UINT val);
/* for TX DMA Operate on Second Frame config */
INT(*config_osf_mode) (UINT ch_no, UINT val);
/* for INCR/INCRX config */
INT(*config_incr_incrx_mode) (UINT val);
/* for AXI PBL config */
INT(*config_axi_pbl_val) (UINT val);
/* for AXI WORL config */
INT(*config_axi_worl_val) (UINT val);
/* for AXI RORL config */
INT(*config_axi_rorl_val) (UINT val);
/* for RX and TX PBL config */
INT(*config_rx_pbl_val) (UINT ch_no, UINT val);
INT(*get_rx_pbl_val) (UINT ch_no);
INT(*config_tx_pbl_val) (UINT ch_no, UINT val);
INT(*get_tx_pbl_val) (UINT ch_no);
INT(*config_pblx8) (UINT ch_no, UINT val);
/* for TX vlan control */
VOID(*enable_vlan_reg_control) (struct DWC_ETH_QOS_tx_wrapper_descriptor *desc_data);
VOID(*enable_vlan_desc_control) (struct DWC_ETH_QOS_prv_data *pdata);
/* for rx vlan stripping */
/* VOID(*config_rx_outer_vlan_stripping) (u32); */
/* VOID(*config_rx_inner_vlan_stripping) (u32); */
/* for sa(source address) insert/replace */
VOID(*configure_mac_addr0_reg) (UCHAR *);
VOID(*configure_mac_addr1_reg) (UCHAR *);
VOID(*configure_sa_via_reg) (u32);
/* for handling multi-queue */
INT(*disable_rx_interrupt)(UINT);
INT(*enable_rx_interrupt)(UINT);
/* for handling MMC */
INT(*disable_mmc_interrupts)(VOID);
INT(*config_mmc_counters)(VOID);
/* for handling split header */
INT(*config_split_header_mode)(UINT QINX, USHORT sph_en);
INT(*config_header_size)(USHORT header_size);
/* for handling DCB and AVB */
INT(*set_dcb_algorithm)(UCHAR dcb_algorithm);
INT(*set_dcb_queue_weight)(UINT QINX, UINT q_weight);
INT(*set_tx_queue_operating_mode)(UINT QINX, UINT q_mode);
INT(*set_avb_algorithm)(UINT QINX, UCHAR avb_algorithm);
INT(*config_credit_control)(UINT QINX, UINT cc);
INT(*config_send_slope)(UINT QINX, UINT send_slope);
INT(*config_idle_slope)(UINT QINX, UINT idle_slope);
INT(*config_high_credit)(UINT QINX, UINT hi_credit);
INT(*config_low_credit)(UINT QINX, UINT lo_credit);
INT(*config_slot_num_check)(UINT QINX, UCHAR slot_check);
INT(*config_advance_slot_num_check)(UINT QINX, UCHAR adv_slot_check);
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
void (*tx_desc_init_pg)(struct DWC_ETH_QOS_prv_data *, UINT QINX);
void (*rx_desc_init_pg)(struct DWC_ETH_QOS_prv_data *, UINT QINX);
INT(*set_ch_arb_weights)(UINT QINX, UCHAR weight);
INT(*config_slot_interrupt)(UINT QINX, UCHAR config);
INT(*set_slot_count)(UINT QINX, UCHAR SLOTCOUNT);
INT(*set_tx_rx_prio_policy)(UCHAR prio_policy);
INT(*set_tx_rx_prio)(UCHAR prio);
INT(*set_tx_rx_prio_ratio)(UCHAR prio_ratio);
INT(*set_dma_tx_arb_algorithm)(UCHAR arb_algo);
INT(*prepare_dev_pktgen)(struct DWC_ETH_QOS_prv_data *);
#endif /* end of DWC_ETH_QOS_CONFIG_PGTEST */
/* for hw time stamping */
INT(*config_hw_time_stamping)(UINT);
INT(*config_sub_second_increment)(unsigned long ptp_clock);
INT(*config_default_addend)(struct DWC_ETH_QOS_prv_data *pdata, unsigned long ptp_clock);
INT(*init_systime)(UINT, UINT);
INT(*config_addend)(UINT);
INT(*adjust_systime)(UINT, UINT, INT, bool);
ULONG_LONG(*get_systime)(void);
UINT (*get_tx_tstamp_status)(struct s_TX_NORMAL_DESC *txdesc);
ULONG_LONG(*get_tx_tstamp)(struct s_TX_NORMAL_DESC *txdesc);
UINT (*get_tx_tstamp_status_via_reg)(void);
ULONG_LONG(*get_tx_tstamp_via_reg)(void);
UINT (*rx_tstamp_available)(struct s_RX_NORMAL_DESC *rxdesc);
UINT (*get_rx_tstamp_status)(struct s_RX_CONTEXT_DESC *rxdesc);
ULONG_LONG(*get_rx_tstamp)(struct s_RX_CONTEXT_DESC *rxdesc);
INT(*drop_tx_status_enabled)(void);
/* for l2, l3 and l4 layer filtering */
INT(*config_l2_da_perfect_inverse_match)(INT perfect_inverse_match);
INT(*update_mac_addr32_127_low_high_reg)(INT idx, UCHAR addr[]);
INT(*update_mac_addr1_31_low_high_reg)(INT idx, UCHAR addr[]);
INT(*update_hash_table_reg)(INT idx, UINT data);
INT(*config_mac_pkt_filter_reg)(UCHAR, UCHAR, UCHAR, UCHAR, UCHAR);
INT(*config_l3_l4_filter_enable)(INT);
INT(*config_l3_filters)(INT filter_no, INT enb_dis, INT ipv4_ipv6_match,
INT src_dst_addr_match, INT perfect_inverse_match);
INT(*update_ip4_addr0)(INT filter_no, UCHAR addr[]);
INT(*update_ip4_addr1)(INT filter_no, UCHAR addr[]);
INT(*update_ip6_addr)(INT filter_no, USHORT addr[]);
INT(*config_l4_filters)(INT filter_no, INT enb_dis,
INT tcp_udp_match, INT src_dst_port_match,
INT perfect_inverse_match);
INT(*update_l4_sa_port_no)(INT filter_no, USHORT port_no);
INT(*update_l4_da_port_no)(INT filter_no, USHORT port_no);
/* for VLAN filtering */
INT(*get_vlan_hash_table_reg)(void);
INT(*update_vlan_hash_table_reg)(USHORT data);
INT(*update_vlan_id)(USHORT vid);
INT(*config_vlan_filtering)(INT filter_enb_dis,
INT perfect_hash_filtering,
INT perfect_inverse_match);
INT(*config_mac_for_vlan_pkt)(void);
UINT (*get_vlan_tag_comparison)(void);
INT(*config_vlan_tag_data)(UINT vlan_tag,
INT vlan_reg_offset,
bool enable_12_bit_vlan_tag_comparison);
/* for differnet PHY interconnect */
INT(*control_an)(bool enable, bool restart);
INT(*get_an_adv_pause_param)(void);
INT(*get_an_adv_duplex_param)(void);
INT(*get_lp_an_adv_pause_param)(void);
INT(*get_lp_an_adv_duplex_param)(void);
/* for EEE */
INT(*set_eee_mode)(void);
INT(*reset_eee_mode)(void);
INT(*set_eee_pls)(int phy_link);
INT(*set_eee_timer)(int lpi_lst, int lpi_twt);
u32 (*get_lpi_status)(void);
INT(*set_lpi_tx_automate)(void);
INT(*set_lpi_tx_auto_entry_timer_en)(void);
INT(*set_lpi_tx_auto_entry_timer)(u32);
INT(*set_lpi_us_tic_counter)(u32);
/* for ARP */
INT(*config_arp_offload)(int enb_dis);
INT(*update_arp_offload_ip_addr)(UCHAR addr[]);
/* for MAC loopback */
INT(*config_mac_loopback_mode)(UINT);
/* for MAC Double VLAN Processing config */
INT(*config_tx_outer_vlan)(UINT op_type, UINT outer_vlt);
INT(*config_tx_inner_vlan)(UINT op_type, UINT inner_vlt);
INT(*config_svlan)(UINT);
VOID(*config_dvlan)(bool enb_dis);
VOID(*config_rx_outer_vlan_stripping)(u32);
VOID(*config_rx_inner_vlan_stripping)(u32);
/* for PFC */
void (*config_pfc)(int enb_dis);
/* for PTP offloading */
VOID(*config_ptpoffload_engine)(UINT, UINT);
/* For enabling PHY interrupt handling */
int (*enable_mac_phy_interrupt)(void);
};
/* wrapper buffer structure to hold transmit pkt details */
struct DWC_ETH_QOS_tx_buffer {
dma_addr_t dma; /* dma address of skb */
struct sk_buff *skb; /* virtual address of skb */
unsigned short len; /* length of first skb */
unsigned char buf1_mapped_as_page;
dma_addr_t dma2; /* dam address of second skb */
unsigned short len2; /* length of second skb */
unsigned char buf2_mapped_as_page;
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
unsigned char slot_number;
#endif
phys_addr_t ipa_tx_buff_phy_addr; /* physical address of ipa TX buff */
};
struct DWC_ETH_QOS_tx_wrapper_descriptor {
char *desc_name; /* ID of descriptor */
struct s_TX_NORMAL_DESC **tx_desc_ptrs;
dma_addr_t *tx_desc_dma_addrs;
struct DWC_ETH_QOS_tx_buffer **tx_buf_ptrs;
void **ipa_tx_buff_pool_va_addrs_base;
dma_addr_t *ipa_tx_buff_pool_pa_addrs_base;
dma_addr_t ipa_tx_buff_pool_pa_addrs_base_dma_handle;
unsigned char contigous_mem;
int cur_tx; /* always gives index of desc which has to
be used for current xfer */
int dirty_tx; /* always gives index of desc which has to
be checked for xfer complete */
unsigned int free_desc_cnt; /* always gives total number of available
free desc count for driver */
unsigned int tx_pkt_queued; /* always gives total number of packets
queued for transmission */
unsigned int queue_stopped;
int packet_count;
UINT tx_threshold_val; /* contain bit value for TX threshold */
UINT tsf_on; /* set to 1 if TSF is enabled else set to 0 */
UINT osf_on; /* set to 1 if OSF is enabled else set to 0 */
UINT tx_pbl;
/* for tx vlan delete/insert/replace */
u32 tx_vlan_tag_via_reg;
u32 tx_vlan_tag_ctrl;
USHORT vlan_tag_id;
UINT vlan_tag_present;
/* for VLAN context descriptor operation */
u32 context_setup;
/* for TSO */
u32 default_mss;
};
struct DWC_ETH_QOS_tx_queue {
/* Tx descriptors */
struct DWC_ETH_QOS_tx_wrapper_descriptor tx_desc_data;
int q_op_mode;
UINT desc_cnt;
};
/* wrapper buffer structure to hold received pkt details */
struct DWC_ETH_QOS_rx_buffer {
dma_addr_t dma; /* dma address of skb */
struct sk_buff *skb; /* virtual address of skb */
void *ipa_buff_va; /* virtual address of ipa_buff */
unsigned short len; /* length of received packet */
struct page *page; /* page address */
unsigned char mapped_as_page;
bool good_pkt; /* set to 1 if it is good packet else
set to 0 */
unsigned int inte; /* set to non-zero if INTE is set for
corresponding desc */
dma_addr_t dma2; /* dma address of second skb */
struct page *page2; /* page address of second buffer */
unsigned short len2; /* length of received packet-second buffer */
unsigned short rx_hdr_size; /* header buff size in case of split header */
phys_addr_t ipa_rx_buff_phy_addr; /* physical address of ipa RX buff */
};
struct DWC_ETH_QOS_rx_wrapper_descriptor {
char *desc_name; /* ID of descriptor */
struct s_RX_NORMAL_DESC **rx_desc_ptrs;
dma_addr_t *rx_desc_dma_addrs;
struct DWC_ETH_QOS_rx_buffer **rx_buf_ptrs;
void **ipa_rx_buff_pool_va_addrs_base;
dma_addr_t *ipa_rx_buff_pool_pa_addrs_base;
dma_addr_t ipa_rx_buff_pool_pa_addrs_base_dma_handle;
unsigned char contigous_mem;
int cur_rx; /* always gives index of desc which needs to
be checked for packet availabilty */
int dirty_rx;
unsigned int pkt_received; /* always gives total number of packets
received from device in one RX interrupt */
unsigned int skb_realloc_idx;
unsigned int skb_realloc_threshold;
/* for rx coalesce schem */
int use_riwt; /* set to 1 if RX watchdog timer should be used
for RX interrupt mitigation */
u32 rx_riwt;
u32 rx_coal_frames; /* Max no of pkts to be received before
an RX interrupt */
UINT rx_threshold_val; /* contain bit vlaue for RX threshold */
UINT rsf_on; /* set to 1 if RSF is enabled else set to 0 */
UINT rx_pbl;
struct sk_buff *skb_top; /* points to first skb in the chain
in case of jumbo pkts */
/* for rx vlan stripping */
u32 rx_inner_vlan_strip;
u32 rx_outer_vlan_strip;
};
struct DWC_ETH_QOS_rx_queue {
/* Rx descriptors */
struct DWC_ETH_QOS_rx_wrapper_descriptor rx_desc_data;
struct napi_struct napi;
struct DWC_ETH_QOS_prv_data *pdata;
#ifdef DWC_INET_LRO
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_arr[DWC_ETH_QOS_MAX_LRO_DESC];
int lro_flush_needed;
#endif
UINT desc_cnt;
};
struct desc_if_struct {
INT(*alloc_queue_struct) (struct DWC_ETH_QOS_prv_data *);
void (*free_queue_struct)(struct DWC_ETH_QOS_prv_data *);
INT(*alloc_buff_and_desc) (struct DWC_ETH_QOS_prv_data *);
void (*realloc_skb)(struct DWC_ETH_QOS_prv_data *, UINT);
void (*unmap_rx_skb)(struct DWC_ETH_QOS_prv_data *,
struct DWC_ETH_QOS_rx_buffer *);
void (*unmap_tx_skb)(struct DWC_ETH_QOS_prv_data *,
struct DWC_ETH_QOS_tx_buffer *);
unsigned int (*map_tx_skb)(struct net_device *, struct sk_buff *);
void (*tx_free_mem)(struct DWC_ETH_QOS_prv_data *);
void (*rx_free_mem)(struct DWC_ETH_QOS_prv_data *);
void (*wrapper_tx_desc_init)(struct DWC_ETH_QOS_prv_data *);
void (*wrapper_tx_desc_init_single_q)(struct DWC_ETH_QOS_prv_data *,
UINT);
void (*wrapper_rx_desc_init)(struct DWC_ETH_QOS_prv_data *);
void (*wrapper_rx_desc_init_single_q)(struct DWC_ETH_QOS_prv_data *,
UINT);
void (*rx_skb_free_mem)(struct DWC_ETH_QOS_prv_data *, UINT);
void (*rx_skb_free_mem_single_q)(struct DWC_ETH_QOS_prv_data *, UINT);
void (*tx_skb_free_mem)(struct DWC_ETH_QOS_prv_data *, UINT);
void (*tx_skb_free_mem_single_q)(struct DWC_ETH_QOS_prv_data *, UINT);
int (*handle_tso)(struct net_device *dev, struct sk_buff *skb);
};
/*
* This structure contains different flags and each flags will indicates
* different hardware features.
*/
struct DWC_ETH_QOS_hw_features {
/* HW Feature Register0 */
unsigned int mii_sel; /* 10/100 Mbps support */
unsigned int gmii_sel; /* 1000 Mbps support */
unsigned int hd_sel; /* Half-duplex support */
unsigned int pcs_sel; /* PCS registers(TBI, SGMII or RTBI PHY
interface) */
unsigned int vlan_hash_en; /* VLAN Hash filter selected */
unsigned int sma_sel; /* SMA(MDIO) Interface */
unsigned int rwk_sel; /* PMT remote wake-up packet */
unsigned int mgk_sel; /* PMT magic packet */
unsigned int mmc_sel; /* RMON module */
unsigned int arp_offld_en; /* ARP Offload features is selected */
unsigned int ts_sel; /* IEEE 1588-2008 Adavanced timestamp */
unsigned int eee_sel; /* Energy Efficient Ethernet is enabled */
unsigned int tx_coe_sel; /* Tx Checksum Offload is enabled */
unsigned int rx_coe_sel; /* Rx Checksum Offload is enabled */
unsigned int mac_addr16_sel; /* MAC Addresses 1-16 are selected */
unsigned int mac_addr32_sel; /* MAC Addresses 32-63 are selected */
unsigned int mac_addr64_sel; /* MAC Addresses 64-127 are selected */
unsigned int tsstssel; /* Timestamp System Time Source */
unsigned int speed_sel; /* Speed Select */
unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
unsigned int act_phy_sel; /* Active PHY Selected */
/* 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_hword; /* Advance timestamping High Word
selected */
unsigned int dcb_en; /* DCB Feature Enable */
unsigned int sph_en; /* Split Header Feature Enable */
unsigned int tso_en; /* TCP Segmentation Offload Enable */
unsigned int dma_debug_gen; /* DMA debug registers are enabled */
unsigned int av_sel; /* AV Feature Enabled */
unsigned int lp_mode_en; /* Low Power Mode Enabled */
unsigned int hash_tbl_sz; /* Hash Table Size */
unsigned int l3l4_filter_num; /* Total 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 Auxiliary snapshot
inputs */
};
/* structure to hold MMC values */
struct DWC_ETH_QOS_mmc_counters {
/* MMC TX counters */
unsigned long mmc_tx_octetcount_gb;
unsigned long mmc_tx_framecount_gb;
unsigned long mmc_tx_broadcastframe_g;
unsigned long mmc_tx_multicastframe_g;
unsigned long mmc_tx_64_octets_gb;
unsigned long mmc_tx_65_to_127_octets_gb;
unsigned long mmc_tx_128_to_255_octets_gb;
unsigned long mmc_tx_256_to_511_octets_gb;
unsigned long mmc_tx_512_to_1023_octets_gb;
unsigned long mmc_tx_1024_to_max_octets_gb;
unsigned long mmc_tx_unicast_gb;
unsigned long mmc_tx_multicast_gb;
unsigned long mmc_tx_broadcast_gb;
unsigned long mmc_tx_underflow_error;
unsigned long mmc_tx_singlecol_g;
unsigned long mmc_tx_multicol_g;
unsigned long mmc_tx_deferred;
unsigned long mmc_tx_latecol;
unsigned long mmc_tx_exesscol;
unsigned long mmc_tx_carrier_error;
unsigned long mmc_tx_octetcount_g;
unsigned long mmc_tx_framecount_g;
unsigned long mmc_tx_excessdef;
unsigned long mmc_tx_pause_frame;
unsigned long mmc_tx_vlan_frame_g;
unsigned long mmc_tx_osize_frame_g;
/* MMC RX counters */
unsigned long mmc_rx_framecount_gb;
unsigned long mmc_rx_octetcount_gb;
unsigned long mmc_rx_octetcount_g;
unsigned long mmc_rx_broadcastframe_g;
unsigned long mmc_rx_multicastframe_g;
unsigned long mmc_rx_crc_errror;
unsigned long mmc_rx_align_error;
unsigned long mmc_rx_run_error;
unsigned long mmc_rx_jabber_error;
unsigned long mmc_rx_undersize_g;
unsigned long mmc_rx_oversize_g;
unsigned long mmc_rx_64_octets_gb;
unsigned long mmc_rx_65_to_127_octets_gb;
unsigned long mmc_rx_128_to_255_octets_gb;
unsigned long mmc_rx_256_to_511_octets_gb;
unsigned long mmc_rx_512_to_1023_octets_gb;
unsigned long mmc_rx_1024_to_max_octets_gb;
unsigned long mmc_rx_unicast_g;
unsigned long mmc_rx_length_error;
unsigned long mmc_rx_outofrangetype;
unsigned long mmc_rx_pause_frames;
unsigned long mmc_rx_fifo_overflow;
unsigned long mmc_rx_vlan_frames_gb;
unsigned long mmc_rx_watchdog_error;
unsigned long mmc_rx_receive_error;
unsigned long mmc_rx_ctrl_frames_g;
/* IPC */
unsigned long mmc_rx_ipc_intr_mask;
unsigned long mmc_rx_ipc_intr;
/* IPv4 */
unsigned long mmc_rx_ipv4_gd;
unsigned long mmc_rx_ipv4_hderr;
unsigned long mmc_rx_ipv4_nopay;
unsigned long mmc_rx_ipv4_frag;
unsigned long mmc_rx_ipv4_udp_csum_disable;
/* IPV6 */
unsigned long mmc_rx_ipv6_gd_octets;
unsigned long mmc_rx_ipv6_hderr_octets;
unsigned long mmc_rx_ipv6_nopay_octets;
/* Protocols */
unsigned long mmc_rx_udp_gd;
unsigned long mmc_rx_udp_csum_err;
unsigned long mmc_rx_tcp_gd;
unsigned long mmc_rx_tcp_csum_err;
unsigned long mmc_rx_icmp_gd;
unsigned long mmc_rx_icmp_csum_err;
/* IPv4 */
unsigned long mmc_rx_ipv4_gd_octets;
unsigned long mmc_rx_ipv4_hderr_octets;
unsigned long mmc_rx_ipv4_nopay_octets;
unsigned long mmc_rx_ipv4_frag_octets;
unsigned long mmc_rx_ipv4_udp_csum_dis_octets;
/* IPV6 */
unsigned long mmc_rx_ipv6_gd;
unsigned long mmc_rx_ipv6_hderr;
unsigned long mmc_rx_ipv6_nopay;
/* Protocols */
unsigned long mmc_rx_udp_gd_octets;
unsigned long mmc_rx_udp_csum_err_octets;
unsigned long mmc_rx_tcp_gd_octets;
unsigned long mmc_rx_tcp_csum_err_octets;
unsigned long mmc_rx_icmp_gd_octets;
unsigned long mmc_rx_icmp_csum_err_octets;
/* LPI Rx and Tx Transition counters */
unsigned long mmc_emac_rx_lpi_tran_cntr;
unsigned long mmc_emac_tx_lpi_tran_cntr;
};
struct DWC_ETH_QOS_extra_stats {
unsigned long q_re_alloc_rx_buf_failed[DWC_ETH_QOS_RXQ_CNT];
/* Tx/Rx IRQ error info */
unsigned long tx_process_stopped_irq_n[DWC_ETH_QOS_TXQ_CNT];
unsigned long rx_process_stopped_irq_n[DWC_ETH_QOS_RXQ_CNT];
unsigned long tx_buf_unavailable_irq_n[DWC_ETH_QOS_TXQ_CNT];
unsigned long rx_buf_unavailable_irq_n[DWC_ETH_QOS_RXQ_CNT];
unsigned long rx_watchdog_irq_n;
unsigned long fatal_bus_error_irq_n;
unsigned long pmt_irq_n;
/* Tx/Rx IRQ Events */
unsigned long tx_normal_irq_n[DWC_ETH_QOS_TXQ_CNT];
unsigned long rx_normal_irq_n[DWC_ETH_QOS_RXQ_CNT];
unsigned long napi_poll_n;
unsigned long tx_clean_n[DWC_ETH_QOS_TXQ_CNT];
/* EEE */
unsigned long tx_path_in_lpi_mode_irq_n;
unsigned long tx_path_exit_lpi_mode_irq_n;
unsigned long rx_path_in_lpi_mode_irq_n;
unsigned long rx_path_exit_lpi_mode_irq_n;
/* Tx/Rx frames */
unsigned long tx_pkt_n;
unsigned long rx_pkt_n;
unsigned long tx_vlan_pkt_n;
unsigned long rx_vlan_pkt_n;
unsigned long tx_timestamp_captured_n;
unsigned long rx_timestamp_captured_n;
unsigned long tx_tso_pkt_n;
unsigned long rx_split_hdr_pkt_n;
/* Tx/Rx frames per channels/queues */
unsigned long q_tx_pkt_n[DWC_ETH_QOS_TXQ_CNT];
unsigned long q_rx_pkt_n[DWC_ETH_QOS_RXQ_CNT];
/* DMA status registers for all channels [0-4] */
unsigned long dma_ch_status[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_intr_enable[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_intr_status;
unsigned long dma_debug_status0;
unsigned long dma_debug_status1;
/* RX DMA descriptor status registers for all channels [0-4] */
unsigned long dma_ch_rx_control[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_rxdesc_list_addr[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_rxdesc_ring_len[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_curr_app_rxdesc[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_rxdesc_tail_ptr[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_curr_app_rxbuf[DWC_ETH_QOS_RXQ_CNT];
unsigned long dma_ch_miss_frame_count[DWC_ETH_QOS_RXQ_CNT];
/* TX DMA descriptors status for all channels [0-5] */
unsigned long dma_ch_tx_control[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_txdesc_list_addr[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_txdesc_ring_len[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_curr_app_txdesc[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_txdesc_tail_ptr[DWC_ETH_QOS_TXQ_CNT];
unsigned long dma_ch_curr_app_txbuf[DWC_ETH_QOS_TXQ_CNT];
};
struct DWC_ETH_QOS_ipa_stats {
unsigned int ipa_rx_Desc_Ring_Base;
unsigned int ipa_rx_Desc_Ring_Size;
unsigned int ipa_rx_Buff_Ring_Base;
unsigned int ipa_rx_Buff_Ring_Size;
unsigned int ipa_rx_Db_Int_Raised;
unsigned int ipa_rx_Cur_Desc_Ptr_Indx;
unsigned int ipa_rx_Tail_Ptr_Indx;
unsigned int ipa_rx_DMA_Status;
unsigned int ipa_rx_DMA_Ch_Status;
unsigned int ipa_rx_DMA_Ch_underflow;
unsigned int ipa_rx_DMA_Ch_stopped;
unsigned int ipa_rx_DMA_Ch_complete;
unsigned int ipa_rx_Int_Mask;
unsigned long ipa_rx_Transfer_Complete_irq;
unsigned long ipa_rx_Transfer_Stopped_irq;
unsigned long ipa_rx_Underflow_irq;
unsigned long ipa_rx_Early_Trans_Comp_irq;
unsigned int ipa_tx_Desc_Ring_Base;
unsigned int ipa_tx_Desc_Ring_Size;
unsigned int ipa_tx_Buff_Ring_Base;
unsigned int ipa_tx_Buff_Ring_Size;
unsigned int ipa_tx_Db_Int_Raised;
unsigned long ipa_tx_Curr_Desc_Ptr_Indx;
unsigned long ipa_tx_Tail_Ptr_Indx;
unsigned int ipa_tx_DMA_Status;
unsigned int ipa_tx_DMA_Ch_Status;
unsigned int ipa_tx_DMA_Ch_underflow;
unsigned int ipa_tx_DMA_Transfer_stopped;
unsigned int ipa_tx_DMA_Transfer_complete;
unsigned int ipa_tx_Int_Mask;
unsigned long ipa_tx_Transfer_Complete_irq;
unsigned long ipa_tx_Transfer_Stopped_irq;
unsigned long ipa_tx_Underflow_irq;
unsigned long ipa_tx_Early_Trans_Cmp_irq;
unsigned long ipa_tx_Fatal_err_irq;
unsigned long ipa_tx_Desc_Err_irq;
unsigned long long ipa_ul_exception;
};
typedef enum {
RGMII_MODE,
RMII_MODE,
MII_MODE
}IO_MACRO_PHY_MODE;
struct DWC_ETH_QOS_res_data {
u32 emac_mem_base;
u32 emac_mem_size;
u32 rgmii_mem_base;
u32 rgmii_mem_size;
u32 sbd_intr;
u32 lpi_intr;
u32 ptp_pps_avb_class_a_irq;
u32 ptp_pps_avb_class_b_irq;
u32 io_macro_tx_mode_non_id;
IO_MACRO_PHY_MODE io_macro_phy_intf;
u32 phy_intr;
#ifdef PER_CH_INT
u32 tx_ch_intr[5];
u32 rx_ch_intr[4];
#endif
/* GPIOs */
bool is_gpio_phy_intr_redirect;
bool is_gpio_phy_reset;
bool is_pinctrl_names;
int gpio_phy_intr_redirect;
int gpio_phy_reset;
struct pinctrl *pinctrl;
struct pinctrl_state *rgmii_rxc_suspend_state;
struct pinctrl_state *rgmii_rxc_resume_state;
/* Regulators */
struct regulator *gdsc_emac;
struct regulator *reg_rgmii;
struct regulator *reg_emac_phy;
struct regulator *reg_rgmii_io_pads;
/* Clocks */
struct clk *axi_clk;
struct clk *ahb_clk;
struct clk *rgmii_clk;
struct clk *ptp_clk;
unsigned int emac_hw_version_type;
bool early_eth_en;
bool pps_lpass_conn_en;
};
struct DWC_ETH_QOS_prv_ipa_data {
phys_addr_t uc_db_rx_addr;
phys_addr_t uc_db_tx_addr;
u32 ipa_client_hndl;
/* IPA state variables */
/* State of EMAC HW initilization */
bool emac_dev_ready;
/* State of IPA readiness */
bool ipa_ready;
/* State of IPA and IPA UC readiness */
bool ipa_uc_ready;
/* State of IPA Offload intf registration with IPA driver */
bool ipa_offload_init;
/* State of IPA pipes connection */
bool ipa_offload_conn;
/* State of debugfs creation */
bool ipa_debugfs_exists;
/* State of IPA offload suspended by user */
bool ipa_offload_susp;
/* State of IPA offload enablement from PHY link event*/
bool ipa_offload_link_down;
/* Dev state */
struct work_struct ntn_ipa_rdy_work;
UINT ipa_ver;
bool vlan_enable;
unsigned short vlan_id;
struct mutex ipa_lock;
struct dentry *debugfs_ipa_stats;
struct dentry *debugfs_dma_stats;
struct dentry *debugfs_suspend_ipa_offload;
};
struct DWC_ETH_QOS_prv_data {
struct net_device *dev;
struct platform_device *pdev;
struct DWC_ETH_QOS_prv_ipa_data prv_ipa;
bool ipa_enabled;
struct DWC_ETH_QOS_res_data *res_data;
bool phy_intr_en;
bool always_on_phy;
/* Module parameter to check if PHY interrupt should be
enabled. Default value is true. */
bool enable_phy_intr;
struct msm_bus_scale_pdata *bus_scale_vec;
uint32_t bus_hdl;
u32 rgmii_clk_rate;
unsigned int vote_idx;
int clks_suspended;
struct completion clk_enable_done;
#ifdef PER_CH_INT
bool per_ch_intr_en;
#endif
struct mutex mlock;
spinlock_t lock;
spinlock_t tx_lock;
struct mutex pmt_lock;
UINT mem_start_addr;
UINT mem_size;
INT irq_number;
INT lpi_irq;
struct hw_if_struct hw_if;
struct desc_if_struct desc_if;
struct s_tx_error_counters tx_error_counters;
struct s_rx_error_counters rx_error_counters;
struct s_rx_pkt_features rx_pkt_features;
struct s_tx_pkt_features tx_pkt_features;
/* TX Queue */
struct DWC_ETH_QOS_tx_queue *tx_queue;
UCHAR tx_queue_cnt;
UINT TX_QINX;
/* RX Queue */
struct DWC_ETH_QOS_rx_queue *rx_queue;
UCHAR rx_queue_cnt;
UINT RX_QINX;
struct mii_bus *mii;
struct phy_device *phydev;
int oldlink;
int speed;
int oldduplex;
int phyaddr;
int bus_id;
u32 dev_state;
u32 interface;
/* saving state for Wake-on-LAN */
int wolopts;
/* state of enabled wol options in PHY*/
u32 phy_wol_wolopts;
/* state of supported wol options in PHY*/
u32 phy_wol_supported;
/* Helper macros for handling FLOW control in HW */
#define DWC_ETH_QOS_FLOW_CTRL_OFF 0
#define DWC_ETH_QOS_FLOW_CTRL_RX 1
#define DWC_ETH_QOS_FLOW_CTRL_TX 2
#define DWC_ETH_QOS_FLOW_CTRL_TX_RX (DWC_ETH_QOS_FLOW_CTRL_TX |\
DWC_ETH_QOS_FLOW_CTRL_RX)
unsigned int flow_ctrl;
/* keeps track of previous programmed flow control options */
unsigned int oldflow_ctrl;
struct DWC_ETH_QOS_hw_features hw_feat;
/* for sa(source address) insert/replace */
u32 tx_sa_ctrl_via_desc;
u32 tx_sa_ctrl_via_reg;
unsigned char mac_addr[DWC_ETH_QOS_MAC_ADDR_LEN];
/* keeps track of power mode for API based PMT control */
u32 power_down;
u32 power_down_type;
/* AXI parameters */
UINT incr_incrx;
UINT axi_pbl;
UINT axi_worl;
UINT axi_rorl;
/* for hanlding jumbo frames and split header feature on rx path */
int (*clean_rx)(struct DWC_ETH_QOS_prv_data *pdata, int quota, UINT QINX);
int (*alloc_rx_buf)(struct DWC_ETH_QOS_prv_data *pdata,
struct DWC_ETH_QOS_rx_buffer *buffer, UINT QINX, gfp_t gfp);
unsigned int rx_buffer_len;
/* variable frame burst size */
UINT drop_tx_pktburstcnt;
unsigned int mac_enable_count; /* counter for enabling MAC transmit at
drop tx packet */
struct DWC_ETH_QOS_mmc_counters mmc;
struct DWC_ETH_QOS_extra_stats xstats;
struct DWC_ETH_QOS_ipa_stats ipa_stats;
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
struct DWC_ETH_QOS_PGSTRUCT *pg;
struct timer_list pg_timer;
INT prepare_pg_packet;
INT run_test;
INT max_counter;
struct workqueue_struct *wq0;
struct workqueue_struct *wq1;
struct workqueue_struct *wq2;
struct workqueue_struct *wq3;
struct workqueue_struct *wq4;
struct workqueue_struct *rx_wq_pg_0;
struct workqueue_struct *rx_wq_pg_1;
struct workqueue_struct *rx_wq_pg_2;
struct workqueue_struct *rx_wq_pg_3;
struct work_struct tx_work_0;
struct work_struct tx_work_1;
struct work_struct tx_work_2;
struct work_struct tx_work_3;
struct work_struct tx_work_4;
struct work_struct rx_work_pg_0;
struct work_struct rx_work_pg_1;
struct work_struct rx_work_pg_2;
struct work_struct rx_work_pg_3;
#endif /* end of DWC_ETH_QOS_CONFIG_PGTEST */
/* rx split header mode */
unsigned char rx_split_hdr;
/* for MAC loopback */
unsigned int mac_loopback_mode;
/* for hw time stamping */
unsigned char hwts_tx_en;
unsigned char hwts_rx_en;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_ops;
spinlock_t ptp_lock; /* protects registers */
unsigned int default_addend;
bool one_nsec_accuracy; /* set to 1 if one nano second accuracy
is enabled else set to zero */
/* for filtering */
int max_hash_table_size;
int max_addr_reg_cnt;
/* L3/L4 filtering */
unsigned int l3_l4_filter;
unsigned char vlan_hash_filtering;
unsigned int l2_filtering_mode; /* 0 - if perfect and 1 - if hash filtering */
/* For handling PCS(TBI/RTBI/SGMII) and RGMII/SMII interface */
unsigned int pcs_link;
unsigned int pcs_duplex;
unsigned int pcs_speed;
unsigned int pause;
unsigned int duplex;
unsigned int lp_pause;
unsigned int lp_duplex;
/* for handling EEE */
struct timer_list eee_ctrl_timer;
bool tx_path_in_lpi_mode;
bool use_lpi_tx_automate;
int eee_enabled;
int eee_active;
int tx_lpi_timer;
bool use_lpi_auto_entry_timer;
/* arp offload enable/disable. */
u32 arp_offload;
/* set to 1 when ptp offload is enabled, else 0. */
u32 ptp_offload;
/* ptp offloading mode - ORDINARY_SLAVE, ORDINARY_MASTER,
* TRANSPARENT_SLAVE, TRANSPARENT_MASTER, PTOP_TRANSPERENT.
* */
u32 ptp_offloading_mode;
/* For configuring double VLAN via descriptor/reg */
int inner_vlan_tag;
int outer_vlan_tag;
/* op_type will be
* 0/1/2/3 for none/delet/insert/replace respectively
* */
int op_type;
/* in_out will be
* 1/2/3 for outer/inner/both respectively.
* */
int in_out;
/* 0 for via registers and 1 for via descriptor */
int via_reg_or_desc;
/* this variable will hold vlan table value if vlan hash filtering
* is enabled else hold vlan id that is programmed in HW. Same is
* used to configure back into HW when device is reset during
* jumbo/split-header features.
* */
UINT vlan_ht_or_id;
/* Used when LRO is enabled,
* set to 1 if skb has TCP payload else set to 0
* */
int tcp_pkt;
unsigned int io_macro_tx_mode_non_id;
unsigned int io_macro_phy_intf;
int phy_irq;
unsigned int emac_hw_version_type;
/* QMP message for disabling ctile power collapse while XO shutdown */
struct mbox_chan *qmp_mbox_chan;
struct mbox_client *qmp_mbox_client;
struct work_struct qmp_mailbox_work;
int disable_ctile_pc;
/* Work struct for handling phy interrupt */
struct work_struct emac_phy_work;
/* Context variabled used for debugger */
struct iommu_domain *iommu_domain;
unsigned int *emac_reg_base_address;
unsigned int *rgmii_reg_base_address;
/* Debugfs base dir */
struct dentry *debugfs_dir;
/* ptp clock frequency set by PTPCLK_Config ioctl default value is 250MHz */
unsigned int ptpclk_freq;
ULONG avb_class_a_intr_cnt;
ULONG avb_class_b_intr_cnt;
/* avb_class_a dev node variables*/
dev_t avb_class_a_dev_t;
struct cdev* avb_class_a_cdev;
struct class* avb_class_a_class;
/* avb_class_b dev node variables*/
dev_t avb_class_b_dev_t;
struct cdev* avb_class_b_cdev;
struct class* avb_class_b_class;
struct delayed_work ipv6_addr_assign_wq;
bool print_kpi;
};
struct ip_params {
UCHAR mac_addr[DWC_ETH_QOS_MAC_ADDR_LEN];
bool is_valid_mac_addr;
char link_speed[32];
bool is_valid_link_speed;
char ipv4_addr_str[32];
struct in_addr ipv4_addr;
bool is_valid_ipv4_addr;
char ipv6_addr_str[48];
struct in6_ifreq ipv6_addr;
bool is_valid_ipv6_addr;
};
typedef enum {
ESAVE,
ERESTORE
} e_int_state;
#define ATH8031_PHY_ID 0x004dd074
#define ATH8035_PHY_ID 0x004dd072
#define QCA8337_PHY_ID 0x004dd036
#define ATH8030_PHY_ID 0x004dd076
#define MICREL_PHY_ID PHY_ID_KSZ9031
static const u32 qca8337_phy_ids[] = {
0x004dd035, /* qca8337 PHY*/
0x004dd036, /* qca8337 PHY*/
};
/* SMMU related */
struct emac_emb_smmu_cb_ctx {
bool valid;
struct platform_device *pdev_master;
struct platform_device *smmu_pdev;
struct dma_iommu_mapping *mapping;
struct iommu_domain *iommu_domain;
u32 va_start;
u32 va_size;
u32 va_end;
int ret;
};
extern struct emac_emb_smmu_cb_ctx emac_emb_smmu_ctx;
#define GET_MEM_PDEV_DEV (emac_emb_smmu_ctx.valid ? \
&emac_emb_smmu_ctx.smmu_pdev->dev : &pdata->pdev->dev)
/* Function prototypes*/
void DWC_ETH_QOS_init_function_ptrs_dev(struct hw_if_struct *);
void DWC_ETH_QOS_init_function_ptrs_desc(struct desc_if_struct *);
struct net_device_ops *DWC_ETH_QOS_get_netdev_ops(void);
struct ethtool_ops *DWC_ETH_QOS_get_ethtool_ops(void);
int DWC_ETH_QOS_poll_mq(struct napi_struct *, int);
void DWC_ETH_QOS_get_pdata(struct DWC_ETH_QOS_prv_data *pdata);
/* Debugfs related functions. */
int create_debug_files(void);
void remove_debug_files(void);
bool DWC_ETH_QOS_is_phy_link_up(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_set_clk_and_bus_config(struct DWC_ETH_QOS_prv_data *pdata, int speed);
int DWC_ETH_QOS_mdio_register(struct net_device *dev);
void DWC_ETH_QOS_mdio_unregister(struct net_device *dev);
INT DWC_ETH_QOS_mdio_read_direct(struct DWC_ETH_QOS_prv_data *pdata,
int phyaddr, int phyreg, int *phydata);
INT DWC_ETH_QOS_mdio_write_direct(struct DWC_ETH_QOS_prv_data *pdata,
int phyaddr, int phyreg, int phydata);
void DWC_ETH_QOS_mdio_mmd_register_write_direct(struct DWC_ETH_QOS_prv_data *pdata,
int phyaddr, int devaddr, int offset, u16 phydata);
void DWC_ETH_QOS_mdio_mmd_register_read_direct(struct DWC_ETH_QOS_prv_data *pdata,
int phyaddr, int devaddr, int offset, u16 *phydata);
void dbgpr_regs(void);
void dump_phy_registers(struct DWC_ETH_QOS_prv_data *);
void dump_tx_desc(struct DWC_ETH_QOS_prv_data *pdata, int first_desc_idx,
int last_desc_idx, int flag, UINT QINX);
void dump_rx_desc(UINT, struct s_RX_NORMAL_DESC *desc, int cur_rx);
void print_pkt(struct sk_buff *skb, int len, bool tx_rx, int desc_idx);
void DWC_ETH_QOS_get_all_hw_features(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_print_all_hw_features(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_configure_flow_ctrl(struct DWC_ETH_QOS_prv_data *pdata);
INT DWC_ETH_QOS_powerup(struct net_device *, UINT);
INT DWC_ETH_QOS_powerdown(struct net_device *, UINT, UINT);
u32 DWC_ETH_QOS_usec2riwt(u32 usec, struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_init_rx_coalesce(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_enable_all_ch_rx_interrpt(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_disable_all_ch_rx_interrpt(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_update_rx_errors(struct net_device *, unsigned int);
void DWC_ETH_QOS_stop_all_ch_tx_dma(struct DWC_ETH_QOS_prv_data *pdata);
UCHAR get_tx_queue_count(void);
UCHAR get_rx_queue_count(void);
void DWC_ETH_QOS_mmc_read(struct DWC_ETH_QOS_mmc_counters *mmc);
UINT DWC_ETH_QOS_get_total_desc_cnt(struct DWC_ETH_QOS_prv_data *pdata,
struct sk_buff *skb, UINT QINX);
int DWC_ETH_QOS_ptp_init(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_ptp_remove(struct DWC_ETH_QOS_prv_data *pdata);
phy_interface_t DWC_ETH_QOS_get_phy_interface(struct DWC_ETH_QOS_prv_data *pdata);
phy_interface_t DWC_ETH_QOS_get_io_macro_phy_interface(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_enable_ptp_clk(struct device *dev);
void DWC_ETH_QOS_disable_ptp_clk(struct device *dev);
#ifdef DWC_ETH_QOS_CONFIG_PTP
/* PTP function to find PHC Index*/
int DWC_ETH_QOS_phc_index(struct DWC_ETH_QOS_prv_data *pdata);
#endif /* end of DWC_ETH_QOS_CONFIG_PTP */
bool DWC_ETH_QOS_eee_init(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_handle_eee_interrupt(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_disable_eee_mode(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_enable_eee_mode(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_suspend_clks(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_resume_clks(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_set_clk_and_bus_config(struct DWC_ETH_QOS_prv_data *pdata, int speed);
#ifdef DWC_ETH_QOS_CONFIG_PGTEST
irqreturn_t DWC_ETH_QOS_ISR_SW_DWC_ETH_QOS_pg(int irq, void *dev_data);
void DWC_ETH_QOS_default_confs(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_handle_pg_ioctl(struct DWC_ETH_QOS_prv_data *pdata, void *ptr);
int DWC_ETH_QOS_alloc_pg(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_free_pg(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_alloc_rx_buf_pg(struct DWC_ETH_QOS_prv_data *pdata,
struct DWC_ETH_QOS_rx_buffer *buffer,
gfp_t gfp);
int DWC_ETH_QOS_alloc_tx_buf_pg(struct DWC_ETH_QOS_prv_data *pdata,
struct DWC_ETH_QOS_tx_buffer *buffer,
gfp_t gfp);
void init_pg_tx_wq(struct DWC_ETH_QOS_prv_data *pdata);
#endif /* end of DWC_ETH_QOS_CONFIG_PGTEST */
irqreturn_t DWC_ETH_QOS_ISR_SW_DWC_ETH_QOS(int irq, void *dev_id);
void DWC_ETH_QOS_handle_phy_interrupt(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_init(struct DWC_ETH_QOS_prv_data *);
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_enable_lp_mode(void);
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_config(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *);
int DWC_ETH_QOS_sdcc_set_bypass_mode(void);
int DWC_ETH_QOS_rgmii_io_macro_dll_reset(struct DWC_ETH_QOS_prv_data *pdata);
void dump_rgmii_io_macro_registers(void);
int DWC_ETH_QOS_set_rgmii_func_clk_en(void);
void DWC_ETH_QOS_set_clk_and_bus_config(struct DWC_ETH_QOS_prv_data *pdata, int speed);
#define EMAC_MDC "dev-emac-mdc"
#define EMAC_MDIO "dev-emac-mdio"
#define EMAC_RGMII_TXD0 "dev-emac-rgmii_txd0_state"
#define EMAC_RGMII_TXD1 "dev-emac-rgmii_txd1_state"
#define EMAC_RGMII_TXD2 "dev-emac-rgmii_txd2_state"
#define EMAC_RGMII_TXD3 "dev-emac-rgmii_txd3_state"
#define EMAC_RGMII_TXC "dev-emac-rgmii_txc_state"
#define EMAC_RGMII_TX_CTL "dev-emac-rgmii_tx_ctl_state"
#define EMAC_RGMII_RXD0 "dev-emac-rgmii_rxd0_state"
#define EMAC_RGMII_RXD1 "dev-emac-rgmii_rxd1_state"
#define EMAC_RGMII_RXD2 "dev-emac-rgmii_rxd2_state"
#define EMAC_RGMII_RXD3 "dev-emac-rgmii_rxd3_state"
#define EMAC_RGMII_RXC "dev-emac-rgmii_rxc_state"
#define EMAC_RGMII_RX_CTL "dev-emac-rgmii_rx_ctl_state"
#define EMAC_PHY_RESET "dev-emac-phy_reset_state"
#define EMAC_PHY_INTR "dev-emac-phy_intr"
#define EMAC_PIN_PPS0 "dev-emac_pin_pps_0"
#define EMAC_RGMII_RXC_SUSPEND "dev-emac-rgmii_rxc_suspend_state"
#define EMAC_RGMII_RXC_RESUME "dev-emac-rgmii_rxc_resume_state"
#ifdef PER_CH_INT
void DWC_ETH_QOS_handle_DMA_Int(struct DWC_ETH_QOS_prv_data *pdata, int chinx, bool);
int DWC_ETH_QOS_register_per_ch_intr(struct DWC_ETH_QOS_prv_data *pdata, int);
void DWC_ETH_QOS_deregister_per_ch_intr(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_dis_en_ch_intr(struct DWC_ETH_QOS_prv_data *pdata,
bool enable);
#endif
void DWC_ETH_QOS_defer_phy_isr_work(struct work_struct *work);
irqreturn_t DWC_ETH_QOS_PHY_ISR(int irq, void *dev_id);
void DWC_ETH_QOS_dma_desc_stats_read(struct DWC_ETH_QOS_prv_data *pdata);
void DWC_ETH_QOS_dma_desc_stats_init(struct DWC_ETH_QOS_prv_data *pdata);
int DWC_ETH_QOS_add_ipaddr(struct DWC_ETH_QOS_prv_data *);
int DWC_ETH_QOS_add_ipv6addr(struct DWC_ETH_QOS_prv_data *);
/* For debug prints*/
#define DRV_NAME "qcom-emac-dwc-eqos"
#define dev_name_ipa_rx "IPA_RX"
#define dev_name_emac_rx "EMAC_RX"
#define dev_name_ipa_tx "IPA_TX"
#define dev_name_emac_tx "EMAC_TX"
#define PRINT_MAC(eth_ptr,count) \
do {\
int i;\
unsigned char* ptr = eth_ptr;\
for ( i = 0;i <= (count);i++,(ptr)++)\
{\
printk("%02x%c",*ptr,i == (count)?' ':':');\
}\
printk("\n");\
}while(0)
#define PRINT_MAC_INFO( skb, _hw, _dir )\
do {\
struct ethhdr* eth;\
skb_reset_mac_header(skb);\
eth = eth_hdr(skb);\
printk("eth type of pkt from %s: 0x%04x \n ",dev_name_##_hw##_##_dir,ntohs(eth->h_proto) );\
printk("Dst Mac address of pkt from %s: ",dev_name_##_hw##_##_dir );\
PRINT_MAC(eth->h_dest,5);\
printk("Src Mac address of the pkt from %s: ",dev_name_##_hw##_##_dir );\
PRINT_MAC(eth->h_source,5);\
printk("Dump of next 4B of skb->data from %s: ",dev_name_##_hw##_##_dir );\
PRINT_MAC((unsigned char*)(skb->data)+ETH_HLEN,3 );\
}while(0)
#define EMACDBG(fmt, args...) \
pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define EMACINFO(fmt, args...) \
pr_info(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define EMACERR(fmt, args...) \
do {\
pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\
if (ipc_emac_log_ctxt) { \
ipc_log_string(ipc_emac_log_ctxt, \
"%s: %s[%u]:[emac] ERROR:" fmt, __FILENAME__ , \
__func__, __LINE__, ## args); \
} \
}while(0)
#ifdef YDEBUG
#define DBGPR(x...) printk(KERN_ALERT x)
#define DBGPR_REGS() dbgpr_regs()
#define DBGPHY_REGS(x...) dump_phy_registers(x)
#else
#define DBGPR(x...) do { } while (0)
#define DBGPR_REGS() do { } while (0)
#define DBGPHY_REGS(x...) do { } while (0)
#endif
#ifdef YDEBUG_PG
#define DBGPR_PG(x...) printk(KERN_ALERT x)
#else
#define DBGPR_PG(x...) do {} while (0)
#endif
#ifdef YDEBUG_MDIO
#define DBGPR_MDIO(x...) printk(KERN_ALERT x)
#else
#define DBGPR_MDIO(x...) do {} while (0)
#endif
#ifdef YDEBUG_PTP
#define DBGPR_PTP(x...) printk(KERN_ALERT x)
#else
#define DBGPR_PTP(x...) do {} while (0)
#endif
#ifdef YDEBUG_FILTER
#define DBGPR_FILTER(x...) printk(KERN_ALERT x)
#else
#define DBGPR_FILTER(x...) do {} while (0)
#endif
#ifdef YDEBUG_EEE
#define DBGPR_EEE(x...) printk(KERN_ALERT x)
#else
#define DBGPR_EEE(x...) do {} while (0)
#endif
#endif