185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* 285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Copyright 2010-2011 Calxeda, Inc. 385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This program is free software; you can redistribute it and/or modify it 585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * under the terms and conditions of the GNU General Public License, 685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * version 2, as published by the Free Software Foundation. 785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This program is distributed in the hope it will be useful, but WITHOUT 985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * more details. 1285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 1385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * You should have received a copy of the GNU General Public License along with 1485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * this program. If not, see <http://www.gnu.org/licenses/>. 1585c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 1685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/module.h> 1785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/kernel.h> 1885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/circ_buf.h> 1985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/interrupt.h> 2085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/etherdevice.h> 2185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/platform_device.h> 2285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/skbuff.h> 2385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/ethtool.h> 2485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/if.h> 2585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/crc32.h> 2685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/dma-mapping.h> 2785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#include <linux/slab.h> 2885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 2985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Register definitions */ 3085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL 0x00000000 /* MAC Configuration */ 3185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER 0x00000004 /* MAC Frame Filter */ 3285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL 0x00000018 /* MAC Flow Control */ 3385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_VLAN_TAG 0x0000001C /* VLAN Tags */ 3485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_VERSION 0x00000020 /* Version */ 3585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_VLAN_INCL 0x00000024 /* VLAN tag for tx frames */ 3685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_LPI_CTRL 0x00000028 /* LPI Control and Status */ 3785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_LPI_TIMER 0x0000002C /* LPI Timers Control */ 3885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_TX_PACE 0x00000030 /* Transmit Pace and Stretch */ 3985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_VLAN_HASH 0x00000034 /* VLAN Hash Table */ 4085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DEBUG 0x00000038 /* Debug */ 4185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_INT_STAT 0x0000003C /* Interrupt and Control */ 4285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_ADDR_HIGH(reg) (0x00000040 + ((reg) * 8)) 4385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_ADDR_LOW(reg) (0x00000044 + ((reg) * 8)) 4485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_HASH(n) (0x00000300 + (n) * 4) /* HASH table regs */ 4585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_NUM_HASH 16 4685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR 0x00000400 4785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_REMOTE_WAKE 0x00000700 /* Remote Wake-Up Frm Filter */ 4885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT 0x00000704 /* PMT Control and Status */ 4985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_CTRL 0x00000800 /* XGMAC MMC Control */ 5085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_INTR_RX 0x00000804 /* Recieve Interrupt */ 5185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_INTR_TX 0x00000808 /* Transmit Interrupt */ 5285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_INTR_MASK_RX 0x0000080c /* Recieve Interrupt Mask */ 5385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_INTR_MASK_TX 0x00000810 /* Transmit Interrupt Mask */ 5485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 5585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Hardware TX Statistics Counters */ 5685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXOCTET_GB_LO 0x00000814 5785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXOCTET_GB_HI 0x00000818 5885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXFRAME_GB_LO 0x0000081C 5985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXFRAME_GB_HI 0x00000820 6085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXBCFRAME_G 0x00000824 6185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXMCFRAME_G 0x0000082C 6285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXUCFRAME_GB 0x00000864 6385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXMCFRAME_GB 0x0000086C 6485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXBCFRAME_GB 0x00000874 6585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXUNDERFLOW 0x0000087C 6685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXOCTET_G_LO 0x00000884 6785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXOCTET_G_HI 0x00000888 6885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXFRAME_G_LO 0x0000088C 6985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXFRAME_G_HI 0x00000890 7085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXPAUSEFRAME 0x00000894 7185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_TXVLANFRAME 0x0000089C 7285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 7385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Hardware RX Statistics Counters */ 7485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXFRAME_GB_LO 0x00000900 7585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXFRAME_GB_HI 0x00000904 7685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXOCTET_GB_LO 0x00000908 7785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXOCTET_GB_HI 0x0000090C 7885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXOCTET_G_LO 0x00000910 7985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXOCTET_G_HI 0x00000914 8085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXBCFRAME_G 0x00000918 8185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXMCFRAME_G 0x00000920 8285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXCRCERR 0x00000928 8385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXRUNT 0x00000930 8485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXJABBER 0x00000934 8585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXUCFRAME_G 0x00000970 8685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXLENGTHERR 0x00000978 8785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXPAUSEFRAME 0x00000988 8885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXOVERFLOW 0x00000990 8985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXVLANFRAME 0x00000998 9085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_RXWATCHDOG 0x000009a0 9185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Control and Status Registers */ 9385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_BUS_MODE 0x00000f00 /* Bus Mode */ 9485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_TX_POLL 0x00000f04 /* Transmit Poll Demand */ 9585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_RX_POLL 0x00000f08 /* Received Poll Demand */ 9685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_RX_BASE_ADDR 0x00000f0c /* Receive List Base */ 9785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_TX_BASE_ADDR 0x00000f10 /* Transmit List Base */ 9885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_STATUS 0x00000f14 /* Status Register */ 9985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_CONTROL 0x00000f18 /* Ctrl (Operational Mode) */ 10085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_INTR_ENA 0x00000f1c /* Interrupt Enable */ 10185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_MISS_FRAME_CTR 0x00000f20 /* Missed Frame Counter */ 10285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_RI_WDOG_TIMER 0x00000f24 /* RX Intr Watchdog Timer */ 10385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_AXI_BUS 0x00000f28 /* AXI Bus Mode */ 10485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_AXI_STATUS 0x00000f2C /* AXI Status */ 10585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_DMA_HW_FEATURE 0x00000f58 /* Enabled Hardware Features */ 10685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 10785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_ADDR_AE 0x80000000 10885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 10985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* PMT Control and Status */ 11085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_POINTER_RESET 0x80000000 11185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_GLBL_UNICAST 0x00000200 11285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_WAKEUP_RX_FRM 0x00000040 11385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_MAGIC_PKT 0x00000020 11485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_WAKEUP_FRM_EN 0x00000004 11585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_MAGIC_PKT_EN 0x00000002 11685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PMT_POWERDOWN 0x00000001 11785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 11885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SPD 0x40000000 /* Speed control */ 11985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SPD_MASK 0x60000000 12085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SPD_1G 0x60000000 12185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SPD_2_5G 0x40000000 12285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SPD_10G 0x00000000 12385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SARC 0x10000000 /* Source Addr Insert/Replace */ 12485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_SARK_MASK 0x18000000 12585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_CAR 0x04000000 /* CRC Addition/Replacement */ 12685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_CAR_MASK 0x06000000 12785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_DP 0x01000000 /* Disable Padding */ 12885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on rx */ 12985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_JD 0x00400000 /* Jabber disable */ 13085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_JE 0x00100000 /* Jumbo frame */ 13185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_LM 0x00001000 /* Loop-back mode */ 13285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */ 13385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_ACS 0x00000080 /* Automatic Pad/FCS Strip */ 13485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_DDIC 0x00000010 /* Disable Deficit Idle Count */ 13585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */ 13685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ 13785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 13885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Frame Filter defines */ 13985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ 14085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */ 14185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */ 14285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */ 14385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */ 14485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */ 14585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */ 14685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */ 14785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */ 14885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_VHF 0x00000800 /* VLAN Hash Filter */ 14985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_VPF 0x00001000 /* VLAN Perfect Filter */ 15085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FRAME_FILTER_RA 0x80000000 /* Receive all mode */ 15185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 15285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC FLOW CTRL defines */ 15385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */ 15485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_PT_SHIFT 16 15585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_DZQP 0x00000080 /* Disable Zero-Quanta Phase */ 15685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_PLT 0x00000020 /* Pause Low Threshhold */ 15785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_PLT_MASK 0x00000030 /* PLT MASK */ 15885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_UP 0x00000008 /* Unicast Pause Frame Detect */ 15985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */ 16085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_TFE 0x00000002 /* Tx Flow Control Enable */ 16185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */ 16285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 16385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC_INT_STAT reg */ 164e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring#define XGMAC_INT_STAT_PMTIM 0x00800000 /* PMT Interrupt Mask */ 16585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_INT_STAT_PMT 0x0080 /* PMT Interrupt Status */ 16685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_INT_STAT_LPI 0x0040 /* LPI Interrupt Status */ 16785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 16885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Bus Mode register defines */ 16985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */ 17085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */ 17185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */ 17285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_ATDS 0x00000080 /* Alternate Descriptor Size */ 17385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 17485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Programmable burst length */ 17585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */ 17685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_PBL_SHIFT 8 17785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */ 17885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */ 17985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_RPBL_SHIFT 17 18085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_USP 0x00800000 18185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_8PBL 0x01000000 18285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_AAL 0x02000000 18385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 18485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Bus Mode register defines */ 18585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_PR_RATIO_MASK 0x0000c000 /* Rx/Tx priority ratio */ 18685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_PR_RATIO_SHIFT 14 18785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_FB 0x00010000 /* Fixed Burst */ 18885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 18985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Control register defines */ 19085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ 19185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ 19285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_DFF 0x01000000 /* Disable flush of rx frames */ 1930aefa8ecd81f4f4b3f7f336aa152b13cc79c4bfeRob Herring#define DMA_CONTROL_OSF 0x00000004 /* Operate on 2nd tx frame */ 19485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 19585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Normal interrupt */ 19685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */ 19785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */ 19885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */ 19985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */ 20085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */ 20185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */ 20285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */ 20385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */ 20485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */ 20585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */ 20685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */ 20785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */ 20885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavail */ 20985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */ 21085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */ 21185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 21285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ 21397a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring DMA_INTR_ENA_TUE | DMA_INTR_ENA_TIE) 21485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 21585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \ 21685c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_RWE | DMA_INTR_ENA_RSE | \ 21785c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_RUE | DMA_INTR_ENA_UNE | \ 21885c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_OVE | DMA_INTR_ENA_TJE | \ 21985c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_TSE) 22085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 22185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA default interrupt mask */ 22285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL) 22385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 22485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Status register defines */ 22585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */ 22685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */ 22785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */ 22885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */ 22985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */ 23085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */ 23185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TS_SHIFT 20 23285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */ 23385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RS_SHIFT 17 23485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */ 23585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */ 23685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */ 23785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */ 23885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */ 23985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */ 24085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */ 24185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */ 24285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */ 24385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */ 24485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */ 24585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */ 24685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavail */ 24785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */ 24885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ 24985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 25085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Common MAC defines */ 25185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */ 25285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAC_ENABLE_RX 0x00000004 /* Receiver Enable */ 25385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 25485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Operation Mode Register */ 25585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TSF 0x00200000 /* TX FIFO Store and Forward */ 25685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_FTF 0x00100000 /* Flush Transmit FIFO */ 25785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshhold Ctrl */ 25885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TTC_MASK 0x00030000 25985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshhold */ 26085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshhold MASK */ 26185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshhold */ 26285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshhold MASK */ 26385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_EFC 0x00000100 /* Enable Hardware FC */ 26485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_FEF 0x00000080 /* Forward Error Frames */ 26585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_DT 0x00000040 /* Drop TCP/IP csum Errors */ 26685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RSF 0x00000020 /* RX FIFO Store and Forward */ 267f62a23a7cb601fb30c4a8b8a5ba1c6bb7f5148b3Rob Herring#define XGMAC_OMR_RTC_256 0x00000018 /* RX Threshhold Ctrl */ 26885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshhold Ctrl MASK */ 26985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC HW Features Register */ 27185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_HW_FEAT_TXCOESEL 0x00010000 /* TX Checksum offload */ 27285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_CTRL_CNT_FRZ 0x00000008 27485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Descriptor Defines */ 27685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAX_DESC_BUF_SZ (0x2000 - 8) 27785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_EXT_STATUS 0x00000001 27985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_CRC_ERR 0x00000002 28085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_RX_ERR 0x00000008 28185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_RX_WDOG 0x00000010 28285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_TYPE 0x00000020 28385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_GIANT_FRAME 0x00000080 28485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_LAST_SEG 0x00000100 28585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FIRST_SEG 0x00000200 28685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_VLAN_FRAME 0x00000400 28785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_OVERFLOW_ERR 0x00000800 28885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_LENGTH_ERR 0x00001000 28985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_SA_FILTER_FAIL 0x00002000 29085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_DESCRIPTOR_ERR 0x00004000 29185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_ERROR_SUMMARY 0x00008000 29285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_LEN_OFFSET 16 29385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_LEN_MASK 0x3fff0000 29485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_DA_FILTER_FAIL 0x40000000 29585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 29685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC1_END_RING 0x00008000 29785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 29885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_MASK 0x00000003 29985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_UDP 0x00000001 30085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_TCP 0x00000002 30185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_ICMP 0x00000003 30285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_HEADER_ERR 0x00000008 30385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_ERR 0x00000010 30485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IPV4_PACKET 0x00000040 30585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IPV6_PACKET 0x00000080 30685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_UNDERFLOW_ERR 0x00000001 30785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_JABBER_TIMEOUT 0x00000002 30885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_LOCAL_FAULT 0x00000004 30985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_REMOTE_FAULT 0x00000008 31085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_VLAN_FRAME 0x00000010 31185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_FRAME_FLUSHED 0x00000020 31285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_IP_HEADER_ERR 0x00000040 31385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_PAYLOAD_CSUM_ERR 0x00000080 31485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_ERROR_SUMMARY 0x00008000 31585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_SA_CTRL_INSERT 0x00040000 31685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_SA_CTRL_REPLACE 0x00080000 31785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_2ND_ADDR_CHAINED 0x00100000 31885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_END_RING 0x00200000 31985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_IP 0x00400000 32085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_IP_PAYLD 0x00800000 32185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_ALL 0x00C00000 32285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CRC_EN_REPLACE 0x01000000 32385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CRC_EN_APPEND 0x02000000 32485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_DISABLE_PAD 0x04000000 32585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_FIRST_SEG 0x10000000 32685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_LAST_SEG 0x20000000 32785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_INTERRUPT 0x40000000 32885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 32985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_OWN 0x80000000 33085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER1_SZ_MASK 0x00001fff 33185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER2_SZ_MASK 0x1fff0000 33285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER2_SZ_OFFSET 16 33385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 33485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_dma_desc { 33585c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 flags; 33685c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf_size; 33785c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf1_addr; /* Buffer 1 Address Pointer */ 33885c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf2_addr; /* Buffer 2 Address Pointer */ 33985c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 ext_status; 34085c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 res[3]; 34185c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 34285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 34385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_extra_stats { 34485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Transmit errors */ 34585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_jabber; 34685c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_frame_flushed; 34785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_payload_error; 34885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_ip_header_error; 34985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_local_fault; 35085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_remote_fault; 35185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Receive errors */ 35285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_watchdog; 35385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_da_filter_fail; 35485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_payload_error; 35585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_ip_header_error; 35685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Tx/Rx IRQ errors */ 35785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_process_stopped; 35885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_buf_unav; 35985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_process_stopped; 36085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_early; 36185c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long fatal_bus_error; 36285c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 36385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 36485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_priv { 36585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *dma_rx; 36685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff **rx_skbuff; 36785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int rx_tail; 36885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int rx_head; 36985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 37085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *dma_tx; 37185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff **tx_skbuff; 37285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int tx_head; 37385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int tx_tail; 37497a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring int tx_irq_cnt; 37585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 37685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *base; 37785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int dma_buf_sz; 37885c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t dma_rx_phy; 37985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t dma_tx_phy; 38085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 38185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev; 38285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct device *device; 38385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct napi_struct napi; 38485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 3850cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring int max_macs; 38685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats xstats; 38785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 38885c10f28286148ee5cdba1d22c81936ff160596eRob Herring spinlock_t stats_lock; 38985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int pmt_irq; 39085c10f28286148ee5cdba1d22c81936ff160596eRob Herring char rx_pause; 39185c10f28286148ee5cdba1d22c81936ff160596eRob Herring char tx_pause; 39285c10f28286148ee5cdba1d22c81936ff160596eRob Herring int wolopts; 3938746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring struct work_struct tx_timeout_work; 39485c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 39585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 39685c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Configuration Settings */ 39785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAX_MTU 9000 39885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define PAUSE_TIME 0x400 39985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_RX_RING_SZ 256 40185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_TX_RING_SZ 128 40285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* minimum number of free TX descriptors required to wake up TX process */ 40385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TX_THRESH (DMA_TX_RING_SZ/4) 40485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA descriptor ring helpers */ 40685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_incr(n, s) (((n) + 1) & ((s) - 1)) 40785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_space(h, t, s) CIRC_SPACE(h, t, s) 40885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_cnt(h, t, s) CIRC_CNT(h, t, s) 40985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 410cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring#define tx_dma_ring_space(p) \ 411cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring dma_ring_space((p)->tx_head, (p)->tx_tail, DMA_TX_RING_SZ) 412cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring 41385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Descriptor Access Helpers */ 41485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz) 41585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 41685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (buf_sz > MAX_DESC_BUF_SZ) 41785c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(MAX_DESC_BUF_SZ | 41885c10f28286148ee5cdba1d22c81936ff160596eRob Herring (buf_sz - MAX_DESC_BUF_SZ) << DESC_BUFFER2_SZ_OFFSET); 41985c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 42085c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(buf_sz); 42185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 42285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 42385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_buf_len(struct xgmac_dma_desc *p) 42485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 425ef07387faf33a95e011993200902d490b605407dRob Herring u32 len = le32_to_cpu(p->buf_size); 42685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return (len & DESC_BUFFER1_SZ_MASK) + 42785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET); 42885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 42985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_rx_desc(struct xgmac_dma_desc *p, int ring_size, 43185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int buf_sz) 43285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 43385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *end = p + ring_size - 1; 43485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43585c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 43685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43785c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (; p <= end; p++) 43885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, buf_sz); 43985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44085c10f28286148ee5cdba1d22c81936ff160596eRob Herring end->buf_size |= cpu_to_le32(RXDESC1_END_RING); 44185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 44285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_tx_desc(struct xgmac_dma_desc *p, u32 ring_size) 44485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 44585c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 44685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p[ring_size - 1].flags = cpu_to_le32(TXDESC_END_RING); 44785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 44885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_owner(struct xgmac_dma_desc *p) 45085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & DESC_OWN; 45285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 45485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_rx_owner(struct xgmac_dma_desc *p) 45585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Clear all fields and set the owner */ 45785c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(DESC_OWN); 45885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 46085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_tx_owner(struct xgmac_dma_desc *p, u32 flags) 46185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 46285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 tmpflags = le32_to_cpu(p->flags); 46385c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags &= TXDESC_END_RING; 46485c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags |= flags | DESC_OWN; 46585c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(tmpflags); 46685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 46785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 46892cd4253e553e87a715243a36623945edcbf1ec7Rob Herringstatic inline void desc_clear_tx_owner(struct xgmac_dma_desc *p) 46992cd4253e553e87a715243a36623945edcbf1ec7Rob Herring{ 47092cd4253e553e87a715243a36623945edcbf1ec7Rob Herring u32 tmpflags = le32_to_cpu(p->flags); 47192cd4253e553e87a715243a36623945edcbf1ec7Rob Herring tmpflags &= TXDESC_END_RING; 47292cd4253e553e87a715243a36623945edcbf1ec7Rob Herring p->flags = cpu_to_le32(tmpflags); 47392cd4253e553e87a715243a36623945edcbf1ec7Rob Herring} 47492cd4253e553e87a715243a36623945edcbf1ec7Rob Herring 47585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_tx_ls(struct xgmac_dma_desc *p) 47685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 47785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & TXDESC_LAST_SEG; 47885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 47985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 4801a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herringstatic inline int desc_get_tx_fs(struct xgmac_dma_desc *p) 4811a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring{ 4821a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring return le32_to_cpu(p->flags) & TXDESC_FIRST_SEG; 4831a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring} 4841a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring 48585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline u32 desc_get_buf_addr(struct xgmac_dma_desc *p) 48685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 48785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->buf1_addr); 48885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 48985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr(struct xgmac_dma_desc *p, 49185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 49285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 49385c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf1_addr = cpu_to_le32(paddr); 49485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (len > MAX_DESC_BUF_SZ) 49585c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf2_addr = cpu_to_le32(paddr + MAX_DESC_BUF_SZ); 49685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 49785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr_and_size(struct xgmac_dma_desc *p, 49985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 50085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 50185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, len); 50285c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr(p, paddr, len); 50385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 50485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 50585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_rx_frame_len(struct xgmac_dma_desc *p) 50685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 50785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data = le32_to_cpu(p->flags); 50885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 len = (data & RXDESC_FRAME_LEN_MASK) >> RXDESC_FRAME_LEN_OFFSET; 50985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (data & RXDESC_FRAME_TYPE) 51085c10f28286148ee5cdba1d22c81936ff160596eRob Herring len -= ETH_FCS_LEN; 51185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return len; 51385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 51485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_dma_flush_tx_fifo(void __iomem *ioaddr) 51685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 51785c10f28286148ee5cdba1d22c81936ff160596eRob Herring int timeout = 1000; 51885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg = readl(ioaddr + XGMAC_OMR); 51985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | XGMAC_OMR_FTF, ioaddr + XGMAC_OMR); 52085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 52185c10f28286148ee5cdba1d22c81936ff160596eRob Herring while ((timeout-- > 0) && readl(ioaddr + XGMAC_OMR) & XGMAC_OMR_FTF) 52285c10f28286148ee5cdba1d22c81936ff160596eRob Herring udelay(1); 52385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 52485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 52585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_tx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 52685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 52785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 52885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 52985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & TXDESC_ERROR_SUMMARY)) 53185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 53285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx desc error = 0x%08x\n", status); 53485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_JABBER_TIMEOUT) 53585c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 53685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_FRAME_FLUSHED) 53785c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_frame_flushed++; 53885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_UNDERFLOW_ERR) 53985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_dma_flush_tx_fifo(priv->base); 54085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_IP_HEADER_ERR) 54185c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_ip_header_error++; 54285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_LOCAL_FAULT) 54385c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_local_fault++; 54485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_REMOTE_FAULT) 54585c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_remote_fault++; 54685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_PAYLOAD_CSUM_ERR) 54785c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_payload_error++; 54885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 54985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 55085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 55185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 55285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 55385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 55485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 55585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = CHECKSUM_UNNECESSARY; 55685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 55785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ext_status = le32_to_cpu(p->ext_status); 55885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 55985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_DA_FILTER_FAIL) { 56085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "XGMAC RX : Dest Address filter fail\n"); 56185c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_da_filter_fail++; 56285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 56385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 56485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 565d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring /* All frames should fit into a single buffer */ 566d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG)) 567d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring return -1; 568d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring 56985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if packet has checksum already */ 57085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && 57185c10f28286148ee5cdba1d22c81936ff160596eRob Herring !(ext_status & RXDESC_IP_PAYLOAD_MASK)) 57285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = CHECKSUM_NONE; 57385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 57485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx status - frame type=%d, csum = %d, ext stat %08x\n", 57585c10f28286148ee5cdba1d22c81936ff160596eRob Herring (status & RXDESC_FRAME_TYPE) ? 1 : 0, ret, ext_status); 57685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 57785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & RXDESC_ERROR_SUMMARY)) 57885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 57985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 58085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Handle any errors */ 58185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & (RXDESC_DESCRIPTOR_ERR | RXDESC_OVERFLOW_ERR | 58285c10f28286148ee5cdba1d22c81936ff160596eRob Herring RXDESC_GIANT_FRAME | RXDESC_LENGTH_ERR | RXDESC_CRC_ERR)) 58385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 58485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 58585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_EXT_STATUS) { 58685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_HEADER_ERR) 58785c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_ip_header_error++; 58885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_PAYLOAD_ERR) 58985c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_payload_error++; 59085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "IP checksum error - stat %08x\n", 59185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ext_status); 59285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return CHECKSUM_NONE; 59385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 59485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 59685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 59785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_enable(void __iomem *ioaddr) 59985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 60085c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_CONTROL); 60185c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= MAC_ENABLE_RX | MAC_ENABLE_TX; 60285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 60385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60485c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_DMA_CONTROL); 60585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= DMA_CONTROL_ST | DMA_CONTROL_SR; 60685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 60785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 60885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_disable(void __iomem *ioaddr) 61085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 61185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_DMA_CONTROL); 61285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 61385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 61485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 61585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_CONTROL); 61685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); 61785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 61885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 61985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 62085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_mac_addr(void __iomem *ioaddr, unsigned char *addr, 62185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 62285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 62385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data; 62485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 6252ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring if (addr) { 6262ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring data = (addr[5] << 8) | addr[4] | (num ? XGMAC_ADDR_AE : 0); 6272ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring writel(data, ioaddr + XGMAC_ADDR_HIGH(num)); 6282ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 6292ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring writel(data, ioaddr + XGMAC_ADDR_LOW(num)); 6302ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring } else { 6312ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring writel(0, ioaddr + XGMAC_ADDR_HIGH(num)); 6322ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring writel(0, ioaddr + XGMAC_ADDR_LOW(num)); 6332ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring } 63485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 63585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 63685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, 63785c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 63885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 63985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hi_addr, lo_addr; 64085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Read the MAC address from the hardware */ 64285c10f28286148ee5cdba1d22c81936ff160596eRob Herring hi_addr = readl(ioaddr + XGMAC_ADDR_HIGH(num)); 64385c10f28286148ee5cdba1d22c81936ff160596eRob Herring lo_addr = readl(ioaddr + XGMAC_ADDR_LOW(num)); 64485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Extract the MAC address from the high and low words */ 64685c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[0] = lo_addr & 0xff; 64785c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[1] = (lo_addr >> 8) & 0xff; 64885c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[2] = (lo_addr >> 16) & 0xff; 64985c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[3] = (lo_addr >> 24) & 0xff; 65085c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[4] = hi_addr & 0xff; 65185c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[5] = (hi_addr >> 8) & 0xff; 65285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 65385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 65485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_flow_ctrl(struct xgmac_priv *priv, int rx, int tx) 65585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 65685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg; 65785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int flow = 0; 65885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 65985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = rx; 66085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = tx; 66185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx || tx) { 66385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx) 66485c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_RFE; 66585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (tx) 66685c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_TFE; 66785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66885c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_PLT | XGMAC_FLOW_CTRL_UP; 66985c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= (PAUSE_TIME << XGMAC_FLOW_CTRL_PT_SHIFT); 67085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(flow, priv->base + XGMAC_FLOW_CTRL); 67285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67385c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_OMR); 67485c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg |= XGMAC_OMR_EFC; 67585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg, priv->base + XGMAC_OMR); 67685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 67785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_FLOW_CTRL); 67885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67985c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_OMR); 68085c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg &= ~XGMAC_OMR_EFC; 68185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg, priv->base + XGMAC_OMR); 68285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 68385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 68485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 68585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 68685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 68785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_rx_refill(struct xgmac_priv *priv) 68885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 68985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 69085c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 691ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring int bufsz = priv->dev->mtu + ETH_HLEN + ETH_FCS_LEN; 69285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69385c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_space(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ) > 1) { 69485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int entry = priv->rx_head; 69585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 69685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69785c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 69885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 6997c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring if (priv->rx_skbuff[entry] == NULL) { 700ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring skb = netdev_alloc_skb_ip_align(priv->dev, bufsz); 7017c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring if (unlikely(skb == NULL)) 7027c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring break; 7037c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring 7047c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring paddr = dma_map_single(priv->device, skb->data, 705531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring priv->dma_buf_sz - NET_IP_ALIGN, 706531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring DMA_FROM_DEVICE); 707531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring if (dma_mapping_error(priv->device, paddr)) { 708531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring dev_kfree_skb_any(skb); 709531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring break; 710531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring } 711531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring priv->rx_skbuff[entry] = skb; 7127c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring desc_set_buf_addr(p, paddr, priv->dma_buf_sz); 7137c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring } 71485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx ring: head %d, tail %d\n", 71685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head, priv->rx_tail); 71785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = dma_ring_incr(priv->rx_head, DMA_RX_RING_SZ); 71985c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_rx_owner(p); 72085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 72185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 72285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 72385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 72485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * init_xgmac_dma_desc_rings - init the RX/TX descriptor rings 72585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev: net device structure 72685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function initializes the DMA RX/TX descriptors 72785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * and allocates the socket buffers. 72885c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 72985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_dma_desc_rings_init(struct net_device *dev) 73085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 73185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 73285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int bfsize; 73385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 73485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set the Buffer size according to the MTU; 735ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring * The total buffer size including any IP offset must be a multiple 736ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring * of 8 bytes. 73785c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 738ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN, 8); 73985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); 74185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_RX_RING_SZ, 74385c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 74485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 74585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 74685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = dma_alloc_coherent(priv->device, 74885c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * 74985c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 75085c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_rx_phy, 75185c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 75285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_rx) 75385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_rx; 75485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 75585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_TX_RING_SZ, 75685c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 75785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 75885c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_tx_skb; 75985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = dma_alloc_coherent(priv->device, 76185c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * 76285c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 76385c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_tx_phy, 76485c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 76585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_tx) 76685c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_tx; 76785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "DMA desc rings: virt addr (Rx %p, " 76985c10f28286148ee5cdba1d22c81936ff160596eRob Herring "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 77085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_tx, 77185c10f28286148ee5cdba1d22c81936ff160596eRob Herring (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 77285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 77385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = 0; 77485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = 0; 77585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz = bfsize; 77685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_rx_desc(priv->dma_rx, DMA_RX_RING_SZ, priv->dma_buf_sz); 77785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 77885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 77985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 78085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 78185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 78285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR); 78485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_rx_phy, priv->base + XGMAC_DMA_RX_BASE_ADDR); 78585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 78785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78885c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_tx: 78985c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 79085c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_tx_skb: 79185c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 79285c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 79385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 79485c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_rx: 79585c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 79685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 79785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 79885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 79985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_rx_skbufs(struct xgmac_priv *priv) 80085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 80185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 80285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 80385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 80585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 80685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80785c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_RX_RING_SZ; i++) { 808531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring struct sk_buff *skb = priv->rx_skbuff[i]; 809531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring if (skb == NULL) 81085c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 81185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 81285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + i; 81385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 814531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring priv->dma_buf_sz - NET_IP_ALIGN, DMA_FROM_DEVICE); 815531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring dev_kfree_skb_any(skb); 81685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[i] = NULL; 81785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 81885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 81985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_tx_skbufs(struct xgmac_priv *priv) 82185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 8221a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring int i; 82385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 82485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 82685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 82785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82885c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_TX_RING_SZ; i++) { 82985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->tx_skbuff[i] == NULL) 83085c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 83185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 83285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + i; 8331a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring if (desc_get_tx_fs(p)) 8341a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 8351a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 8361a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring else 83785c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 83885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 83985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 8401a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring if (desc_get_tx_ls(p)) 8411a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring dev_kfree_skb_any(priv->tx_skbuff[i]); 84285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[i] = NULL; 84385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 84485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 84585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 84685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_dma_desc_rings(struct xgmac_priv *priv) 84785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 84885c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release the DMA TX/RX socket buffers */ 84985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_rx_skbufs(priv); 85085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 85185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 85285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the consistent memory allocated for descriptor rings */ 85385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_tx) { 85485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 85585c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * sizeof(struct xgmac_dma_desc), 85685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx, priv->dma_tx_phy); 85785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = NULL; 85885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 85985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_rx) { 86085c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 86185c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 86285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 86385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = NULL; 86485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 86585c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 86685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = NULL; 86785c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 86885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = NULL; 86985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 87085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 87285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx: 87385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @priv: private driver structure 87485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: it reclaims resources after transmission completes. 87585c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 87685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_complete(struct xgmac_priv *priv) 87785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 87885c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) { 87985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry = priv->tx_tail; 88085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb = priv->tx_skbuff[entry]; 88185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p = priv->dma_tx + entry; 88285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if the descriptor is owned by the DMA. */ 88485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 88585c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 88685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx ring: curr %d, dirty %d\n", 88885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head, priv->tx_tail); 88985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 8901a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring if (desc_get_tx_fs(p)) 8911a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 8921a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 8931a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring else 89485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 89585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 8961a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring 8971a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring /* Check tx error on the last segment */ 8981a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring if (desc_get_tx_ls(p)) { 8991a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring desc_get_tx_status(priv, p); 900f5cf76ba620fd48538c13ba9bce8a6876b07c7f6Eric W. Biederman dev_consume_skb_any(skb); 90185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 90285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9031a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring priv->tx_skbuff[entry] = NULL; 9041a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ); 90585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 90685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 907cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring /* Ensure tx_tail is visible to xgmac_xmit */ 908cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring smp_mb(); 909cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring if (unlikely(netif_queue_stopped(priv->dev) && 910cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring (tx_dma_ring_space(priv) > MAX_SKB_FRAGS))) 91185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 91285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 91385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9148746f671ef04114ab25f5a35ec6219efbdf3703eRob Herringstatic void xgmac_tx_timeout_work(struct work_struct *work) 91585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 9168746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring u32 reg, value; 9178746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring struct xgmac_priv *priv = 9188746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring container_of(work, struct xgmac_priv, tx_timeout_work); 91985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9208746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring napi_disable(&priv->napi); 92185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 92385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9248746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring netif_tx_lock(priv->dev); 9258746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring 92685c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_DMA_CONTROL); 92785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg & ~DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 92885c10f28286148ee5cdba1d22c81936ff160596eRob Herring do { 92985c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_STATUS) & 0x700000; 93085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } while (value && (value != 0x600000)); 93185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 93385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 93485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 93585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 936eb5e1b29a5ff4b782796ec9d17b443b5b38b7ffeRob Herring writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR); 93785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 93885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS, 94085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base + XGMAC_DMA_STATUS); 94185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 9428746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring netif_tx_unlock(priv->dev); 94385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 9448746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring 9458746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring napi_enable(&priv->napi); 9468746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring 9478746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring /* Enable interrupts */ 9488746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_STATUS); 9498746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); 95085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 95185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 95285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_hw_init(struct net_device *dev) 95385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 95485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value, ctrl; 95585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int limit; 95685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 95785c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 95885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 95985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Save the ctrl register value */ 96085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL) & XGMAC_CONTROL_SPD_MASK; 96185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 96285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* SW reset */ 96385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = DMA_BUS_MODE_SFT_RESET; 96485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 96585c10f28286148ee5cdba1d22c81936ff160596eRob Herring limit = 15000; 96685c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (limit-- && 96785c10f28286148ee5cdba1d22c81936ff160596eRob Herring (readl(ioaddr + XGMAC_DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) 96885c10f28286148ee5cdba1d22c81936ff160596eRob Herring cpu_relax(); 96985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (limit < 0) 97085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 97185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 97285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = (0x10 << DMA_BUS_MODE_PBL_SHIFT) | 97385c10f28286148ee5cdba1d22c81936ff160596eRob Herring (0x10 << DMA_BUS_MODE_RPBL_SHIFT) | 97485c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_BUS_MODE_FB | DMA_BUS_MODE_ATDS | DMA_BUS_MODE_AAL; 97585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 97685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 977f7ea10520d7dacbc416d130c4b10505c66bf4c36Rob Herring writel(0, ioaddr + XGMAC_DMA_INTR_ENA); 97885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 979e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring /* Mask power mgt interrupt */ 980e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT); 981e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring 98285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* XGMAC requires AXI bus init. This is a 'magic number' for now */ 983e36ce6eb2ba35b0b7335aef12731a96af9531055Rob Herring writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS); 98485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 98585c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_DDIC | XGMAC_CONTROL_JE | XGMAC_CONTROL_ACS | 98685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_CONTROL_CAR; 98785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->features & NETIF_F_RXCSUM) 98885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_IPC; 98985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(ctrl, ioaddr + XGMAC_CONTROL); 99085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 991b821bd8e5a4413c8e28e64d878720978883ebfc8Rob Herring writel(DMA_CONTROL_OSF, ioaddr + XGMAC_DMA_CONTROL); 99285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 99385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set the HW DMA mode and the COE */ 994f62a23a7cb601fb30c4a8b8a5ba1c6bb7f5148b3Rob Herring writel(XGMAC_OMR_TSF | XGMAC_OMR_RFD | XGMAC_OMR_RFA | 995f62a23a7cb601fb30c4a8b8a5ba1c6bb7f5148b3Rob Herring XGMAC_OMR_RTC_256, 99685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ioaddr + XGMAC_OMR); 99785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 99885c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Reset the MMC counters */ 99985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(1, ioaddr + XGMAC_MMC_CTRL); 100085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 100185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 100285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 100385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 100485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_open - open entry point of the driver 100585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : pointer to the device structure. 100685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 100785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function is the open entry point of the driver. 100885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 100985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 0 on success and an appropriate (-)ve integer as defined in errno.h 101085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * file on failure. 101185c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 101285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_open(struct net_device *dev) 101385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 101485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret; 101585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 101685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 101785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 101885c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check that the MAC address is valid. If its not, refuse 101985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to bring the device up. The user must specify an 102085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * address using the following linux command: 102185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ 102285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(dev->dev_addr)) { 10237ce5d222190cb3ce3ae88bafde7c4fa52a5103e0Danny Kukawka eth_hw_addr_random(dev); 102485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "generated random MAC address %pM\n", 102585c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev->dev_addr); 102685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 102785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 102885c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(&priv->xstats, 0, sizeof(struct xgmac_extra_stats)); 102985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Initialize the XGMAC and descriptors */ 103185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_hw_init(dev); 103285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0); 103385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_flow_ctrl(priv, priv->rx_pause, priv->tx_pause); 103485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103585c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = xgmac_dma_desc_rings_init(dev); 103685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) 103785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 103885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable the MAC Rx/Tx */ 104085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_enable(ioaddr); 104185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 104285c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_enable(&priv->napi); 104385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_start_queue(dev); 104485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1045f7ea10520d7dacbc416d130c4b10505c66bf4c36Rob Herring /* Enable interrupts */ 1046f7ea10520d7dacbc416d130c4b10505c66bf4c36Rob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 1047f7ea10520d7dacbc416d130c4b10505c66bf4c36Rob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); 1048f7ea10520d7dacbc416d130c4b10505c66bf4c36Rob Herring 104985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 105085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 105185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 105385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_release - close entry point of the driver 105485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 105585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 105685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This is the stop entry point of the driver. 105785c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 105885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_stop(struct net_device *dev) 105985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 106085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 106185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 106285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_INTR_ENA)) 106385c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 106485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 106585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 106685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1067b5ad795e52dae6e9f88b193a5e779b70005d005cAndreas Herrmann netif_tx_disable(dev); 1068b5ad795e52dae6e9f88b193a5e779b70005d005cAndreas Herrmann 106985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Disable the MAC core */ 107085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 107185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 107285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release and free the Rx/Tx resources */ 107385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_dma_desc_rings(priv); 107485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 107585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 107685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 107785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 107885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 107985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_xmit: 108085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @skb : the socket buffer 108185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer 108285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : Tx entry point of the driver. 108385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 108485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) 108585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 108685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 108785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 108885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 108997a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring u32 irq_flag; 109085c10f28286148ee5cdba1d22c81936ff160596eRob Herring int nfrags = skb_shinfo(skb)->nr_frags; 109185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *desc, *first; 109285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int desc_flags; 109385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int len; 109485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 109585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109697a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring priv->tx_irq_cnt = (priv->tx_irq_cnt + 1) & (DMA_TX_RING_SZ/4 - 1); 109797a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring irq_flag = priv->tx_irq_cnt ? 0 : TXDESC_INTERRUPT; 109885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109985c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? 110085c10f28286148ee5cdba1d22c81936ff160596eRob Herring TXDESC_CSUM_ALL : 0; 110185c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->tx_head; 110285c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 110385c10f28286148ee5cdba1d22c81936ff160596eRob Herring first = desc; 110485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 110585c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = skb_headlen(skb); 110685c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = dma_map_single(priv->device, skb->data, len, DMA_TO_DEVICE); 110785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_mapping_error(priv->device, paddr)) { 1108f5cf76ba620fd48538c13ba9bce8a6876b07c7f6Eric W. Biederman dev_kfree_skb_any(skb); 110992cd4253e553e87a715243a36623945edcbf1ec7Rob Herring return NETDEV_TX_OK; 111085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 111185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = skb; 111285c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 111385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < nfrags; i++) { 111585c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 111685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111785c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = frag->size; 111885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111985c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = skb_frag_dma_map(priv->device, frag, 0, len, 112085c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TO_DEVICE); 112192cd4253e553e87a715243a36623945edcbf1ec7Rob Herring if (dma_mapping_error(priv->device, paddr)) 112292cd4253e553e87a715243a36623945edcbf1ec7Rob Herring goto dma_err; 112385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112485c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = dma_ring_incr(entry, DMA_TX_RING_SZ); 112585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 11261a1d4d2f30a3c7e91bb7876df95baae363be5434Rob Herring priv->tx_skbuff[entry] = skb; 112785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 112985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (i < (nfrags - 1)) 113085c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags); 113185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 113285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 113385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Interrupt on completition only for the latest segment */ 113485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc != first) 113585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags | 113697a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring TXDESC_LAST_SEG | irq_flag); 113785c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 113897a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring desc_flags |= TXDESC_LAST_SEG | irq_flag; 113985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set owner on first desc last to avoid race condition */ 114185c10f28286148ee5cdba1d22c81936ff160596eRob Herring wmb(); 114285c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(first, desc_flags | TXDESC_FIRST_SEG); 114385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1144ca32723afedd65d612029705446bf44bde5eab14Rob Herring writel(1, priv->base + XGMAC_DMA_TX_POLL); 1145ca32723afedd65d612029705446bf44bde5eab14Rob Herring 114685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); 114785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1148cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring /* Ensure tx_head update is visible to tx completion */ 1149cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring smp_mb(); 1150cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring if (unlikely(tx_dma_ring_space(priv) <= MAX_SKB_FRAGS)) { 115197a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring netif_stop_queue(dev); 1152cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring /* Ensure netif_stop_queue is visible to tx completion */ 1153cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring smp_mb(); 1154cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring if (tx_dma_ring_space(priv) > MAX_SKB_FRAGS) 1155cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring netif_start_queue(dev); 1156cbe157b60c8e70d4b4dc937dfdd39525d8f47b46Rob Herring } 115785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return NETDEV_TX_OK; 115892cd4253e553e87a715243a36623945edcbf1ec7Rob Herring 115992cd4253e553e87a715243a36623945edcbf1ec7Rob Herringdma_err: 116092cd4253e553e87a715243a36623945edcbf1ec7Rob Herring entry = priv->tx_head; 116192cd4253e553e87a715243a36623945edcbf1ec7Rob Herring for ( ; i > 0; i--) { 116292cd4253e553e87a715243a36623945edcbf1ec7Rob Herring entry = dma_ring_incr(entry, DMA_TX_RING_SZ); 116392cd4253e553e87a715243a36623945edcbf1ec7Rob Herring desc = priv->dma_tx + entry; 116492cd4253e553e87a715243a36623945edcbf1ec7Rob Herring priv->tx_skbuff[entry] = NULL; 116592cd4253e553e87a715243a36623945edcbf1ec7Rob Herring dma_unmap_page(priv->device, desc_get_buf_addr(desc), 116692cd4253e553e87a715243a36623945edcbf1ec7Rob Herring desc_get_buf_len(desc), DMA_TO_DEVICE); 116792cd4253e553e87a715243a36623945edcbf1ec7Rob Herring desc_clear_tx_owner(desc); 116892cd4253e553e87a715243a36623945edcbf1ec7Rob Herring } 116992cd4253e553e87a715243a36623945edcbf1ec7Rob Herring desc = first; 117092cd4253e553e87a715243a36623945edcbf1ec7Rob Herring dma_unmap_single(priv->device, desc_get_buf_addr(desc), 117192cd4253e553e87a715243a36623945edcbf1ec7Rob Herring desc_get_buf_len(desc), DMA_TO_DEVICE); 1172f5cf76ba620fd48538c13ba9bce8a6876b07c7f6Eric W. Biederman dev_kfree_skb_any(skb); 117392cd4253e553e87a715243a36623945edcbf1ec7Rob Herring return NETDEV_TX_OK; 117485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 117585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 117685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_rx(struct xgmac_priv *priv, int limit) 117785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 117885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 117985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int count = 0; 118085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 118185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118285c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (count < limit) { 118385c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ip_checksum; 118485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 118585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int frame_len; 118685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1187dc574f1d52d893f516f3786ff7635450bac00eefRob Herring if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ)) 1188dc574f1d52d893f516f3786ff7635450bac00eefRob Herring break; 1189dc574f1d52d893f516f3786ff7635450bac00eefRob Herring 119085c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->rx_tail; 119185c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 119285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 119385c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 119485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 119585c10f28286148ee5cdba1d22c81936ff160596eRob Herring count++; 119685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = dma_ring_incr(priv->rx_tail, DMA_RX_RING_SZ); 119785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 119885c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status of the incoming frame */ 119985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ip_checksum = desc_get_rx_status(priv, p); 120085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum < 0) 120185c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 120285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 120385c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb = priv->rx_skbuff[entry]; 120485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(!skb)) { 120585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "Inconsistent Rx descriptor chain\n"); 120685c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 120785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 120885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[entry] = NULL; 120985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121085c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len = desc_get_rx_frame_len(p); 121185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "RX frame size %d, COE status: %d\n", 121285c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len, ip_checksum); 121385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121485c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_put(skb, frame_len); 121585c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 1216531cda20cd44d5a7a77debaaeaa407d4802d7e05Rob Herring priv->dma_buf_sz - NET_IP_ALIGN, DMA_FROM_DEVICE); 121785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121885c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->protocol = eth_type_trans(skb, priv->dev); 121985c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->ip_summed = ip_checksum; 122085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum == CHECKSUM_NONE) 122185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_receive_skb(skb); 122285c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 122385c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_gro_receive(&priv->napi, skb); 122485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 122585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 122685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 122785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 122885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return count; 122985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 123085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 123185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 123285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_poll - xgmac poll method (NAPI) 123385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @napi : pointer to the napi structure. 123485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @budget : maximum number of packets that the current CPU can receive from 123585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * all interfaces. 123685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : 123785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function implements the the reception process. 123885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Also it runs the TX completion thread 123985c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 124085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_poll(struct napi_struct *napi, int budget) 124185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 124285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = container_of(napi, 124385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv, napi); 124485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int work_done = 0; 124585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 124685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_complete(priv); 124785c10f28286148ee5cdba1d22c81936ff160596eRob Herring work_done = xgmac_rx(priv, budget); 124885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 124985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (work_done < budget) { 125085c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_complete(napi); 12510ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); 125285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 125385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return work_done; 125485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 125585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 125685c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 125785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx_timeout 125885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : Pointer to net device structure 125985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function is called when a packet transmission fails to 126085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * complete within a reasonable tmrate. The driver will mark the error in the 126185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * netdev structure and arrange for the device to be reset to a sane state 126285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * in order to transmit a new packet. 126385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 126485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_timeout(struct net_device *dev) 126585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 126685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 12678746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring schedule_work(&priv->tx_timeout_work); 126885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 126985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 127085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 127185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_set_rx_mode - entry point for multicast addressing 127285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : pointer to the device structure 127385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 127485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function is a driver entry point which gets called by the kernel 127585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * whenever multicast addresses must be enabled/disabled. 127685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 127785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * void. 127885c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 127985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_rx_mode(struct net_device *dev) 128085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 128185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 128285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 128385c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 128485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int value = 0; 128585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hash_filter[XGMAC_NUM_HASH]; 128685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int reg = 1; 128785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct netdev_hw_addr *ha; 128885c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool use_hash = false; 128985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 129085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "# mcasts %d, # unicast %d\n", 129185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_mc_count(dev), netdev_uc_count(dev)); 129285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 12938a8c3f5bebe2455200cd488aea8546d01645b06bRob Herring if (dev->flags & IFF_PROMISC) 12948a8c3f5bebe2455200cd488aea8546d01645b06bRob Herring value |= XGMAC_FRAME_FILTER_PR; 129585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 129685c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(hash_filter, 0, sizeof(hash_filter)); 129785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 12980cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring if (netdev_uc_count(dev) > priv->max_macs) { 129985c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 130085c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF; 130185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 130285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_uc_addr(ha, dev) { 130385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 130485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 130585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 130685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 130785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 130885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 130985c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 131085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 131185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 131285c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 131385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 131485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 131585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 131685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->flags & IFF_ALLMULTI) { 131785c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_PM; 131885c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto out; 131985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 132085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 13210cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring if ((netdev_mc_count(dev) + reg - 1) > priv->max_macs) { 132285c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 132385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF; 13242ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring } else { 13252ee68f621af280c37a6bd72fe75e47de0750f301Rob Herring use_hash = false; 132685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 132785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_mc_addr(ha, dev) { 132885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 132985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 133085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 133185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 133285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 133385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 133485c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 133585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 133685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 133785c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 133885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 133985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 134085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134185c10f28286148ee5cdba1d22c81936ff160596eRob Herringout: 13420cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring for (i = reg; i <= priv->max_macs; i++) 13438c1c58ec70ce45cd5c7866811e90df131e7a3005Rob Herring xgmac_set_mac_addr(ioaddr, NULL, i); 134485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_NUM_HASH; i++) 134585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(hash_filter[i], ioaddr + XGMAC_HASH(i)); 134685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_FRAME_FILTER); 134885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 134985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 135085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 135185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_change_mtu - entry point to change MTU size for the device. 135285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 135385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @new_mtu : the new MTU size for the device. 135485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the Maximum Transfer Unit (MTU) is used by the network layer 135585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to drive packet transmission. Ethernet has an MTU of 1500 octets 135685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * (ETH_DATA_LEN). This value can be changed with ifconfig. 135785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 135885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 0 on success and an appropriate (-)ve integer as defined in errno.h 135985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * file on failure. 136085c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 136185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_change_mtu(struct net_device *dev, int new_mtu) 136285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 136385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 136485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int old_mtu; 136585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 136685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((new_mtu < 46) || (new_mtu > MAX_MTU)) { 136785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "invalid MTU, max MTU is: %d\n", MAX_MTU); 136885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 136985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 137085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137185c10f28286148ee5cdba1d22c81936ff160596eRob Herring old_mtu = dev->mtu; 137285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* return early if the buffer sizes will not change */ 137485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (old_mtu == new_mtu) 137585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 137685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop everything, get ready to change the MTU */ 137885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(dev)) 137985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 138085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1381b5ad795e52dae6e9f88b193a5e779b70005d005cAndreas Herrmann /* Bring interface down, change mtu and bring interface back up */ 138285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_stop(dev); 1383b5ad795e52dae6e9f88b193a5e779b70005d005cAndreas Herrmann dev->mtu = new_mtu; 138485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_open(dev); 138585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 138685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 138785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id) 138885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 138985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 139085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 139185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 139285c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 139385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 13940ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status = __raw_readl(ioaddr + XGMAC_INT_STAT); 139585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & XGMAC_INT_STAT_PMT) { 139685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "received Magic frame\n"); 139785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* clear the PMT bits 5 and 6 by reading the PMT */ 139885c10f28286148ee5cdba1d22c81936ff160596eRob Herring readl(ioaddr + XGMAC_PMT); 139985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 140085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 140185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 140285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 140385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_interrupt(int irq, void *dev_id) 140485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 140585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 140685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 140785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 140885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 140985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 141085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status register (CSR5) */ 14110ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status = __raw_readl(priv->base + XGMAC_DMA_STATUS); 14120ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status &= __raw_readl(priv->base + XGMAC_DMA_INTR_ENA); 14130ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(intr_status, priv->base + XGMAC_DMA_STATUS); 141485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 141585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* It displays the DMA process states (CSR5 register) */ 141685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* ABNORMAL interrupts */ 141785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(intr_status & DMA_STATUS_AIS)) { 141885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TJT) { 141985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit jabber\n"); 142085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 142185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 142285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RU) 142385c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_buf_unav++; 142485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RPS) { 142585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "receive process stopped\n"); 142685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_process_stopped++; 142785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 142885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_ETI) { 142985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit early interrupt\n"); 143085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_early++; 143185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 143285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TPS) { 143385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit process stopped\n"); 143485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_process_stopped++; 14358746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring schedule_work(&priv->tx_timeout_work); 143685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 143785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_FBI) { 143885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "fatal bus error\n"); 143985c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->fatal_bus_error++; 144085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 144185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 144285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 144385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* TX/RX NORMAL interrupts */ 144497a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU | DMA_STATUS_TI)) { 14450ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); 144685c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_schedule(&priv->napi); 144785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 144885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 144985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 145085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 145185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 145385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Polling receive - used by NETCONSOLE and other diagnostic tools 145485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to allow network I/O with interrupts disabled. */ 145585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_poll_controller(struct net_device *dev) 145685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 145785c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq(dev->irq); 145885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_interrupt(dev->irq, dev); 145985c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq(dev->irq); 146085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 146185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 146285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1463bd601cc464e1ddc041d07ba2e4c015cdb9e392ecstephen hemmingerstatic struct rtnl_link_stats64 * 146485c10f28286148ee5cdba1d22c81936ff160596eRob Herringxgmac_get_stats64(struct net_device *dev, 146585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct rtnl_link_stats64 *storage) 146685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 146785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 146885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *base = priv->base; 146985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 count; 147085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147185c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_bh(&priv->stats_lock); 147285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_MMC_CTRL_CNT_FRZ, base + XGMAC_MMC_CTRL); 147385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147485c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes = readl(base + XGMAC_MMC_RXOCTET_G_LO); 147585c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes |= (u64)(readl(base + XGMAC_MMC_RXOCTET_G_HI)) << 32; 147685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_packets = readl(base + XGMAC_MMC_RXFRAME_GB_LO); 147885c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->multicast = readl(base + XGMAC_MMC_RXMCFRAME_G); 147985c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_crc_errors = readl(base + XGMAC_MMC_RXCRCERR); 148085c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_length_errors = readl(base + XGMAC_MMC_RXLENGTHERR); 148185c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_missed_errors = readl(base + XGMAC_MMC_RXOVERFLOW); 148285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148385c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes = readl(base + XGMAC_MMC_TXOCTET_G_LO); 148485c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes |= (u64)(readl(base + XGMAC_MMC_TXOCTET_G_HI)) << 32; 148585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148685c10f28286148ee5cdba1d22c81936ff160596eRob Herring count = readl(base + XGMAC_MMC_TXFRAME_GB_LO); 148785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_errors = count - readl(base + XGMAC_MMC_TXFRAME_G_LO); 148885c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_packets = count; 148985c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_fifo_errors = readl(base + XGMAC_MMC_TXUNDERFLOW); 149085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, base + XGMAC_MMC_CTRL); 149285c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_unlock_bh(&priv->stats_lock); 149385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return storage; 149485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 149585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_mac_address(struct net_device *dev, void *p) 149785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 149885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 149985c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 150085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sockaddr *addr = p; 150185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(addr->sa_data)) 150385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EADDRNOTAVAIL; 150485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150585c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 150685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0); 150885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 151085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 151185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 151285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_features(struct net_device *dev, netdev_features_t features) 151385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 151485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ctrl; 151585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 151685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 1517cf62cb72d63944f4dcc7376efd84959afc9366cbDan Carpenter netdev_features_t changed = dev->features ^ features; 151885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 151985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(changed & NETIF_F_RXCSUM)) 152085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 152185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 152285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL); 152385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (features & NETIF_F_RXCSUM) 152485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_IPC; 152585c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 152685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl &= ~XGMAC_CONTROL_IPC; 152785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(ctrl, ioaddr + XGMAC_CONTROL); 152885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 152985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 153085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 153185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 153285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct net_device_ops xgmac_netdev_ops = { 153385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_open = xgmac_open, 153485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_start_xmit = xgmac_xmit, 153585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_stop = xgmac_stop, 153685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_change_mtu = xgmac_change_mtu, 153785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_rx_mode = xgmac_set_rx_mode, 153885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_tx_timeout = xgmac_tx_timeout, 153985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_get_stats64 = xgmac_get_stats64, 154085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 154185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_poll_controller = xgmac_poll_controller, 154285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 154385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_mac_address = xgmac_set_mac_address, 154485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_features = xgmac_set_features, 154585c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 154685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_ethtool_getsettings(struct net_device *dev, 154885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_cmd *cmd) 154985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 155085c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->autoneg = 0; 155185c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->duplex = DUPLEX_FULL; 155285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ethtool_cmd_speed_set(cmd, 10000); 155385c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->supported = 0; 155485c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->advertising = 0; 155585c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->transceiver = XCVR_INTERNAL; 155685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 155785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 155885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_pauseparam(struct net_device *netdev, 156085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 156185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 156285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 156385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 156485c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->rx_pause = priv->rx_pause; 156585c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->tx_pause = priv->tx_pause; 156685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 156785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 156885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_pauseparam(struct net_device *netdev, 156985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 157085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 157185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 157285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 157385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (pause->autoneg) 157485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 157585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 157685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_set_flow_ctrl(priv, pause->rx_pause, pause->tx_pause); 157785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 157885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 157985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_stats { 158085c10f28286148ee5cdba1d22c81936ff160596eRob Herring char stat_string[ETH_GSTRING_LEN]; 158185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int stat_offset; 158285c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool is_reg; 158385c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 158485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 158585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STAT(m) \ 158685c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, offsetof(struct xgmac_priv, xstats.m), false } 158785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_HW_STAT(m, reg_offset) \ 158885c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, reg_offset, true } 158985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 159085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct xgmac_stats xgmac_gstrings_stats[] = { 159185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_frame_flushed), 159285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_payload_error), 159385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_ip_header_error), 159485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_local_fault), 159585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_remote_fault), 159685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_early), 159785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_process_stopped), 159885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_jabber), 159985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_buf_unav), 160085c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_process_stopped), 160185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_payload_error), 160285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_ip_header_error), 160385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_da_filter_fail), 160485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(fatal_bus_error), 160585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_watchdog, XGMAC_MMC_RXWATCHDOG), 160685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_vlan, XGMAC_MMC_TXVLANFRAME), 160785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_vlan, XGMAC_MMC_RXVLANFRAME), 160885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_pause, XGMAC_MMC_TXPAUSEFRAME), 160985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_pause, XGMAC_MMC_RXPAUSEFRAME), 161085c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 161185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STATS_LEN ARRAY_SIZE(xgmac_gstrings_stats) 161285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 161385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_ethtool_stats(struct net_device *dev, 161485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_stats *dummy, 161585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u64 *data) 161685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 161785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 161885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void *p = priv; 161985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 162085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 162185c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 162285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (xgmac_gstrings_stats[i].is_reg) 162385c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = readl(priv->base + 162485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 162585c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 162685c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = *(u32 *)(p + 162785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 162885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 162985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 163085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 163185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_get_sset_count(struct net_device *netdev, int sset) 163285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 163385c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (sset) { 163485c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 163585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return XGMAC_STATS_LEN; 163685c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 163785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 163885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 163985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 164085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_strings(struct net_device *dev, u32 stringset, 164285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *data) 164385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 164485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 164585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *p = data; 164685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164785c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (stringset) { 164885c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 164985c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 165085c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(p, xgmac_gstrings_stats[i].stat_string, 165185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ETH_GSTRING_LEN); 165285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p += ETH_GSTRING_LEN; 165385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 165485c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 165585c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 165685c10f28286148ee5cdba1d22c81936ff160596eRob Herring WARN_ON(1); 165785c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 165885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 165985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 166085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_wol(struct net_device *dev, 166285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 166385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 166485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 166585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) { 166785c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->supported = WAKE_MAGIC | WAKE_UCAST; 166885c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->wolopts = priv->wolopts; 166985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 167085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 167185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 167285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_wol(struct net_device *dev, 167385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 167485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 167585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 167685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 support = WAKE_MAGIC | WAKE_UCAST; 167785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 167885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!device_can_wakeup(priv->device)) 167985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOTSUPP; 168085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 168185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts & ~support) 168285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 168385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 168485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = wol->wolopts; 168585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 168685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts) { 168785c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 1); 168885c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq_wake(dev->irq); 168985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 169085c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 0); 169185c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq_wake(dev->irq); 169285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 169385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 169485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 169585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 169685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1697bd601cc464e1ddc041d07ba2e4c015cdb9e392ecstephen hemmingerstatic const struct ethtool_ops xgmac_ethtool_ops = { 169885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_settings = xgmac_ethtool_getsettings, 169985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_link = ethtool_op_get_link, 170085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_pauseparam = xgmac_get_pauseparam, 170185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_pauseparam = xgmac_set_pauseparam, 170285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_ethtool_stats = xgmac_get_ethtool_stats, 170385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_strings = xgmac_get_strings, 170485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_wol = xgmac_get_wol, 170585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_wol = xgmac_set_wol, 170685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_sset_count = xgmac_get_sset_count, 170785c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 170885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 170985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 171085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_probe 171185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 171285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the driver is initialized through platform_device. 171385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 171485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_probe(struct platform_device *pdev) 171585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 171685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = 0; 171785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 171885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = NULL; 171985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = NULL; 172085c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 uid; 172185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172285c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 172385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!res) 172485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENODEV; 172585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!request_mem_region(res->start, resource_size(res), pdev->name)) 172785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 172885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev = alloc_etherdev(sizeof(struct xgmac_priv)); 173085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev) { 173185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 173285c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_alloc; 173385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 173485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 173585c10f28286148ee5cdba1d22c81936ff160596eRob Herring SET_NETDEV_DEV(ndev, &pdev->dev); 173685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv = netdev_priv(ndev); 173785c10f28286148ee5cdba1d22c81936ff160596eRob Herring platform_set_drvdata(pdev, ndev); 173885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->netdev_ops = &xgmac_netdev_ops; 17397ad24ea4bf620a32631d7b3069c3e30c078b0c3eWilfried Klaebe ndev->ethtool_ops = &xgmac_ethtool_ops; 174085c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_init(&priv->stats_lock); 17418746f671ef04114ab25f5a35ec6219efbdf3703eRob Herring INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work); 174285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 174385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->device = &pdev->dev; 174485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dev = ndev; 174585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = 1; 174685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = 1; 174785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 174885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base = ioremap(res->start, resource_size(res)); 174985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->base) { 175085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "ioremap failed\n"); 175185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 175285c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_io; 175385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 175485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 175585c10f28286148ee5cdba1d22c81936ff160596eRob Herring uid = readl(priv->base + XGMAC_VERSION); 175685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_info(ndev, "h/w version is 0x%x\n", uid); 175785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 17580cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring /* Figure out how many valid mac address filter registers we have */ 17590cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring writel(1, priv->base + XGMAC_ADDR_HIGH(31)); 17600cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring if (readl(priv->base + XGMAC_ADDR_HIGH(31)) == 1) 17610cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring priv->max_macs = 31; 17620cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring else 17630cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring priv->max_macs = 7; 17640cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6Rob Herring 176585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 176685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq = platform_get_irq(pdev, 0); 176785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ndev->irq == -ENXIO) { 176885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No irq resource\n"); 176985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = ndev->irq; 177085c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 177185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 177285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 177385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(ndev->irq, xgmac_interrupt, 0, 177485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 177585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 177685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 177785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq, ret); 177885c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 177985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 178085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq = platform_get_irq(pdev, 1); 178285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->pmt_irq == -ENXIO) { 178385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No pmt irq resource\n"); 178485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = priv->pmt_irq; 178585c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 178685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 178785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(priv->pmt_irq, xgmac_pmt_interrupt, 0, 178985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 179085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 179185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 179285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq, ret); 179385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 179485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 179585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 179685c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_capable(&pdev->dev, 1); 179785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) 179885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ 179985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 180050ae3c22763b77d55c59fb00274d4b9800e0c857Rob Herring ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA; 180185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL) 180285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 180385c10f28286148ee5cdba1d22c81936ff160596eRob Herring NETIF_F_RXCSUM; 180485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->features |= ndev->hw_features; 180585c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->priv_flags |= IFF_UNICAST_FLT; 180685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 180785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Get the MAC address */ 180885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_get_mac_addr(priv->base, ndev->dev_addr, 0); 180985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(ndev->dev_addr)) 181085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_warn(ndev, "MAC address %pM not valid", 181185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->dev_addr); 181285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 181385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_add(ndev, &priv->napi, xgmac_poll, 64); 181485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = register_netdev(ndev); 181585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret) 181685c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_reg; 181785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 181885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 181985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182085c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_reg: 182185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 182285c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 182385c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_pmt_irq: 182485c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 182585c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_irq: 182685c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 182785c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_io: 182885c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 182985c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_alloc: 183085c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 183185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 183285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 183385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 183585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_dvr_remove 183685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 183785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function resets the TX/RX processes, disables the MAC RX/TX 183885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * changes the link status, releases the DMA descriptor rings, 183985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * unregisters the MDIO bus and unmaps the allocated memory. 184085c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 184185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_remove(struct platform_device *pdev) 184285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 184385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(pdev); 184485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 184585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 184685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 184885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the IRQ lines */ 185085c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 185185c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 185285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unregister_netdev(ndev); 185485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 185585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185685c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 185785c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 185885c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 185985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186085c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 186185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 186385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 186485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_PM_SLEEP 186685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) 186785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 186885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int pmt = 0; 186985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_MAGIC) 1871e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN; 187285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_UCAST) 187385c10f28286148ee5cdba1d22c81936ff160596eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; 187485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(pmt, ioaddr + XGMAC_PMT); 187685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 187785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_suspend(struct device *dev) 187985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 188085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 188185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 188285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value; 188385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev || !netif_running(ndev)) 188585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 188685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_detach(ndev); 188885c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 188985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 189085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_may_wakeup(priv->device)) { 189285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop TX/RX DMA Only */ 189385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_CONTROL); 189485c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 189585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, priv->base + XGMAC_DMA_CONTROL); 189685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(priv->base, priv->wolopts); 189885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else 189985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 190085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 190285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 190385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_resume(struct device *dev) 190585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 190685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 190785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 190885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 190985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 191085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(ndev)) 191185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 191285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 191385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(ioaddr, 0); 191485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 191585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable the MAC and DMA */ 191685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_enable(ioaddr); 191785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 191885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); 191985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_attach(ndev); 192185c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_enable(&priv->napi); 192285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 192485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 1925c132cf56f1527d4667b52bf64453155bcacbea8aFabio Estevam#endif /* CONFIG_PM_SLEEP */ 192685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic SIMPLE_DEV_PM_OPS(xgmac_pm_ops, xgmac_suspend, xgmac_resume); 192885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct of_device_id xgmac_of_match[] = { 193085c10f28286148ee5cdba1d22c81936ff160596eRob Herring { .compatible = "calxeda,hb-xgmac", }, 193185c10f28286148ee5cdba1d22c81936ff160596eRob Herring {}, 193285c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 193385c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DEVICE_TABLE(of, xgmac_of_match); 193485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 193585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic struct platform_driver xgmac_driver = { 193685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .driver = { 193785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .name = "calxedaxgmac", 193885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .of_match_table = xgmac_of_match, 193985c10f28286148ee5cdba1d22c81936ff160596eRob Herring }, 194085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .probe = xgmac_probe, 194185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .remove = xgmac_remove, 1942c132cf56f1527d4667b52bf64453155bcacbea8aFabio Estevam .driver.pm = &xgmac_pm_ops, 194385c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 194485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 194585c10f28286148ee5cdba1d22c81936ff160596eRob Herringmodule_platform_driver(xgmac_driver); 194685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 194785c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_AUTHOR("Calxeda, Inc."); 194885c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DESCRIPTION("Calxeda 10G XGMAC driver"); 194985c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_LICENSE("GPL v2"); 1950