148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* 248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * Freescale Ethernet controllers 348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * 49b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Copyright (c) 2005 Intracom S.A. 548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * by Pantelis Antoniou <panto@intracom.gr> 648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * 79b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * 2005 (c) MontaVista Software, Inc. 848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * Vitaly Bordug <vbordug@ru.mvista.com> 948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * 109b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * This file is licensed under the terms of the GNU General Public License 119b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * version 2. This program is licensed "as is" without any warranty of any 1248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * kind, whether express or implied. 1348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 1448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 1548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/module.h> 1648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/kernel.h> 1748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/types.h> 1848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/string.h> 1948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/ptrace.h> 2048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/errno.h> 2148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/ioport.h> 2248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/interrupt.h> 2348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/delay.h> 2448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/netdevice.h> 2548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/etherdevice.h> 2648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/skbuff.h> 2748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/spinlock.h> 2848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/mii.h> 2948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/ethtool.h> 3048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/bitops.h> 3148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <linux/fs.h> 32f7b9996990bccaa9f53cbea7aea8ab5355e7f10cMarcelo Tosatti#include <linux/platform_device.h> 335af5073004071cedd0343eee51d77955037ec6f3Rob Herring#include <linux/of_address.h> 34b219108cbacee5f2eaeca63cba013688eeba3bd4Kumar Gala#include <linux/of_device.h> 355af5073004071cedd0343eee51d77955037ec6f3Rob Herring#include <linux/of_irq.h> 365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 3748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 3848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <asm/irq.h> 3948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <asm/uaccess.h> 4048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 4148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#ifdef CONFIG_8xx 4248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <asm/8xx_immap.h> 4348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include <asm/pgtable.h> 44b5677d848cbb94220ac2cfd36d93bcdbe49c3280Jochen Friedrich#include <asm/cpm1.h> 4548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#endif 4648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 4748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#include "fs_enet.h" 485b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug#include "fec.h" 4948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 5048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/*************************************************/ 5148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 5248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#if defined(CONFIG_CPM1) 5348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* for a CPM1 __raw_xxx's are sufficient */ 5448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_out32(addr, x) __raw_writel(x, addr) 5548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_out16(addr, x) __raw_writew(x, addr) 5648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_in32(addr) __raw_readl(addr) 5748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_in16(addr) __raw_readw(addr) 5848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#else 5948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* for others play it safe */ 6048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_out32(addr, x) out_be32(addr, x) 6148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_out16(addr, x) out_be16(addr, x) 6248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_in32(addr) in_be32(addr) 6348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define __fs_in16(addr) in_be16(addr) 6448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#endif 6548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 6648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* write */ 6748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v)) 6848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 6948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* read */ 7048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg) 7148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 7248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* set bits */ 7348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) 7448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 7548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* clear bits */ 7648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) 7748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 7848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/* 795b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug * Delay to wait for FEC reset command to complete (in us) 8048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 8148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FEC_RESET_DELAY 50 8248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 8360ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschinstatic int whack_reset(struct fec __iomem *fecp) 8448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 8548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou int i; 8648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 8748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); 8848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou for (i = 0; i < FEC_RESET_DELAY; i++) { 8948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0) 9048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return 0; /* OK */ 9148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou udelay(1); 9248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 9348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 9448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return -1; 9548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 9648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 9748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic int do_pd_setup(struct fs_enet_private *fep) 9848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 992dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *ofdev = to_platform_device(fep->dev); 100976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood 101f7578496a671a96e501f16a5104893275e32c33aThierry Reding fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0); 102976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood if (fep->interrupt == NO_IRQ) 103976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood return -EINVAL; 104976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood 10561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); 106976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood if (!fep->fcc.fccp) 107976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood return -EINVAL; 108976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood 109976de6a8c304dcc43e38efcb8a0bace7866b6242Scott Wood return 0; 11048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 11148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 11248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) 113d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe#define FEC_NAPI_TX_EVENT_MSK (FEC_ENET_TXF | FEC_ENET_TXB) 11448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FEC_RX_EVENT (FEC_ENET_RXF) 11548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FEC_TX_EVENT (FEC_ENET_TXF) 11648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \ 11748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FEC_ENET_BABT | FEC_ENET_EBERR) 11848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 11948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic int setup_data(struct net_device *dev) 12048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 12148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 12248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 12348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (do_pd_setup(fep) != 0) 12448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return -EINVAL; 12548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 12648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.hthi = 0; 12748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.htlo = 0; 12848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 12948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK; 130d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe fep->ev_napi_tx = FEC_NAPI_TX_EVENT_MSK; 13148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->ev_rx = FEC_RX_EVENT; 13248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->ev_tx = FEC_TX_EVENT; 13348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->ev_err = FEC_ERR_EVENT_MSK; 13448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 13548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return 0; 13648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 13748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 13848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic int allocate_bd(struct net_device *dev) 13948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 14048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 14148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou const struct fs_platform_info *fpi = fep->fpi; 1429b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug 14331a5bb04d59931eb4657826213a439d37d12d4a9Scott Wood fep->ring_base = (void __force __iomem *)dma_alloc_coherent(fep->dev, 14448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou (fpi->tx_ring + fpi->rx_ring) * 14548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou sizeof(cbd_t), &fep->ring_mem_addr, 14648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou GFP_KERNEL); 14748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (fep->ring_base == NULL) 14848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return -ENOMEM; 14948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 15048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return 0; 15148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 15248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 15348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void free_bd(struct net_device *dev) 15448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 15548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 15648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou const struct fs_platform_info *fpi = fep->fpi; 15748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 15848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if(fep->ring_base) 15948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) 16048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou * sizeof(cbd_t), 16131a5bb04d59931eb4657826213a439d37d12d4a9Scott Wood (void __force *)fep->ring_base, 16248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->ring_mem_addr); 16348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 16448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 16548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void cleanup_data(struct net_device *dev) 16648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 16748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* nothing */ 16848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 16948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 17048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void set_promiscuous_mode(struct net_device *dev) 17148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 17248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 17360ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 17448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 17548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FS(fecp, r_cntrl, FEC_RCNTRL_PROM); 17648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 17748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 17848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void set_multicast_start(struct net_device *dev) 17948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 18048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 18148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 18248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.hthi = 0; 18348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.htlo = 0; 18448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 18548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 18648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void set_multicast_one(struct net_device *dev, const u8 *mac) 18748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 18848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 18948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou int temp, hash_index, i, j; 19048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou u32 crc, csrVal; 19148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou u8 byte, msb; 19248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 19348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou crc = 0xffffffff; 19448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou for (i = 0; i < 6; i++) { 19548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou byte = mac[i]; 19648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou for (j = 0; j < 8; j++) { 19748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou msb = crc >> 31; 19848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou crc <<= 1; 19948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (msb ^ (byte & 0x1)) 20048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou crc ^= FEC_CRC_POLY; 20148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou byte >>= 1; 20248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 20348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 20448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 20548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou temp = (crc & 0x3f) >> 1; 20648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou hash_index = ((temp & 0x01) << 4) | 20748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((temp & 0x02) << 2) | 20848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((temp & 0x04)) | 20948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((temp & 0x08) >> 2) | 21048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((temp & 0x10) >> 4); 21148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou csrVal = 1 << hash_index; 21248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (crc & 1) 21348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.hthi |= csrVal; 21448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou else 21548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.htlo |= csrVal; 21648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 21748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 21848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void set_multicast_finish(struct net_device *dev) 21948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 22048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 22160ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 22248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 22348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* if all multi or too many multicasts; just enable all */ 22448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if ((dev->flags & IFF_ALLMULTI) != 0 || 2254cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko netdev_mc_count(dev) > FEC_MAX_MULTICAST_ADDRS) { 22648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.hthi = 0xffffffffU; 22748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fep->fec.htlo = 0xffffffffU; 22848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 22948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 23048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FC(fecp, r_cntrl, FEC_RCNTRL_PROM); 231e2a85aecebc03d165bc2dcd233deadd5dd97ea9fAndrea Galbusera FW(fecp, grp_hash_table_high, fep->fec.hthi); 232e2a85aecebc03d165bc2dcd233deadd5dd97ea9fAndrea Galbusera FW(fecp, grp_hash_table_low, fep->fec.htlo); 23348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 23448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 23548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void set_multicast_list(struct net_device *dev) 23648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 23722bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko struct netdev_hw_addr *ha; 23848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 23948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if ((dev->flags & IFF_PROMISC) == 0) { 24048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou set_multicast_start(dev); 24122bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko netdev_for_each_mc_addr(ha, dev) 24222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko set_multicast_one(dev, ha->addr); 24348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou set_multicast_finish(dev); 24448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } else 24548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou set_promiscuous_mode(dev); 24648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 24748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 24848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void restart(struct net_device *dev) 24948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 25048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 25160ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 25248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou const struct fs_platform_info *fpi = fep->fpi; 25348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou dma_addr_t rx_bd_base_phys, tx_bd_base_phys; 25448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou int r; 25548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou u32 addrhi, addrlo; 25648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 2575b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug struct mii_bus* mii = fep->phydev->bus; 2585b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug struct fec_info* fec_inf = mii->priv; 2595b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug 26048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou r = whack_reset(fep->fec.fecp); 26148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (r != 0) 262fcb6a1c83e48c30ff99624e9c46ce301707ede05Anatolij Gustschin dev_err(fep->dev, "FEC Reset FAILED!\n"); 26348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 2645b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug * Set station address. 26548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 26648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou addrhi = ((u32) dev->dev_addr[0] << 24) | 26748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((u32) dev->dev_addr[1] << 16) | 26848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((u32) dev->dev_addr[2] << 8) | 26948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou (u32) dev->dev_addr[3]; 27048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou addrlo = ((u32) dev->dev_addr[4] << 24) | 27148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou ((u32) dev->dev_addr[5] << 16); 27248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, addr_low, addrhi); 27348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, addr_high, addrlo); 27448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 27548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 2769b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Reset all multicast. 27748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 278e2a85aecebc03d165bc2dcd233deadd5dd97ea9fAndrea Galbusera FW(fecp, grp_hash_table_high, fep->fec.hthi); 279e2a85aecebc03d165bc2dcd233deadd5dd97ea9fAndrea Galbusera FW(fecp, grp_hash_table_low, fep->fec.htlo); 28048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 28148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 2829b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Set maximum receive buffer size. 28348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 28448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); 28560ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#ifdef CONFIG_FS_ENET_MPC5121_FEC 28660ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin FW(fecp, r_cntrl, PKT_MAXBUF_SIZE << 16); 28760ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#else 28848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_hash, PKT_MAXBUF_SIZE); 28960ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#endif 29048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 29148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* get physical address */ 29248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou rx_bd_base_phys = fep->ring_mem_addr; 29348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; 29448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 29548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 2969b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Set receive and transmit descriptor base. 29748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 29848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_des_start, rx_bd_base_phys); 29948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, x_des_start, tx_bd_base_phys); 30048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 30148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fs_init_bds(dev); 30248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 30348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3049b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Enable big endian and don't care about SDMA FC. 30548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 30660ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#ifdef CONFIG_FS_ENET_MPC5121_FEC 30760ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin FS(fecp, dma_control, 0xC0000000); 30860ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#else 30948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, fun_code, 0x78000000); 31060ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#endif 31148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 31248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3135b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug * Set MII speed. 31448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 3155b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug FW(fecp, mii_speed, fec_inf->mii_speed); 31648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 31748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3185b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug * Clear any outstanding interrupt. 31948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 32048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ievent, 0xffc0); 32160ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#ifndef CONFIG_FS_ENET_MPC5121_FEC 322b1f54ba34f9e036ab515bbac0c01d17300e1c79aVitaly Bordug FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); 32348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 32448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 32560ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#else 32660ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin /* 327ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov * Only set MII/RMII mode - do not touch maximum frame length 32860ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin * configured before. 32960ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin */ 330ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov FS(fecp, r_cntrl, fpi->use_rmii ? 331ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov FEC_RCNTRL_RMII_MODE : FEC_RCNTRL_MII_MODE); 33260ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin#endif 33348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3345b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug * adjust to duplex mode 33548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 3365b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug if (fep->phydev->duplex) { 33748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FC(fecp, r_cntrl, FEC_RCNTRL_DRT); 33848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ 33948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } else { 34048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FS(fecp, r_cntrl, FEC_RCNTRL_DRT); 34148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ 34248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 34348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 3448751b12cd93cc37337256f650e309b8364d40b35LEROY Christophe /* Restore multicast and promiscuous settings */ 3458751b12cd93cc37337256f650e309b8364d40b35LEROY Christophe set_multicast_list(dev); 3468751b12cd93cc37337256f650e309b8364d40b35LEROY Christophe 34748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3489b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Enable interrupts we wish to service. 34948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 35048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | 35148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FEC_ENET_RXF | FEC_ENET_RXB); 35248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 35348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3549b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * And last, enable the transmit and receive processing. 35548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 35648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 35748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_des_active, 0x01000000); 35848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 35948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 36048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void stop(struct net_device *dev) 36148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 36248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 3635b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug const struct fs_platform_info *fpi = fep->fpi; 36460ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 3655b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug 3665b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug struct fec_info* feci= fep->phydev->bus->priv; 3675b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug 36848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou int i; 36948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 37048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) 37148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return; /* already down */ 37248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 37348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ 37448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && 37548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou i < FEC_RESET_DELAY; i++) 37648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou udelay(1); 37748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 37848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou if (i == FEC_RESET_DELAY) 379fcb6a1c83e48c30ff99624e9c46ce301707ede05Anatolij Gustschin dev_warn(fep->dev, "FEC timeout on graceful transmit stop\n"); 38048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* 3819b8ee8e7d6b7f2270b19b3425a393d918fe497d3Vitaly Bordug * Disable FEC. Let only MII interrupts. 38248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou */ 38348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, imask, 0); 38448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN); 38548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 38648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou fs_cleanup_bds(dev); 38748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 38848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* shut down FEC1? that's where the mii bus is */ 3895b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug if (fpi->has_phy) { 390ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov FS(fecp, r_cntrl, fpi->use_rmii ? 391ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov FEC_RCNTRL_RMII_MODE : 392ba568335b089e0a27829e3a6117a7e1bf957ad07Vladimir Ermakov FEC_RCNTRL_MII_MODE); /* MII/RMII enable */ 39348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 39448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ievent, FEC_ENET_MII); 3955b4b8454344a0391bb0f69fda0f4ec8e1f0d2fedVitaly Bordug FW(fecp, mii_speed, feci->mii_speed); 39648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou } 39748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 39848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 39948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void napi_clear_rx_event(struct net_device *dev) 40048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 40148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 40260ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 40348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 40448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); 40548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 40648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 40748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void napi_enable_rx(struct net_device *dev) 40848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 40948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 41060ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 41148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 41248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 41348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 41448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 41548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void napi_disable_rx(struct net_device *dev) 41648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 41748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 41860ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 41948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 42048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 42148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 42248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 423d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophestatic void napi_clear_tx_event(struct net_device *dev) 424d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe{ 425d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fs_enet_private *fep = netdev_priv(dev); 426d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fec __iomem *fecp = fep->fec.fecp; 427d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 428d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe FW(fecp, ievent, FEC_NAPI_TX_EVENT_MSK); 429d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe} 430d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 431d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophestatic void napi_enable_tx(struct net_device *dev) 432d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe{ 433d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fs_enet_private *fep = netdev_priv(dev); 434d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fec __iomem *fecp = fep->fec.fecp; 435d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 436d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe FS(fecp, imask, FEC_NAPI_TX_EVENT_MSK); 437d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe} 438d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 439d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophestatic void napi_disable_tx(struct net_device *dev) 440d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe{ 441d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fs_enet_private *fep = netdev_priv(dev); 442d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe struct fec __iomem *fecp = fep->fec.fecp; 443d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 444d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe FC(fecp, imask, FEC_NAPI_TX_EVENT_MSK); 445d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe} 446d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe 44748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void rx_bd_done(struct net_device *dev) 44848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 44948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 45060ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 45148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 45248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, r_des_active, 0x01000000); 45348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 45448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 45548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void tx_kickstart(struct net_device *dev) 45648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 45748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 45860ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 45948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 46048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, x_des_active, 0x01000000); 46148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 46248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 46348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic u32 get_int_events(struct net_device *dev) 46448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 46548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 46660ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 46748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 46848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return FR(fecp, ievent) & FR(fecp, imask); 46948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 47048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 47148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void clear_int_events(struct net_device *dev, u32 int_events) 47248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 47348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 47460ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin struct fec __iomem *fecp = fep->fec.fecp; 47548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 47648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou FW(fecp, ievent, int_events); 47748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 47848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 47948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antonioustatic void ev_error(struct net_device *dev, u32 int_events) 48048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 481fcb6a1c83e48c30ff99624e9c46ce301707ede05Anatolij Gustschin struct fs_enet_private *fep = netdev_priv(dev); 482fcb6a1c83e48c30ff99624e9c46ce301707ede05Anatolij Gustschin 483fcb6a1c83e48c30ff99624e9c46ce301707ede05Anatolij Gustschin dev_warn(fep->dev, "FEC ERROR(s) 0x%x\n", int_events); 48448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 48548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 48631a5bb04d59931eb4657826213a439d37d12d4a9Scott Woodstatic int get_regs(struct net_device *dev, void *p, int *sizep) 48748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 48848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou struct fs_enet_private *fep = netdev_priv(dev); 48948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 49060ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin if (*sizep < sizeof(struct fec)) 49148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return -EINVAL; 49248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 49360ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin memcpy_fromio(p, fep->fec.fecp, sizeof(struct fec)); 49448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 49548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou return 0; 49648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 49748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 49831a5bb04d59931eb4657826213a439d37d12d4a9Scott Woodstatic int get_regs_len(struct net_device *dev) 49948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 50060ab4361adc188fb47da1c4892cc7a2bb621efefAnatolij Gustschin return sizeof(struct fec); 50148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 50248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 50331a5bb04d59931eb4657826213a439d37d12d4a9Scott Woodstatic void tx_restart(struct net_device *dev) 50448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou{ 50548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou /* nothing */ 50648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou} 50748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 50848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou/*************************************************************************/ 50948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 51048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniouconst struct fs_ops fs_fec_ops = { 51148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .setup_data = setup_data, 51248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .cleanup_data = cleanup_data, 51348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .set_multicast_list = set_multicast_list, 51448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .restart = restart, 51548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .stop = stop, 51648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .napi_clear_rx_event = napi_clear_rx_event, 51748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .napi_enable_rx = napi_enable_rx, 51848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .napi_disable_rx = napi_disable_rx, 519d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe .napi_clear_tx_event = napi_clear_tx_event, 520d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe .napi_enable_tx = napi_enable_tx, 521d43a396af0f54740c4f491a066d249b7d7467593LEROY Christophe .napi_disable_tx = napi_disable_tx, 52248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .rx_bd_done = rx_bd_done, 52348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .tx_kickstart = tx_kickstart, 52448257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .get_int_events = get_int_events, 52548257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .clear_int_events = clear_int_events, 52648257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .ev_error = ev_error, 52748257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .get_regs = get_regs, 52848257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .get_regs_len = get_regs_len, 52948257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .tx_restart = tx_restart, 53048257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .allocate_bd = allocate_bd, 53148257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou .free_bd = free_bd, 53248257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou}; 53348257c4f168e5d040394aeca4d37b59f68e0d36bPantelis Antoniou 534