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