xgmac.c revision ef07387faf33a95e011993200902d490b605407d
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; 39685c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 39785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 39885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Configuration Settings */ 39985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAX_MTU 9000 40085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define PAUSE_TIME 0x400 40185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_RX_RING_SZ 256 40385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_TX_RING_SZ 128 40485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* minimum number of free TX descriptors required to wake up TX process */ 40585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TX_THRESH (DMA_TX_RING_SZ/4) 40685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40785c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA descriptor ring helpers */ 40885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_incr(n, s) (((n) + 1) & ((s) - 1)) 40985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_space(h, t, s) CIRC_SPACE(h, t, s) 41085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_cnt(h, t, s) CIRC_CNT(h, t, s) 41185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 41285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Descriptor Access Helpers */ 41385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz) 41485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 41585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (buf_sz > MAX_DESC_BUF_SZ) 41685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(MAX_DESC_BUF_SZ | 41785c10f28286148ee5cdba1d22c81936ff160596eRob Herring (buf_sz - MAX_DESC_BUF_SZ) << DESC_BUFFER2_SZ_OFFSET); 41885c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 41985c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(buf_sz); 42085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 42185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 42285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_buf_len(struct xgmac_dma_desc *p) 42385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 424ef07387faf33a95e011993200902d490b605407dRob Herring u32 len = le32_to_cpu(p->buf_size); 42585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return (len & DESC_BUFFER1_SZ_MASK) + 42685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET); 42785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 42885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 42985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_rx_desc(struct xgmac_dma_desc *p, int ring_size, 43085c10f28286148ee5cdba1d22c81936ff160596eRob Herring int buf_sz) 43185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 43285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *end = p + ring_size - 1; 43385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43485c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 43585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43685c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (; p <= end; p++) 43785c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, buf_sz); 43885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43985c10f28286148ee5cdba1d22c81936ff160596eRob Herring end->buf_size |= cpu_to_le32(RXDESC1_END_RING); 44085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 44185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_tx_desc(struct xgmac_dma_desc *p, u32 ring_size) 44385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 44485c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 44585c10f28286148ee5cdba1d22c81936ff160596eRob Herring p[ring_size - 1].flags = cpu_to_le32(TXDESC_END_RING); 44685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 44785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_owner(struct xgmac_dma_desc *p) 44985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & DESC_OWN; 45185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 45385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_rx_owner(struct xgmac_dma_desc *p) 45485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Clear all fields and set the owner */ 45685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(DESC_OWN); 45785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 45985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_tx_owner(struct xgmac_dma_desc *p, u32 flags) 46085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 46185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 tmpflags = le32_to_cpu(p->flags); 46285c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags &= TXDESC_END_RING; 46385c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags |= flags | DESC_OWN; 46485c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(tmpflags); 46585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 46685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 46785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_tx_ls(struct xgmac_dma_desc *p) 46885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 46985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & TXDESC_LAST_SEG; 47085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 47185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 47285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline u32 desc_get_buf_addr(struct xgmac_dma_desc *p) 47385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 47485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->buf1_addr); 47585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 47685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 47785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr(struct xgmac_dma_desc *p, 47885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 47985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 48085c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf1_addr = cpu_to_le32(paddr); 48185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (len > MAX_DESC_BUF_SZ) 48285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf2_addr = cpu_to_le32(paddr + MAX_DESC_BUF_SZ); 48385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 48485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 48585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr_and_size(struct xgmac_dma_desc *p, 48685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 48785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 48885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, len); 48985c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr(p, paddr, len); 49085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 49185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_rx_frame_len(struct xgmac_dma_desc *p) 49385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 49485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data = le32_to_cpu(p->flags); 49585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 len = (data & RXDESC_FRAME_LEN_MASK) >> RXDESC_FRAME_LEN_OFFSET; 49685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (data & RXDESC_FRAME_TYPE) 49785c10f28286148ee5cdba1d22c81936ff160596eRob Herring len -= ETH_FCS_LEN; 49885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return len; 50085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 50185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 50285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_dma_flush_tx_fifo(void __iomem *ioaddr) 50385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 50485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int timeout = 1000; 50585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg = readl(ioaddr + XGMAC_OMR); 50685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | XGMAC_OMR_FTF, ioaddr + XGMAC_OMR); 50785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 50885c10f28286148ee5cdba1d22c81936ff160596eRob Herring while ((timeout-- > 0) && readl(ioaddr + XGMAC_OMR) & XGMAC_OMR_FTF) 50985c10f28286148ee5cdba1d22c81936ff160596eRob Herring udelay(1); 51085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 51185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_tx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 51385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 51485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 51585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 51685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & TXDESC_ERROR_SUMMARY)) 51885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 51985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 52085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx desc error = 0x%08x\n", status); 52185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_JABBER_TIMEOUT) 52285c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 52385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_FRAME_FLUSHED) 52485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_frame_flushed++; 52585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_UNDERFLOW_ERR) 52685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_dma_flush_tx_fifo(priv->base); 52785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_IP_HEADER_ERR) 52885c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_ip_header_error++; 52985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_LOCAL_FAULT) 53085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_local_fault++; 53185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_REMOTE_FAULT) 53285c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_remote_fault++; 53385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_PAYLOAD_CSUM_ERR) 53485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_payload_error++; 53585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 53785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 53885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 54085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 54185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 54285c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = CHECKSUM_UNNECESSARY; 54385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 54485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ext_status = le32_to_cpu(p->ext_status); 54585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 54685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_DA_FILTER_FAIL) { 54785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "XGMAC RX : Dest Address filter fail\n"); 54885c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_da_filter_fail++; 54985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 55085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 55185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 552d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring /* All frames should fit into a single buffer */ 553d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG)) 554d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring return -1; 555d6fb3be544b46a7611a3373fcaa62b5b0be01888Rob Herring 55685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if packet has checksum already */ 55785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && 55885c10f28286148ee5cdba1d22c81936ff160596eRob Herring !(ext_status & RXDESC_IP_PAYLOAD_MASK)) 55985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = CHECKSUM_NONE; 56085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 56185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx status - frame type=%d, csum = %d, ext stat %08x\n", 56285c10f28286148ee5cdba1d22c81936ff160596eRob Herring (status & RXDESC_FRAME_TYPE) ? 1 : 0, ret, ext_status); 56385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 56485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & RXDESC_ERROR_SUMMARY)) 56585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 56685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 56785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Handle any errors */ 56885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & (RXDESC_DESCRIPTOR_ERR | RXDESC_OVERFLOW_ERR | 56985c10f28286148ee5cdba1d22c81936ff160596eRob Herring RXDESC_GIANT_FRAME | RXDESC_LENGTH_ERR | RXDESC_CRC_ERR)) 57085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 57185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 57285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_EXT_STATUS) { 57385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_HEADER_ERR) 57485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_ip_header_error++; 57585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_PAYLOAD_ERR) 57685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_payload_error++; 57785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "IP checksum error - stat %08x\n", 57885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ext_status); 57985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return CHECKSUM_NONE; 58085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 58185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 58285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 58385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 58485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 58585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_enable(void __iomem *ioaddr) 58685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 58785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_CONTROL); 58885c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= MAC_ENABLE_RX | MAC_ENABLE_TX; 58985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 59085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59185c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_DMA_CONTROL); 59285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= DMA_CONTROL_ST | DMA_CONTROL_SR; 59385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 59485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 59585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_disable(void __iomem *ioaddr) 59785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 59885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_DMA_CONTROL); 59985c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 60085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 60185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_CONTROL); 60385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); 60485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 60585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 60685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_mac_addr(void __iomem *ioaddr, unsigned char *addr, 60885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 60985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 61085c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data; 61185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 61285c10f28286148ee5cdba1d22c81936ff160596eRob Herring data = (addr[5] << 8) | addr[4] | (num ? XGMAC_ADDR_AE : 0); 61385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(data, ioaddr + XGMAC_ADDR_HIGH(num)); 61485c10f28286148ee5cdba1d22c81936ff160596eRob Herring data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 61585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(data, ioaddr + XGMAC_ADDR_LOW(num)); 61685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 61785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 61885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, 61985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 62085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 62185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hi_addr, lo_addr; 62285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 62385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Read the MAC address from the hardware */ 62485c10f28286148ee5cdba1d22c81936ff160596eRob Herring hi_addr = readl(ioaddr + XGMAC_ADDR_HIGH(num)); 62585c10f28286148ee5cdba1d22c81936ff160596eRob Herring lo_addr = readl(ioaddr + XGMAC_ADDR_LOW(num)); 62685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 62785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Extract the MAC address from the high and low words */ 62885c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[0] = lo_addr & 0xff; 62985c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[1] = (lo_addr >> 8) & 0xff; 63085c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[2] = (lo_addr >> 16) & 0xff; 63185c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[3] = (lo_addr >> 24) & 0xff; 63285c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[4] = hi_addr & 0xff; 63385c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[5] = (hi_addr >> 8) & 0xff; 63485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 63585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 63685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_flow_ctrl(struct xgmac_priv *priv, int rx, int tx) 63785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 63885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg; 63985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int flow = 0; 64085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = rx; 64285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = tx; 64385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx || tx) { 64585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx) 64685c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_RFE; 64785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (tx) 64885c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_TFE; 64985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 65085c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_PLT | XGMAC_FLOW_CTRL_UP; 65185c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= (PAUSE_TIME << XGMAC_FLOW_CTRL_PT_SHIFT); 65285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 65385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(flow, priv->base + XGMAC_FLOW_CTRL); 65485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 65585c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_OMR); 65685c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg |= XGMAC_OMR_EFC; 65785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg, priv->base + XGMAC_OMR); 65885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 65985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_FLOW_CTRL); 66085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66185c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_OMR); 66285c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg &= ~XGMAC_OMR_EFC; 66385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg, priv->base + XGMAC_OMR); 66485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 66585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 66785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 66885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_rx_refill(struct xgmac_priv *priv) 67085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 67185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 67285c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 673ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring int bufsz = priv->dev->mtu + ETH_HLEN + ETH_FCS_LEN; 67485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67585c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_space(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ) > 1) { 67685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int entry = priv->rx_head; 67785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 67885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67985c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 68085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 6817c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring if (priv->rx_skbuff[entry] == NULL) { 682ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring skb = netdev_alloc_skb_ip_align(priv->dev, bufsz); 6837c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring if (unlikely(skb == NULL)) 6847c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring break; 6857c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring 6867c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring priv->rx_skbuff[entry] = skb; 6877c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring paddr = dma_map_single(priv->device, skb->data, 688ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring bufsz, DMA_FROM_DEVICE); 6897c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring desc_set_buf_addr(p, paddr, priv->dma_buf_sz); 6907c4009192ea2276c1d7ed8ec0a18f3ecfca5cd2bRob Herring } 69185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx ring: head %d, tail %d\n", 69385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head, priv->rx_tail); 69485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = dma_ring_incr(priv->rx_head, DMA_RX_RING_SZ); 69685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_rx_owner(p); 69785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 69885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 69985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 70085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 70185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * init_xgmac_dma_desc_rings - init the RX/TX descriptor rings 70285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev: net device structure 70385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function initializes the DMA RX/TX descriptors 70485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * and allocates the socket buffers. 70585c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 70685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_dma_desc_rings_init(struct net_device *dev) 70785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 70885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 70985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int bfsize; 71085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set the Buffer size according to the MTU; 712ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring * The total buffer size including any IP offset must be a multiple 713ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring * of 8 bytes. 71485c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 715ef468d234753aff7afa96075d3be135b0df1ded0Rob Herring bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN, 8); 71685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); 71885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_RX_RING_SZ, 72085c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 72185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 72285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 72385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 72485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = dma_alloc_coherent(priv->device, 72585c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * 72685c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 72785c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_rx_phy, 72885c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 72985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_rx) 73085c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_rx; 73185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 73285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_TX_RING_SZ, 73385c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 73485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 73585c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_tx_skb; 73685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 73785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = dma_alloc_coherent(priv->device, 73885c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * 73985c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 74085c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_tx_phy, 74185c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 74285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_tx) 74385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_tx; 74485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "DMA desc rings: virt addr (Rx %p, " 74685c10f28286148ee5cdba1d22c81936ff160596eRob Herring "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 74785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_tx, 74885c10f28286148ee5cdba1d22c81936ff160596eRob Herring (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 74985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 75085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = 0; 75185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = 0; 75285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz = bfsize; 75385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_rx_desc(priv->dma_rx, DMA_RX_RING_SZ, priv->dma_buf_sz); 75485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 75585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 75685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 75785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 75885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 75985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR); 76185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_rx_phy, priv->base + XGMAC_DMA_RX_BASE_ADDR); 76285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 76485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76585c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_tx: 76685c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 76785c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_tx_skb: 76885c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 76985c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 77085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 77185c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_rx: 77285c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 77385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 77485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 77585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 77685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_rx_skbufs(struct xgmac_priv *priv) 77785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 77885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 77985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 78085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 78285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 78385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_RX_RING_SZ; i++) { 78585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->rx_skbuff[i] == NULL) 78685c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 78785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78885c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + i; 78985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 79085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz, DMA_FROM_DEVICE); 79185c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb_any(priv->rx_skbuff[i]); 79285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[i] = NULL; 79385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 79485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 79585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 79685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_tx_skbufs(struct xgmac_priv *priv) 79785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 79885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i, f; 79985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 80085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 80285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 80385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_TX_RING_SZ; i++) { 80585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->tx_skbuff[i] == NULL) 80685c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 80785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80885c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + i; 80985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 81085c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 81185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 81285c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (f = 0; f < skb_shinfo(priv->tx_skbuff[i])->nr_frags; f++) { 81385c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + i++; 81485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 81585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 81685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 81785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 81885c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb_any(priv->tx_skbuff[i]); 81985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[i] = NULL; 82085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 82185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 82285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_dma_desc_rings(struct xgmac_priv *priv) 82485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 82585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release the DMA TX/RX socket buffers */ 82685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_rx_skbufs(priv); 82785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 82885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the consistent memory allocated for descriptor rings */ 83085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_tx) { 83185c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 83285c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * sizeof(struct xgmac_dma_desc), 83385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx, priv->dma_tx_phy); 83485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = NULL; 83585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 83685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_rx) { 83785c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 83885c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 83985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 84085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = NULL; 84185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 84285c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 84385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = NULL; 84485c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 84585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = NULL; 84685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 84785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 84885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 84985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx: 85085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @priv: private driver structure 85185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: it reclaims resources after transmission completes. 85285c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 85385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_complete(struct xgmac_priv *priv) 85485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 85585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 85685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 85785c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) { 85885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry = priv->tx_tail; 85985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb = priv->tx_skbuff[entry]; 86085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p = priv->dma_tx + entry; 86185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 86285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if the descriptor is owned by the DMA. */ 86385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 86485c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 86585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 86685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Verify tx error by looking at the last segment */ 86785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_tx_ls(p)) 86885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_tx_status(priv, p); 86985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx ring: curr %d, dirty %d\n", 87185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head, priv->tx_tail); 87285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 87485c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 87585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = NULL; 87785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ); 87885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!skb) { 88085c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 88185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 88285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88385c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 88485c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->tx_tail = dma_ring_incr(priv->tx_tail, 88585c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ); 88685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + priv->tx_tail; 88785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88885c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 88985c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 89085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 89185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 892acb600def2110b1310466c0e485c0d26299898aeEric Dumazet dev_kfree_skb(skb); 89385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 89485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 89585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) > 89697a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring MAX_SKB_FRAGS) 89785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 89885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 89985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 90085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 90185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx_err: 90285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @priv: pointer to the private device structure 90385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: it cleans the descriptors and restarts the transmission 90485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * in case of errors. 90585c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 90685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_err(struct xgmac_priv *priv) 90785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 90885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg, value, inten; 90985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 91085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_stop_queue(priv->dev); 91185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 91285c10f28286148ee5cdba1d22c81936ff160596eRob Herring inten = readl(priv->base + XGMAC_DMA_INTR_ENA); 91385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 91485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 91585c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_DMA_CONTROL); 91685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg & ~DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 91785c10f28286148ee5cdba1d22c81936ff160596eRob Herring do { 91885c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_STATUS) & 0x700000; 91985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } while (value && (value != 0x600000)); 92085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 92285c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 92385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 92485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 925eb5e1b29a5ff4b782796ec9d17b443b5b38b7ffeRob Herring writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR); 92685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 92785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS, 92985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base + XGMAC_DMA_STATUS); 93085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(inten, priv->base + XGMAC_DMA_INTR_ENA); 93185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 93385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 93485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_hw_init(struct net_device *dev) 93685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 93785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value, ctrl; 93885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int limit; 93985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 94085c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 94185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 94285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Save the ctrl register value */ 94385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL) & XGMAC_CONTROL_SPD_MASK; 94485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 94585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* SW reset */ 94685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = DMA_BUS_MODE_SFT_RESET; 94785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 94885c10f28286148ee5cdba1d22c81936ff160596eRob Herring limit = 15000; 94985c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (limit-- && 95085c10f28286148ee5cdba1d22c81936ff160596eRob Herring (readl(ioaddr + XGMAC_DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) 95185c10f28286148ee5cdba1d22c81936ff160596eRob Herring cpu_relax(); 95285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (limit < 0) 95385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 95485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 95585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = (0x10 << DMA_BUS_MODE_PBL_SHIFT) | 95685c10f28286148ee5cdba1d22c81936ff160596eRob Herring (0x10 << DMA_BUS_MODE_RPBL_SHIFT) | 95785c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_BUS_MODE_FB | DMA_BUS_MODE_ATDS | DMA_BUS_MODE_AAL; 95885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 95985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 96085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable interrupts */ 96185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 96285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, 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 103085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 103185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 103285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 103485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_release - close entry point of the driver 103585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 103685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 103785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This is the stop entry point of the driver. 103885c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 103985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_stop(struct net_device *dev) 104085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 104185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 104285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 104385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_stop_queue(dev); 104485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 104585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_INTR_ENA)) 104685c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 104785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 104885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 104985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Disable the MAC core */ 105185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 105285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release and free the Rx/Tx resources */ 105485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_dma_desc_rings(priv); 105585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 105785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 105885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 106085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_xmit: 106185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @skb : the socket buffer 106285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer 106385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : Tx entry point of the driver. 106485c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 106585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) 106685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 106785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 106885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 106985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 107097a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring u32 irq_flag; 107185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int nfrags = skb_shinfo(skb)->nr_frags; 107285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *desc, *first; 107385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int desc_flags; 107485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int len; 107585c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 107685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 107797a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring priv->tx_irq_cnt = (priv->tx_irq_cnt + 1) & (DMA_TX_RING_SZ/4 - 1); 107897a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring irq_flag = priv->tx_irq_cnt ? 0 : TXDESC_INTERRUPT; 107985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 108085c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? 108185c10f28286148ee5cdba1d22c81936ff160596eRob Herring TXDESC_CSUM_ALL : 0; 108285c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->tx_head; 108385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 108485c10f28286148ee5cdba1d22c81936ff160596eRob Herring first = desc; 108585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 108685c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = skb_headlen(skb); 108785c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = dma_map_single(priv->device, skb->data, len, DMA_TO_DEVICE); 108885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_mapping_error(priv->device, paddr)) { 108985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb(skb); 109085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EIO; 109185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 109285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = skb; 109385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 109485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109585c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < nfrags; i++) { 109685c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 109785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109885c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = frag->size; 109985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 110085c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = skb_frag_dma_map(priv->device, frag, 0, len, 110185c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TO_DEVICE); 110285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_mapping_error(priv->device, paddr)) { 110385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb(skb); 110485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EIO; 110585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 110685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 110785c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = dma_ring_incr(entry, DMA_TX_RING_SZ); 110885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 110985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = NULL; 111085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 111285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (i < (nfrags - 1)) 111385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags); 111485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 111585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Interrupt on completition only for the latest segment */ 111785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc != first) 111885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags | 111997a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring TXDESC_LAST_SEG | irq_flag); 112085c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 112197a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring desc_flags |= TXDESC_LAST_SEG | irq_flag; 112285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set owner on first desc last to avoid race condition */ 112485c10f28286148ee5cdba1d22c81936ff160596eRob Herring wmb(); 112585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(first, desc_flags | TXDESC_FIRST_SEG); 112685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); 112885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(1, priv->base + XGMAC_DMA_TX_POLL); 113097a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < 113197a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring MAX_SKB_FRAGS) 113297a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring netif_stop_queue(dev); 113385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 113485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return NETDEV_TX_OK; 113585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 113685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 113785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_rx(struct xgmac_priv *priv, int limit) 113885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 113985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 114085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int count = 0; 114185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 114285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114385c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (count < limit) { 114485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ip_checksum; 114585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 114685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int frame_len; 114785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1148dc574f1d52d893f516f3786ff7635450bac00eefRob Herring if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ)) 1149dc574f1d52d893f516f3786ff7635450bac00eefRob Herring break; 1150dc574f1d52d893f516f3786ff7635450bac00eefRob Herring 115185c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->rx_tail; 115285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 115385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 115485c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 115585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 115685c10f28286148ee5cdba1d22c81936ff160596eRob Herring count++; 115785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = dma_ring_incr(priv->rx_tail, DMA_RX_RING_SZ); 115885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 115985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status of the incoming frame */ 116085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ip_checksum = desc_get_rx_status(priv, p); 116185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum < 0) 116285c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 116385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 116485c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb = priv->rx_skbuff[entry]; 116585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(!skb)) { 116685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "Inconsistent Rx descriptor chain\n"); 116785c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 116885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 116985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[entry] = NULL; 117085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 117185c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len = desc_get_rx_frame_len(p); 117285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "RX frame size %d, COE status: %d\n", 117385c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len, ip_checksum); 117485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 117585c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_put(skb, frame_len); 117685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 117785c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len, DMA_FROM_DEVICE); 117885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 117985c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->protocol = eth_type_trans(skb, priv->dev); 118085c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->ip_summed = ip_checksum; 118185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum == CHECKSUM_NONE) 118285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_receive_skb(skb); 118385c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 118485c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_gro_receive(&priv->napi, skb); 118585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 118685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 118885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return count; 119085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 119185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 119285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 119385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_poll - xgmac poll method (NAPI) 119485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @napi : pointer to the napi structure. 119585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @budget : maximum number of packets that the current CPU can receive from 119685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * all interfaces. 119785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : 119885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function implements the the reception process. 119985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Also it runs the TX completion thread 120085c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 120185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_poll(struct napi_struct *napi, int budget) 120285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 120385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = container_of(napi, 120485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv, napi); 120585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int work_done = 0; 120685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 120785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_complete(priv); 120885c10f28286148ee5cdba1d22c81936ff160596eRob Herring work_done = xgmac_rx(priv, budget); 120985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (work_done < budget) { 121185c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_complete(napi); 12120ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); 121385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 121485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return work_done; 121585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 121685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121785c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 121885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx_timeout 121985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : Pointer to net device structure 122085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function is called when a packet transmission fails to 122185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * complete within a reasonable tmrate. The driver will mark the error in the 122285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * netdev structure and arrange for the device to be reset to a sane state 122385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * in order to transmit a new packet. 122485c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 122585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_timeout(struct net_device *dev) 122685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 122785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 122885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 122985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Clear Tx resources and restart transmitting again */ 123085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_err(priv); 123185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 123285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 123385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 123485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_set_rx_mode - entry point for multicast addressing 123585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : pointer to the device structure 123685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 123785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function is a driver entry point which gets called by the kernel 123885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * whenever multicast addresses must be enabled/disabled. 123985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 124085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * void. 124185c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 124285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_rx_mode(struct net_device *dev) 124385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 124485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 124585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 124685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 124785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int value = 0; 124885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hash_filter[XGMAC_NUM_HASH]; 124985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int reg = 1; 125085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct netdev_hw_addr *ha; 125185c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool use_hash = false; 125285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 125385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "# mcasts %d, # unicast %d\n", 125485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_mc_count(dev), netdev_uc_count(dev)); 125585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 125685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->flags & IFF_PROMISC) { 125785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_FRAME_FILTER_PR, ioaddr + XGMAC_FRAME_FILTER); 125885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 125985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 126085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 126185c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(hash_filter, 0, sizeof(hash_filter)); 126285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 126385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (netdev_uc_count(dev) > XGMAC_MAX_FILTER_ADDR) { 126485c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 126585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF; 126685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 126785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_uc_addr(ha, dev) { 126885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 126985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 127085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 127185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 127285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 127385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 127485c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 127585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 127685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 127785c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 127885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 127985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 128085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 128185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->flags & IFF_ALLMULTI) { 128285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_PM; 128385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto out; 128485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 128585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 128685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((netdev_mc_count(dev) + reg - 1) > XGMAC_MAX_FILTER_ADDR) { 128785c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 128885c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF; 128985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 129085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_mc_addr(ha, dev) { 129185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 129285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 129385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 129485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 129585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 129685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 129785c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 129885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 129985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 130085c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 130185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 130285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 130385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 130485c10f28286148ee5cdba1d22c81936ff160596eRob Herringout: 130585c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_NUM_HASH; i++) 130685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(hash_filter[i], ioaddr + XGMAC_HASH(i)); 130785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 130885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_FRAME_FILTER); 130985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 131085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 131185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 131285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_change_mtu - entry point to change MTU size for the device. 131385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 131485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @new_mtu : the new MTU size for the device. 131585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the Maximum Transfer Unit (MTU) is used by the network layer 131685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to drive packet transmission. Ethernet has an MTU of 1500 octets 131785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * (ETH_DATA_LEN). This value can be changed with ifconfig. 131885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 131985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 0 on success and an appropriate (-)ve integer as defined in errno.h 132085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * file on failure. 132185c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 132285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_change_mtu(struct net_device *dev, int new_mtu) 132385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 132485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 132585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int old_mtu; 132685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 132785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((new_mtu < 46) || (new_mtu > MAX_MTU)) { 132885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "invalid MTU, max MTU is: %d\n", MAX_MTU); 132985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 133085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 133185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 133285c10f28286148ee5cdba1d22c81936ff160596eRob Herring old_mtu = dev->mtu; 133385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev->mtu = new_mtu; 133485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 133585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* return early if the buffer sizes will not change */ 133685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN) 133785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 133885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (old_mtu == new_mtu) 133985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 134085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop everything, get ready to change the MTU */ 134285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(dev)) 134385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 134485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Bring the interface down and then back up */ 134685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_stop(dev); 134785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_open(dev); 134885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 134985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 135085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id) 135185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 135285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 135385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 135485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 135585c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 135685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 13570ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status = __raw_readl(ioaddr + XGMAC_INT_STAT); 135885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & XGMAC_INT_STAT_PMT) { 135985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "received Magic frame\n"); 136085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* clear the PMT bits 5 and 6 by reading the PMT */ 136185c10f28286148ee5cdba1d22c81936ff160596eRob Herring readl(ioaddr + XGMAC_PMT); 136285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 136385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 136485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 136585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 136685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_interrupt(int irq, void *dev_id) 136785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 136885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 136985c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool tx_err = false; 137085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 137185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 137285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 137385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status register (CSR5) */ 13750ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status = __raw_readl(priv->base + XGMAC_DMA_STATUS); 13760ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring intr_status &= __raw_readl(priv->base + XGMAC_DMA_INTR_ENA); 13770ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(intr_status, priv->base + XGMAC_DMA_STATUS); 137885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* It displays the DMA process states (CSR5 register) */ 138085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* ABNORMAL interrupts */ 138185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(intr_status & DMA_STATUS_AIS)) { 138285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TJT) { 138385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit jabber\n"); 138485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 138585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 138685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RU) 138785c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_buf_unav++; 138885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RPS) { 138985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "receive process stopped\n"); 139085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_process_stopped++; 139185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 139285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_ETI) { 139385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit early interrupt\n"); 139485c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_early++; 139585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 139685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TPS) { 139785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit process stopped\n"); 139885c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_process_stopped++; 139985c10f28286148ee5cdba1d22c81936ff160596eRob Herring tx_err = true; 140085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 140185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_FBI) { 140285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "fatal bus error\n"); 140385c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->fatal_bus_error++; 140485c10f28286148ee5cdba1d22c81936ff160596eRob Herring tx_err = true; 140585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 140685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 140785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (tx_err) 140885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_err(priv); 140985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 141085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 141185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* TX/RX NORMAL interrupts */ 141297a3a9a67b711bedc1e0d3a33a0dd019c3af2f46Rob Herring if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU | DMA_STATUS_TI)) { 14130ec6d343f7bcf9e0944aa9ff65287b987ec00c0fRob Herring __raw_writel(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); 141485c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_schedule(&priv->napi); 141585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 141685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 141785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 141885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 141985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 142085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 142185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Polling receive - used by NETCONSOLE and other diagnostic tools 142285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to allow network I/O with interrupts disabled. */ 142385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_poll_controller(struct net_device *dev) 142485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 142585c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq(dev->irq); 142685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_interrupt(dev->irq, dev); 142785c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq(dev->irq); 142885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 142985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 143085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1431bd601cc464e1ddc041d07ba2e4c015cdb9e392ecstephen hemmingerstatic struct rtnl_link_stats64 * 143285c10f28286148ee5cdba1d22c81936ff160596eRob Herringxgmac_get_stats64(struct net_device *dev, 143385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct rtnl_link_stats64 *storage) 143485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 143585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 143685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *base = priv->base; 143785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 count; 143885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 143985c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_bh(&priv->stats_lock); 144085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_MMC_CTRL_CNT_FRZ, base + XGMAC_MMC_CTRL); 144185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 144285c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes = readl(base + XGMAC_MMC_RXOCTET_G_LO); 144385c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes |= (u64)(readl(base + XGMAC_MMC_RXOCTET_G_HI)) << 32; 144485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 144585c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_packets = readl(base + XGMAC_MMC_RXFRAME_GB_LO); 144685c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->multicast = readl(base + XGMAC_MMC_RXMCFRAME_G); 144785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_crc_errors = readl(base + XGMAC_MMC_RXCRCERR); 144885c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_length_errors = readl(base + XGMAC_MMC_RXLENGTHERR); 144985c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_missed_errors = readl(base + XGMAC_MMC_RXOVERFLOW); 145085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145185c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes = readl(base + XGMAC_MMC_TXOCTET_G_LO); 145285c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes |= (u64)(readl(base + XGMAC_MMC_TXOCTET_G_HI)) << 32; 145385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145485c10f28286148ee5cdba1d22c81936ff160596eRob Herring count = readl(base + XGMAC_MMC_TXFRAME_GB_LO); 145585c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_errors = count - readl(base + XGMAC_MMC_TXFRAME_G_LO); 145685c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_packets = count; 145785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_fifo_errors = readl(base + XGMAC_MMC_TXUNDERFLOW); 145885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, base + XGMAC_MMC_CTRL); 146085c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_unlock_bh(&priv->stats_lock); 146185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return storage; 146285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 146385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 146485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_mac_address(struct net_device *dev, void *p) 146585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 146685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 146785c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 146885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sockaddr *addr = p; 146985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(addr->sa_data)) 147185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EADDRNOTAVAIL; 147285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147385c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 147485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0); 147685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 147885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 147985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_features(struct net_device *dev, netdev_features_t features) 148185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 148285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ctrl; 148385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 148485c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 1485cf62cb72d63944f4dcc7376efd84959afc9366cbDan Carpenter netdev_features_t changed = dev->features ^ features; 148685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(changed & NETIF_F_RXCSUM)) 148885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 148985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL); 149185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (features & NETIF_F_RXCSUM) 149285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_IPC; 149385c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 149485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl &= ~XGMAC_CONTROL_IPC; 149585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(ctrl, ioaddr + XGMAC_CONTROL); 149685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 149885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 149985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct net_device_ops xgmac_netdev_ops = { 150185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_open = xgmac_open, 150285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_start_xmit = xgmac_xmit, 150385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_stop = xgmac_stop, 150485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_change_mtu = xgmac_change_mtu, 150585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_rx_mode = xgmac_set_rx_mode, 150685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_tx_timeout = xgmac_tx_timeout, 150785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_get_stats64 = xgmac_get_stats64, 150885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 150985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_poll_controller = xgmac_poll_controller, 151085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 151185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_mac_address = xgmac_set_mac_address, 151285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_features = xgmac_set_features, 151385c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 151485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 151585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_ethtool_getsettings(struct net_device *dev, 151685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_cmd *cmd) 151785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 151885c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->autoneg = 0; 151985c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->duplex = DUPLEX_FULL; 152085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ethtool_cmd_speed_set(cmd, 10000); 152185c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->supported = 0; 152285c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->advertising = 0; 152385c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->transceiver = XCVR_INTERNAL; 152485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 152585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 152685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 152785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_pauseparam(struct net_device *netdev, 152885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 152985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 153085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 153185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 153285c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->rx_pause = priv->rx_pause; 153385c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->tx_pause = priv->tx_pause; 153485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 153585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 153685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_pauseparam(struct net_device *netdev, 153785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 153885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 153985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 154085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (pause->autoneg) 154285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 154385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_set_flow_ctrl(priv, pause->rx_pause, pause->tx_pause); 154585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 154685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_stats { 154885c10f28286148ee5cdba1d22c81936ff160596eRob Herring char stat_string[ETH_GSTRING_LEN]; 154985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int stat_offset; 155085c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool is_reg; 155185c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 155285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STAT(m) \ 155485c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, offsetof(struct xgmac_priv, xstats.m), false } 155585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_HW_STAT(m, reg_offset) \ 155685c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, reg_offset, true } 155785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct xgmac_stats xgmac_gstrings_stats[] = { 155985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_frame_flushed), 156085c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_payload_error), 156185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_ip_header_error), 156285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_local_fault), 156385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_remote_fault), 156485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_early), 156585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_process_stopped), 156685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_jabber), 156785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_buf_unav), 156885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_process_stopped), 156985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_payload_error), 157085c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_ip_header_error), 157185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_da_filter_fail), 157285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_sa_filter_fail), 157385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(fatal_bus_error), 157485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_watchdog, XGMAC_MMC_RXWATCHDOG), 157585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_vlan, XGMAC_MMC_TXVLANFRAME), 157685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_vlan, XGMAC_MMC_RXVLANFRAME), 157785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_pause, XGMAC_MMC_TXPAUSEFRAME), 157885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_pause, XGMAC_MMC_RXPAUSEFRAME), 157985c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 158085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STATS_LEN ARRAY_SIZE(xgmac_gstrings_stats) 158185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 158285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_ethtool_stats(struct net_device *dev, 158385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_stats *dummy, 158485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u64 *data) 158585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 158685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 158785c10f28286148ee5cdba1d22c81936ff160596eRob Herring void *p = priv; 158885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 158985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 159085c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 159185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (xgmac_gstrings_stats[i].is_reg) 159285c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = readl(priv->base + 159385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 159485c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 159585c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = *(u32 *)(p + 159685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 159785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 159885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 159985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 160085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_get_sset_count(struct net_device *netdev, int sset) 160185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 160285c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (sset) { 160385c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 160485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return XGMAC_STATS_LEN; 160585c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 160685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 160785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 160885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 160985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 161085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_strings(struct net_device *dev, u32 stringset, 161185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *data) 161285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 161385c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 161485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *p = data; 161585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 161685c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (stringset) { 161785c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 161885c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 161985c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(p, xgmac_gstrings_stats[i].stat_string, 162085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ETH_GSTRING_LEN); 162185c10f28286148ee5cdba1d22c81936ff160596eRob Herring p += ETH_GSTRING_LEN; 162285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 162385c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 162485c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 162585c10f28286148ee5cdba1d22c81936ff160596eRob Herring WARN_ON(1); 162685c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 162785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 162885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 162985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 163085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_wol(struct net_device *dev, 163185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 163285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 163385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 163485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 163585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) { 163685c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->supported = WAKE_MAGIC | WAKE_UCAST; 163785c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->wolopts = priv->wolopts; 163885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 163985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 164085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_wol(struct net_device *dev, 164285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 164385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 164485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 164585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 support = WAKE_MAGIC | WAKE_UCAST; 164685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!device_can_wakeup(priv->device)) 164885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOTSUPP; 164985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 165085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts & ~support) 165185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 165285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 165385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = wol->wolopts; 165485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 165585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts) { 165685c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 1); 165785c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq_wake(dev->irq); 165885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 165985c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 0); 166085c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq_wake(dev->irq); 166185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 166285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 166485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 166585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 1666bd601cc464e1ddc041d07ba2e4c015cdb9e392ecstephen hemmingerstatic const struct ethtool_ops xgmac_ethtool_ops = { 166785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_settings = xgmac_ethtool_getsettings, 166885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_link = ethtool_op_get_link, 166985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_pauseparam = xgmac_get_pauseparam, 167085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_pauseparam = xgmac_set_pauseparam, 167185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_ethtool_stats = xgmac_get_ethtool_stats, 167285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_strings = xgmac_get_strings, 167385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_wol = xgmac_get_wol, 167485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_wol = xgmac_set_wol, 167585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_sset_count = xgmac_get_sset_count, 167685c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 167785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 167885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 167985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_probe 168085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 168185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the driver is initialized through platform_device. 168285c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 168385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_probe(struct platform_device *pdev) 168485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 168585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = 0; 168685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 168785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = NULL; 168885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = NULL; 168985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 uid; 169085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 169185c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 169285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!res) 169385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENODEV; 169485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 169585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!request_mem_region(res->start, resource_size(res), pdev->name)) 169685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 169785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 169885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev = alloc_etherdev(sizeof(struct xgmac_priv)); 169985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev) { 170085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 170185c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_alloc; 170285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 170385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 170485c10f28286148ee5cdba1d22c81936ff160596eRob Herring SET_NETDEV_DEV(ndev, &pdev->dev); 170585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv = netdev_priv(ndev); 170685c10f28286148ee5cdba1d22c81936ff160596eRob Herring platform_set_drvdata(pdev, ndev); 170785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ether_setup(ndev); 170885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->netdev_ops = &xgmac_netdev_ops; 170985c10f28286148ee5cdba1d22c81936ff160596eRob Herring SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops); 171085c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_init(&priv->stats_lock); 171185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 171285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->device = &pdev->dev; 171385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dev = ndev; 171485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = 1; 171585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = 1; 171685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 171785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base = ioremap(res->start, resource_size(res)); 171885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->base) { 171985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "ioremap failed\n"); 172085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 172185c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_io; 172285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 172385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172485c10f28286148ee5cdba1d22c81936ff160596eRob Herring uid = readl(priv->base + XGMAC_VERSION); 172585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_info(ndev, "h/w version is 0x%x\n", uid); 172685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 172885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq = platform_get_irq(pdev, 0); 172985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ndev->irq == -ENXIO) { 173085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No irq resource\n"); 173185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = ndev->irq; 173285c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 173385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 173485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 173585c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(ndev->irq, xgmac_interrupt, 0, 173685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 173785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 173885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 173985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq, ret); 174085c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 174185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 174285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 174385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq = platform_get_irq(pdev, 1); 174485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->pmt_irq == -ENXIO) { 174585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No pmt irq resource\n"); 174685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = priv->pmt_irq; 174785c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 174885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 174985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 175085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(priv->pmt_irq, xgmac_pmt_interrupt, 0, 175185c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 175285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 175385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 175485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq, ret); 175585c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 175685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 175785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 175885c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_capable(&pdev->dev, 1); 175985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) 176085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ 176185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 176250ae3c22763b77d55c59fb00274d4b9800e0c857Rob Herring ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA; 176385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL) 176485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 176585c10f28286148ee5cdba1d22c81936ff160596eRob Herring NETIF_F_RXCSUM; 176685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->features |= ndev->hw_features; 176785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->priv_flags |= IFF_UNICAST_FLT; 176885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 176985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Get the MAC address */ 177085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_get_mac_addr(priv->base, ndev->dev_addr, 0); 177185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(ndev->dev_addr)) 177285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_warn(ndev, "MAC address %pM not valid", 177385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->dev_addr); 177485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 177585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_add(ndev, &priv->napi, xgmac_poll, 64); 177685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = register_netdev(ndev); 177785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret) 177885c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_reg; 177985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 178185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178285c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_reg: 178385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 178485c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 178585c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_pmt_irq: 178685c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 178785c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_irq: 178885c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 178985c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_io: 179085c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 179185c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_alloc: 179285c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 179385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 179485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 179585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 179685c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 179785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_dvr_remove 179885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 179985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function resets the TX/RX processes, disables the MAC RX/TX 180085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * changes the link status, releases the DMA descriptor rings, 180185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * unregisters the MDIO bus and unmaps the allocated memory. 180285c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 180385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_remove(struct platform_device *pdev) 180485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 180585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(pdev); 180685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 180785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 180885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 180985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 181085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 181185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the IRQ lines */ 181285c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 181385c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 181485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 181585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unregister_netdev(ndev); 181685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 181785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 181885c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 181985c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 182085c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 182185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182285c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 182385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 182585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 182685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_PM_SLEEP 182885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) 182985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 183085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int pmt = 0; 183185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_MAGIC) 1833e6c3827dcfe53dd78b824d2ee4007a216ada739eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN; 183485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_UCAST) 183585c10f28286148ee5cdba1d22c81936ff160596eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; 183685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(pmt, ioaddr + XGMAC_PMT); 183885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 183985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_suspend(struct device *dev) 184185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 184285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 184385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 184485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value; 184585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev || !netif_running(ndev)) 184785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 184885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_detach(ndev); 185085c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 185185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 185285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_may_wakeup(priv->device)) { 185485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop TX/RX DMA Only */ 185585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_CONTROL); 185685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 185785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, priv->base + XGMAC_DMA_CONTROL); 185885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(priv->base, priv->wolopts); 186085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else 186185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 186285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 186485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 186585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_resume(struct device *dev) 186785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 186885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 186985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 187085c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 187185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(ndev)) 187385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 187485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(ioaddr, 0); 187685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable the MAC and DMA */ 187885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_enable(ioaddr); 187985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 188085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); 188185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_attach(ndev); 188385c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_enable(&priv->napi); 188485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 188685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 1887c132cf56f1527d4667b52bf64453155bcacbea8aFabio Estevam#endif /* CONFIG_PM_SLEEP */ 188885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic SIMPLE_DEV_PM_OPS(xgmac_pm_ops, xgmac_suspend, xgmac_resume); 189085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct of_device_id xgmac_of_match[] = { 189285c10f28286148ee5cdba1d22c81936ff160596eRob Herring { .compatible = "calxeda,hb-xgmac", }, 189385c10f28286148ee5cdba1d22c81936ff160596eRob Herring {}, 189485c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 189585c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DEVICE_TABLE(of, xgmac_of_match); 189685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic struct platform_driver xgmac_driver = { 189885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .driver = { 189985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .name = "calxedaxgmac", 190085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .of_match_table = xgmac_of_match, 190185c10f28286148ee5cdba1d22c81936ff160596eRob Herring }, 190285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .probe = xgmac_probe, 190385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .remove = xgmac_remove, 1904c132cf56f1527d4667b52bf64453155bcacbea8aFabio Estevam .driver.pm = &xgmac_pm_ops, 190585c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 190685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190785c10f28286148ee5cdba1d22c81936ff160596eRob Herringmodule_platform_driver(xgmac_driver); 190885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190985c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_AUTHOR("Calxeda, Inc."); 191085c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DESCRIPTION("Calxeda 10G XGMAC driver"); 191185c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_LICENSE("GPL v2"); 1912