1b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 2b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * drivers/net/ethernet/nxp/lpc_eth.c 3b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * 4b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Author: Kevin Wells <kevin.wells@nxp.com> 5b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * 6b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Copyright (C) 2010 NXP Semiconductors 7b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Copyright (C) 2012 Roland Stigge <stigge@antcom.de> 8b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * 9b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * This program is free software; you can redistribute it and/or modify 10b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * it under the terms of the GNU General Public License as published by 11b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * the Free Software Foundation; either version 2 of the License, or 12b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * (at your option) any later version. 13b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * 14b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * This program is distributed in the hope that it will be useful, 15b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * but WITHOUT ANY WARRANTY; without even the implied warranty of 16b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * GNU General Public License for more details. 18b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 19b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 20b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 21b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 22b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/module.h> 23b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/kernel.h> 24b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/sched.h> 25b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/slab.h> 26b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/delay.h> 27b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/interrupt.h> 28b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/errno.h> 29b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/ioport.h> 30b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/crc32.h> 31b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/platform_device.h> 32b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/spinlock.h> 33b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/ethtool.h> 34b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/mii.h> 35b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/clk.h> 36b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/workqueue.h> 37b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/netdevice.h> 38b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/etherdevice.h> 39b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/skbuff.h> 40b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/phy.h> 41b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/dma-mapping.h> 424de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge#include <linux/of.h> 43b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/of_net.h> 44b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/types.h> 45b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 46b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <linux/io.h> 47b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <mach/board.h> 48b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <mach/platform.h> 49b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#include <mach/hardware.h> 50b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 51b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define MODNAME "lpc-eth" 52b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define DRV_VERSION "1.00" 53b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 54b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define ENET_MAXF_SIZE 1536 55b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define ENET_RX_DESC 48 56b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define ENET_TX_DESC 16 57b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 58b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define NAPI_WEIGHT 16 59b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 60b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 61b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Ethernet MAC controller Register offsets 62b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 63b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MAC1(x) (x + 0x000) 64b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MAC2(x) (x + 0x004) 65b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_IPGT(x) (x + 0x008) 66b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_IPGR(x) (x + 0x00C) 67b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_CLRT(x) (x + 0x010) 68b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MAXF(x) (x + 0x014) 69b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_SUPP(x) (x + 0x018) 70b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TEST(x) (x + 0x01C) 71b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MCFG(x) (x + 0x020) 72b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MCMD(x) (x + 0x024) 73b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MADR(x) (x + 0x028) 74b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MWTD(x) (x + 0x02C) 75b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MRDD(x) (x + 0x030) 76b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_MIND(x) (x + 0x034) 77b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_SA0(x) (x + 0x040) 78b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_SA1(x) (x + 0x044) 79b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_SA2(x) (x + 0x048) 80b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_COMMAND(x) (x + 0x100) 81b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_STATUS(x) (x + 0x104) 82b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXDESCRIPTOR(x) (x + 0x108) 83b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXSTATUS(x) (x + 0x10C) 84b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXDESCRIPTORNUMBER(x) (x + 0x110) 85b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXPRODUCEINDEX(x) (x + 0x114) 86b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXCONSUMEINDEX(x) (x + 0x118) 87b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TXDESCRIPTOR(x) (x + 0x11C) 88b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TXSTATUS(x) (x + 0x120) 89b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TXDESCRIPTORNUMBER(x) (x + 0x124) 90b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TXPRODUCEINDEX(x) (x + 0x128) 91b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TXCONSUMEINDEX(x) (x + 0x12C) 92b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TSV0(x) (x + 0x158) 93b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_TSV1(x) (x + 0x15C) 94b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RSV(x) (x + 0x160) 95b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_FLOWCONTROLCOUNTER(x) (x + 0x170) 96b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_FLOWCONTROLSTATUS(x) (x + 0x174) 97b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXFILTER_CTRL(x) (x + 0x200) 98b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXFILTERWOLSTATUS(x) (x + 0x204) 99b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_RXFILTERWOLCLEAR(x) (x + 0x208) 100b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_HASHFILTERL(x) (x + 0x210) 101b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_HASHFILTERH(x) (x + 0x214) 102b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_INTSTATUS(x) (x + 0xFE0) 103b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_INTENABLE(x) (x + 0xFE4) 104b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_INTCLEAR(x) (x + 0xFE8) 105b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_INTSET(x) (x + 0xFEC) 106b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_ENET_POWERDOWN(x) (x + 0xFF4) 107b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 108b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 109b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mac1 register definitions 110b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 111b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RECV_ENABLE (1 << 0) 112b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_PASS_ALL_RX_FRAMES (1 << 1) 113b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RX_FLOW_CONTROL (1 << 2) 114b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_TX_FLOW_CONTROL (1 << 3) 115b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_LOOPBACK (1 << 4) 116b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RESET_TX (1 << 8) 117b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RESET_MCS_TX (1 << 9) 118b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RESET_RX (1 << 10) 119b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_RESET_MCS_RX (1 << 11) 120b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_SIMULATION_RESET (1 << 14) 121b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC1_SOFT_RESET (1 << 15) 122b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 123b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 124b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mac2 register definitions 125b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 126b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_FULL_DUPLEX (1 << 0) 127b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_FRAME_LENGTH_CHECKING (1 << 1) 128b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_HUGH_LENGTH_CHECKING (1 << 2) 129b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_DELAYED_CRC (1 << 3) 130b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_CRC_ENABLE (1 << 4) 131b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_PAD_CRC_ENABLE (1 << 5) 132b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_VLAN_PAD_ENABLE (1 << 6) 133b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_AUTO_DETECT_PAD_ENABLE (1 << 7) 134b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_PURE_PREAMBLE_ENFORCEMENT (1 << 8) 135b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_LONG_PREAMBLE_ENFORCEMENT (1 << 9) 136b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_NO_BACKOFF (1 << 12) 137b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_BACK_PRESSURE (1 << 13) 138b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAC2_EXCESS_DEFER (1 << 14) 139b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 140b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 141b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * ipgt register definitions 142b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 143b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_IPGT_LOAD(n) ((n) & 0x7F) 144b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 145b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 146b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * ipgr register definitions 147b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 148b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_IPGR_LOAD_PART2(n) ((n) & 0x7F) 149b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_IPGR_LOAD_PART1(n) (((n) & 0x7F) << 8) 150b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 151b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 152b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * clrt register definitions 153b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 154b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_CLRT_LOAD_RETRY_MAX(n) ((n) & 0xF) 155b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_CLRT_LOAD_COLLISION_WINDOW(n) (((n) & 0x3F) << 8) 156b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 157b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 158b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * maxf register definitions 159b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 160b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MAXF_LOAD_MAX_FRAME_LEN(n) ((n) & 0xFFFF) 161b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 162b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 163b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * supp register definitions 164b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 165b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_SUPP_SPEED (1 << 8) 166b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_SUPP_RESET_RMII (1 << 11) 167b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 168b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 169b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * test register definitions 170b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 171b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TEST_SHORTCUT_PAUSE_QUANTA (1 << 0) 172b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TEST_PAUSE (1 << 1) 173b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TEST_BACKPRESSURE (1 << 2) 174b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 175b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 176b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mcfg register definitions 177b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 178b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_SCAN_INCREMENT (1 << 0) 179b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_SUPPRESS_PREAMBLE (1 << 1) 180b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_SELECT(n) (((n) & 0x7) << 2) 181b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_4 0 182b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_6 2 183b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_8 3 184b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_10 4 185b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_14 5 186b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_20 6 187b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_CLOCK_HOST_DIV_28 7 188b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCFG_RESET_MII_MGMT (1 << 15) 189b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 190b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 191b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mcmd register definitions 192b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 193b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCMD_READ (1 << 0) 194b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MCMD_SCAN (1 << 1) 195b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 196b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 197b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * madr register definitions 198b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 199b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MADR_REGISTER_ADDRESS(n) ((n) & 0x1F) 200b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MADR_PHY_0ADDRESS(n) (((n) & 0x1F) << 8) 201b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 202b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 203b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mwtd register definitions 204b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 205b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MWDT_WRITE(n) ((n) & 0xFFFF) 206b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 207b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 208b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mrdd register definitions 209b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 210b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MRDD_READ_MASK 0xFFFF 211b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 212b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 213b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * mind register definitions 214b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 215b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MIND_BUSY (1 << 0) 216b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MIND_SCANNING (1 << 1) 217b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MIND_NOT_VALID (1 << 2) 218b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MIND_MII_LINK_FAIL (1 << 3) 219b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 220b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 221b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * command register definitions 222b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 223b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_RXENABLE (1 << 0) 224b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_TXENABLE (1 << 1) 225b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_REG_RESET (1 << 3) 226b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_TXRESET (1 << 4) 227b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_RXRESET (1 << 5) 228b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_PASSRUNTFRAME (1 << 6) 229b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_PASSRXFILTER (1 << 7) 230b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_TXFLOWCONTROL (1 << 8) 231b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_RMII (1 << 9) 232b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_COMMAND_FULLDUPLEX (1 << 10) 233b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 234b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 235b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * status register definitions 236b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 237b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_STATUS_RXACTIVE (1 << 0) 238b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_STATUS_TXACTIVE (1 << 1) 239b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 240b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 241b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * tsv0 register definitions 242b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 243b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_CRC_ERROR (1 << 0) 244b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_LENGTH_CHECK_ERROR (1 << 1) 245b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_LENGTH_OUT_OF_RANGE (1 << 2) 246b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_DONE (1 << 3) 247b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_MULTICAST (1 << 4) 248b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_BROADCAST (1 << 5) 249b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_PACKET_DEFER (1 << 6) 250b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_ESCESSIVE_DEFER (1 << 7) 251b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_ESCESSIVE_COLLISION (1 << 8) 252b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_LATE_COLLISION (1 << 9) 253b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_GIANT (1 << 10) 254b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_UNDERRUN (1 << 11) 255b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_TOTAL_BYTES(n) (((n) >> 12) & 0xFFFF) 256b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_CONTROL_FRAME (1 << 28) 257b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_PAUSE (1 << 29) 258b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_BACKPRESSURE (1 << 30) 259b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV0_VLAN (1 << 31) 260b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 261b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 262b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * tsv1 register definitions 263b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 264b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV1_TRANSMIT_BYTE_COUNT(n) ((n) & 0xFFFF) 265b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_TSV1_COLLISION_COUNT(n) (((n) >> 16) & 0xF) 266b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 267b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 268b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * rsv register definitions 269b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 270b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_RECEIVED_BYTE_COUNT(n) ((n) & 0xFFFF) 271b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_RXDV_EVENT_IGNORED (1 << 16) 272b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_RXDV_EVENT_PREVIOUSLY_SEEN (1 << 17) 273b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_CARRIER_EVNT_PREVIOUS_SEEN (1 << 18) 274b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_RECEIVE_CODE_VIOLATION (1 << 19) 275b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_CRC_ERROR (1 << 20) 276b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_LENGTH_CHECK_ERROR (1 << 21) 277b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_LENGTH_OUT_OF_RANGE (1 << 22) 278b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_RECEIVE_OK (1 << 23) 279b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_MULTICAST (1 << 24) 280b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_BROADCAST (1 << 25) 281b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_DRIBBLE_NIBBLE (1 << 26) 282b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_CONTROL_FRAME (1 << 27) 283b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_PAUSE (1 << 28) 284b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_UNSUPPORTED_OPCODE (1 << 29) 285b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RSV_VLAN (1 << 30) 286b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 287b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 288b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * flowcontrolcounter register definitions 289b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 290b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_FCCR_MIRRORCOUNTER(n) ((n) & 0xFFFF) 291b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_FCCR_PAUSETIMER(n) (((n) >> 16) & 0xFFFF) 292b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 293b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 294b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * flowcontrolstatus register definitions 295b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 296b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_FCCR_MIRRORCOUNTERCURRENT(n) ((n) & 0xFFFF) 297b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 298b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 299b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * rxfliterctrl, rxfilterwolstatus, and rxfilterwolclear shared 300b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * register definitions 301b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 302b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTUNICAST (1 << 0) 303b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTUBROADCAST (1 << 1) 304b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTUMULTICAST (1 << 2) 305b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTUNICASTHASH (1 << 3) 306b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTUMULTICASTHASH (1 << 4) 307b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRW_ACCEPTPERFECT (1 << 5) 308b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 309b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 310b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * rxfliterctrl register definitions 311b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 312b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRWSTS_MAGICPACKETENWOL (1 << 12) 313b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRWSTS_RXFILTERENWOL (1 << 13) 314b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 315b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 316b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * rxfilterwolstatus/rxfilterwolclear register definitions 317b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 318b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRWSTS_RXFILTERWOL (1 << 7) 319b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_RXFLTRWSTS_MAGICPACKETWOL (1 << 8) 320b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 321b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 322b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * intstatus, intenable, intclear, and Intset shared register 323b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * definitions 324b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 325b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_RXOVERRUNINTEN (1 << 0) 326b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_RXERRORONINT (1 << 1) 327b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_RXFINISHEDINTEN (1 << 2) 328b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_RXDONEINTEN (1 << 3) 329b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_TXUNDERRUNINTEN (1 << 4) 330b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_TXERRORINTEN (1 << 5) 331b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_TXFINISHEDINTEN (1 << 6) 332b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_TXDONEINTEN (1 << 7) 333b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_SOFTINTEN (1 << 12) 334b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_MACINT_WAKEUPINTEN (1 << 13) 335b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 336b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 337b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * powerdown register definitions 338b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 339b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define LPC_POWERDOWN_MACAHB (1 << 31) 340b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 3414de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stiggestatic phy_interface_t lpc_phy_interface_mode(struct device *dev) 342b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 3434de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (dev && dev->of_node) { 3444de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge const char *mode = of_get_property(dev->of_node, 3454de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge "phy-mode", NULL); 3464de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (mode && !strcmp(mode, "mii")) 3474de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge return PHY_INTERFACE_MODE_MII; 3484de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge } 349b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return PHY_INTERFACE_MODE_RMII; 350b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 351b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 3524de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stiggestatic bool use_iram_for_net(struct device *dev) 353b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 3544de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (dev && dev->of_node) 3554de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge return of_property_read_bool(dev->of_node, "use-iram"); 3564de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge return false; 357b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 358b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 359b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* Receive Status information word */ 360b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_SIZE 0x000007FF 361b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_CONTROL (1 << 18) 362b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_VLAN (1 << 19) 363b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_FILTER (1 << 20) 364b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_MULTICAST (1 << 21) 365b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_BROADCAST (1 << 22) 366b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_CRC (1 << 23) 367b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_SYMBOL (1 << 24) 368b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_LENGTH (1 << 25) 369b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_RANGE (1 << 26) 370b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_ALIGN (1 << 27) 371b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_OVERRUN (1 << 28) 372b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_NODESC (1 << 29) 373b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_LAST (1 << 30) 374b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_ERROR (1 << 31) 375b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 376b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXSTATUS_STATUS_ERROR \ 377b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de (RXSTATUS_NODESC | RXSTATUS_OVERRUN | RXSTATUS_ALIGN | \ 378b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de RXSTATUS_RANGE | RXSTATUS_LENGTH | RXSTATUS_SYMBOL | RXSTATUS_CRC) 379b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 380b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* Receive Descriptor control word */ 381b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXDESC_CONTROL_SIZE 0x000007FF 382b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define RXDESC_CONTROL_INT (1 << 31) 383b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 384b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* Transmit Status information word */ 385b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_COLLISIONS_GET(x) (((x) >> 21) & 0xF) 386b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_DEFER (1 << 25) 387b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_EXCESSDEFER (1 << 26) 388b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_EXCESSCOLL (1 << 27) 389b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_LATECOLL (1 << 28) 390b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_UNDERRUN (1 << 29) 391b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_NODESC (1 << 30) 392b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXSTATUS_ERROR (1 << 31) 393b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 394b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* Transmit Descriptor control word */ 395b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_SIZE 0x000007FF 396b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_OVERRIDE (1 << 26) 397b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_HUGE (1 << 27) 398b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_PAD (1 << 28) 399b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_CRC (1 << 29) 400b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_LAST (1 << 30) 401b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#define TXDESC_CONTROL_INT (1 << 31) 402b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 403b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 404b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Structure of a TX/RX descriptors and RX status 405b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 406b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destruct txrx_desc_t { 407b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __le32 packet; 408b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __le32 control; 409b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 410b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destruct rx_status_t { 411b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __le32 statusinfo; 412b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __le32 statushashcrc; 413b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 414b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 415b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 416b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Device driver data structure 417b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 418b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destruct netdata_local { 419b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct platform_device *pdev; 420b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev; 421b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spinlock_t lock; 422b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de void __iomem *net_base; 423b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 msg_enable; 424a7e2eaadd0edf6d71637c0d99aca404b0da8c1beEric Dumazet unsigned int skblen[ENET_TX_DESC]; 425b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned int last_tx_idx; 426b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned int num_used_tx_buffs; 427b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct mii_bus *mii_bus; 428b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phy_dev; 429b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct clk *clk; 430b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dma_addr_t dma_buff_base_p; 431b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de void *dma_buff_base_v; 432b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de size_t dma_buff_size; 433b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct txrx_desc_t *tx_desc_v; 434b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 *tx_stat_v; 435b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de void *tx_buff_v; 436b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct txrx_desc_t *rx_desc_v; 437b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct rx_status_t *rx_stat_v; 438b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de void *rx_buff_v; 439b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int link; 440b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int speed; 441b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int duplex; 442b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct napi_struct napi; 443b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 444b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 445b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 446b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * MAC support functions 447b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 448b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_set_mac(struct netdata_local *pldat, u8 *mac) 449b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 450b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp; 451b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 452b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Set station address */ 453b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = mac[0] | ((u32)mac[1] << 8); 454b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_SA2(pldat->net_base)); 455b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = mac[2] | ((u32)mac[3] << 8); 456b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_SA1(pldat->net_base)); 457b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = mac[4] | ((u32)mac[5] << 8); 458b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_SA0(pldat->net_base)); 459b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 460b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_dbg(pldat->ndev, "Ethernet MAC address %pM\n", mac); 461b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 462b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 463b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_get_mac(struct netdata_local *pldat, u8 *mac) 464b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 465b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp; 466b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 467b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get station address */ 468b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_SA2(pldat->net_base)); 469b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[0] = tmp & 0xFF; 470b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[1] = tmp >> 8; 471b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_SA1(pldat->net_base)); 472b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[2] = tmp & 0xFF; 473b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[3] = tmp >> 8; 474b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_SA0(pldat->net_base)); 475b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[4] = tmp & 0xFF; 476b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mac[5] = tmp >> 8; 477b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 478b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 479b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_eth_clock_enable(struct netdata_local *pldat, 480b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de bool enable) 481b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 482b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (enable) 483b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_enable(pldat->clk); 484b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else 485b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_disable(pldat->clk); 486b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 487b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 488b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_params_setup(struct netdata_local *pldat) 489b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 490b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp; 491b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 492b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->duplex == DUPLEX_FULL) { 493b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_MAC2(pldat->net_base)); 494b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp |= LPC_MAC2_FULL_DUPLEX; 495b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_MAC2(pldat->net_base)); 496b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); 497b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp |= LPC_COMMAND_FULLDUPLEX; 498b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); 499b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_IPGT_LOAD(0x15), LPC_ENET_IPGT(pldat->net_base)); 500b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else { 501b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_MAC2(pldat->net_base)); 502b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp &= ~LPC_MAC2_FULL_DUPLEX; 503b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_MAC2(pldat->net_base)); 504b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); 505b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp &= ~LPC_COMMAND_FULLDUPLEX; 506b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); 507b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_IPGT_LOAD(0x12), LPC_ENET_IPGT(pldat->net_base)); 508b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 509b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 510b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->speed == SPEED_100) 511b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_SUPP_SPEED, LPC_ENET_SUPP(pldat->net_base)); 512b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else 513b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_SUPP(pldat->net_base)); 514b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 515b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 516b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_eth_reset(struct netdata_local *pldat) 517b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 518b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset all MAC logic */ 519b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_MAC1_RESET_TX | LPC_MAC1_RESET_MCS_TX | LPC_MAC1_RESET_RX | 520b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_MAC1_RESET_MCS_RX | LPC_MAC1_SIMULATION_RESET | 521b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_MAC1_SOFT_RESET), LPC_ENET_MAC1(pldat->net_base)); 522b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_COMMAND_REG_RESET | LPC_COMMAND_TXRESET | 523b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_COMMAND_RXRESET), LPC_ENET_COMMAND(pldat->net_base)); 524b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 525b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 526b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int __lpc_mii_mngt_reset(struct netdata_local *pldat) 527b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 528b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset MII management hardware */ 529b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_MCFG_RESET_MII_MGMT, LPC_ENET_MCFG(pldat->net_base)); 530b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 531b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup MII clock to slowest rate with a /28 divider */ 532b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_MCFG_CLOCK_SELECT(LPC_MCFG_CLOCK_HOST_DIV_28), 533b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_MCFG(pldat->net_base)); 534b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 535b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 536b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 537b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 538b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic inline phys_addr_t __va_to_pa(void *addr, struct netdata_local *pldat) 539b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 540b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phys_addr_t phaddr; 541b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 542b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phaddr = addr - pldat->dma_buff_base_v; 543b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phaddr += pldat->dma_buff_base_p; 544b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 545b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return phaddr; 546b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 547b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 548b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_eth_enable_int(void __iomem *regbase) 549b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 550b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_MACINT_RXDONEINTEN | LPC_MACINT_TXDONEINTEN), 551b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_INTENABLE(regbase)); 552b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 553b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 554b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_eth_disable_int(void __iomem *regbase) 555b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 556b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_INTENABLE(regbase)); 557b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 558b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 559b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* Setup TX/RX descriptors */ 560b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_txrx_desc_setup(struct netdata_local *pldat) 561b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 562b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 *ptxstat; 563b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de void *tbuff; 564b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int i; 565b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct txrx_desc_t *ptxrxdesc; 566b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct rx_status_t *prxstat; 567b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 568b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff = PTR_ALIGN(pldat->dma_buff_base_v, 16); 569b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 570b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup TX descriptors, status, and buffers */ 571b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->tx_desc_v = tbuff; 572b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += sizeof(struct txrx_desc_t) * ENET_TX_DESC; 573b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 574b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->tx_stat_v = tbuff; 575b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += sizeof(u32) * ENET_TX_DESC; 576b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 577b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff = PTR_ALIGN(tbuff, 16); 578b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->tx_buff_v = tbuff; 579b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += ENET_MAXF_SIZE * ENET_TX_DESC; 580b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 581b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup RX descriptors, status, and buffers */ 582b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->rx_desc_v = tbuff; 583b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += sizeof(struct txrx_desc_t) * ENET_RX_DESC; 584b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 585b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff = PTR_ALIGN(tbuff, 16); 586b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->rx_stat_v = tbuff; 587b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += sizeof(struct rx_status_t) * ENET_RX_DESC; 588b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 589b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff = PTR_ALIGN(tbuff, 16); 590b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->rx_buff_v = tbuff; 591b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tbuff += ENET_MAXF_SIZE * ENET_RX_DESC; 592b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 593b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Map the TX descriptors to the TX buffers in hardware */ 594b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de for (i = 0; i < ENET_TX_DESC; i++) { 595b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxstat = &pldat->tx_stat_v[i]; 596b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc = &pldat->tx_desc_v[i]; 597b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 598b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc->packet = __va_to_pa( 599b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->tx_buff_v + i * ENET_MAXF_SIZE, pldat); 600b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc->control = 0; 601b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de *ptxstat = 0; 602b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 603b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 604b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Map the RX descriptors to the RX buffers in hardware */ 605b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de for (i = 0; i < ENET_RX_DESC; i++) { 606b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de prxstat = &pldat->rx_stat_v[i]; 607b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc = &pldat->rx_desc_v[i]; 608b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 609b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc->packet = __va_to_pa( 610b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->rx_buff_v + i * ENET_MAXF_SIZE, pldat); 611b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc->control = RXDESC_CONTROL_INT | (ENET_MAXF_SIZE - 1); 612b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de prxstat->statusinfo = 0; 613b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de prxstat->statushashcrc = 0; 614b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 615b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 616b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup base addresses in hardware to point to buffers and 617b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * descriptors 618b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 619b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((ENET_TX_DESC - 1), 620b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_TXDESCRIPTORNUMBER(pldat->net_base)); 621b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(__va_to_pa(pldat->tx_desc_v, pldat), 622b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_TXDESCRIPTOR(pldat->net_base)); 623b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(__va_to_pa(pldat->tx_stat_v, pldat), 624b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_TXSTATUS(pldat->net_base)); 625b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((ENET_RX_DESC - 1), 626b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_RXDESCRIPTORNUMBER(pldat->net_base)); 627b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(__va_to_pa(pldat->rx_desc_v, pldat), 628b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_RXDESCRIPTOR(pldat->net_base)); 629b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(__va_to_pa(pldat->rx_stat_v, pldat), 630b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_RXSTATUS(pldat->net_base)); 631b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 632b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 633b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_eth_init(struct netdata_local *pldat) 634b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 635b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp; 636b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 637b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Disable controller and reset */ 638b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); 639b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp &= ~LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; 640b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); 641b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_MAC1(pldat->net_base)); 642b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp &= ~LPC_MAC1_RECV_ENABLE; 643b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_MAC1(pldat->net_base)); 644b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 645b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Initial MAC setup */ 646b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_MAC1_PASS_ALL_RX_FRAMES, LPC_ENET_MAC1(pldat->net_base)); 647b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_MAC2_PAD_CRC_ENABLE | LPC_MAC2_CRC_ENABLE), 648b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_MAC2(pldat->net_base)); 649b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(ENET_MAXF_SIZE, LPC_ENET_MAXF(pldat->net_base)); 650b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 651b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Collision window, gap */ 652b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_CLRT_LOAD_RETRY_MAX(0xF) | 653b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_CLRT_LOAD_COLLISION_WINDOW(0x37)), 654b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_CLRT(pldat->net_base)); 655b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base)); 656b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 6574de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) 658b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_COMMAND_PASSRUNTFRAME, 659b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_COMMAND(pldat->net_base)); 660b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else { 661b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), 662b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_COMMAND(pldat->net_base)); 663b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); 664b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 665b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 666b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_params_setup(pldat); 667b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 668b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup TX and RX descriptors */ 669b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_txrx_desc_setup(pldat); 670b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 671b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup packet filtering */ 672b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_RXFLTRW_ACCEPTUBROADCAST | LPC_RXFLTRW_ACCEPTPERFECT), 673b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_RXFILTER_CTRL(pldat->net_base)); 674b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 675b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get the next TX buffer output index */ 676b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->num_used_tx_buffs = 0; 677b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->last_tx_idx = 678b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); 679b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 680b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Clear and enable interrupts */ 681b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0xFFFF, LPC_ENET_INTCLEAR(pldat->net_base)); 682b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de smp_wmb(); 683b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de lpc_eth_enable_int(pldat->net_base); 684b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 685b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Enable controller */ 686b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); 687b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp |= LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; 688b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); 689b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_MAC1(pldat->net_base)); 690b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp |= LPC_MAC1_RECV_ENABLE; 691b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_MAC1(pldat->net_base)); 692b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 693b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 694b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_eth_shutdown(struct netdata_local *pldat) 695b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 696b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset ethernet and power down PHY */ 697b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 698b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_MAC1(pldat->net_base)); 699b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_MAC2(pldat->net_base)); 700b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 701b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 702b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 703b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * MAC<--->PHY support functions 704b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 705b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_mdio_read(struct mii_bus *bus, int phy_id, int phyreg) 706b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 707b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = bus->priv; 708b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long timeout = jiffies + msecs_to_jiffies(100); 709b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int lps; 710b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 711b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(((phy_id << 8) | phyreg), LPC_ENET_MADR(pldat->net_base)); 712b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_MCMD_READ, LPC_ENET_MCMD(pldat->net_base)); 713b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 714b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Wait for unbusy status */ 715b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de while (readl(LPC_ENET_MIND(pldat->net_base)) & LPC_MIND_BUSY) { 716b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (time_after(jiffies, timeout)) 717b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EIO; 718b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de cpu_relax(); 719b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 720b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 721b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de lps = readl(LPC_ENET_MRDD(pldat->net_base)); 722b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_MCMD(pldat->net_base)); 723b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 724b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return lps; 725b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 726b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 727b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_mdio_write(struct mii_bus *bus, int phy_id, int phyreg, 728b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u16 phydata) 729b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 730b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = bus->priv; 731b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long timeout = jiffies + msecs_to_jiffies(100); 732b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 733b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(((phy_id << 8) | phyreg), LPC_ENET_MADR(pldat->net_base)); 734b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(phydata, LPC_ENET_MWTD(pldat->net_base)); 735b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 736b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Wait for completion */ 737b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de while (readl(LPC_ENET_MIND(pldat->net_base)) & LPC_MIND_BUSY) { 738b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (time_after(jiffies, timeout)) 739b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EIO; 740b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de cpu_relax(); 741b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 742b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 743b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 744b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 745b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 746b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_mdio_reset(struct mii_bus *bus) 747b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 748b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return __lpc_mii_mngt_reset((struct netdata_local *)bus->priv); 749b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 750b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 751b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_handle_link_change(struct net_device *ndev) 752b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 753b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 754b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev = pldat->phy_dev; 755b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long flags; 756b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 757b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de bool status_change = false; 758b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 759b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_irqsave(&pldat->lock, flags); 760b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 761b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (phydev->link) { 762b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if ((pldat->speed != phydev->speed) || 763b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de (pldat->duplex != phydev->duplex)) { 764b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->speed = phydev->speed; 765b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->duplex = phydev->duplex; 766b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de status_change = true; 767b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 768b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 769b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 770b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (phydev->link != pldat->link) { 771b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!phydev->link) { 772b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->speed = 0; 773b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->duplex = -1; 774b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 775b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->link = phydev->link; 776b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 777b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de status_change = true; 778b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 779b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 780b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irqrestore(&pldat->lock, flags); 781b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 782b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (status_change) 783b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_params_setup(pldat); 784b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 785b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 786b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_mii_probe(struct net_device *ndev) 787b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 788b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 789b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev = phy_find_first(pldat->mii_bus); 790b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 791b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!phydev) { 792b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_err(ndev, "no PHY found\n"); 793b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -ENODEV; 794b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 795b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 796b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Attach to the PHY */ 7974de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) 798b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_info(ndev, "using MII interface\n"); 799b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else 800b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_info(ndev, "using RMII interface\n"); 801b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phydev = phy_connect(ndev, dev_name(&phydev->dev), 802f9a8f83b04e0c362a2fc660dbad980d24af209fcFlorian Fainelli &lpc_handle_link_change, 8034de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge lpc_phy_interface_mode(&pldat->pdev->dev)); 804b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 805b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (IS_ERR(phydev)) { 806b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_err(ndev, "Could not attach to PHY\n"); 807b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return PTR_ERR(phydev); 808b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 809b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 810b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* mask with MAC supported features */ 811b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phydev->supported &= PHY_BASIC_FEATURES; 812b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 813b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phydev->advertising = phydev->supported; 814b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 815b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->link = 0; 816b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->speed = 0; 817b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->duplex = -1; 818b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->phy_dev = phydev; 819b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 820b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_info(ndev, 821b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", 822b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phydev->drv->name, dev_name(&phydev->dev), phydev->irq); 823b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 824b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 825b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 826b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_mii_init(struct netdata_local *pldat) 827b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 828b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int err = -ENXIO, i; 829b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 830b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus = mdiobus_alloc(); 831b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!pldat->mii_bus) { 832b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de err = -ENOMEM; 833b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out; 834b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 835b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 836b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup MII mode */ 8374de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) 838b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_COMMAND_PASSRUNTFRAME, 839b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_COMMAND(pldat->net_base)); 840b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else { 841b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), 842b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_COMMAND(pldat->net_base)); 843b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); 844b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 845b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 846b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->name = "lpc_mii_bus"; 847b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->read = &lpc_mdio_read; 848b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->write = &lpc_mdio_write; 849b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->reset = &lpc_mdio_reset; 850b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de snprintf(pldat->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", 851b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->pdev->name, pldat->pdev->id); 852b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->priv = pldat; 853b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->parent = &pldat->pdev->dev; 854b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 855b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); 856b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!pldat->mii_bus->irq) { 857b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de err = -ENOMEM; 858b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_1; 859b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 860b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 861b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de for (i = 0; i < PHY_MAX_ADDR; i++) 862b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->mii_bus->irq[i] = PHY_POLL; 863b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 864b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de platform_set_drvdata(pldat->pdev, pldat->mii_bus); 865b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 866b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (mdiobus_register(pldat->mii_bus)) 867b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_free_mdio_irq; 868b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 869b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (lpc_mii_probe(pldat->ndev) != 0) 870b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_unregister_bus; 871b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 872b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 873b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 874b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_unregister_bus: 875b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mdiobus_unregister(pldat->mii_bus); 876b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_free_mdio_irq: 877b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de kfree(pldat->mii_bus->irq); 878b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_1: 879b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mdiobus_free(pldat->mii_bus); 880b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out: 881b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return err; 882b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 883b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 884b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void __lpc_handle_xmit(struct net_device *ndev) 885b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 886b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 887b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 txcidx, *ptxstat, txstat; 888b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 889b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); 890b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de while (pldat->last_tx_idx != txcidx) { 891a7e2eaadd0edf6d71637c0d99aca404b0da8c1beEric Dumazet unsigned int skblen = pldat->skblen[pldat->last_tx_idx]; 892b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 893b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* A buffer is available, get buffer status */ 894b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx]; 895b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txstat = *ptxstat; 896b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 897b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Next buffer and decrement used buffer counter */ 898b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->num_used_tx_buffs--; 899b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->last_tx_idx++; 900b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->last_tx_idx >= ENET_TX_DESC) 901b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->last_tx_idx = 0; 902b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 903b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Update collision counter */ 904b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.collisions += TXSTATUS_COLLISIONS_GET(txstat); 905b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 906b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Any errors occurred? */ 907b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txstat & TXSTATUS_ERROR) { 908b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txstat & TXSTATUS_UNDERRUN) { 909b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* FIFO underrun */ 910b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_fifo_errors++; 911b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 912b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txstat & TXSTATUS_LATECOLL) { 913b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Late collision */ 914b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_aborted_errors++; 915b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 916b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txstat & TXSTATUS_EXCESSCOLL) { 917b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Excessive collision */ 918b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_aborted_errors++; 919b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 920b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txstat & TXSTATUS_EXCESSDEFER) { 921b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Defer limit */ 922b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_aborted_errors++; 923b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 924b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_errors++; 925b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else { 926b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Update stats */ 927b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.tx_packets++; 928a7e2eaadd0edf6d71637c0d99aca404b0da8c1beEric Dumazet ndev->stats.tx_bytes += skblen; 929b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 930b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 931b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); 932b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 933b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 9343f16da51b0e533871d22a29682f3c3969d4f7e22Eric Dumazet if (pldat->num_used_tx_buffs <= ENET_TX_DESC/2) { 9353f16da51b0e533871d22a29682f3c3969d4f7e22Eric Dumazet if (netif_queue_stopped(ndev)) 9363f16da51b0e533871d22a29682f3c3969d4f7e22Eric Dumazet netif_wake_queue(ndev); 9373f16da51b0e533871d22a29682f3c3969d4f7e22Eric Dumazet } 938b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 939b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 940b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int __lpc_handle_recv(struct net_device *ndev, int budget) 941b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 942b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 943b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct sk_buff *skb; 944b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 rxconsidx, len, ethst; 945b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct rx_status_t *prxstat; 946b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u8 *prdbuf; 947b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int rx_done = 0; 948b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 949b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get the current RX buffer indexes */ 950b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rxconsidx = readl(LPC_ENET_RXCONSUMEINDEX(pldat->net_base)); 951b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de while (rx_done < budget && rxconsidx != 952b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de readl(LPC_ENET_RXPRODUCEINDEX(pldat->net_base))) { 953b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get pointer to receive status */ 954b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de prxstat = &pldat->rx_stat_v[rxconsidx]; 955b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de len = (prxstat->statusinfo & RXSTATUS_SIZE) + 1; 956b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 957b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Status error? */ 958b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ethst = prxstat->statusinfo; 959b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if ((ethst & (RXSTATUS_ERROR | RXSTATUS_STATUS_ERROR)) == 960b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de (RXSTATUS_ERROR | RXSTATUS_RANGE)) 961b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ethst &= ~RXSTATUS_ERROR; 962b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 963b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ethst & RXSTATUS_ERROR) { 964b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int si = prxstat->statusinfo; 965b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Check statuses */ 966b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (si & RXSTATUS_OVERRUN) { 967b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Overrun error */ 968b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_fifo_errors++; 969b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else if (si & RXSTATUS_CRC) { 970b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* CRC error */ 971b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_crc_errors++; 972b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else if (si & RXSTATUS_LENGTH) { 973b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Length error */ 974b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_length_errors++; 975b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else if (si & RXSTATUS_ERROR) { 976b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Other error */ 977b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_length_errors++; 978b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 979b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_errors++; 980b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } else { 981b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Packet is good */ 982e7f8c1fe1705e78f56ca4c8350545ad58d73451aEric Dumazet skb = dev_alloc_skb(len); 983e7f8c1fe1705e78f56ca4c8350545ad58d73451aEric Dumazet if (!skb) { 984b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_dropped++; 985e7f8c1fe1705e78f56ca4c8350545ad58d73451aEric Dumazet } else { 986b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de prdbuf = skb_put(skb, len); 987b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 988b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Copy packet from buffer */ 989b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de memcpy(prdbuf, pldat->rx_buff_v + 990b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rxconsidx * ENET_MAXF_SIZE, len); 991b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 992b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Pass to upper layer */ 993b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de skb->protocol = eth_type_trans(skb, ndev); 994b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_receive_skb(skb); 995b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_packets++; 996b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->stats.rx_bytes += len; 997b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 998b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 999b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1000b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Increment consume index */ 1001b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rxconsidx = rxconsidx + 1; 1002b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (rxconsidx >= ENET_RX_DESC) 1003b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rxconsidx = 0; 1004b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(rxconsidx, 1005b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_ENET_RXCONSUMEINDEX(pldat->net_base)); 1006b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rx_done++; 1007b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1008b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1009b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return rx_done; 1010b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1011b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1012b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_poll(struct napi_struct *napi, int budget) 1013b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1014b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = container_of(napi, 1015b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local, napi); 1016b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev = pldat->ndev; 1017b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int rx_done = 0; 1018b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdev_queue *txq = netdev_get_tx_queue(ndev, 0); 1019b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1020b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __netif_tx_lock(txq, smp_processor_id()); 1021b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_handle_xmit(ndev); 1022b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __netif_tx_unlock(txq); 1023b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de rx_done = __lpc_handle_recv(ndev, budget); 1024b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1025b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (rx_done < budget) { 1026b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de napi_complete(napi); 1027b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de lpc_eth_enable_int(pldat->net_base); 1028b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1029b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1030b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return rx_done; 1031b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1032b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1033b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic irqreturn_t __lpc_eth_interrupt(int irq, void *dev_id) 1034b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1035b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev = dev_id; 1036b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1037b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp; 1038b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1039b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock(&pldat->lock); 1040b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1041b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp = readl(LPC_ENET_INTSTATUS(pldat->net_base)); 1042b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Clear interrupts */ 1043b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp, LPC_ENET_INTCLEAR(pldat->net_base)); 1044b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1045b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de lpc_eth_disable_int(pldat->net_base); 1046b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (likely(napi_schedule_prep(&pldat->napi))) 1047b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __napi_schedule(&pldat->napi); 1048b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1049b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock(&pldat->lock); 1050b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1051b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return IRQ_HANDLED; 1052b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1053b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1054b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_close(struct net_device *ndev) 1055b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1056b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long flags; 1057b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1058b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1059b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (netif_msg_ifdown(pldat)) 1060b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_dbg(&pldat->pdev->dev, "shutting down %s\n", ndev->name); 1061b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1062b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de napi_disable(&pldat->napi); 1063b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_stop_queue(ndev); 1064b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1065b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->phy_dev) 1066b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phy_stop(pldat->phy_dev); 1067b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1068b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_irqsave(&pldat->lock, flags); 1069b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 1070b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_carrier_off(ndev); 1071b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_MAC1(pldat->net_base)); 1072b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(0, LPC_ENET_MAC2(pldat->net_base)); 1073b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irqrestore(&pldat->lock, flags); 1074b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1075b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_clock_enable(pldat, false); 1076b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1077b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1078b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1079b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1080b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) 1081b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1082b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1083b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 len, txidx; 1084b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 *ptxstat; 1085b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct txrx_desc_t *ptxrxdesc; 1086b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1087b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de len = skb->len; 1088b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1089b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_irq(&pldat->lock); 1090b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1091b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->num_used_tx_buffs >= (ENET_TX_DESC - 1)) { 1092b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* This function should never be called when there are no 1093b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de buffers */ 1094b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_stop_queue(ndev); 1095b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irq(&pldat->lock); 1096b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de WARN(1, "BUG! TX request when no free TX buffers!\n"); 1097b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return NETDEV_TX_BUSY; 1098b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1099b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1100b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get the next TX descriptor index */ 1101b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txidx = readl(LPC_ENET_TXPRODUCEINDEX(pldat->net_base)); 1102b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1103b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup control for the transfer */ 1104b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxstat = &pldat->tx_stat_v[txidx]; 1105b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de *ptxstat = 0; 1106b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc = &pldat->tx_desc_v[txidx]; 1107b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ptxrxdesc->control = 1108b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de (len - 1) | TXDESC_CONTROL_LAST | TXDESC_CONTROL_INT; 1109b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1110b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Copy data to the DMA buffer */ 1111b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len); 1112b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1113b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Save the buffer and increment the buffer counter */ 1114a7e2eaadd0edf6d71637c0d99aca404b0da8c1beEric Dumazet pldat->skblen[txidx] = len; 1115b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->num_used_tx_buffs++; 1116b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1117b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Start transmit */ 1118b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txidx++; 1119b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (txidx >= ENET_TX_DESC) 1120b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de txidx = 0; 1121b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(txidx, LPC_ENET_TXPRODUCEINDEX(pldat->net_base)); 1122b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1123b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Stop queue if no more TX buffers */ 1124b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->num_used_tx_buffs >= (ENET_TX_DESC - 1)) 1125b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_stop_queue(ndev); 1126b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1127b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irq(&pldat->lock); 1128b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1129a7e2eaadd0edf6d71637c0d99aca404b0da8c1beEric Dumazet dev_kfree_skb(skb); 1130b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return NETDEV_TX_OK; 1131b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1132b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1133b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_set_mac_address(struct net_device *ndev, void *p) 1134b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1135b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct sockaddr *addr = p; 1136b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1137b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long flags; 1138b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1139b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!is_valid_ether_addr(addr->sa_data)) 1140b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EADDRNOTAVAIL; 1141b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de memcpy(ndev->dev_addr, addr->sa_data, ETH_ALEN); 1142b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1143b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_irqsave(&pldat->lock, flags); 1144b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1145b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Set station address */ 1146b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_set_mac(pldat, ndev->dev_addr); 1147b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1148b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irqrestore(&pldat->lock, flags); 1149b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1150b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1151b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1152b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1153b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_eth_set_multicast_list(struct net_device *ndev) 1154b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1155b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1156b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdev_hw_addr_list *mcptr = &ndev->mc; 1157b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdev_hw_addr *ha; 1158b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de u32 tmp32, hash_val, hashlo, hashhi; 1159b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unsigned long flags; 1160b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1161b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_irqsave(&pldat->lock, flags); 1162b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1163b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Set station address */ 1164b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_set_mac(pldat, ndev->dev_addr); 1165b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1166b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp32 = LPC_RXFLTRW_ACCEPTUBROADCAST | LPC_RXFLTRW_ACCEPTPERFECT; 1167b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1168b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ndev->flags & IFF_PROMISC) 1169b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp32 |= LPC_RXFLTRW_ACCEPTUNICAST | 1170b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de LPC_RXFLTRW_ACCEPTUMULTICAST; 1171b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ndev->flags & IFF_ALLMULTI) 1172b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp32 |= LPC_RXFLTRW_ACCEPTUMULTICAST; 1173b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1174b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (netdev_hw_addr_list_count(mcptr)) 1175b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de tmp32 |= LPC_RXFLTRW_ACCEPTUMULTICASTHASH; 1176b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1177b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(tmp32, LPC_ENET_RXFILTER_CTRL(pldat->net_base)); 1178b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1179b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1180b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Set initial hash table */ 1181b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de hashlo = 0x0; 1182b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de hashhi = 0x0; 1183b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1184b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* 64 bits : multicast address in hash table */ 1185b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_hw_addr_list_for_each(ha, mcptr) { 1186b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de hash_val = (ether_crc(6, ha->addr) >> 23) & 0x3F; 1187b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1188b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (hash_val >= 32) 1189b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de hashhi |= 1 << (hash_val - 32); 1190b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else 1191b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de hashlo |= 1 << hash_val; 1192b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1193b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1194b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(hashlo, LPC_ENET_HASHFILTERL(pldat->net_base)); 1195b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de writel(hashhi, LPC_ENET_HASHFILTERH(pldat->net_base)); 1196b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1197b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_unlock_irqrestore(&pldat->lock, flags); 1198b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1199b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1200b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) 1201b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1202b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1203b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev = pldat->phy_dev; 1204b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1205b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!netif_running(ndev)) 1206b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EINVAL; 1207b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1208b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!phydev) 1209b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -ENODEV; 1210b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1211b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return phy_mii_ioctl(phydev, req, cmd); 1212b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1213b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1214b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_open(struct net_device *ndev) 1215b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1216b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1217b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1218b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (netif_msg_ifup(pldat)) 1219b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_dbg(&pldat->pdev->dev, "enabling %s\n", ndev->name); 1220b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1221b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_clock_enable(pldat, true); 1222b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1223aff88a0695976596b39dcfa65da4896c802c938dRoland Stigge /* Suspended PHY makes LPC ethernet core block, so resume now */ 1224aff88a0695976596b39dcfa65da4896c802c938dRoland Stigge phy_resume(pldat->phy_dev); 1225aff88a0695976596b39dcfa65da4896c802c938dRoland Stigge 1226b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset and initialize */ 1227b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 1228b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_init(pldat); 1229b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1230b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* schedule a link state check */ 1231b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phy_start(pldat->phy_dev); 1232b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_start_queue(ndev); 1233b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de napi_enable(&pldat->napi); 1234b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1235b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1236b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1237b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1238b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de/* 1239b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Ethtool ops 1240b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 1241b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_eth_ethtool_getdrvinfo(struct net_device *ndev, 1242b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct ethtool_drvinfo *info) 1243b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 12447826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko strlcpy(info->driver, MODNAME, sizeof(info->driver)); 12457826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 12467826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko strlcpy(info->bus_info, dev_name(ndev->dev.parent), 12477826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko sizeof(info->bus_info)); 1248b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1249b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1250b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic u32 lpc_eth_ethtool_getmsglevel(struct net_device *ndev) 1251b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1252b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1253b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1254b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return pldat->msg_enable; 1255b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1256b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1257b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic void lpc_eth_ethtool_setmsglevel(struct net_device *ndev, u32 level) 1258b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1259b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1260b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1261b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->msg_enable = level; 1262b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1263b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1264b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_ethtool_getsettings(struct net_device *ndev, 1265b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct ethtool_cmd *cmd) 1266b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1267b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1268b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev = pldat->phy_dev; 1269b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1270b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!phydev) 1271b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EOPNOTSUPP; 1272b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1273b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return phy_ethtool_gset(phydev, cmd); 1274b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1275b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1276b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_ethtool_setsettings(struct net_device *ndev, 1277b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct ethtool_cmd *cmd) 1278b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1279b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1280b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev = pldat->phy_dev; 1281b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1282b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!phydev) 1283b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return -EOPNOTSUPP; 1284b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1285b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return phy_ethtool_sset(phydev, cmd); 1286b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1287b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1288b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic const struct ethtool_ops lpc_eth_ethtool_ops = { 1289b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .get_drvinfo = lpc_eth_ethtool_getdrvinfo, 1290b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .get_settings = lpc_eth_ethtool_getsettings, 1291b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .set_settings = lpc_eth_ethtool_setsettings, 1292b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .get_msglevel = lpc_eth_ethtool_getmsglevel, 1293b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .set_msglevel = lpc_eth_ethtool_setmsglevel, 1294b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .get_link = ethtool_op_get_link, 1295b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 1296b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1297b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic const struct net_device_ops lpc_netdev_ops = { 1298b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_open = lpc_eth_open, 1299b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_stop = lpc_eth_close, 1300b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_start_xmit = lpc_eth_hard_start_xmit, 1301b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_set_rx_mode = lpc_eth_set_multicast_list, 1302b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_do_ioctl = lpc_eth_ioctl, 1303b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .ndo_set_mac_address = lpc_set_mac_address, 1304c867b55eb4831a493631205f2744b2e77ce0983bJoachim Eastwood .ndo_validate_addr = eth_validate_addr, 1305e30478598a8476d02e3b00caa89ce1a3b1dad54bEric Dumazet .ndo_change_mtu = eth_change_mtu, 1306b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 1307b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1308b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_drv_probe(struct platform_device *pdev) 1309b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1310b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct resource *res; 1311b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev; 1312b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat; 1313b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct phy_device *phydev; 1314b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dma_addr_t dma_handle; 1315b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de int irq, ret; 13164de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge u32 tmp; 13174de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge 13184de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge /* Setup network interface for RMII or MII mode */ 13194de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); 13204de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; 13214de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (lpc_phy_interface_mode(&pdev->dev) == PHY_INTERFACE_MODE_MII) 13224de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS; 13234de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge else 13244de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; 13254de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); 1326b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1327b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get platform resources */ 1328b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1329b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de irq = platform_get_irq(pdev, 0); 13304de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if ((!res) || (irq < 0) || (irq >= NR_IRQS)) { 1331b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "error getting resources.\n"); 1332b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = -ENXIO; 1333b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_exit; 1334b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1335b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1336b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Allocate net driver data structure */ 1337b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev = alloc_etherdev(sizeof(struct netdata_local)); 1338b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!ndev) { 1339b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "could not allocate device.\n"); 1340b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = -ENOMEM; 1341b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_exit; 1342b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1343b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1344b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de SET_NETDEV_DEV(ndev, &pdev->dev); 1345b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1346b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat = netdev_priv(ndev); 1347b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->pdev = pdev; 1348b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->ndev = ndev; 1349b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1350b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de spin_lock_init(&pldat->lock); 1351b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1352b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Save resources */ 1353b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->irq = irq; 1354b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1355b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get clock for the device */ 1356b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->clk = clk_get(&pdev->dev, NULL); 1357b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (IS_ERR(pldat->clk)) { 1358b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "error getting clock.\n"); 1359b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = PTR_ERR(pldat->clk); 1360b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_free_dev; 1361b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1362b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1363b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Enable network clock */ 1364b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_clock_enable(pldat, true); 1365b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1366b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Map IO space */ 13679323b239953605071866899e675c06fb2d41880cBenoit Taine pldat->net_base = ioremap(res->start, resource_size(res)); 1368b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!pldat->net_base) { 1369b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "failed to map registers\n"); 1370b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = -ENOMEM; 1371b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_disable_clocks; 1372b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1373b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = request_irq(ndev->irq, __lpc_eth_interrupt, 0, 1374b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->name, ndev); 1375b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ret) { 1376b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "error requesting interrupt.\n"); 1377b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_iounmap; 1378b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1379b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1380b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Setup driver functions */ 1381b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->netdev_ops = &lpc_netdev_ops; 1382b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->ethtool_ops = &lpc_eth_ethtool_ops; 1383b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ndev->watchdog_timeo = msecs_to_jiffies(2500); 1384b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1385b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get size of DMA buffers/descriptors region */ 1386b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_size = (ENET_TX_DESC + ENET_RX_DESC) * (ENET_MAXF_SIZE + 1387b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t)); 1388b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v = 0; 1389b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 13904de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (use_iram_for_net(&pldat->pdev->dev)) { 13914de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge dma_handle = LPC32XX_IRAM_BASE; 1392b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->dma_buff_size <= lpc32xx_return_iram_size()) 1393b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v = 13944de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge io_p2v(LPC32XX_IRAM_BASE); 1395b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de else 1396b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_err(ndev, 1397b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de "IRAM not big enough for net buffers, using SDRAM instead.\n"); 1398b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1399b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1400b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->dma_buff_base_v == 0) { 1401b469357f4ba28bd8d659106143fb1f6b3c64d5dfRussell King ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 1402b469357f4ba28bd8d659106143fb1f6b3c64d5dfRussell King if (ret) 1403b469357f4ba28bd8d659106143fb1f6b3c64d5dfRussell King goto err_out_free_irq; 1404b469357f4ba28bd8d659106143fb1f6b3c64d5dfRussell King 1405b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_size = PAGE_ALIGN(pldat->dma_buff_size); 1406b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1407b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Allocate a chunk of memory for the DMA ethernet buffers 1408b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de and descriptors */ 1409b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v = 1410b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dma_alloc_coherent(&pldat->pdev->dev, 1411b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_size, &dma_handle, 1412b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de GFP_KERNEL); 1413b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (pldat->dma_buff_base_v == NULL) { 1414b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = -ENOMEM; 1415b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_free_irq; 1416b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1417b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1418b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_p = dma_handle; 1419b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 14209323b239953605071866899e675c06fb2d41880cBenoit Taine netdev_dbg(ndev, "IO address space :%pR\n", res); 14219323b239953605071866899e675c06fb2d41880cBenoit Taine netdev_dbg(ndev, "IO address size :%d\n", resource_size(res)); 1422b31525d16b50fe0eb33545afbc0be1a03f2896e3stigge@antcom.de netdev_dbg(ndev, "IO address (mapped) :0x%p\n", 1423b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->net_base); 1424b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_dbg(ndev, "IRQ number :%d\n", ndev->irq); 1425b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_dbg(ndev, "DMA buffer size :%d\n", pldat->dma_buff_size); 1426b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_dbg(ndev, "DMA buffer P address :0x%08x\n", 1427b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_p); 1428b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_dbg(ndev, "DMA buffer V address :0x%p\n", 1429b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v); 1430b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1431b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Get MAC address from current HW setting (POR state is all zeros) */ 1432b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_get_mac(pldat, ndev->dev_addr); 1433b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1434b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!is_valid_ether_addr(ndev->dev_addr)) { 1435b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de const char *macaddr = of_get_mac_address(pdev->dev.of_node); 1436b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (macaddr) 1437b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de memcpy(ndev->dev_addr, macaddr, ETH_ALEN); 1438b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1439b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (!is_valid_ether_addr(ndev->dev_addr)) 1440cdaf0b835df04177397b90214f8b457fd23b67e0stigge@antcom.de eth_hw_addr_random(ndev); 1441b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1442b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset the ethernet controller */ 1443b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 1444b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1445b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* then shut everything down to save power */ 1446b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_shutdown(pldat); 1447b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1448b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Set default parameters */ 1449b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->msg_enable = NETIF_MSG_LINK; 1450b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1451b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Force an MII interface reset and clock setup */ 1452b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_mii_mngt_reset(pldat); 1453b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1454b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Force default PHY interface setup in chip, this will probably be 1455b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de changed by the PHY driver */ 1456b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->link = 0; 1457b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->speed = 100; 1458b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->duplex = DUPLEX_FULL; 1459b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_params_setup(pldat); 1460b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1461b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_napi_add(ndev, &pldat->napi, lpc_eth_poll, NAPI_WEIGHT); 1462b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1463b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de ret = register_netdev(ndev); 1464b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ret) { 1465b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); 1466b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_dma_unmap; 1467b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1468b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de platform_set_drvdata(pdev, ndev); 1469b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1470fa90b077d72b4ea92706e86fdff7b5dca294caa3Wei Yongjun ret = lpc_mii_init(pldat); 1471fa90b077d72b4ea92706e86fdff7b5dca294caa3Wei Yongjun if (ret) 1472b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de goto err_out_unregister_netdev; 1473b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1474b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netdev_info(ndev, "LPC mac at 0x%08x irq %d\n", 1475b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de res->start, ndev->irq); 1476b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1477b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de phydev = pldat->phy_dev; 1478b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1479b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de device_init_wakeup(&pdev->dev, 1); 1480b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de device_set_wakeup_enable(&pdev->dev, 0); 1481b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1482b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1483b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1484b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_unregister_netdev: 1485b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unregister_netdev(ndev); 1486b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_dma_unmap: 14874de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (!use_iram_for_net(&pldat->pdev->dev) || 1488b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_size > lpc32xx_return_iram_size()) 1489b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1490b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v, 1491b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_p); 1492b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_free_irq: 1493b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de free_irq(ndev->irq, ndev); 1494b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_iounmap: 1495b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de iounmap(pldat->net_base); 1496b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_disable_clocks: 1497b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_disable(pldat->clk); 1498b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_put(pldat->clk); 1499b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_out_free_dev: 1500b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de free_netdev(ndev); 1501b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deerr_exit: 1502b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pr_err("%s: not found (%d).\n", MODNAME, ret); 1503b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return ret; 1504b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1505b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1506b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_drv_remove(struct platform_device *pdev) 1507b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1508b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev = platform_get_drvdata(pdev); 1509b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1510b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1511b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de unregister_netdev(ndev); 1512b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 15134de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge if (!use_iram_for_net(&pldat->pdev->dev) || 1514b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_size > lpc32xx_return_iram_size()) 1515b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1516b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_v, 1517b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat->dma_buff_base_p); 1518b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de free_irq(ndev->irq, ndev); 1519b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de iounmap(pldat->net_base); 152057c10b61c84bfed68b1b317d6f507a392724b9c4Peter Senna Tschudin mdiobus_unregister(pldat->mii_bus); 1521b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de mdiobus_free(pldat->mii_bus); 1522b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_disable(pldat->clk); 1523b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_put(pldat->clk); 1524b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de free_netdev(ndev); 1525b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1526b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1527b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1528b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1529b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#ifdef CONFIG_PM 1530b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_drv_suspend(struct platform_device *pdev, 1531b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pm_message_t state) 1532b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1533b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev = platform_get_drvdata(pdev); 1534b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat = netdev_priv(ndev); 1535b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1536b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (device_may_wakeup(&pdev->dev)) 1537b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de enable_irq_wake(ndev->irq); 1538b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1539b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ndev) { 1540b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (netif_running(ndev)) { 1541b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_device_detach(ndev); 1542b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_shutdown(pldat); 1543b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_disable(pldat->clk); 1544b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1545b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* 1546b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * Reset again now clock is disable to be sure 1547b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de * EMC_MDC is down 1548b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de */ 1549b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 1550b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1551b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1552b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1553b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1554b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1555b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1556b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic int lpc_eth_drv_resume(struct platform_device *pdev) 1557b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de{ 1558b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct net_device *ndev = platform_get_drvdata(pdev); 1559b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de struct netdata_local *pldat; 1560b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1561b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (device_may_wakeup(&pdev->dev)) 1562b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de disable_irq_wake(ndev->irq); 1563b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1564b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (ndev) { 1565b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de if (netif_running(ndev)) { 1566b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de pldat = netdev_priv(ndev); 1567b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1568b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Enable interface clock */ 1569b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de clk_enable(pldat->clk); 1570b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1571b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de /* Reset and initialize */ 1572b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_reset(pldat); 1573b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de __lpc_eth_init(pldat); 1574b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1575b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de netif_device_attach(ndev); 1576b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1577b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de } 1578b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1579b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de return 0; 1580b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de} 1581b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#endif 1582b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 15834de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge#ifdef CONFIG_OF 15844de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stiggestatic const struct of_device_id lpc_eth_match[] = { 15854de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge { .compatible = "nxp,lpc-eth" }, 15864de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge { } 15874de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge}; 15884de02e4a280678224bd12ec3b182e369c87c8fc5Roland StiggeMODULE_DEVICE_TABLE(of, lpc_eth_match); 15894de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge#endif 15904de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge 1591b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.destatic struct platform_driver lpc_eth_driver = { 1592b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .probe = lpc_eth_drv_probe, 159321524526b3ec66329cba682f11fdba77c8b0e698Bill Pemberton .remove = lpc_eth_drv_remove, 1594b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#ifdef CONFIG_PM 1595b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .suspend = lpc_eth_drv_suspend, 1596b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .resume = lpc_eth_drv_resume, 1597b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de#endif 1598b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .driver = { 1599b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de .name = MODNAME, 16004de02e4a280678224bd12ec3b182e369c87c8fc5Roland Stigge .of_match_table = of_match_ptr(lpc_eth_match), 1601b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de }, 1602b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de}; 1603b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1604b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.demodule_platform_driver(lpc_eth_driver); 1605b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.de 1606b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deMODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); 1607b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deMODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 1608b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deMODULE_DESCRIPTION("LPC Ethernet Driver"); 1609b7370112f5195ae2e2e52b5ef46961422fa4daf0stigge@antcom.deMODULE_LICENSE("GPL"); 1610