fsl_pq_mdio: Clean up tbi address configuration
[linux-2.6-block.git] / drivers / net / ethernet / via / via-velocity.c
CommitLineData
1da177e4
LT
1/*
2 * This code is derived from the VIA reference driver (copyright message
3 * below) provided to Red Hat by VIA Networking Technologies, Inc. for
4 * addition to the Linux kernel.
5 *
6 * The code has been merged into one source file, cleaned up to follow
7 * Linux coding style, ported to the Linux 2.6 kernel tree and cleaned
8 * for 64bit hardware platforms.
9 *
10 * TODO
1da177e4 11 * rx_copybreak/alignment
1da177e4
LT
12 * More testing
13 *
113aa838 14 * The changes are (c) Copyright 2004, Red Hat Inc. <alan@lxorguk.ukuu.org.uk>
1da177e4
LT
15 * Additional fixes and clean up: Francois Romieu
16 *
17 * This source has not been verified for use in safety critical systems.
18 *
19 * Please direct queries about the revamped driver to the linux-kernel
20 * list not VIA.
21 *
22 * Original code:
23 *
24 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
25 * All rights reserved.
26 *
27 * This software may be redistributed and/or modified under
28 * the terms of the GNU General Public License as published by the Free
29 * Software Foundation; either version 2 of the License, or
30 * any later version.
31 *
32 * This program is distributed in the hope that it will be useful, but
33 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35 * for more details.
36 *
37 * Author: Chuang Liang-Shing, AJ Jiang
38 *
39 * Date: Jan 24, 2003
40 *
41 * MODULE_LICENSE("GPL");
42 *
43 */
44
1da177e4
LT
45#include <linux/module.h>
46#include <linux/types.h>
73b54688 47#include <linux/bitops.h>
1da177e4
LT
48#include <linux/init.h>
49#include <linux/mm.h>
50#include <linux/errno.h>
51#include <linux/ioport.h>
52#include <linux/pci.h>
53#include <linux/kernel.h>
54#include <linux/netdevice.h>
55#include <linux/etherdevice.h>
56#include <linux/skbuff.h>
57#include <linux/delay.h>
58#include <linux/timer.h>
59#include <linux/slab.h>
60#include <linux/interrupt.h>
1da177e4
LT
61#include <linux/string.h>
62#include <linux/wait.h>
c4067400 63#include <linux/io.h>
1da177e4 64#include <linux/if.h>
c4067400 65#include <linux/uaccess.h>
1da177e4
LT
66#include <linux/proc_fs.h>
67#include <linux/inetdevice.h>
68#include <linux/reboot.h>
69#include <linux/ethtool.h>
70#include <linux/mii.h>
71#include <linux/in.h>
72#include <linux/if_arp.h>
501e4d24 73#include <linux/if_vlan.h>
1da177e4
LT
74#include <linux/ip.h>
75#include <linux/tcp.h>
76#include <linux/udp.h>
77#include <linux/crc-ccitt.h>
78#include <linux/crc32.h>
79
80#include "via-velocity.h"
81
82
c4067400 83static int velocity_nics;
1da177e4
LT
84static int msglevel = MSG_LEVEL_INFO;
85
01faccbf
SH
86/**
87 * mac_get_cam_mask - Read a CAM mask
88 * @regs: register block for this velocity
89 * @mask: buffer to store mask
90 *
91 * Fetch the mask bits of the selected CAM and store them into the
92 * provided mask buffer.
93 */
c4067400 94static void mac_get_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
01faccbf
SH
95{
96 int i;
97
98 /* Select CAM mask */
99 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
100
101 writeb(0, &regs->CAMADDR);
102
103 /* read mask */
104 for (i = 0; i < 8; i++)
105 *mask++ = readb(&(regs->MARCAM[i]));
106
107 /* disable CAMEN */
108 writeb(0, &regs->CAMADDR);
109
110 /* Select mar */
111 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
01faccbf
SH
112}
113
01faccbf
SH
114/**
115 * mac_set_cam_mask - Set a CAM mask
116 * @regs: register block for this velocity
117 * @mask: CAM mask to load
118 *
119 * Store a new mask into a CAM
120 */
c4067400 121static void mac_set_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
01faccbf
SH
122{
123 int i;
124 /* Select CAM mask */
125 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
126
127 writeb(CAMADDR_CAMEN, &regs->CAMADDR);
128
c4067400 129 for (i = 0; i < 8; i++)
01faccbf 130 writeb(*mask++, &(regs->MARCAM[i]));
c4067400 131
01faccbf
SH
132 /* disable CAMEN */
133 writeb(0, &regs->CAMADDR);
134
135 /* Select mar */
136 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
137}
138
c4067400 139static void mac_set_vlan_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
01faccbf
SH
140{
141 int i;
142 /* Select CAM mask */
143 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
144
145 writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
146
c4067400 147 for (i = 0; i < 8; i++)
01faccbf 148 writeb(*mask++, &(regs->MARCAM[i]));
c4067400 149
01faccbf
SH
150 /* disable CAMEN */
151 writeb(0, &regs->CAMADDR);
152
153 /* Select mar */
154 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
155}
156
157/**
158 * mac_set_cam - set CAM data
159 * @regs: register block of this velocity
160 * @idx: Cam index
161 * @addr: 2 or 6 bytes of CAM data
162 *
163 * Load an address or vlan tag into a CAM
164 */
c4067400 165static void mac_set_cam(struct mac_regs __iomem *regs, int idx, const u8 *addr)
01faccbf
SH
166{
167 int i;
168
169 /* Select CAM mask */
170 BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
171
172 idx &= (64 - 1);
173
174 writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
175
c4067400 176 for (i = 0; i < 6; i++)
01faccbf 177 writeb(*addr++, &(regs->MARCAM[i]));
c4067400 178
01faccbf
SH
179 BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
180
181 udelay(10);
182
183 writeb(0, &regs->CAMADDR);
184
185 /* Select mar */
186 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
187}
188
c4067400 189static void mac_set_vlan_cam(struct mac_regs __iomem *regs, int idx,
01faccbf
SH
190 const u8 *addr)
191{
192
193 /* Select CAM mask */
194 BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
195
196 idx &= (64 - 1);
197
198 writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
199 writew(*((u16 *) addr), &regs->MARCAM[0]);
200
201 BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
202
203 udelay(10);
204
205 writeb(0, &regs->CAMADDR);
206
207 /* Select mar */
208 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
209}
210
211
212/**
213 * mac_wol_reset - reset WOL after exiting low power
214 * @regs: register block of this velocity
215 *
216 * Called after we drop out of wake on lan mode in order to
217 * reset the Wake on lan features. This function doesn't restore
218 * the rest of the logic from the result of sleep/wakeup
219 */
c4067400 220static void mac_wol_reset(struct mac_regs __iomem *regs)
01faccbf
SH
221{
222
223 /* Turn off SWPTAG right after leaving power mode */
224 BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
225 /* clear sticky bits */
226 BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
227
228 BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
229 BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
230 /* disable force PME-enable */
231 writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
232 /* disable power-event config bit */
233 writew(0xFFFF, &regs->WOLCRClr);
234 /* clear power status */
235 writew(0xFFFF, &regs->WOLSRClr);
236}
1da177e4 237
7282d491 238static const struct ethtool_ops velocity_ethtool_ops;
1da177e4
LT
239
240/*
241 Define module options
242*/
243
244MODULE_AUTHOR("VIA Networking Technologies, Inc.");
245MODULE_LICENSE("GPL");
246MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
247
c4067400
DJ
248#define VELOCITY_PARAM(N, D) \
249 static int N[MAX_UNITS] = OPTION_DEFAULT;\
1da177e4 250 module_param_array(N, int, NULL, 0); \
c4067400 251 MODULE_PARM_DESC(N, D);
1da177e4
LT
252
253#define RX_DESC_MIN 64
254#define RX_DESC_MAX 255
255#define RX_DESC_DEF 64
256VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors");
257
258#define TX_DESC_MIN 16
259#define TX_DESC_MAX 256
260#define TX_DESC_DEF 64
261VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
262
1da177e4
LT
263#define RX_THRESH_MIN 0
264#define RX_THRESH_MAX 3
265#define RX_THRESH_DEF 0
266/* rx_thresh[] is used for controlling the receive fifo threshold.
267 0: indicate the rxfifo threshold is 128 bytes.
268 1: indicate the rxfifo threshold is 512 bytes.
269 2: indicate the rxfifo threshold is 1024 bytes.
270 3: indicate the rxfifo threshold is store & forward.
271*/
272VELOCITY_PARAM(rx_thresh, "Receive fifo threshold");
273
274#define DMA_LENGTH_MIN 0
275#define DMA_LENGTH_MAX 7
2a5774f7 276#define DMA_LENGTH_DEF 6
1da177e4
LT
277
278/* DMA_length[] is used for controlling the DMA length
279 0: 8 DWORDs
280 1: 16 DWORDs
281 2: 32 DWORDs
282 3: 64 DWORDs
283 4: 128 DWORDs
284 5: 256 DWORDs
285 6: SF(flush till emply)
286 7: SF(flush till emply)
287*/
288VELOCITY_PARAM(DMA_length, "DMA length");
289
1da177e4
LT
290#define IP_ALIG_DEF 0
291/* IP_byte_align[] is used for IP header DWORD byte aligned
292 0: indicate the IP header won't be DWORD byte aligned.(Default) .
293 1: indicate the IP header will be DWORD byte aligned.
25985edc 294 In some environment, the IP header should be DWORD byte aligned,
1da177e4
LT
295 or the packet will be droped when we receive it. (eg: IPVS)
296*/
297VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
298
1da177e4
LT
299#define FLOW_CNTL_DEF 1
300#define FLOW_CNTL_MIN 1
301#define FLOW_CNTL_MAX 5
302
303/* flow_control[] is used for setting the flow control ability of NIC.
304 1: hardware deafult - AUTO (default). Use Hardware default value in ANAR.
305 2: enable TX flow control.
306 3: enable RX flow control.
307 4: enable RX/TX flow control.
308 5: disable
309*/
310VELOCITY_PARAM(flow_control, "Enable flow control ability");
311
312#define MED_LNK_DEF 0
313#define MED_LNK_MIN 0
15419227 314#define MED_LNK_MAX 5
1da177e4
LT
315/* speed_duplex[] is used for setting the speed and duplex mode of NIC.
316 0: indicate autonegotiation for both speed and duplex mode
317 1: indicate 100Mbps half duplex mode
318 2: indicate 100Mbps full duplex mode
319 3: indicate 10Mbps half duplex mode
320 4: indicate 10Mbps full duplex mode
15419227 321 5: indicate 1000Mbps full duplex mode
1da177e4
LT
322
323 Note:
c4067400
DJ
324 if EEPROM have been set to the force mode, this option is ignored
325 by driver.
1da177e4
LT
326*/
327VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
328
329#define VAL_PKT_LEN_DEF 0
330/* ValPktLen[] is used for setting the checksum offload ability of NIC.
331 0: Receive frame with invalid layer 2 length (Default)
332 1: Drop frame with invalid layer 2 length
333*/
334VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
335
336#define WOL_OPT_DEF 0
337#define WOL_OPT_MIN 0
338#define WOL_OPT_MAX 7
339/* wol_opts[] is used for controlling wake on lan behavior.
340 0: Wake up if recevied a magic packet. (Default)
341 1: Wake up if link status is on/off.
342 2: Wake up if recevied an arp packet.
343 4: Wake up if recevied any unicast packet.
344 Those value can be sumed up to support more than one option.
345*/
346VELOCITY_PARAM(wol_opts, "Wake On Lan options");
347
1da177e4
LT
348static int rx_copybreak = 200;
349module_param(rx_copybreak, int, 0644);
350MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
351
1da177e4
LT
352/*
353 * Internal board variants. At the moment we have only one
354 */
4f14b92f 355static struct velocity_info_tbl chip_info_table[] = {
cabb7667
JG
356 {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 1, 0x00FFFFFFUL},
357 { }
1da177e4
LT
358};
359
360/*
361 * Describe the PCI device identifiers that we support in this
362 * device driver. Used for hotplug autoloading.
363 */
a3aa1884 364static DEFINE_PCI_DEVICE_TABLE(velocity_id_table) = {
e54f4893
JG
365 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
366 { }
1da177e4
LT
367};
368
369MODULE_DEVICE_TABLE(pci, velocity_id_table);
370
371/**
372 * get_chip_name - identifier to name
373 * @id: chip identifier
374 *
375 * Given a chip identifier return a suitable description. Returns
376 * a pointer a static string valid while the driver is loaded.
377 */
01faccbf 378static const char __devinit *get_chip_name(enum chip_type chip_id)
1da177e4
LT
379{
380 int i;
381 for (i = 0; chip_info_table[i].name != NULL; i++)
382 if (chip_info_table[i].chip_id == chip_id)
383 break;
384 return chip_info_table[i].name;
385}
386
387/**
388 * velocity_remove1 - device unplug
389 * @pdev: PCI device being removed
390 *
391 * Device unload callback. Called on an unplug or on module
392 * unload for each active device that is present. Disconnects
393 * the device from the network layer and frees all the resources
394 */
1da177e4
LT
395static void __devexit velocity_remove1(struct pci_dev *pdev)
396{
397 struct net_device *dev = pci_get_drvdata(pdev);
8ab6f3f7 398 struct velocity_info *vptr = netdev_priv(dev);
1da177e4 399
1da177e4
LT
400 unregister_netdev(dev);
401 iounmap(vptr->mac_regs);
402 pci_release_regions(pdev);
403 pci_disable_device(pdev);
404 pci_set_drvdata(pdev, NULL);
405 free_netdev(dev);
406
407 velocity_nics--;
408}
409
410/**
411 * velocity_set_int_opt - parser for integer options
412 * @opt: pointer to option value
413 * @val: value the user requested (or -1 for default)
414 * @min: lowest value allowed
415 * @max: highest value allowed
416 * @def: default value
417 * @name: property name
418 * @dev: device name
419 *
420 * Set an integer property in the module options. This function does
421 * all the verification and checking as well as reporting so that
422 * we don't duplicate code for each option.
423 */
07b5f6a6 424static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, const char *devname)
1da177e4
LT
425{
426 if (val == -1)
427 *opt = def;
428 else if (val < min || val > max) {
429 VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n",
430 devname, name, min, max);
431 *opt = def;
432 } else {
433 VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
434 devname, name, val);
435 *opt = val;
436 }
437}
438
439/**
440 * velocity_set_bool_opt - parser for boolean options
441 * @opt: pointer to option value
442 * @val: value the user requested (or -1 for default)
443 * @def: default value (yes/no)
444 * @flag: numeric value to set for true.
445 * @name: property name
446 * @dev: device name
447 *
448 * Set a boolean property in the module options. This function does
449 * all the verification and checking as well as reporting so that
450 * we don't duplicate code for each option.
451 */
c4067400 452static void __devinit velocity_set_bool_opt(u32 *opt, int val, int def, u32 flag, char *name, const char *devname)
1da177e4
LT
453{
454 (*opt) &= (~flag);
455 if (val == -1)
456 *opt |= (def ? flag : 0);
457 else if (val < 0 || val > 1) {
6aa20a22 458 printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
1da177e4
LT
459 devname, name);
460 *opt |= (def ? flag : 0);
461 } else {
6aa20a22 462 printk(KERN_INFO "%s: set parameter %s to %s\n",
1da177e4
LT
463 devname, name, val ? "TRUE" : "FALSE");
464 *opt |= (val ? flag : 0);
465 }
466}
467
468/**
469 * velocity_get_options - set options on device
470 * @opts: option structure for the device
471 * @index: index of option to use in module options array
472 * @devname: device name
473 *
474 * Turn the module and command options into a single structure
475 * for the current device
476 */
07b5f6a6 477static void __devinit velocity_get_options(struct velocity_opt *opts, int index, const char *devname)
1da177e4
LT
478{
479
480 velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
481 velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
482 velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
483 velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
501e4d24 484
1da177e4
LT
485 velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
486 velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
487 velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
488 velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
489 velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
1da177e4
LT
490 opts->numrx = (opts->numrx & ~3);
491}
492
493/**
494 * velocity_init_cam_filter - initialise CAM
495 * @vptr: velocity to program
496 *
497 * Initialize the content addressable memory used for filters. Load
498 * appropriately according to the presence of VLAN
499 */
1da177e4
LT
500static void velocity_init_cam_filter(struct velocity_info *vptr)
501{
c4067400 502 struct mac_regs __iomem *regs = vptr->mac_regs;
73b54688 503 unsigned int vid, i = 0;
1da177e4
LT
504
505 /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
506 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
507 WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
508
509 /* Disable all CAMs */
510 memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
511 memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
01faccbf
SH
512 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
513 mac_set_cam_mask(regs, vptr->mCAMmask);
1da177e4 514
d4f73c8e 515 /* Enable VCAMs */
73b54688
JP
516 for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) {
517 mac_set_vlan_cam(regs, i, (u8 *) &vid);
518 vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
519 if (++i >= VCAM_SIZE)
520 break;
521 }
522 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
d4f73c8e
FR
523}
524
501e4d24
SH
525static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
526{
527 struct velocity_info *vptr = netdev_priv(dev);
528
c4067400 529 spin_lock_irq(&vptr->lock);
73b54688 530 set_bit(vid, vptr->active_vlans);
501e4d24 531 velocity_init_cam_filter(vptr);
c4067400 532 spin_unlock_irq(&vptr->lock);
501e4d24
SH
533}
534
535static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
536{
537 struct velocity_info *vptr = netdev_priv(dev);
538
c4067400 539 spin_lock_irq(&vptr->lock);
73b54688 540 clear_bit(vid, vptr->active_vlans);
501e4d24 541 velocity_init_cam_filter(vptr);
c4067400 542 spin_unlock_irq(&vptr->lock);
501e4d24
SH
543}
544
3c4dc711
FR
545static void velocity_init_rx_ring_indexes(struct velocity_info *vptr)
546{
547 vptr->rx.dirty = vptr->rx.filled = vptr->rx.curr = 0;
548}
501e4d24 549
1da177e4
LT
550/**
551 * velocity_rx_reset - handle a receive reset
552 * @vptr: velocity we are resetting
553 *
554 * Reset the ownership and status for the receive ring side.
555 * Hand all the receive queue to the NIC.
556 */
1da177e4
LT
557static void velocity_rx_reset(struct velocity_info *vptr)
558{
559
c4067400 560 struct mac_regs __iomem *regs = vptr->mac_regs;
1da177e4
LT
561 int i;
562
3c4dc711 563 velocity_init_rx_ring_indexes(vptr);
1da177e4
LT
564
565 /*
566 * Init state, all RD entries belong to the NIC
567 */
568 for (i = 0; i < vptr->options.numrx; ++i)
0fe9f15e 569 vptr->rx.ring[i].rdesc0.len |= OWNED_BY_NIC;
1da177e4
LT
570
571 writew(vptr->options.numrx, &regs->RBRDU);
0fe9f15e 572 writel(vptr->rx.pool_dma, &regs->RDBaseLo);
1da177e4
LT
573 writew(0, &regs->RDIdx);
574 writew(vptr->options.numrx - 1, &regs->RDCSize);
575}
576
577/**
2cf71d2e
DJ
578 * velocity_get_opt_media_mode - get media selection
579 * @vptr: velocity adapter
1da177e4 580 *
2cf71d2e
DJ
581 * Get the media mode stored in EEPROM or module options and load
582 * mii_status accordingly. The requested link state information
583 * is also returned.
1da177e4 584 */
2cf71d2e 585static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
1da177e4 586{
2cf71d2e 587 u32 status = 0;
1da177e4 588
2cf71d2e
DJ
589 switch (vptr->options.spd_dpx) {
590 case SPD_DPX_AUTO:
591 status = VELOCITY_AUTONEG_ENABLE;
1da177e4 592 break;
2cf71d2e
DJ
593 case SPD_DPX_100_FULL:
594 status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
595 break;
596 case SPD_DPX_10_FULL:
597 status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
598 break;
599 case SPD_DPX_100_HALF:
600 status = VELOCITY_SPEED_100;
601 break;
602 case SPD_DPX_10_HALF:
603 status = VELOCITY_SPEED_10;
604 break;
15419227 605 case SPD_DPX_1000_FULL:
606 status = VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
607 break;
2cf71d2e
DJ
608 }
609 vptr->mii_status = status;
610 return status;
611}
1da177e4 612
2cf71d2e
DJ
613/**
614 * safe_disable_mii_autopoll - autopoll off
615 * @regs: velocity registers
616 *
617 * Turn off the autopoll and wait for it to disable on the chip
618 */
619static void safe_disable_mii_autopoll(struct mac_regs __iomem *regs)
620{
621 u16 ww;
1da177e4 622
2cf71d2e
DJ
623 /* turn off MAUTO */
624 writeb(0, &regs->MIICR);
625 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
626 udelay(1);
627 if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
628 break;
629 }
630}
1da177e4 631
2cf71d2e
DJ
632/**
633 * enable_mii_autopoll - turn on autopolling
634 * @regs: velocity registers
635 *
636 * Enable the MII link status autopoll feature on the Velocity
637 * hardware. Wait for it to enable.
638 */
639static void enable_mii_autopoll(struct mac_regs __iomem *regs)
640{
641 int ii;
1da177e4 642
2cf71d2e
DJ
643 writeb(0, &(regs->MIICR));
644 writeb(MIIADR_SWMPL, &regs->MIIADR);
1da177e4 645
2cf71d2e
DJ
646 for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
647 udelay(1);
648 if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
649 break;
650 }
1da177e4 651
2cf71d2e 652 writeb(MIICR_MAUTO, &regs->MIICR);
1da177e4 653
2cf71d2e
DJ
654 for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
655 udelay(1);
656 if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
657 break;
658 }
1da177e4 659
2cf71d2e 660}
1da177e4 661
2cf71d2e
DJ
662/**
663 * velocity_mii_read - read MII data
664 * @regs: velocity registers
665 * @index: MII register index
666 * @data: buffer for received data
667 *
668 * Perform a single read of an MII 16bit register. Returns zero
669 * on success or -ETIMEDOUT if the PHY did not respond.
670 */
671static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
672{
673 u16 ww;
1da177e4 674
2cf71d2e
DJ
675 /*
676 * Disable MIICR_MAUTO, so that mii addr can be set normally
677 */
678 safe_disable_mii_autopoll(regs);
1da177e4 679
2cf71d2e 680 writeb(index, &regs->MIIADR);
1da177e4 681
2cf71d2e 682 BYTE_REG_BITS_ON(MIICR_RCMD, &regs->MIICR);
1da177e4 683
2cf71d2e
DJ
684 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
685 if (!(readb(&regs->MIICR) & MIICR_RCMD))
686 break;
687 }
1da177e4 688
2cf71d2e 689 *data = readw(&regs->MIIDATA);
1da177e4 690
2cf71d2e
DJ
691 enable_mii_autopoll(regs);
692 if (ww == W_MAX_TIMEOUT)
693 return -ETIMEDOUT;
694 return 0;
1da177e4
LT
695}
696
697/**
2cf71d2e
DJ
698 * mii_check_media_mode - check media state
699 * @regs: velocity registers
1da177e4 700 *
2cf71d2e
DJ
701 * Check the current MII status and determine the link status
702 * accordingly
1da177e4 703 */
2cf71d2e 704static u32 mii_check_media_mode(struct mac_regs __iomem *regs)
1da177e4 705{
2cf71d2e
DJ
706 u32 status = 0;
707 u16 ANAR;
1da177e4 708
3a7f8681 709 if (!MII_REG_BITS_IS_ON(BMSR_LSTATUS, MII_BMSR, regs))
2cf71d2e 710 status |= VELOCITY_LINK_FAIL;
1da177e4 711
3a7f8681 712 if (MII_REG_BITS_IS_ON(ADVERTISE_1000FULL, MII_CTRL1000, regs))
2cf71d2e 713 status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
3a7f8681 714 else if (MII_REG_BITS_IS_ON(ADVERTISE_1000HALF, MII_CTRL1000, regs))
2cf71d2e
DJ
715 status |= (VELOCITY_SPEED_1000);
716 else {
3a7f8681
FR
717 velocity_mii_read(regs, MII_ADVERTISE, &ANAR);
718 if (ANAR & ADVERTISE_100FULL)
2cf71d2e 719 status |= (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
3a7f8681 720 else if (ANAR & ADVERTISE_100HALF)
2cf71d2e 721 status |= VELOCITY_SPEED_100;
3a7f8681 722 else if (ANAR & ADVERTISE_10FULL)
2cf71d2e
DJ
723 status |= (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
724 else
725 status |= (VELOCITY_SPEED_10);
1da177e4
LT
726 }
727
3a7f8681
FR
728 if (MII_REG_BITS_IS_ON(BMCR_ANENABLE, MII_BMCR, regs)) {
729 velocity_mii_read(regs, MII_ADVERTISE, &ANAR);
730 if ((ANAR & (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF))
731 == (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF)) {
732 if (MII_REG_BITS_IS_ON(ADVERTISE_1000HALF | ADVERTISE_1000FULL, MII_CTRL1000, regs))
2cf71d2e
DJ
733 status |= VELOCITY_AUTONEG_ENABLE;
734 }
1da177e4 735 }
1da177e4 736
2cf71d2e
DJ
737 return status;
738}
39a11bd9 739
1da177e4 740/**
2cf71d2e
DJ
741 * velocity_mii_write - write MII data
742 * @regs: velocity registers
743 * @index: MII register index
744 * @data: 16bit data for the MII register
1da177e4 745 *
2cf71d2e
DJ
746 * Perform a single write to an MII 16bit register. Returns zero
747 * on success or -ETIMEDOUT if the PHY did not respond.
1da177e4 748 */
2cf71d2e 749static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
1da177e4 750{
2cf71d2e 751 u16 ww;
1da177e4 752
2cf71d2e
DJ
753 /*
754 * Disable MIICR_MAUTO, so that mii addr can be set normally
e54f4893 755 */
2cf71d2e 756 safe_disable_mii_autopoll(regs);
1da177e4 757
2cf71d2e
DJ
758 /* MII reg offset */
759 writeb(mii_addr, &regs->MIIADR);
760 /* set MII data */
761 writew(data, &regs->MIIDATA);
762
763 /* turn on MIICR_WCMD */
764 BYTE_REG_BITS_ON(MIICR_WCMD, &regs->MIICR);
765
766 /* W_MAX_TIMEOUT is the timeout period */
767 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
768 udelay(5);
769 if (!(readb(&regs->MIICR) & MIICR_WCMD))
770 break;
1da177e4 771 }
2cf71d2e 772 enable_mii_autopoll(regs);
6aa20a22 773
2cf71d2e
DJ
774 if (ww == W_MAX_TIMEOUT)
775 return -ETIMEDOUT;
776 return 0;
777}
6aa20a22 778
2cf71d2e
DJ
779/**
780 * set_mii_flow_control - flow control setup
781 * @vptr: velocity interface
782 *
783 * Set up the flow control on this interface according to
784 * the supplied user/eeprom options.
785 */
786static void set_mii_flow_control(struct velocity_info *vptr)
787{
788 /*Enable or Disable PAUSE in ANAR */
789 switch (vptr->options.flow_cntl) {
790 case FLOW_CNTL_TX:
3a7f8681
FR
791 MII_REG_BITS_OFF(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs);
792 MII_REG_BITS_ON(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
2cf71d2e 793 break;
1da177e4 794
2cf71d2e 795 case FLOW_CNTL_RX:
3a7f8681
FR
796 MII_REG_BITS_ON(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs);
797 MII_REG_BITS_ON(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
2cf71d2e 798 break;
1da177e4 799
2cf71d2e 800 case FLOW_CNTL_TX_RX:
3a7f8681 801 MII_REG_BITS_ON(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs);
4a35ecf8 802 MII_REG_BITS_OFF(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
2cf71d2e 803 break;
1da177e4 804
2cf71d2e 805 case FLOW_CNTL_DISABLE:
3a7f8681
FR
806 MII_REG_BITS_OFF(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs);
807 MII_REG_BITS_OFF(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
2cf71d2e
DJ
808 break;
809 default:
810 break;
811 }
812}
1da177e4 813
2cf71d2e
DJ
814/**
815 * mii_set_auto_on - autonegotiate on
816 * @vptr: velocity
817 *
818 * Enable autonegotation on this interface
819 */
820static void mii_set_auto_on(struct velocity_info *vptr)
821{
3a7f8681
FR
822 if (MII_REG_BITS_IS_ON(BMCR_ANENABLE, MII_BMCR, vptr->mac_regs))
823 MII_REG_BITS_ON(BMCR_ANRESTART, MII_BMCR, vptr->mac_regs);
2cf71d2e 824 else
3a7f8681 825 MII_REG_BITS_ON(BMCR_ANENABLE, MII_BMCR, vptr->mac_regs);
2cf71d2e 826}
1da177e4 827
2cf71d2e
DJ
828static u32 check_connection_type(struct mac_regs __iomem *regs)
829{
830 u32 status = 0;
831 u8 PHYSR0;
832 u16 ANAR;
833 PHYSR0 = readb(&regs->PHYSR0);
1da177e4 834
2cf71d2e
DJ
835 /*
836 if (!(PHYSR0 & PHYSR0_LINKGD))
837 status|=VELOCITY_LINK_FAIL;
838 */
1da177e4 839
2cf71d2e
DJ
840 if (PHYSR0 & PHYSR0_FDPX)
841 status |= VELOCITY_DUPLEX_FULL;
1da177e4 842
2cf71d2e
DJ
843 if (PHYSR0 & PHYSR0_SPDG)
844 status |= VELOCITY_SPEED_1000;
845 else if (PHYSR0 & PHYSR0_SPD10)
846 status |= VELOCITY_SPEED_10;
847 else
848 status |= VELOCITY_SPEED_100;
1da177e4 849
3a7f8681
FR
850 if (MII_REG_BITS_IS_ON(BMCR_ANENABLE, MII_BMCR, regs)) {
851 velocity_mii_read(regs, MII_ADVERTISE, &ANAR);
852 if ((ANAR & (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF))
853 == (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF)) {
854 if (MII_REG_BITS_IS_ON(ADVERTISE_1000HALF | ADVERTISE_1000FULL, MII_CTRL1000, regs))
2cf71d2e
DJ
855 status |= VELOCITY_AUTONEG_ENABLE;
856 }
1da177e4
LT
857 }
858
2cf71d2e
DJ
859 return status;
860}
1da177e4 861
2cf71d2e
DJ
862/**
863 * velocity_set_media_mode - set media mode
864 * @mii_status: old MII link state
865 *
866 * Check the media link state and configure the flow control
867 * PHY and also velocity hardware setup accordingly. In particular
868 * we need to set up CD polling and frame bursting.
869 */
870static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
871{
872 u32 curr_status;
873 struct mac_regs __iomem *regs = vptr->mac_regs;
1da177e4 874
2cf71d2e
DJ
875 vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
876 curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
07b5f6a6 877
2cf71d2e
DJ
878 /* Set mii link status */
879 set_mii_flow_control(vptr);
1da177e4 880
6aa20a22 881 /*
a34f0b31 882 Check if new status is consistent with current status
8e95a202
JP
883 if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) ||
884 (mii_status==curr_status)) {
2cf71d2e
DJ
885 vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
886 vptr->mii_status=check_connection_type(vptr->mac_regs);
887 VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
888 return 0;
889 }
1da177e4 890 */
6aa20a22 891
2cf71d2e 892 if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
3a7f8681 893 MII_REG_BITS_ON(AUXCR_MDPPS, MII_NCONFIG, vptr->mac_regs);
1da177e4
LT
894
895 /*
2cf71d2e 896 * If connection type is AUTO
1da177e4 897 */
2cf71d2e
DJ
898 if (mii_status & VELOCITY_AUTONEG_ENABLE) {
899 VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n");
900 /* clear force MAC mode bit */
901 BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
902 /* set duplex mode of MAC according to duplex mode of MII */
3a7f8681
FR
903 MII_REG_BITS_ON(ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF, MII_ADVERTISE, vptr->mac_regs);
904 MII_REG_BITS_ON(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs);
905 MII_REG_BITS_ON(BMCR_SPEED1000, MII_BMCR, vptr->mac_regs);
6aa20a22 906
2cf71d2e
DJ
907 /* enable AUTO-NEGO mode */
908 mii_set_auto_on(vptr);
909 } else {
15419227 910 u16 CTRL1000;
2cf71d2e
DJ
911 u16 ANAR;
912 u8 CHIPGCR;
1da177e4 913
2cf71d2e
DJ
914 /*
915 * 1. if it's 3119, disable frame bursting in halfduplex mode
916 * and enable it in fullduplex mode
917 * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR
918 * 3. only enable CD heart beat counter in 10HD mode
919 */
1da177e4 920
2cf71d2e
DJ
921 /* set force MAC mode bit */
922 BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
1da177e4 923
2cf71d2e 924 CHIPGCR = readb(&regs->CHIPGCR);
15419227 925
926 if (mii_status & VELOCITY_SPEED_1000)
927 CHIPGCR |= CHIPGCR_FCGMII;
928 else
929 CHIPGCR &= ~CHIPGCR_FCGMII;
501e4d24 930
2cf71d2e
DJ
931 if (mii_status & VELOCITY_DUPLEX_FULL) {
932 CHIPGCR |= CHIPGCR_FCFDX;
933 writeb(CHIPGCR, &regs->CHIPGCR);
934 VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n");
935 if (vptr->rev_id < REV_ID_VT3216_A0)
936 BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
937 } else {
938 CHIPGCR &= ~CHIPGCR_FCFDX;
939 VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n");
940 writeb(CHIPGCR, &regs->CHIPGCR);
941 if (vptr->rev_id < REV_ID_VT3216_A0)
942 BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
943 }
1da177e4 944
15419227 945 velocity_mii_read(vptr->mac_regs, MII_CTRL1000, &CTRL1000);
946 CTRL1000 &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
947 if ((mii_status & VELOCITY_SPEED_1000) &&
948 (mii_status & VELOCITY_DUPLEX_FULL)) {
949 CTRL1000 |= ADVERTISE_1000FULL;
950 }
951 velocity_mii_write(vptr->mac_regs, MII_CTRL1000, CTRL1000);
1da177e4 952
2cf71d2e
DJ
953 if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10))
954 BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
955 else
956 BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
1da177e4 957
3a7f8681
FR
958 /* MII_REG_BITS_OFF(BMCR_SPEED1000, MII_BMCR, vptr->mac_regs); */
959 velocity_mii_read(vptr->mac_regs, MII_ADVERTISE, &ANAR);
960 ANAR &= (~(ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF));
2cf71d2e
DJ
961 if (mii_status & VELOCITY_SPEED_100) {
962 if (mii_status & VELOCITY_DUPLEX_FULL)
3a7f8681 963 ANAR |= ADVERTISE_100FULL;
2cf71d2e 964 else
3a7f8681 965 ANAR |= ADVERTISE_100HALF;
15419227 966 } else if (mii_status & VELOCITY_SPEED_10) {
2cf71d2e 967 if (mii_status & VELOCITY_DUPLEX_FULL)
3a7f8681 968 ANAR |= ADVERTISE_10FULL;
2cf71d2e 969 else
3a7f8681 970 ANAR |= ADVERTISE_10HALF;
2cf71d2e 971 }
3a7f8681 972 velocity_mii_write(vptr->mac_regs, MII_ADVERTISE, ANAR);
2cf71d2e
DJ
973 /* enable AUTO-NEGO mode */
974 mii_set_auto_on(vptr);
3a7f8681 975 /* MII_REG_BITS_ON(BMCR_ANENABLE, MII_BMCR, vptr->mac_regs); */
d3b238a0 976 }
2cf71d2e
DJ
977 /* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */
978 /* vptr->mii_status=check_connection_type(vptr->mac_regs); */
979 return VELOCITY_LINK_CHANGE;
980}
8a22dddb 981
2cf71d2e
DJ
982/**
983 * velocity_print_link_status - link status reporting
984 * @vptr: velocity to report on
985 *
986 * Turn the link status of the velocity card into a kernel log
987 * description of the new link state, detailing speed and duplex
988 * status
989 */
990static void velocity_print_link_status(struct velocity_info *vptr)
991{
6aa20a22 992
2cf71d2e
DJ
993 if (vptr->mii_status & VELOCITY_LINK_FAIL) {
994 VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
995 } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
996 VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
6aa20a22 997
2cf71d2e
DJ
998 if (vptr->mii_status & VELOCITY_SPEED_1000)
999 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
1000 else if (vptr->mii_status & VELOCITY_SPEED_100)
1001 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps");
1002 else
1003 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps");
1da177e4 1004
2cf71d2e
DJ
1005 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
1006 VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n");
1007 else
1008 VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
1009 } else {
1010 VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
1011 switch (vptr->options.spd_dpx) {
15419227 1012 case SPD_DPX_1000_FULL:
1013 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n");
1014 break;
2cf71d2e
DJ
1015 case SPD_DPX_100_HALF:
1016 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
1017 break;
1018 case SPD_DPX_100_FULL:
1019 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n");
1020 break;
1021 case SPD_DPX_10_HALF:
1022 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n");
1023 break;
1024 case SPD_DPX_10_FULL:
1025 VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n");
1026 break;
1027 default:
1028 break;
1029 }
1da177e4 1030 }
1da177e4
LT
1031}
1032
1033/**
2cf71d2e
DJ
1034 * enable_flow_control_ability - flow control
1035 * @vptr: veloity to configure
1da177e4 1036 *
2cf71d2e
DJ
1037 * Set up flow control according to the flow control options
1038 * determined by the eeprom/configuration.
1da177e4 1039 */
2cf71d2e 1040static void enable_flow_control_ability(struct velocity_info *vptr)
1da177e4 1041{
1da177e4 1042
2cf71d2e 1043 struct mac_regs __iomem *regs = vptr->mac_regs;
1da177e4 1044
2cf71d2e 1045 switch (vptr->options.flow_cntl) {
1da177e4 1046
2cf71d2e
DJ
1047 case FLOW_CNTL_DEFAULT:
1048 if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, &regs->PHYSR0))
1049 writel(CR0_FDXRFCEN, &regs->CR0Set);
1050 else
1051 writel(CR0_FDXRFCEN, &regs->CR0Clr);
1052
1053 if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, &regs->PHYSR0))
1054 writel(CR0_FDXTFCEN, &regs->CR0Set);
1055 else
1056 writel(CR0_FDXTFCEN, &regs->CR0Clr);
1057 break;
1058
1059 case FLOW_CNTL_TX:
1060 writel(CR0_FDXTFCEN, &regs->CR0Set);
1061 writel(CR0_FDXRFCEN, &regs->CR0Clr);
1062 break;
1063
1064 case FLOW_CNTL_RX:
1065 writel(CR0_FDXRFCEN, &regs->CR0Set);
1066 writel(CR0_FDXTFCEN, &regs->CR0Clr);
1067 break;
1068
1069 case FLOW_CNTL_TX_RX:
1070 writel(CR0_FDXTFCEN, &regs->CR0Set);
1071 writel(CR0_FDXRFCEN, &regs->CR0Set);
1072 break;
1073
1074 case FLOW_CNTL_DISABLE:
1075 writel(CR0_FDXRFCEN, &regs->CR0Clr);
1076 writel(CR0_FDXTFCEN, &regs->CR0Clr);
1077 break;
1078
1079 default:
1080 break;
1081 }
1da177e4 1082
1da177e4
LT
1083}
1084
1085/**
2cf71d2e
DJ
1086 * velocity_soft_reset - soft reset
1087 * @vptr: velocity to reset
1da177e4 1088 *
2cf71d2e
DJ
1089 * Kick off a soft reset of the velocity adapter and then poll
1090 * until the reset sequence has completed before returning.
1da177e4 1091 */
2cf71d2e 1092static int velocity_soft_reset(struct velocity_info *vptr)
1da177e4 1093{
2cf71d2e
DJ
1094 struct mac_regs __iomem *regs = vptr->mac_regs;
1095 int i = 0;
6aa20a22 1096
2cf71d2e 1097 writel(CR0_SFRST, &regs->CR0Set);
1da177e4 1098
2cf71d2e
DJ
1099 for (i = 0; i < W_MAX_TIMEOUT; i++) {
1100 udelay(5);
1101 if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, &regs->CR0Set))
1102 break;
1da177e4
LT
1103 }
1104
2cf71d2e
DJ
1105 if (i == W_MAX_TIMEOUT) {
1106 writel(CR0_FORSRST, &regs->CR0Set);
1107 /* FIXME: PCI POSTING */
1108 /* delay 2ms */
1109 mdelay(2);
1da177e4 1110 }
1da177e4
LT
1111 return 0;
1112}
1113
1114/**
2cf71d2e
DJ
1115 * velocity_set_multi - filter list change callback
1116 * @dev: network device
1da177e4 1117 *
2cf71d2e
DJ
1118 * Called by the network layer when the filter lists need to change
1119 * for a velocity adapter. Reload the CAMs with the new address
1120 * filter ruleset.
1da177e4 1121 */
2cf71d2e 1122static void velocity_set_multi(struct net_device *dev)
1da177e4 1123{
2cf71d2e 1124 struct velocity_info *vptr = netdev_priv(dev);
1da177e4 1125 struct mac_regs __iomem *regs = vptr->mac_regs;
2cf71d2e
DJ
1126 u8 rx_mode;
1127 int i;
22bedad3 1128 struct netdev_hw_addr *ha;
1da177e4 1129
2cf71d2e
DJ
1130 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
1131 writel(0xffffffff, &regs->MARCAM[0]);
1132 writel(0xffffffff, &regs->MARCAM[4]);
1133 rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
4cd24eaf 1134 } else if ((netdev_mc_count(dev) > vptr->multicast_limit) ||
8e95a202 1135 (dev->flags & IFF_ALLMULTI)) {
2cf71d2e
DJ
1136 writel(0xffffffff, &regs->MARCAM[0]);
1137 writel(0xffffffff, &regs->MARCAM[4]);
1138 rx_mode = (RCR_AM | RCR_AB);
1139 } else {
1140 int offset = MCAM_SIZE - vptr->multicast_limit;
1141 mac_get_cam_mask(regs, vptr->mCAMmask);
1da177e4 1142
567ec874 1143 i = 0;
22bedad3
JP
1144 netdev_for_each_mc_addr(ha, dev) {
1145 mac_set_cam(regs, i + offset, ha->addr);
2cf71d2e 1146 vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
567ec874 1147 i++;
1da177e4 1148 }
1da177e4 1149
2cf71d2e
DJ
1150 mac_set_cam_mask(regs, vptr->mCAMmask);
1151 rx_mode = RCR_AM | RCR_AB | RCR_AP;
1da177e4 1152 }
2cf71d2e
DJ
1153 if (dev->mtu > 1500)
1154 rx_mode |= RCR_AL;
1da177e4 1155
2cf71d2e 1156 BYTE_REG_BITS_ON(rx_mode, &regs->RCR);
1da177e4 1157
9088d9a4
FR
1158}
1159
2cf71d2e
DJ
1160/*
1161 * MII access , media link mode setting functions
1da177e4
LT
1162 */
1163
1da177e4 1164/**
2cf71d2e
DJ
1165 * mii_init - set up MII
1166 * @vptr: velocity adapter
1167 * @mii_status: links tatus
1da177e4 1168 *
2cf71d2e 1169 * Set up the PHY for the current link state.
1da177e4 1170 */
2cf71d2e 1171static void mii_init(struct velocity_info *vptr, u32 mii_status)
1da177e4 1172{
2cf71d2e 1173 u16 BMCR;
1da177e4 1174
2cf71d2e
DJ
1175 switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
1176 case PHYID_CICADA_CS8201:
1177 /*
1178 * Reset to hardware default
1179 */
3a7f8681 1180 MII_REG_BITS_OFF((ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP), MII_ADVERTISE, vptr->mac_regs);
2cf71d2e
DJ
1181 /*
1182 * Turn on ECHODIS bit in NWay-forced full mode and turn it
1183 * off it in NWay-forced half mode for NWay-forced v.s.
1184 * legacy-forced issue.
1185 */
1186 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
3a7f8681 1187 MII_REG_BITS_ON(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
2cf71d2e 1188 else
3a7f8681 1189 MII_REG_BITS_OFF(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
2cf71d2e
DJ
1190 /*
1191 * Turn on Link/Activity LED enable bit for CIS8201
1192 */
3a7f8681 1193 MII_REG_BITS_ON(PLED_LALBE, MII_TPISTATUS, vptr->mac_regs);
2cf71d2e
DJ
1194 break;
1195 case PHYID_VT3216_32BIT:
1196 case PHYID_VT3216_64BIT:
1197 /*
1198 * Reset to hardware default
1199 */
3a7f8681 1200 MII_REG_BITS_ON((ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP), MII_ADVERTISE, vptr->mac_regs);
2cf71d2e
DJ
1201 /*
1202 * Turn on ECHODIS bit in NWay-forced full mode and turn it
1203 * off it in NWay-forced half mode for NWay-forced v.s.
1204 * legacy-forced issue
1205 */
1206 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
3a7f8681 1207 MII_REG_BITS_ON(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
2cf71d2e 1208 else
3a7f8681 1209 MII_REG_BITS_OFF(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
2cf71d2e 1210 break;
1da177e4 1211
2cf71d2e
DJ
1212 case PHYID_MARVELL_1000:
1213 case PHYID_MARVELL_1000S:
1214 /*
1215 * Assert CRS on Transmit
1216 */
1217 MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
1218 /*
1219 * Reset to hardware default
1220 */
3a7f8681 1221 MII_REG_BITS_ON((ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP), MII_ADVERTISE, vptr->mac_regs);
2cf71d2e
DJ
1222 break;
1223 default:
1224 ;
1225 }
3a7f8681
FR
1226 velocity_mii_read(vptr->mac_regs, MII_BMCR, &BMCR);
1227 if (BMCR & BMCR_ISOLATE) {
1228 BMCR &= ~BMCR_ISOLATE;
1229 velocity_mii_write(vptr->mac_regs, MII_BMCR, BMCR);
1da177e4 1230 }
1da177e4
LT
1231}
1232
6dfc4b95
SK
1233/**
1234 * setup_queue_timers - Setup interrupt timers
1235 *
1236 * Setup interrupt frequency during suppression (timeout if the frame
1237 * count isn't filled).
1238 */
1239static void setup_queue_timers(struct velocity_info *vptr)
1240{
1241 /* Only for newer revisions */
1242 if (vptr->rev_id >= REV_ID_VT3216_A0) {
1243 u8 txqueue_timer = 0;
1244 u8 rxqueue_timer = 0;
1245
1246 if (vptr->mii_status & (VELOCITY_SPEED_1000 |
1247 VELOCITY_SPEED_100)) {
1248 txqueue_timer = vptr->options.txqueue_timer;
1249 rxqueue_timer = vptr->options.rxqueue_timer;
1250 }
1251
1252 writeb(txqueue_timer, &vptr->mac_regs->TQETMR);
1253 writeb(rxqueue_timer, &vptr->mac_regs->RQETMR);
1254 }
1255}
5ae297b0 1256
6dfc4b95
SK
1257/**
1258 * setup_adaptive_interrupts - Setup interrupt suppression
1259 *
1260 * @vptr velocity adapter
1261 *
1262 * The velocity is able to suppress interrupt during high interrupt load.
1263 * This function turns on that feature.
1264 */
1265static void setup_adaptive_interrupts(struct velocity_info *vptr)
1266{
1267 struct mac_regs __iomem *regs = vptr->mac_regs;
1268 u16 tx_intsup = vptr->options.tx_intsup;
1269 u16 rx_intsup = vptr->options.rx_intsup;
1270
1271 /* Setup default interrupt mask (will be changed below) */
1272 vptr->int_mask = INT_MASK_DEF;
1273
1274 /* Set Tx Interrupt Suppression Threshold */
1275 writeb(CAMCR_PS0, &regs->CAMCR);
1276 if (tx_intsup != 0) {
1277 vptr->int_mask &= ~(ISR_PTXI | ISR_PTX0I | ISR_PTX1I |
1278 ISR_PTX2I | ISR_PTX3I);
1279 writew(tx_intsup, &regs->ISRCTL);
1280 } else
1281 writew(ISRCTL_TSUPDIS, &regs->ISRCTL);
1282
1283 /* Set Rx Interrupt Suppression Threshold */
1284 writeb(CAMCR_PS1, &regs->CAMCR);
1285 if (rx_intsup != 0) {
1286 vptr->int_mask &= ~ISR_PRXI;
1287 writew(rx_intsup, &regs->ISRCTL);
1288 } else
1289 writew(ISRCTL_RSUPDIS, &regs->ISRCTL);
1290
1291 /* Select page to interrupt hold timer */
1292 writeb(0, &regs->CAMCR);
1293}
2cf71d2e 1294
1da177e4 1295/**
2cf71d2e
DJ
1296 * velocity_init_registers - initialise MAC registers
1297 * @vptr: velocity to init
1298 * @type: type of initialisation (hot or cold)
1da177e4 1299 *
2cf71d2e
DJ
1300 * Initialise the MAC on a reset or on first set up on the
1301 * hardware.
1da177e4 1302 */
2cf71d2e
DJ
1303static void velocity_init_registers(struct velocity_info *vptr,
1304 enum velocity_init_type type)
1da177e4 1305{
2cf71d2e
DJ
1306 struct mac_regs __iomem *regs = vptr->mac_regs;
1307 int i, mii_status;
1da177e4 1308
2cf71d2e 1309 mac_wol_reset(regs);
1da177e4 1310
2cf71d2e
DJ
1311 switch (type) {
1312 case VELOCITY_INIT_RESET:
1313 case VELOCITY_INIT_WOL:
1da177e4 1314
2cf71d2e 1315 netif_stop_queue(vptr->dev);
6aa20a22 1316
2cf71d2e
DJ
1317 /*
1318 * Reset RX to prevent RX pointer not on the 4X location
1319 */
1320 velocity_rx_reset(vptr);
1321 mac_rx_queue_run(regs);
1322 mac_rx_queue_wake(regs);
6aa20a22 1323
2cf71d2e
DJ
1324 mii_status = velocity_get_opt_media_mode(vptr);
1325 if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
1326 velocity_print_link_status(vptr);
1327 if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
1328 netif_wake_queue(vptr->dev);
1da177e4 1329 }
1da177e4 1330
2cf71d2e 1331 enable_flow_control_ability(vptr);
1da177e4 1332
2cf71d2e
DJ
1333 mac_clear_isr(regs);
1334 writel(CR0_STOP, &regs->CR0Clr);
1335 writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
1336 &regs->CR0Set);
6aa20a22 1337
2cf71d2e 1338 break;
1da177e4 1339
2cf71d2e
DJ
1340 case VELOCITY_INIT_COLD:
1341 default:
1342 /*
1343 * Do reset
1344 */
1345 velocity_soft_reset(vptr);
1346 mdelay(5);
1da177e4 1347
2cf71d2e
DJ
1348 mac_eeprom_reload(regs);
1349 for (i = 0; i < 6; i++)
1350 writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
1da177e4 1351
2cf71d2e
DJ
1352 /*
1353 * clear Pre_ACPI bit.
1354 */
1355 BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
1356 mac_set_rx_thresh(regs, vptr->options.rx_thresh);
1357 mac_set_dma_length(regs, vptr->options.DMA_length);
1da177e4 1358
2cf71d2e
DJ
1359 writeb(WOLCFG_SAM | WOLCFG_SAB, &regs->WOLCFGSet);
1360 /*
1361 * Back off algorithm use original IEEE standard
1362 */
1363 BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), &regs->CFGB);
1da177e4
LT
1364
1365 /*
2cf71d2e 1366 * Init CAM filter
1da177e4 1367 */
2cf71d2e 1368 velocity_init_cam_filter(vptr);
1da177e4 1369
2cf71d2e
DJ
1370 /*
1371 * Set packet filter: Receive directed and broadcast address
1372 */
1373 velocity_set_multi(vptr->dev);
1da177e4 1374
2cf71d2e
DJ
1375 /*
1376 * Enable MII auto-polling
1377 */
1378 enable_mii_autopoll(regs);
1da177e4 1379
6dfc4b95 1380 setup_adaptive_interrupts(vptr);
1da177e4 1381
2cf71d2e
DJ
1382 writel(vptr->rx.pool_dma, &regs->RDBaseLo);
1383 writew(vptr->options.numrx - 1, &regs->RDCSize);
1384 mac_rx_queue_run(regs);
1385 mac_rx_queue_wake(regs);
1da177e4 1386
2cf71d2e 1387 writew(vptr->options.numtx - 1, &regs->TDCSize);
1da177e4 1388
2cf71d2e
DJ
1389 for (i = 0; i < vptr->tx.numq; i++) {
1390 writel(vptr->tx.pool_dma[i], &regs->TDBaseLo[i]);
1391 mac_tx_queue_run(regs, i);
1392 }
1da177e4 1393
2cf71d2e 1394 init_flow_control_register(vptr);
6aa20a22 1395
2cf71d2e
DJ
1396 writel(CR0_STOP, &regs->CR0Clr);
1397 writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), &regs->CR0Set);
1da177e4 1398
2cf71d2e
DJ
1399 mii_status = velocity_get_opt_media_mode(vptr);
1400 netif_stop_queue(vptr->dev);
1da177e4 1401
2cf71d2e 1402 mii_init(vptr, mii_status);
1da177e4 1403
2cf71d2e
DJ
1404 if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
1405 velocity_print_link_status(vptr);
1406 if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
1407 netif_wake_queue(vptr->dev);
1da177e4 1408 }
6aa20a22 1409
2cf71d2e
DJ
1410 enable_flow_control_ability(vptr);
1411 mac_hw_mibs_init(regs);
1412 mac_write_int_mask(vptr->int_mask, regs);
1413 mac_clear_isr(regs);
1414
1da177e4 1415 }
1da177e4
LT
1416}
1417
2cf71d2e 1418static void velocity_give_many_rx_descs(struct velocity_info *vptr)
1da177e4 1419{
2cf71d2e
DJ
1420 struct mac_regs __iomem *regs = vptr->mac_regs;
1421 int avail, dirty, unusable;
1422
1423 /*
1424 * RD number must be equal to 4X per hardware spec
1425 * (programming guide rev 1.20, p.13)
1426 */
1427 if (vptr->rx.filled < 4)
1428 return;
1429
1430 wmb();
1431
1432 unusable = vptr->rx.filled & 0x0003;
1433 dirty = vptr->rx.dirty - unusable;
1434 for (avail = vptr->rx.filled & 0xfffc; avail; avail--) {
1435 dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
1436 vptr->rx.ring[dirty].rdesc0.len |= OWNED_BY_NIC;
1da177e4 1437 }
2cf71d2e
DJ
1438
1439 writew(vptr->rx.filled & 0xfffc, &regs->RBRDU);
1440 vptr->rx.filled = unusable;
1da177e4
LT
1441}
1442
1443/**
2cf71d2e
DJ
1444 * velocity_init_dma_rings - set up DMA rings
1445 * @vptr: Velocity to set up
6aa20a22 1446 *
2cf71d2e
DJ
1447 * Allocate PCI mapped DMA rings for the receive and transmit layer
1448 * to use.
1da177e4 1449 */
2cf71d2e 1450static int velocity_init_dma_rings(struct velocity_info *vptr)
1da177e4 1451{
2cf71d2e
DJ
1452 struct velocity_opt *opt = &vptr->options;
1453 const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
1454 const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc);
1455 struct pci_dev *pdev = vptr->pdev;
1456 dma_addr_t pool_dma;
1457 void *pool;
1458 unsigned int i;
1da177e4
LT
1459
1460 /*
2cf71d2e
DJ
1461 * Allocate all RD/TD rings a single pool.
1462 *
1463 * pci_alloc_consistent() fulfills the requirement for 64 bytes
1464 * alignment
1da177e4 1465 */
2cf71d2e
DJ
1466 pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->tx.numq +
1467 rx_ring_size, &pool_dma);
1468 if (!pool) {
1469 dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
1470 vptr->dev->name);
1471 return -ENOMEM;
1da177e4
LT
1472 }
1473
2cf71d2e
DJ
1474 vptr->rx.ring = pool;
1475 vptr->rx.pool_dma = pool_dma;
1da177e4 1476
2cf71d2e
DJ
1477 pool += rx_ring_size;
1478 pool_dma += rx_ring_size;
d4f73c8e 1479
2cf71d2e
DJ
1480 for (i = 0; i < vptr->tx.numq; i++) {
1481 vptr->tx.rings[i] = pool;
1482 vptr->tx.pool_dma[i] = pool_dma;
1483 pool += tx_ring_size;
1484 pool_dma += tx_ring_size;
1485 }
1da177e4
LT
1486
1487 return 0;
1488}
1489
2cf71d2e
DJ
1490static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
1491{
1492 vptr->rx.buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
1493}
1494
1da177e4
LT
1495/**
1496 * velocity_alloc_rx_buf - allocate aligned receive buffer
1497 * @vptr: velocity
1498 * @idx: ring index
1499 *
1500 * Allocate a new full sized buffer for the reception of a frame and
1501 * map it into PCI space for the hardware to use. The hardware
1502 * requires *64* byte alignment of the buffer which makes life
1503 * less fun than would be ideal.
1504 */
1da177e4
LT
1505static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
1506{
0fe9f15e
FR
1507 struct rx_desc *rd = &(vptr->rx.ring[idx]);
1508 struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
1da177e4 1509
0fe9f15e 1510 rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
1da177e4
LT
1511 if (rd_info->skb == NULL)
1512 return -ENOMEM;
1513
1514 /*
1515 * Do the gymnastics to get the buffer head for data at
1516 * 64byte alignment.
1517 */
da95b2d4
SK
1518 skb_reserve(rd_info->skb,
1519 64 - ((unsigned long) rd_info->skb->data & 63));
0fe9f15e
FR
1520 rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
1521 vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
6aa20a22 1522
1da177e4
LT
1523 /*
1524 * Fill in the descriptor to match
0fe9f15e 1525 */
6aa20a22 1526
1da177e4 1527 *((u32 *) & (rd->rdesc0)) = 0;
0fe9f15e 1528 rd->size = cpu_to_le16(vptr->rx.buf_sz) | RX_INTEN;
1da177e4
LT
1529 rd->pa_low = cpu_to_le32(rd_info->skb_dma);
1530 rd->pa_high = 0;
1531 return 0;
1532}
1533
6aa20a22 1534
2cf71d2e 1535static int velocity_rx_refill(struct velocity_info *vptr)
1da177e4 1536{
2cf71d2e 1537 int dirty = vptr->rx.dirty, done = 0;
1da177e4 1538
2cf71d2e
DJ
1539 do {
1540 struct rx_desc *rd = vptr->rx.ring + dirty;
1da177e4 1541
2cf71d2e
DJ
1542 /* Fine for an all zero Rx desc at init time as well */
1543 if (rd->rdesc0.len & OWNED_BY_NIC)
1544 break;
1da177e4 1545
2cf71d2e
DJ
1546 if (!vptr->rx.info[dirty].skb) {
1547 if (velocity_alloc_rx_buf(vptr, dirty) < 0)
1da177e4 1548 break;
1da177e4 1549 }
2cf71d2e
DJ
1550 done++;
1551 dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
1552 } while (dirty != vptr->rx.curr);
1da177e4 1553
2cf71d2e
DJ
1554 if (done) {
1555 vptr->rx.dirty = dirty;
1556 vptr->rx.filled += done;
1da177e4 1557 }
2cf71d2e
DJ
1558
1559 return done;
1da177e4
LT
1560}
1561
1562/**
2cf71d2e
DJ
1563 * velocity_free_rd_ring - free receive ring
1564 * @vptr: velocity to clean up
1da177e4 1565 *
2cf71d2e
DJ
1566 * Free the receive buffers for each ring slot and any
1567 * attached socket buffers that need to go away.
1da177e4 1568 */
2cf71d2e 1569static void velocity_free_rd_ring(struct velocity_info *vptr)
1da177e4 1570{
2cf71d2e 1571 int i;
1da177e4 1572
2cf71d2e
DJ
1573 if (vptr->rx.info == NULL)
1574 return;
6aa20a22 1575
2cf71d2e
DJ
1576 for (i = 0; i < vptr->options.numrx; i++) {
1577 struct velocity_rd_info *rd_info = &(vptr->rx.info[i]);
1578 struct rx_desc *rd = vptr->rx.ring + i;
1da177e4 1579
2cf71d2e 1580 memset(rd, 0, sizeof(*rd));
1da177e4 1581
2cf71d2e
DJ
1582 if (!rd_info->skb)
1583 continue;
1584 pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
1585 PCI_DMA_FROMDEVICE);
1586 rd_info->skb_dma = 0;
6aa20a22 1587
2cf71d2e
DJ
1588 dev_kfree_skb(rd_info->skb);
1589 rd_info->skb = NULL;
1da177e4
LT
1590 }
1591
2cf71d2e
DJ
1592 kfree(vptr->rx.info);
1593 vptr->rx.info = NULL;
1594}
1da177e4 1595
2cf71d2e
DJ
1596/**
1597 * velocity_init_rd_ring - set up receive ring
1598 * @vptr: velocity to configure
1599 *
1600 * Allocate and set up the receive buffers for each ring slot and
1601 * assign them to the network adapter.
1602 */
1603static int velocity_init_rd_ring(struct velocity_info *vptr)
1604{
1605 int ret = -ENOMEM;
1da177e4 1606
2cf71d2e
DJ
1607 vptr->rx.info = kcalloc(vptr->options.numrx,
1608 sizeof(struct velocity_rd_info), GFP_KERNEL);
1609 if (!vptr->rx.info)
1610 goto out;
6aa20a22 1611
2cf71d2e 1612 velocity_init_rx_ring_indexes(vptr);
1da177e4 1613
2cf71d2e
DJ
1614 if (velocity_rx_refill(vptr) != vptr->options.numrx) {
1615 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
1616 "%s: failed to allocate RX buffer.\n", vptr->dev->name);
1617 velocity_free_rd_ring(vptr);
1618 goto out;
1619 }
1da177e4 1620
2cf71d2e
DJ
1621 ret = 0;
1622out:
1623 return ret;
1da177e4
LT
1624}
1625
1626/**
2cf71d2e
DJ
1627 * velocity_init_td_ring - set up transmit ring
1628 * @vptr: velocity
1da177e4 1629 *
2cf71d2e
DJ
1630 * Set up the transmit ring and chain the ring pointers together.
1631 * Returns zero on success or a negative posix errno code for
1632 * failure.
1da177e4 1633 */
2cf71d2e 1634static int velocity_init_td_ring(struct velocity_info *vptr)
1da177e4 1635{
2cf71d2e 1636 int j;
1da177e4 1637
2cf71d2e
DJ
1638 /* Init the TD ring entries */
1639 for (j = 0; j < vptr->tx.numq; j++) {
1da177e4 1640
2cf71d2e
DJ
1641 vptr->tx.infos[j] = kcalloc(vptr->options.numtx,
1642 sizeof(struct velocity_td_info),
1643 GFP_KERNEL);
1644 if (!vptr->tx.infos[j]) {
1645 while (--j >= 0)
1646 kfree(vptr->tx.infos[j]);
1647 return -ENOMEM;
1da177e4 1648 }
2cf71d2e
DJ
1649
1650 vptr->tx.tail[j] = vptr->tx.curr[j] = vptr->tx.used[j] = 0;
1da177e4 1651 }
2cf71d2e
DJ
1652 return 0;
1653}
1654
1655/**
1656 * velocity_free_dma_rings - free PCI ring pointers
1657 * @vptr: Velocity to free from
1658 *
1659 * Clean up the PCI ring buffers allocated to this velocity.
1660 */
1661static void velocity_free_dma_rings(struct velocity_info *vptr)
1662{
1663 const int size = vptr->options.numrx * sizeof(struct rx_desc) +
1664 vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
1665
1666 pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
1da177e4
LT
1667}
1668
3c4dc711
FR
1669static int velocity_init_rings(struct velocity_info *vptr, int mtu)
1670{
1671 int ret;
1672
1673 velocity_set_rxbufsize(vptr, mtu);
1674
1675 ret = velocity_init_dma_rings(vptr);
1676 if (ret < 0)
1677 goto out;
1678
1679 ret = velocity_init_rd_ring(vptr);
1680 if (ret < 0)
1681 goto err_free_dma_rings_0;
1682
1683 ret = velocity_init_td_ring(vptr);
1684 if (ret < 0)
1685 goto err_free_rd_ring_1;
1686out:
1687 return ret;
1688
1689err_free_rd_ring_1:
1690 velocity_free_rd_ring(vptr);
1691err_free_dma_rings_0:
1692 velocity_free_dma_rings(vptr);
1693 goto out;
1694}
1695
1da177e4 1696/**
2cf71d2e
DJ
1697 * velocity_free_tx_buf - free transmit buffer
1698 * @vptr: velocity
1699 * @tdinfo: buffer
1da177e4 1700 *
2cf71d2e
DJ
1701 * Release an transmit buffer. If the buffer was preallocated then
1702 * recycle it, if not then unmap the buffer.
1da177e4 1703 */
c79992fd
SK
1704static void velocity_free_tx_buf(struct velocity_info *vptr,
1705 struct velocity_td_info *tdinfo, struct tx_desc *td)
1da177e4 1706{
2cf71d2e 1707 struct sk_buff *skb = tdinfo->skb;
28133176 1708
2cf71d2e
DJ
1709 /*
1710 * Don't unmap the pre-allocated tx_bufs
1711 */
1712 if (tdinfo->skb_dma) {
c79992fd 1713 int i;
1da177e4 1714
2cf71d2e 1715 for (i = 0; i < tdinfo->nskb_dma; i++) {
c79992fd
SK
1716 size_t pktlen = max_t(size_t, skb->len, ETH_ZLEN);
1717
1718 /* For scatter-gather */
1719 if (skb_shinfo(skb)->nr_frags > 0)
1720 pktlen = max_t(size_t, pktlen,
1721 td->td_buf[i].size & ~TD_QUEUE);
1722
1723 pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
1724 le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
2cf71d2e 1725 }
1da177e4 1726 }
2cf71d2e
DJ
1727 dev_kfree_skb_irq(skb);
1728 tdinfo->skb = NULL;
1da177e4
LT
1729}
1730
2cf71d2e
DJ
1731/*
1732 * FIXME: could we merge this with velocity_free_tx_buf ?
1733 */
1734static void velocity_free_td_ring_entry(struct velocity_info *vptr,
1735 int q, int n)
1da177e4 1736{
2cf71d2e
DJ
1737 struct velocity_td_info *td_info = &(vptr->tx.infos[q][n]);
1738 int i;
bd7b3f34 1739
2cf71d2e
DJ
1740 if (td_info == NULL)
1741 return;
3c4dc711 1742
2cf71d2e
DJ
1743 if (td_info->skb) {
1744 for (i = 0; i < td_info->nskb_dma; i++) {
1745 if (td_info->skb_dma[i]) {
1746 pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
1747 td_info->skb->len, PCI_DMA_TODEVICE);
1748 td_info->skb_dma[i] = 0;
1749 }
3c4dc711 1750 }
2cf71d2e
DJ
1751 dev_kfree_skb(td_info->skb);
1752 td_info->skb = NULL;
3c4dc711 1753 }
1da177e4
LT
1754}
1755
1756/**
2cf71d2e
DJ
1757 * velocity_free_td_ring - free td ring
1758 * @vptr: velocity
1da177e4 1759 *
2cf71d2e
DJ
1760 * Free up the transmit ring for this particular velocity adapter.
1761 * We free the ring contents but not the ring itself.
1762 */
1763static void velocity_free_td_ring(struct velocity_info *vptr)
1764{
1765 int i, j;
1da177e4 1766
2cf71d2e
DJ
1767 for (j = 0; j < vptr->tx.numq; j++) {
1768 if (vptr->tx.infos[j] == NULL)
1769 continue;
1770 for (i = 0; i < vptr->options.numtx; i++)
1771 velocity_free_td_ring_entry(vptr, j, i);
6aa20a22 1772
2cf71d2e
DJ
1773 kfree(vptr->tx.infos[j]);
1774 vptr->tx.infos[j] = NULL;
1775 }
1776}
6aa20a22 1777
2cf71d2e
DJ
1778static void velocity_free_rings(struct velocity_info *vptr)
1779{
1780 velocity_free_td_ring(vptr);
1781 velocity_free_rd_ring(vptr);
1782 velocity_free_dma_rings(vptr);
1da177e4
LT
1783}
1784
1785/**
2cf71d2e
DJ
1786 * velocity_error - handle error from controller
1787 * @vptr: velocity
1788 * @status: card status
1789 *
1790 * Process an error report from the hardware and attempt to recover
1791 * the card itself. At the moment we cannot recover from some
1792 * theoretically impossible errors but this could be fixed using
1793 * the pci_device_failed logic to bounce the hardware
1da177e4 1794 *
1da177e4 1795 */
2cf71d2e 1796static void velocity_error(struct velocity_info *vptr, int status)
1da177e4 1797{
580a6902 1798
2cf71d2e
DJ
1799 if (status & ISR_TXSTLI) {
1800 struct mac_regs __iomem *regs = vptr->mac_regs;
1da177e4 1801
2cf71d2e
DJ
1802 printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
1803 BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
1804 writew(TRDCSR_RUN, &regs->TDCSRClr);
1805 netif_stop_queue(vptr->dev);
1da177e4 1806
2cf71d2e
DJ
1807 /* FIXME: port over the pci_device_failed code and use it
1808 here */
1809 }
1da177e4 1810
2cf71d2e
DJ
1811 if (status & ISR_SRCI) {
1812 struct mac_regs __iomem *regs = vptr->mac_regs;
1813 int linked;
1da177e4 1814
2cf71d2e
DJ
1815 if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
1816 vptr->mii_status = check_connection_type(regs);
1da177e4 1817
2cf71d2e
DJ
1818 /*
1819 * If it is a 3119, disable frame bursting in
1820 * halfduplex mode and enable it in fullduplex
1821 * mode
1822 */
1823 if (vptr->rev_id < REV_ID_VT3216_A0) {
0527a1a8 1824 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
2cf71d2e
DJ
1825 BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
1826 else
1827 BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
1828 }
1829 /*
1830 * Only enable CD heart beat counter in 10HD mode
1831 */
1832 if (!(vptr->mii_status & VELOCITY_DUPLEX_FULL) && (vptr->mii_status & VELOCITY_SPEED_10))
1833 BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
1834 else
1835 BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
6dfc4b95
SK
1836
1837 setup_queue_timers(vptr);
2cf71d2e
DJ
1838 }
1839 /*
1840 * Get link status from PHYSR0
1841 */
1842 linked = readb(&regs->PHYSR0) & PHYSR0_LINKGD;
1da177e4 1843
2cf71d2e
DJ
1844 if (linked) {
1845 vptr->mii_status &= ~VELOCITY_LINK_FAIL;
1846 netif_carrier_on(vptr->dev);
1847 } else {
1848 vptr->mii_status |= VELOCITY_LINK_FAIL;
1849 netif_carrier_off(vptr->dev);
1850 }
1da177e4 1851
2cf71d2e
DJ
1852 velocity_print_link_status(vptr);
1853 enable_flow_control_ability(vptr);
1da177e4 1854
2cf71d2e
DJ
1855 /*
1856 * Re-enable auto-polling because SRCI will disable
1857 * auto-polling
1858 */
1da177e4 1859
2cf71d2e 1860 enable_mii_autopoll(regs);
1da177e4 1861
2cf71d2e
DJ
1862 if (vptr->mii_status & VELOCITY_LINK_FAIL)
1863 netif_stop_queue(vptr->dev);
1864 else
1865 netif_wake_queue(vptr->dev);
1da177e4 1866
6403eab1 1867 }
2cf71d2e
DJ
1868 if (status & ISR_MIBFI)
1869 velocity_update_hw_mibs(vptr);
1870 if (status & ISR_LSTEI)
1871 mac_rx_queue_wake(vptr->mac_regs);
1da177e4
LT
1872}
1873
1874/**
2cf71d2e
DJ
1875 * tx_srv - transmit interrupt service
1876 * @vptr; Velocity
1da177e4 1877 *
2cf71d2e
DJ
1878 * Scan the queues looking for transmitted packets that
1879 * we can complete and clean up. Update any statistics as
1880 * necessary/
1da177e4 1881 */
d6cade0f 1882static int velocity_tx_srv(struct velocity_info *vptr)
1da177e4 1883{
2cf71d2e
DJ
1884 struct tx_desc *td;
1885 int qnum;
1886 int full = 0;
1887 int idx;
1888 int works = 0;
1889 struct velocity_td_info *tdinfo;
1890 struct net_device_stats *stats = &vptr->dev->stats;
1da177e4 1891
2cf71d2e
DJ
1892 for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
1893 for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
1894 idx = (idx + 1) % vptr->options.numtx) {
1da177e4 1895
2cf71d2e
DJ
1896 /*
1897 * Get Tx Descriptor
1898 */
1899 td = &(vptr->tx.rings[qnum][idx]);
1900 tdinfo = &(vptr->tx.infos[qnum][idx]);
1da177e4 1901
2cf71d2e
DJ
1902 if (td->tdesc0.len & OWNED_BY_NIC)
1903 break;
1da177e4 1904
2cf71d2e
DJ
1905 if ((works++ > 15))
1906 break;
1907
1908 if (td->tdesc0.TSR & TSR0_TERR) {
1909 stats->tx_errors++;
1910 stats->tx_dropped++;
1911 if (td->tdesc0.TSR & TSR0_CDH)
1912 stats->tx_heartbeat_errors++;
1913 if (td->tdesc0.TSR & TSR0_CRS)
1914 stats->tx_carrier_errors++;
1915 if (td->tdesc0.TSR & TSR0_ABT)
1916 stats->tx_aborted_errors++;
1917 if (td->tdesc0.TSR & TSR0_OWC)
1918 stats->tx_window_errors++;
1919 } else {
1920 stats->tx_packets++;
1921 stats->tx_bytes += tdinfo->skb->len;
1922 }
c79992fd 1923 velocity_free_tx_buf(vptr, tdinfo, td);
2cf71d2e
DJ
1924 vptr->tx.used[qnum]--;
1925 }
1926 vptr->tx.tail[qnum] = idx;
1da177e4 1927
2cf71d2e
DJ
1928 if (AVAIL_TD(vptr, qnum) < 1)
1929 full = 1;
1930 }
1da177e4 1931 /*
2cf71d2e
DJ
1932 * Look to see if we should kick the transmit network
1933 * layer for more work.
1da177e4 1934 */
8e95a202
JP
1935 if (netif_queue_stopped(vptr->dev) && (full == 0) &&
1936 (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
2cf71d2e
DJ
1937 netif_wake_queue(vptr->dev);
1938 }
1939 return works;
1940}
1941
1942/**
1943 * velocity_rx_csum - checksum process
1944 * @rd: receive packet descriptor
1945 * @skb: network layer packet buffer
1946 *
1947 * Process the status bits for the received packet and determine
1948 * if the checksum was computed and verified by the hardware
1949 */
1950static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
1951{
bc8acf2c 1952 skb_checksum_none_assert(skb);
6aa20a22 1953
2cf71d2e
DJ
1954 if (rd->rdesc1.CSM & CSM_IPKT) {
1955 if (rd->rdesc1.CSM & CSM_IPOK) {
1956 if ((rd->rdesc1.CSM & CSM_TCPKT) ||
1957 (rd->rdesc1.CSM & CSM_UDPKT)) {
1958 if (!(rd->rdesc1.CSM & CSM_TUPOK))
1959 return;
1960 }
1961 skb->ip_summed = CHECKSUM_UNNECESSARY;
1da177e4
LT
1962 }
1963 }
1da177e4
LT
1964}
1965
1da177e4 1966/**
2cf71d2e
DJ
1967 * velocity_rx_copy - in place Rx copy for small packets
1968 * @rx_skb: network layer packet buffer candidate
1969 * @pkt_size: received data size
1970 * @rd: receive packet descriptor
1da177e4
LT
1971 * @dev: network device
1972 *
2cf71d2e 1973 * Replace the current skb that is scheduled for Rx processing by a
25985edc 1974 * shorter, immediately allocated skb, if the received packet is small
2cf71d2e
DJ
1975 * enough. This function returns a negative value if the received
1976 * packet is too big or if memory is exhausted.
1da177e4 1977 */
2cf71d2e
DJ
1978static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
1979 struct velocity_info *vptr)
1da177e4 1980{
2cf71d2e
DJ
1981 int ret = -1;
1982 if (pkt_size < rx_copybreak) {
1983 struct sk_buff *new_skb;
1da177e4 1984
89d71a66 1985 new_skb = netdev_alloc_skb_ip_align(vptr->dev, pkt_size);
2cf71d2e
DJ
1986 if (new_skb) {
1987 new_skb->ip_summed = rx_skb[0]->ip_summed;
2cf71d2e
DJ
1988 skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
1989 *rx_skb = new_skb;
1990 ret = 0;
1da177e4
LT
1991 }
1992
1da177e4 1993 }
2cf71d2e 1994 return ret;
1da177e4
LT
1995}
1996
1997/**
2cf71d2e
DJ
1998 * velocity_iph_realign - IP header alignment
1999 * @vptr: velocity we are handling
2000 * @skb: network layer packet buffer
2001 * @pkt_size: received data size
1da177e4 2002 *
2cf71d2e
DJ
2003 * Align IP header on a 2 bytes boundary. This behavior can be
2004 * configured by the user.
1da177e4 2005 */
2cf71d2e
DJ
2006static inline void velocity_iph_realign(struct velocity_info *vptr,
2007 struct sk_buff *skb, int pkt_size)
1da177e4 2008{
2cf71d2e
DJ
2009 if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
2010 memmove(skb->data + 2, skb->data, pkt_size);
2011 skb_reserve(skb, 2);
2012 }
2013}
6aa20a22 2014
2cf71d2e
DJ
2015/**
2016 * velocity_receive_frame - received packet processor
2017 * @vptr: velocity we are handling
2018 * @idx: ring index
2019 *
2020 * A packet has arrived. We process the packet and if appropriate
2021 * pass the frame up the network stack
2022 */
2023static int velocity_receive_frame(struct velocity_info *vptr, int idx)
2024{
2025 void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
2026 struct net_device_stats *stats = &vptr->dev->stats;
2027 struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
2028 struct rx_desc *rd = &(vptr->rx.ring[idx]);
2029 int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
2030 struct sk_buff *skb;
1da177e4 2031
2cf71d2e
DJ
2032 if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
2033 VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
2034 stats->rx_length_errors++;
2035 return -EINVAL;
2036 }
1da177e4 2037
2cf71d2e
DJ
2038 if (rd->rdesc0.RSR & RSR_MAR)
2039 stats->multicast++;
1da177e4 2040
2cf71d2e 2041 skb = rd_info->skb;
1da177e4 2042
2cf71d2e
DJ
2043 pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
2044 vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
1da177e4 2045
2cf71d2e
DJ
2046 /*
2047 * Drop frame not meeting IEEE 802.3
2048 */
1da177e4 2049
2cf71d2e
DJ
2050 if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
2051 if (rd->rdesc0.RSR & RSR_RL) {
2052 stats->rx_length_errors++;
2053 return -EINVAL;
2054 }
2055 }
6aa20a22 2056
2cf71d2e 2057 pci_action = pci_dma_sync_single_for_device;
1da177e4 2058
2cf71d2e 2059 velocity_rx_csum(rd, skb);
6aa20a22 2060
2cf71d2e
DJ
2061 if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
2062 velocity_iph_realign(vptr, skb, pkt_len);
2063 pci_action = pci_unmap_single;
2064 rd_info->skb = NULL;
2065 }
6aa20a22 2066
2cf71d2e
DJ
2067 pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
2068 PCI_DMA_FROMDEVICE);
1da177e4 2069
2cf71d2e
DJ
2070 skb_put(skb, pkt_len - 4);
2071 skb->protocol = eth_type_trans(skb, vptr->dev);
2072
73b54688
JP
2073 if (rd->rdesc0.RSR & RSR_DETAG) {
2074 u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG));
2075
2076 __vlan_hwaccel_put_tag(skb, vid);
2077 }
2078 netif_rx(skb);
6aa20a22 2079
2cf71d2e 2080 stats->rx_bytes += pkt_len;
3cb7a798 2081 stats->rx_packets++;
6aa20a22 2082
2cf71d2e 2083 return 0;
1da177e4
LT
2084}
2085
1da177e4 2086/**
2cf71d2e
DJ
2087 * velocity_rx_srv - service RX interrupt
2088 * @vptr: velocity
1da177e4 2089 *
2cf71d2e
DJ
2090 * Walk the receive ring of the velocity adapter and remove
2091 * any received packets from the receive queue. Hand the ring
2092 * slots back to the adapter for reuse.
1da177e4 2093 */
d6cade0f 2094static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
1da177e4 2095{
2cf71d2e
DJ
2096 struct net_device_stats *stats = &vptr->dev->stats;
2097 int rd_curr = vptr->rx.curr;
2098 int works = 0;
2099
dfff7144 2100 while (works < budget_left) {
2cf71d2e
DJ
2101 struct rx_desc *rd = vptr->rx.ring + rd_curr;
2102
2103 if (!vptr->rx.info[rd_curr].skb)
2104 break;
2105
2106 if (rd->rdesc0.len & OWNED_BY_NIC)
2107 break;
2108
2109 rmb();
1da177e4 2110
2cf71d2e
DJ
2111 /*
2112 * Don't drop CE or RL error frame although RXOK is off
2113 */
2114 if (rd->rdesc0.RSR & (RSR_RXOK | RSR_CE | RSR_RL)) {
2115 if (velocity_receive_frame(vptr, rd_curr) < 0)
2116 stats->rx_dropped++;
2117 } else {
2118 if (rd->rdesc0.RSR & RSR_CRC)
2119 stats->rx_crc_errors++;
2120 if (rd->rdesc0.RSR & RSR_FAE)
2121 stats->rx_frame_errors++;
1da177e4 2122
2cf71d2e
DJ
2123 stats->rx_dropped++;
2124 }
6aa20a22 2125
2cf71d2e 2126 rd->size |= RX_INTEN;
1da177e4 2127
2cf71d2e
DJ
2128 rd_curr++;
2129 if (rd_curr >= vptr->options.numrx)
2130 rd_curr = 0;
dfff7144
SK
2131 works++;
2132 }
1da177e4 2133
2cf71d2e 2134 vptr->rx.curr = rd_curr;
1da177e4 2135
2cf71d2e
DJ
2136 if ((works > 0) && (velocity_rx_refill(vptr) > 0))
2137 velocity_give_many_rx_descs(vptr);
2138
2139 VAR_USED(stats);
2140 return works;
2141}
6aa20a22 2142
dfff7144
SK
2143static int velocity_poll(struct napi_struct *napi, int budget)
2144{
2145 struct velocity_info *vptr = container_of(napi,
2146 struct velocity_info, napi);
2147 unsigned int rx_done;
3f2e8d9f 2148 unsigned long flags;
dfff7144 2149
3f2e8d9f 2150 spin_lock_irqsave(&vptr->lock, flags);
dfff7144
SK
2151 /*
2152 * Do rx and tx twice for performance (taken from the VIA
2153 * out-of-tree driver).
2154 */
d6cade0f
SK
2155 rx_done = velocity_rx_srv(vptr, budget / 2);
2156 velocity_tx_srv(vptr);
2157 rx_done += velocity_rx_srv(vptr, budget - rx_done);
2158 velocity_tx_srv(vptr);
dfff7144
SK
2159
2160 /* If budget not fully consumed, exit the polling mode */
2161 if (rx_done < budget) {
2162 napi_complete(napi);
2163 mac_enable_int(vptr->mac_regs);
2164 }
3f2e8d9f 2165 spin_unlock_irqrestore(&vptr->lock, flags);
dfff7144
SK
2166
2167 return rx_done;
2168}
6aa20a22 2169
1da177e4 2170/**
2cf71d2e
DJ
2171 * velocity_intr - interrupt callback
2172 * @irq: interrupt number
2173 * @dev_instance: interrupting device
1da177e4 2174 *
2cf71d2e
DJ
2175 * Called whenever an interrupt is generated by the velocity
2176 * adapter IRQ line. We may not be the source of the interrupt
2177 * and need to identify initially if we are, and if not exit as
2178 * efficiently as possible.
1da177e4 2179 */
2cf71d2e 2180static irqreturn_t velocity_intr(int irq, void *dev_instance)
1da177e4 2181{
2cf71d2e
DJ
2182 struct net_device *dev = dev_instance;
2183 struct velocity_info *vptr = netdev_priv(dev);
2184 u32 isr_status;
1da177e4 2185
2cf71d2e
DJ
2186 spin_lock(&vptr->lock);
2187 isr_status = mac_read_isr(vptr->mac_regs);
2188
2189 /* Not us ? */
2190 if (isr_status == 0) {
2191 spin_unlock(&vptr->lock);
2192 return IRQ_NONE;
1da177e4 2193 }
1da177e4 2194
3f2e8d9f
SK
2195 /* Ack the interrupt */
2196 mac_write_isr(vptr->mac_regs, isr_status);
2197
dfff7144
SK
2198 if (likely(napi_schedule_prep(&vptr->napi))) {
2199 mac_disable_int(vptr->mac_regs);
2200 __napi_schedule(&vptr->napi);
1da177e4 2201 }
3f2e8d9f
SK
2202
2203 if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
2204 velocity_error(vptr, isr_status);
2205
2cf71d2e 2206 spin_unlock(&vptr->lock);
2cf71d2e 2207
dfff7144 2208 return IRQ_HANDLED;
1da177e4
LT
2209}
2210
2211/**
2cf71d2e
DJ
2212 * velocity_open - interface activation callback
2213 * @dev: network layer device to open
1da177e4 2214 *
2cf71d2e
DJ
2215 * Called when the network layer brings the interface up. Returns
2216 * a negative posix error code on failure, or zero on success.
2217 *
2218 * All the ring allocation and set up is done on open for this
2219 * adapter to minimise memory usage when inactive
1da177e4 2220 */
2cf71d2e 2221static int velocity_open(struct net_device *dev)
1da177e4 2222{
2cf71d2e
DJ
2223 struct velocity_info *vptr = netdev_priv(dev);
2224 int ret;
1da177e4 2225
2cf71d2e
DJ
2226 ret = velocity_init_rings(vptr, dev->mtu);
2227 if (ret < 0)
2228 goto out;
1da177e4 2229
2cf71d2e
DJ
2230 /* Ensure chip is running */
2231 pci_set_power_state(vptr->pdev, PCI_D0);
1da177e4 2232
2cf71d2e
DJ
2233 velocity_init_registers(vptr, VELOCITY_INIT_COLD);
2234
1ede9b52 2235 ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
2cf71d2e
DJ
2236 dev->name, dev);
2237 if (ret < 0) {
2238 /* Power down the chip */
2239 pci_set_power_state(vptr->pdev, PCI_D3hot);
2240 velocity_free_rings(vptr);
2241 goto out;
1da177e4
LT
2242 }
2243
35bb5cad
BH
2244 velocity_give_many_rx_descs(vptr);
2245
2cf71d2e
DJ
2246 mac_enable_int(vptr->mac_regs);
2247 netif_start_queue(dev);
dfff7144 2248 napi_enable(&vptr->napi);
2cf71d2e
DJ
2249 vptr->flags |= VELOCITY_FLAGS_OPENED;
2250out:
2251 return ret;
1da177e4
LT
2252}
2253
2254/**
2cf71d2e
DJ
2255 * velocity_shutdown - shut down the chip
2256 * @vptr: velocity to deactivate
1da177e4 2257 *
2cf71d2e
DJ
2258 * Shuts down the internal operations of the velocity and
2259 * disables interrupts, autopolling, transmit and receive
1da177e4 2260 */
2cf71d2e 2261static void velocity_shutdown(struct velocity_info *vptr)
1da177e4 2262{
2cf71d2e
DJ
2263 struct mac_regs __iomem *regs = vptr->mac_regs;
2264 mac_disable_int(regs);
2265 writel(CR0_STOP, &regs->CR0Set);
2266 writew(0xFFFF, &regs->TDCSRClr);
2267 writeb(0xFF, &regs->RDCSRClr);
1da177e4 2268 safe_disable_mii_autopoll(regs);
2cf71d2e
DJ
2269 mac_clear_isr(regs);
2270}
1da177e4 2271
2cf71d2e
DJ
2272/**
2273 * velocity_change_mtu - MTU change callback
2274 * @dev: network device
2275 * @new_mtu: desired MTU
2276 *
2277 * Handle requests from the networking layer for MTU change on
2278 * this interface. It gets called on a change by the network layer.
2279 * Return zero for success or negative posix error code.
2280 */
2281static int velocity_change_mtu(struct net_device *dev, int new_mtu)
2282{
2283 struct velocity_info *vptr = netdev_priv(dev);
2284 int ret = 0;
1da177e4 2285
2cf71d2e
DJ
2286 if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
2287 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
2288 vptr->dev->name);
2289 ret = -EINVAL;
2290 goto out_0;
2291 }
1da177e4 2292
2cf71d2e
DJ
2293 if (!netif_running(dev)) {
2294 dev->mtu = new_mtu;
2295 goto out_0;
1da177e4
LT
2296 }
2297
2cf71d2e
DJ
2298 if (dev->mtu != new_mtu) {
2299 struct velocity_info *tmp_vptr;
2300 unsigned long flags;
2301 struct rx_info rx;
2302 struct tx_info tx;
1da177e4 2303
2cf71d2e
DJ
2304 tmp_vptr = kzalloc(sizeof(*tmp_vptr), GFP_KERNEL);
2305 if (!tmp_vptr) {
2306 ret = -ENOMEM;
2307 goto out_0;
2308 }
1da177e4 2309
2cf71d2e
DJ
2310 tmp_vptr->dev = dev;
2311 tmp_vptr->pdev = vptr->pdev;
2312 tmp_vptr->options = vptr->options;
2313 tmp_vptr->tx.numq = vptr->tx.numq;
6aa20a22 2314
2cf71d2e
DJ
2315 ret = velocity_init_rings(tmp_vptr, new_mtu);
2316 if (ret < 0)
2317 goto out_free_tmp_vptr_1;
1da177e4 2318
2cf71d2e 2319 spin_lock_irqsave(&vptr->lock, flags);
1da177e4 2320
2cf71d2e
DJ
2321 netif_stop_queue(dev);
2322 velocity_shutdown(vptr);
1da177e4 2323
2cf71d2e
DJ
2324 rx = vptr->rx;
2325 tx = vptr->tx;
1da177e4 2326
2cf71d2e
DJ
2327 vptr->rx = tmp_vptr->rx;
2328 vptr->tx = tmp_vptr->tx;
1da177e4 2329
2cf71d2e
DJ
2330 tmp_vptr->rx = rx;
2331 tmp_vptr->tx = tx;
1da177e4 2332
2cf71d2e 2333 dev->mtu = new_mtu;
6aa20a22 2334
2cf71d2e 2335 velocity_init_registers(vptr, VELOCITY_INIT_COLD);
1da177e4 2336
35bb5cad
BH
2337 velocity_give_many_rx_descs(vptr);
2338
2cf71d2e
DJ
2339 mac_enable_int(vptr->mac_regs);
2340 netif_start_queue(dev);
6aa20a22 2341
2cf71d2e 2342 spin_unlock_irqrestore(&vptr->lock, flags);
1da177e4 2343
2cf71d2e 2344 velocity_free_rings(tmp_vptr);
1da177e4 2345
2cf71d2e
DJ
2346out_free_tmp_vptr_1:
2347 kfree(tmp_vptr);
2348 }
2349out_0:
2350 return ret;
1da177e4 2351}
1da177e4
LT
2352
2353/**
2cf71d2e
DJ
2354 * velocity_mii_ioctl - MII ioctl handler
2355 * @dev: network device
2356 * @ifr: the ifreq block for the ioctl
2357 * @cmd: the command
1da177e4 2358 *
2cf71d2e
DJ
2359 * Process MII requests made via ioctl from the network layer. These
2360 * are used by tools like kudzu to interrogate the link state of the
2361 * hardware
1da177e4 2362 */
2cf71d2e 2363static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1da177e4 2364{
2cf71d2e
DJ
2365 struct velocity_info *vptr = netdev_priv(dev);
2366 struct mac_regs __iomem *regs = vptr->mac_regs;
2367 unsigned long flags;
2368 struct mii_ioctl_data *miidata = if_mii(ifr);
2369 int err;
1da177e4 2370
2cf71d2e
DJ
2371 switch (cmd) {
2372 case SIOCGMIIPHY:
2373 miidata->phy_id = readb(&regs->MIIADR) & 0x1f;
1da177e4 2374 break;
2cf71d2e 2375 case SIOCGMIIREG:
2cf71d2e
DJ
2376 if (velocity_mii_read(vptr->mac_regs, miidata->reg_num & 0x1f, &(miidata->val_out)) < 0)
2377 return -ETIMEDOUT;
1da177e4 2378 break;
2cf71d2e 2379 case SIOCSMIIREG:
2cf71d2e
DJ
2380 spin_lock_irqsave(&vptr->lock, flags);
2381 err = velocity_mii_write(vptr->mac_regs, miidata->reg_num & 0x1f, miidata->val_in);
2382 spin_unlock_irqrestore(&vptr->lock, flags);
2383 check_connection_type(vptr->mac_regs);
2384 if (err)
2385 return err;
1da177e4
LT
2386 break;
2387 default:
2cf71d2e 2388 return -EOPNOTSUPP;
1da177e4 2389 }
2cf71d2e 2390 return 0;
1da177e4
LT
2391}
2392
2393/**
2cf71d2e
DJ
2394 * velocity_ioctl - ioctl entry point
2395 * @dev: network device
2396 * @rq: interface request ioctl
2397 * @cmd: command code
1da177e4 2398 *
2cf71d2e
DJ
2399 * Called when the user issues an ioctl request to the network
2400 * device in question. The velocity interface supports MII.
1da177e4 2401 */
2cf71d2e
DJ
2402static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2403{
2404 struct velocity_info *vptr = netdev_priv(dev);
2405 int ret;
6aa20a22 2406
2cf71d2e
DJ
2407 /* If we are asked for information and the device is power
2408 saving then we need to bring the device back up to talk to it */
1da177e4 2409
2cf71d2e
DJ
2410 if (!netif_running(dev))
2411 pci_set_power_state(vptr->pdev, PCI_D0);
1da177e4 2412
2cf71d2e
DJ
2413 switch (cmd) {
2414 case SIOCGMIIPHY: /* Get address of MII PHY in use. */
2415 case SIOCGMIIREG: /* Read MII PHY register. */
2416 case SIOCSMIIREG: /* Write to MII PHY register. */
2417 ret = velocity_mii_ioctl(dev, rq, cmd);
2418 break;
1da177e4 2419
2cf71d2e
DJ
2420 default:
2421 ret = -EOPNOTSUPP;
2422 }
2423 if (!netif_running(dev))
2424 pci_set_power_state(vptr->pdev, PCI_D3hot);
1da177e4 2425
c4067400 2426
2cf71d2e 2427 return ret;
1da177e4
LT
2428}
2429
2430/**
2cf71d2e
DJ
2431 * velocity_get_status - statistics callback
2432 * @dev: network device
1da177e4 2433 *
2cf71d2e
DJ
2434 * Callback from the network layer to allow driver statistics
2435 * to be resynchronized with hardware collected state. In the
2436 * case of the velocity we need to pull the MIB counters from
2437 * the hardware into the counters before letting the network
2438 * layer display them.
1da177e4 2439 */
2cf71d2e 2440static struct net_device_stats *velocity_get_stats(struct net_device *dev)
1da177e4 2441{
2cf71d2e 2442 struct velocity_info *vptr = netdev_priv(dev);
1da177e4 2443
2cf71d2e
DJ
2444 /* If the hardware is down, don't touch MII */
2445 if (!netif_running(dev))
2446 return &dev->stats;
1da177e4 2447
2cf71d2e
DJ
2448 spin_lock_irq(&vptr->lock);
2449 velocity_update_hw_mibs(vptr);
2450 spin_unlock_irq(&vptr->lock);
1da177e4 2451
2cf71d2e
DJ
2452 dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
2453 dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
2454 dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
1da177e4 2455
2cf71d2e
DJ
2456// unsigned long rx_dropped; /* no space in linux buffers */
2457 dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
2458 /* detailed rx_errors: */
2459// unsigned long rx_length_errors;
2460// unsigned long rx_over_errors; /* receiver ring buff overflow */
2461 dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
2462// unsigned long rx_frame_errors; /* recv'd frame alignment error */
2463// unsigned long rx_fifo_errors; /* recv'r fifo overrun */
2464// unsigned long rx_missed_errors; /* receiver missed packet */
2465
2466 /* detailed tx_errors */
2467// unsigned long tx_fifo_errors;
2468
2469 return &dev->stats;
1da177e4
LT
2470}
2471
2cf71d2e
DJ
2472/**
2473 * velocity_close - close adapter callback
2474 * @dev: network device
2475 *
2476 * Callback from the network layer when the velocity is being
2477 * deactivated by the network layer
2478 */
2479static int velocity_close(struct net_device *dev)
1da177e4 2480{
2cf71d2e 2481 struct velocity_info *vptr = netdev_priv(dev);
1da177e4 2482
dfff7144 2483 napi_disable(&vptr->napi);
2cf71d2e
DJ
2484 netif_stop_queue(dev);
2485 velocity_shutdown(vptr);
1da177e4 2486
2cf71d2e
DJ
2487 if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
2488 velocity_get_ip(vptr);
2489 if (dev->irq != 0)
2490 free_irq(dev->irq, dev);
1da177e4 2491
2cf71d2e
DJ
2492 /* Power down the chip */
2493 pci_set_power_state(vptr->pdev, PCI_D3hot);
1da177e4 2494
2cf71d2e 2495 velocity_free_rings(vptr);
1da177e4 2496
2cf71d2e
DJ
2497 vptr->flags &= (~VELOCITY_FLAGS_OPENED);
2498 return 0;
1da177e4
LT
2499}
2500
2501/**
2cf71d2e
DJ
2502 * velocity_xmit - transmit packet callback
2503 * @skb: buffer to transmit
2504 * @dev: network device
1da177e4 2505 *
2cf71d2e
DJ
2506 * Called by the networ layer to request a packet is queued to
2507 * the velocity. Returns zero on success.
1da177e4 2508 */
61357325
SH
2509static netdev_tx_t velocity_xmit(struct sk_buff *skb,
2510 struct net_device *dev)
1da177e4 2511{
2cf71d2e
DJ
2512 struct velocity_info *vptr = netdev_priv(dev);
2513 int qnum = 0;
2514 struct tx_desc *td_ptr;
2515 struct velocity_td_info *tdinfo;
2516 unsigned long flags;
2517 int pktlen;
c79992fd
SK
2518 int index, prev;
2519 int i = 0;
1da177e4 2520
2cf71d2e
DJ
2521 if (skb_padto(skb, ETH_ZLEN))
2522 goto out;
1da177e4 2523
c79992fd
SK
2524 /* The hardware can handle at most 7 memory segments, so merge
2525 * the skb if there are more */
2526 if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
2527 kfree_skb(skb);
2528 return NETDEV_TX_OK;
2529 }
2530
2531 pktlen = skb_shinfo(skb)->nr_frags == 0 ?
2532 max_t(unsigned int, skb->len, ETH_ZLEN) :
2533 skb_headlen(skb);
1da177e4 2534
2cf71d2e 2535 spin_lock_irqsave(&vptr->lock, flags);
1da177e4 2536
2cf71d2e
DJ
2537 index = vptr->tx.curr[qnum];
2538 td_ptr = &(vptr->tx.rings[qnum][index]);
2539 tdinfo = &(vptr->tx.infos[qnum][index]);
1da177e4 2540
2cf71d2e
DJ
2541 td_ptr->tdesc1.TCR = TCR0_TIC;
2542 td_ptr->td_buf[0].size &= ~TD_QUEUE;
1da177e4 2543
2cf71d2e
DJ
2544 /*
2545 * Map the linear network buffer into PCI space and
2546 * add it to the transmit ring.
2547 */
2548 tdinfo->skb = skb;
2549 tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
c79992fd 2550 td_ptr->tdesc0.len = cpu_to_le16(pktlen);
2cf71d2e
DJ
2551 td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
2552 td_ptr->td_buf[0].pa_high = 0;
c79992fd
SK
2553 td_ptr->td_buf[0].size = cpu_to_le16(pktlen);
2554
2555 /* Handle fragments */
2556 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
9e903e08 2557 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
c79992fd 2558
e4cb193f
IC
2559 tdinfo->skb_dma[i + 1] = skb_frag_dma_map(&vptr->pdev->dev,
2560 frag, 0,
9e903e08 2561 skb_frag_size(frag),
5d6bcdfe 2562 DMA_TO_DEVICE);
c79992fd
SK
2563
2564 td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
2565 td_ptr->td_buf[i + 1].pa_high = 0;
9e903e08 2566 td_ptr->td_buf[i + 1].size = cpu_to_le16(skb_frag_size(frag));
c79992fd
SK
2567 }
2568 tdinfo->nskb_dma = i + 1;
2cf71d2e
DJ
2569
2570 td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
2571
eab6d18d 2572 if (vlan_tx_tag_present(skb)) {
2cf71d2e
DJ
2573 td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb));
2574 td_ptr->tdesc1.TCR |= TCR0_VETAG;
2575 }
2576
2577 /*
2578 * Handle hardware checksum
2579 */
f593fe36 2580 if (skb->ip_summed == CHECKSUM_PARTIAL) {
2cf71d2e
DJ
2581 const struct iphdr *ip = ip_hdr(skb);
2582 if (ip->protocol == IPPROTO_TCP)
2583 td_ptr->tdesc1.TCR |= TCR0_TCPCK;
2584 else if (ip->protocol == IPPROTO_UDP)
2585 td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
2586 td_ptr->tdesc1.TCR |= TCR0_IPCK;
2587 }
1da177e4 2588
c79992fd
SK
2589 prev = index - 1;
2590 if (prev < 0)
2591 prev = vptr->options.numtx - 1;
2592 td_ptr->tdesc0.len |= OWNED_BY_NIC;
2593 vptr->tx.used[qnum]++;
2594 vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
1da177e4 2595
c79992fd
SK
2596 if (AVAIL_TD(vptr, qnum) < 1)
2597 netif_stop_queue(dev);
1da177e4 2598
c79992fd
SK
2599 td_ptr = &(vptr->tx.rings[qnum][prev]);
2600 td_ptr->td_buf[0].size |= TD_QUEUE;
2601 mac_tx_queue_wake(vptr->mac_regs, qnum);
1da177e4 2602
2cf71d2e
DJ
2603 spin_unlock_irqrestore(&vptr->lock, flags);
2604out:
2605 return NETDEV_TX_OK;
1da177e4
LT
2606}
2607
2cf71d2e
DJ
2608static const struct net_device_ops velocity_netdev_ops = {
2609 .ndo_open = velocity_open,
2610 .ndo_stop = velocity_close,
2611 .ndo_start_xmit = velocity_xmit,
2612 .ndo_get_stats = velocity_get_stats,
2613 .ndo_validate_addr = eth_validate_addr,
5ae297b0 2614 .ndo_set_mac_address = eth_mac_addr,
afc4b13d 2615 .ndo_set_rx_mode = velocity_set_multi,
2cf71d2e
DJ
2616 .ndo_change_mtu = velocity_change_mtu,
2617 .ndo_do_ioctl = velocity_ioctl,
2618 .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid,
2619 .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid,
2cf71d2e
DJ
2620};
2621
1da177e4 2622/**
2cf71d2e
DJ
2623 * velocity_init_info - init private data
2624 * @pdev: PCI device
2625 * @vptr: Velocity info
2626 * @info: Board type
1da177e4 2627 *
2cf71d2e
DJ
2628 * Set up the initial velocity_info struct for the device that has been
2629 * discovered.
1da177e4 2630 */
2cf71d2e
DJ
2631static void __devinit velocity_init_info(struct pci_dev *pdev,
2632 struct velocity_info *vptr,
2633 const struct velocity_info_tbl *info)
1da177e4 2634{
2cf71d2e
DJ
2635 memset(vptr, 0, sizeof(struct velocity_info));
2636
2637 vptr->pdev = pdev;
2638 vptr->chip_id = info->chip_id;
2639 vptr->tx.numq = info->txqueue;
2640 vptr->multicast_limit = MCAM_SIZE;
2641 spin_lock_init(&vptr->lock);
6aa20a22 2642}
1da177e4
LT
2643
2644/**
2cf71d2e
DJ
2645 * velocity_get_pci_info - retrieve PCI info for device
2646 * @vptr: velocity device
2647 * @pdev: PCI device it matches
1da177e4 2648 *
2cf71d2e
DJ
2649 * Retrieve the PCI configuration space data that interests us from
2650 * the kernel PCI layer
1da177e4 2651 */
2cf71d2e 2652static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
1da177e4 2653{
2cf71d2e 2654 vptr->rev_id = pdev->revision;
1da177e4 2655
2cf71d2e 2656 pci_set_master(pdev);
1da177e4 2657
2cf71d2e
DJ
2658 vptr->ioaddr = pci_resource_start(pdev, 0);
2659 vptr->memaddr = pci_resource_start(pdev, 1);
1da177e4 2660
2cf71d2e
DJ
2661 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
2662 dev_err(&pdev->dev,
2663 "region #0 is not an I/O resource, aborting.\n");
2664 return -EINVAL;
2665 }
2666
2667 if ((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) {
2668 dev_err(&pdev->dev,
2669 "region #1 is an I/O resource, aborting.\n");
2670 return -EINVAL;
2671 }
2672
2673 if (pci_resource_len(pdev, 1) < VELOCITY_IO_SIZE) {
2674 dev_err(&pdev->dev, "region #1 is too small.\n");
2675 return -EINVAL;
2676 }
2677 vptr->pdev = pdev;
6aa20a22 2678
1da177e4
LT
2679 return 0;
2680}
2681
2cf71d2e
DJ
2682/**
2683 * velocity_print_info - per driver data
2684 * @vptr: velocity
2685 *
2686 * Print per driver data as the kernel driver finds Velocity
2687 * hardware
2688 */
2689static void __devinit velocity_print_info(struct velocity_info *vptr)
1da177e4 2690{
2cf71d2e 2691 struct net_device *dev = vptr->dev;
1da177e4 2692
2cf71d2e 2693 printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
aa7c68a5
HS
2694 printk(KERN_INFO "%s: Ethernet Address: %pM\n",
2695 dev->name, dev->dev_addr);
1da177e4
LT
2696}
2697
2698static u32 velocity_get_link(struct net_device *dev)
2699{
8ab6f3f7 2700 struct velocity_info *vptr = netdev_priv(dev);
c4067400 2701 struct mac_regs __iomem *regs = vptr->mac_regs;
59b693fb 2702 return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 1 : 0;
1da177e4
LT
2703}
2704
2cf71d2e
DJ
2705/**
2706 * velocity_found1 - set up discovered velocity card
2707 * @pdev: PCI device
2708 * @ent: PCI device table entry that matched
2709 *
2710 * Configure a discovered adapter from scratch. Return a negative
2711 * errno error code on failure paths.
2712 */
2713static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent)
1da177e4 2714{
2cf71d2e
DJ
2715 static int first = 1;
2716 struct net_device *dev;
2717 int i;
2718 const char *drv_string;
2719 const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
2720 struct velocity_info *vptr;
2721 struct mac_regs __iomem *regs;
2722 int ret = -ENOMEM;
1da177e4 2723
2cf71d2e
DJ
2724 /* FIXME: this driver, like almost all other ethernet drivers,
2725 * can support more than MAX_UNITS.
2726 */
2727 if (velocity_nics >= MAX_UNITS) {
2728 dev_notice(&pdev->dev, "already found %d NICs.\n",
2729 velocity_nics);
2730 return -ENODEV;
2731 }
1da177e4 2732
2cf71d2e
DJ
2733 dev = alloc_etherdev(sizeof(struct velocity_info));
2734 if (!dev) {
2735 dev_err(&pdev->dev, "allocate net device failed.\n");
2736 goto out;
2737 }
1da177e4 2738
2cf71d2e 2739 /* Chain it all together */
1da177e4 2740
2cf71d2e
DJ
2741 SET_NETDEV_DEV(dev, &pdev->dev);
2742 vptr = netdev_priv(dev);
2743
2744
2745 if (first) {
2746 printk(KERN_INFO "%s Ver. %s\n",
2747 VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
2748 printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
2749 printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
2750 first = 0;
2751 }
2752
2753 velocity_init_info(pdev, vptr, info);
2754
2755 vptr->dev = dev;
2756
2cf71d2e
DJ
2757 ret = pci_enable_device(pdev);
2758 if (ret < 0)
2759 goto err_free_dev;
2760
889635fd
KV
2761 dev->irq = pdev->irq;
2762
2cf71d2e
DJ
2763 ret = velocity_get_pci_info(vptr, pdev);
2764 if (ret < 0) {
2765 /* error message already printed */
2766 goto err_disable;
1da177e4 2767 }
2cf71d2e
DJ
2768
2769 ret = pci_request_regions(pdev, VELOCITY_NAME);
2770 if (ret < 0) {
2771 dev_err(&pdev->dev, "No PCI resources.\n");
2772 goto err_disable;
1da177e4 2773 }
2cf71d2e
DJ
2774
2775 regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE);
2776 if (regs == NULL) {
2777 ret = -EIO;
2778 goto err_release_res;
1da177e4 2779 }
1da177e4 2780
2cf71d2e 2781 vptr->mac_regs = regs;
1da177e4 2782
2cf71d2e 2783 mac_wol_reset(regs);
1da177e4 2784
2cf71d2e 2785 dev->base_addr = vptr->ioaddr;
1da177e4 2786
2cf71d2e
DJ
2787 for (i = 0; i < 6; i++)
2788 dev->dev_addr[i] = readb(&regs->PAR[i]);
6aa20a22 2789
6aa20a22 2790
2cf71d2e 2791 drv_string = dev_driver_string(&pdev->dev);
1da177e4 2792
2cf71d2e 2793 velocity_get_options(&vptr->options, velocity_nics, drv_string);
1da177e4 2794
2cf71d2e
DJ
2795 /*
2796 * Mask out the options cannot be set to the chip
2797 */
6aa20a22 2798
2cf71d2e 2799 vptr->options.flags &= info->flags;
1da177e4 2800
2cf71d2e
DJ
2801 /*
2802 * Enable the chip specified capbilities
2803 */
1da177e4 2804
2cf71d2e 2805 vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
1da177e4 2806
2cf71d2e
DJ
2807 vptr->wol_opts = vptr->options.wol_opts;
2808 vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
1da177e4 2809
2cf71d2e 2810 vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
1da177e4 2811
2cf71d2e
DJ
2812 dev->irq = pdev->irq;
2813 dev->netdev_ops = &velocity_netdev_ops;
2814 dev->ethtool_ops = &velocity_ethtool_ops;
dfff7144 2815 netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
6aa20a22 2816
f593fe36 2817 dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HW_VLAN_TX;
2cf71d2e 2818 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
de2b96f1 2819 NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
1da177e4 2820
2cf71d2e
DJ
2821 ret = register_netdev(dev);
2822 if (ret < 0)
2823 goto err_iounmap;
2824
2825 if (!velocity_get_link(dev)) {
2826 netif_carrier_off(dev);
2827 vptr->mii_status |= VELOCITY_LINK_FAIL;
1da177e4
LT
2828 }
2829
2cf71d2e
DJ
2830 velocity_print_info(vptr);
2831 pci_set_drvdata(pdev, dev);
1da177e4 2832
2cf71d2e 2833 /* and leave the chip powered down */
1da177e4 2834
2cf71d2e 2835 pci_set_power_state(pdev, PCI_D3hot);
2cf71d2e
DJ
2836 velocity_nics++;
2837out:
2838 return ret;
2839
2840err_iounmap:
2841 iounmap(regs);
2842err_release_res:
2843 pci_release_regions(pdev);
2844err_disable:
2845 pci_disable_device(pdev);
2846err_free_dev:
2847 free_netdev(dev);
2848 goto out;
1da177e4
LT
2849}
2850
2cf71d2e 2851#ifdef CONFIG_PM
1da177e4
LT
2852/**
2853 * wol_calc_crc - WOL CRC
2854 * @pattern: data pattern
2855 * @mask_pattern: mask
2856 *
2857 * Compute the wake on lan crc hashes for the packet header
2858 * we are interested in.
2859 */
c4067400 2860static u16 wol_calc_crc(int size, u8 *pattern, u8 *mask_pattern)
1da177e4
LT
2861{
2862 u16 crc = 0xFFFF;
2863 u8 mask;
2864 int i, j;
2865
2866 for (i = 0; i < size; i++) {
2867 mask = mask_pattern[i];
2868
2869 /* Skip this loop if the mask equals to zero */
2870 if (mask == 0x00)
2871 continue;
2872
2873 for (j = 0; j < 8; j++) {
2874 if ((mask & 0x01) == 0) {
2875 mask >>= 1;
2876 continue;
2877 }
2878 mask >>= 1;
2879 crc = crc_ccitt(crc, &(pattern[i * 8 + j]), 1);
2880 }
2881 }
2882 /* Finally, invert the result once to get the correct data */
2883 crc = ~crc;
906d66df 2884 return bitrev32(crc) >> 16;
1da177e4
LT
2885}
2886
2887/**
2888 * velocity_set_wol - set up for wake on lan
2889 * @vptr: velocity to set WOL status on
2890 *
2891 * Set a card up for wake on lan either by unicast or by
2892 * ARP packet.
2893 *
2894 * FIXME: check static buffer is safe here
2895 */
1da177e4
LT
2896static int velocity_set_wol(struct velocity_info *vptr)
2897{
c4067400 2898 struct mac_regs __iomem *regs = vptr->mac_regs;
2ffa007e 2899 enum speed_opt spd_dpx = vptr->options.spd_dpx;
1da177e4
LT
2900 static u8 buf[256];
2901 int i;
2902
2903 static u32 mask_pattern[2][4] = {
2904 {0x00203000, 0x000003C0, 0x00000000, 0x0000000}, /* ARP */
2905 {0xfffff000, 0xffffffff, 0xffffffff, 0x000ffff} /* Magic Packet */
2906 };
2907
2908 writew(0xFFFF, &regs->WOLCRClr);
2909 writeb(WOLCFG_SAB | WOLCFG_SAM, &regs->WOLCFGSet);
2910 writew(WOLCR_MAGIC_EN, &regs->WOLCRSet);
2911
2912 /*
2913 if (vptr->wol_opts & VELOCITY_WOL_PHY)
2914 writew((WOLCR_LINKON_EN|WOLCR_LINKOFF_EN), &regs->WOLCRSet);
2915 */
2916
c4067400 2917 if (vptr->wol_opts & VELOCITY_WOL_UCAST)
1da177e4 2918 writew(WOLCR_UNICAST_EN, &regs->WOLCRSet);
1da177e4
LT
2919
2920 if (vptr->wol_opts & VELOCITY_WOL_ARP) {
2921 struct arp_packet *arp = (struct arp_packet *) buf;
2922 u16 crc;
2923 memset(buf, 0, sizeof(struct arp_packet) + 7);
2924
2925 for (i = 0; i < 4; i++)
2926 writel(mask_pattern[0][i], &regs->ByteMask[0][i]);
2927
2928 arp->type = htons(ETH_P_ARP);
2929 arp->ar_op = htons(1);
2930
2931 memcpy(arp->ar_tip, vptr->ip_addr, 4);
2932
2933 crc = wol_calc_crc((sizeof(struct arp_packet) + 7) / 8, buf,
2934 (u8 *) & mask_pattern[0][0]);
2935
2936 writew(crc, &regs->PatternCRC[0]);
2937 writew(WOLCR_ARP_EN, &regs->WOLCRSet);
2938 }
2939
2940 BYTE_REG_BITS_ON(PWCFG_WOLTYPE, &regs->PWCFGSet);
2941 BYTE_REG_BITS_ON(PWCFG_LEGACY_WOLEN, &regs->PWCFGSet);
2942
2943 writew(0x0FFF, &regs->WOLSRClr);
2944
2ffa007e 2945 if (spd_dpx == SPD_DPX_1000_FULL)
2946 goto mac_done;
2947
2948 if (spd_dpx != SPD_DPX_AUTO)
2949 goto advertise_done;
2950
1da177e4
LT
2951 if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) {
2952 if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
3a7f8681 2953 MII_REG_BITS_ON(AUXCR_MDPPS, MII_NCONFIG, vptr->mac_regs);
1da177e4 2954
3a7f8681 2955 MII_REG_BITS_OFF(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs);
1da177e4
LT
2956 }
2957
2958 if (vptr->mii_status & VELOCITY_SPEED_1000)
3a7f8681 2959 MII_REG_BITS_ON(BMCR_ANRESTART, MII_BMCR, vptr->mac_regs);
1da177e4 2960
2ffa007e 2961advertise_done:
1da177e4
LT
2962 BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
2963
2964 {
2965 u8 GCR;
2966 GCR = readb(&regs->CHIPGCR);
2967 GCR = (GCR & ~CHIPGCR_FCGMII) | CHIPGCR_FCFDX;
2968 writeb(GCR, &regs->CHIPGCR);
2969 }
2970
2ffa007e 2971mac_done:
1da177e4
LT
2972 BYTE_REG_BITS_OFF(ISR_PWEI, &regs->ISR);
2973 /* Turn on SWPTAG just before entering power mode */
2974 BYTE_REG_BITS_ON(STICKHW_SWPTAG, &regs->STICKHW);
2975 /* Go to bed ..... */
2976 BYTE_REG_BITS_ON((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
2977
2978 return 0;
2979}
2980
2cf71d2e
DJ
2981/**
2982 * velocity_save_context - save registers
2983 * @vptr: velocity
2984 * @context: buffer for stored context
2985 *
2986 * Retrieve the current configuration from the velocity hardware
2987 * and stash it in the context structure, for use by the context
2988 * restore functions. This allows us to save things we need across
2989 * power down states
2990 */
2991static void velocity_save_context(struct velocity_info *vptr, struct velocity_context *context)
2992{
2993 struct mac_regs __iomem *regs = vptr->mac_regs;
2994 u16 i;
2995 u8 __iomem *ptr = (u8 __iomem *)regs;
2996
2997 for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4)
2998 *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
2999
3000 for (i = MAC_REG_MAR; i < MAC_REG_TDCSR_CLR; i += 4)
3001 *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
3002
3003 for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
3004 *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
3005
3006}
3007
1da177e4
LT
3008static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
3009{
3010 struct net_device *dev = pci_get_drvdata(pdev);
3011 struct velocity_info *vptr = netdev_priv(dev);
3012 unsigned long flags;
3013
c4067400 3014 if (!netif_running(vptr->dev))
1da177e4
LT
3015 return 0;
3016
3017 netif_device_detach(vptr->dev);
3018
3019 spin_lock_irqsave(&vptr->lock, flags);
3020 pci_save_state(pdev);
5ae297b0 3021
1da177e4
LT
3022 if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
3023 velocity_get_ip(vptr);
3024 velocity_save_context(vptr, &vptr->context);
3025 velocity_shutdown(vptr);
3026 velocity_set_wol(vptr);
4a51c0d0 3027 pci_enable_wake(pdev, PCI_D3hot, 1);
1da177e4
LT
3028 pci_set_power_state(pdev, PCI_D3hot);
3029 } else {
3030 velocity_save_context(vptr, &vptr->context);
3031 velocity_shutdown(vptr);
3032 pci_disable_device(pdev);
3033 pci_set_power_state(pdev, pci_choose_state(pdev, state));
3034 }
5ae297b0 3035
2cf71d2e
DJ
3036 spin_unlock_irqrestore(&vptr->lock, flags);
3037 return 0;
3038}
3039
3040/**
3041 * velocity_restore_context - restore registers
3042 * @vptr: velocity
3043 * @context: buffer for stored context
3044 *
3045 * Reload the register configuration from the velocity context
3046 * created by velocity_save_context.
3047 */
3048static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
3049{
3050 struct mac_regs __iomem *regs = vptr->mac_regs;
3051 int i;
3052 u8 __iomem *ptr = (u8 __iomem *)regs;
3053
3054 for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4)
3055 writel(*((u32 *) (context->mac_reg + i)), ptr + i);
3056
3057 /* Just skip cr0 */
3058 for (i = MAC_REG_CR1_SET; i < MAC_REG_CR0_CLR; i++) {
3059 /* Clear */
3060 writeb(~(*((u8 *) (context->mac_reg + i))), ptr + i + 4);
3061 /* Set */
3062 writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
3063 }
3064
3065 for (i = MAC_REG_MAR; i < MAC_REG_IMR; i += 4)
3066 writel(*((u32 *) (context->mac_reg + i)), ptr + i);
3067
3068 for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
3069 writel(*((u32 *) (context->mac_reg + i)), ptr + i);
3070
3071 for (i = MAC_REG_TDCSR_SET; i <= MAC_REG_RDCSR_SET; i++)
3072 writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
1da177e4
LT
3073}
3074
3075static int velocity_resume(struct pci_dev *pdev)
3076{
3077 struct net_device *dev = pci_get_drvdata(pdev);
3078 struct velocity_info *vptr = netdev_priv(dev);
3079 unsigned long flags;
3080 int i;
3081
c4067400 3082 if (!netif_running(vptr->dev))
1da177e4
LT
3083 return 0;
3084
3085 pci_set_power_state(pdev, PCI_D0);
3086 pci_enable_wake(pdev, 0, 0);
3087 pci_restore_state(pdev);
3088
3089 mac_wol_reset(vptr->mac_regs);
3090
3091 spin_lock_irqsave(&vptr->lock, flags);
3092 velocity_restore_context(vptr, &vptr->context);
3093 velocity_init_registers(vptr, VELOCITY_INIT_WOL);
3094 mac_disable_int(vptr->mac_regs);
3095
d6cade0f 3096 velocity_tx_srv(vptr);
1da177e4 3097
0fe9f15e 3098 for (i = 0; i < vptr->tx.numq; i++) {
c4067400 3099 if (vptr->tx.used[i])
1da177e4 3100 mac_tx_queue_wake(vptr->mac_regs, i);
1da177e4
LT
3101 }
3102
3103 mac_enable_int(vptr->mac_regs);
3104 spin_unlock_irqrestore(&vptr->lock, flags);
3105 netif_device_attach(vptr->dev);
3106
3107 return 0;
3108}
2cf71d2e 3109#endif
1da177e4 3110
2cf71d2e
DJ
3111/*
3112 * Definition for our device driver. The PCI layer interface
3113 * uses this to handle all our card discover and plugging
3114 */
3115static struct pci_driver velocity_driver = {
5ae297b0 3116 .name = VELOCITY_NAME,
3117 .id_table = velocity_id_table,
3118 .probe = velocity_found1,
3119 .remove = __devexit_p(velocity_remove1),
2cf71d2e 3120#ifdef CONFIG_PM
5ae297b0 3121 .suspend = velocity_suspend,
3122 .resume = velocity_resume,
2cf71d2e
DJ
3123#endif
3124};
3125
3126
3127/**
3128 * velocity_ethtool_up - pre hook for ethtool
3129 * @dev: network device
3130 *
3131 * Called before an ethtool operation. We need to make sure the
3132 * chip is out of D3 state before we poke at it.
3133 */
3134static int velocity_ethtool_up(struct net_device *dev)
3135{
3136 struct velocity_info *vptr = netdev_priv(dev);
3137 if (!netif_running(dev))
3138 pci_set_power_state(vptr->pdev, PCI_D0);
3139 return 0;
3140}
3141
3142/**
3143 * velocity_ethtool_down - post hook for ethtool
3144 * @dev: network device
3145 *
3146 * Called after an ethtool operation. Restore the chip back to D3
3147 * state if it isn't running.
3148 */
3149static void velocity_ethtool_down(struct net_device *dev)
3150{
3151 struct velocity_info *vptr = netdev_priv(dev);
3152 if (!netif_running(dev))
3153 pci_set_power_state(vptr->pdev, PCI_D3hot);
3154}
3155
70739497
DD
3156static int velocity_get_settings(struct net_device *dev,
3157 struct ethtool_cmd *cmd)
2cf71d2e
DJ
3158{
3159 struct velocity_info *vptr = netdev_priv(dev);
3160 struct mac_regs __iomem *regs = vptr->mac_regs;
3161 u32 status;
3162 status = check_connection_type(vptr->mac_regs);
3163
3164 cmd->supported = SUPPORTED_TP |
3165 SUPPORTED_Autoneg |
3166 SUPPORTED_10baseT_Half |
3167 SUPPORTED_10baseT_Full |
3168 SUPPORTED_100baseT_Half |
3169 SUPPORTED_100baseT_Full |
3170 SUPPORTED_1000baseT_Half |
3171 SUPPORTED_1000baseT_Full;
15419227 3172
3173 cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
3174 if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
3175 cmd->advertising |=
3176 ADVERTISED_10baseT_Half |
3177 ADVERTISED_10baseT_Full |
3178 ADVERTISED_100baseT_Half |
3179 ADVERTISED_100baseT_Full |
3180 ADVERTISED_1000baseT_Half |
3181 ADVERTISED_1000baseT_Full;
3182 } else {
3183 switch (vptr->options.spd_dpx) {
3184 case SPD_DPX_1000_FULL:
3185 cmd->advertising |= ADVERTISED_1000baseT_Full;
3186 break;
3187 case SPD_DPX_100_HALF:
3188 cmd->advertising |= ADVERTISED_100baseT_Half;
3189 break;
3190 case SPD_DPX_100_FULL:
3191 cmd->advertising |= ADVERTISED_100baseT_Full;
3192 break;
3193 case SPD_DPX_10_HALF:
3194 cmd->advertising |= ADVERTISED_10baseT_Half;
3195 break;
3196 case SPD_DPX_10_FULL:
3197 cmd->advertising |= ADVERTISED_10baseT_Full;
3198 break;
3199 default:
3200 break;
3201 }
3202 }
70739497 3203
2cf71d2e 3204 if (status & VELOCITY_SPEED_1000)
70739497 3205 ethtool_cmd_speed_set(cmd, SPEED_1000);
2cf71d2e 3206 else if (status & VELOCITY_SPEED_100)
70739497 3207 ethtool_cmd_speed_set(cmd, SPEED_100);
2cf71d2e 3208 else
70739497
DD
3209 ethtool_cmd_speed_set(cmd, SPEED_10);
3210
2cf71d2e
DJ
3211 cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
3212 cmd->port = PORT_TP;
3213 cmd->transceiver = XCVR_INTERNAL;
3214 cmd->phy_address = readb(&regs->MIIADR) & 0x1F;
3215
3216 if (status & VELOCITY_DUPLEX_FULL)
3217 cmd->duplex = DUPLEX_FULL;
3218 else
3219 cmd->duplex = DUPLEX_HALF;
3220
3221 return 0;
3222}
3223
25db0338
DD
3224static int velocity_set_settings(struct net_device *dev,
3225 struct ethtool_cmd *cmd)
2cf71d2e
DJ
3226{
3227 struct velocity_info *vptr = netdev_priv(dev);
25db0338 3228 u32 speed = ethtool_cmd_speed(cmd);
2cf71d2e
DJ
3229 u32 curr_status;
3230 u32 new_status = 0;
3231 int ret = 0;
3232
3233 curr_status = check_connection_type(vptr->mac_regs);
3234 curr_status &= (~VELOCITY_LINK_FAIL);
3235
3236 new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0);
25db0338
DD
3237 new_status |= ((speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
3238 new_status |= ((speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
3239 new_status |= ((speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
2cf71d2e
DJ
3240 new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
3241
15419227 3242 if ((new_status & VELOCITY_AUTONEG_ENABLE) &&
3243 (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) {
2cf71d2e 3244 ret = -EINVAL;
15419227 3245 } else {
3246 enum speed_opt spd_dpx;
3247
3248 if (new_status & VELOCITY_AUTONEG_ENABLE)
3249 spd_dpx = SPD_DPX_AUTO;
3250 else if ((new_status & VELOCITY_SPEED_1000) &&
3251 (new_status & VELOCITY_DUPLEX_FULL)) {
3252 spd_dpx = SPD_DPX_1000_FULL;
3253 } else if (new_status & VELOCITY_SPEED_100)
3254 spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ?
3255 SPD_DPX_100_FULL : SPD_DPX_100_HALF;
3256 else if (new_status & VELOCITY_SPEED_10)
3257 spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ?
3258 SPD_DPX_10_FULL : SPD_DPX_10_HALF;
3259 else
3260 return -EOPNOTSUPP;
3261
3262 vptr->options.spd_dpx = spd_dpx;
3263
2cf71d2e 3264 velocity_set_media_mode(vptr, new_status);
15419227 3265 }
2cf71d2e
DJ
3266
3267 return ret;
3268}
3269
3270static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
3271{
3272 struct velocity_info *vptr = netdev_priv(dev);
3273 strcpy(info->driver, VELOCITY_NAME);
3274 strcpy(info->version, VELOCITY_VERSION);
3275 strcpy(info->bus_info, pci_name(vptr->pdev));
3276}
3277
3278static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3279{
3280 struct velocity_info *vptr = netdev_priv(dev);
3281 wol->supported = WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP;
3282 wol->wolopts |= WAKE_MAGIC;
3283 /*
3284 if (vptr->wol_opts & VELOCITY_WOL_PHY)
3285 wol.wolopts|=WAKE_PHY;
3286 */
3287 if (vptr->wol_opts & VELOCITY_WOL_UCAST)
3288 wol->wolopts |= WAKE_UCAST;
3289 if (vptr->wol_opts & VELOCITY_WOL_ARP)
3290 wol->wolopts |= WAKE_ARP;
3291 memcpy(&wol->sopass, vptr->wol_passwd, 6);
3292}
3293
3294static int velocity_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3295{
3296 struct velocity_info *vptr = netdev_priv(dev);
3297
3298 if (!(wol->wolopts & (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP)))
3299 return -EFAULT;
3300 vptr->wol_opts = VELOCITY_WOL_MAGIC;
3301
3302 /*
3303 if (wol.wolopts & WAKE_PHY) {
3304 vptr->wol_opts|=VELOCITY_WOL_PHY;
3305 vptr->flags |=VELOCITY_FLAGS_WOL_ENABLED;
3306 }
3307 */
3308
3309 if (wol->wolopts & WAKE_MAGIC) {
3310 vptr->wol_opts |= VELOCITY_WOL_MAGIC;
3311 vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
3312 }
3313 if (wol->wolopts & WAKE_UCAST) {
3314 vptr->wol_opts |= VELOCITY_WOL_UCAST;
3315 vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
3316 }
3317 if (wol->wolopts & WAKE_ARP) {
3318 vptr->wol_opts |= VELOCITY_WOL_ARP;
3319 vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
3320 }
3321 memcpy(vptr->wol_passwd, wol->sopass, 6);
3322 return 0;
3323}
3324
3325static u32 velocity_get_msglevel(struct net_device *dev)
3326{
3327 return msglevel;
3328}
3329
3330static void velocity_set_msglevel(struct net_device *dev, u32 value)
3331{
3332 msglevel = value;
3333}
3334
6dfc4b95
SK
3335static int get_pending_timer_val(int val)
3336{
3337 int mult_bits = val >> 6;
3338 int mult = 1;
3339
3340 switch (mult_bits)
3341 {
3342 case 1:
3343 mult = 4; break;
3344 case 2:
3345 mult = 16; break;
3346 case 3:
3347 mult = 64; break;
3348 case 0:
3349 default:
3350 break;
3351 }
3352
3353 return (val & 0x3f) * mult;
3354}
3355
3356static void set_pending_timer_val(int *val, u32 us)
3357{
3358 u8 mult = 0;
3359 u8 shift = 0;
3360
3361 if (us >= 0x3f) {
3362 mult = 1; /* mult with 4 */
3363 shift = 2;
3364 }
3365 if (us >= 0x3f * 4) {
3366 mult = 2; /* mult with 16 */
3367 shift = 4;
3368 }
3369 if (us >= 0x3f * 16) {
3370 mult = 3; /* mult with 64 */
3371 shift = 6;
3372 }
3373
3374 *val = (mult << 6) | ((us >> shift) & 0x3f);
3375}
3376
3377
3378static int velocity_get_coalesce(struct net_device *dev,
3379 struct ethtool_coalesce *ecmd)
3380{
3381 struct velocity_info *vptr = netdev_priv(dev);
3382
3383 ecmd->tx_max_coalesced_frames = vptr->options.tx_intsup;
3384 ecmd->rx_max_coalesced_frames = vptr->options.rx_intsup;
3385
3386 ecmd->rx_coalesce_usecs = get_pending_timer_val(vptr->options.rxqueue_timer);
3387 ecmd->tx_coalesce_usecs = get_pending_timer_val(vptr->options.txqueue_timer);
3388
3389 return 0;
3390}
3391
3392static int velocity_set_coalesce(struct net_device *dev,
3393 struct ethtool_coalesce *ecmd)
3394{
3395 struct velocity_info *vptr = netdev_priv(dev);
3396 int max_us = 0x3f * 64;
39c2ff43 3397 unsigned long flags;
6dfc4b95
SK
3398
3399 /* 6 bits of */
3400 if (ecmd->tx_coalesce_usecs > max_us)
3401 return -EINVAL;
3402 if (ecmd->rx_coalesce_usecs > max_us)
3403 return -EINVAL;
3404
3405 if (ecmd->tx_max_coalesced_frames > 0xff)
3406 return -EINVAL;
3407 if (ecmd->rx_max_coalesced_frames > 0xff)
3408 return -EINVAL;
3409
3410 vptr->options.rx_intsup = ecmd->rx_max_coalesced_frames;
3411 vptr->options.tx_intsup = ecmd->tx_max_coalesced_frames;
3412
3413 set_pending_timer_val(&vptr->options.rxqueue_timer,
3414 ecmd->rx_coalesce_usecs);
3415 set_pending_timer_val(&vptr->options.txqueue_timer,
3416 ecmd->tx_coalesce_usecs);
3417
3418 /* Setup the interrupt suppression and queue timers */
39c2ff43 3419 spin_lock_irqsave(&vptr->lock, flags);
6dfc4b95
SK
3420 mac_disable_int(vptr->mac_regs);
3421 setup_adaptive_interrupts(vptr);
3422 setup_queue_timers(vptr);
3423
3424 mac_write_int_mask(vptr->int_mask, vptr->mac_regs);
3425 mac_clear_isr(vptr->mac_regs);
3426 mac_enable_int(vptr->mac_regs);
39c2ff43 3427 spin_unlock_irqrestore(&vptr->lock, flags);
6dfc4b95
SK
3428
3429 return 0;
3430}
3431
ad66fa7a 3432static const char velocity_gstrings[][ETH_GSTRING_LEN] = {
3433 "rx_all",
3434 "rx_ok",
3435 "tx_ok",
3436 "rx_error",
3437 "rx_runt_ok",
3438 "rx_runt_err",
3439 "rx_64",
3440 "tx_64",
3441 "rx_65_to_127",
3442 "tx_65_to_127",
3443 "rx_128_to_255",
3444 "tx_128_to_255",
3445 "rx_256_to_511",
3446 "tx_256_to_511",
3447 "rx_512_to_1023",
3448 "tx_512_to_1023",
3449 "rx_1024_to_1518",
3450 "tx_1024_to_1518",
3451 "tx_ether_collisions",
3452 "rx_crc_errors",
3453 "rx_jumbo",
3454 "tx_jumbo",
3455 "rx_mac_control_frames",
3456 "tx_mac_control_frames",
3457 "rx_frame_alignement_errors",
3458 "rx_long_ok",
3459 "rx_long_err",
3460 "tx_sqe_errors",
3461 "rx_no_buf",
3462 "rx_symbol_errors",
3463 "in_range_length_errors",
3464 "late_collisions"
3465};
3466
3467static void velocity_get_strings(struct net_device *dev, u32 sset, u8 *data)
3468{
3469 switch (sset) {
3470 case ETH_SS_STATS:
3471 memcpy(data, *velocity_gstrings, sizeof(velocity_gstrings));
3472 break;
3473 }
3474}
3475
3476static int velocity_get_sset_count(struct net_device *dev, int sset)
3477{
3478 switch (sset) {
3479 case ETH_SS_STATS:
3480 return ARRAY_SIZE(velocity_gstrings);
3481 default:
3482 return -EOPNOTSUPP;
3483 }
3484}
3485
3486static void velocity_get_ethtool_stats(struct net_device *dev,
3487 struct ethtool_stats *stats, u64 *data)
3488{
3489 if (netif_running(dev)) {
3490 struct velocity_info *vptr = netdev_priv(dev);
3491 u32 *p = vptr->mib_counter;
3492 int i;
3493
3494 spin_lock_irq(&vptr->lock);
3495 velocity_update_hw_mibs(vptr);
3496 spin_unlock_irq(&vptr->lock);
3497
3498 for (i = 0; i < ARRAY_SIZE(velocity_gstrings); i++)
3499 *data++ = *p++;
3500 }
3501}
3502
2cf71d2e 3503static const struct ethtool_ops velocity_ethtool_ops = {
5ae297b0 3504 .get_settings = velocity_get_settings,
3505 .set_settings = velocity_set_settings,
3506 .get_drvinfo = velocity_get_drvinfo,
3507 .get_wol = velocity_ethtool_get_wol,
3508 .set_wol = velocity_ethtool_set_wol,
3509 .get_msglevel = velocity_get_msglevel,
3510 .set_msglevel = velocity_set_msglevel,
3511 .get_link = velocity_get_link,
ad66fa7a 3512 .get_strings = velocity_get_strings,
3513 .get_sset_count = velocity_get_sset_count,
3514 .get_ethtool_stats = velocity_get_ethtool_stats,
5ae297b0 3515 .get_coalesce = velocity_get_coalesce,
3516 .set_coalesce = velocity_set_coalesce,
3517 .begin = velocity_ethtool_up,
3518 .complete = velocity_ethtool_down
2cf71d2e 3519};
ce9f7fe3 3520
5ae297b0 3521#if defined(CONFIG_PM) && defined(CONFIG_INET)
1da177e4
LT
3522static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
3523{
5ae297b0 3524 struct in_ifaddr *ifa = ptr;
a337499f 3525 struct net_device *dev = ifa->ifa_dev->dev;
1da177e4 3526
516b4df1
BH
3527 if (dev_net(dev) == &init_net &&
3528 dev->netdev_ops == &velocity_netdev_ops)
3529 velocity_get_ip(netdev_priv(dev));
a337499f 3530
1da177e4
LT
3531 return NOTIFY_DONE;
3532}
ce9f7fe3 3533
2cf71d2e 3534static struct notifier_block velocity_inetaddr_notifier = {
5ae297b0 3535 .notifier_call = velocity_netdev_event,
2cf71d2e
DJ
3536};
3537
3538static void velocity_register_notifier(void)
3539{
3540 register_inetaddr_notifier(&velocity_inetaddr_notifier);
3541}
3542
3543static void velocity_unregister_notifier(void)
3544{
3545 unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
3546}
3547
3548#else
3549
3550#define velocity_register_notifier() do {} while (0)
3551#define velocity_unregister_notifier() do {} while (0)
3552
3553#endif /* defined(CONFIG_PM) && defined(CONFIG_INET) */
3554
3555/**
3556 * velocity_init_module - load time function
3557 *
3558 * Called when the velocity module is loaded. The PCI driver
3559 * is registered with the PCI layer, and in turn will call
3560 * the probe functions for each velocity adapter installed
3561 * in the system.
3562 */
3563static int __init velocity_init_module(void)
3564{
3565 int ret;
3566
3567 velocity_register_notifier();
3568 ret = pci_register_driver(&velocity_driver);
3569 if (ret < 0)
3570 velocity_unregister_notifier();
3571 return ret;
3572}
3573
3574/**
3575 * velocity_cleanup - module unload
3576 *
3577 * When the velocity hardware is unloaded this function is called.
3578 * It will clean up the notifiers and the unregister the PCI
3579 * driver interface for this hardware. This in turn cleans up
3580 * all discovered interfaces before returning from the function
3581 */
3582static void __exit velocity_cleanup_module(void)
3583{
3584 velocity_unregister_notifier();
3585 pci_unregister_driver(&velocity_driver);
3586}
3587
3588module_init(velocity_init_module);
3589module_exit(velocity_cleanup_module);