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