xgmac.c revision 85c10f28286148ee5cdba1d22c81936ff160596e
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 */ 16685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_INT_STAT_PMT 0x0080 /* PMT Interrupt Status */ 16785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_INT_STAT_LPI 0x0040 /* LPI Interrupt Status */ 16885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 16985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Bus Mode register defines */ 17085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */ 17185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */ 17285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */ 17385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_ATDS 0x00000080 /* Alternate Descriptor Size */ 17485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 17585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Programmable burst length */ 17685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */ 17785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_PBL_SHIFT 8 17885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */ 17985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */ 18085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_RPBL_SHIFT 17 18185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_USP 0x00800000 18285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_8PBL 0x01000000 18385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_MODE_AAL 0x02000000 18485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 18585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Bus Mode register defines */ 18685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_PR_RATIO_MASK 0x0000c000 /* Rx/Tx priority ratio */ 18785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_PR_RATIO_SHIFT 14 18885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_BUS_FB 0x00010000 /* Fixed Burst */ 18985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 19085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Control register defines */ 19185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ 19285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ 19385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_CONTROL_DFF 0x01000000 /* Disable flush of rx frames */ 19485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 19585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Normal interrupt */ 19685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */ 19785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */ 19885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */ 19985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */ 20085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */ 20185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */ 20285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */ 20385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */ 20485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */ 20585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */ 20685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */ 20785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */ 20885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavail */ 20985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */ 21085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */ 21185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 21285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ 21385c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_TUE) 21485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 21585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \ 21685c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_RWE | DMA_INTR_ENA_RSE | \ 21785c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_RUE | DMA_INTR_ENA_UNE | \ 21885c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_OVE | DMA_INTR_ENA_TJE | \ 21985c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_INTR_ENA_TSE) 22085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 22185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA default interrupt mask */ 22285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL) 22385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 22485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA Status register defines */ 22585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */ 22685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */ 22785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */ 22885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */ 22985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */ 23085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */ 23185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TS_SHIFT 20 23285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */ 23385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RS_SHIFT 17 23485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */ 23585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */ 23685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */ 23785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */ 23885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */ 23985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */ 24085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */ 24185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */ 24285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */ 24385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */ 24485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */ 24585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */ 24685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavail */ 24785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */ 24885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ 24985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 25085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Common MAC defines */ 25185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */ 25285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAC_ENABLE_RX 0x00000004 /* Receiver Enable */ 25385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 25485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Operation Mode Register */ 25585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TSF 0x00200000 /* TX FIFO Store and Forward */ 25685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_FTF 0x00100000 /* Flush Transmit FIFO */ 25785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshhold Ctrl */ 25885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_TTC_MASK 0x00030000 25985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshhold */ 26085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshhold MASK */ 26185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshhold */ 26285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshhold MASK */ 26385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_EFC 0x00000100 /* Enable Hardware FC */ 26485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_FEF 0x00000080 /* Forward Error Frames */ 26585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_DT 0x00000040 /* Drop TCP/IP csum Errors */ 26685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RSF 0x00000020 /* RX FIFO Store and Forward */ 26785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RTC 0x00000010 /* RX Threshhold Ctrl */ 26885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshhold Ctrl MASK */ 26985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC HW Features Register */ 27185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_HW_FEAT_TXCOESEL 0x00010000 /* TX Checksum offload */ 27285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_MMC_CTRL_CNT_FRZ 0x00000008 27485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Descriptor Defines */ 27685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAX_DESC_BUF_SZ (0x2000 - 8) 27785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 27885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_EXT_STATUS 0x00000001 27985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_CRC_ERR 0x00000002 28085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_RX_ERR 0x00000008 28185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_RX_WDOG 0x00000010 28285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_TYPE 0x00000020 28385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_GIANT_FRAME 0x00000080 28485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_LAST_SEG 0x00000100 28585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FIRST_SEG 0x00000200 28685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_VLAN_FRAME 0x00000400 28785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_OVERFLOW_ERR 0x00000800 28885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_LENGTH_ERR 0x00001000 28985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_SA_FILTER_FAIL 0x00002000 29085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_DESCRIPTOR_ERR 0x00004000 29185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_ERROR_SUMMARY 0x00008000 29285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_LEN_OFFSET 16 29385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_FRAME_LEN_MASK 0x3fff0000 29485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_DA_FILTER_FAIL 0x40000000 29585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 29685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC1_END_RING 0x00008000 29785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 29885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_MASK 0x00000003 29985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_UDP 0x00000001 30085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_TCP 0x00000002 30185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_ICMP 0x00000003 30285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_HEADER_ERR 0x00000008 30385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IP_PAYLOAD_ERR 0x00000010 30485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IPV4_PACKET 0x00000040 30585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define RXDESC_IPV6_PACKET 0x00000080 30685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_UNDERFLOW_ERR 0x00000001 30785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_JABBER_TIMEOUT 0x00000002 30885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_LOCAL_FAULT 0x00000004 30985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_REMOTE_FAULT 0x00000008 31085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_VLAN_FRAME 0x00000010 31185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_FRAME_FLUSHED 0x00000020 31285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_IP_HEADER_ERR 0x00000040 31385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_PAYLOAD_CSUM_ERR 0x00000080 31485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_ERROR_SUMMARY 0x00008000 31585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_SA_CTRL_INSERT 0x00040000 31685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_SA_CTRL_REPLACE 0x00080000 31785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_2ND_ADDR_CHAINED 0x00100000 31885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_END_RING 0x00200000 31985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_IP 0x00400000 32085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_IP_PAYLD 0x00800000 32185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CSUM_ALL 0x00C00000 32285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CRC_EN_REPLACE 0x01000000 32385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_CRC_EN_APPEND 0x02000000 32485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_DISABLE_PAD 0x04000000 32585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_FIRST_SEG 0x10000000 32685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_LAST_SEG 0x20000000 32785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TXDESC_INTERRUPT 0x40000000 32885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 32985c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_OWN 0x80000000 33085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER1_SZ_MASK 0x00001fff 33185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER2_SZ_MASK 0x1fff0000 33285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DESC_BUFFER2_SZ_OFFSET 16 33385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 33485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_dma_desc { 33585c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 flags; 33685c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf_size; 33785c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf1_addr; /* Buffer 1 Address Pointer */ 33885c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 buf2_addr; /* Buffer 2 Address Pointer */ 33985c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 ext_status; 34085c10f28286148ee5cdba1d22c81936ff160596eRob Herring __le32 res[3]; 34185c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 34285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 34385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_extra_stats { 34485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Transmit errors */ 34585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_jabber; 34685c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_frame_flushed; 34785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_payload_error; 34885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_ip_header_error; 34985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_local_fault; 35085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_remote_fault; 35185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Receive errors */ 35285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_watchdog; 35385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_da_filter_fail; 35485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_sa_filter_fail; 35585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_payload_error; 35685c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_ip_header_error; 35785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Tx/Rx IRQ errors */ 35885c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_undeflow; 35985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_process_stopped; 36085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_buf_unav; 36185c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long rx_process_stopped; 36285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long tx_early; 36385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned long fatal_bus_error; 36485c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 36585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 36685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_priv { 36785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *dma_rx; 36885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff **rx_skbuff; 36985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int rx_tail; 37085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int rx_head; 37185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 37285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *dma_tx; 37385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff **tx_skbuff; 37485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int tx_head; 37585c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int tx_tail; 37685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 37785c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *base; 37885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff_head rx_recycle; 37985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int dma_buf_sz; 38085c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t dma_rx_phy; 38185c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t dma_tx_phy; 38285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 38385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev; 38485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct device *device; 38585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct napi_struct napi; 38685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 38785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats xstats; 38885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 38985c10f28286148ee5cdba1d22c81936ff160596eRob Herring spinlock_t stats_lock; 39085c10f28286148ee5cdba1d22c81936ff160596eRob Herring int pmt_irq; 39185c10f28286148ee5cdba1d22c81936ff160596eRob Herring char rx_pause; 39285c10f28286148ee5cdba1d22c81936ff160596eRob Herring char tx_pause; 39385c10f28286148ee5cdba1d22c81936ff160596eRob Herring int wolopts; 39485c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 39585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 39685c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Configuration Settings */ 39785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define MAX_MTU 9000 39885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define PAUSE_TIME 0x400 39985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_RX_RING_SZ 256 40185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define DMA_TX_RING_SZ 128 40285c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* minimum number of free TX descriptors required to wake up TX process */ 40385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define TX_THRESH (DMA_TX_RING_SZ/4) 40485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 40585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* DMA descriptor ring helpers */ 40685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_incr(n, s) (((n) + 1) & ((s) - 1)) 40785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_space(h, t, s) CIRC_SPACE(h, t, s) 40885c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define dma_ring_cnt(h, t, s) CIRC_CNT(h, t, s) 40985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 41085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* XGMAC Descriptor Access Helpers */ 41185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz) 41285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 41385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (buf_sz > MAX_DESC_BUF_SZ) 41485c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(MAX_DESC_BUF_SZ | 41585c10f28286148ee5cdba1d22c81936ff160596eRob Herring (buf_sz - MAX_DESC_BUF_SZ) << DESC_BUFFER2_SZ_OFFSET); 41685c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 41785c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf_size = cpu_to_le32(buf_sz); 41885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 41985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 42085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_buf_len(struct xgmac_dma_desc *p) 42185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 42285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 len = cpu_to_le32(p->flags); 42385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return (len & DESC_BUFFER1_SZ_MASK) + 42485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET); 42585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 42685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 42785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_rx_desc(struct xgmac_dma_desc *p, int ring_size, 42885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int buf_sz) 42985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 43085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *end = p + ring_size - 1; 43185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43285c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 43385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (; p <= end; p++) 43585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, buf_sz); 43685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 43785c10f28286148ee5cdba1d22c81936ff160596eRob Herring end->buf_size |= cpu_to_le32(RXDESC1_END_RING); 43885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 43985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_init_tx_desc(struct xgmac_dma_desc *p, u32 ring_size) 44185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 44285c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(p, 0, sizeof(*p) * ring_size); 44385c10f28286148ee5cdba1d22c81936ff160596eRob Herring p[ring_size - 1].flags = cpu_to_le32(TXDESC_END_RING); 44485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 44585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 44685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_owner(struct xgmac_dma_desc *p) 44785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 44885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & DESC_OWN; 44985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 45185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_rx_owner(struct xgmac_dma_desc *p) 45285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Clear all fields and set the owner */ 45485c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(DESC_OWN); 45585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 45685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 45785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_tx_owner(struct xgmac_dma_desc *p, u32 flags) 45885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 45985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 tmpflags = le32_to_cpu(p->flags); 46085c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags &= TXDESC_END_RING; 46185c10f28286148ee5cdba1d22c81936ff160596eRob Herring tmpflags |= flags | DESC_OWN; 46285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->flags = cpu_to_le32(tmpflags); 46385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 46485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 46585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_tx_ls(struct xgmac_dma_desc *p) 46685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 46785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->flags) & TXDESC_LAST_SEG; 46885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 46985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 47085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline u32 desc_get_buf_addr(struct xgmac_dma_desc *p) 47185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 47285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return le32_to_cpu(p->buf1_addr); 47385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 47485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 47585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr(struct xgmac_dma_desc *p, 47685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 47785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 47885c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf1_addr = cpu_to_le32(paddr); 47985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (len > MAX_DESC_BUF_SZ) 48085c10f28286148ee5cdba1d22c81936ff160596eRob Herring p->buf2_addr = cpu_to_le32(paddr + MAX_DESC_BUF_SZ); 48185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 48285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 48385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void desc_set_buf_addr_and_size(struct xgmac_dma_desc *p, 48485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 paddr, int len) 48585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 48685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_len(p, len); 48785c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr(p, paddr, len); 48885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 48985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline int desc_get_rx_frame_len(struct xgmac_dma_desc *p) 49185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 49285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data = le32_to_cpu(p->flags); 49385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 len = (data & RXDESC_FRAME_LEN_MASK) >> RXDESC_FRAME_LEN_OFFSET; 49485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (data & RXDESC_FRAME_TYPE) 49585c10f28286148ee5cdba1d22c81936ff160596eRob Herring len -= ETH_FCS_LEN; 49685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 49785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return len; 49885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 49985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 50085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_dma_flush_tx_fifo(void __iomem *ioaddr) 50185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 50285c10f28286148ee5cdba1d22c81936ff160596eRob Herring int timeout = 1000; 50385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg = readl(ioaddr + XGMAC_OMR); 50485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | XGMAC_OMR_FTF, ioaddr + XGMAC_OMR); 50585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 50685c10f28286148ee5cdba1d22c81936ff160596eRob Herring while ((timeout-- > 0) && readl(ioaddr + XGMAC_OMR) & XGMAC_OMR_FTF) 50785c10f28286148ee5cdba1d22c81936ff160596eRob Herring udelay(1); 50885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 50985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_tx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 51185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 51285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 51385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 51485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & TXDESC_ERROR_SUMMARY)) 51685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 51785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 51885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx desc error = 0x%08x\n", status); 51985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_JABBER_TIMEOUT) 52085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 52185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_FRAME_FLUSHED) 52285c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_frame_flushed++; 52385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_UNDERFLOW_ERR) 52485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_dma_flush_tx_fifo(priv->base); 52585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_IP_HEADER_ERR) 52685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_ip_header_error++; 52785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_LOCAL_FAULT) 52885c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_local_fault++; 52985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_REMOTE_FAULT) 53085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_remote_fault++; 53185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & TXDESC_PAYLOAD_CSUM_ERR) 53285c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_payload_error++; 53385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 53585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 53685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 53785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) 53885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 53985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 54085c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = CHECKSUM_UNNECESSARY; 54185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 status = le32_to_cpu(p->flags); 54285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ext_status = le32_to_cpu(p->ext_status); 54385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 54485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_DA_FILTER_FAIL) { 54585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "XGMAC RX : Dest Address filter fail\n"); 54685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_da_filter_fail++; 54785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 54885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 54985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 55085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if packet has checksum already */ 55185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && 55285c10f28286148ee5cdba1d22c81936ff160596eRob Herring !(ext_status & RXDESC_IP_PAYLOAD_MASK)) 55385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = CHECKSUM_NONE; 55485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 55585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx status - frame type=%d, csum = %d, ext stat %08x\n", 55685c10f28286148ee5cdba1d22c81936ff160596eRob Herring (status & RXDESC_FRAME_TYPE) ? 1 : 0, ret, ext_status); 55785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 55885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(status & RXDESC_ERROR_SUMMARY)) 55985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 56085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 56185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Handle any errors */ 56285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & (RXDESC_DESCRIPTOR_ERR | RXDESC_OVERFLOW_ERR | 56385c10f28286148ee5cdba1d22c81936ff160596eRob Herring RXDESC_GIANT_FRAME | RXDESC_LENGTH_ERR | RXDESC_CRC_ERR)) 56485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -1; 56585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 56685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (status & RXDESC_EXT_STATUS) { 56785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_HEADER_ERR) 56885c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_ip_header_error++; 56985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ext_status & RXDESC_IP_PAYLOAD_ERR) 57085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_payload_error++; 57185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "IP checksum error - stat %08x\n", 57285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ext_status); 57385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return CHECKSUM_NONE; 57485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 57585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 57685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 57785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 57885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 57985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_enable(void __iomem *ioaddr) 58085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 58185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_CONTROL); 58285c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= MAC_ENABLE_RX | MAC_ENABLE_TX; 58385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 58485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 58585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_DMA_CONTROL); 58685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= DMA_CONTROL_ST | DMA_CONTROL_SR; 58785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 58885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 58985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic inline void xgmac_mac_disable(void __iomem *ioaddr) 59185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 59285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value = readl(ioaddr + XGMAC_DMA_CONTROL); 59385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 59485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 59585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 59685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(ioaddr + XGMAC_CONTROL); 59785c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); 59885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_CONTROL); 59985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 60085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_mac_addr(void __iomem *ioaddr, unsigned char *addr, 60285c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 60385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 60485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 data; 60585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 60685c10f28286148ee5cdba1d22c81936ff160596eRob Herring data = (addr[5] << 8) | addr[4] | (num ? XGMAC_ADDR_AE : 0); 60785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(data, ioaddr + XGMAC_ADDR_HIGH(num)); 60885c10f28286148ee5cdba1d22c81936ff160596eRob Herring data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 60985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(data, ioaddr + XGMAC_ADDR_LOW(num)); 61085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 61185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 61285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, 61385c10f28286148ee5cdba1d22c81936ff160596eRob Herring int num) 61485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 61585c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hi_addr, lo_addr; 61685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 61785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Read the MAC address from the hardware */ 61885c10f28286148ee5cdba1d22c81936ff160596eRob Herring hi_addr = readl(ioaddr + XGMAC_ADDR_HIGH(num)); 61985c10f28286148ee5cdba1d22c81936ff160596eRob Herring lo_addr = readl(ioaddr + XGMAC_ADDR_LOW(num)); 62085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 62185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Extract the MAC address from the high and low words */ 62285c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[0] = lo_addr & 0xff; 62385c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[1] = (lo_addr >> 8) & 0xff; 62485c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[2] = (lo_addr >> 16) & 0xff; 62585c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[3] = (lo_addr >> 24) & 0xff; 62685c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[4] = hi_addr & 0xff; 62785c10f28286148ee5cdba1d22c81936ff160596eRob Herring addr[5] = (hi_addr >> 8) & 0xff; 62885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 62985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 63085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_flow_ctrl(struct xgmac_priv *priv, int rx, int tx) 63185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 63285c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg; 63385c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int flow = 0; 63485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 63585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = rx; 63685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = tx; 63785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 63885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx || tx) { 63985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (rx) 64085c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_RFE; 64185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (tx) 64285c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_TFE; 64385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64485c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= XGMAC_FLOW_CTRL_PLT | XGMAC_FLOW_CTRL_UP; 64585c10f28286148ee5cdba1d22c81936ff160596eRob Herring flow |= (PAUSE_TIME << XGMAC_FLOW_CTRL_PT_SHIFT); 64685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(flow, priv->base + XGMAC_FLOW_CTRL); 64885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64985c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_OMR); 65085c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg |= XGMAC_OMR_EFC; 65185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg, priv->base + XGMAC_OMR); 65285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 65385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, 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 } 65985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 66185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 66285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_rx_refill(struct xgmac_priv *priv) 66485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 66585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 66685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 66785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 66885c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_space(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ) > 1) { 66985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int entry = priv->rx_head; 67085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 67185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 67385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->rx_skbuff[entry] != NULL) 67585c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 67685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 67785c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb = __skb_dequeue(&priv->rx_recycle); 67885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (skb == NULL) 67985c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz); 68085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(skb == NULL)) 68185c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 68285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 68385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[entry] = skb; 68485c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = dma_map_single(priv->device, skb->data, 68585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz, DMA_FROM_DEVICE); 68685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr(p, paddr, priv->dma_buf_sz); 68785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 68885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "rx ring: head %d, tail %d\n", 68985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head, priv->rx_tail); 69085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = dma_ring_incr(priv->rx_head, DMA_RX_RING_SZ); 69285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Ensure descriptor is in memory before handing to h/w */ 69385c10f28286148ee5cdba1d22c81936ff160596eRob Herring wmb(); 69485c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_rx_owner(p); 69585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 69685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 69785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 69885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 69985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * init_xgmac_dma_desc_rings - init the RX/TX descriptor rings 70085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev: net device structure 70185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function initializes the DMA RX/TX descriptors 70285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * and allocates the socket buffers. 70385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 70485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_dma_desc_rings_init(struct net_device *dev) 70585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 70685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 70785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int bfsize; 70885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 70985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set the Buffer size according to the MTU; 71085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * indeed, in case of jumbo we need to bump-up the buffer sizes. 71185c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 71285c10f28286148ee5cdba1d22c81936ff160596eRob Herring bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN + 64, 71385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 64); 71485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); 71685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 71785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_RX_RING_SZ, 71885c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 71985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 72085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 72185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 72285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = dma_alloc_coherent(priv->device, 72385c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * 72485c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 72585c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_rx_phy, 72685c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 72785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_rx) 72885c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_rx; 72985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 73085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_TX_RING_SZ, 73185c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 73285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 73385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_tx_skb; 73485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 73585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = dma_alloc_coherent(priv->device, 73685c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * 73785c10f28286148ee5cdba1d22c81936ff160596eRob Herring sizeof(struct xgmac_dma_desc), 73885c10f28286148ee5cdba1d22c81936ff160596eRob Herring &priv->dma_tx_phy, 73985c10f28286148ee5cdba1d22c81936ff160596eRob Herring GFP_KERNEL); 74085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->dma_tx) 74185c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_dma_tx; 74285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "DMA desc rings: virt addr (Rx %p, " 74485c10f28286148ee5cdba1d22c81936ff160596eRob Herring "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 74585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_tx, 74685c10f28286148ee5cdba1d22c81936ff160596eRob Herring (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 74785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 74885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = 0; 74985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_head = 0; 75085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz = bfsize; 75185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_rx_desc(priv->dma_rx, DMA_RX_RING_SZ, priv->dma_buf_sz); 75285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 75385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 75485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 75585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 75685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 75785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 75885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR); 75985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(priv->dma_rx_phy, priv->base + XGMAC_DMA_RX_BASE_ADDR); 76085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 76285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 76385c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_tx: 76485c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 76585c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_tx_skb: 76685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 76785c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 76885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 76985c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_dma_rx: 77085c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 77185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOMEM; 77285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 77385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 77485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_rx_skbufs(struct xgmac_priv *priv) 77585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 77685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 77785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 77885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 77985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->rx_skbuff) 78085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 78185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78285c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_RX_RING_SZ; i++) { 78385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->rx_skbuff[i] == NULL) 78485c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 78585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 78685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + i; 78785c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 78885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_buf_sz, DMA_FROM_DEVICE); 78985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb_any(priv->rx_skbuff[i]); 79085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[i] = NULL; 79185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 79285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 79385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 79485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_tx_skbufs(struct xgmac_priv *priv) 79585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 79685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i, f; 79785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 79885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 79985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->tx_skbuff) 80085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 80185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80285c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < DMA_TX_RING_SZ; i++) { 80385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->tx_skbuff[i] == NULL) 80485c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 80585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 80685c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + i; 80785c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 80885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 80985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 81085c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (f = 0; f < skb_shinfo(priv->tx_skbuff[i])->nr_frags; f++) { 81185c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + i++; 81285c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 81385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 81485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 81585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 81685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb_any(priv->tx_skbuff[i]); 81785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[i] = NULL; 81885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 81985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 82085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_free_dma_desc_rings(struct xgmac_priv *priv) 82285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 82385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release the DMA TX/RX socket buffers */ 82485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_rx_skbufs(priv); 82585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 82685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 82785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the consistent memory allocated for descriptor rings */ 82885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_tx) { 82985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 83085c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ * sizeof(struct xgmac_dma_desc), 83185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx, priv->dma_tx_phy); 83285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_tx = NULL; 83385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 83485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->dma_rx) { 83585c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_free_coherent(priv->device, 83685c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ * sizeof(struct xgmac_dma_desc), 83785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx, priv->dma_rx_phy); 83885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dma_rx = NULL; 83985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 84085c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->rx_skbuff); 84185c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff = NULL; 84285c10f28286148ee5cdba1d22c81936ff160596eRob Herring kfree(priv->tx_skbuff); 84385c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff = NULL; 84485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 84585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 84685c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 84785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx: 84885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @priv: private driver structure 84985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: it reclaims resources after transmission completes. 85085c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 85185c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_complete(struct xgmac_priv *priv) 85285c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 85385c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 85485c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 85585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 85685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_STATUS_TU | DMA_STATUS_NIS, ioaddr + XGMAC_DMA_STATUS); 85785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 85885c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) { 85985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry = priv->tx_tail; 86085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb = priv->tx_skbuff[entry]; 86185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p = priv->dma_tx + entry; 86285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 86385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check if the descriptor is owned by the DMA. */ 86485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 86585c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 86685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 86785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Verify tx error by looking at the last segment */ 86885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_tx_ls(p)) 86985c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_tx_status(priv, p); 87085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "tx ring: curr %d, dirty %d\n", 87285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head, priv->tx_tail); 87385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87485c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 87585c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 87685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 87785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = NULL; 87885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ); 87985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!skb) { 88185c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 88285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 88385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88485c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 88585c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->tx_tail = dma_ring_incr(priv->tx_tail, 88685c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TX_RING_SZ); 88785c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_tx + priv->tx_tail; 88885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 88985c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_page(priv->device, desc_get_buf_addr(p), 89085c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_get_buf_len(p), DMA_TO_DEVICE); 89185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 89285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 89385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* 89485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * If there's room in the queue (limit it to size) 89585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * we add this skb back into the pool, 89685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * if it's the right size. 89785c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 89885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((skb_queue_len(&priv->rx_recycle) < 89985c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_RX_RING_SZ) && 90085c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_recycle_check(skb, priv->dma_buf_sz)) 90185c10f28286148ee5cdba1d22c81936ff160596eRob Herring __skb_queue_head(&priv->rx_recycle, skb); 90285c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 90385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb(skb); 90485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 90585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 90685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) > 90785c10f28286148ee5cdba1d22c81936ff160596eRob Herring TX_THRESH) 90885c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 90985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 91085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 91185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 91285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx_err: 91385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @priv: pointer to the private device structure 91485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: it cleans the descriptors and restarts the transmission 91585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * in case of errors. 91685c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 91785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_err(struct xgmac_priv *priv) 91885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 91985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 reg, value, inten; 92085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_stop_queue(priv->dev); 92285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92385c10f28286148ee5cdba1d22c81936ff160596eRob Herring inten = readl(priv->base + XGMAC_DMA_INTR_ENA); 92485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 92585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 92685c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg = readl(priv->base + XGMAC_DMA_CONTROL); 92785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg & ~DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 92885c10f28286148ee5cdba1d22c81936ff160596eRob Herring do { 92985c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_STATUS) & 0x700000; 93085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } while (value && (value != 0x600000)); 93185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_tx_skbufs(priv); 93385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ); 93485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_tail = 0; 93585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = 0; 93685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(reg | DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL); 93785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 93885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS, 93985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base + XGMAC_DMA_STATUS); 94085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(inten, priv->base + XGMAC_DMA_INTR_ENA); 94185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 94285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_wake_queue(priv->dev); 94385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 94485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 94585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_hw_init(struct net_device *dev) 94685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 94785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value, ctrl; 94885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int limit; 94985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 95085c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 95185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 95285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Save the ctrl register value */ 95385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL) & XGMAC_CONTROL_SPD_MASK; 95485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 95585c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* SW reset */ 95685c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = DMA_BUS_MODE_SFT_RESET; 95785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 95885c10f28286148ee5cdba1d22c81936ff160596eRob Herring limit = 15000; 95985c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (limit-- && 96085c10f28286148ee5cdba1d22c81936ff160596eRob Herring (readl(ioaddr + XGMAC_DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) 96185c10f28286148ee5cdba1d22c81936ff160596eRob Herring cpu_relax(); 96285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (limit < 0) 96385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 96485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 96585c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = (0x10 << DMA_BUS_MODE_PBL_SHIFT) | 96685c10f28286148ee5cdba1d22c81936ff160596eRob Herring (0x10 << DMA_BUS_MODE_RPBL_SHIFT) | 96785c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_BUS_MODE_FB | DMA_BUS_MODE_ATDS | DMA_BUS_MODE_AAL; 96885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_BUS_MODE); 96985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 97085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable interrupts */ 97185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 97285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); 97385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 97485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* XGMAC requires AXI bus init. This is a 'magic number' for now */ 97585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0x000100E, ioaddr + XGMAC_DMA_AXI_BUS); 97685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 97785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_DDIC | XGMAC_CONTROL_JE | XGMAC_CONTROL_ACS | 97885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_CONTROL_CAR; 97985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->features & NETIF_F_RXCSUM) 98085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_IPC; 98185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(ctrl, ioaddr + XGMAC_CONTROL); 98285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 98385c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = DMA_CONTROL_DFF; 98485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_DMA_CONTROL); 98585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 98685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set the HW DMA mode and the COE */ 98785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_OMR_TSF | XGMAC_OMR_RSF | XGMAC_OMR_RFD | XGMAC_OMR_RFA, 98885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ioaddr + XGMAC_OMR); 98985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 99085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Reset the MMC counters */ 99185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(1, ioaddr + XGMAC_MMC_CTRL); 99285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 99385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 99485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 99585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 99685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_open - open entry point of the driver 99785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : pointer to the device structure. 99885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 99985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function is the open entry point of the driver. 100085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 100185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 0 on success and an appropriate (-)ve integer as defined in errno.h 100285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * file on failure. 100385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 100485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_open(struct net_device *dev) 100585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 100685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret; 100785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 100885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 100985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 101085c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Check that the MAC address is valid. If its not, refuse 101185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to bring the device up. The user must specify an 101285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * address using the following linux command: 101385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ 101485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(dev->dev_addr)) { 101585c10f28286148ee5cdba1d22c81936ff160596eRob Herring random_ether_addr(dev->dev_addr); 101685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "generated random MAC address %pM\n", 101785c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev->dev_addr); 101885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 101985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 102085c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_queue_head_init(&priv->rx_recycle); 102185c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(&priv->xstats, 0, sizeof(struct xgmac_extra_stats)); 102285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 102385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Initialize the XGMAC and descriptors */ 102485c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_hw_init(dev); 102585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0); 102685c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_flow_ctrl(priv, priv->rx_pause, priv->tx_pause); 102785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 102885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = xgmac_dma_desc_rings_init(dev); 102985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) 103085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 103185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable the MAC Rx/Tx */ 103385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_enable(ioaddr); 103485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103585c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_enable(&priv->napi); 103685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_start_queue(dev); 103785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 103885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 103985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 104085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 104185c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 104285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_release - close entry point of the driver 104385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 104485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 104585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This is the stop entry point of the driver. 104685c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 104785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_stop(struct net_device *dev) 104885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 104985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 105085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_stop_queue(dev); 105285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_INTR_ENA)) 105485c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 105585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105685c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 105785c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_queue_purge(&priv->rx_recycle); 105885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 105985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Disable the MAC core */ 106085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 106185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 106285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Release and free the Rx/Tx resources */ 106385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_free_dma_desc_rings(priv); 106485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 106585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 106685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 106785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 106885c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 106985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_xmit: 107085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @skb : the socket buffer 107185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer 107285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : Tx entry point of the driver. 107385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 107485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) 107585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 107685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 107785c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 107885c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 107985c10f28286148ee5cdba1d22c81936ff160596eRob Herring int nfrags = skb_shinfo(skb)->nr_frags; 108085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *desc, *first; 108185c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int desc_flags; 108285c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int len; 108385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_addr_t paddr; 108485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 108585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < 108685c10f28286148ee5cdba1d22c81936ff160596eRob Herring (nfrags + 1)) { 108785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK | DMA_INTR_ENA_TIE, 108885c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base + XGMAC_DMA_INTR_ENA); 108985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_stop_queue(dev); 109085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return NETDEV_TX_BUSY; 109185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 109285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109385c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? 109485c10f28286148ee5cdba1d22c81936ff160596eRob Herring TXDESC_CSUM_ALL : 0; 109585c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->tx_head; 109685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 109785c10f28286148ee5cdba1d22c81936ff160596eRob Herring first = desc; 109885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 109985c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = skb_headlen(skb); 110085c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = dma_map_single(priv->device, skb->data, len, DMA_TO_DEVICE); 110185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_mapping_error(priv->device, paddr)) { 110285c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb(skb); 110385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EIO; 110485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 110585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = skb; 110685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 110785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 110885c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < nfrags; i++) { 110985c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 111085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111185c10f28286148ee5cdba1d22c81936ff160596eRob Herring len = frag->size; 111285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 111385c10f28286148ee5cdba1d22c81936ff160596eRob Herring paddr = skb_frag_dma_map(priv->device, frag, 0, len, 111485c10f28286148ee5cdba1d22c81936ff160596eRob Herring DMA_TO_DEVICE); 111585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dma_mapping_error(priv->device, paddr)) { 111685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_kfree_skb(skb); 111785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EIO; 111885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 111985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112085c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = dma_ring_incr(entry, DMA_TX_RING_SZ); 112185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc = priv->dma_tx + entry; 112285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_skbuff[entry] = NULL; 112385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112485c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_buf_addr_and_size(desc, paddr, len); 112585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (i < (nfrags - 1)) 112685c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags); 112785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 112885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 112985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Interrupt on completition only for the latest segment */ 113085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc != first) 113185c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(desc, desc_flags | 113285c10f28286148ee5cdba1d22c81936ff160596eRob Herring TXDESC_LAST_SEG | TXDESC_INTERRUPT); 113385c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 113485c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_flags |= TXDESC_LAST_SEG | TXDESC_INTERRUPT; 113585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 113685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Set owner on first desc last to avoid race condition */ 113785c10f28286148ee5cdba1d22c81936ff160596eRob Herring wmb(); 113885c10f28286148ee5cdba1d22c81936ff160596eRob Herring desc_set_tx_owner(first, desc_flags | TXDESC_FIRST_SEG); 113985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114085c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); 114185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(1, priv->base + XGMAC_DMA_TX_POLL); 114385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return NETDEV_TX_OK; 114585c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 114685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 114785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_rx(struct xgmac_priv *priv, int limit) 114885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 114985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int entry; 115085c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int count = 0; 115185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_dma_desc *p; 115285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 115385c10f28286148ee5cdba1d22c81936ff160596eRob Herring while (count < limit) { 115485c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ip_checksum; 115585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sk_buff *skb; 115685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int frame_len; 115785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 115885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_STATUS_RI | DMA_STATUS_NIS, 115985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base + XGMAC_DMA_STATUS); 116085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 116185c10f28286148ee5cdba1d22c81936ff160596eRob Herring entry = priv->rx_tail; 116285c10f28286148ee5cdba1d22c81936ff160596eRob Herring p = priv->dma_rx + entry; 116385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (desc_get_owner(p)) 116485c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 116585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 116685c10f28286148ee5cdba1d22c81936ff160596eRob Herring count++; 116785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_tail = dma_ring_incr(priv->rx_tail, DMA_RX_RING_SZ); 116885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 116985c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status of the incoming frame */ 117085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ip_checksum = desc_get_rx_status(priv, p); 117185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum < 0) 117285c10f28286148ee5cdba1d22c81936ff160596eRob Herring continue; 117385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 117485c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb = priv->rx_skbuff[entry]; 117585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(!skb)) { 117685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "Inconsistent Rx descriptor chain\n"); 117785c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 117885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 117985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_skbuff[entry] = NULL; 118085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118185c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len = desc_get_rx_frame_len(p); 118285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "RX frame size %d, COE status: %d\n", 118385c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len, ip_checksum); 118485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118585c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb_put(skb, frame_len); 118685c10f28286148ee5cdba1d22c81936ff160596eRob Herring dma_unmap_single(priv->device, desc_get_buf_addr(p), 118785c10f28286148ee5cdba1d22c81936ff160596eRob Herring frame_len, DMA_FROM_DEVICE); 118885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 118985c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->protocol = eth_type_trans(skb, priv->dev); 119085c10f28286148ee5cdba1d22c81936ff160596eRob Herring skb->ip_summed = ip_checksum; 119185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ip_checksum == CHECKSUM_NONE) 119285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_receive_skb(skb); 119385c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 119485c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_gro_receive(&priv->napi, skb); 119585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 119685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 119785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_rx_refill(priv); 119885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 119985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(1, priv->base + XGMAC_DMA_RX_POLL); 120085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 120185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return count; 120285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 120385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 120485c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 120585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_poll - xgmac poll method (NAPI) 120685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @napi : pointer to the napi structure. 120785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @budget : maximum number of packets that the current CPU can receive from 120885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * all interfaces. 120985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description : 121085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function implements the the reception process. 121185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Also it runs the TX completion thread 121285c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 121385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_poll(struct napi_struct *napi, int budget) 121485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 121585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = container_of(napi, 121685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv, napi); 121785c10f28286148ee5cdba1d22c81936ff160596eRob Herring int work_done = 0; 121885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 121985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_complete(priv); 122085c10f28286148ee5cdba1d22c81936ff160596eRob Herring work_done = xgmac_rx(priv, budget); 122185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 122285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (work_done < budget) { 122385c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_complete(napi); 122485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); 122585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 122685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return work_done; 122785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 122885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 122985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 123085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_tx_timeout 123185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : Pointer to net device structure 123285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function is called when a packet transmission fails to 123385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * complete within a reasonable tmrate. The driver will mark the error in the 123485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * netdev structure and arrange for the device to be reset to a sane state 123585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * in order to transmit a new packet. 123685c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 123785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_tx_timeout(struct net_device *dev) 123885c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 123985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 124085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 124185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Clear Tx resources and restart transmitting again */ 124285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_err(priv); 124385c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 124485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 124585c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 124685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_set_rx_mode - entry point for multicast addressing 124785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : pointer to the device structure 124885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: 124985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * This function is a driver entry point which gets called by the kernel 125085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * whenever multicast addresses must be enabled/disabled. 125185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 125285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * void. 125385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 125485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_set_rx_mode(struct net_device *dev) 125585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 125685c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 125785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 125885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 125985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int value = 0; 126085c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 hash_filter[XGMAC_NUM_HASH]; 126185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int reg = 1; 126285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct netdev_hw_addr *ha; 126385c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool use_hash = false; 126485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 126585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "# mcasts %d, # unicast %d\n", 126685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_mc_count(dev), netdev_uc_count(dev)); 126785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 126885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->flags & IFF_PROMISC) { 126985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_FRAME_FILTER_PR, ioaddr + XGMAC_FRAME_FILTER); 127085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return; 127185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 127285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 127385c10f28286148ee5cdba1d22c81936ff160596eRob Herring memset(hash_filter, 0, sizeof(hash_filter)); 127485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 127585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (netdev_uc_count(dev) > XGMAC_MAX_FILTER_ADDR) { 127685c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 127785c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF; 127885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 127985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_uc_addr(ha, dev) { 128085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 128185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 128285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 128385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 128485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 128585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 128685c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 128785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 128885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 128985c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 129085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 129185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 129285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 129385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (dev->flags & IFF_ALLMULTI) { 129485c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_PM; 129585c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto out; 129685c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 129785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 129885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((netdev_mc_count(dev) + reg - 1) > XGMAC_MAX_FILTER_ADDR) { 129985c10f28286148ee5cdba1d22c81936ff160596eRob Herring use_hash = true; 130085c10f28286148ee5cdba1d22c81936ff160596eRob Herring value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF; 130185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 130285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_for_each_mc_addr(ha, dev) { 130385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (use_hash) { 130485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 bit_nr = ~ether_crc(ETH_ALEN, ha->addr) >> 23; 130585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 130685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* The most significant 4 bits determine the register to 130785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * use (H/L) while the other 5 bits determine the bit 130885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * within the register. */ 130985c10f28286148ee5cdba1d22c81936ff160596eRob Herring hash_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 131085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 131185c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, ha->addr, reg); 131285c10f28286148ee5cdba1d22c81936ff160596eRob Herring reg++; 131385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 131485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 131585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 131685c10f28286148ee5cdba1d22c81936ff160596eRob Herringout: 131785c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_NUM_HASH; i++) 131885c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(hash_filter[i], ioaddr + XGMAC_HASH(i)); 131985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 132085c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, ioaddr + XGMAC_FRAME_FILTER); 132185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 132285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 132385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 132485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_change_mtu - entry point to change MTU size for the device. 132585c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @dev : device pointer. 132685c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @new_mtu : the new MTU size for the device. 132785c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the Maximum Transfer Unit (MTU) is used by the network layer 132885c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to drive packet transmission. Ethernet has an MTU of 1500 octets 132985c10f28286148ee5cdba1d22c81936ff160596eRob Herring * (ETH_DATA_LEN). This value can be changed with ifconfig. 133085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Return value: 133185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * 0 on success and an appropriate (-)ve integer as defined in errno.h 133285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * file on failure. 133385c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 133485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_change_mtu(struct net_device *dev, int new_mtu) 133585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 133685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 133785c10f28286148ee5cdba1d22c81936ff160596eRob Herring int old_mtu; 133885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 133985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if ((new_mtu < 46) || (new_mtu > MAX_MTU)) { 134085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "invalid MTU, max MTU is: %d\n", MAX_MTU); 134185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 134285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 134385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134485c10f28286148ee5cdba1d22c81936ff160596eRob Herring old_mtu = dev->mtu; 134585c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev->mtu = new_mtu; 134685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 134785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* return early if the buffer sizes will not change */ 134885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN) 134985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 135085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (old_mtu == new_mtu) 135185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 135285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 135385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop everything, get ready to change the MTU */ 135485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(dev)) 135585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 135685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 135785c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Bring the interface down and then back up */ 135885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_stop(dev); 135985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_open(dev); 136085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 136185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 136285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id) 136385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 136485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 136585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 136685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 136785c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 136885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 136985c10f28286148ee5cdba1d22c81936ff160596eRob Herring intr_status = readl(ioaddr + XGMAC_INT_STAT); 137085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & XGMAC_INT_STAT_PMT) { 137185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_dbg(priv->dev, "received Magic frame\n"); 137285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* clear the PMT bits 5 and 6 by reading the PMT */ 137385c10f28286148ee5cdba1d22c81936ff160596eRob Herring readl(ioaddr + XGMAC_PMT); 137485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 137585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 137685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 137785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 137885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic irqreturn_t xgmac_interrupt(int irq, void *dev_id) 137985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 138085c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 intr_status; 138185c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool tx_err = false; 138285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *dev = (struct net_device *)dev_id; 138385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 138485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_extra_stats *x = &priv->xstats; 138585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 138685c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* read the status register (CSR5) */ 138785c10f28286148ee5cdba1d22c81936ff160596eRob Herring intr_status = readl(priv->base + XGMAC_DMA_STATUS); 138885c10f28286148ee5cdba1d22c81936ff160596eRob Herring intr_status &= readl(priv->base + XGMAC_DMA_INTR_ENA); 138985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(intr_status, priv->base + XGMAC_DMA_STATUS); 139085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 139185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* It displays the DMA process states (CSR5 register) */ 139285c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* ABNORMAL interrupts */ 139385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (unlikely(intr_status & DMA_STATUS_AIS)) { 139485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TJT) { 139585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit jabber\n"); 139685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_jabber++; 139785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 139885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RU) 139985c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_buf_unav++; 140085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_RPS) { 140185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "receive process stopped\n"); 140285c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->rx_process_stopped++; 140385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 140485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_ETI) { 140585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit early interrupt\n"); 140685c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_early++; 140785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 140885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_TPS) { 140985c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "transmit process stopped\n"); 141085c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->tx_process_stopped++; 141185c10f28286148ee5cdba1d22c81936ff160596eRob Herring tx_err = true; 141285c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 141385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & DMA_STATUS_FBI) { 141485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(priv->dev, "fatal bus error\n"); 141585c10f28286148ee5cdba1d22c81936ff160596eRob Herring x->fatal_bus_error++; 141685c10f28286148ee5cdba1d22c81936ff160596eRob Herring tx_err = true; 141785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 141885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 141985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (tx_err) 142085c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_tx_err(priv); 142185c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 142285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 142385c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* TX/RX NORMAL interrupts */ 142485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU)) { 142585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); 142685c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_schedule(&priv->napi); 142785c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 142885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 142985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return IRQ_HANDLED; 143085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 143185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 143285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 143385c10f28286148ee5cdba1d22c81936ff160596eRob Herring/* Polling receive - used by NETCONSOLE and other diagnostic tools 143485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * to allow network I/O with interrupts disabled. */ 143585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_poll_controller(struct net_device *dev) 143685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 143785c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq(dev->irq); 143885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_interrupt(dev->irq, dev); 143985c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq(dev->irq); 144085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 144185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 144285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 144385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct rtnl_link_stats64 * 144485c10f28286148ee5cdba1d22c81936ff160596eRob Herringxgmac_get_stats64(struct net_device *dev, 144585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct rtnl_link_stats64 *storage) 144685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 144785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 144885c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *base = priv->base; 144985c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 count; 145085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145185c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_bh(&priv->stats_lock); 145285c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(XGMAC_MMC_CTRL_CNT_FRZ, base + XGMAC_MMC_CTRL); 145385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145485c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes = readl(base + XGMAC_MMC_RXOCTET_G_LO); 145585c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_bytes |= (u64)(readl(base + XGMAC_MMC_RXOCTET_G_HI)) << 32; 145685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 145785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_packets = readl(base + XGMAC_MMC_RXFRAME_GB_LO); 145885c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->multicast = readl(base + XGMAC_MMC_RXMCFRAME_G); 145985c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_crc_errors = readl(base + XGMAC_MMC_RXCRCERR); 146085c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_length_errors = readl(base + XGMAC_MMC_RXLENGTHERR); 146185c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->rx_missed_errors = readl(base + XGMAC_MMC_RXOVERFLOW); 146285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 146385c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes = readl(base + XGMAC_MMC_TXOCTET_G_LO); 146485c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_bytes |= (u64)(readl(base + XGMAC_MMC_TXOCTET_G_HI)) << 32; 146585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 146685c10f28286148ee5cdba1d22c81936ff160596eRob Herring count = readl(base + XGMAC_MMC_TXFRAME_GB_LO); 146785c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_errors = count - readl(base + XGMAC_MMC_TXFRAME_G_LO); 146885c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_packets = count; 146985c10f28286148ee5cdba1d22c81936ff160596eRob Herring storage->tx_fifo_errors = readl(base + XGMAC_MMC_TXUNDERFLOW); 147085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, base + XGMAC_MMC_CTRL); 147285c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_unlock_bh(&priv->stats_lock); 147385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return storage; 147485c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 147585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 147685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_mac_address(struct net_device *dev, void *p) 147785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 147885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 147985c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 148085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct sockaddr *addr = p; 148185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(addr->sa_data)) 148385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EADDRNOTAVAIL; 148485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148585c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 148685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148785c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0); 148885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 148985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 149085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 149185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_features(struct net_device *dev, netdev_features_t features) 149385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 149485c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 ctrl; 149585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 149685c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 149785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 changed = dev->features ^ features; 149885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 149985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!(changed & NETIF_F_RXCSUM)) 150085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 150185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl = readl(ioaddr + XGMAC_CONTROL); 150385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (features & NETIF_F_RXCSUM) 150485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl |= XGMAC_CONTROL_IPC; 150585c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 150685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ctrl &= ~XGMAC_CONTROL_IPC; 150785c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(ctrl, ioaddr + XGMAC_CONTROL); 150885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 150985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 151085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 151185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 151285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct net_device_ops xgmac_netdev_ops = { 151385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_open = xgmac_open, 151485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_start_xmit = xgmac_xmit, 151585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_stop = xgmac_stop, 151685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_change_mtu = xgmac_change_mtu, 151785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_rx_mode = xgmac_set_rx_mode, 151885c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_tx_timeout = xgmac_tx_timeout, 151985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_get_stats64 = xgmac_get_stats64, 152085c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_NET_POLL_CONTROLLER 152185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_poll_controller = xgmac_poll_controller, 152285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif 152385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_mac_address = xgmac_set_mac_address, 152485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .ndo_set_features = xgmac_set_features, 152585c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 152685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 152785c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_ethtool_getsettings(struct net_device *dev, 152885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_cmd *cmd) 152985c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 153085c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->autoneg = 0; 153185c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->duplex = DUPLEX_FULL; 153285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ethtool_cmd_speed_set(cmd, 10000); 153385c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->supported = 0; 153485c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->advertising = 0; 153585c10f28286148ee5cdba1d22c81936ff160596eRob Herring cmd->transceiver = XCVR_INTERNAL; 153685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 153785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 153885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 153985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_pauseparam(struct net_device *netdev, 154085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 154185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 154285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 154385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154485c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->rx_pause = priv->rx_pause; 154585c10f28286148ee5cdba1d22c81936ff160596eRob Herring pause->tx_pause = priv->tx_pause; 154685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 154785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 154885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_pauseparam(struct net_device *netdev, 154985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_pauseparam *pause) 155085c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 155185c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(netdev); 155285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (pause->autoneg) 155485c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 155585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return xgmac_set_flow_ctrl(priv, pause->rx_pause, pause->tx_pause); 155785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 155885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 155985c10f28286148ee5cdba1d22c81936ff160596eRob Herringstruct xgmac_stats { 156085c10f28286148ee5cdba1d22c81936ff160596eRob Herring char stat_string[ETH_GSTRING_LEN]; 156185c10f28286148ee5cdba1d22c81936ff160596eRob Herring int stat_offset; 156285c10f28286148ee5cdba1d22c81936ff160596eRob Herring bool is_reg; 156385c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 156485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 156585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STAT(m) \ 156685c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, offsetof(struct xgmac_priv, xstats.m), false } 156785c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_HW_STAT(m, reg_offset) \ 156885c10f28286148ee5cdba1d22c81936ff160596eRob Herring { #m, reg_offset, true } 156985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 157085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct xgmac_stats xgmac_gstrings_stats[] = { 157185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_frame_flushed), 157285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_payload_error), 157385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_ip_header_error), 157485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_local_fault), 157585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_remote_fault), 157685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_early), 157785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_process_stopped), 157885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(tx_jabber), 157985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_buf_unav), 158085c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_process_stopped), 158185c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_payload_error), 158285c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_ip_header_error), 158385c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_da_filter_fail), 158485c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(rx_sa_filter_fail), 158585c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_STAT(fatal_bus_error), 158685c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_watchdog, XGMAC_MMC_RXWATCHDOG), 158785c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_vlan, XGMAC_MMC_TXVLANFRAME), 158885c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_vlan, XGMAC_MMC_RXVLANFRAME), 158985c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(tx_pause, XGMAC_MMC_TXPAUSEFRAME), 159085c10f28286148ee5cdba1d22c81936ff160596eRob Herring XGMAC_HW_STAT(rx_pause, XGMAC_MMC_RXPAUSEFRAME), 159185c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 159285c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_STATS_LEN ARRAY_SIZE(xgmac_gstrings_stats) 159385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 159485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_ethtool_stats(struct net_device *dev, 159585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_stats *dummy, 159685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u64 *data) 159785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 159885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 159985c10f28286148ee5cdba1d22c81936ff160596eRob Herring void *p = priv; 160085c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 160185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 160285c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 160385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (xgmac_gstrings_stats[i].is_reg) 160485c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = readl(priv->base + 160585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 160685c10f28286148ee5cdba1d22c81936ff160596eRob Herring else 160785c10f28286148ee5cdba1d22c81936ff160596eRob Herring *data++ = *(u32 *)(p + 160885c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_gstrings_stats[i].stat_offset); 160985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 161085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 161185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 161285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_get_sset_count(struct net_device *netdev, int sset) 161385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 161485c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (sset) { 161585c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 161685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return XGMAC_STATS_LEN; 161785c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 161885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 161985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 162085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 162185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 162285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_strings(struct net_device *dev, u32 stringset, 162385c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *data) 162485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 162585c10f28286148ee5cdba1d22c81936ff160596eRob Herring int i; 162685c10f28286148ee5cdba1d22c81936ff160596eRob Herring u8 *p = data; 162785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 162885c10f28286148ee5cdba1d22c81936ff160596eRob Herring switch (stringset) { 162985c10f28286148ee5cdba1d22c81936ff160596eRob Herring case ETH_SS_STATS: 163085c10f28286148ee5cdba1d22c81936ff160596eRob Herring for (i = 0; i < XGMAC_STATS_LEN; i++) { 163185c10f28286148ee5cdba1d22c81936ff160596eRob Herring memcpy(p, xgmac_gstrings_stats[i].stat_string, 163285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ETH_GSTRING_LEN); 163385c10f28286148ee5cdba1d22c81936ff160596eRob Herring p += ETH_GSTRING_LEN; 163485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 163585c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 163685c10f28286148ee5cdba1d22c81936ff160596eRob Herring default: 163785c10f28286148ee5cdba1d22c81936ff160596eRob Herring WARN_ON(1); 163885c10f28286148ee5cdba1d22c81936ff160596eRob Herring break; 163985c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 164085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 164185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_get_wol(struct net_device *dev, 164385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 164485c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 164585c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 164685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 164785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) { 164885c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->supported = WAKE_MAGIC | WAKE_UCAST; 164985c10f28286148ee5cdba1d22c81936ff160596eRob Herring wol->wolopts = priv->wolopts; 165085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 165185c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 165285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 165385c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_set_wol(struct net_device *dev, 165485c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct ethtool_wolinfo *wol) 165585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 165685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(dev); 165785c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 support = WAKE_MAGIC | WAKE_UCAST; 165885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 165985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!device_can_wakeup(priv->device)) 166085c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENOTSUPP; 166185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166285c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts & ~support) 166385c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EINVAL; 166485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = wol->wolopts; 166685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 166785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (wol->wolopts) { 166885c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 1); 166985c10f28286148ee5cdba1d22c81936ff160596eRob Herring enable_irq_wake(dev->irq); 167085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else { 167185c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_enable(priv->device, 0); 167285c10f28286148ee5cdba1d22c81936ff160596eRob Herring disable_irq_wake(dev->irq); 167385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 167485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 167585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 167685c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 167785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 167885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic struct ethtool_ops xgmac_ethtool_ops = { 167985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_settings = xgmac_ethtool_getsettings, 168085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_link = ethtool_op_get_link, 168185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_pauseparam = xgmac_get_pauseparam, 168285c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_pauseparam = xgmac_set_pauseparam, 168385c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_ethtool_stats = xgmac_get_ethtool_stats, 168485c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_strings = xgmac_get_strings, 168585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_wol = xgmac_get_wol, 168685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .set_wol = xgmac_set_wol, 168785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .get_sset_count = xgmac_get_sset_count, 168885c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 168985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 169085c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 169185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_probe 169285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 169385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: the driver is initialized through platform_device. 169485c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 169585c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_probe(struct platform_device *pdev) 169685c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 169785c10f28286148ee5cdba1d22c81936ff160596eRob Herring int ret = 0; 169885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 169985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = NULL; 170085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = NULL; 170185c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 uid; 170285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 170385c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 170485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!res) 170585c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -ENODEV; 170685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 170785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!request_mem_region(res->start, resource_size(res), pdev->name)) 170885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return -EBUSY; 170985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 171085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev = alloc_etherdev(sizeof(struct xgmac_priv)); 171185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev) { 171285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 171385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_alloc; 171485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 171585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 171685c10f28286148ee5cdba1d22c81936ff160596eRob Herring SET_NETDEV_DEV(ndev, &pdev->dev); 171785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv = netdev_priv(ndev); 171885c10f28286148ee5cdba1d22c81936ff160596eRob Herring platform_set_drvdata(pdev, ndev); 171985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ether_setup(ndev); 172085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->netdev_ops = &xgmac_netdev_ops; 172185c10f28286148ee5cdba1d22c81936ff160596eRob Herring SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops); 172285c10f28286148ee5cdba1d22c81936ff160596eRob Herring spin_lock_init(&priv->stats_lock); 172385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172485c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->device = &pdev->dev; 172585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->dev = ndev; 172685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->rx_pause = 1; 172785c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->tx_pause = 1; 172885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 172985c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->base = ioremap(res->start, resource_size(res)); 173085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!priv->base) { 173185c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "ioremap failed\n"); 173285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = -ENOMEM; 173385c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_io; 173485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 173585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 173685c10f28286148ee5cdba1d22c81936ff160596eRob Herring uid = readl(priv->base + XGMAC_VERSION); 173785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_info(ndev, "h/w version is 0x%x\n", uid); 173885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 173985c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 174085c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq = platform_get_irq(pdev, 0); 174185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ndev->irq == -ENXIO) { 174285c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No irq resource\n"); 174385c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = ndev->irq; 174485c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 174585c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 174685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 174785c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(ndev->irq, xgmac_interrupt, 0, 174885c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 174985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 175085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 175185c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->irq, ret); 175285c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_irq; 175385c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 175485c10f28286148ee5cdba1d22c81936ff160596eRob Herring 175585c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq = platform_get_irq(pdev, 1); 175685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (priv->pmt_irq == -ENXIO) { 175785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "No pmt irq resource\n"); 175885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = priv->pmt_irq; 175985c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 176085c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 176185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 176285c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = request_irq(priv->pmt_irq, xgmac_pmt_interrupt, 0, 176385c10f28286148ee5cdba1d22c81936ff160596eRob Herring dev_name(&pdev->dev), ndev); 176485c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret < 0) { 176585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_err(ndev, "Could not request irq %d - ret %d)\n", 176685c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->pmt_irq, ret); 176785c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_pmt_irq; 176885c10f28286148ee5cdba1d22c81936ff160596eRob Herring } 176985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 177085c10f28286148ee5cdba1d22c81936ff160596eRob Herring device_set_wakeup_capable(&pdev->dev, 1); 177185c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_can_wakeup(priv->device)) 177285c10f28286148ee5cdba1d22c81936ff160596eRob Herring priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ 177385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 177485c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA; 177585c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL) 177685c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 177785c10f28286148ee5cdba1d22c81936ff160596eRob Herring NETIF_F_RXCSUM; 177885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->features |= ndev->hw_features; 177985c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->priv_flags |= IFF_UNICAST_FLT; 178085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Get the MAC address */ 178285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_get_mac_addr(priv->base, ndev->dev_addr, 0); 178385c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!is_valid_ether_addr(ndev->dev_addr)) 178485c10f28286148ee5cdba1d22c81936ff160596eRob Herring netdev_warn(ndev, "MAC address %pM not valid", 178585c10f28286148ee5cdba1d22c81936ff160596eRob Herring ndev->dev_addr); 178685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 178785c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_add(ndev, &priv->napi, xgmac_poll, 64); 178885c10f28286148ee5cdba1d22c81936ff160596eRob Herring ret = register_netdev(ndev); 178985c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (ret) 179085c10f28286148ee5cdba1d22c81936ff160596eRob Herring goto err_reg; 179185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 179285c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 179385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 179485c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_reg: 179585c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 179685c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 179785c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_pmt_irq: 179885c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 179985c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_irq: 180085c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 180185c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_io: 180285c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 180385c10f28286148ee5cdba1d22c81936ff160596eRob Herringerr_alloc: 180485c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 180585c10f28286148ee5cdba1d22c81936ff160596eRob Herring platform_set_drvdata(pdev, NULL); 180685c10f28286148ee5cdba1d22c81936ff160596eRob Herring return ret; 180785c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 180885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 180985c10f28286148ee5cdba1d22c81936ff160596eRob Herring/** 181085c10f28286148ee5cdba1d22c81936ff160596eRob Herring * xgmac_dvr_remove 181185c10f28286148ee5cdba1d22c81936ff160596eRob Herring * @pdev: platform device pointer 181285c10f28286148ee5cdba1d22c81936ff160596eRob Herring * Description: this function resets the TX/RX processes, disables the MAC RX/TX 181385c10f28286148ee5cdba1d22c81936ff160596eRob Herring * changes the link status, releases the DMA descriptor rings, 181485c10f28286148ee5cdba1d22c81936ff160596eRob Herring * unregisters the MDIO bus and unmaps the allocated memory. 181585c10f28286148ee5cdba1d22c81936ff160596eRob Herring */ 181685c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_remove(struct platform_device *pdev) 181785c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 181885c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(pdev); 181985c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 182085c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct resource *res; 182185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 182385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182485c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Free the IRQ lines */ 182585c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(ndev->irq, ndev); 182685c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_irq(priv->pmt_irq, ndev); 182785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 182885c10f28286148ee5cdba1d22c81936ff160596eRob Herring platform_set_drvdata(pdev, NULL); 182985c10f28286148ee5cdba1d22c81936ff160596eRob Herring unregister_netdev(ndev); 183085c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_napi_del(&priv->napi); 183185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183285c10f28286148ee5cdba1d22c81936ff160596eRob Herring iounmap(priv->base); 183385c10f28286148ee5cdba1d22c81936ff160596eRob Herring res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 183485c10f28286148ee5cdba1d22c81936ff160596eRob Herring release_mem_region(res->start, resource_size(res)); 183585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183685c10f28286148ee5cdba1d22c81936ff160596eRob Herring free_netdev(ndev); 183785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 183885c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 183985c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 184085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184185c10f28286148ee5cdba1d22c81936ff160596eRob Herring#ifdef CONFIG_PM_SLEEP 184285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) 184385c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 184485c10f28286148ee5cdba1d22c81936ff160596eRob Herring unsigned int pmt = 0; 184585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 184685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_MAGIC) 184785c10f28286148ee5cdba1d22c81936ff160596eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT; 184885c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (mode & WAKE_UCAST) 184985c10f28286148ee5cdba1d22c81936ff160596eRob Herring pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; 185085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(pmt, ioaddr + XGMAC_PMT); 185285c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 185385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 185485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_suspend(struct device *dev) 185585c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 185685c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 185785c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 185885c10f28286148ee5cdba1d22c81936ff160596eRob Herring u32 value; 185985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186085c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!ndev || !netif_running(ndev)) 186185c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 186285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186385c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_detach(ndev); 186485c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_disable(&priv->napi); 186585c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(0, priv->base + XGMAC_DMA_INTR_ENA); 186685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 186785c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (device_may_wakeup(priv->device)) { 186885c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Stop TX/RX DMA Only */ 186985c10f28286148ee5cdba1d22c81936ff160596eRob Herring value = readl(priv->base + XGMAC_DMA_CONTROL); 187085c10f28286148ee5cdba1d22c81936ff160596eRob Herring value &= ~(DMA_CONTROL_ST | DMA_CONTROL_SR); 187185c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(value, priv->base + XGMAC_DMA_CONTROL); 187285c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187385c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(priv->base, priv->wolopts); 187485c10f28286148ee5cdba1d22c81936ff160596eRob Herring } else 187585c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_disable(priv->base); 187685c10f28286148ee5cdba1d22c81936ff160596eRob Herring 187785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 187885c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 187985c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188085c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic int xgmac_resume(struct device *dev) 188185c10f28286148ee5cdba1d22c81936ff160596eRob Herring{ 188285c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct net_device *ndev = platform_get_drvdata(to_platform_device(dev)); 188385c10f28286148ee5cdba1d22c81936ff160596eRob Herring struct xgmac_priv *priv = netdev_priv(ndev); 188485c10f28286148ee5cdba1d22c81936ff160596eRob Herring void __iomem *ioaddr = priv->base; 188585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188685c10f28286148ee5cdba1d22c81936ff160596eRob Herring if (!netif_running(ndev)) 188785c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 188885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 188985c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_pmt(ioaddr, 0); 189085c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189185c10f28286148ee5cdba1d22c81936ff160596eRob Herring /* Enable the MAC and DMA */ 189285c10f28286148ee5cdba1d22c81936ff160596eRob Herring xgmac_mac_enable(ioaddr); 189385c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); 189485c10f28286148ee5cdba1d22c81936ff160596eRob Herring writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); 189585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189685c10f28286148ee5cdba1d22c81936ff160596eRob Herring netif_device_attach(ndev); 189785c10f28286148ee5cdba1d22c81936ff160596eRob Herring napi_enable(&priv->napi); 189885c10f28286148ee5cdba1d22c81936ff160596eRob Herring 189985c10f28286148ee5cdba1d22c81936ff160596eRob Herring return 0; 190085c10f28286148ee5cdba1d22c81936ff160596eRob Herring} 190185c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190285c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic SIMPLE_DEV_PM_OPS(xgmac_pm_ops, xgmac_suspend, xgmac_resume); 190385c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PM_OPS (&xgmac_pm_ops) 190485c10f28286148ee5cdba1d22c81936ff160596eRob Herring#else 190585c10f28286148ee5cdba1d22c81936ff160596eRob Herring#define XGMAC_PM_OPS NULL 190685c10f28286148ee5cdba1d22c81936ff160596eRob Herring#endif /* CONFIG_PM_SLEEP */ 190785c10f28286148ee5cdba1d22c81936ff160596eRob Herring 190885c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic const struct of_device_id xgmac_of_match[] = { 190985c10f28286148ee5cdba1d22c81936ff160596eRob Herring { .compatible = "calxeda,hb-xgmac", }, 191085c10f28286148ee5cdba1d22c81936ff160596eRob Herring {}, 191185c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 191285c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DEVICE_TABLE(of, xgmac_of_match); 191385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 191485c10f28286148ee5cdba1d22c81936ff160596eRob Herringstatic struct platform_driver xgmac_driver = { 191585c10f28286148ee5cdba1d22c81936ff160596eRob Herring .driver = { 191685c10f28286148ee5cdba1d22c81936ff160596eRob Herring .name = "calxedaxgmac", 191785c10f28286148ee5cdba1d22c81936ff160596eRob Herring .of_match_table = xgmac_of_match, 191885c10f28286148ee5cdba1d22c81936ff160596eRob Herring }, 191985c10f28286148ee5cdba1d22c81936ff160596eRob Herring .probe = xgmac_probe, 192085c10f28286148ee5cdba1d22c81936ff160596eRob Herring .remove = xgmac_remove, 192185c10f28286148ee5cdba1d22c81936ff160596eRob Herring .driver.pm = XGMAC_PM_OPS, 192285c10f28286148ee5cdba1d22c81936ff160596eRob Herring}; 192385c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192485c10f28286148ee5cdba1d22c81936ff160596eRob Herringmodule_platform_driver(xgmac_driver); 192585c10f28286148ee5cdba1d22c81936ff160596eRob Herring 192685c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_AUTHOR("Calxeda, Inc."); 192785c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_DESCRIPTION("Calxeda 10G XGMAC driver"); 192885c10f28286148ee5cdba1d22c81936ff160596eRob HerringMODULE_LICENSE("GPL v2"); 1929