1 |
62 |
marcus.erl |
/*
|
2 |
|
|
* Driver for Marvell Discovery (MV643XX) and Marvell Orion ethernet ports
|
3 |
|
|
* Copyright (C) 2002 Matthew Dharm <mdharm@momenco.com>
|
4 |
|
|
*
|
5 |
|
|
* Based on the 64360 driver from:
|
6 |
|
|
* Copyright (C) 2002 rabeeh@galileo.co.il
|
7 |
|
|
*
|
8 |
|
|
* Copyright (C) 2003 PMC-Sierra, Inc.,
|
9 |
|
|
* written by Manish Lachwani
|
10 |
|
|
*
|
11 |
|
|
* Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
|
12 |
|
|
*
|
13 |
|
|
* Copyright (C) 2004-2006 MontaVista Software, Inc.
|
14 |
|
|
* Dale Farnsworth <dale@farnsworth.org>
|
15 |
|
|
*
|
16 |
|
|
* Copyright (C) 2004 Steven J. Hill <sjhill1@rockwellcollins.com>
|
17 |
|
|
* <sjhill@realitydiluted.com>
|
18 |
|
|
*
|
19 |
|
|
* This program is free software; you can redistribute it and/or
|
20 |
|
|
* modify it under the terms of the GNU General Public License
|
21 |
|
|
* as published by the Free Software Foundation; either version 2
|
22 |
|
|
* of the License, or (at your option) any later version.
|
23 |
|
|
*
|
24 |
|
|
* This program is distributed in the hope that it will be useful,
|
25 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
26 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
27 |
|
|
* GNU General Public License for more details.
|
28 |
|
|
*
|
29 |
|
|
* You should have received a copy of the GNU General Public License
|
30 |
|
|
* along with this program; if not, write to the Free Software
|
31 |
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
32 |
|
|
*/
|
33 |
|
|
#include <linux/init.h>
|
34 |
|
|
#include <linux/dma-mapping.h>
|
35 |
|
|
#include <linux/in.h>
|
36 |
|
|
#include <linux/ip.h>
|
37 |
|
|
#include <linux/tcp.h>
|
38 |
|
|
#include <linux/udp.h>
|
39 |
|
|
#include <linux/etherdevice.h>
|
40 |
|
|
|
41 |
|
|
#include <linux/bitops.h>
|
42 |
|
|
#include <linux/delay.h>
|
43 |
|
|
#include <linux/ethtool.h>
|
44 |
|
|
#include <linux/platform_device.h>
|
45 |
|
|
|
46 |
|
|
#include <linux/module.h>
|
47 |
|
|
#include <linux/kernel.h>
|
48 |
|
|
#include <linux/spinlock.h>
|
49 |
|
|
#include <linux/workqueue.h>
|
50 |
|
|
#include <linux/mii.h>
|
51 |
|
|
|
52 |
|
|
#include <linux/mv643xx_eth.h>
|
53 |
|
|
|
54 |
|
|
#include <asm/io.h>
|
55 |
|
|
#include <asm/types.h>
|
56 |
|
|
#include <asm/pgtable.h>
|
57 |
|
|
#include <asm/system.h>
|
58 |
|
|
#include <asm/delay.h>
|
59 |
|
|
#include <asm/dma-mapping.h>
|
60 |
|
|
|
61 |
|
|
#define MV643XX_CHECKSUM_OFFLOAD_TX
|
62 |
|
|
#define MV643XX_NAPI
|
63 |
|
|
#define MV643XX_TX_FAST_REFILL
|
64 |
|
|
#undef MV643XX_COAL
|
65 |
|
|
|
66 |
|
|
/*
|
67 |
|
|
* Number of RX / TX descriptors on RX / TX rings.
|
68 |
|
|
* Note that allocating RX descriptors is done by allocating the RX
|
69 |
|
|
* ring AND a preallocated RX buffers (skb's) for each descriptor.
|
70 |
|
|
* The TX descriptors only allocates the TX descriptors ring,
|
71 |
|
|
* with no pre allocated TX buffers (skb's are allocated by higher layers.
|
72 |
|
|
*/
|
73 |
|
|
|
74 |
|
|
/* Default TX ring size is 1000 descriptors */
|
75 |
|
|
#define MV643XX_DEFAULT_TX_QUEUE_SIZE 1000
|
76 |
|
|
|
77 |
|
|
/* Default RX ring size is 400 descriptors */
|
78 |
|
|
#define MV643XX_DEFAULT_RX_QUEUE_SIZE 400
|
79 |
|
|
|
80 |
|
|
#define MV643XX_TX_COAL 100
|
81 |
|
|
#ifdef MV643XX_COAL
|
82 |
|
|
#define MV643XX_RX_COAL 100
|
83 |
|
|
#endif
|
84 |
|
|
|
85 |
|
|
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
86 |
|
|
#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
|
87 |
|
|
#else
|
88 |
|
|
#define MAX_DESCS_PER_SKB 1
|
89 |
|
|
#endif
|
90 |
|
|
|
91 |
|
|
#define ETH_VLAN_HLEN 4
|
92 |
|
|
#define ETH_FCS_LEN 4
|
93 |
|
|
#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */
|
94 |
|
|
#define ETH_WRAPPER_LEN (ETH_HW_IP_ALIGN + ETH_HLEN + \
|
95 |
|
|
ETH_VLAN_HLEN + ETH_FCS_LEN)
|
96 |
|
|
#define ETH_RX_SKB_SIZE (dev->mtu + ETH_WRAPPER_LEN + \
|
97 |
|
|
dma_get_cache_alignment())
|
98 |
|
|
|
99 |
|
|
/*
|
100 |
|
|
* Registers shared between all ports.
|
101 |
|
|
*/
|
102 |
|
|
#define PHY_ADDR_REG 0x0000
|
103 |
|
|
#define SMI_REG 0x0004
|
104 |
|
|
|
105 |
|
|
/*
|
106 |
|
|
* Per-port registers.
|
107 |
|
|
*/
|
108 |
|
|
#define PORT_CONFIG_REG(p) (0x0400 + ((p) << 10))
|
109 |
|
|
#define PORT_CONFIG_EXTEND_REG(p) (0x0404 + ((p) << 10))
|
110 |
|
|
#define MAC_ADDR_LOW(p) (0x0414 + ((p) << 10))
|
111 |
|
|
#define MAC_ADDR_HIGH(p) (0x0418 + ((p) << 10))
|
112 |
|
|
#define SDMA_CONFIG_REG(p) (0x041c + ((p) << 10))
|
113 |
|
|
#define PORT_SERIAL_CONTROL_REG(p) (0x043c + ((p) << 10))
|
114 |
|
|
#define PORT_STATUS_REG(p) (0x0444 + ((p) << 10))
|
115 |
|
|
#define TRANSMIT_QUEUE_COMMAND_REG(p) (0x0448 + ((p) << 10))
|
116 |
|
|
#define MAXIMUM_TRANSMIT_UNIT(p) (0x0458 + ((p) << 10))
|
117 |
|
|
#define INTERRUPT_CAUSE_REG(p) (0x0460 + ((p) << 10))
|
118 |
|
|
#define INTERRUPT_CAUSE_EXTEND_REG(p) (0x0464 + ((p) << 10))
|
119 |
|
|
#define INTERRUPT_MASK_REG(p) (0x0468 + ((p) << 10))
|
120 |
|
|
#define INTERRUPT_EXTEND_MASK_REG(p) (0x046c + ((p) << 10))
|
121 |
|
|
#define TX_FIFO_URGENT_THRESHOLD_REG(p) (0x0474 + ((p) << 10))
|
122 |
|
|
#define RX_CURRENT_QUEUE_DESC_PTR_0(p) (0x060c + ((p) << 10))
|
123 |
|
|
#define RECEIVE_QUEUE_COMMAND_REG(p) (0x0680 + ((p) << 10))
|
124 |
|
|
#define TX_CURRENT_QUEUE_DESC_PTR_0(p) (0x06c0 + ((p) << 10))
|
125 |
|
|
#define MIB_COUNTERS_BASE(p) (0x1000 + ((p) << 7))
|
126 |
|
|
#define DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(p) (0x1400 + ((p) << 10))
|
127 |
|
|
#define DA_FILTER_OTHER_MULTICAST_TABLE_BASE(p) (0x1500 + ((p) << 10))
|
128 |
|
|
#define DA_FILTER_UNICAST_TABLE_BASE(p) (0x1600 + ((p) << 10))
|
129 |
|
|
|
130 |
|
|
/* These macros describe Ethernet Port configuration reg (Px_cR) bits */
|
131 |
|
|
#define UNICAST_NORMAL_MODE (0 << 0)
|
132 |
|
|
#define UNICAST_PROMISCUOUS_MODE (1 << 0)
|
133 |
|
|
#define DEFAULT_RX_QUEUE(queue) ((queue) << 1)
|
134 |
|
|
#define DEFAULT_RX_ARP_QUEUE(queue) ((queue) << 4)
|
135 |
|
|
#define RECEIVE_BC_IF_NOT_IP_OR_ARP (0 << 7)
|
136 |
|
|
#define REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7)
|
137 |
|
|
#define RECEIVE_BC_IF_IP (0 << 8)
|
138 |
|
|
#define REJECT_BC_IF_IP (1 << 8)
|
139 |
|
|
#define RECEIVE_BC_IF_ARP (0 << 9)
|
140 |
|
|
#define REJECT_BC_IF_ARP (1 << 9)
|
141 |
|
|
#define TX_AM_NO_UPDATE_ERROR_SUMMARY (1 << 12)
|
142 |
|
|
#define CAPTURE_TCP_FRAMES_DIS (0 << 14)
|
143 |
|
|
#define CAPTURE_TCP_FRAMES_EN (1 << 14)
|
144 |
|
|
#define CAPTURE_UDP_FRAMES_DIS (0 << 15)
|
145 |
|
|
#define CAPTURE_UDP_FRAMES_EN (1 << 15)
|
146 |
|
|
#define DEFAULT_RX_TCP_QUEUE(queue) ((queue) << 16)
|
147 |
|
|
#define DEFAULT_RX_UDP_QUEUE(queue) ((queue) << 19)
|
148 |
|
|
#define DEFAULT_RX_BPDU_QUEUE(queue) ((queue) << 22)
|
149 |
|
|
|
150 |
|
|
#define PORT_CONFIG_DEFAULT_VALUE \
|
151 |
|
|
UNICAST_NORMAL_MODE | \
|
152 |
|
|
DEFAULT_RX_QUEUE(0) | \
|
153 |
|
|
DEFAULT_RX_ARP_QUEUE(0) | \
|
154 |
|
|
RECEIVE_BC_IF_NOT_IP_OR_ARP | \
|
155 |
|
|
RECEIVE_BC_IF_IP | \
|
156 |
|
|
RECEIVE_BC_IF_ARP | \
|
157 |
|
|
CAPTURE_TCP_FRAMES_DIS | \
|
158 |
|
|
CAPTURE_UDP_FRAMES_DIS | \
|
159 |
|
|
DEFAULT_RX_TCP_QUEUE(0) | \
|
160 |
|
|
DEFAULT_RX_UDP_QUEUE(0) | \
|
161 |
|
|
DEFAULT_RX_BPDU_QUEUE(0)
|
162 |
|
|
|
163 |
|
|
/* These macros describe Ethernet Port configuration extend reg (Px_cXR) bits*/
|
164 |
|
|
#define CLASSIFY_EN (1 << 0)
|
165 |
|
|
#define SPAN_BPDU_PACKETS_AS_NORMAL (0 << 1)
|
166 |
|
|
#define SPAN_BPDU_PACKETS_TO_RX_QUEUE_7 (1 << 1)
|
167 |
|
|
#define PARTITION_DISABLE (0 << 2)
|
168 |
|
|
#define PARTITION_ENABLE (1 << 2)
|
169 |
|
|
|
170 |
|
|
#define PORT_CONFIG_EXTEND_DEFAULT_VALUE \
|
171 |
|
|
SPAN_BPDU_PACKETS_AS_NORMAL | \
|
172 |
|
|
PARTITION_DISABLE
|
173 |
|
|
|
174 |
|
|
/* These macros describe Ethernet Port Sdma configuration reg (SDCR) bits */
|
175 |
|
|
#define RIFB (1 << 0)
|
176 |
|
|
#define RX_BURST_SIZE_1_64BIT (0 << 1)
|
177 |
|
|
#define RX_BURST_SIZE_2_64BIT (1 << 1)
|
178 |
|
|
#define RX_BURST_SIZE_4_64BIT (2 << 1)
|
179 |
|
|
#define RX_BURST_SIZE_8_64BIT (3 << 1)
|
180 |
|
|
#define RX_BURST_SIZE_16_64BIT (4 << 1)
|
181 |
|
|
#define BLM_RX_NO_SWAP (1 << 4)
|
182 |
|
|
#define BLM_RX_BYTE_SWAP (0 << 4)
|
183 |
|
|
#define BLM_TX_NO_SWAP (1 << 5)
|
184 |
|
|
#define BLM_TX_BYTE_SWAP (0 << 5)
|
185 |
|
|
#define DESCRIPTORS_BYTE_SWAP (1 << 6)
|
186 |
|
|
#define DESCRIPTORS_NO_SWAP (0 << 6)
|
187 |
|
|
#define IPG_INT_RX(value) (((value) & 0x3fff) << 8)
|
188 |
|
|
#define TX_BURST_SIZE_1_64BIT (0 << 22)
|
189 |
|
|
#define TX_BURST_SIZE_2_64BIT (1 << 22)
|
190 |
|
|
#define TX_BURST_SIZE_4_64BIT (2 << 22)
|
191 |
|
|
#define TX_BURST_SIZE_8_64BIT (3 << 22)
|
192 |
|
|
#define TX_BURST_SIZE_16_64BIT (4 << 22)
|
193 |
|
|
|
194 |
|
|
#if defined(__BIG_ENDIAN)
|
195 |
|
|
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
|
196 |
|
|
RX_BURST_SIZE_4_64BIT | \
|
197 |
|
|
IPG_INT_RX(0) | \
|
198 |
|
|
TX_BURST_SIZE_4_64BIT
|
199 |
|
|
#elif defined(__LITTLE_ENDIAN)
|
200 |
|
|
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
|
201 |
|
|
RX_BURST_SIZE_4_64BIT | \
|
202 |
|
|
BLM_RX_NO_SWAP | \
|
203 |
|
|
BLM_TX_NO_SWAP | \
|
204 |
|
|
IPG_INT_RX(0) | \
|
205 |
|
|
TX_BURST_SIZE_4_64BIT
|
206 |
|
|
#else
|
207 |
|
|
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
|
208 |
|
|
#endif
|
209 |
|
|
|
210 |
|
|
/* These macros describe Ethernet Port serial control reg (PSCR) bits */
|
211 |
|
|
#define SERIAL_PORT_DISABLE (0 << 0)
|
212 |
|
|
#define SERIAL_PORT_ENABLE (1 << 0)
|
213 |
|
|
#define DO_NOT_FORCE_LINK_PASS (0 << 1)
|
214 |
|
|
#define FORCE_LINK_PASS (1 << 1)
|
215 |
|
|
#define ENABLE_AUTO_NEG_FOR_DUPLX (0 << 2)
|
216 |
|
|
#define DISABLE_AUTO_NEG_FOR_DUPLX (1 << 2)
|
217 |
|
|
#define ENABLE_AUTO_NEG_FOR_FLOW_CTRL (0 << 3)
|
218 |
|
|
#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL (1 << 3)
|
219 |
|
|
#define ADV_NO_FLOW_CTRL (0 << 4)
|
220 |
|
|
#define ADV_SYMMETRIC_FLOW_CTRL (1 << 4)
|
221 |
|
|
#define FORCE_FC_MODE_NO_PAUSE_DIS_TX (0 << 5)
|
222 |
|
|
#define FORCE_FC_MODE_TX_PAUSE_DIS (1 << 5)
|
223 |
|
|
#define FORCE_BP_MODE_NO_JAM (0 << 7)
|
224 |
|
|
#define FORCE_BP_MODE_JAM_TX (1 << 7)
|
225 |
|
|
#define FORCE_BP_MODE_JAM_TX_ON_RX_ERR (2 << 7)
|
226 |
|
|
#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
|
227 |
|
|
#define FORCE_LINK_FAIL (0 << 10)
|
228 |
|
|
#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
|
229 |
|
|
#define RETRANSMIT_16_ATTEMPTS (0 << 11)
|
230 |
|
|
#define RETRANSMIT_FOREVER (1 << 11)
|
231 |
|
|
#define ENABLE_AUTO_NEG_SPEED_GMII (0 << 13)
|
232 |
|
|
#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
|
233 |
|
|
#define DTE_ADV_0 (0 << 14)
|
234 |
|
|
#define DTE_ADV_1 (1 << 14)
|
235 |
|
|
#define DISABLE_AUTO_NEG_BYPASS (0 << 15)
|
236 |
|
|
#define ENABLE_AUTO_NEG_BYPASS (1 << 15)
|
237 |
|
|
#define AUTO_NEG_NO_CHANGE (0 << 16)
|
238 |
|
|
#define RESTART_AUTO_NEG (1 << 16)
|
239 |
|
|
#define MAX_RX_PACKET_1518BYTE (0 << 17)
|
240 |
|
|
#define MAX_RX_PACKET_1522BYTE (1 << 17)
|
241 |
|
|
#define MAX_RX_PACKET_1552BYTE (2 << 17)
|
242 |
|
|
#define MAX_RX_PACKET_9022BYTE (3 << 17)
|
243 |
|
|
#define MAX_RX_PACKET_9192BYTE (4 << 17)
|
244 |
|
|
#define MAX_RX_PACKET_9700BYTE (5 << 17)
|
245 |
|
|
#define MAX_RX_PACKET_MASK (7 << 17)
|
246 |
|
|
#define CLR_EXT_LOOPBACK (0 << 20)
|
247 |
|
|
#define SET_EXT_LOOPBACK (1 << 20)
|
248 |
|
|
#define SET_HALF_DUPLEX_MODE (0 << 21)
|
249 |
|
|
#define SET_FULL_DUPLEX_MODE (1 << 21)
|
250 |
|
|
#define DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (0 << 22)
|
251 |
|
|
#define ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1 << 22)
|
252 |
|
|
#define SET_GMII_SPEED_TO_10_100 (0 << 23)
|
253 |
|
|
#define SET_GMII_SPEED_TO_1000 (1 << 23)
|
254 |
|
|
#define SET_MII_SPEED_TO_10 (0 << 24)
|
255 |
|
|
#define SET_MII_SPEED_TO_100 (1 << 24)
|
256 |
|
|
|
257 |
|
|
#define PORT_SERIAL_CONTROL_DEFAULT_VALUE \
|
258 |
|
|
DO_NOT_FORCE_LINK_PASS | \
|
259 |
|
|
ENABLE_AUTO_NEG_FOR_DUPLX | \
|
260 |
|
|
DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
|
261 |
|
|
ADV_SYMMETRIC_FLOW_CTRL | \
|
262 |
|
|
FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
|
263 |
|
|
FORCE_BP_MODE_NO_JAM | \
|
264 |
|
|
(1 << 9) /* reserved */ | \
|
265 |
|
|
DO_NOT_FORCE_LINK_FAIL | \
|
266 |
|
|
RETRANSMIT_16_ATTEMPTS | \
|
267 |
|
|
ENABLE_AUTO_NEG_SPEED_GMII | \
|
268 |
|
|
DTE_ADV_0 | \
|
269 |
|
|
DISABLE_AUTO_NEG_BYPASS | \
|
270 |
|
|
AUTO_NEG_NO_CHANGE | \
|
271 |
|
|
MAX_RX_PACKET_9700BYTE | \
|
272 |
|
|
CLR_EXT_LOOPBACK | \
|
273 |
|
|
SET_FULL_DUPLEX_MODE | \
|
274 |
|
|
ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
|
275 |
|
|
|
276 |
|
|
/* These macros describe Ethernet Serial Status reg (PSR) bits */
|
277 |
|
|
#define PORT_STATUS_MODE_10_BIT (1 << 0)
|
278 |
|
|
#define PORT_STATUS_LINK_UP (1 << 1)
|
279 |
|
|
#define PORT_STATUS_FULL_DUPLEX (1 << 2)
|
280 |
|
|
#define PORT_STATUS_FLOW_CONTROL (1 << 3)
|
281 |
|
|
#define PORT_STATUS_GMII_1000 (1 << 4)
|
282 |
|
|
#define PORT_STATUS_MII_100 (1 << 5)
|
283 |
|
|
/* PSR bit 6 is undocumented */
|
284 |
|
|
#define PORT_STATUS_TX_IN_PROGRESS (1 << 7)
|
285 |
|
|
#define PORT_STATUS_AUTONEG_BYPASSED (1 << 8)
|
286 |
|
|
#define PORT_STATUS_PARTITION (1 << 9)
|
287 |
|
|
#define PORT_STATUS_TX_FIFO_EMPTY (1 << 10)
|
288 |
|
|
/* PSR bits 11-31 are reserved */
|
289 |
|
|
|
290 |
|
|
#define PORT_DEFAULT_TRANSMIT_QUEUE_SIZE 800
|
291 |
|
|
#define PORT_DEFAULT_RECEIVE_QUEUE_SIZE 400
|
292 |
|
|
|
293 |
|
|
#define DESC_SIZE 64
|
294 |
|
|
|
295 |
|
|
#define ETH_RX_QUEUES_ENABLED (1 << 0) /* use only Q0 for receive */
|
296 |
|
|
#define ETH_TX_QUEUES_ENABLED (1 << 0) /* use only Q0 for transmit */
|
297 |
|
|
|
298 |
|
|
#define ETH_INT_CAUSE_RX_DONE (ETH_RX_QUEUES_ENABLED << 2)
|
299 |
|
|
#define ETH_INT_CAUSE_RX_ERROR (ETH_RX_QUEUES_ENABLED << 9)
|
300 |
|
|
#define ETH_INT_CAUSE_RX (ETH_INT_CAUSE_RX_DONE | ETH_INT_CAUSE_RX_ERROR)
|
301 |
|
|
#define ETH_INT_CAUSE_EXT 0x00000002
|
302 |
|
|
#define ETH_INT_UNMASK_ALL (ETH_INT_CAUSE_RX | ETH_INT_CAUSE_EXT)
|
303 |
|
|
|
304 |
|
|
#define ETH_INT_CAUSE_TX_DONE (ETH_TX_QUEUES_ENABLED << 0)
|
305 |
|
|
#define ETH_INT_CAUSE_TX_ERROR (ETH_TX_QUEUES_ENABLED << 8)
|
306 |
|
|
#define ETH_INT_CAUSE_TX (ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
|
307 |
|
|
#define ETH_INT_CAUSE_PHY 0x00010000
|
308 |
|
|
#define ETH_INT_CAUSE_STATE 0x00100000
|
309 |
|
|
#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
|
310 |
|
|
ETH_INT_CAUSE_STATE)
|
311 |
|
|
|
312 |
|
|
#define ETH_INT_MASK_ALL 0x00000000
|
313 |
|
|
#define ETH_INT_MASK_ALL_EXT 0x00000000
|
314 |
|
|
|
315 |
|
|
#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */
|
316 |
|
|
#define PHY_WAIT_MICRO_SECONDS 10
|
317 |
|
|
|
318 |
|
|
/* Buffer offset from buffer pointer */
|
319 |
|
|
#define RX_BUF_OFFSET 0x2
|
320 |
|
|
|
321 |
|
|
/* Gigabit Ethernet Unit Global Registers */
|
322 |
|
|
|
323 |
|
|
/* MIB Counters register definitions */
|
324 |
|
|
#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
|
325 |
|
|
#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
|
326 |
|
|
#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
|
327 |
|
|
#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
|
328 |
|
|
#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
|
329 |
|
|
#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
|
330 |
|
|
#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
|
331 |
|
|
#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
|
332 |
|
|
#define ETH_MIB_FRAMES_64_OCTETS 0x20
|
333 |
|
|
#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
|
334 |
|
|
#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
|
335 |
|
|
#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
|
336 |
|
|
#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
|
337 |
|
|
#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
|
338 |
|
|
#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
|
339 |
|
|
#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
|
340 |
|
|
#define ETH_MIB_GOOD_FRAMES_SENT 0x40
|
341 |
|
|
#define ETH_MIB_EXCESSIVE_COLLISION 0x44
|
342 |
|
|
#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
|
343 |
|
|
#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
|
344 |
|
|
#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
|
345 |
|
|
#define ETH_MIB_FC_SENT 0x54
|
346 |
|
|
#define ETH_MIB_GOOD_FC_RECEIVED 0x58
|
347 |
|
|
#define ETH_MIB_BAD_FC_RECEIVED 0x5c
|
348 |
|
|
#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
|
349 |
|
|
#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
|
350 |
|
|
#define ETH_MIB_OVERSIZE_RECEIVED 0x68
|
351 |
|
|
#define ETH_MIB_JABBER_RECEIVED 0x6c
|
352 |
|
|
#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
|
353 |
|
|
#define ETH_MIB_BAD_CRC_EVENT 0x74
|
354 |
|
|
#define ETH_MIB_COLLISION 0x78
|
355 |
|
|
#define ETH_MIB_LATE_COLLISION 0x7c
|
356 |
|
|
|
357 |
|
|
/* Port serial status reg (PSR) */
|
358 |
|
|
#define ETH_INTERFACE_PCM 0x00000001
|
359 |
|
|
#define ETH_LINK_IS_UP 0x00000002
|
360 |
|
|
#define ETH_PORT_AT_FULL_DUPLEX 0x00000004
|
361 |
|
|
#define ETH_RX_FLOW_CTRL_ENABLED 0x00000008
|
362 |
|
|
#define ETH_GMII_SPEED_1000 0x00000010
|
363 |
|
|
#define ETH_MII_SPEED_100 0x00000020
|
364 |
|
|
#define ETH_TX_IN_PROGRESS 0x00000080
|
365 |
|
|
#define ETH_BYPASS_ACTIVE 0x00000100
|
366 |
|
|
#define ETH_PORT_AT_PARTITION_STATE 0x00000200
|
367 |
|
|
#define ETH_PORT_TX_FIFO_EMPTY 0x00000400
|
368 |
|
|
|
369 |
|
|
/* SMI reg */
|
370 |
|
|
#define ETH_SMI_BUSY 0x10000000 /* 0 - Write, 1 - Read */
|
371 |
|
|
#define ETH_SMI_READ_VALID 0x08000000 /* 0 - Write, 1 - Read */
|
372 |
|
|
#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read */
|
373 |
|
|
#define ETH_SMI_OPCODE_READ 0x04000000 /* Operation is in progress */
|
374 |
|
|
|
375 |
|
|
/* Interrupt Cause Register Bit Definitions */
|
376 |
|
|
|
377 |
|
|
/* SDMA command status fields macros */
|
378 |
|
|
|
379 |
|
|
/* Tx & Rx descriptors status */
|
380 |
|
|
#define ETH_ERROR_SUMMARY 0x00000001
|
381 |
|
|
|
382 |
|
|
/* Tx & Rx descriptors command */
|
383 |
|
|
#define ETH_BUFFER_OWNED_BY_DMA 0x80000000
|
384 |
|
|
|
385 |
|
|
/* Tx descriptors status */
|
386 |
|
|
#define ETH_LC_ERROR 0
|
387 |
|
|
#define ETH_UR_ERROR 0x00000002
|
388 |
|
|
#define ETH_RL_ERROR 0x00000004
|
389 |
|
|
#define ETH_LLC_SNAP_FORMAT 0x00000200
|
390 |
|
|
|
391 |
|
|
/* Rx descriptors status */
|
392 |
|
|
#define ETH_OVERRUN_ERROR 0x00000002
|
393 |
|
|
#define ETH_MAX_FRAME_LENGTH_ERROR 0x00000004
|
394 |
|
|
#define ETH_RESOURCE_ERROR 0x00000006
|
395 |
|
|
#define ETH_VLAN_TAGGED 0x00080000
|
396 |
|
|
#define ETH_BPDU_FRAME 0x00100000
|
397 |
|
|
#define ETH_UDP_FRAME_OVER_IP_V_4 0x00200000
|
398 |
|
|
#define ETH_OTHER_FRAME_TYPE 0x00400000
|
399 |
|
|
#define ETH_LAYER_2_IS_ETH_V_2 0x00800000
|
400 |
|
|
#define ETH_FRAME_TYPE_IP_V_4 0x01000000
|
401 |
|
|
#define ETH_FRAME_HEADER_OK 0x02000000
|
402 |
|
|
#define ETH_RX_LAST_DESC 0x04000000
|
403 |
|
|
#define ETH_RX_FIRST_DESC 0x08000000
|
404 |
|
|
#define ETH_UNKNOWN_DESTINATION_ADDR 0x10000000
|
405 |
|
|
#define ETH_RX_ENABLE_INTERRUPT 0x20000000
|
406 |
|
|
#define ETH_LAYER_4_CHECKSUM_OK 0x40000000
|
407 |
|
|
|
408 |
|
|
/* Rx descriptors byte count */
|
409 |
|
|
#define ETH_FRAME_FRAGMENTED 0x00000004
|
410 |
|
|
|
411 |
|
|
/* Tx descriptors command */
|
412 |
|
|
#define ETH_LAYER_4_CHECKSUM_FIRST_DESC 0x00000400
|
413 |
|
|
#define ETH_FRAME_SET_TO_VLAN 0x00008000
|
414 |
|
|
#define ETH_UDP_FRAME 0x00010000
|
415 |
|
|
#define ETH_GEN_TCP_UDP_CHECKSUM 0x00020000
|
416 |
|
|
#define ETH_GEN_IP_V_4_CHECKSUM 0x00040000
|
417 |
|
|
#define ETH_ZERO_PADDING 0x00080000
|
418 |
|
|
#define ETH_TX_LAST_DESC 0x00100000
|
419 |
|
|
#define ETH_TX_FIRST_DESC 0x00200000
|
420 |
|
|
#define ETH_GEN_CRC 0x00400000
|
421 |
|
|
#define ETH_TX_ENABLE_INTERRUPT 0x00800000
|
422 |
|
|
#define ETH_AUTO_MODE 0x40000000
|
423 |
|
|
|
424 |
|
|
#define ETH_TX_IHL_SHIFT 11
|
425 |
|
|
|
426 |
|
|
/* typedefs */
|
427 |
|
|
|
428 |
|
|
typedef enum _eth_func_ret_status {
|
429 |
|
|
ETH_OK, /* Returned as expected. */
|
430 |
|
|
ETH_ERROR, /* Fundamental error. */
|
431 |
|
|
ETH_RETRY, /* Could not process request. Try later.*/
|
432 |
|
|
ETH_END_OF_JOB, /* Ring has nothing to process. */
|
433 |
|
|
ETH_QUEUE_FULL, /* Ring resource error. */
|
434 |
|
|
ETH_QUEUE_LAST_RESOURCE /* Ring resources about to exhaust. */
|
435 |
|
|
} ETH_FUNC_RET_STATUS;
|
436 |
|
|
|
437 |
|
|
typedef enum _eth_target {
|
438 |
|
|
ETH_TARGET_DRAM,
|
439 |
|
|
ETH_TARGET_DEVICE,
|
440 |
|
|
ETH_TARGET_CBS,
|
441 |
|
|
ETH_TARGET_PCI0,
|
442 |
|
|
ETH_TARGET_PCI1
|
443 |
|
|
} ETH_TARGET;
|
444 |
|
|
|
445 |
|
|
/* These are for big-endian machines. Little endian needs different
|
446 |
|
|
* definitions.
|
447 |
|
|
*/
|
448 |
|
|
#if defined(__BIG_ENDIAN)
|
449 |
|
|
struct eth_rx_desc {
|
450 |
|
|
u16 byte_cnt; /* Descriptor buffer byte count */
|
451 |
|
|
u16 buf_size; /* Buffer size */
|
452 |
|
|
u32 cmd_sts; /* Descriptor command status */
|
453 |
|
|
u32 next_desc_ptr; /* Next descriptor pointer */
|
454 |
|
|
u32 buf_ptr; /* Descriptor buffer pointer */
|
455 |
|
|
};
|
456 |
|
|
|
457 |
|
|
struct eth_tx_desc {
|
458 |
|
|
u16 byte_cnt; /* buffer byte count */
|
459 |
|
|
u16 l4i_chk; /* CPU provided TCP checksum */
|
460 |
|
|
u32 cmd_sts; /* Command/status field */
|
461 |
|
|
u32 next_desc_ptr; /* Pointer to next descriptor */
|
462 |
|
|
u32 buf_ptr; /* pointer to buffer for this descriptor*/
|
463 |
|
|
};
|
464 |
|
|
#elif defined(__LITTLE_ENDIAN)
|
465 |
|
|
struct eth_rx_desc {
|
466 |
|
|
u32 cmd_sts; /* Descriptor command status */
|
467 |
|
|
u16 buf_size; /* Buffer size */
|
468 |
|
|
u16 byte_cnt; /* Descriptor buffer byte count */
|
469 |
|
|
u32 buf_ptr; /* Descriptor buffer pointer */
|
470 |
|
|
u32 next_desc_ptr; /* Next descriptor pointer */
|
471 |
|
|
};
|
472 |
|
|
|
473 |
|
|
struct eth_tx_desc {
|
474 |
|
|
u32 cmd_sts; /* Command/status field */
|
475 |
|
|
u16 l4i_chk; /* CPU provided TCP checksum */
|
476 |
|
|
u16 byte_cnt; /* buffer byte count */
|
477 |
|
|
u32 buf_ptr; /* pointer to buffer for this descriptor*/
|
478 |
|
|
u32 next_desc_ptr; /* Pointer to next descriptor */
|
479 |
|
|
};
|
480 |
|
|
#else
|
481 |
|
|
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
|
482 |
|
|
#endif
|
483 |
|
|
|
484 |
|
|
/* Unified struct for Rx and Tx operations. The user is not required to */
|
485 |
|
|
/* be familier with neither Tx nor Rx descriptors. */
|
486 |
|
|
struct pkt_info {
|
487 |
|
|
unsigned short byte_cnt; /* Descriptor buffer byte count */
|
488 |
|
|
unsigned short l4i_chk; /* Tx CPU provided TCP Checksum */
|
489 |
|
|
unsigned int cmd_sts; /* Descriptor command status */
|
490 |
|
|
dma_addr_t buf_ptr; /* Descriptor buffer pointer */
|
491 |
|
|
struct sk_buff *return_info; /* User resource return information */
|
492 |
|
|
};
|
493 |
|
|
|
494 |
|
|
/* Ethernet port specific information */
|
495 |
|
|
struct mv643xx_mib_counters {
|
496 |
|
|
u64 good_octets_received;
|
497 |
|
|
u32 bad_octets_received;
|
498 |
|
|
u32 internal_mac_transmit_err;
|
499 |
|
|
u32 good_frames_received;
|
500 |
|
|
u32 bad_frames_received;
|
501 |
|
|
u32 broadcast_frames_received;
|
502 |
|
|
u32 multicast_frames_received;
|
503 |
|
|
u32 frames_64_octets;
|
504 |
|
|
u32 frames_65_to_127_octets;
|
505 |
|
|
u32 frames_128_to_255_octets;
|
506 |
|
|
u32 frames_256_to_511_octets;
|
507 |
|
|
u32 frames_512_to_1023_octets;
|
508 |
|
|
u32 frames_1024_to_max_octets;
|
509 |
|
|
u64 good_octets_sent;
|
510 |
|
|
u32 good_frames_sent;
|
511 |
|
|
u32 excessive_collision;
|
512 |
|
|
u32 multicast_frames_sent;
|
513 |
|
|
u32 broadcast_frames_sent;
|
514 |
|
|
u32 unrec_mac_control_received;
|
515 |
|
|
u32 fc_sent;
|
516 |
|
|
u32 good_fc_received;
|
517 |
|
|
u32 bad_fc_received;
|
518 |
|
|
u32 undersize_received;
|
519 |
|
|
u32 fragments_received;
|
520 |
|
|
u32 oversize_received;
|
521 |
|
|
u32 jabber_received;
|
522 |
|
|
u32 mac_receive_error;
|
523 |
|
|
u32 bad_crc_event;
|
524 |
|
|
u32 collision;
|
525 |
|
|
u32 late_collision;
|
526 |
|
|
};
|
527 |
|
|
|
528 |
|
|
struct mv643xx_private {
|
529 |
|
|
int port_num; /* User Ethernet port number */
|
530 |
|
|
|
531 |
|
|
u32 rx_sram_addr; /* Base address of rx sram area */
|
532 |
|
|
u32 rx_sram_size; /* Size of rx sram area */
|
533 |
|
|
u32 tx_sram_addr; /* Base address of tx sram area */
|
534 |
|
|
u32 tx_sram_size; /* Size of tx sram area */
|
535 |
|
|
|
536 |
|
|
int rx_resource_err; /* Rx ring resource error flag */
|
537 |
|
|
|
538 |
|
|
/* Tx/Rx rings managment indexes fields. For driver use */
|
539 |
|
|
|
540 |
|
|
/* Next available and first returning Rx resource */
|
541 |
|
|
int rx_curr_desc_q, rx_used_desc_q;
|
542 |
|
|
|
543 |
|
|
/* Next available and first returning Tx resource */
|
544 |
|
|
int tx_curr_desc_q, tx_used_desc_q;
|
545 |
|
|
|
546 |
|
|
#ifdef MV643XX_TX_FAST_REFILL
|
547 |
|
|
u32 tx_clean_threshold;
|
548 |
|
|
#endif
|
549 |
|
|
|
550 |
|
|
struct eth_rx_desc *p_rx_desc_area;
|
551 |
|
|
dma_addr_t rx_desc_dma;
|
552 |
|
|
int rx_desc_area_size;
|
553 |
|
|
struct sk_buff **rx_skb;
|
554 |
|
|
|
555 |
|
|
struct eth_tx_desc *p_tx_desc_area;
|
556 |
|
|
dma_addr_t tx_desc_dma;
|
557 |
|
|
int tx_desc_area_size;
|
558 |
|
|
struct sk_buff **tx_skb;
|
559 |
|
|
|
560 |
|
|
struct work_struct tx_timeout_task;
|
561 |
|
|
|
562 |
|
|
struct net_device *dev;
|
563 |
|
|
struct napi_struct napi;
|
564 |
|
|
struct net_device_stats stats;
|
565 |
|
|
struct mv643xx_mib_counters mib_counters;
|
566 |
|
|
spinlock_t lock;
|
567 |
|
|
/* Size of Tx Ring per queue */
|
568 |
|
|
int tx_ring_size;
|
569 |
|
|
/* Number of tx descriptors in use */
|
570 |
|
|
int tx_desc_count;
|
571 |
|
|
/* Size of Rx Ring per queue */
|
572 |
|
|
int rx_ring_size;
|
573 |
|
|
/* Number of rx descriptors in use */
|
574 |
|
|
int rx_desc_count;
|
575 |
|
|
|
576 |
|
|
/*
|
577 |
|
|
* Used in case RX Ring is empty, which can be caused when
|
578 |
|
|
* system does not have resources (skb's)
|
579 |
|
|
*/
|
580 |
|
|
struct timer_list timeout;
|
581 |
|
|
|
582 |
|
|
u32 rx_int_coal;
|
583 |
|
|
u32 tx_int_coal;
|
584 |
|
|
struct mii_if_info mii;
|
585 |
|
|
};
|
586 |
|
|
|
587 |
|
|
/* Static function declarations */
|
588 |
|
|
static void eth_port_init(struct mv643xx_private *mp);
|
589 |
|
|
static void eth_port_reset(unsigned int eth_port_num);
|
590 |
|
|
static void eth_port_start(struct net_device *dev);
|
591 |
|
|
|
592 |
|
|
static void ethernet_phy_reset(unsigned int eth_port_num);
|
593 |
|
|
|
594 |
|
|
static void eth_port_write_smi_reg(unsigned int eth_port_num,
|
595 |
|
|
unsigned int phy_reg, unsigned int value);
|
596 |
|
|
|
597 |
|
|
static void eth_port_read_smi_reg(unsigned int eth_port_num,
|
598 |
|
|
unsigned int phy_reg, unsigned int *value);
|
599 |
|
|
|
600 |
|
|
static void eth_clear_mib_counters(unsigned int eth_port_num);
|
601 |
|
|
|
602 |
|
|
static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
|
603 |
|
|
struct pkt_info *p_pkt_info);
|
604 |
|
|
static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
|
605 |
|
|
struct pkt_info *p_pkt_info);
|
606 |
|
|
|
607 |
|
|
static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr);
|
608 |
|
|
static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr);
|
609 |
|
|
static void eth_port_set_multicast_list(struct net_device *);
|
610 |
|
|
static void mv643xx_eth_port_enable_tx(unsigned int port_num,
|
611 |
|
|
unsigned int queues);
|
612 |
|
|
static void mv643xx_eth_port_enable_rx(unsigned int port_num,
|
613 |
|
|
unsigned int queues);
|
614 |
|
|
static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num);
|
615 |
|
|
static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num);
|
616 |
|
|
static int mv643xx_eth_open(struct net_device *);
|
617 |
|
|
static int mv643xx_eth_stop(struct net_device *);
|
618 |
|
|
static int mv643xx_eth_change_mtu(struct net_device *, int);
|
619 |
|
|
static void eth_port_init_mac_tables(unsigned int eth_port_num);
|
620 |
|
|
#ifdef MV643XX_NAPI
|
621 |
|
|
static int mv643xx_poll(struct napi_struct *napi, int budget);
|
622 |
|
|
#endif
|
623 |
|
|
static int ethernet_phy_get(unsigned int eth_port_num);
|
624 |
|
|
static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
|
625 |
|
|
static int ethernet_phy_detect(unsigned int eth_port_num);
|
626 |
|
|
static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
|
627 |
|
|
static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
|
628 |
|
|
static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
|
629 |
|
|
static const struct ethtool_ops mv643xx_ethtool_ops;
|
630 |
|
|
|
631 |
|
|
static char mv643xx_driver_name[] = "mv643xx_eth";
|
632 |
|
|
static char mv643xx_driver_version[] = "1.0";
|
633 |
|
|
|
634 |
|
|
static void __iomem *mv643xx_eth_base;
|
635 |
|
|
|
636 |
|
|
/* used to protect SMI_REG, which is shared across ports */
|
637 |
|
|
static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
|
638 |
|
|
|
639 |
|
|
static inline u32 mv_read(int offset)
|
640 |
|
|
{
|
641 |
|
|
return readl(mv643xx_eth_base + offset);
|
642 |
|
|
}
|
643 |
|
|
|
644 |
|
|
static inline void mv_write(int offset, u32 data)
|
645 |
|
|
{
|
646 |
|
|
writel(data, mv643xx_eth_base + offset);
|
647 |
|
|
}
|
648 |
|
|
|
649 |
|
|
/*
|
650 |
|
|
* Changes MTU (maximum transfer unit) of the gigabit ethenret port
|
651 |
|
|
*
|
652 |
|
|
* Input : pointer to ethernet interface network device structure
|
653 |
|
|
* new mtu size
|
654 |
|
|
* Output : 0 upon success, -EINVAL upon failure
|
655 |
|
|
*/
|
656 |
|
|
static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
|
657 |
|
|
{
|
658 |
|
|
if ((new_mtu > 9500) || (new_mtu < 64))
|
659 |
|
|
return -EINVAL;
|
660 |
|
|
|
661 |
|
|
dev->mtu = new_mtu;
|
662 |
|
|
/*
|
663 |
|
|
* Stop then re-open the interface. This will allocate RX skb's with
|
664 |
|
|
* the new MTU.
|
665 |
|
|
* There is a possible danger that the open will not successed, due
|
666 |
|
|
* to memory is full, which might fail the open function.
|
667 |
|
|
*/
|
668 |
|
|
if (netif_running(dev)) {
|
669 |
|
|
mv643xx_eth_stop(dev);
|
670 |
|
|
if (mv643xx_eth_open(dev))
|
671 |
|
|
printk(KERN_ERR
|
672 |
|
|
"%s: Fatal error on opening device\n",
|
673 |
|
|
dev->name);
|
674 |
|
|
}
|
675 |
|
|
|
676 |
|
|
return 0;
|
677 |
|
|
}
|
678 |
|
|
|
679 |
|
|
/*
|
680 |
|
|
* mv643xx_eth_rx_refill_descs
|
681 |
|
|
*
|
682 |
|
|
* Fills / refills RX queue on a certain gigabit ethernet port
|
683 |
|
|
*
|
684 |
|
|
* Input : pointer to ethernet interface network device structure
|
685 |
|
|
* Output : N/A
|
686 |
|
|
*/
|
687 |
|
|
static void mv643xx_eth_rx_refill_descs(struct net_device *dev)
|
688 |
|
|
{
|
689 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
690 |
|
|
struct pkt_info pkt_info;
|
691 |
|
|
struct sk_buff *skb;
|
692 |
|
|
int unaligned;
|
693 |
|
|
|
694 |
|
|
while (mp->rx_desc_count < mp->rx_ring_size) {
|
695 |
|
|
skb = dev_alloc_skb(ETH_RX_SKB_SIZE + dma_get_cache_alignment());
|
696 |
|
|
if (!skb)
|
697 |
|
|
break;
|
698 |
|
|
mp->rx_desc_count++;
|
699 |
|
|
unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
|
700 |
|
|
if (unaligned)
|
701 |
|
|
skb_reserve(skb, dma_get_cache_alignment() - unaligned);
|
702 |
|
|
pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
|
703 |
|
|
pkt_info.byte_cnt = ETH_RX_SKB_SIZE;
|
704 |
|
|
pkt_info.buf_ptr = dma_map_single(NULL, skb->data,
|
705 |
|
|
ETH_RX_SKB_SIZE, DMA_FROM_DEVICE);
|
706 |
|
|
pkt_info.return_info = skb;
|
707 |
|
|
if (eth_rx_return_buff(mp, &pkt_info) != ETH_OK) {
|
708 |
|
|
printk(KERN_ERR
|
709 |
|
|
"%s: Error allocating RX Ring\n", dev->name);
|
710 |
|
|
break;
|
711 |
|
|
}
|
712 |
|
|
skb_reserve(skb, ETH_HW_IP_ALIGN);
|
713 |
|
|
}
|
714 |
|
|
/*
|
715 |
|
|
* If RX ring is empty of SKB, set a timer to try allocating
|
716 |
|
|
* again at a later time.
|
717 |
|
|
*/
|
718 |
|
|
if (mp->rx_desc_count == 0) {
|
719 |
|
|
printk(KERN_INFO "%s: Rx ring is empty\n", dev->name);
|
720 |
|
|
mp->timeout.expires = jiffies + (HZ / 10); /* 100 mSec */
|
721 |
|
|
add_timer(&mp->timeout);
|
722 |
|
|
}
|
723 |
|
|
}
|
724 |
|
|
|
725 |
|
|
/*
|
726 |
|
|
* mv643xx_eth_rx_refill_descs_timer_wrapper
|
727 |
|
|
*
|
728 |
|
|
* Timer routine to wake up RX queue filling task. This function is
|
729 |
|
|
* used only in case the RX queue is empty, and all alloc_skb has
|
730 |
|
|
* failed (due to out of memory event).
|
731 |
|
|
*
|
732 |
|
|
* Input : pointer to ethernet interface network device structure
|
733 |
|
|
* Output : N/A
|
734 |
|
|
*/
|
735 |
|
|
static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data)
|
736 |
|
|
{
|
737 |
|
|
mv643xx_eth_rx_refill_descs((struct net_device *)data);
|
738 |
|
|
}
|
739 |
|
|
|
740 |
|
|
/*
|
741 |
|
|
* mv643xx_eth_update_mac_address
|
742 |
|
|
*
|
743 |
|
|
* Update the MAC address of the port in the address table
|
744 |
|
|
*
|
745 |
|
|
* Input : pointer to ethernet interface network device structure
|
746 |
|
|
* Output : N/A
|
747 |
|
|
*/
|
748 |
|
|
static void mv643xx_eth_update_mac_address(struct net_device *dev)
|
749 |
|
|
{
|
750 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
751 |
|
|
unsigned int port_num = mp->port_num;
|
752 |
|
|
|
753 |
|
|
eth_port_init_mac_tables(port_num);
|
754 |
|
|
eth_port_uc_addr_set(port_num, dev->dev_addr);
|
755 |
|
|
}
|
756 |
|
|
|
757 |
|
|
/*
|
758 |
|
|
* mv643xx_eth_set_rx_mode
|
759 |
|
|
*
|
760 |
|
|
* Change from promiscuos to regular rx mode
|
761 |
|
|
*
|
762 |
|
|
* Input : pointer to ethernet interface network device structure
|
763 |
|
|
* Output : N/A
|
764 |
|
|
*/
|
765 |
|
|
static void mv643xx_eth_set_rx_mode(struct net_device *dev)
|
766 |
|
|
{
|
767 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
768 |
|
|
u32 config_reg;
|
769 |
|
|
|
770 |
|
|
config_reg = mv_read(PORT_CONFIG_REG(mp->port_num));
|
771 |
|
|
if (dev->flags & IFF_PROMISC)
|
772 |
|
|
config_reg |= (u32) UNICAST_PROMISCUOUS_MODE;
|
773 |
|
|
else
|
774 |
|
|
config_reg &= ~(u32) UNICAST_PROMISCUOUS_MODE;
|
775 |
|
|
mv_write(PORT_CONFIG_REG(mp->port_num), config_reg);
|
776 |
|
|
|
777 |
|
|
eth_port_set_multicast_list(dev);
|
778 |
|
|
}
|
779 |
|
|
|
780 |
|
|
/*
|
781 |
|
|
* mv643xx_eth_set_mac_address
|
782 |
|
|
*
|
783 |
|
|
* Change the interface's mac address.
|
784 |
|
|
* No special hardware thing should be done because interface is always
|
785 |
|
|
* put in promiscuous mode.
|
786 |
|
|
*
|
787 |
|
|
* Input : pointer to ethernet interface network device structure and
|
788 |
|
|
* a pointer to the designated entry to be added to the cache.
|
789 |
|
|
* Output : zero upon success, negative upon failure
|
790 |
|
|
*/
|
791 |
|
|
static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
|
792 |
|
|
{
|
793 |
|
|
int i;
|
794 |
|
|
|
795 |
|
|
for (i = 0; i < 6; i++)
|
796 |
|
|
/* +2 is for the offset of the HW addr type */
|
797 |
|
|
dev->dev_addr[i] = ((unsigned char *)addr)[i + 2];
|
798 |
|
|
mv643xx_eth_update_mac_address(dev);
|
799 |
|
|
return 0;
|
800 |
|
|
}
|
801 |
|
|
|
802 |
|
|
/*
|
803 |
|
|
* mv643xx_eth_tx_timeout
|
804 |
|
|
*
|
805 |
|
|
* Called upon a timeout on transmitting a packet
|
806 |
|
|
*
|
807 |
|
|
* Input : pointer to ethernet interface network device structure.
|
808 |
|
|
* Output : N/A
|
809 |
|
|
*/
|
810 |
|
|
static void mv643xx_eth_tx_timeout(struct net_device *dev)
|
811 |
|
|
{
|
812 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
813 |
|
|
|
814 |
|
|
printk(KERN_INFO "%s: TX timeout ", dev->name);
|
815 |
|
|
|
816 |
|
|
/* Do the reset outside of interrupt context */
|
817 |
|
|
schedule_work(&mp->tx_timeout_task);
|
818 |
|
|
}
|
819 |
|
|
|
820 |
|
|
/*
|
821 |
|
|
* mv643xx_eth_tx_timeout_task
|
822 |
|
|
*
|
823 |
|
|
* Actual routine to reset the adapter when a timeout on Tx has occurred
|
824 |
|
|
*/
|
825 |
|
|
static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly)
|
826 |
|
|
{
|
827 |
|
|
struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private,
|
828 |
|
|
tx_timeout_task);
|
829 |
|
|
struct net_device *dev = mp->mii.dev; /* yuck */
|
830 |
|
|
|
831 |
|
|
if (!netif_running(dev))
|
832 |
|
|
return;
|
833 |
|
|
|
834 |
|
|
netif_stop_queue(dev);
|
835 |
|
|
|
836 |
|
|
eth_port_reset(mp->port_num);
|
837 |
|
|
eth_port_start(dev);
|
838 |
|
|
|
839 |
|
|
if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
|
840 |
|
|
netif_wake_queue(dev);
|
841 |
|
|
}
|
842 |
|
|
|
843 |
|
|
/**
|
844 |
|
|
* mv643xx_eth_free_tx_descs - Free the tx desc data for completed descriptors
|
845 |
|
|
*
|
846 |
|
|
* If force is non-zero, frees uncompleted descriptors as well
|
847 |
|
|
*/
|
848 |
|
|
int mv643xx_eth_free_tx_descs(struct net_device *dev, int force)
|
849 |
|
|
{
|
850 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
851 |
|
|
struct eth_tx_desc *desc;
|
852 |
|
|
u32 cmd_sts;
|
853 |
|
|
struct sk_buff *skb;
|
854 |
|
|
unsigned long flags;
|
855 |
|
|
int tx_index;
|
856 |
|
|
dma_addr_t addr;
|
857 |
|
|
int count;
|
858 |
|
|
int released = 0;
|
859 |
|
|
|
860 |
|
|
while (mp->tx_desc_count > 0) {
|
861 |
|
|
spin_lock_irqsave(&mp->lock, flags);
|
862 |
|
|
|
863 |
|
|
/* tx_desc_count might have changed before acquiring the lock */
|
864 |
|
|
if (mp->tx_desc_count <= 0) {
|
865 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
866 |
|
|
return released;
|
867 |
|
|
}
|
868 |
|
|
|
869 |
|
|
tx_index = mp->tx_used_desc_q;
|
870 |
|
|
desc = &mp->p_tx_desc_area[tx_index];
|
871 |
|
|
cmd_sts = desc->cmd_sts;
|
872 |
|
|
|
873 |
|
|
if (!force && (cmd_sts & ETH_BUFFER_OWNED_BY_DMA)) {
|
874 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
875 |
|
|
return released;
|
876 |
|
|
}
|
877 |
|
|
|
878 |
|
|
mp->tx_used_desc_q = (tx_index + 1) % mp->tx_ring_size;
|
879 |
|
|
mp->tx_desc_count--;
|
880 |
|
|
|
881 |
|
|
addr = desc->buf_ptr;
|
882 |
|
|
count = desc->byte_cnt;
|
883 |
|
|
skb = mp->tx_skb[tx_index];
|
884 |
|
|
if (skb)
|
885 |
|
|
mp->tx_skb[tx_index] = NULL;
|
886 |
|
|
|
887 |
|
|
if (cmd_sts & ETH_ERROR_SUMMARY) {
|
888 |
|
|
printk("%s: Error in TX\n", dev->name);
|
889 |
|
|
dev->stats.tx_errors++;
|
890 |
|
|
}
|
891 |
|
|
|
892 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
893 |
|
|
|
894 |
|
|
if (cmd_sts & ETH_TX_FIRST_DESC)
|
895 |
|
|
dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
|
896 |
|
|
else
|
897 |
|
|
dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE);
|
898 |
|
|
|
899 |
|
|
if (skb)
|
900 |
|
|
dev_kfree_skb_irq(skb);
|
901 |
|
|
|
902 |
|
|
released = 1;
|
903 |
|
|
}
|
904 |
|
|
|
905 |
|
|
return released;
|
906 |
|
|
}
|
907 |
|
|
|
908 |
|
|
static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev)
|
909 |
|
|
{
|
910 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
911 |
|
|
|
912 |
|
|
if (mv643xx_eth_free_tx_descs(dev, 0) &&
|
913 |
|
|
mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
|
914 |
|
|
netif_wake_queue(dev);
|
915 |
|
|
}
|
916 |
|
|
|
917 |
|
|
static void mv643xx_eth_free_all_tx_descs(struct net_device *dev)
|
918 |
|
|
{
|
919 |
|
|
mv643xx_eth_free_tx_descs(dev, 1);
|
920 |
|
|
}
|
921 |
|
|
|
922 |
|
|
/*
|
923 |
|
|
* mv643xx_eth_receive
|
924 |
|
|
*
|
925 |
|
|
* This function is forward packets that are received from the port's
|
926 |
|
|
* queues toward kernel core or FastRoute them to another interface.
|
927 |
|
|
*
|
928 |
|
|
* Input : dev - a pointer to the required interface
|
929 |
|
|
* max - maximum number to receive (0 means unlimted)
|
930 |
|
|
*
|
931 |
|
|
* Output : number of served packets
|
932 |
|
|
*/
|
933 |
|
|
static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
|
934 |
|
|
{
|
935 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
936 |
|
|
struct net_device_stats *stats = &dev->stats;
|
937 |
|
|
unsigned int received_packets = 0;
|
938 |
|
|
struct sk_buff *skb;
|
939 |
|
|
struct pkt_info pkt_info;
|
940 |
|
|
|
941 |
|
|
while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
|
942 |
|
|
dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
|
943 |
|
|
DMA_FROM_DEVICE);
|
944 |
|
|
mp->rx_desc_count--;
|
945 |
|
|
received_packets++;
|
946 |
|
|
|
947 |
|
|
/*
|
948 |
|
|
* Update statistics.
|
949 |
|
|
* Note byte count includes 4 byte CRC count
|
950 |
|
|
*/
|
951 |
|
|
stats->rx_packets++;
|
952 |
|
|
stats->rx_bytes += pkt_info.byte_cnt;
|
953 |
|
|
skb = pkt_info.return_info;
|
954 |
|
|
/*
|
955 |
|
|
* In case received a packet without first / last bits on OR
|
956 |
|
|
* the error summary bit is on, the packets needs to be dropeed.
|
957 |
|
|
*/
|
958 |
|
|
if (((pkt_info.cmd_sts
|
959 |
|
|
& (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
|
960 |
|
|
(ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
|
961 |
|
|
|| (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
|
962 |
|
|
stats->rx_dropped++;
|
963 |
|
|
if ((pkt_info.cmd_sts & (ETH_RX_FIRST_DESC |
|
964 |
|
|
ETH_RX_LAST_DESC)) !=
|
965 |
|
|
(ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) {
|
966 |
|
|
if (net_ratelimit())
|
967 |
|
|
printk(KERN_ERR
|
968 |
|
|
"%s: Received packet spread "
|
969 |
|
|
"on multiple descriptors\n",
|
970 |
|
|
dev->name);
|
971 |
|
|
}
|
972 |
|
|
if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)
|
973 |
|
|
stats->rx_errors++;
|
974 |
|
|
|
975 |
|
|
dev_kfree_skb_irq(skb);
|
976 |
|
|
} else {
|
977 |
|
|
/*
|
978 |
|
|
* The -4 is for the CRC in the trailer of the
|
979 |
|
|
* received packet
|
980 |
|
|
*/
|
981 |
|
|
skb_put(skb, pkt_info.byte_cnt - 4);
|
982 |
|
|
|
983 |
|
|
if (pkt_info.cmd_sts & ETH_LAYER_4_CHECKSUM_OK) {
|
984 |
|
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
985 |
|
|
skb->csum = htons(
|
986 |
|
|
(pkt_info.cmd_sts & 0x0007fff8) >> 3);
|
987 |
|
|
}
|
988 |
|
|
skb->protocol = eth_type_trans(skb, dev);
|
989 |
|
|
#ifdef MV643XX_NAPI
|
990 |
|
|
netif_receive_skb(skb);
|
991 |
|
|
#else
|
992 |
|
|
netif_rx(skb);
|
993 |
|
|
#endif
|
994 |
|
|
}
|
995 |
|
|
dev->last_rx = jiffies;
|
996 |
|
|
}
|
997 |
|
|
mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */
|
998 |
|
|
|
999 |
|
|
return received_packets;
|
1000 |
|
|
}
|
1001 |
|
|
|
1002 |
|
|
/* Set the mv643xx port configuration register for the speed/duplex mode. */
|
1003 |
|
|
static void mv643xx_eth_update_pscr(struct net_device *dev,
|
1004 |
|
|
struct ethtool_cmd *ecmd)
|
1005 |
|
|
{
|
1006 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1007 |
|
|
int port_num = mp->port_num;
|
1008 |
|
|
u32 o_pscr, n_pscr;
|
1009 |
|
|
unsigned int queues;
|
1010 |
|
|
|
1011 |
|
|
o_pscr = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
|
1012 |
|
|
n_pscr = o_pscr;
|
1013 |
|
|
|
1014 |
|
|
/* clear speed, duplex and rx buffer size fields */
|
1015 |
|
|
n_pscr &= ~(SET_MII_SPEED_TO_100 |
|
1016 |
|
|
SET_GMII_SPEED_TO_1000 |
|
1017 |
|
|
SET_FULL_DUPLEX_MODE |
|
1018 |
|
|
MAX_RX_PACKET_MASK);
|
1019 |
|
|
|
1020 |
|
|
if (ecmd->duplex == DUPLEX_FULL)
|
1021 |
|
|
n_pscr |= SET_FULL_DUPLEX_MODE;
|
1022 |
|
|
|
1023 |
|
|
if (ecmd->speed == SPEED_1000)
|
1024 |
|
|
n_pscr |= SET_GMII_SPEED_TO_1000 |
|
1025 |
|
|
MAX_RX_PACKET_9700BYTE;
|
1026 |
|
|
else {
|
1027 |
|
|
if (ecmd->speed == SPEED_100)
|
1028 |
|
|
n_pscr |= SET_MII_SPEED_TO_100;
|
1029 |
|
|
n_pscr |= MAX_RX_PACKET_1522BYTE;
|
1030 |
|
|
}
|
1031 |
|
|
|
1032 |
|
|
if (n_pscr != o_pscr) {
|
1033 |
|
|
if ((o_pscr & SERIAL_PORT_ENABLE) == 0)
|
1034 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
|
1035 |
|
|
else {
|
1036 |
|
|
queues = mv643xx_eth_port_disable_tx(port_num);
|
1037 |
|
|
|
1038 |
|
|
o_pscr &= ~SERIAL_PORT_ENABLE;
|
1039 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), o_pscr);
|
1040 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
|
1041 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
|
1042 |
|
|
if (queues)
|
1043 |
|
|
mv643xx_eth_port_enable_tx(port_num, queues);
|
1044 |
|
|
}
|
1045 |
|
|
}
|
1046 |
|
|
}
|
1047 |
|
|
|
1048 |
|
|
/*
|
1049 |
|
|
* mv643xx_eth_int_handler
|
1050 |
|
|
*
|
1051 |
|
|
* Main interrupt handler for the gigbit ethernet ports
|
1052 |
|
|
*
|
1053 |
|
|
* Input : irq - irq number (not used)
|
1054 |
|
|
* dev_id - a pointer to the required interface's data structure
|
1055 |
|
|
* regs - not used
|
1056 |
|
|
* Output : N/A
|
1057 |
|
|
*/
|
1058 |
|
|
|
1059 |
|
|
static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
|
1060 |
|
|
{
|
1061 |
|
|
struct net_device *dev = (struct net_device *)dev_id;
|
1062 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1063 |
|
|
u32 eth_int_cause, eth_int_cause_ext = 0;
|
1064 |
|
|
unsigned int port_num = mp->port_num;
|
1065 |
|
|
|
1066 |
|
|
/* Read interrupt cause registers */
|
1067 |
|
|
eth_int_cause = mv_read(INTERRUPT_CAUSE_REG(port_num)) &
|
1068 |
|
|
ETH_INT_UNMASK_ALL;
|
1069 |
|
|
if (eth_int_cause & ETH_INT_CAUSE_EXT) {
|
1070 |
|
|
eth_int_cause_ext = mv_read(
|
1071 |
|
|
INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
|
1072 |
|
|
ETH_INT_UNMASK_ALL_EXT;
|
1073 |
|
|
mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num),
|
1074 |
|
|
~eth_int_cause_ext);
|
1075 |
|
|
}
|
1076 |
|
|
|
1077 |
|
|
/* PHY status changed */
|
1078 |
|
|
if (eth_int_cause_ext & (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) {
|
1079 |
|
|
struct ethtool_cmd cmd;
|
1080 |
|
|
|
1081 |
|
|
if (mii_link_ok(&mp->mii)) {
|
1082 |
|
|
mii_ethtool_gset(&mp->mii, &cmd);
|
1083 |
|
|
mv643xx_eth_update_pscr(dev, &cmd);
|
1084 |
|
|
mv643xx_eth_port_enable_tx(port_num,
|
1085 |
|
|
ETH_TX_QUEUES_ENABLED);
|
1086 |
|
|
if (!netif_carrier_ok(dev)) {
|
1087 |
|
|
netif_carrier_on(dev);
|
1088 |
|
|
if (mp->tx_ring_size - mp->tx_desc_count >=
|
1089 |
|
|
MAX_DESCS_PER_SKB)
|
1090 |
|
|
netif_wake_queue(dev);
|
1091 |
|
|
}
|
1092 |
|
|
} else if (netif_carrier_ok(dev)) {
|
1093 |
|
|
netif_stop_queue(dev);
|
1094 |
|
|
netif_carrier_off(dev);
|
1095 |
|
|
}
|
1096 |
|
|
}
|
1097 |
|
|
|
1098 |
|
|
#ifdef MV643XX_NAPI
|
1099 |
|
|
if (eth_int_cause & ETH_INT_CAUSE_RX) {
|
1100 |
|
|
/* schedule the NAPI poll routine to maintain port */
|
1101 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
|
1102 |
|
|
|
1103 |
|
|
/* wait for previous write to complete */
|
1104 |
|
|
mv_read(INTERRUPT_MASK_REG(port_num));
|
1105 |
|
|
|
1106 |
|
|
netif_rx_schedule(dev, &mp->napi);
|
1107 |
|
|
}
|
1108 |
|
|
#else
|
1109 |
|
|
if (eth_int_cause & ETH_INT_CAUSE_RX)
|
1110 |
|
|
mv643xx_eth_receive_queue(dev, INT_MAX);
|
1111 |
|
|
#endif
|
1112 |
|
|
if (eth_int_cause_ext & ETH_INT_CAUSE_TX)
|
1113 |
|
|
mv643xx_eth_free_completed_tx_descs(dev);
|
1114 |
|
|
|
1115 |
|
|
/*
|
1116 |
|
|
* If no real interrupt occured, exit.
|
1117 |
|
|
* This can happen when using gigE interrupt coalescing mechanism.
|
1118 |
|
|
*/
|
1119 |
|
|
if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0))
|
1120 |
|
|
return IRQ_NONE;
|
1121 |
|
|
|
1122 |
|
|
return IRQ_HANDLED;
|
1123 |
|
|
}
|
1124 |
|
|
|
1125 |
|
|
#ifdef MV643XX_COAL
|
1126 |
|
|
|
1127 |
|
|
/*
|
1128 |
|
|
* eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
|
1129 |
|
|
*
|
1130 |
|
|
* DESCRIPTION:
|
1131 |
|
|
* This routine sets the RX coalescing interrupt mechanism parameter.
|
1132 |
|
|
* This parameter is a timeout counter, that counts in 64 t_clk
|
1133 |
|
|
* chunks ; that when timeout event occurs a maskable interrupt
|
1134 |
|
|
* occurs.
|
1135 |
|
|
* The parameter is calculated using the tClk of the MV-643xx chip
|
1136 |
|
|
* , and the required delay of the interrupt in usec.
|
1137 |
|
|
*
|
1138 |
|
|
* INPUT:
|
1139 |
|
|
* unsigned int eth_port_num Ethernet port number
|
1140 |
|
|
* unsigned int t_clk t_clk of the MV-643xx chip in HZ units
|
1141 |
|
|
* unsigned int delay Delay in usec
|
1142 |
|
|
*
|
1143 |
|
|
* OUTPUT:
|
1144 |
|
|
* Interrupt coalescing mechanism value is set in MV-643xx chip.
|
1145 |
|
|
*
|
1146 |
|
|
* RETURN:
|
1147 |
|
|
* The interrupt coalescing value set in the gigE port.
|
1148 |
|
|
*
|
1149 |
|
|
*/
|
1150 |
|
|
static unsigned int eth_port_set_rx_coal(unsigned int eth_port_num,
|
1151 |
|
|
unsigned int t_clk, unsigned int delay)
|
1152 |
|
|
{
|
1153 |
|
|
unsigned int coal = ((t_clk / 1000000) * delay) / 64;
|
1154 |
|
|
|
1155 |
|
|
/* Set RX Coalescing mechanism */
|
1156 |
|
|
mv_write(SDMA_CONFIG_REG(eth_port_num),
|
1157 |
|
|
((coal & 0x3fff) << 8) |
|
1158 |
|
|
(mv_read(SDMA_CONFIG_REG(eth_port_num))
|
1159 |
|
|
& 0xffc000ff));
|
1160 |
|
|
|
1161 |
|
|
return coal;
|
1162 |
|
|
}
|
1163 |
|
|
#endif
|
1164 |
|
|
|
1165 |
|
|
/*
|
1166 |
|
|
* eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
|
1167 |
|
|
*
|
1168 |
|
|
* DESCRIPTION:
|
1169 |
|
|
* This routine sets the TX coalescing interrupt mechanism parameter.
|
1170 |
|
|
* This parameter is a timeout counter, that counts in 64 t_clk
|
1171 |
|
|
* chunks ; that when timeout event occurs a maskable interrupt
|
1172 |
|
|
* occurs.
|
1173 |
|
|
* The parameter is calculated using the t_cLK frequency of the
|
1174 |
|
|
* MV-643xx chip and the required delay in the interrupt in uSec
|
1175 |
|
|
*
|
1176 |
|
|
* INPUT:
|
1177 |
|
|
* unsigned int eth_port_num Ethernet port number
|
1178 |
|
|
* unsigned int t_clk t_clk of the MV-643xx chip in HZ units
|
1179 |
|
|
* unsigned int delay Delay in uSeconds
|
1180 |
|
|
*
|
1181 |
|
|
* OUTPUT:
|
1182 |
|
|
* Interrupt coalescing mechanism value is set in MV-643xx chip.
|
1183 |
|
|
*
|
1184 |
|
|
* RETURN:
|
1185 |
|
|
* The interrupt coalescing value set in the gigE port.
|
1186 |
|
|
*
|
1187 |
|
|
*/
|
1188 |
|
|
static unsigned int eth_port_set_tx_coal(unsigned int eth_port_num,
|
1189 |
|
|
unsigned int t_clk, unsigned int delay)
|
1190 |
|
|
{
|
1191 |
|
|
unsigned int coal;
|
1192 |
|
|
coal = ((t_clk / 1000000) * delay) / 64;
|
1193 |
|
|
/* Set TX Coalescing mechanism */
|
1194 |
|
|
mv_write(TX_FIFO_URGENT_THRESHOLD_REG(eth_port_num), coal << 4);
|
1195 |
|
|
return coal;
|
1196 |
|
|
}
|
1197 |
|
|
|
1198 |
|
|
/*
|
1199 |
|
|
* ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
|
1200 |
|
|
*
|
1201 |
|
|
* DESCRIPTION:
|
1202 |
|
|
* This function prepares a Rx chained list of descriptors and packet
|
1203 |
|
|
* buffers in a form of a ring. The routine must be called after port
|
1204 |
|
|
* initialization routine and before port start routine.
|
1205 |
|
|
* The Ethernet SDMA engine uses CPU bus addresses to access the various
|
1206 |
|
|
* devices in the system (i.e. DRAM). This function uses the ethernet
|
1207 |
|
|
* struct 'virtual to physical' routine (set by the user) to set the ring
|
1208 |
|
|
* with physical addresses.
|
1209 |
|
|
*
|
1210 |
|
|
* INPUT:
|
1211 |
|
|
* struct mv643xx_private *mp Ethernet Port Control srtuct.
|
1212 |
|
|
*
|
1213 |
|
|
* OUTPUT:
|
1214 |
|
|
* The routine updates the Ethernet port control struct with information
|
1215 |
|
|
* regarding the Rx descriptors and buffers.
|
1216 |
|
|
*
|
1217 |
|
|
* RETURN:
|
1218 |
|
|
* None.
|
1219 |
|
|
*/
|
1220 |
|
|
static void ether_init_rx_desc_ring(struct mv643xx_private *mp)
|
1221 |
|
|
{
|
1222 |
|
|
volatile struct eth_rx_desc *p_rx_desc;
|
1223 |
|
|
int rx_desc_num = mp->rx_ring_size;
|
1224 |
|
|
int i;
|
1225 |
|
|
|
1226 |
|
|
/* initialize the next_desc_ptr links in the Rx descriptors ring */
|
1227 |
|
|
p_rx_desc = (struct eth_rx_desc *)mp->p_rx_desc_area;
|
1228 |
|
|
for (i = 0; i < rx_desc_num; i++) {
|
1229 |
|
|
p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma +
|
1230 |
|
|
((i + 1) % rx_desc_num) * sizeof(struct eth_rx_desc);
|
1231 |
|
|
}
|
1232 |
|
|
|
1233 |
|
|
/* Save Rx desc pointer to driver struct. */
|
1234 |
|
|
mp->rx_curr_desc_q = 0;
|
1235 |
|
|
mp->rx_used_desc_q = 0;
|
1236 |
|
|
|
1237 |
|
|
mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc);
|
1238 |
|
|
}
|
1239 |
|
|
|
1240 |
|
|
/*
|
1241 |
|
|
* ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
|
1242 |
|
|
*
|
1243 |
|
|
* DESCRIPTION:
|
1244 |
|
|
* This function prepares a Tx chained list of descriptors and packet
|
1245 |
|
|
* buffers in a form of a ring. The routine must be called after port
|
1246 |
|
|
* initialization routine and before port start routine.
|
1247 |
|
|
* The Ethernet SDMA engine uses CPU bus addresses to access the various
|
1248 |
|
|
* devices in the system (i.e. DRAM). This function uses the ethernet
|
1249 |
|
|
* struct 'virtual to physical' routine (set by the user) to set the ring
|
1250 |
|
|
* with physical addresses.
|
1251 |
|
|
*
|
1252 |
|
|
* INPUT:
|
1253 |
|
|
* struct mv643xx_private *mp Ethernet Port Control srtuct.
|
1254 |
|
|
*
|
1255 |
|
|
* OUTPUT:
|
1256 |
|
|
* The routine updates the Ethernet port control struct with information
|
1257 |
|
|
* regarding the Tx descriptors and buffers.
|
1258 |
|
|
*
|
1259 |
|
|
* RETURN:
|
1260 |
|
|
* None.
|
1261 |
|
|
*/
|
1262 |
|
|
static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
|
1263 |
|
|
{
|
1264 |
|
|
int tx_desc_num = mp->tx_ring_size;
|
1265 |
|
|
struct eth_tx_desc *p_tx_desc;
|
1266 |
|
|
int i;
|
1267 |
|
|
|
1268 |
|
|
/* Initialize the next_desc_ptr links in the Tx descriptors ring */
|
1269 |
|
|
p_tx_desc = (struct eth_tx_desc *)mp->p_tx_desc_area;
|
1270 |
|
|
for (i = 0; i < tx_desc_num; i++) {
|
1271 |
|
|
p_tx_desc[i].next_desc_ptr = mp->tx_desc_dma +
|
1272 |
|
|
((i + 1) % tx_desc_num) * sizeof(struct eth_tx_desc);
|
1273 |
|
|
}
|
1274 |
|
|
|
1275 |
|
|
mp->tx_curr_desc_q = 0;
|
1276 |
|
|
mp->tx_used_desc_q = 0;
|
1277 |
|
|
|
1278 |
|
|
mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc);
|
1279 |
|
|
}
|
1280 |
|
|
|
1281 |
|
|
static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
1282 |
|
|
{
|
1283 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1284 |
|
|
int err;
|
1285 |
|
|
|
1286 |
|
|
spin_lock_irq(&mp->lock);
|
1287 |
|
|
err = mii_ethtool_sset(&mp->mii, cmd);
|
1288 |
|
|
spin_unlock_irq(&mp->lock);
|
1289 |
|
|
|
1290 |
|
|
return err;
|
1291 |
|
|
}
|
1292 |
|
|
|
1293 |
|
|
static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
1294 |
|
|
{
|
1295 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1296 |
|
|
int err;
|
1297 |
|
|
|
1298 |
|
|
spin_lock_irq(&mp->lock);
|
1299 |
|
|
err = mii_ethtool_gset(&mp->mii, cmd);
|
1300 |
|
|
spin_unlock_irq(&mp->lock);
|
1301 |
|
|
|
1302 |
|
|
/* The PHY may support 1000baseT_Half, but the mv643xx does not */
|
1303 |
|
|
cmd->supported &= ~SUPPORTED_1000baseT_Half;
|
1304 |
|
|
cmd->advertising &= ~ADVERTISED_1000baseT_Half;
|
1305 |
|
|
|
1306 |
|
|
return err;
|
1307 |
|
|
}
|
1308 |
|
|
|
1309 |
|
|
/*
|
1310 |
|
|
* mv643xx_eth_open
|
1311 |
|
|
*
|
1312 |
|
|
* This function is called when openning the network device. The function
|
1313 |
|
|
* should initialize all the hardware, initialize cyclic Rx/Tx
|
1314 |
|
|
* descriptors chain and buffers and allocate an IRQ to the network
|
1315 |
|
|
* device.
|
1316 |
|
|
*
|
1317 |
|
|
* Input : a pointer to the network device structure
|
1318 |
|
|
*
|
1319 |
|
|
* Output : zero of success , nonzero if fails.
|
1320 |
|
|
*/
|
1321 |
|
|
|
1322 |
|
|
static int mv643xx_eth_open(struct net_device *dev)
|
1323 |
|
|
{
|
1324 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1325 |
|
|
unsigned int port_num = mp->port_num;
|
1326 |
|
|
unsigned int size;
|
1327 |
|
|
int err;
|
1328 |
|
|
|
1329 |
|
|
/* Clear any pending ethernet port interrupts */
|
1330 |
|
|
mv_write(INTERRUPT_CAUSE_REG(port_num), 0);
|
1331 |
|
|
mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
|
1332 |
|
|
/* wait for previous write to complete */
|
1333 |
|
|
mv_read (INTERRUPT_CAUSE_EXTEND_REG(port_num));
|
1334 |
|
|
|
1335 |
|
|
err = request_irq(dev->irq, mv643xx_eth_int_handler,
|
1336 |
|
|
IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
|
1337 |
|
|
if (err) {
|
1338 |
|
|
printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
|
1339 |
|
|
port_num);
|
1340 |
|
|
return -EAGAIN;
|
1341 |
|
|
}
|
1342 |
|
|
|
1343 |
|
|
eth_port_init(mp);
|
1344 |
|
|
|
1345 |
|
|
memset(&mp->timeout, 0, sizeof(struct timer_list));
|
1346 |
|
|
mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper;
|
1347 |
|
|
mp->timeout.data = (unsigned long)dev;
|
1348 |
|
|
|
1349 |
|
|
/* Allocate RX and TX skb rings */
|
1350 |
|
|
mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size,
|
1351 |
|
|
GFP_KERNEL);
|
1352 |
|
|
if (!mp->rx_skb) {
|
1353 |
|
|
printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name);
|
1354 |
|
|
err = -ENOMEM;
|
1355 |
|
|
goto out_free_irq;
|
1356 |
|
|
}
|
1357 |
|
|
mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size,
|
1358 |
|
|
GFP_KERNEL);
|
1359 |
|
|
if (!mp->tx_skb) {
|
1360 |
|
|
printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name);
|
1361 |
|
|
err = -ENOMEM;
|
1362 |
|
|
goto out_free_rx_skb;
|
1363 |
|
|
}
|
1364 |
|
|
|
1365 |
|
|
/* Allocate TX ring */
|
1366 |
|
|
mp->tx_desc_count = 0;
|
1367 |
|
|
size = mp->tx_ring_size * sizeof(struct eth_tx_desc);
|
1368 |
|
|
mp->tx_desc_area_size = size;
|
1369 |
|
|
|
1370 |
|
|
if (mp->tx_sram_size) {
|
1371 |
|
|
mp->p_tx_desc_area = ioremap(mp->tx_sram_addr,
|
1372 |
|
|
mp->tx_sram_size);
|
1373 |
|
|
mp->tx_desc_dma = mp->tx_sram_addr;
|
1374 |
|
|
} else
|
1375 |
|
|
mp->p_tx_desc_area = dma_alloc_coherent(NULL, size,
|
1376 |
|
|
&mp->tx_desc_dma,
|
1377 |
|
|
GFP_KERNEL);
|
1378 |
|
|
|
1379 |
|
|
if (!mp->p_tx_desc_area) {
|
1380 |
|
|
printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
|
1381 |
|
|
dev->name, size);
|
1382 |
|
|
err = -ENOMEM;
|
1383 |
|
|
goto out_free_tx_skb;
|
1384 |
|
|
}
|
1385 |
|
|
BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */
|
1386 |
|
|
memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size);
|
1387 |
|
|
|
1388 |
|
|
ether_init_tx_desc_ring(mp);
|
1389 |
|
|
|
1390 |
|
|
/* Allocate RX ring */
|
1391 |
|
|
mp->rx_desc_count = 0;
|
1392 |
|
|
size = mp->rx_ring_size * sizeof(struct eth_rx_desc);
|
1393 |
|
|
mp->rx_desc_area_size = size;
|
1394 |
|
|
|
1395 |
|
|
if (mp->rx_sram_size) {
|
1396 |
|
|
mp->p_rx_desc_area = ioremap(mp->rx_sram_addr,
|
1397 |
|
|
mp->rx_sram_size);
|
1398 |
|
|
mp->rx_desc_dma = mp->rx_sram_addr;
|
1399 |
|
|
} else
|
1400 |
|
|
mp->p_rx_desc_area = dma_alloc_coherent(NULL, size,
|
1401 |
|
|
&mp->rx_desc_dma,
|
1402 |
|
|
GFP_KERNEL);
|
1403 |
|
|
|
1404 |
|
|
if (!mp->p_rx_desc_area) {
|
1405 |
|
|
printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n",
|
1406 |
|
|
dev->name, size);
|
1407 |
|
|
printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
|
1408 |
|
|
dev->name);
|
1409 |
|
|
if (mp->rx_sram_size)
|
1410 |
|
|
iounmap(mp->p_tx_desc_area);
|
1411 |
|
|
else
|
1412 |
|
|
dma_free_coherent(NULL, mp->tx_desc_area_size,
|
1413 |
|
|
mp->p_tx_desc_area, mp->tx_desc_dma);
|
1414 |
|
|
err = -ENOMEM;
|
1415 |
|
|
goto out_free_tx_skb;
|
1416 |
|
|
}
|
1417 |
|
|
memset((void *)mp->p_rx_desc_area, 0, size);
|
1418 |
|
|
|
1419 |
|
|
ether_init_rx_desc_ring(mp);
|
1420 |
|
|
|
1421 |
|
|
mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */
|
1422 |
|
|
|
1423 |
|
|
#ifdef MV643XX_NAPI
|
1424 |
|
|
napi_enable(&mp->napi);
|
1425 |
|
|
#endif
|
1426 |
|
|
|
1427 |
|
|
eth_port_start(dev);
|
1428 |
|
|
|
1429 |
|
|
/* Interrupt Coalescing */
|
1430 |
|
|
|
1431 |
|
|
#ifdef MV643XX_COAL
|
1432 |
|
|
mp->rx_int_coal =
|
1433 |
|
|
eth_port_set_rx_coal(port_num, 133000000, MV643XX_RX_COAL);
|
1434 |
|
|
#endif
|
1435 |
|
|
|
1436 |
|
|
mp->tx_int_coal =
|
1437 |
|
|
eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
|
1438 |
|
|
|
1439 |
|
|
/* Unmask phy and link status changes interrupts */
|
1440 |
|
|
mv_write(INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT);
|
1441 |
|
|
|
1442 |
|
|
/* Unmask RX buffer and TX end interrupt */
|
1443 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
|
1444 |
|
|
|
1445 |
|
|
return 0;
|
1446 |
|
|
|
1447 |
|
|
out_free_tx_skb:
|
1448 |
|
|
kfree(mp->tx_skb);
|
1449 |
|
|
out_free_rx_skb:
|
1450 |
|
|
kfree(mp->rx_skb);
|
1451 |
|
|
out_free_irq:
|
1452 |
|
|
free_irq(dev->irq, dev);
|
1453 |
|
|
|
1454 |
|
|
return err;
|
1455 |
|
|
}
|
1456 |
|
|
|
1457 |
|
|
static void mv643xx_eth_free_tx_rings(struct net_device *dev)
|
1458 |
|
|
{
|
1459 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1460 |
|
|
|
1461 |
|
|
/* Stop Tx Queues */
|
1462 |
|
|
mv643xx_eth_port_disable_tx(mp->port_num);
|
1463 |
|
|
|
1464 |
|
|
/* Free outstanding skb's on TX ring */
|
1465 |
|
|
mv643xx_eth_free_all_tx_descs(dev);
|
1466 |
|
|
|
1467 |
|
|
BUG_ON(mp->tx_used_desc_q != mp->tx_curr_desc_q);
|
1468 |
|
|
|
1469 |
|
|
/* Free TX ring */
|
1470 |
|
|
if (mp->tx_sram_size)
|
1471 |
|
|
iounmap(mp->p_tx_desc_area);
|
1472 |
|
|
else
|
1473 |
|
|
dma_free_coherent(NULL, mp->tx_desc_area_size,
|
1474 |
|
|
mp->p_tx_desc_area, mp->tx_desc_dma);
|
1475 |
|
|
}
|
1476 |
|
|
|
1477 |
|
|
static void mv643xx_eth_free_rx_rings(struct net_device *dev)
|
1478 |
|
|
{
|
1479 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1480 |
|
|
unsigned int port_num = mp->port_num;
|
1481 |
|
|
int curr;
|
1482 |
|
|
|
1483 |
|
|
/* Stop RX Queues */
|
1484 |
|
|
mv643xx_eth_port_disable_rx(port_num);
|
1485 |
|
|
|
1486 |
|
|
/* Free preallocated skb's on RX rings */
|
1487 |
|
|
for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) {
|
1488 |
|
|
if (mp->rx_skb[curr]) {
|
1489 |
|
|
dev_kfree_skb(mp->rx_skb[curr]);
|
1490 |
|
|
mp->rx_desc_count--;
|
1491 |
|
|
}
|
1492 |
|
|
}
|
1493 |
|
|
|
1494 |
|
|
if (mp->rx_desc_count)
|
1495 |
|
|
printk(KERN_ERR
|
1496 |
|
|
"%s: Error in freeing Rx Ring. %d skb's still"
|
1497 |
|
|
" stuck in RX Ring - ignoring them\n", dev->name,
|
1498 |
|
|
mp->rx_desc_count);
|
1499 |
|
|
/* Free RX ring */
|
1500 |
|
|
if (mp->rx_sram_size)
|
1501 |
|
|
iounmap(mp->p_rx_desc_area);
|
1502 |
|
|
else
|
1503 |
|
|
dma_free_coherent(NULL, mp->rx_desc_area_size,
|
1504 |
|
|
mp->p_rx_desc_area, mp->rx_desc_dma);
|
1505 |
|
|
}
|
1506 |
|
|
|
1507 |
|
|
/*
|
1508 |
|
|
* mv643xx_eth_stop
|
1509 |
|
|
*
|
1510 |
|
|
* This function is used when closing the network device.
|
1511 |
|
|
* It updates the hardware,
|
1512 |
|
|
* release all memory that holds buffers and descriptors and release the IRQ.
|
1513 |
|
|
* Input : a pointer to the device structure
|
1514 |
|
|
* Output : zero if success , nonzero if fails
|
1515 |
|
|
*/
|
1516 |
|
|
|
1517 |
|
|
static int mv643xx_eth_stop(struct net_device *dev)
|
1518 |
|
|
{
|
1519 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1520 |
|
|
unsigned int port_num = mp->port_num;
|
1521 |
|
|
|
1522 |
|
|
/* Mask all interrupts on ethernet port */
|
1523 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
|
1524 |
|
|
/* wait for previous write to complete */
|
1525 |
|
|
mv_read(INTERRUPT_MASK_REG(port_num));
|
1526 |
|
|
|
1527 |
|
|
#ifdef MV643XX_NAPI
|
1528 |
|
|
napi_disable(&mp->napi);
|
1529 |
|
|
#endif
|
1530 |
|
|
netif_carrier_off(dev);
|
1531 |
|
|
netif_stop_queue(dev);
|
1532 |
|
|
|
1533 |
|
|
eth_port_reset(mp->port_num);
|
1534 |
|
|
|
1535 |
|
|
mv643xx_eth_free_tx_rings(dev);
|
1536 |
|
|
mv643xx_eth_free_rx_rings(dev);
|
1537 |
|
|
|
1538 |
|
|
free_irq(dev->irq, dev);
|
1539 |
|
|
|
1540 |
|
|
return 0;
|
1541 |
|
|
}
|
1542 |
|
|
|
1543 |
|
|
#ifdef MV643XX_NAPI
|
1544 |
|
|
/*
|
1545 |
|
|
* mv643xx_poll
|
1546 |
|
|
*
|
1547 |
|
|
* This function is used in case of NAPI
|
1548 |
|
|
*/
|
1549 |
|
|
static int mv643xx_poll(struct napi_struct *napi, int budget)
|
1550 |
|
|
{
|
1551 |
|
|
struct mv643xx_private *mp = container_of(napi, struct mv643xx_private, napi);
|
1552 |
|
|
struct net_device *dev = mp->dev;
|
1553 |
|
|
unsigned int port_num = mp->port_num;
|
1554 |
|
|
int work_done;
|
1555 |
|
|
|
1556 |
|
|
#ifdef MV643XX_TX_FAST_REFILL
|
1557 |
|
|
if (++mp->tx_clean_threshold > 5) {
|
1558 |
|
|
mv643xx_eth_free_completed_tx_descs(dev);
|
1559 |
|
|
mp->tx_clean_threshold = 0;
|
1560 |
|
|
}
|
1561 |
|
|
#endif
|
1562 |
|
|
|
1563 |
|
|
work_done = 0;
|
1564 |
|
|
if ((mv_read(RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))
|
1565 |
|
|
!= (u32) mp->rx_used_desc_q)
|
1566 |
|
|
work_done = mv643xx_eth_receive_queue(dev, budget);
|
1567 |
|
|
|
1568 |
|
|
if (work_done < budget) {
|
1569 |
|
|
netif_rx_complete(dev, napi);
|
1570 |
|
|
mv_write(INTERRUPT_CAUSE_REG(port_num), 0);
|
1571 |
|
|
mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
|
1572 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
|
1573 |
|
|
}
|
1574 |
|
|
|
1575 |
|
|
return work_done;
|
1576 |
|
|
}
|
1577 |
|
|
#endif
|
1578 |
|
|
|
1579 |
|
|
/**
|
1580 |
|
|
* has_tiny_unaligned_frags - check if skb has any small, unaligned fragments
|
1581 |
|
|
*
|
1582 |
|
|
* Hardware can't handle unaligned fragments smaller than 9 bytes.
|
1583 |
|
|
* This helper function detects that case.
|
1584 |
|
|
*/
|
1585 |
|
|
|
1586 |
|
|
static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
|
1587 |
|
|
{
|
1588 |
|
|
unsigned int frag;
|
1589 |
|
|
skb_frag_t *fragp;
|
1590 |
|
|
|
1591 |
|
|
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
1592 |
|
|
fragp = &skb_shinfo(skb)->frags[frag];
|
1593 |
|
|
if (fragp->size <= 8 && fragp->page_offset & 0x7)
|
1594 |
|
|
return 1;
|
1595 |
|
|
}
|
1596 |
|
|
return 0;
|
1597 |
|
|
}
|
1598 |
|
|
|
1599 |
|
|
/**
|
1600 |
|
|
* eth_alloc_tx_desc_index - return the index of the next available tx desc
|
1601 |
|
|
*/
|
1602 |
|
|
static int eth_alloc_tx_desc_index(struct mv643xx_private *mp)
|
1603 |
|
|
{
|
1604 |
|
|
int tx_desc_curr;
|
1605 |
|
|
|
1606 |
|
|
BUG_ON(mp->tx_desc_count >= mp->tx_ring_size);
|
1607 |
|
|
|
1608 |
|
|
tx_desc_curr = mp->tx_curr_desc_q;
|
1609 |
|
|
mp->tx_curr_desc_q = (tx_desc_curr + 1) % mp->tx_ring_size;
|
1610 |
|
|
|
1611 |
|
|
BUG_ON(mp->tx_curr_desc_q == mp->tx_used_desc_q);
|
1612 |
|
|
|
1613 |
|
|
return tx_desc_curr;
|
1614 |
|
|
}
|
1615 |
|
|
|
1616 |
|
|
/**
|
1617 |
|
|
* eth_tx_fill_frag_descs - fill tx hw descriptors for an skb's fragments.
|
1618 |
|
|
*
|
1619 |
|
|
* Ensure the data for each fragment to be transmitted is mapped properly,
|
1620 |
|
|
* then fill in descriptors in the tx hw queue.
|
1621 |
|
|
*/
|
1622 |
|
|
static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
|
1623 |
|
|
struct sk_buff *skb)
|
1624 |
|
|
{
|
1625 |
|
|
int frag;
|
1626 |
|
|
int tx_index;
|
1627 |
|
|
struct eth_tx_desc *desc;
|
1628 |
|
|
|
1629 |
|
|
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
1630 |
|
|
skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
|
1631 |
|
|
|
1632 |
|
|
tx_index = eth_alloc_tx_desc_index(mp);
|
1633 |
|
|
desc = &mp->p_tx_desc_area[tx_index];
|
1634 |
|
|
|
1635 |
|
|
desc->cmd_sts = ETH_BUFFER_OWNED_BY_DMA;
|
1636 |
|
|
/* Last Frag enables interrupt and frees the skb */
|
1637 |
|
|
if (frag == (skb_shinfo(skb)->nr_frags - 1)) {
|
1638 |
|
|
desc->cmd_sts |= ETH_ZERO_PADDING |
|
1639 |
|
|
ETH_TX_LAST_DESC |
|
1640 |
|
|
ETH_TX_ENABLE_INTERRUPT;
|
1641 |
|
|
mp->tx_skb[tx_index] = skb;
|
1642 |
|
|
} else
|
1643 |
|
|
mp->tx_skb[tx_index] = NULL;
|
1644 |
|
|
|
1645 |
|
|
desc = &mp->p_tx_desc_area[tx_index];
|
1646 |
|
|
desc->l4i_chk = 0;
|
1647 |
|
|
desc->byte_cnt = this_frag->size;
|
1648 |
|
|
desc->buf_ptr = dma_map_page(NULL, this_frag->page,
|
1649 |
|
|
this_frag->page_offset,
|
1650 |
|
|
this_frag->size,
|
1651 |
|
|
DMA_TO_DEVICE);
|
1652 |
|
|
}
|
1653 |
|
|
}
|
1654 |
|
|
|
1655 |
|
|
/**
|
1656 |
|
|
* eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw
|
1657 |
|
|
*
|
1658 |
|
|
* Ensure the data for an skb to be transmitted is mapped properly,
|
1659 |
|
|
* then fill in descriptors in the tx hw queue and start the hardware.
|
1660 |
|
|
*/
|
1661 |
|
|
static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
|
1662 |
|
|
struct sk_buff *skb)
|
1663 |
|
|
{
|
1664 |
|
|
int tx_index;
|
1665 |
|
|
struct eth_tx_desc *desc;
|
1666 |
|
|
u32 cmd_sts;
|
1667 |
|
|
int length;
|
1668 |
|
|
int nr_frags = skb_shinfo(skb)->nr_frags;
|
1669 |
|
|
|
1670 |
|
|
cmd_sts = ETH_TX_FIRST_DESC | ETH_GEN_CRC | ETH_BUFFER_OWNED_BY_DMA;
|
1671 |
|
|
|
1672 |
|
|
tx_index = eth_alloc_tx_desc_index(mp);
|
1673 |
|
|
desc = &mp->p_tx_desc_area[tx_index];
|
1674 |
|
|
|
1675 |
|
|
if (nr_frags) {
|
1676 |
|
|
eth_tx_fill_frag_descs(mp, skb);
|
1677 |
|
|
|
1678 |
|
|
length = skb_headlen(skb);
|
1679 |
|
|
mp->tx_skb[tx_index] = NULL;
|
1680 |
|
|
} else {
|
1681 |
|
|
cmd_sts |= ETH_ZERO_PADDING |
|
1682 |
|
|
ETH_TX_LAST_DESC |
|
1683 |
|
|
ETH_TX_ENABLE_INTERRUPT;
|
1684 |
|
|
length = skb->len;
|
1685 |
|
|
mp->tx_skb[tx_index] = skb;
|
1686 |
|
|
}
|
1687 |
|
|
|
1688 |
|
|
desc->byte_cnt = length;
|
1689 |
|
|
desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
|
1690 |
|
|
|
1691 |
|
|
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
1692 |
|
|
BUG_ON(skb->protocol != ETH_P_IP);
|
1693 |
|
|
|
1694 |
|
|
cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
|
1695 |
|
|
ETH_GEN_IP_V_4_CHECKSUM |
|
1696 |
|
|
ip_hdr(skb)->ihl << ETH_TX_IHL_SHIFT;
|
1697 |
|
|
|
1698 |
|
|
switch (ip_hdr(skb)->protocol) {
|
1699 |
|
|
case IPPROTO_UDP:
|
1700 |
|
|
cmd_sts |= ETH_UDP_FRAME;
|
1701 |
|
|
desc->l4i_chk = udp_hdr(skb)->check;
|
1702 |
|
|
break;
|
1703 |
|
|
case IPPROTO_TCP:
|
1704 |
|
|
desc->l4i_chk = tcp_hdr(skb)->check;
|
1705 |
|
|
break;
|
1706 |
|
|
default:
|
1707 |
|
|
BUG();
|
1708 |
|
|
}
|
1709 |
|
|
} else {
|
1710 |
|
|
/* Errata BTS #50, IHL must be 5 if no HW checksum */
|
1711 |
|
|
cmd_sts |= 5 << ETH_TX_IHL_SHIFT;
|
1712 |
|
|
desc->l4i_chk = 0;
|
1713 |
|
|
}
|
1714 |
|
|
|
1715 |
|
|
/* ensure all other descriptors are written before first cmd_sts */
|
1716 |
|
|
wmb();
|
1717 |
|
|
desc->cmd_sts = cmd_sts;
|
1718 |
|
|
|
1719 |
|
|
/* ensure all descriptors are written before poking hardware */
|
1720 |
|
|
wmb();
|
1721 |
|
|
mv643xx_eth_port_enable_tx(mp->port_num, ETH_TX_QUEUES_ENABLED);
|
1722 |
|
|
|
1723 |
|
|
mp->tx_desc_count += nr_frags + 1;
|
1724 |
|
|
}
|
1725 |
|
|
|
1726 |
|
|
/**
|
1727 |
|
|
* mv643xx_eth_start_xmit - queue an skb to the hardware for transmission
|
1728 |
|
|
*
|
1729 |
|
|
*/
|
1730 |
|
|
static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
1731 |
|
|
{
|
1732 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1733 |
|
|
struct net_device_stats *stats = &dev->stats;
|
1734 |
|
|
unsigned long flags;
|
1735 |
|
|
|
1736 |
|
|
BUG_ON(netif_queue_stopped(dev));
|
1737 |
|
|
BUG_ON(skb == NULL);
|
1738 |
|
|
|
1739 |
|
|
if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) {
|
1740 |
|
|
printk(KERN_ERR "%s: transmit with queue full\n", dev->name);
|
1741 |
|
|
netif_stop_queue(dev);
|
1742 |
|
|
return 1;
|
1743 |
|
|
}
|
1744 |
|
|
|
1745 |
|
|
if (has_tiny_unaligned_frags(skb)) {
|
1746 |
|
|
if (__skb_linearize(skb)) {
|
1747 |
|
|
stats->tx_dropped++;
|
1748 |
|
|
printk(KERN_DEBUG "%s: failed to linearize tiny "
|
1749 |
|
|
"unaligned fragment\n", dev->name);
|
1750 |
|
|
return 1;
|
1751 |
|
|
}
|
1752 |
|
|
}
|
1753 |
|
|
|
1754 |
|
|
spin_lock_irqsave(&mp->lock, flags);
|
1755 |
|
|
|
1756 |
|
|
eth_tx_submit_descs_for_skb(mp, skb);
|
1757 |
|
|
stats->tx_bytes += skb->len;
|
1758 |
|
|
stats->tx_packets++;
|
1759 |
|
|
dev->trans_start = jiffies;
|
1760 |
|
|
|
1761 |
|
|
if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB)
|
1762 |
|
|
netif_stop_queue(dev);
|
1763 |
|
|
|
1764 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
1765 |
|
|
|
1766 |
|
|
return 0; /* success */
|
1767 |
|
|
}
|
1768 |
|
|
|
1769 |
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
1770 |
|
|
static void mv643xx_netpoll(struct net_device *netdev)
|
1771 |
|
|
{
|
1772 |
|
|
struct mv643xx_private *mp = netdev_priv(netdev);
|
1773 |
|
|
int port_num = mp->port_num;
|
1774 |
|
|
|
1775 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
|
1776 |
|
|
/* wait for previous write to complete */
|
1777 |
|
|
mv_read(INTERRUPT_MASK_REG(port_num));
|
1778 |
|
|
|
1779 |
|
|
mv643xx_eth_int_handler(netdev->irq, netdev);
|
1780 |
|
|
|
1781 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
|
1782 |
|
|
}
|
1783 |
|
|
#endif
|
1784 |
|
|
|
1785 |
|
|
static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address,
|
1786 |
|
|
int speed, int duplex,
|
1787 |
|
|
struct ethtool_cmd *cmd)
|
1788 |
|
|
{
|
1789 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
1790 |
|
|
|
1791 |
|
|
memset(cmd, 0, sizeof(*cmd));
|
1792 |
|
|
|
1793 |
|
|
cmd->port = PORT_MII;
|
1794 |
|
|
cmd->transceiver = XCVR_INTERNAL;
|
1795 |
|
|
cmd->phy_address = phy_address;
|
1796 |
|
|
|
1797 |
|
|
if (speed == 0) {
|
1798 |
|
|
cmd->autoneg = AUTONEG_ENABLE;
|
1799 |
|
|
/* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */
|
1800 |
|
|
cmd->speed = SPEED_100;
|
1801 |
|
|
cmd->advertising = ADVERTISED_10baseT_Half |
|
1802 |
|
|
ADVERTISED_10baseT_Full |
|
1803 |
|
|
ADVERTISED_100baseT_Half |
|
1804 |
|
|
ADVERTISED_100baseT_Full;
|
1805 |
|
|
if (mp->mii.supports_gmii)
|
1806 |
|
|
cmd->advertising |= ADVERTISED_1000baseT_Full;
|
1807 |
|
|
} else {
|
1808 |
|
|
cmd->autoneg = AUTONEG_DISABLE;
|
1809 |
|
|
cmd->speed = speed;
|
1810 |
|
|
cmd->duplex = duplex;
|
1811 |
|
|
}
|
1812 |
|
|
}
|
1813 |
|
|
|
1814 |
|
|
/*/
|
1815 |
|
|
* mv643xx_eth_probe
|
1816 |
|
|
*
|
1817 |
|
|
* First function called after registering the network device.
|
1818 |
|
|
* It's purpose is to initialize the device as an ethernet device,
|
1819 |
|
|
* fill the ethernet device structure with pointers * to functions,
|
1820 |
|
|
* and set the MAC address of the interface
|
1821 |
|
|
*
|
1822 |
|
|
* Input : struct device *
|
1823 |
|
|
* Output : -ENOMEM if failed , 0 if success
|
1824 |
|
|
*/
|
1825 |
|
|
static int mv643xx_eth_probe(struct platform_device *pdev)
|
1826 |
|
|
{
|
1827 |
|
|
struct mv643xx_eth_platform_data *pd;
|
1828 |
|
|
int port_num;
|
1829 |
|
|
struct mv643xx_private *mp;
|
1830 |
|
|
struct net_device *dev;
|
1831 |
|
|
u8 *p;
|
1832 |
|
|
struct resource *res;
|
1833 |
|
|
int err;
|
1834 |
|
|
struct ethtool_cmd cmd;
|
1835 |
|
|
int duplex = DUPLEX_HALF;
|
1836 |
|
|
int speed = 0; /* default to auto-negotiation */
|
1837 |
|
|
DECLARE_MAC_BUF(mac);
|
1838 |
|
|
|
1839 |
|
|
pd = pdev->dev.platform_data;
|
1840 |
|
|
if (pd == NULL) {
|
1841 |
|
|
printk(KERN_ERR "No mv643xx_eth_platform_data\n");
|
1842 |
|
|
return -ENODEV;
|
1843 |
|
|
}
|
1844 |
|
|
|
1845 |
|
|
dev = alloc_etherdev(sizeof(struct mv643xx_private));
|
1846 |
|
|
if (!dev)
|
1847 |
|
|
return -ENOMEM;
|
1848 |
|
|
|
1849 |
|
|
platform_set_drvdata(pdev, dev);
|
1850 |
|
|
|
1851 |
|
|
mp = netdev_priv(dev);
|
1852 |
|
|
mp->dev = dev;
|
1853 |
|
|
#ifdef MV643XX_NAPI
|
1854 |
|
|
netif_napi_add(dev, &mp->napi, mv643xx_poll, 64);
|
1855 |
|
|
#endif
|
1856 |
|
|
|
1857 |
|
|
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
1858 |
|
|
BUG_ON(!res);
|
1859 |
|
|
dev->irq = res->start;
|
1860 |
|
|
|
1861 |
|
|
dev->open = mv643xx_eth_open;
|
1862 |
|
|
dev->stop = mv643xx_eth_stop;
|
1863 |
|
|
dev->hard_start_xmit = mv643xx_eth_start_xmit;
|
1864 |
|
|
dev->set_mac_address = mv643xx_eth_set_mac_address;
|
1865 |
|
|
dev->set_multicast_list = mv643xx_eth_set_rx_mode;
|
1866 |
|
|
|
1867 |
|
|
/* No need to Tx Timeout */
|
1868 |
|
|
dev->tx_timeout = mv643xx_eth_tx_timeout;
|
1869 |
|
|
|
1870 |
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
1871 |
|
|
dev->poll_controller = mv643xx_netpoll;
|
1872 |
|
|
#endif
|
1873 |
|
|
|
1874 |
|
|
dev->watchdog_timeo = 2 * HZ;
|
1875 |
|
|
dev->base_addr = 0;
|
1876 |
|
|
dev->change_mtu = mv643xx_eth_change_mtu;
|
1877 |
|
|
dev->do_ioctl = mv643xx_eth_do_ioctl;
|
1878 |
|
|
SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops);
|
1879 |
|
|
|
1880 |
|
|
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
1881 |
|
|
#ifdef MAX_SKB_FRAGS
|
1882 |
|
|
/*
|
1883 |
|
|
* Zero copy can only work if we use Discovery II memory. Else, we will
|
1884 |
|
|
* have to map the buffers to ISA memory which is only 16 MB
|
1885 |
|
|
*/
|
1886 |
|
|
dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
|
1887 |
|
|
#endif
|
1888 |
|
|
#endif
|
1889 |
|
|
|
1890 |
|
|
/* Configure the timeout task */
|
1891 |
|
|
INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task);
|
1892 |
|
|
|
1893 |
|
|
spin_lock_init(&mp->lock);
|
1894 |
|
|
|
1895 |
|
|
port_num = mp->port_num = pd->port_number;
|
1896 |
|
|
|
1897 |
|
|
/* set default config values */
|
1898 |
|
|
eth_port_uc_addr_get(port_num, dev->dev_addr);
|
1899 |
|
|
mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
|
1900 |
|
|
mp->tx_ring_size = PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
|
1901 |
|
|
|
1902 |
|
|
if (is_valid_ether_addr(pd->mac_addr))
|
1903 |
|
|
memcpy(dev->dev_addr, pd->mac_addr, 6);
|
1904 |
|
|
|
1905 |
|
|
if (pd->phy_addr || pd->force_phy_addr)
|
1906 |
|
|
ethernet_phy_set(port_num, pd->phy_addr);
|
1907 |
|
|
|
1908 |
|
|
if (pd->rx_queue_size)
|
1909 |
|
|
mp->rx_ring_size = pd->rx_queue_size;
|
1910 |
|
|
|
1911 |
|
|
if (pd->tx_queue_size)
|
1912 |
|
|
mp->tx_ring_size = pd->tx_queue_size;
|
1913 |
|
|
|
1914 |
|
|
if (pd->tx_sram_size) {
|
1915 |
|
|
mp->tx_sram_size = pd->tx_sram_size;
|
1916 |
|
|
mp->tx_sram_addr = pd->tx_sram_addr;
|
1917 |
|
|
}
|
1918 |
|
|
|
1919 |
|
|
if (pd->rx_sram_size) {
|
1920 |
|
|
mp->rx_sram_size = pd->rx_sram_size;
|
1921 |
|
|
mp->rx_sram_addr = pd->rx_sram_addr;
|
1922 |
|
|
}
|
1923 |
|
|
|
1924 |
|
|
duplex = pd->duplex;
|
1925 |
|
|
speed = pd->speed;
|
1926 |
|
|
|
1927 |
|
|
/* Hook up MII support for ethtool */
|
1928 |
|
|
mp->mii.dev = dev;
|
1929 |
|
|
mp->mii.mdio_read = mv643xx_mdio_read;
|
1930 |
|
|
mp->mii.mdio_write = mv643xx_mdio_write;
|
1931 |
|
|
mp->mii.phy_id = ethernet_phy_get(port_num);
|
1932 |
|
|
mp->mii.phy_id_mask = 0x3f;
|
1933 |
|
|
mp->mii.reg_num_mask = 0x1f;
|
1934 |
|
|
|
1935 |
|
|
err = ethernet_phy_detect(port_num);
|
1936 |
|
|
if (err) {
|
1937 |
|
|
pr_debug("MV643xx ethernet port %d: "
|
1938 |
|
|
"No PHY detected at addr %d\n",
|
1939 |
|
|
port_num, ethernet_phy_get(port_num));
|
1940 |
|
|
goto out;
|
1941 |
|
|
}
|
1942 |
|
|
|
1943 |
|
|
ethernet_phy_reset(port_num);
|
1944 |
|
|
mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
|
1945 |
|
|
mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd);
|
1946 |
|
|
mv643xx_eth_update_pscr(dev, &cmd);
|
1947 |
|
|
mv643xx_set_settings(dev, &cmd);
|
1948 |
|
|
|
1949 |
|
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
1950 |
|
|
err = register_netdev(dev);
|
1951 |
|
|
if (err)
|
1952 |
|
|
goto out;
|
1953 |
|
|
|
1954 |
|
|
p = dev->dev_addr;
|
1955 |
|
|
printk(KERN_NOTICE
|
1956 |
|
|
"%s: port %d with MAC address %s\n",
|
1957 |
|
|
dev->name, port_num, print_mac(mac, p));
|
1958 |
|
|
|
1959 |
|
|
if (dev->features & NETIF_F_SG)
|
1960 |
|
|
printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name);
|
1961 |
|
|
|
1962 |
|
|
if (dev->features & NETIF_F_IP_CSUM)
|
1963 |
|
|
printk(KERN_NOTICE "%s: TX TCP/IP Checksumming Supported\n",
|
1964 |
|
|
dev->name);
|
1965 |
|
|
|
1966 |
|
|
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
1967 |
|
|
printk(KERN_NOTICE "%s: RX TCP/UDP Checksum Offload ON \n", dev->name);
|
1968 |
|
|
#endif
|
1969 |
|
|
|
1970 |
|
|
#ifdef MV643XX_COAL
|
1971 |
|
|
printk(KERN_NOTICE "%s: TX and RX Interrupt Coalescing ON \n",
|
1972 |
|
|
dev->name);
|
1973 |
|
|
#endif
|
1974 |
|
|
|
1975 |
|
|
#ifdef MV643XX_NAPI
|
1976 |
|
|
printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
|
1977 |
|
|
#endif
|
1978 |
|
|
|
1979 |
|
|
if (mp->tx_sram_size > 0)
|
1980 |
|
|
printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
|
1981 |
|
|
|
1982 |
|
|
return 0;
|
1983 |
|
|
|
1984 |
|
|
out:
|
1985 |
|
|
free_netdev(dev);
|
1986 |
|
|
|
1987 |
|
|
return err;
|
1988 |
|
|
}
|
1989 |
|
|
|
1990 |
|
|
static int mv643xx_eth_remove(struct platform_device *pdev)
|
1991 |
|
|
{
|
1992 |
|
|
struct net_device *dev = platform_get_drvdata(pdev);
|
1993 |
|
|
|
1994 |
|
|
unregister_netdev(dev);
|
1995 |
|
|
flush_scheduled_work();
|
1996 |
|
|
|
1997 |
|
|
free_netdev(dev);
|
1998 |
|
|
platform_set_drvdata(pdev, NULL);
|
1999 |
|
|
return 0;
|
2000 |
|
|
}
|
2001 |
|
|
|
2002 |
|
|
static int mv643xx_eth_shared_probe(struct platform_device *pdev)
|
2003 |
|
|
{
|
2004 |
|
|
struct resource *res;
|
2005 |
|
|
|
2006 |
|
|
printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
|
2007 |
|
|
|
2008 |
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
2009 |
|
|
if (res == NULL)
|
2010 |
|
|
return -ENODEV;
|
2011 |
|
|
|
2012 |
|
|
mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1);
|
2013 |
|
|
if (mv643xx_eth_base == NULL)
|
2014 |
|
|
return -ENOMEM;
|
2015 |
|
|
|
2016 |
|
|
return 0;
|
2017 |
|
|
|
2018 |
|
|
}
|
2019 |
|
|
|
2020 |
|
|
static int mv643xx_eth_shared_remove(struct platform_device *pdev)
|
2021 |
|
|
{
|
2022 |
|
|
iounmap(mv643xx_eth_base);
|
2023 |
|
|
mv643xx_eth_base = NULL;
|
2024 |
|
|
|
2025 |
|
|
return 0;
|
2026 |
|
|
}
|
2027 |
|
|
|
2028 |
|
|
static void mv643xx_eth_shutdown(struct platform_device *pdev)
|
2029 |
|
|
{
|
2030 |
|
|
struct net_device *dev = platform_get_drvdata(pdev);
|
2031 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
2032 |
|
|
unsigned int port_num = mp->port_num;
|
2033 |
|
|
|
2034 |
|
|
/* Mask all interrupts on ethernet port */
|
2035 |
|
|
mv_write(INTERRUPT_MASK_REG(port_num), 0);
|
2036 |
|
|
mv_read (INTERRUPT_MASK_REG(port_num));
|
2037 |
|
|
|
2038 |
|
|
eth_port_reset(port_num);
|
2039 |
|
|
}
|
2040 |
|
|
|
2041 |
|
|
static struct platform_driver mv643xx_eth_driver = {
|
2042 |
|
|
.probe = mv643xx_eth_probe,
|
2043 |
|
|
.remove = mv643xx_eth_remove,
|
2044 |
|
|
.shutdown = mv643xx_eth_shutdown,
|
2045 |
|
|
.driver = {
|
2046 |
|
|
.name = MV643XX_ETH_NAME,
|
2047 |
|
|
},
|
2048 |
|
|
};
|
2049 |
|
|
|
2050 |
|
|
static struct platform_driver mv643xx_eth_shared_driver = {
|
2051 |
|
|
.probe = mv643xx_eth_shared_probe,
|
2052 |
|
|
.remove = mv643xx_eth_shared_remove,
|
2053 |
|
|
.driver = {
|
2054 |
|
|
.name = MV643XX_ETH_SHARED_NAME,
|
2055 |
|
|
},
|
2056 |
|
|
};
|
2057 |
|
|
|
2058 |
|
|
/*
|
2059 |
|
|
* mv643xx_init_module
|
2060 |
|
|
*
|
2061 |
|
|
* Registers the network drivers into the Linux kernel
|
2062 |
|
|
*
|
2063 |
|
|
* Input : N/A
|
2064 |
|
|
*
|
2065 |
|
|
* Output : N/A
|
2066 |
|
|
*/
|
2067 |
|
|
static int __init mv643xx_init_module(void)
|
2068 |
|
|
{
|
2069 |
|
|
int rc;
|
2070 |
|
|
|
2071 |
|
|
rc = platform_driver_register(&mv643xx_eth_shared_driver);
|
2072 |
|
|
if (!rc) {
|
2073 |
|
|
rc = platform_driver_register(&mv643xx_eth_driver);
|
2074 |
|
|
if (rc)
|
2075 |
|
|
platform_driver_unregister(&mv643xx_eth_shared_driver);
|
2076 |
|
|
}
|
2077 |
|
|
return rc;
|
2078 |
|
|
}
|
2079 |
|
|
|
2080 |
|
|
/*
|
2081 |
|
|
* mv643xx_cleanup_module
|
2082 |
|
|
*
|
2083 |
|
|
* Registers the network drivers into the Linux kernel
|
2084 |
|
|
*
|
2085 |
|
|
* Input : N/A
|
2086 |
|
|
*
|
2087 |
|
|
* Output : N/A
|
2088 |
|
|
*/
|
2089 |
|
|
static void __exit mv643xx_cleanup_module(void)
|
2090 |
|
|
{
|
2091 |
|
|
platform_driver_unregister(&mv643xx_eth_driver);
|
2092 |
|
|
platform_driver_unregister(&mv643xx_eth_shared_driver);
|
2093 |
|
|
}
|
2094 |
|
|
|
2095 |
|
|
module_init(mv643xx_init_module);
|
2096 |
|
|
module_exit(mv643xx_cleanup_module);
|
2097 |
|
|
|
2098 |
|
|
MODULE_LICENSE("GPL");
|
2099 |
|
|
MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
|
2100 |
|
|
" and Dale Farnsworth");
|
2101 |
|
|
MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
|
2102 |
|
|
|
2103 |
|
|
/*
|
2104 |
|
|
* The second part is the low level driver of the gigE ethernet ports.
|
2105 |
|
|
*/
|
2106 |
|
|
|
2107 |
|
|
/*
|
2108 |
|
|
* Marvell's Gigabit Ethernet controller low level driver
|
2109 |
|
|
*
|
2110 |
|
|
* DESCRIPTION:
|
2111 |
|
|
* This file introduce low level API to Marvell's Gigabit Ethernet
|
2112 |
|
|
* controller. This Gigabit Ethernet Controller driver API controls
|
2113 |
|
|
* 1) Operations (i.e. port init, start, reset etc').
|
2114 |
|
|
* 2) Data flow (i.e. port send, receive etc').
|
2115 |
|
|
* Each Gigabit Ethernet port is controlled via
|
2116 |
|
|
* struct mv643xx_private.
|
2117 |
|
|
* This struct includes user configuration information as well as
|
2118 |
|
|
* driver internal data needed for its operations.
|
2119 |
|
|
*
|
2120 |
|
|
* Supported Features:
|
2121 |
|
|
* - This low level driver is OS independent. Allocating memory for
|
2122 |
|
|
* the descriptor rings and buffers are not within the scope of
|
2123 |
|
|
* this driver.
|
2124 |
|
|
* - The user is free from Rx/Tx queue managing.
|
2125 |
|
|
* - This low level driver introduce functionality API that enable
|
2126 |
|
|
* the to operate Marvell's Gigabit Ethernet Controller in a
|
2127 |
|
|
* convenient way.
|
2128 |
|
|
* - Simple Gigabit Ethernet port operation API.
|
2129 |
|
|
* - Simple Gigabit Ethernet port data flow API.
|
2130 |
|
|
* - Data flow and operation API support per queue functionality.
|
2131 |
|
|
* - Support cached descriptors for better performance.
|
2132 |
|
|
* - Enable access to all four DRAM banks and internal SRAM memory
|
2133 |
|
|
* spaces.
|
2134 |
|
|
* - PHY access and control API.
|
2135 |
|
|
* - Port control register configuration API.
|
2136 |
|
|
* - Full control over Unicast and Multicast MAC configurations.
|
2137 |
|
|
*
|
2138 |
|
|
* Operation flow:
|
2139 |
|
|
*
|
2140 |
|
|
* Initialization phase
|
2141 |
|
|
* This phase complete the initialization of the the
|
2142 |
|
|
* mv643xx_private struct.
|
2143 |
|
|
* User information regarding port configuration has to be set
|
2144 |
|
|
* prior to calling the port initialization routine.
|
2145 |
|
|
*
|
2146 |
|
|
* In this phase any port Tx/Rx activity is halted, MIB counters
|
2147 |
|
|
* are cleared, PHY address is set according to user parameter and
|
2148 |
|
|
* access to DRAM and internal SRAM memory spaces.
|
2149 |
|
|
*
|
2150 |
|
|
* Driver ring initialization
|
2151 |
|
|
* Allocating memory for the descriptor rings and buffers is not
|
2152 |
|
|
* within the scope of this driver. Thus, the user is required to
|
2153 |
|
|
* allocate memory for the descriptors ring and buffers. Those
|
2154 |
|
|
* memory parameters are used by the Rx and Tx ring initialization
|
2155 |
|
|
* routines in order to curve the descriptor linked list in a form
|
2156 |
|
|
* of a ring.
|
2157 |
|
|
* Note: Pay special attention to alignment issues when using
|
2158 |
|
|
* cached descriptors/buffers. In this phase the driver store
|
2159 |
|
|
* information in the mv643xx_private struct regarding each queue
|
2160 |
|
|
* ring.
|
2161 |
|
|
*
|
2162 |
|
|
* Driver start
|
2163 |
|
|
* This phase prepares the Ethernet port for Rx and Tx activity.
|
2164 |
|
|
* It uses the information stored in the mv643xx_private struct to
|
2165 |
|
|
* initialize the various port registers.
|
2166 |
|
|
*
|
2167 |
|
|
* Data flow:
|
2168 |
|
|
* All packet references to/from the driver are done using
|
2169 |
|
|
* struct pkt_info.
|
2170 |
|
|
* This struct is a unified struct used with Rx and Tx operations.
|
2171 |
|
|
* This way the user is not required to be familiar with neither
|
2172 |
|
|
* Tx nor Rx descriptors structures.
|
2173 |
|
|
* The driver's descriptors rings are management by indexes.
|
2174 |
|
|
* Those indexes controls the ring resources and used to indicate
|
2175 |
|
|
* a SW resource error:
|
2176 |
|
|
* 'current'
|
2177 |
|
|
* This index points to the current available resource for use. For
|
2178 |
|
|
* example in Rx process this index will point to the descriptor
|
2179 |
|
|
* that will be passed to the user upon calling the receive
|
2180 |
|
|
* routine. In Tx process, this index will point to the descriptor
|
2181 |
|
|
* that will be assigned with the user packet info and transmitted.
|
2182 |
|
|
* 'used'
|
2183 |
|
|
* This index points to the descriptor that need to restore its
|
2184 |
|
|
* resources. For example in Rx process, using the Rx buffer return
|
2185 |
|
|
* API will attach the buffer returned in packet info to the
|
2186 |
|
|
* descriptor pointed by 'used'. In Tx process, using the Tx
|
2187 |
|
|
* descriptor return will merely return the user packet info with
|
2188 |
|
|
* the command status of the transmitted buffer pointed by the
|
2189 |
|
|
* 'used' index. Nevertheless, it is essential to use this routine
|
2190 |
|
|
* to update the 'used' index.
|
2191 |
|
|
* 'first'
|
2192 |
|
|
* This index supports Tx Scatter-Gather. It points to the first
|
2193 |
|
|
* descriptor of a packet assembled of multiple buffers. For
|
2194 |
|
|
* example when in middle of Such packet we have a Tx resource
|
2195 |
|
|
* error the 'curr' index get the value of 'first' to indicate
|
2196 |
|
|
* that the ring returned to its state before trying to transmit
|
2197 |
|
|
* this packet.
|
2198 |
|
|
*
|
2199 |
|
|
* Receive operation:
|
2200 |
|
|
* The eth_port_receive API set the packet information struct,
|
2201 |
|
|
* passed by the caller, with received information from the
|
2202 |
|
|
* 'current' SDMA descriptor.
|
2203 |
|
|
* It is the user responsibility to return this resource back
|
2204 |
|
|
* to the Rx descriptor ring to enable the reuse of this source.
|
2205 |
|
|
* Return Rx resource is done using the eth_rx_return_buff API.
|
2206 |
|
|
*
|
2207 |
|
|
* Prior to calling the initialization routine eth_port_init() the user
|
2208 |
|
|
* must set the following fields under mv643xx_private struct:
|
2209 |
|
|
* port_num User Ethernet port number.
|
2210 |
|
|
* port_config User port configuration value.
|
2211 |
|
|
* port_config_extend User port config extend value.
|
2212 |
|
|
* port_sdma_config User port SDMA config value.
|
2213 |
|
|
* port_serial_control User port serial control value.
|
2214 |
|
|
*
|
2215 |
|
|
* This driver data flow is done using the struct pkt_info which
|
2216 |
|
|
* is a unified struct for Rx and Tx operations:
|
2217 |
|
|
*
|
2218 |
|
|
* byte_cnt Tx/Rx descriptor buffer byte count.
|
2219 |
|
|
* l4i_chk CPU provided TCP Checksum. For Tx operation
|
2220 |
|
|
* only.
|
2221 |
|
|
* cmd_sts Tx/Rx descriptor command status.
|
2222 |
|
|
* buf_ptr Tx/Rx descriptor buffer pointer.
|
2223 |
|
|
* return_info Tx/Rx user resource return information.
|
2224 |
|
|
*/
|
2225 |
|
|
|
2226 |
|
|
/* PHY routines */
|
2227 |
|
|
static int ethernet_phy_get(unsigned int eth_port_num);
|
2228 |
|
|
static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
|
2229 |
|
|
|
2230 |
|
|
/* Ethernet Port routines */
|
2231 |
|
|
static void eth_port_set_filter_table_entry(int table, unsigned char entry);
|
2232 |
|
|
|
2233 |
|
|
/*
|
2234 |
|
|
* eth_port_init - Initialize the Ethernet port driver
|
2235 |
|
|
*
|
2236 |
|
|
* DESCRIPTION:
|
2237 |
|
|
* This function prepares the ethernet port to start its activity:
|
2238 |
|
|
* 1) Completes the ethernet port driver struct initialization toward port
|
2239 |
|
|
* start routine.
|
2240 |
|
|
* 2) Resets the device to a quiescent state in case of warm reboot.
|
2241 |
|
|
* 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
|
2242 |
|
|
* 4) Clean MAC tables. The reset status of those tables is unknown.
|
2243 |
|
|
* 5) Set PHY address.
|
2244 |
|
|
* Note: Call this routine prior to eth_port_start routine and after
|
2245 |
|
|
* setting user values in the user fields of Ethernet port control
|
2246 |
|
|
* struct.
|
2247 |
|
|
*
|
2248 |
|
|
* INPUT:
|
2249 |
|
|
* struct mv643xx_private *mp Ethernet port control struct
|
2250 |
|
|
*
|
2251 |
|
|
* OUTPUT:
|
2252 |
|
|
* See description.
|
2253 |
|
|
*
|
2254 |
|
|
* RETURN:
|
2255 |
|
|
* None.
|
2256 |
|
|
*/
|
2257 |
|
|
static void eth_port_init(struct mv643xx_private *mp)
|
2258 |
|
|
{
|
2259 |
|
|
mp->rx_resource_err = 0;
|
2260 |
|
|
|
2261 |
|
|
eth_port_reset(mp->port_num);
|
2262 |
|
|
|
2263 |
|
|
eth_port_init_mac_tables(mp->port_num);
|
2264 |
|
|
}
|
2265 |
|
|
|
2266 |
|
|
/*
|
2267 |
|
|
* eth_port_start - Start the Ethernet port activity.
|
2268 |
|
|
*
|
2269 |
|
|
* DESCRIPTION:
|
2270 |
|
|
* This routine prepares the Ethernet port for Rx and Tx activity:
|
2271 |
|
|
* 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
|
2272 |
|
|
* has been initialized a descriptor's ring (using
|
2273 |
|
|
* ether_init_tx_desc_ring for Tx and ether_init_rx_desc_ring for Rx)
|
2274 |
|
|
* 2. Initialize and enable the Ethernet configuration port by writing to
|
2275 |
|
|
* the port's configuration and command registers.
|
2276 |
|
|
* 3. Initialize and enable the SDMA by writing to the SDMA's
|
2277 |
|
|
* configuration and command registers. After completing these steps,
|
2278 |
|
|
* the ethernet port SDMA can starts to perform Rx and Tx activities.
|
2279 |
|
|
*
|
2280 |
|
|
* Note: Each Rx and Tx queue descriptor's list must be initialized prior
|
2281 |
|
|
* to calling this function (use ether_init_tx_desc_ring for Tx queues
|
2282 |
|
|
* and ether_init_rx_desc_ring for Rx queues).
|
2283 |
|
|
*
|
2284 |
|
|
* INPUT:
|
2285 |
|
|
* dev - a pointer to the required interface
|
2286 |
|
|
*
|
2287 |
|
|
* OUTPUT:
|
2288 |
|
|
* Ethernet port is ready to receive and transmit.
|
2289 |
|
|
*
|
2290 |
|
|
* RETURN:
|
2291 |
|
|
* None.
|
2292 |
|
|
*/
|
2293 |
|
|
static void eth_port_start(struct net_device *dev)
|
2294 |
|
|
{
|
2295 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
2296 |
|
|
unsigned int port_num = mp->port_num;
|
2297 |
|
|
int tx_curr_desc, rx_curr_desc;
|
2298 |
|
|
u32 pscr;
|
2299 |
|
|
struct ethtool_cmd ethtool_cmd;
|
2300 |
|
|
|
2301 |
|
|
/* Assignment of Tx CTRP of given queue */
|
2302 |
|
|
tx_curr_desc = mp->tx_curr_desc_q;
|
2303 |
|
|
mv_write(TX_CURRENT_QUEUE_DESC_PTR_0(port_num),
|
2304 |
|
|
(u32)((struct eth_tx_desc *)mp->tx_desc_dma + tx_curr_desc));
|
2305 |
|
|
|
2306 |
|
|
/* Assignment of Rx CRDP of given queue */
|
2307 |
|
|
rx_curr_desc = mp->rx_curr_desc_q;
|
2308 |
|
|
mv_write(RX_CURRENT_QUEUE_DESC_PTR_0(port_num),
|
2309 |
|
|
(u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc));
|
2310 |
|
|
|
2311 |
|
|
/* Add the assigned Ethernet address to the port's address table */
|
2312 |
|
|
eth_port_uc_addr_set(port_num, dev->dev_addr);
|
2313 |
|
|
|
2314 |
|
|
/* Assign port configuration and command. */
|
2315 |
|
|
mv_write(PORT_CONFIG_REG(port_num),
|
2316 |
|
|
PORT_CONFIG_DEFAULT_VALUE);
|
2317 |
|
|
|
2318 |
|
|
mv_write(PORT_CONFIG_EXTEND_REG(port_num),
|
2319 |
|
|
PORT_CONFIG_EXTEND_DEFAULT_VALUE);
|
2320 |
|
|
|
2321 |
|
|
pscr = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
|
2322 |
|
|
|
2323 |
|
|
pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS);
|
2324 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
2325 |
|
|
|
2326 |
|
|
pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
|
2327 |
|
|
DISABLE_AUTO_NEG_SPEED_GMII |
|
2328 |
|
|
DISABLE_AUTO_NEG_FOR_DUPLX |
|
2329 |
|
|
DO_NOT_FORCE_LINK_FAIL |
|
2330 |
|
|
SERIAL_PORT_CONTROL_RESERVED;
|
2331 |
|
|
|
2332 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
2333 |
|
|
|
2334 |
|
|
pscr |= SERIAL_PORT_ENABLE;
|
2335 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
2336 |
|
|
|
2337 |
|
|
/* Assign port SDMA configuration */
|
2338 |
|
|
mv_write(SDMA_CONFIG_REG(port_num),
|
2339 |
|
|
PORT_SDMA_CONFIG_DEFAULT_VALUE);
|
2340 |
|
|
|
2341 |
|
|
/* Enable port Rx. */
|
2342 |
|
|
mv643xx_eth_port_enable_rx(port_num, ETH_RX_QUEUES_ENABLED);
|
2343 |
|
|
|
2344 |
|
|
/* Disable port bandwidth limits by clearing MTU register */
|
2345 |
|
|
mv_write(MAXIMUM_TRANSMIT_UNIT(port_num), 0);
|
2346 |
|
|
|
2347 |
|
|
/* save phy settings across reset */
|
2348 |
|
|
mv643xx_get_settings(dev, ðtool_cmd);
|
2349 |
|
|
ethernet_phy_reset(mp->port_num);
|
2350 |
|
|
mv643xx_set_settings(dev, ðtool_cmd);
|
2351 |
|
|
}
|
2352 |
|
|
|
2353 |
|
|
/*
|
2354 |
|
|
* eth_port_uc_addr_set - Write a MAC address into the port's hw registers
|
2355 |
|
|
*/
|
2356 |
|
|
static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr)
|
2357 |
|
|
{
|
2358 |
|
|
unsigned int mac_h;
|
2359 |
|
|
unsigned int mac_l;
|
2360 |
|
|
int table;
|
2361 |
|
|
|
2362 |
|
|
mac_l = (p_addr[4] << 8) | (p_addr[5]);
|
2363 |
|
|
mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
|
2364 |
|
|
(p_addr[3] << 0);
|
2365 |
|
|
|
2366 |
|
|
mv_write(MAC_ADDR_LOW(port_num), mac_l);
|
2367 |
|
|
mv_write(MAC_ADDR_HIGH(port_num), mac_h);
|
2368 |
|
|
|
2369 |
|
|
/* Accept frames with this address */
|
2370 |
|
|
table = DA_FILTER_UNICAST_TABLE_BASE(port_num);
|
2371 |
|
|
eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f);
|
2372 |
|
|
}
|
2373 |
|
|
|
2374 |
|
|
/*
|
2375 |
|
|
* eth_port_uc_addr_get - Read the MAC address from the port's hw registers
|
2376 |
|
|
*/
|
2377 |
|
|
static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr)
|
2378 |
|
|
{
|
2379 |
|
|
unsigned int mac_h;
|
2380 |
|
|
unsigned int mac_l;
|
2381 |
|
|
|
2382 |
|
|
mac_h = mv_read(MAC_ADDR_HIGH(port_num));
|
2383 |
|
|
mac_l = mv_read(MAC_ADDR_LOW(port_num));
|
2384 |
|
|
|
2385 |
|
|
p_addr[0] = (mac_h >> 24) & 0xff;
|
2386 |
|
|
p_addr[1] = (mac_h >> 16) & 0xff;
|
2387 |
|
|
p_addr[2] = (mac_h >> 8) & 0xff;
|
2388 |
|
|
p_addr[3] = mac_h & 0xff;
|
2389 |
|
|
p_addr[4] = (mac_l >> 8) & 0xff;
|
2390 |
|
|
p_addr[5] = mac_l & 0xff;
|
2391 |
|
|
}
|
2392 |
|
|
|
2393 |
|
|
/*
|
2394 |
|
|
* The entries in each table are indexed by a hash of a packet's MAC
|
2395 |
|
|
* address. One bit in each entry determines whether the packet is
|
2396 |
|
|
* accepted. There are 4 entries (each 8 bits wide) in each register
|
2397 |
|
|
* of the table. The bits in each entry are defined as follows:
|
2398 |
|
|
* 0 Accept=1, Drop=0
|
2399 |
|
|
* 3-1 Queue (ETH_Q0=0)
|
2400 |
|
|
* 7-4 Reserved = 0;
|
2401 |
|
|
*/
|
2402 |
|
|
static void eth_port_set_filter_table_entry(int table, unsigned char entry)
|
2403 |
|
|
{
|
2404 |
|
|
unsigned int table_reg;
|
2405 |
|
|
unsigned int tbl_offset;
|
2406 |
|
|
unsigned int reg_offset;
|
2407 |
|
|
|
2408 |
|
|
tbl_offset = (entry / 4) * 4; /* Register offset of DA table entry */
|
2409 |
|
|
reg_offset = entry % 4; /* Entry offset within the register */
|
2410 |
|
|
|
2411 |
|
|
/* Set "accepts frame bit" at specified table entry */
|
2412 |
|
|
table_reg = mv_read(table + tbl_offset);
|
2413 |
|
|
table_reg |= 0x01 << (8 * reg_offset);
|
2414 |
|
|
mv_write(table + tbl_offset, table_reg);
|
2415 |
|
|
}
|
2416 |
|
|
|
2417 |
|
|
/*
|
2418 |
|
|
* eth_port_mc_addr - Multicast address settings.
|
2419 |
|
|
*
|
2420 |
|
|
* The MV device supports multicast using two tables:
|
2421 |
|
|
* 1) Special Multicast Table for MAC addresses of the form
|
2422 |
|
|
* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF).
|
2423 |
|
|
* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
|
2424 |
|
|
* Table entries in the DA-Filter table.
|
2425 |
|
|
* 2) Other Multicast Table for multicast of another type. A CRC-8bit
|
2426 |
|
|
* is used as an index to the Other Multicast Table entries in the
|
2427 |
|
|
* DA-Filter table. This function calculates the CRC-8bit value.
|
2428 |
|
|
* In either case, eth_port_set_filter_table_entry() is then called
|
2429 |
|
|
* to set to set the actual table entry.
|
2430 |
|
|
*/
|
2431 |
|
|
static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
|
2432 |
|
|
{
|
2433 |
|
|
unsigned int mac_h;
|
2434 |
|
|
unsigned int mac_l;
|
2435 |
|
|
unsigned char crc_result = 0;
|
2436 |
|
|
int table;
|
2437 |
|
|
int mac_array[48];
|
2438 |
|
|
int crc[8];
|
2439 |
|
|
int i;
|
2440 |
|
|
|
2441 |
|
|
if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) &&
|
2442 |
|
|
(p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
|
2443 |
|
|
table = DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
|
2444 |
|
|
(eth_port_num);
|
2445 |
|
|
eth_port_set_filter_table_entry(table, p_addr[5]);
|
2446 |
|
|
return;
|
2447 |
|
|
}
|
2448 |
|
|
|
2449 |
|
|
/* Calculate CRC-8 out of the given address */
|
2450 |
|
|
mac_h = (p_addr[0] << 8) | (p_addr[1]);
|
2451 |
|
|
mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
|
2452 |
|
|
(p_addr[4] << 8) | (p_addr[5] << 0);
|
2453 |
|
|
|
2454 |
|
|
for (i = 0; i < 32; i++)
|
2455 |
|
|
mac_array[i] = (mac_l >> i) & 0x1;
|
2456 |
|
|
for (i = 32; i < 48; i++)
|
2457 |
|
|
mac_array[i] = (mac_h >> (i - 32)) & 0x1;
|
2458 |
|
|
|
2459 |
|
|
crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^
|
2460 |
|
|
mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^
|
2461 |
|
|
mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
|
2462 |
|
|
mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^
|
2463 |
|
|
mac_array[8] ^ mac_array[7] ^ mac_array[6] ^ mac_array[0];
|
2464 |
|
|
|
2465 |
|
|
crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
|
2466 |
|
|
mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^
|
2467 |
|
|
mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
|
2468 |
|
|
mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^
|
2469 |
|
|
mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^
|
2470 |
|
|
mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
|
2471 |
|
|
mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ mac_array[0];
|
2472 |
|
|
|
2473 |
|
|
crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^
|
2474 |
|
|
mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^
|
2475 |
|
|
mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
|
2476 |
|
|
mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^
|
2477 |
|
|
mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8] ^
|
2478 |
|
|
mac_array[6] ^ mac_array[2] ^ mac_array[1] ^ mac_array[0];
|
2479 |
|
|
|
2480 |
|
|
crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
|
2481 |
|
|
mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^
|
2482 |
|
|
mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
|
2483 |
|
|
mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
|
2484 |
|
|
mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[7] ^
|
2485 |
|
|
mac_array[3] ^ mac_array[2] ^ mac_array[1];
|
2486 |
|
|
|
2487 |
|
|
crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^
|
2488 |
|
|
mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^
|
2489 |
|
|
mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
|
2490 |
|
|
mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^
|
2491 |
|
|
mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ mac_array[4] ^
|
2492 |
|
|
mac_array[3] ^ mac_array[2];
|
2493 |
|
|
|
2494 |
|
|
crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^
|
2495 |
|
|
mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^
|
2496 |
|
|
mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
|
2497 |
|
|
mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^
|
2498 |
|
|
mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[5] ^
|
2499 |
|
|
mac_array[4] ^ mac_array[3];
|
2500 |
|
|
|
2501 |
|
|
crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^
|
2502 |
|
|
mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^
|
2503 |
|
|
mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
|
2504 |
|
|
mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^
|
2505 |
|
|
mac_array[12] ^ mac_array[10] ^ mac_array[6] ^ mac_array[5] ^
|
2506 |
|
|
mac_array[4];
|
2507 |
|
|
|
2508 |
|
|
crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^
|
2509 |
|
|
mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^
|
2510 |
|
|
mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
|
2511 |
|
|
mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^
|
2512 |
|
|
mac_array[11] ^ mac_array[7] ^ mac_array[6] ^ mac_array[5];
|
2513 |
|
|
|
2514 |
|
|
for (i = 0; i < 8; i++)
|
2515 |
|
|
crc_result = crc_result | (crc[i] << i);
|
2516 |
|
|
|
2517 |
|
|
table = DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num);
|
2518 |
|
|
eth_port_set_filter_table_entry(table, crc_result);
|
2519 |
|
|
}
|
2520 |
|
|
|
2521 |
|
|
/*
|
2522 |
|
|
* Set the entire multicast list based on dev->mc_list.
|
2523 |
|
|
*/
|
2524 |
|
|
static void eth_port_set_multicast_list(struct net_device *dev)
|
2525 |
|
|
{
|
2526 |
|
|
|
2527 |
|
|
struct dev_mc_list *mc_list;
|
2528 |
|
|
int i;
|
2529 |
|
|
int table_index;
|
2530 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
2531 |
|
|
unsigned int eth_port_num = mp->port_num;
|
2532 |
|
|
|
2533 |
|
|
/* If the device is in promiscuous mode or in all multicast mode,
|
2534 |
|
|
* we will fully populate both multicast tables with accept.
|
2535 |
|
|
* This is guaranteed to yield a match on all multicast addresses...
|
2536 |
|
|
*/
|
2537 |
|
|
if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
|
2538 |
|
|
for (table_index = 0; table_index <= 0xFC; table_index += 4) {
|
2539 |
|
|
/* Set all entries in DA filter special multicast
|
2540 |
|
|
* table (Ex_dFSMT)
|
2541 |
|
|
* Set for ETH_Q0 for now
|
2542 |
|
|
* Bits
|
2543 |
|
|
* 0 Accept=1, Drop=0
|
2544 |
|
|
* 3-1 Queue ETH_Q0=0
|
2545 |
|
|
* 7-4 Reserved = 0;
|
2546 |
|
|
*/
|
2547 |
|
|
mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
|
2548 |
|
|
|
2549 |
|
|
/* Set all entries in DA filter other multicast
|
2550 |
|
|
* table (Ex_dFOMT)
|
2551 |
|
|
* Set for ETH_Q0 for now
|
2552 |
|
|
* Bits
|
2553 |
|
|
* 0 Accept=1, Drop=0
|
2554 |
|
|
* 3-1 Queue ETH_Q0=0
|
2555 |
|
|
* 7-4 Reserved = 0;
|
2556 |
|
|
*/
|
2557 |
|
|
mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
|
2558 |
|
|
}
|
2559 |
|
|
return;
|
2560 |
|
|
}
|
2561 |
|
|
|
2562 |
|
|
/* We will clear out multicast tables every time we get the list.
|
2563 |
|
|
* Then add the entire new list...
|
2564 |
|
|
*/
|
2565 |
|
|
for (table_index = 0; table_index <= 0xFC; table_index += 4) {
|
2566 |
|
|
/* Clear DA filter special multicast table (Ex_dFSMT) */
|
2567 |
|
|
mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
|
2568 |
|
|
(eth_port_num) + table_index, 0);
|
2569 |
|
|
|
2570 |
|
|
/* Clear DA filter other multicast table (Ex_dFOMT) */
|
2571 |
|
|
mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE
|
2572 |
|
|
(eth_port_num) + table_index, 0);
|
2573 |
|
|
}
|
2574 |
|
|
|
2575 |
|
|
/* Get pointer to net_device multicast list and add each one... */
|
2576 |
|
|
for (i = 0, mc_list = dev->mc_list;
|
2577 |
|
|
(i < 256) && (mc_list != NULL) && (i < dev->mc_count);
|
2578 |
|
|
i++, mc_list = mc_list->next)
|
2579 |
|
|
if (mc_list->dmi_addrlen == 6)
|
2580 |
|
|
eth_port_mc_addr(eth_port_num, mc_list->dmi_addr);
|
2581 |
|
|
}
|
2582 |
|
|
|
2583 |
|
|
/*
|
2584 |
|
|
* eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
|
2585 |
|
|
*
|
2586 |
|
|
* DESCRIPTION:
|
2587 |
|
|
* Go through all the DA filter tables (Unicast, Special Multicast &
|
2588 |
|
|
* Other Multicast) and set each entry to 0.
|
2589 |
|
|
*
|
2590 |
|
|
* INPUT:
|
2591 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2592 |
|
|
*
|
2593 |
|
|
* OUTPUT:
|
2594 |
|
|
* Multicast and Unicast packets are rejected.
|
2595 |
|
|
*
|
2596 |
|
|
* RETURN:
|
2597 |
|
|
* None.
|
2598 |
|
|
*/
|
2599 |
|
|
static void eth_port_init_mac_tables(unsigned int eth_port_num)
|
2600 |
|
|
{
|
2601 |
|
|
int table_index;
|
2602 |
|
|
|
2603 |
|
|
/* Clear DA filter unicast table (Ex_dFUT) */
|
2604 |
|
|
for (table_index = 0; table_index <= 0xC; table_index += 4)
|
2605 |
|
|
mv_write(DA_FILTER_UNICAST_TABLE_BASE
|
2606 |
|
|
(eth_port_num) + table_index, 0);
|
2607 |
|
|
|
2608 |
|
|
for (table_index = 0; table_index <= 0xFC; table_index += 4) {
|
2609 |
|
|
/* Clear DA filter special multicast table (Ex_dFSMT) */
|
2610 |
|
|
mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
|
2611 |
|
|
(eth_port_num) + table_index, 0);
|
2612 |
|
|
/* Clear DA filter other multicast table (Ex_dFOMT) */
|
2613 |
|
|
mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE
|
2614 |
|
|
(eth_port_num) + table_index, 0);
|
2615 |
|
|
}
|
2616 |
|
|
}
|
2617 |
|
|
|
2618 |
|
|
/*
|
2619 |
|
|
* eth_clear_mib_counters - Clear all MIB counters
|
2620 |
|
|
*
|
2621 |
|
|
* DESCRIPTION:
|
2622 |
|
|
* This function clears all MIB counters of a specific ethernet port.
|
2623 |
|
|
* A read from the MIB counter will reset the counter.
|
2624 |
|
|
*
|
2625 |
|
|
* INPUT:
|
2626 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2627 |
|
|
*
|
2628 |
|
|
* OUTPUT:
|
2629 |
|
|
* After reading all MIB counters, the counters resets.
|
2630 |
|
|
*
|
2631 |
|
|
* RETURN:
|
2632 |
|
|
* MIB counter value.
|
2633 |
|
|
*
|
2634 |
|
|
*/
|
2635 |
|
|
static void eth_clear_mib_counters(unsigned int eth_port_num)
|
2636 |
|
|
{
|
2637 |
|
|
int i;
|
2638 |
|
|
|
2639 |
|
|
/* Perform dummy reads from MIB counters */
|
2640 |
|
|
for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
|
2641 |
|
|
i += 4)
|
2642 |
|
|
mv_read(MIB_COUNTERS_BASE(eth_port_num) + i);
|
2643 |
|
|
}
|
2644 |
|
|
|
2645 |
|
|
static inline u32 read_mib(struct mv643xx_private *mp, int offset)
|
2646 |
|
|
{
|
2647 |
|
|
return mv_read(MIB_COUNTERS_BASE(mp->port_num) + offset);
|
2648 |
|
|
}
|
2649 |
|
|
|
2650 |
|
|
static void eth_update_mib_counters(struct mv643xx_private *mp)
|
2651 |
|
|
{
|
2652 |
|
|
struct mv643xx_mib_counters *p = &mp->mib_counters;
|
2653 |
|
|
int offset;
|
2654 |
|
|
|
2655 |
|
|
p->good_octets_received +=
|
2656 |
|
|
read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
|
2657 |
|
|
p->good_octets_received +=
|
2658 |
|
|
(u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32;
|
2659 |
|
|
|
2660 |
|
|
for (offset = ETH_MIB_BAD_OCTETS_RECEIVED;
|
2661 |
|
|
offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS;
|
2662 |
|
|
offset += 4)
|
2663 |
|
|
*(u32 *)((char *)p + offset) += read_mib(mp, offset);
|
2664 |
|
|
|
2665 |
|
|
p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW);
|
2666 |
|
|
p->good_octets_sent +=
|
2667 |
|
|
(u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_HIGH) << 32;
|
2668 |
|
|
|
2669 |
|
|
for (offset = ETH_MIB_GOOD_FRAMES_SENT;
|
2670 |
|
|
offset <= ETH_MIB_LATE_COLLISION;
|
2671 |
|
|
offset += 4)
|
2672 |
|
|
*(u32 *)((char *)p + offset) += read_mib(mp, offset);
|
2673 |
|
|
}
|
2674 |
|
|
|
2675 |
|
|
/*
|
2676 |
|
|
* ethernet_phy_detect - Detect whether a phy is present
|
2677 |
|
|
*
|
2678 |
|
|
* DESCRIPTION:
|
2679 |
|
|
* This function tests whether there is a PHY present on
|
2680 |
|
|
* the specified port.
|
2681 |
|
|
*
|
2682 |
|
|
* INPUT:
|
2683 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2684 |
|
|
*
|
2685 |
|
|
* OUTPUT:
|
2686 |
|
|
* None
|
2687 |
|
|
*
|
2688 |
|
|
* RETURN:
|
2689 |
|
|
* 0 on success
|
2690 |
|
|
* -ENODEV on failure
|
2691 |
|
|
*
|
2692 |
|
|
*/
|
2693 |
|
|
static int ethernet_phy_detect(unsigned int port_num)
|
2694 |
|
|
{
|
2695 |
|
|
unsigned int phy_reg_data0;
|
2696 |
|
|
int auto_neg;
|
2697 |
|
|
|
2698 |
|
|
eth_port_read_smi_reg(port_num, 0, &phy_reg_data0);
|
2699 |
|
|
auto_neg = phy_reg_data0 & 0x1000;
|
2700 |
|
|
phy_reg_data0 ^= 0x1000; /* invert auto_neg */
|
2701 |
|
|
eth_port_write_smi_reg(port_num, 0, phy_reg_data0);
|
2702 |
|
|
|
2703 |
|
|
eth_port_read_smi_reg(port_num, 0, &phy_reg_data0);
|
2704 |
|
|
if ((phy_reg_data0 & 0x1000) == auto_neg)
|
2705 |
|
|
return -ENODEV; /* change didn't take */
|
2706 |
|
|
|
2707 |
|
|
phy_reg_data0 ^= 0x1000;
|
2708 |
|
|
eth_port_write_smi_reg(port_num, 0, phy_reg_data0);
|
2709 |
|
|
return 0;
|
2710 |
|
|
}
|
2711 |
|
|
|
2712 |
|
|
/*
|
2713 |
|
|
* ethernet_phy_get - Get the ethernet port PHY address.
|
2714 |
|
|
*
|
2715 |
|
|
* DESCRIPTION:
|
2716 |
|
|
* This routine returns the given ethernet port PHY address.
|
2717 |
|
|
*
|
2718 |
|
|
* INPUT:
|
2719 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2720 |
|
|
*
|
2721 |
|
|
* OUTPUT:
|
2722 |
|
|
* None.
|
2723 |
|
|
*
|
2724 |
|
|
* RETURN:
|
2725 |
|
|
* PHY address.
|
2726 |
|
|
*
|
2727 |
|
|
*/
|
2728 |
|
|
static int ethernet_phy_get(unsigned int eth_port_num)
|
2729 |
|
|
{
|
2730 |
|
|
unsigned int reg_data;
|
2731 |
|
|
|
2732 |
|
|
reg_data = mv_read(PHY_ADDR_REG);
|
2733 |
|
|
|
2734 |
|
|
return ((reg_data >> (5 * eth_port_num)) & 0x1f);
|
2735 |
|
|
}
|
2736 |
|
|
|
2737 |
|
|
/*
|
2738 |
|
|
* ethernet_phy_set - Set the ethernet port PHY address.
|
2739 |
|
|
*
|
2740 |
|
|
* DESCRIPTION:
|
2741 |
|
|
* This routine sets the given ethernet port PHY address.
|
2742 |
|
|
*
|
2743 |
|
|
* INPUT:
|
2744 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2745 |
|
|
* int phy_addr PHY address.
|
2746 |
|
|
*
|
2747 |
|
|
* OUTPUT:
|
2748 |
|
|
* None.
|
2749 |
|
|
*
|
2750 |
|
|
* RETURN:
|
2751 |
|
|
* None.
|
2752 |
|
|
*
|
2753 |
|
|
*/
|
2754 |
|
|
static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr)
|
2755 |
|
|
{
|
2756 |
|
|
u32 reg_data;
|
2757 |
|
|
int addr_shift = 5 * eth_port_num;
|
2758 |
|
|
|
2759 |
|
|
reg_data = mv_read(PHY_ADDR_REG);
|
2760 |
|
|
reg_data &= ~(0x1f << addr_shift);
|
2761 |
|
|
reg_data |= (phy_addr & 0x1f) << addr_shift;
|
2762 |
|
|
mv_write(PHY_ADDR_REG, reg_data);
|
2763 |
|
|
}
|
2764 |
|
|
|
2765 |
|
|
/*
|
2766 |
|
|
* ethernet_phy_reset - Reset Ethernet port PHY.
|
2767 |
|
|
*
|
2768 |
|
|
* DESCRIPTION:
|
2769 |
|
|
* This routine utilizes the SMI interface to reset the ethernet port PHY.
|
2770 |
|
|
*
|
2771 |
|
|
* INPUT:
|
2772 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2773 |
|
|
*
|
2774 |
|
|
* OUTPUT:
|
2775 |
|
|
* The PHY is reset.
|
2776 |
|
|
*
|
2777 |
|
|
* RETURN:
|
2778 |
|
|
* None.
|
2779 |
|
|
*
|
2780 |
|
|
*/
|
2781 |
|
|
static void ethernet_phy_reset(unsigned int eth_port_num)
|
2782 |
|
|
{
|
2783 |
|
|
unsigned int phy_reg_data;
|
2784 |
|
|
|
2785 |
|
|
/* Reset the PHY */
|
2786 |
|
|
eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
|
2787 |
|
|
phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
|
2788 |
|
|
eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data);
|
2789 |
|
|
|
2790 |
|
|
/* wait for PHY to come out of reset */
|
2791 |
|
|
do {
|
2792 |
|
|
udelay(1);
|
2793 |
|
|
eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
|
2794 |
|
|
} while (phy_reg_data & 0x8000);
|
2795 |
|
|
}
|
2796 |
|
|
|
2797 |
|
|
static void mv643xx_eth_port_enable_tx(unsigned int port_num,
|
2798 |
|
|
unsigned int queues)
|
2799 |
|
|
{
|
2800 |
|
|
mv_write(TRANSMIT_QUEUE_COMMAND_REG(port_num), queues);
|
2801 |
|
|
}
|
2802 |
|
|
|
2803 |
|
|
static void mv643xx_eth_port_enable_rx(unsigned int port_num,
|
2804 |
|
|
unsigned int queues)
|
2805 |
|
|
{
|
2806 |
|
|
mv_write(RECEIVE_QUEUE_COMMAND_REG(port_num), queues);
|
2807 |
|
|
}
|
2808 |
|
|
|
2809 |
|
|
static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num)
|
2810 |
|
|
{
|
2811 |
|
|
u32 queues;
|
2812 |
|
|
|
2813 |
|
|
/* Stop Tx port activity. Check port Tx activity. */
|
2814 |
|
|
queues = mv_read(TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF;
|
2815 |
|
|
if (queues) {
|
2816 |
|
|
/* Issue stop command for active queues only */
|
2817 |
|
|
mv_write(TRANSMIT_QUEUE_COMMAND_REG(port_num), (queues << 8));
|
2818 |
|
|
|
2819 |
|
|
/* Wait for all Tx activity to terminate. */
|
2820 |
|
|
/* Check port cause register that all Tx queues are stopped */
|
2821 |
|
|
while (mv_read(TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF)
|
2822 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2823 |
|
|
|
2824 |
|
|
/* Wait for Tx FIFO to empty */
|
2825 |
|
|
while (mv_read(PORT_STATUS_REG(port_num)) &
|
2826 |
|
|
ETH_PORT_TX_FIFO_EMPTY)
|
2827 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2828 |
|
|
}
|
2829 |
|
|
|
2830 |
|
|
return queues;
|
2831 |
|
|
}
|
2832 |
|
|
|
2833 |
|
|
static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num)
|
2834 |
|
|
{
|
2835 |
|
|
u32 queues;
|
2836 |
|
|
|
2837 |
|
|
/* Stop Rx port activity. Check port Rx activity. */
|
2838 |
|
|
queues = mv_read(RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF;
|
2839 |
|
|
if (queues) {
|
2840 |
|
|
/* Issue stop command for active queues only */
|
2841 |
|
|
mv_write(RECEIVE_QUEUE_COMMAND_REG(port_num), (queues << 8));
|
2842 |
|
|
|
2843 |
|
|
/* Wait for all Rx activity to terminate. */
|
2844 |
|
|
/* Check port cause register that all Rx queues are stopped */
|
2845 |
|
|
while (mv_read(RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF)
|
2846 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2847 |
|
|
}
|
2848 |
|
|
|
2849 |
|
|
return queues;
|
2850 |
|
|
}
|
2851 |
|
|
|
2852 |
|
|
/*
|
2853 |
|
|
* eth_port_reset - Reset Ethernet port
|
2854 |
|
|
*
|
2855 |
|
|
* DESCRIPTION:
|
2856 |
|
|
* This routine resets the chip by aborting any SDMA engine activity and
|
2857 |
|
|
* clearing the MIB counters. The Receiver and the Transmit unit are in
|
2858 |
|
|
* idle state after this command is performed and the port is disabled.
|
2859 |
|
|
*
|
2860 |
|
|
* INPUT:
|
2861 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2862 |
|
|
*
|
2863 |
|
|
* OUTPUT:
|
2864 |
|
|
* Channel activity is halted.
|
2865 |
|
|
*
|
2866 |
|
|
* RETURN:
|
2867 |
|
|
* None.
|
2868 |
|
|
*
|
2869 |
|
|
*/
|
2870 |
|
|
static void eth_port_reset(unsigned int port_num)
|
2871 |
|
|
{
|
2872 |
|
|
unsigned int reg_data;
|
2873 |
|
|
|
2874 |
|
|
mv643xx_eth_port_disable_tx(port_num);
|
2875 |
|
|
mv643xx_eth_port_disable_rx(port_num);
|
2876 |
|
|
|
2877 |
|
|
/* Clear all MIB counters */
|
2878 |
|
|
eth_clear_mib_counters(port_num);
|
2879 |
|
|
|
2880 |
|
|
/* Reset the Enable bit in the Configuration Register */
|
2881 |
|
|
reg_data = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
|
2882 |
|
|
reg_data &= ~(SERIAL_PORT_ENABLE |
|
2883 |
|
|
DO_NOT_FORCE_LINK_FAIL |
|
2884 |
|
|
FORCE_LINK_PASS);
|
2885 |
|
|
mv_write(PORT_SERIAL_CONTROL_REG(port_num), reg_data);
|
2886 |
|
|
}
|
2887 |
|
|
|
2888 |
|
|
|
2889 |
|
|
/*
|
2890 |
|
|
* eth_port_read_smi_reg - Read PHY registers
|
2891 |
|
|
*
|
2892 |
|
|
* DESCRIPTION:
|
2893 |
|
|
* This routine utilize the SMI interface to interact with the PHY in
|
2894 |
|
|
* order to perform PHY register read.
|
2895 |
|
|
*
|
2896 |
|
|
* INPUT:
|
2897 |
|
|
* unsigned int port_num Ethernet Port number.
|
2898 |
|
|
* unsigned int phy_reg PHY register address offset.
|
2899 |
|
|
* unsigned int *value Register value buffer.
|
2900 |
|
|
*
|
2901 |
|
|
* OUTPUT:
|
2902 |
|
|
* Write the value of a specified PHY register into given buffer.
|
2903 |
|
|
*
|
2904 |
|
|
* RETURN:
|
2905 |
|
|
* false if the PHY is busy or read data is not in valid state.
|
2906 |
|
|
* true otherwise.
|
2907 |
|
|
*
|
2908 |
|
|
*/
|
2909 |
|
|
static void eth_port_read_smi_reg(unsigned int port_num,
|
2910 |
|
|
unsigned int phy_reg, unsigned int *value)
|
2911 |
|
|
{
|
2912 |
|
|
int phy_addr = ethernet_phy_get(port_num);
|
2913 |
|
|
unsigned long flags;
|
2914 |
|
|
int i;
|
2915 |
|
|
|
2916 |
|
|
/* the SMI register is a shared resource */
|
2917 |
|
|
spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
|
2918 |
|
|
|
2919 |
|
|
/* wait for the SMI register to become available */
|
2920 |
|
|
for (i = 0; mv_read(SMI_REG) & ETH_SMI_BUSY; i++) {
|
2921 |
|
|
if (i == PHY_WAIT_ITERATIONS) {
|
2922 |
|
|
printk("mv643xx PHY busy timeout, port %d\n", port_num);
|
2923 |
|
|
goto out;
|
2924 |
|
|
}
|
2925 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2926 |
|
|
}
|
2927 |
|
|
|
2928 |
|
|
mv_write(SMI_REG,
|
2929 |
|
|
(phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
|
2930 |
|
|
|
2931 |
|
|
/* now wait for the data to be valid */
|
2932 |
|
|
for (i = 0; !(mv_read(SMI_REG) & ETH_SMI_READ_VALID); i++) {
|
2933 |
|
|
if (i == PHY_WAIT_ITERATIONS) {
|
2934 |
|
|
printk("mv643xx PHY read timeout, port %d\n", port_num);
|
2935 |
|
|
goto out;
|
2936 |
|
|
}
|
2937 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2938 |
|
|
}
|
2939 |
|
|
|
2940 |
|
|
*value = mv_read(SMI_REG) & 0xffff;
|
2941 |
|
|
out:
|
2942 |
|
|
spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
|
2943 |
|
|
}
|
2944 |
|
|
|
2945 |
|
|
/*
|
2946 |
|
|
* eth_port_write_smi_reg - Write to PHY registers
|
2947 |
|
|
*
|
2948 |
|
|
* DESCRIPTION:
|
2949 |
|
|
* This routine utilize the SMI interface to interact with the PHY in
|
2950 |
|
|
* order to perform writes to PHY registers.
|
2951 |
|
|
*
|
2952 |
|
|
* INPUT:
|
2953 |
|
|
* unsigned int eth_port_num Ethernet Port number.
|
2954 |
|
|
* unsigned int phy_reg PHY register address offset.
|
2955 |
|
|
* unsigned int value Register value.
|
2956 |
|
|
*
|
2957 |
|
|
* OUTPUT:
|
2958 |
|
|
* Write the given value to the specified PHY register.
|
2959 |
|
|
*
|
2960 |
|
|
* RETURN:
|
2961 |
|
|
* false if the PHY is busy.
|
2962 |
|
|
* true otherwise.
|
2963 |
|
|
*
|
2964 |
|
|
*/
|
2965 |
|
|
static void eth_port_write_smi_reg(unsigned int eth_port_num,
|
2966 |
|
|
unsigned int phy_reg, unsigned int value)
|
2967 |
|
|
{
|
2968 |
|
|
int phy_addr;
|
2969 |
|
|
int i;
|
2970 |
|
|
unsigned long flags;
|
2971 |
|
|
|
2972 |
|
|
phy_addr = ethernet_phy_get(eth_port_num);
|
2973 |
|
|
|
2974 |
|
|
/* the SMI register is a shared resource */
|
2975 |
|
|
spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
|
2976 |
|
|
|
2977 |
|
|
/* wait for the SMI register to become available */
|
2978 |
|
|
for (i = 0; mv_read(SMI_REG) & ETH_SMI_BUSY; i++) {
|
2979 |
|
|
if (i == PHY_WAIT_ITERATIONS) {
|
2980 |
|
|
printk("mv643xx PHY busy timeout, port %d\n",
|
2981 |
|
|
eth_port_num);
|
2982 |
|
|
goto out;
|
2983 |
|
|
}
|
2984 |
|
|
udelay(PHY_WAIT_MICRO_SECONDS);
|
2985 |
|
|
}
|
2986 |
|
|
|
2987 |
|
|
mv_write(SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
|
2988 |
|
|
ETH_SMI_OPCODE_WRITE | (value & 0xffff));
|
2989 |
|
|
out:
|
2990 |
|
|
spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
|
2991 |
|
|
}
|
2992 |
|
|
|
2993 |
|
|
/*
|
2994 |
|
|
* Wrappers for MII support library.
|
2995 |
|
|
*/
|
2996 |
|
|
static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location)
|
2997 |
|
|
{
|
2998 |
|
|
int val;
|
2999 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
3000 |
|
|
|
3001 |
|
|
eth_port_read_smi_reg(mp->port_num, location, &val);
|
3002 |
|
|
return val;
|
3003 |
|
|
}
|
3004 |
|
|
|
3005 |
|
|
static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val)
|
3006 |
|
|
{
|
3007 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
3008 |
|
|
eth_port_write_smi_reg(mp->port_num, location, val);
|
3009 |
|
|
}
|
3010 |
|
|
|
3011 |
|
|
/*
|
3012 |
|
|
* eth_port_receive - Get received information from Rx ring.
|
3013 |
|
|
*
|
3014 |
|
|
* DESCRIPTION:
|
3015 |
|
|
* This routine returns the received data to the caller. There is no
|
3016 |
|
|
* data copying during routine operation. All information is returned
|
3017 |
|
|
* using pointer to packet information struct passed from the caller.
|
3018 |
|
|
* If the routine exhausts Rx ring resources then the resource error flag
|
3019 |
|
|
* is set.
|
3020 |
|
|
*
|
3021 |
|
|
* INPUT:
|
3022 |
|
|
* struct mv643xx_private *mp Ethernet Port Control srtuct.
|
3023 |
|
|
* struct pkt_info *p_pkt_info User packet buffer.
|
3024 |
|
|
*
|
3025 |
|
|
* OUTPUT:
|
3026 |
|
|
* Rx ring current and used indexes are updated.
|
3027 |
|
|
*
|
3028 |
|
|
* RETURN:
|
3029 |
|
|
* ETH_ERROR in case the routine can not access Rx desc ring.
|
3030 |
|
|
* ETH_QUEUE_FULL if Rx ring resources are exhausted.
|
3031 |
|
|
* ETH_END_OF_JOB if there is no received data.
|
3032 |
|
|
* ETH_OK otherwise.
|
3033 |
|
|
*/
|
3034 |
|
|
static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
|
3035 |
|
|
struct pkt_info *p_pkt_info)
|
3036 |
|
|
{
|
3037 |
|
|
int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
|
3038 |
|
|
volatile struct eth_rx_desc *p_rx_desc;
|
3039 |
|
|
unsigned int command_status;
|
3040 |
|
|
unsigned long flags;
|
3041 |
|
|
|
3042 |
|
|
/* Do not process Rx ring in case of Rx ring resource error */
|
3043 |
|
|
if (mp->rx_resource_err)
|
3044 |
|
|
return ETH_QUEUE_FULL;
|
3045 |
|
|
|
3046 |
|
|
spin_lock_irqsave(&mp->lock, flags);
|
3047 |
|
|
|
3048 |
|
|
/* Get the Rx Desc ring 'curr and 'used' indexes */
|
3049 |
|
|
rx_curr_desc = mp->rx_curr_desc_q;
|
3050 |
|
|
rx_used_desc = mp->rx_used_desc_q;
|
3051 |
|
|
|
3052 |
|
|
p_rx_desc = &mp->p_rx_desc_area[rx_curr_desc];
|
3053 |
|
|
|
3054 |
|
|
/* The following parameters are used to save readings from memory */
|
3055 |
|
|
command_status = p_rx_desc->cmd_sts;
|
3056 |
|
|
rmb();
|
3057 |
|
|
|
3058 |
|
|
/* Nothing to receive... */
|
3059 |
|
|
if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
|
3060 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
3061 |
|
|
return ETH_END_OF_JOB;
|
3062 |
|
|
}
|
3063 |
|
|
|
3064 |
|
|
p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET;
|
3065 |
|
|
p_pkt_info->cmd_sts = command_status;
|
3066 |
|
|
p_pkt_info->buf_ptr = (p_rx_desc->buf_ptr) + RX_BUF_OFFSET;
|
3067 |
|
|
p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
|
3068 |
|
|
p_pkt_info->l4i_chk = p_rx_desc->buf_size;
|
3069 |
|
|
|
3070 |
|
|
/*
|
3071 |
|
|
* Clean the return info field to indicate that the
|
3072 |
|
|
* packet has been moved to the upper layers
|
3073 |
|
|
*/
|
3074 |
|
|
mp->rx_skb[rx_curr_desc] = NULL;
|
3075 |
|
|
|
3076 |
|
|
/* Update current index in data structure */
|
3077 |
|
|
rx_next_curr_desc = (rx_curr_desc + 1) % mp->rx_ring_size;
|
3078 |
|
|
mp->rx_curr_desc_q = rx_next_curr_desc;
|
3079 |
|
|
|
3080 |
|
|
/* Rx descriptors exhausted. Set the Rx ring resource error flag */
|
3081 |
|
|
if (rx_next_curr_desc == rx_used_desc)
|
3082 |
|
|
mp->rx_resource_err = 1;
|
3083 |
|
|
|
3084 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
3085 |
|
|
|
3086 |
|
|
return ETH_OK;
|
3087 |
|
|
}
|
3088 |
|
|
|
3089 |
|
|
/*
|
3090 |
|
|
* eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
|
3091 |
|
|
*
|
3092 |
|
|
* DESCRIPTION:
|
3093 |
|
|
* This routine returns a Rx buffer back to the Rx ring. It retrieves the
|
3094 |
|
|
* next 'used' descriptor and attached the returned buffer to it.
|
3095 |
|
|
* In case the Rx ring was in "resource error" condition, where there are
|
3096 |
|
|
* no available Rx resources, the function resets the resource error flag.
|
3097 |
|
|
*
|
3098 |
|
|
* INPUT:
|
3099 |
|
|
* struct mv643xx_private *mp Ethernet Port Control srtuct.
|
3100 |
|
|
* struct pkt_info *p_pkt_info Information on returned buffer.
|
3101 |
|
|
*
|
3102 |
|
|
* OUTPUT:
|
3103 |
|
|
* New available Rx resource in Rx descriptor ring.
|
3104 |
|
|
*
|
3105 |
|
|
* RETURN:
|
3106 |
|
|
* ETH_ERROR in case the routine can not access Rx desc ring.
|
3107 |
|
|
* ETH_OK otherwise.
|
3108 |
|
|
*/
|
3109 |
|
|
static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
|
3110 |
|
|
struct pkt_info *p_pkt_info)
|
3111 |
|
|
{
|
3112 |
|
|
int used_rx_desc; /* Where to return Rx resource */
|
3113 |
|
|
volatile struct eth_rx_desc *p_used_rx_desc;
|
3114 |
|
|
unsigned long flags;
|
3115 |
|
|
|
3116 |
|
|
spin_lock_irqsave(&mp->lock, flags);
|
3117 |
|
|
|
3118 |
|
|
/* Get 'used' Rx descriptor */
|
3119 |
|
|
used_rx_desc = mp->rx_used_desc_q;
|
3120 |
|
|
p_used_rx_desc = &mp->p_rx_desc_area[used_rx_desc];
|
3121 |
|
|
|
3122 |
|
|
p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
|
3123 |
|
|
p_used_rx_desc->buf_size = p_pkt_info->byte_cnt;
|
3124 |
|
|
mp->rx_skb[used_rx_desc] = p_pkt_info->return_info;
|
3125 |
|
|
|
3126 |
|
|
/* Flush the write pipe */
|
3127 |
|
|
|
3128 |
|
|
/* Return the descriptor to DMA ownership */
|
3129 |
|
|
wmb();
|
3130 |
|
|
p_used_rx_desc->cmd_sts =
|
3131 |
|
|
ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
|
3132 |
|
|
wmb();
|
3133 |
|
|
|
3134 |
|
|
/* Move the used descriptor pointer to the next descriptor */
|
3135 |
|
|
mp->rx_used_desc_q = (used_rx_desc + 1) % mp->rx_ring_size;
|
3136 |
|
|
|
3137 |
|
|
/* Any Rx return cancels the Rx resource error status */
|
3138 |
|
|
mp->rx_resource_err = 0;
|
3139 |
|
|
|
3140 |
|
|
spin_unlock_irqrestore(&mp->lock, flags);
|
3141 |
|
|
|
3142 |
|
|
return ETH_OK;
|
3143 |
|
|
}
|
3144 |
|
|
|
3145 |
|
|
/************* Begin ethtool support *************************/
|
3146 |
|
|
|
3147 |
|
|
struct mv643xx_stats {
|
3148 |
|
|
char stat_string[ETH_GSTRING_LEN];
|
3149 |
|
|
int sizeof_stat;
|
3150 |
|
|
int stat_offset;
|
3151 |
|
|
};
|
3152 |
|
|
|
3153 |
|
|
#define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
|
3154 |
|
|
offsetof(struct mv643xx_private, m)
|
3155 |
|
|
|
3156 |
|
|
static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
|
3157 |
|
|
{ "rx_packets", MV643XX_STAT(stats.rx_packets) },
|
3158 |
|
|
{ "tx_packets", MV643XX_STAT(stats.tx_packets) },
|
3159 |
|
|
{ "rx_bytes", MV643XX_STAT(stats.rx_bytes) },
|
3160 |
|
|
{ "tx_bytes", MV643XX_STAT(stats.tx_bytes) },
|
3161 |
|
|
{ "rx_errors", MV643XX_STAT(stats.rx_errors) },
|
3162 |
|
|
{ "tx_errors", MV643XX_STAT(stats.tx_errors) },
|
3163 |
|
|
{ "rx_dropped", MV643XX_STAT(stats.rx_dropped) },
|
3164 |
|
|
{ "tx_dropped", MV643XX_STAT(stats.tx_dropped) },
|
3165 |
|
|
{ "good_octets_received", MV643XX_STAT(mib_counters.good_octets_received) },
|
3166 |
|
|
{ "bad_octets_received", MV643XX_STAT(mib_counters.bad_octets_received) },
|
3167 |
|
|
{ "internal_mac_transmit_err", MV643XX_STAT(mib_counters.internal_mac_transmit_err) },
|
3168 |
|
|
{ "good_frames_received", MV643XX_STAT(mib_counters.good_frames_received) },
|
3169 |
|
|
{ "bad_frames_received", MV643XX_STAT(mib_counters.bad_frames_received) },
|
3170 |
|
|
{ "broadcast_frames_received", MV643XX_STAT(mib_counters.broadcast_frames_received) },
|
3171 |
|
|
{ "multicast_frames_received", MV643XX_STAT(mib_counters.multicast_frames_received) },
|
3172 |
|
|
{ "frames_64_octets", MV643XX_STAT(mib_counters.frames_64_octets) },
|
3173 |
|
|
{ "frames_65_to_127_octets", MV643XX_STAT(mib_counters.frames_65_to_127_octets) },
|
3174 |
|
|
{ "frames_128_to_255_octets", MV643XX_STAT(mib_counters.frames_128_to_255_octets) },
|
3175 |
|
|
{ "frames_256_to_511_octets", MV643XX_STAT(mib_counters.frames_256_to_511_octets) },
|
3176 |
|
|
{ "frames_512_to_1023_octets", MV643XX_STAT(mib_counters.frames_512_to_1023_octets) },
|
3177 |
|
|
{ "frames_1024_to_max_octets", MV643XX_STAT(mib_counters.frames_1024_to_max_octets) },
|
3178 |
|
|
{ "good_octets_sent", MV643XX_STAT(mib_counters.good_octets_sent) },
|
3179 |
|
|
{ "good_frames_sent", MV643XX_STAT(mib_counters.good_frames_sent) },
|
3180 |
|
|
{ "excessive_collision", MV643XX_STAT(mib_counters.excessive_collision) },
|
3181 |
|
|
{ "multicast_frames_sent", MV643XX_STAT(mib_counters.multicast_frames_sent) },
|
3182 |
|
|
{ "broadcast_frames_sent", MV643XX_STAT(mib_counters.broadcast_frames_sent) },
|
3183 |
|
|
{ "unrec_mac_control_received", MV643XX_STAT(mib_counters.unrec_mac_control_received) },
|
3184 |
|
|
{ "fc_sent", MV643XX_STAT(mib_counters.fc_sent) },
|
3185 |
|
|
{ "good_fc_received", MV643XX_STAT(mib_counters.good_fc_received) },
|
3186 |
|
|
{ "bad_fc_received", MV643XX_STAT(mib_counters.bad_fc_received) },
|
3187 |
|
|
{ "undersize_received", MV643XX_STAT(mib_counters.undersize_received) },
|
3188 |
|
|
{ "fragments_received", MV643XX_STAT(mib_counters.fragments_received) },
|
3189 |
|
|
{ "oversize_received", MV643XX_STAT(mib_counters.oversize_received) },
|
3190 |
|
|
{ "jabber_received", MV643XX_STAT(mib_counters.jabber_received) },
|
3191 |
|
|
{ "mac_receive_error", MV643XX_STAT(mib_counters.mac_receive_error) },
|
3192 |
|
|
{ "bad_crc_event", MV643XX_STAT(mib_counters.bad_crc_event) },
|
3193 |
|
|
{ "collision", MV643XX_STAT(mib_counters.collision) },
|
3194 |
|
|
{ "late_collision", MV643XX_STAT(mib_counters.late_collision) },
|
3195 |
|
|
};
|
3196 |
|
|
|
3197 |
|
|
#define MV643XX_STATS_LEN ARRAY_SIZE(mv643xx_gstrings_stats)
|
3198 |
|
|
|
3199 |
|
|
static void mv643xx_get_drvinfo(struct net_device *netdev,
|
3200 |
|
|
struct ethtool_drvinfo *drvinfo)
|
3201 |
|
|
{
|
3202 |
|
|
strncpy(drvinfo->driver, mv643xx_driver_name, 32);
|
3203 |
|
|
strncpy(drvinfo->version, mv643xx_driver_version, 32);
|
3204 |
|
|
strncpy(drvinfo->fw_version, "N/A", 32);
|
3205 |
|
|
strncpy(drvinfo->bus_info, "mv643xx", 32);
|
3206 |
|
|
drvinfo->n_stats = MV643XX_STATS_LEN;
|
3207 |
|
|
}
|
3208 |
|
|
|
3209 |
|
|
static int mv643xx_get_sset_count(struct net_device *netdev, int sset)
|
3210 |
|
|
{
|
3211 |
|
|
switch (sset) {
|
3212 |
|
|
case ETH_SS_STATS:
|
3213 |
|
|
return MV643XX_STATS_LEN;
|
3214 |
|
|
default:
|
3215 |
|
|
return -EOPNOTSUPP;
|
3216 |
|
|
}
|
3217 |
|
|
}
|
3218 |
|
|
|
3219 |
|
|
static void mv643xx_get_ethtool_stats(struct net_device *netdev,
|
3220 |
|
|
struct ethtool_stats *stats, uint64_t *data)
|
3221 |
|
|
{
|
3222 |
|
|
struct mv643xx_private *mp = netdev->priv;
|
3223 |
|
|
int i;
|
3224 |
|
|
|
3225 |
|
|
eth_update_mib_counters(mp);
|
3226 |
|
|
|
3227 |
|
|
for (i = 0; i < MV643XX_STATS_LEN; i++) {
|
3228 |
|
|
char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;
|
3229 |
|
|
data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
|
3230 |
|
|
sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
|
3231 |
|
|
}
|
3232 |
|
|
}
|
3233 |
|
|
|
3234 |
|
|
static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
|
3235 |
|
|
uint8_t *data)
|
3236 |
|
|
{
|
3237 |
|
|
int i;
|
3238 |
|
|
|
3239 |
|
|
switch(stringset) {
|
3240 |
|
|
case ETH_SS_STATS:
|
3241 |
|
|
for (i=0; i < MV643XX_STATS_LEN; i++) {
|
3242 |
|
|
memcpy(data + i * ETH_GSTRING_LEN,
|
3243 |
|
|
mv643xx_gstrings_stats[i].stat_string,
|
3244 |
|
|
ETH_GSTRING_LEN);
|
3245 |
|
|
}
|
3246 |
|
|
break;
|
3247 |
|
|
}
|
3248 |
|
|
}
|
3249 |
|
|
|
3250 |
|
|
static u32 mv643xx_eth_get_link(struct net_device *dev)
|
3251 |
|
|
{
|
3252 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
3253 |
|
|
|
3254 |
|
|
return mii_link_ok(&mp->mii);
|
3255 |
|
|
}
|
3256 |
|
|
|
3257 |
|
|
static int mv643xx_eth_nway_restart(struct net_device *dev)
|
3258 |
|
|
{
|
3259 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
3260 |
|
|
|
3261 |
|
|
return mii_nway_restart(&mp->mii);
|
3262 |
|
|
}
|
3263 |
|
|
|
3264 |
|
|
static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
3265 |
|
|
{
|
3266 |
|
|
struct mv643xx_private *mp = netdev_priv(dev);
|
3267 |
|
|
|
3268 |
|
|
return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
|
3269 |
|
|
}
|
3270 |
|
|
|
3271 |
|
|
static const struct ethtool_ops mv643xx_ethtool_ops = {
|
3272 |
|
|
.get_settings = mv643xx_get_settings,
|
3273 |
|
|
.set_settings = mv643xx_set_settings,
|
3274 |
|
|
.get_drvinfo = mv643xx_get_drvinfo,
|
3275 |
|
|
.get_link = mv643xx_eth_get_link,
|
3276 |
|
|
.set_sg = ethtool_op_set_sg,
|
3277 |
|
|
.get_sset_count = mv643xx_get_sset_count,
|
3278 |
|
|
.get_ethtool_stats = mv643xx_get_ethtool_stats,
|
3279 |
|
|
.get_strings = mv643xx_get_strings,
|
3280 |
|
|
.nway_reset = mv643xx_eth_nway_restart,
|
3281 |
|
|
};
|
3282 |
|
|
|
3283 |
|
|
/************* End ethtool support *************************/
|