forcedeth.c

Go to the documentation of this file.
00001 /**************************************************************************
00002 *    forcedeth.c -- Etherboot device driver for the NVIDIA nForce 
00003 *                       media access controllers.
00004 *
00005 * Note: This driver is based on the Linux driver that was based on
00006 *      a cleanroom reimplementation which was based on reverse
00007 *      engineered documentation written by Carl-Daniel Hailfinger
00008 *      and Andrew de Quincey. It's neither supported nor endorsed
00009 *      by NVIDIA Corp. Use at your own risk.
00010 *
00011 *    Written 2004 by Timothy Legge <tlegge@rogers.com>
00012 *
00013 *    This program is free software; you can redistribute it and/or modify
00014 *    it under the terms of the GNU General Public License as published by
00015 *    the Free Software Foundation; either version 2 of the License, or
00016 *    (at your option) any later version.
00017 *
00018 *    This program is distributed in the hope that it will be useful,
00019 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 *    GNU General Public License for more details.
00022 *
00023 *    You should have received a copy of the GNU General Public License
00024 *    along with this program; if not, write to the Free Software
00025 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00026 *
00027 *    Portions of this code based on:
00028 *               forcedeth: Ethernet driver for NVIDIA nForce media access controllers:
00029 *
00030 *       (C) 2003 Manfred Spraul
00031 *               See Linux Driver for full information
00032 *       
00033 *       Linux Driver Version 0.30, 25 Sep 2004
00034 *       Linux Kernel 2.6.10
00035 * 
00036 * 
00037 *    REVISION HISTORY:
00038 *    ================
00039 *    v1.0       01-31-2004      timlegge        Initial port of Linux driver
00040 *    v1.1       02-03-2004      timlegge        Large Clean up, first release 
00041 *    v1.2       05-14-2005      timlegge        Add Linux 0.22 to .030 features
00042 *
00043 *    Indent Options: indent -kr -i8
00044 ***************************************************************************/
00045 
00046 FILE_LICENCE ( GPL2_OR_LATER );
00047 
00048 /* to get some global routines like printf */
00049 #include "etherboot.h"
00050 /* to get the interface to the body of the program */
00051 #include "nic.h"
00052 /* to get the PCI support functions, if this is a PCI NIC */
00053 #include <gpxe/pci.h>
00054 /* Include timer support functions */
00055 #include <gpxe/ethernet.h>
00056 #include "mii.h"
00057 
00058 #define drv_version "v1.2"
00059 #define drv_date "05-14-2005"
00060 
00061 //#define TFTM_DEBUG
00062 #ifdef TFTM_DEBUG
00063 #define dprintf(x) printf x
00064 #else
00065 #define dprintf(x)
00066 #endif
00067 
00068 #define ETH_DATA_LEN   1500
00069 
00070 /* Condensed operations for readability. */
00071 #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
00072 #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
00073 
00074 static unsigned long BASE;
00075 /* NIC specific static variables go here */
00076 #define PCI_DEVICE_ID_NVIDIA_NVENET_1           0x01c3
00077 #define PCI_DEVICE_ID_NVIDIA_NVENET_2           0x0066
00078 #define PCI_DEVICE_ID_NVIDIA_NVENET_4           0x0086
00079 #define PCI_DEVICE_ID_NVIDIA_NVENET_5           0x008c
00080 #define PCI_DEVICE_ID_NVIDIA_NVENET_3           0x00d6
00081 #define PCI_DEVICE_ID_NVIDIA_NVENET_7           0x00df
00082 #define PCI_DEVICE_ID_NVIDIA_NVENET_6           0x00e6
00083 #define PCI_DEVICE_ID_NVIDIA_NVENET_8           0x0056
00084 #define PCI_DEVICE_ID_NVIDIA_NVENET_9           0x0057
00085 #define PCI_DEVICE_ID_NVIDIA_NVENET_10          0x0037
00086 #define PCI_DEVICE_ID_NVIDIA_NVENET_11          0x0038
00087 #define PCI_DEVICE_ID_NVIDIA_NVENET_15          0x0373
00088 
00089 
00090 /*
00091  * Hardware access:
00092  */
00093 
00094 #define DEV_NEED_LASTPACKET1    0x0001  /* set LASTPACKET1 in tx flags */
00095 #define DEV_IRQMASK_1           0x0002  /* use NVREG_IRQMASK_WANTED_1 for irq mask */
00096 #define DEV_IRQMASK_2           0x0004  /* use NVREG_IRQMASK_WANTED_2 for irq mask */
00097 #define DEV_NEED_TIMERIRQ       0x0008  /* set the timer irq flag in the irq mask */
00098 #define DEV_NEED_LINKTIMER      0x0010  /* poll link settings. Relies on the timer irq */
00099 
00100 enum {
00101         NvRegIrqStatus = 0x000,
00102 #define NVREG_IRQSTAT_MIIEVENT  0040
00103 #define NVREG_IRQSTAT_MASK              0x1ff
00104         NvRegIrqMask = 0x004,
00105 #define NVREG_IRQ_RX_ERROR              0x0001
00106 #define NVREG_IRQ_RX                    0x0002
00107 #define NVREG_IRQ_RX_NOBUF              0x0004
00108 #define NVREG_IRQ_TX_ERR                0x0008
00109 #define NVREG_IRQ_TX2                   0x0010
00110 #define NVREG_IRQ_TIMER                 0x0020
00111 #define NVREG_IRQ_LINK                  0x0040
00112 #define NVREG_IRQ_TX1                   0x0100
00113 #define NVREG_IRQMASK_WANTED_1          0x005f
00114 #define NVREG_IRQMASK_WANTED_2          0x0147
00115 #define NVREG_IRQ_UNKNOWN               (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1))
00116 
00117         NvRegUnknownSetupReg6 = 0x008,
00118 #define NVREG_UNKSETUP6_VAL             3
00119 
00120 /*
00121  * NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
00122  * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
00123  */
00124         NvRegPollingInterval = 0x00c,
00125 #define NVREG_POLL_DEFAULT      970
00126         NvRegMisc1 = 0x080,
00127 #define NVREG_MISC1_HD          0x02
00128 #define NVREG_MISC1_FORCE       0x3b0f3c
00129 
00130         NvRegTransmitterControl = 0x084,
00131 #define NVREG_XMITCTL_START     0x01
00132         NvRegTransmitterStatus = 0x088,
00133 #define NVREG_XMITSTAT_BUSY     0x01
00134 
00135         NvRegPacketFilterFlags = 0x8c,
00136 #define NVREG_PFF_ALWAYS        0x7F0008
00137 #define NVREG_PFF_PROMISC       0x80
00138 #define NVREG_PFF_MYADDR        0x20
00139 
00140         NvRegOffloadConfig = 0x90,
00141 #define NVREG_OFFLOAD_HOMEPHY   0x601
00142 #define NVREG_OFFLOAD_NORMAL    RX_NIC_BUFSIZE
00143         NvRegReceiverControl = 0x094,
00144 #define NVREG_RCVCTL_START      0x01
00145         NvRegReceiverStatus = 0x98,
00146 #define NVREG_RCVSTAT_BUSY      0x01
00147 
00148         NvRegRandomSeed = 0x9c,
00149 #define NVREG_RNDSEED_MASK      0x00ff
00150 #define NVREG_RNDSEED_FORCE     0x7f00
00151 #define NVREG_RNDSEED_FORCE2    0x2d00
00152 #define NVREG_RNDSEED_FORCE3    0x7400
00153 
00154         NvRegUnknownSetupReg1 = 0xA0,
00155 #define NVREG_UNKSETUP1_VAL     0x16070f
00156         NvRegUnknownSetupReg2 = 0xA4,
00157 #define NVREG_UNKSETUP2_VAL     0x16
00158         NvRegMacAddrA = 0xA8,
00159         NvRegMacAddrB = 0xAC,
00160         NvRegMulticastAddrA = 0xB0,
00161 #define NVREG_MCASTADDRA_FORCE  0x01
00162         NvRegMulticastAddrB = 0xB4,
00163         NvRegMulticastMaskA = 0xB8,
00164         NvRegMulticastMaskB = 0xBC,
00165 
00166         NvRegPhyInterface = 0xC0,
00167 #define PHY_RGMII               0x10000000
00168 
00169         NvRegTxRingPhysAddr = 0x100,
00170         NvRegRxRingPhysAddr = 0x104,
00171         NvRegRingSizes = 0x108,
00172 #define NVREG_RINGSZ_TXSHIFT 0
00173 #define NVREG_RINGSZ_RXSHIFT 16
00174         NvRegUnknownTransmitterReg = 0x10c,
00175         NvRegLinkSpeed = 0x110,
00176 #define NVREG_LINKSPEED_FORCE 0x10000
00177 #define NVREG_LINKSPEED_10      1000
00178 #define NVREG_LINKSPEED_100     100
00179 #define NVREG_LINKSPEED_1000    50
00180         NvRegUnknownSetupReg5 = 0x130,
00181 #define NVREG_UNKSETUP5_BIT31   (1<<31)
00182         NvRegUnknownSetupReg3 = 0x13c,
00183 #define NVREG_UNKSETUP3_VAL1    0x200010
00184         NvRegTxRxControl = 0x144,
00185 #define NVREG_TXRXCTL_KICK      0x0001
00186 #define NVREG_TXRXCTL_BIT1      0x0002
00187 #define NVREG_TXRXCTL_BIT2      0x0004
00188 #define NVREG_TXRXCTL_IDLE      0x0008
00189 #define NVREG_TXRXCTL_RESET     0x0010
00190 #define NVREG_TXRXCTL_RXCHECK   0x0400
00191         NvRegMIIStatus = 0x180,
00192 #define NVREG_MIISTAT_ERROR             0x0001
00193 #define NVREG_MIISTAT_LINKCHANGE        0x0008
00194 #define NVREG_MIISTAT_MASK              0x000f
00195 #define NVREG_MIISTAT_MASK2             0x000f
00196         NvRegUnknownSetupReg4 = 0x184,
00197 #define NVREG_UNKSETUP4_VAL     8
00198 
00199         NvRegAdapterControl = 0x188,
00200 #define NVREG_ADAPTCTL_START    0x02
00201 #define NVREG_ADAPTCTL_LINKUP   0x04
00202 #define NVREG_ADAPTCTL_PHYVALID 0x40000
00203 #define NVREG_ADAPTCTL_RUNNING  0x100000
00204 #define NVREG_ADAPTCTL_PHYSHIFT 24
00205         NvRegMIISpeed = 0x18c,
00206 #define NVREG_MIISPEED_BIT8     (1<<8)
00207 #define NVREG_MIIDELAY  5
00208         NvRegMIIControl = 0x190,
00209 #define NVREG_MIICTL_INUSE      0x08000
00210 #define NVREG_MIICTL_WRITE      0x00400
00211 #define NVREG_MIICTL_ADDRSHIFT  5
00212         NvRegMIIData = 0x194,
00213         NvRegWakeUpFlags = 0x200,
00214 #define NVREG_WAKEUPFLAGS_VAL           0x7770
00215 #define NVREG_WAKEUPFLAGS_BUSYSHIFT     24
00216 #define NVREG_WAKEUPFLAGS_ENABLESHIFT   16
00217 #define NVREG_WAKEUPFLAGS_D3SHIFT       12
00218 #define NVREG_WAKEUPFLAGS_D2SHIFT       8
00219 #define NVREG_WAKEUPFLAGS_D1SHIFT       4
00220 #define NVREG_WAKEUPFLAGS_D0SHIFT       0
00221 #define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT         0x01
00222 #define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT      0x02
00223 #define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE     0x04
00224 #define NVREG_WAKEUPFLAGS_ENABLE        0x1111
00225 
00226         NvRegPatternCRC = 0x204,
00227         NvRegPatternMask = 0x208,
00228         NvRegPowerCap = 0x268,
00229 #define NVREG_POWERCAP_D3SUPP   (1<<30)
00230 #define NVREG_POWERCAP_D2SUPP   (1<<26)
00231 #define NVREG_POWERCAP_D1SUPP   (1<<25)
00232         NvRegPowerState = 0x26c,
00233 #define NVREG_POWERSTATE_POWEREDUP      0x8000
00234 #define NVREG_POWERSTATE_VALID          0x0100
00235 #define NVREG_POWERSTATE_MASK           0x0003
00236 #define NVREG_POWERSTATE_D0             0x0000
00237 #define NVREG_POWERSTATE_D1             0x0001
00238 #define NVREG_POWERSTATE_D2             0x0002
00239 #define NVREG_POWERSTATE_D3             0x0003
00240 };
00241 
00242 #define FLAG_MASK_V1 0xffff0000
00243 #define FLAG_MASK_V2 0xffffc000
00244 #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1)
00245 #define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2)
00246 
00247 #define NV_TX_LASTPACKET        (1<<16)
00248 #define NV_TX_RETRYERROR        (1<<19)
00249 #define NV_TX_LASTPACKET1       (1<<24)
00250 #define NV_TX_DEFERRED          (1<<26)
00251 #define NV_TX_CARRIERLOST       (1<<27)
00252 #define NV_TX_LATECOLLISION     (1<<28)
00253 #define NV_TX_UNDERFLOW         (1<<29)
00254 #define NV_TX_ERROR             (1<<30)
00255 #define NV_TX_VALID             (1<<31)
00256 
00257 #define NV_TX2_LASTPACKET       (1<<29)
00258 #define NV_TX2_RETRYERROR       (1<<18)
00259 #define NV_TX2_LASTPACKET1      (1<<23)
00260 #define NV_TX2_DEFERRED         (1<<25)
00261 #define NV_TX2_CARRIERLOST      (1<<26)
00262 #define NV_TX2_LATECOLLISION    (1<<27)
00263 #define NV_TX2_UNDERFLOW        (1<<28)
00264 /* error and valid are the same for both */
00265 #define NV_TX2_ERROR            (1<<30)
00266 #define NV_TX2_VALID            (1<<31)
00267 
00268 #define NV_RX_DESCRIPTORVALID   (1<<16)
00269 #define NV_RX_MISSEDFRAME       (1<<17)
00270 #define NV_RX_SUBSTRACT1        (1<<18)
00271 #define NV_RX_ERROR1            (1<<23)
00272 #define NV_RX_ERROR2            (1<<24)
00273 #define NV_RX_ERROR3            (1<<25)
00274 #define NV_RX_ERROR4            (1<<26)
00275 #define NV_RX_CRCERR            (1<<27)
00276 #define NV_RX_OVERFLOW          (1<<28)
00277 #define NV_RX_FRAMINGERR        (1<<29)
00278 #define NV_RX_ERROR             (1<<30)
00279 #define NV_RX_AVAIL             (1<<31)
00280 
00281 #define NV_RX2_CHECKSUMMASK     (0x1C000000)
00282 #define NV_RX2_CHECKSUMOK1      (0x10000000)
00283 #define NV_RX2_CHECKSUMOK2      (0x14000000)
00284 #define NV_RX2_CHECKSUMOK3      (0x18000000)
00285 #define NV_RX2_DESCRIPTORVALID  (1<<29)
00286 #define NV_RX2_SUBSTRACT1       (1<<25)
00287 #define NV_RX2_ERROR1           (1<<18)
00288 #define NV_RX2_ERROR2           (1<<19)
00289 #define NV_RX2_ERROR3           (1<<20)
00290 #define NV_RX2_ERROR4           (1<<21)
00291 #define NV_RX2_CRCERR           (1<<22)
00292 #define NV_RX2_OVERFLOW         (1<<23)
00293 #define NV_RX2_FRAMINGERR       (1<<24)
00294 /* error and avail are the same for both */
00295 #define NV_RX2_ERROR            (1<<30)
00296 #define NV_RX2_AVAIL            (1<<31)
00297 
00298 /* Miscelaneous hardware related defines: */
00299 #define NV_PCI_REGSZ            0x270
00300 
00301 /* various timeout delays: all in usec */
00302 #define NV_TXRX_RESET_DELAY     4
00303 #define NV_TXSTOP_DELAY1        10
00304 #define NV_TXSTOP_DELAY1MAX     500000
00305 #define NV_TXSTOP_DELAY2        100
00306 #define NV_RXSTOP_DELAY1        10
00307 #define NV_RXSTOP_DELAY1MAX     500000
00308 #define NV_RXSTOP_DELAY2        100
00309 #define NV_SETUP5_DELAY         5
00310 #define NV_SETUP5_DELAYMAX      50000
00311 #define NV_POWERUP_DELAY        5
00312 #define NV_POWERUP_DELAYMAX     5000
00313 #define NV_MIIBUSY_DELAY        50
00314 #define NV_MIIPHY_DELAY 10
00315 #define NV_MIIPHY_DELAYMAX      10000
00316 
00317 #define NV_WAKEUPPATTERNS       5
00318 #define NV_WAKEUPMASKENTRIES    4
00319 
00320 /* General driver defaults */
00321 #define NV_WATCHDOG_TIMEO       (5*HZ)
00322 
00323 #define RX_RING         4
00324 #define TX_RING         2
00325 
00326 /* 
00327  * If your nic mysteriously hangs then try to reduce the limits
00328  * to 1/0: It might be required to set NV_TX_LASTPACKET in the
00329  * last valid ring entry. But this would be impossible to
00330  * implement - probably a disassembly error.
00331  */
00332 #define TX_LIMIT_STOP   63
00333 #define TX_LIMIT_START  62
00334 
00335 /* rx/tx mac addr + type + vlan + align + slack*/
00336 #define RX_NIC_BUFSIZE          (ETH_DATA_LEN + 64)
00337 /* even more slack */
00338 #define RX_ALLOC_BUFSIZE        (ETH_DATA_LEN + 128)
00339 
00340 #define OOM_REFILL      (1+HZ/20)
00341 #define POLL_WAIT       (1+HZ/100)
00342 #define LINK_TIMEOUT    (3*HZ)
00343 
00344 /* 
00345  * desc_ver values:
00346  * This field has two purposes:
00347  * - Newer nics uses a different ring layout. The layout is selected by
00348  *   comparing np->desc_ver with DESC_VER_xy.
00349  * - It contains bits that are forced on when writing to NvRegTxRxControl.
00350  */
00351 #define DESC_VER_1      0x0
00352 #define DESC_VER_2      (0x02100|NVREG_TXRXCTL_RXCHECK)
00353 
00354 /* PHY defines */
00355 #define PHY_OUI_MARVELL 0x5043
00356 #define PHY_OUI_CICADA  0x03f1
00357 #define PHYID1_OUI_MASK 0x03ff
00358 #define PHYID1_OUI_SHFT 6
00359 #define PHYID2_OUI_MASK 0xfc00
00360 #define PHYID2_OUI_SHFT 10
00361 #define PHY_INIT1       0x0f000
00362 #define PHY_INIT2       0x0e00
00363 #define PHY_INIT3       0x01000
00364 #define PHY_INIT4       0x0200
00365 #define PHY_INIT5       0x0004
00366 #define PHY_INIT6       0x02000
00367 #define PHY_GIGABIT     0x0100
00368 
00369 #define PHY_TIMEOUT     0x1
00370 #define PHY_ERROR       0x2
00371 
00372 #define PHY_100 0x1
00373 #define PHY_1000        0x2
00374 #define PHY_HALF        0x100
00375 
00376 
00377 /* Bit to know if MAC addr is stored in correct order */
00378 #define MAC_ADDR_CORRECT        0x01
00379 
00380 /* Big endian: should work, but is untested */
00381 struct ring_desc {
00382         u32 PacketBuffer;
00383         u32 FlagLen;
00384 };
00385 
00386 
00387 /* Define the TX and RX Descriptor and Buffers */
00388 struct {
00389         struct ring_desc tx_ring[TX_RING];
00390         unsigned char txb[TX_RING * RX_NIC_BUFSIZE];
00391         struct ring_desc rx_ring[RX_RING];
00392         unsigned char rxb[RX_RING * RX_NIC_BUFSIZE];
00393 } forcedeth_bufs __shared;
00394 #define tx_ring forcedeth_bufs.tx_ring
00395 #define rx_ring forcedeth_bufs.rx_ring
00396 #define txb forcedeth_bufs.txb
00397 #define rxb forcedeth_bufs.rxb
00398 
00399 /* Private Storage for the NIC */
00400 static struct forcedeth_private {
00401         /* General data:
00402          * Locking: spin_lock(&np->lock); */
00403         int in_shutdown;
00404         u32 linkspeed;
00405         int duplex;
00406         int phyaddr;
00407         int wolenabled;
00408         unsigned int phy_oui;
00409         u16 gigabit;
00410 
00411         /* General data: RO fields */
00412         u8 *ring_addr;
00413         u32 orig_mac[2];
00414         u32 irqmask;
00415         u32 desc_ver;
00416         /* rx specific fields.
00417          * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
00418          */
00419         unsigned int cur_rx, refill_rx;
00420 
00421         /*
00422          * tx specific fields.
00423          */
00424         unsigned int next_tx, nic_tx;
00425         u32 tx_flags;
00426 } npx;
00427 
00428 static struct forcedeth_private *np;
00429 
00430 static inline void pci_push(u8 * base)
00431 {
00432         /* force out pending posted writes */
00433         readl(base);
00434 }
00435 
00436 static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v)
00437 {
00438         return le32_to_cpu(prd->FlagLen)
00439             & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2);
00440 }
00441 
00442 static int reg_delay(int offset, u32 mask,
00443                      u32 target, int delay, int delaymax, const char *msg)
00444 {
00445         u8 *base = (u8 *) BASE;
00446 
00447         pci_push(base);
00448         do {
00449                 udelay(delay);
00450                 delaymax -= delay;
00451                 if (delaymax < 0) {
00452                         if (msg)
00453                                 printf("%s", msg);
00454                         return 1;
00455                 }
00456         } while ((readl(base + offset) & mask) != target);
00457         return 0;
00458 }
00459 
00460 #define MII_READ        (-1)
00461 
00462 /* mii_rw: read/write a register on the PHY.
00463  *
00464  * Caller must guarantee serialization
00465  */
00466 static int mii_rw(struct nic *nic __unused, int addr, int miireg,
00467                   int value)
00468 {
00469         u8 *base = (u8 *) BASE;
00470         u32 reg;
00471         int retval;
00472 
00473         writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
00474 
00475         reg = readl(base + NvRegMIIControl);
00476         if (reg & NVREG_MIICTL_INUSE) {
00477                 writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl);
00478                 udelay(NV_MIIBUSY_DELAY);
00479         }
00480 
00481         reg =
00482             (addr << NVREG_MIICTL_ADDRSHIFT) | miireg;
00483         if (value != MII_READ) {
00484                 writel(value, base + NvRegMIIData);
00485                 reg |= NVREG_MIICTL_WRITE;
00486         }
00487         writel(reg, base + NvRegMIIControl);
00488 
00489         if (reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0,
00490                       NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) {
00491                 dprintf(("mii_rw of reg %d at PHY %d timed out.\n",
00492                          miireg, addr));
00493                 retval = -1;
00494         } else if (value != MII_READ) {
00495                 /* it was a write operation - fewer failures are detectable */
00496                 dprintf(("mii_rw wrote 0x%x to reg %d at PHY %d\n",
00497                          value, miireg, addr));
00498                 retval = 0;
00499         } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) {
00500                 dprintf(("mii_rw of reg %d at PHY %d failed.\n",
00501                          miireg, addr));
00502                 retval = -1;
00503         } else {
00504                 retval = readl(base + NvRegMIIData);
00505                 dprintf(("mii_rw read from reg %d at PHY %d: 0x%x.\n",
00506                          miireg, addr, retval));
00507         }
00508         return retval;
00509 }
00510 
00511 static int phy_reset(struct nic *nic)
00512 {
00513 
00514         u32 miicontrol;
00515         unsigned int tries = 0;
00516 
00517         miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
00518         miicontrol |= BMCR_RESET;
00519         if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) {
00520                 return -1;
00521         }
00522 
00523         /* wait for 500ms */
00524         mdelay(500);
00525 
00526         /* must wait till reset is deasserted */
00527         while (miicontrol & BMCR_RESET) {
00528                 mdelay(10);
00529                 miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
00530                 /* FIXME: 100 tries seem excessive */
00531                 if (tries++ > 100)
00532                         return -1;
00533         }
00534         return 0;
00535 }
00536 
00537 static int phy_init(struct nic *nic)
00538 {
00539         u8 *base = (u8 *) BASE;
00540         u32 phyinterface, phy_reserved, mii_status, mii_control,
00541             mii_control_1000, reg;
00542 
00543         /* set advertise register */
00544         reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
00545         reg |=
00546             (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
00547              ADVERTISE_100FULL | 0x800 | 0x400);
00548         if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) {
00549                 printf("phy write to advertise failed.\n");
00550                 return PHY_ERROR;
00551         }
00552 
00553         /* get phy interface type */
00554         phyinterface = readl(base + NvRegPhyInterface);
00555 
00556         /* see if gigabit phy */
00557         mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
00558 
00559         if (mii_status & PHY_GIGABIT) {
00560                 np->gigabit = PHY_GIGABIT;
00561                 mii_control_1000 =
00562                     mii_rw(nic, np->phyaddr, MII_CTRL1000, MII_READ);
00563                 mii_control_1000 &= ~ADVERTISE_1000HALF;
00564                 if (phyinterface & PHY_RGMII)
00565                         mii_control_1000 |= ADVERTISE_1000FULL;
00566                 else
00567                         mii_control_1000 &= ~ADVERTISE_1000FULL;
00568 
00569                 if (mii_rw
00570                     (nic, np->phyaddr, MII_CTRL1000, mii_control_1000)) {
00571                         printf("phy init failed.\n");
00572                         return PHY_ERROR;
00573                 }
00574         } else
00575                 np->gigabit = 0;
00576 
00577         /* reset the phy */
00578         if (phy_reset(nic)) {
00579                 printf("phy reset failed\n");
00580                 return PHY_ERROR;
00581         }
00582 
00583         /* phy vendor specific configuration */
00584         if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) {
00585                 phy_reserved =
00586                     mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ);
00587                 phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
00588                 phy_reserved |= (PHY_INIT3 | PHY_INIT4);
00589                 if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) {
00590                         printf("phy init failed.\n");
00591                         return PHY_ERROR;
00592                 }
00593                 phy_reserved =
00594                     mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ);
00595                 phy_reserved |= PHY_INIT5;
00596                 if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) {
00597                         printf("phy init failed.\n");
00598                         return PHY_ERROR;
00599                 }
00600         }
00601         if (np->phy_oui == PHY_OUI_CICADA) {
00602                 phy_reserved =
00603                     mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ);
00604                 phy_reserved |= PHY_INIT6;
00605                 if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) {
00606                         printf("phy init failed.\n");
00607                         return PHY_ERROR;
00608                 }
00609         }
00610 
00611         /* restart auto negotiation */
00612         mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
00613         mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
00614         if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) {
00615                 return PHY_ERROR;
00616         }
00617 
00618         return 0;
00619 }
00620 
00621 static void start_rx(struct nic *nic __unused)
00622 {
00623         u8 *base = (u8 *) BASE;
00624 
00625         dprintf(("start_rx\n"));
00626         /* Already running? Stop it. */
00627         if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
00628                 writel(0, base + NvRegReceiverControl);
00629                 pci_push(base);
00630         }
00631         writel(np->linkspeed, base + NvRegLinkSpeed);
00632         pci_push(base);
00633         writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
00634         pci_push(base);
00635 }
00636 
00637 static void stop_rx(void)
00638 {
00639         u8 *base = (u8 *) BASE;
00640 
00641         dprintf(("stop_rx\n"));
00642         writel(0, base + NvRegReceiverControl);
00643         reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
00644                   NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
00645                   "stop_rx: ReceiverStatus remained busy");
00646 
00647         udelay(NV_RXSTOP_DELAY2);
00648         writel(0, base + NvRegLinkSpeed);
00649 }
00650 
00651 static void start_tx(struct nic *nic __unused)
00652 {
00653         u8 *base = (u8 *) BASE;
00654 
00655         dprintf(("start_tx\n"));
00656         writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl);
00657         pci_push(base);
00658 }
00659 
00660 static void stop_tx(void)
00661 {
00662         u8 *base = (u8 *) BASE;
00663 
00664         dprintf(("stop_tx\n"));
00665         writel(0, base + NvRegTransmitterControl);
00666         reg_delay(NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
00667                   NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
00668                   "stop_tx: TransmitterStatus remained busy");
00669 
00670         udelay(NV_TXSTOP_DELAY2);
00671         writel(0, base + NvRegUnknownTransmitterReg);
00672 }
00673 
00674 
00675 static void txrx_reset(struct nic *nic __unused)
00676 {
00677         u8 *base = (u8 *) BASE;
00678 
00679         dprintf(("txrx_reset\n"));
00680         writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver,
00681                base + NvRegTxRxControl);
00682 
00683         pci_push(base);
00684         udelay(NV_TXRX_RESET_DELAY);
00685         writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
00686         pci_push(base);
00687 }
00688 
00689 /*
00690  * alloc_rx: fill rx ring entries.
00691  * Return 1 if the allocations for the skbs failed and the
00692  * rx engine is without Available descriptors
00693  */
00694 static int alloc_rx(struct nic *nic __unused)
00695 {
00696         unsigned int refill_rx = np->refill_rx;
00697         int i;
00698         //while (np->cur_rx != refill_rx) {
00699         for (i = 0; i < RX_RING; i++) {
00700                 //int nr = refill_rx % RX_RING;
00701                 rx_ring[i].PacketBuffer =
00702                     virt_to_le32desc(&rxb[i * RX_NIC_BUFSIZE]);
00703                 wmb();
00704                 rx_ring[i].FlagLen =
00705                     cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL);
00706                 /*      printf("alloc_rx: Packet  %d marked as Available\n",
00707                    refill_rx); */
00708                 refill_rx++;
00709         }
00710         np->refill_rx = refill_rx;
00711         if (np->cur_rx - refill_rx == RX_RING)
00712                 return 1;
00713         return 0;
00714 }
00715 
00716 static int update_linkspeed(struct nic *nic)
00717 {
00718         int adv, lpa;
00719         u32 newls;
00720         int newdup = np->duplex;
00721         u32 mii_status;
00722         int retval = 0; 
00723         u32 control_1000, status_1000, phyreg;
00724         u8 *base = (u8 *) BASE;
00725         int i;
00726 
00727         /* BMSR_LSTATUS is latched, read it twice:
00728          * we want the current value.
00729          */
00730         mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
00731         mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
00732 
00733 #if 1
00734         //yhlu
00735         for(i=0;i<30;i++) {
00736                 mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
00737                 if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break;
00738                 mdelay(100);
00739         }
00740 #endif
00741 
00742         if (!(mii_status & BMSR_LSTATUS)) {
00743                 printf
00744                     ("no link detected by phy - falling back to 10HD.\n");
00745                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00746                 newdup = 0;
00747                 retval = 0;
00748                 goto set_speed;
00749         }
00750 
00751         /* check auto negotiation is complete */
00752         if (!(mii_status & BMSR_ANEGCOMPLETE)) {
00753                 /* still in autonegotiation - configure nic for 10 MBit HD and wait. */
00754                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00755                 newdup = 0;
00756                 retval = 0;
00757                 printf("autoneg not completed - falling back to 10HD.\n");
00758                 goto set_speed;
00759         }
00760 
00761         retval = 1;
00762         if (np->gigabit == PHY_GIGABIT) {
00763                 control_1000 =
00764                     mii_rw(nic, np->phyaddr, MII_CTRL1000, MII_READ);
00765                 status_1000 =
00766                     mii_rw(nic, np->phyaddr, MII_STAT1000, MII_READ);
00767 
00768                 if ((control_1000 & ADVERTISE_1000FULL) &&
00769                     (status_1000 & LPA_1000FULL)) {
00770                         printf
00771                             ("update_linkspeed: GBit ethernet detected.\n");
00772                         newls =
00773                             NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000;
00774                         newdup = 1;
00775                         goto set_speed;
00776                 }
00777         }
00778 
00779         adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
00780         lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ);
00781         dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n",
00782                  adv, lpa));
00783 
00784         /* FIXME: handle parallel detection properly, handle gigabit ethernet */
00785         lpa = lpa & adv;
00786         if (lpa & LPA_100FULL) {
00787                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100;
00788                 newdup = 1;
00789         } else if (lpa & LPA_100HALF) {
00790                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100;
00791                 newdup = 0;
00792         } else if (lpa & LPA_10FULL) {
00793                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00794                 newdup = 1;
00795         } else if (lpa & LPA_10HALF) {
00796                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00797                 newdup = 0;
00798         } else {
00799                 printf("bad ability %hX - falling back to 10HD.\n", lpa);
00800                 newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00801                 newdup = 0;
00802         }
00803 
00804       set_speed:
00805         if (np->duplex == newdup && np->linkspeed == newls)
00806                 return retval;
00807 
00808         dprintf(("changing link setting from %d/%s to %d/%s.\n",
00809                np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex"));
00810 
00811         np->duplex = newdup;
00812         np->linkspeed = newls;
00813 
00814         if (np->gigabit == PHY_GIGABIT) {
00815                 phyreg = readl(base + NvRegRandomSeed);
00816                 phyreg &= ~(0x3FF00);
00817                 if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10)
00818                         phyreg |= NVREG_RNDSEED_FORCE3;
00819                 else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
00820                         phyreg |= NVREG_RNDSEED_FORCE2;
00821                 else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
00822                         phyreg |= NVREG_RNDSEED_FORCE;
00823                 writel(phyreg, base + NvRegRandomSeed);
00824         }
00825 
00826         phyreg = readl(base + NvRegPhyInterface);
00827         phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000);
00828         if (np->duplex == 0)
00829                 phyreg |= PHY_HALF;
00830         if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
00831                 phyreg |= PHY_100;
00832         else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
00833                 phyreg |= PHY_1000;
00834         writel(phyreg, base + NvRegPhyInterface);
00835 
00836         writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD),
00837                base + NvRegMisc1);
00838         pci_push(base);
00839         writel(np->linkspeed, base + NvRegLinkSpeed);
00840         pci_push(base);
00841 
00842         return retval;
00843 }
00844 
00845 #if 0 /* Not used */
00846 static void nv_linkchange(struct nic *nic)
00847 {
00848         if (update_linkspeed(nic)) {
00849 //                if (netif_carrier_ok(nic)) {
00850                 stop_rx();
00851 //=                } else {
00852                 //                      netif_carrier_on(dev);
00853                 //                    printk(KERN_INFO "%s: link up.\n", dev->name);
00854                 //          }
00855                 start_rx(nic);
00856         } else {
00857                 //        if (netif_carrier_ok(dev)) {
00858                 //              netif_carrier_off(dev);
00859                 //            printk(KERN_INFO "%s: link down.\n", dev->name);
00860                 stop_rx();
00861                 //  }
00862         }
00863 }
00864 #endif
00865 
00866 static int init_ring(struct nic *nic)
00867 {
00868         int i;
00869 
00870         np->next_tx = np->nic_tx = 0;
00871         for (i = 0; i < TX_RING; i++)
00872                 tx_ring[i].FlagLen = 0;
00873 
00874         np->cur_rx = 0;
00875         np->refill_rx = 0;
00876         for (i = 0; i < RX_RING; i++)
00877                 rx_ring[i].FlagLen = 0;
00878         return alloc_rx(nic);
00879 }
00880 
00881 static void set_multicast(struct nic *nic)
00882 {
00883 
00884         u8 *base = (u8 *) BASE;
00885         u32 addr[2];
00886         u32 mask[2];
00887         u32 pff;
00888         u32 alwaysOff[2];
00889         u32 alwaysOn[2];
00890 
00891         memset(addr, 0, sizeof(addr));
00892         memset(mask, 0, sizeof(mask));
00893 
00894         pff = NVREG_PFF_MYADDR;
00895 
00896         alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
00897 
00898         addr[0] = alwaysOn[0];
00899         addr[1] = alwaysOn[1];
00900         mask[0] = alwaysOn[0] | alwaysOff[0];
00901         mask[1] = alwaysOn[1] | alwaysOff[1];
00902 
00903         addr[0] |= NVREG_MCASTADDRA_FORCE;
00904         pff |= NVREG_PFF_ALWAYS;
00905         stop_rx();
00906         writel(addr[0], base + NvRegMulticastAddrA);
00907         writel(addr[1], base + NvRegMulticastAddrB);
00908         writel(mask[0], base + NvRegMulticastMaskA);
00909         writel(mask[1], base + NvRegMulticastMaskB);
00910         writel(pff, base + NvRegPacketFilterFlags);
00911         start_rx(nic);
00912 }
00913 
00914 /**************************************************************************
00915 RESET - Reset the NIC to prepare for use
00916 ***************************************************************************/
00917 static int forcedeth_reset(struct nic *nic)
00918 {
00919         u8 *base = (u8 *) BASE;
00920         int ret, oom, i;
00921         ret = 0;
00922         dprintf(("forcedeth: open\n"));
00923 
00924         /* 1) erase previous misconfiguration */
00925         /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
00926         writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
00927         writel(0, base + NvRegMulticastAddrB);
00928         writel(0, base + NvRegMulticastMaskA);
00929         writel(0, base + NvRegMulticastMaskB);
00930         writel(0, base + NvRegPacketFilterFlags);
00931 
00932         writel(0, base + NvRegTransmitterControl);
00933         writel(0, base + NvRegReceiverControl);
00934 
00935         writel(0, base + NvRegAdapterControl);
00936 
00937         /* 2) initialize descriptor rings */
00938         oom = init_ring(nic);
00939 
00940         writel(0, base + NvRegLinkSpeed);
00941         writel(0, base + NvRegUnknownTransmitterReg);
00942         txrx_reset(nic);
00943         writel(0, base + NvRegUnknownSetupReg6);
00944 
00945         np->in_shutdown = 0;
00946 
00947         /* 3) set mac address */
00948         {
00949                 u32 mac[2];
00950 
00951                 mac[0] =
00952                     (nic->node_addr[0] << 0) + (nic->node_addr[1] << 8) +
00953                     (nic->node_addr[2] << 16) + (nic->node_addr[3] << 24);
00954                 mac[1] =
00955                     (nic->node_addr[4] << 0) + (nic->node_addr[5] << 8);
00956 
00957                 writel(mac[0], base + NvRegMacAddrA);
00958                 writel(mac[1], base + NvRegMacAddrB);
00959         }
00960 
00961         /* 4) give hw rings */
00962         writel((u32) virt_to_le32desc(&rx_ring[0]),
00963                base + NvRegRxRingPhysAddr);
00964         writel((u32) virt_to_le32desc(&tx_ring[0]),
00965                base + NvRegTxRingPhysAddr);
00966 
00967         writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) +
00968                ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT),
00969                base + NvRegRingSizes);
00970 
00971         /* 5) continue setup */
00972         np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
00973         np->duplex = 0;
00974         writel(np->linkspeed, base + NvRegLinkSpeed);
00975         writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
00976         writel(np->desc_ver, base + NvRegTxRxControl);
00977         pci_push(base);
00978         writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl);
00979         reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31,
00980                   NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY,
00981                   NV_SETUP5_DELAYMAX,
00982                   "open: SetupReg5, Bit 31 remained off\n");
00983 
00984         writel(0, base + NvRegUnknownSetupReg4);
00985 //       writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
00986         writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
00987 #if 0
00988         printf("%d-Mbs Link, %s-Duplex\n",
00989                np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100,
00990                np->duplex ? "Full" : "Half");
00991 #endif
00992 
00993         /* 6) continue setup */
00994         writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
00995         writel(readl(base + NvRegTransmitterStatus),
00996                base + NvRegTransmitterStatus);
00997         writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags);
00998         writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig);
00999 
01000         writel(readl(base + NvRegReceiverStatus),
01001                base + NvRegReceiverStatus);
01002 
01003         /* Get a random number */
01004         i = random();
01005         writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK),
01006                base + NvRegRandomSeed);
01007         writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
01008         writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
01009         writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
01010         writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
01011         writel((np->
01012                 phyaddr << NVREG_ADAPTCTL_PHYSHIFT) |
01013                NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING,
01014                base + NvRegAdapterControl);
01015         writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed);
01016         writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4);
01017         writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags);
01018 
01019         i = readl(base + NvRegPowerState);
01020         if ((i & NVREG_POWERSTATE_POWEREDUP) == 0)
01021                 writel(NVREG_POWERSTATE_POWEREDUP | i,
01022                        base + NvRegPowerState);
01023 
01024         pci_push(base);
01025         udelay(10);
01026         writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID,
01027                base + NvRegPowerState);
01028 
01029         writel(0, base + NvRegIrqMask);
01030         pci_push(base);
01031         writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
01032         writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
01033         pci_push(base);
01034 /*
01035         writel(np->irqmask, base + NvRegIrqMask);
01036 */
01037         writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
01038         writel(0, base + NvRegMulticastAddrB);
01039         writel(0, base + NvRegMulticastMaskA);
01040         writel(0, base + NvRegMulticastMaskB);
01041         writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR,
01042                base + NvRegPacketFilterFlags);
01043 
01044         set_multicast(nic);
01045         /* One manual link speed update: Interrupts are enabled, future link
01046          * speed changes cause interrupts and are handled by nv_link_irq().
01047          */
01048         {
01049                 u32 miistat;
01050                 miistat = readl(base + NvRegMIIStatus);
01051                 writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
01052                 dprintf(("startup: got 0x%hX.\n", miistat));
01053         }
01054         ret = update_linkspeed(nic);
01055 
01056         //start_rx(nic);
01057         start_tx(nic);
01058 
01059         if (ret) {
01060                 //Start Connection netif_carrier_on(dev);
01061         } else {
01062                 printf("no link during initialization.\n");
01063         }
01064 
01065         return ret;
01066 }
01067 
01068 /* 
01069  * extern void hex_dump(const char *data, const unsigned int len);
01070 */
01071 /**************************************************************************
01072 POLL - Wait for a frame
01073 ***************************************************************************/
01074 static int forcedeth_poll(struct nic *nic, int retrieve)
01075 {
01076         /* return true if there's an ethernet packet ready to read */
01077         /* nic->packet should contain data on return */
01078         /* nic->packetlen should contain length of data */
01079 
01080         int len;
01081         int i;
01082         u32 Flags;
01083 
01084         i = np->cur_rx % RX_RING;
01085 
01086         Flags = le32_to_cpu(rx_ring[i].FlagLen);
01087         len = nv_descr_getlength(&rx_ring[i], np->desc_ver);
01088 
01089         if (Flags & NV_RX_AVAIL)
01090                 return 0;       /* still owned by hardware, */
01091 
01092         if (np->desc_ver == DESC_VER_1) {
01093                 if (!(Flags & NV_RX_DESCRIPTORVALID))
01094                         return 0;
01095         } else {
01096                 if (!(Flags & NV_RX2_DESCRIPTORVALID))
01097                         return 0;
01098         }
01099 
01100         if (!retrieve)
01101                 return 1;
01102 
01103         /* got a valid packet - forward it to the network core */
01104         nic->packetlen = len;
01105         memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen);
01106 /*
01107  *      hex_dump(rxb + (i * RX_NIC_BUFSIZE), len);
01108 */
01109         wmb();
01110         np->cur_rx++;
01111         alloc_rx(nic);
01112         return 1;
01113 }
01114 
01115 
01116 /**************************************************************************
01117 TRANSMIT - Transmit a frame
01118 ***************************************************************************/
01119 static void forcedeth_transmit(struct nic *nic, const char *d,  /* Destination */
01120                                unsigned int t,  /* Type */
01121                                unsigned int s,  /* size */
01122                                const char *p)
01123 {                               /* Packet */
01124         /* send the packet to destination */
01125         u8 *ptxb;
01126         u16 nstype;
01127         u8 *base = (u8 *) BASE;
01128         int nr = np->next_tx % TX_RING;
01129 
01130         /* point to the current txb incase multiple tx_rings are used */
01131         ptxb = txb + (nr * RX_NIC_BUFSIZE);
01132         //np->tx_skbuff[nr] = ptxb;
01133 
01134         /* copy the packet to ring buffer */
01135         memcpy(ptxb, d, ETH_ALEN);      /* dst */
01136         memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);      /* src */
01137         nstype = htons((u16) t);        /* type */
01138         memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);        /* type */
01139         memcpy(ptxb + ETH_HLEN, p, s);
01140 
01141         s += ETH_HLEN;
01142         while (s < ETH_ZLEN)    /* pad to min length */
01143                 ptxb[s++] = '\0';
01144 
01145         tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb);
01146 
01147         wmb();
01148         tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags);
01149 
01150         writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl);
01151         pci_push(base);
01152         np->next_tx++;
01153 }
01154 
01155 /**************************************************************************
01156 DISABLE - Turn off ethernet interface
01157 ***************************************************************************/
01158 static void forcedeth_disable ( struct nic *nic __unused ) {
01159         /* put the card in its initial state */
01160         /* This function serves 3 purposes.
01161          * This disables DMA and interrupts so we don't receive
01162          *  unexpected packets or interrupts from the card after
01163          *  etherboot has finished. 
01164          * This frees resources so etherboot may use
01165          *  this driver on another interface
01166          * This allows etherboot to reinitialize the interface
01167          *  if something is something goes wrong.
01168          */
01169         u8 *base = (u8 *) BASE;
01170         np->in_shutdown = 1;
01171         stop_tx();
01172         stop_rx();
01173 
01174         /* disable interrupts on the nic or we will lock up */
01175         writel(0, base + NvRegIrqMask);
01176         pci_push(base);
01177         dprintf(("Irqmask is zero again\n"));
01178 
01179         /* specia op:o write back the misordered MAC address - otherwise
01180          * the next probe_nic would see a wrong address.
01181          */
01182         writel(np->orig_mac[0], base + NvRegMacAddrA);
01183         writel(np->orig_mac[1], base + NvRegMacAddrB);
01184 }
01185 
01186 /**************************************************************************
01187 IRQ - Enable, Disable, or Force interrupts
01188 ***************************************************************************/
01189 static void forcedeth_irq(struct nic *nic __unused,
01190                           irq_action_t action __unused)
01191 {
01192         switch (action) {
01193         case DISABLE:
01194                 break;
01195         case ENABLE:
01196                 break;
01197         case FORCE:
01198                 break;
01199         }
01200 }
01201 
01202 static struct nic_operations forcedeth_operations = {
01203         .connect        = dummy_connect,
01204         .poll           = forcedeth_poll,
01205         .transmit       = forcedeth_transmit,
01206         .irq            = forcedeth_irq,
01207 
01208 };
01209 
01210 /**************************************************************************
01211 PROBE - Look for an adapter, this routine's visible to the outside
01212 ***************************************************************************/
01213 #define IORESOURCE_MEM 0x00000200
01214 #define board_found 1
01215 #define valid_link 0
01216 static int forcedeth_probe ( struct nic *nic, struct pci_device *pci ) {
01217 
01218         unsigned long addr;
01219         int sz;
01220         u8 *base;
01221         int i;
01222         struct pci_device_id *ids = pci->driver->ids;
01223         int id_count = pci->driver->id_count;
01224         unsigned int flags = 0;
01225 
01226         if (pci->ioaddr == 0)
01227                 return 0;
01228 
01229         printf("forcedeth.c: Found %s, vendor=0x%hX, device=0x%hX\n",
01230                pci->driver_name, pci->vendor, pci->device);
01231 
01232         nic->ioaddr = pci->ioaddr;
01233         nic->irqno = 0;
01234 
01235         /* point to private storage */
01236         np = &npx;
01237 
01238         adjust_pci_device(pci);
01239 
01240         addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0);
01241         sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0);
01242 
01243         /* BASE is used throughout to address the card */
01244         BASE = (unsigned long) ioremap(addr, sz);
01245         if (!BASE)
01246                 return 0;
01247 
01248         /* handle different descriptor versions */
01249         if (pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 ||
01250             pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 ||
01251             pci->device == PCI_DEVICE_ID_NVIDIA_NVENET_3)
01252                 np->desc_ver = DESC_VER_1;
01253         else
01254                 np->desc_ver = DESC_VER_2;
01255 
01256         //rx_ring[0] = rx_ring;
01257         //tx_ring[0] = tx_ring; 
01258 
01259         /* read the mac address */
01260         base = (u8 *) BASE;
01261         np->orig_mac[0] = readl(base + NvRegMacAddrA);
01262         np->orig_mac[1] = readl(base + NvRegMacAddrB);
01263 
01264         /* lookup the flags from pci_device_id */
01265         for(i = 0; i < id_count; i++) {
01266                 if(pci->vendor == ids[i].vendor &&
01267                    pci->device == ids[i].device) {
01268                         flags = ids[i].driver_data;
01269                         break;
01270                    }
01271         }
01272 
01273         /* read MAC address */
01274         if(flags & MAC_ADDR_CORRECT) {
01275                 nic->node_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
01276                 nic->node_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
01277                 nic->node_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
01278                 nic->node_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
01279                 nic->node_addr[4] = (np->orig_mac[1] >>  0) & 0xff;
01280                 nic->node_addr[5] = (np->orig_mac[1] >>  8) & 0xff;
01281         } else {
01282                 nic->node_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
01283                 nic->node_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
01284                 nic->node_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
01285                 nic->node_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
01286                 nic->node_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
01287                 nic->node_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
01288         }
01289 #ifdef LINUX
01290         if (!is_valid_ether_addr(dev->dev_addr)) {
01291                 /*
01292                  * Bad mac address. At least one bios sets the mac address
01293                  * to 01:23:45:67:89:ab
01294                  */
01295                 printk(KERN_ERR
01296                        "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n",
01297                        pci_name(pci_dev), dev->dev_addr[0],
01298                        dev->dev_addr[1], dev->dev_addr[2],
01299                        dev->dev_addr[3], dev->dev_addr[4],
01300                        dev->dev_addr[5]);
01301                 printk(KERN_ERR
01302                        "Please complain to your hardware vendor. Switching to a random MAC.\n");
01303                 dev->dev_addr[0] = 0x00;
01304                 dev->dev_addr[1] = 0x00;
01305                 dev->dev_addr[2] = 0x6c;
01306                 get_random_bytes(&dev->dev_addr[3], 3);
01307         }
01308 #endif
01309 
01310         DBG ( "%s: MAC Address %s\n", pci->driver_name, eth_ntoa ( nic->node_addr ) );
01311 
01312         /* disable WOL */
01313         writel(0, base + NvRegWakeUpFlags);
01314         np->wolenabled = 0;
01315         
01316         if (np->desc_ver == DESC_VER_1) {
01317                 np->tx_flags = NV_TX_LASTPACKET | NV_TX_VALID;
01318         } else {
01319                 np->tx_flags = NV_TX2_LASTPACKET | NV_TX2_VALID;
01320         }
01321 
01322         switch (pci->device) {
01323         case 0x01C3:            // nforce
01324         case 0x054C:
01325                 // DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
01326                 np->irqmask = NVREG_IRQMASK_WANTED_2 | NVREG_IRQ_TIMER;
01327                 //              np->need_linktimer = 1;
01328                 //              np->link_timeout = jiffies + LINK_TIMEOUT;
01329                 break;
01330         case 0x0066:
01331                 /* Fall Through */
01332         case 0x00D6:
01333                 // DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER
01334                 np->irqmask = NVREG_IRQMASK_WANTED_2;
01335                 np->irqmask |= NVREG_IRQ_TIMER;
01336                 //              np->need_linktimer = 1;
01337                 //              np->link_timeout = jiffies + LINK_TIMEOUT;
01338                 if (np->desc_ver == DESC_VER_1)
01339                         np->tx_flags |= NV_TX_LASTPACKET1;
01340                 else
01341                         np->tx_flags |= NV_TX2_LASTPACKET1;
01342                 break;
01343         case 0x0373:
01344                 /* Fall Through */
01345         case 0x0086:
01346                 /* Fall Through */
01347         case 0x008c:
01348                 /* Fall Through */
01349         case 0x00e6:
01350                 /* Fall Through */
01351         case 0x00df:
01352                 /* Fall Through */
01353         case 0x0056:
01354                 /* Fall Through */
01355         case 0x0057:
01356                 /* Fall Through */
01357         case 0x0037:
01358                 /* Fall Through */
01359         case 0x0038:
01360                 //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ
01361                 np->irqmask = NVREG_IRQMASK_WANTED_2;
01362                 np->irqmask |= NVREG_IRQ_TIMER;
01363                 //              np->need_linktimer = 1;
01364                 //              np->link_timeout = jiffies + LINK_TIMEOUT;
01365                 if (np->desc_ver == DESC_VER_1)
01366                         np->tx_flags |= NV_TX_LASTPACKET1;
01367                 else
01368                         np->tx_flags |= NV_TX2_LASTPACKET1;
01369                 break;
01370         default:
01371                 printf
01372                         ("Your card was undefined in this driver.  Review driver_data in Linux driver and send a patch\n");
01373         }
01374         
01375         /* find a suitable phy */
01376         for (i = 1; i < 32; i++) {
01377                 int id1, id2;
01378                 id1 = mii_rw(nic, i, MII_PHYSID1, MII_READ);
01379                 if (id1 < 0 || id1 == 0xffff)
01380                         continue;
01381                 id2 = mii_rw(nic, i, MII_PHYSID2, MII_READ);
01382                 if (id2 < 0 || id2 == 0xffff)
01383                         continue;
01384                 id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
01385                 id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
01386                 dprintf
01387                         (("%s: open: Found PHY %hX:%hX at address %d.\n",
01388                           pci->driver_name, id1, id2, i));
01389                 np->phyaddr = i;
01390                 np->phy_oui = id1 | id2;
01391                 break;
01392         }
01393         if (i == 32) {
01394                 /* PHY in isolate mode? No phy attached and user wants to
01395                  * test loopback? Very odd, but can be correct.
01396                  */
01397                 printf
01398                         ("%s: open: Could not find a valid PHY.\n", pci->driver_name);
01399         }
01400         
01401         if (i != 32) {
01402                 /* reset it */
01403                 phy_init(nic);
01404         }
01405         
01406         dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n",
01407                  pci->driver_name, pci->vendor, pci->dev_id, pci->driver_name));
01408         if(!forcedeth_reset(nic)) return 0; // no valid link
01409 
01410         /* point to NIC specific routines */
01411         nic->nic_op     = &forcedeth_operations;
01412         return 1;
01413 }
01414 
01415 static struct pci_device_id forcedeth_nics[] = {
01416 PCI_ROM(0x10de, 0x01C3, "nforce", "nForce NVENET_1 Ethernet Controller", 0),
01417 PCI_ROM(0x10de, 0x0066, "nforce2", "nForce NVENET_2 Ethernet Controller", 0),
01418 PCI_ROM(0x10de, 0x00D6, "nforce3", "nForce NVENET_3 Ethernet Controller", 0),
01419 PCI_ROM(0x10de, 0x0086, "nforce4", "nForce NVENET_4 Ethernet Controller", 0),
01420 PCI_ROM(0x10de, 0x008c, "nforce5", "nForce NVENET_5 Ethernet Controller", 0),
01421 PCI_ROM(0x10de, 0x00e6, "nforce6", "nForce NVENET_6 Ethernet Controller", 0),
01422 PCI_ROM(0x10de, 0x00df, "nforce7", "nForce NVENET_7 Ethernet Controller", 0),
01423 PCI_ROM(0x10de, 0x0056, "nforce8", "nForce NVENET_8 Ethernet Controller", 0),
01424 PCI_ROM(0x10de, 0x0057, "nforce9", "nForce NVENET_9 Ethernet Controller", 0),
01425 PCI_ROM(0x10de, 0x0037, "nforce10", "nForce NVENET_10 Ethernet Controller", 0),
01426 PCI_ROM(0x10de, 0x0038, "nforce11", "nForce NVENET_11 Ethernet Controller", 0),
01427 PCI_ROM(0x10de, 0x0373, "nforce15", "nForce NVENET_15 Ethernet Controller", 0),
01428 PCI_ROM(0x10de, 0x0269, "nforce16", "nForce NVENET_16 Ethernet Controller", 0),
01429 PCI_ROM(0x10de, 0x0760, "nforce17", "nForce NVENET_17 Ethernet Controller", MAC_ADDR_CORRECT),
01430 PCI_ROM(0x10de, 0x054c, "nforce67", "nForce NVENET_67 Ethernet Controller", MAC_ADDR_CORRECT),
01431 };
01432 
01433 PCI_DRIVER ( forcedeth_driver, forcedeth_nics, PCI_NO_CLASS );
01434 
01435 DRIVER ( "forcedeth", nic_driver, pci_driver, forcedeth_driver,
01436          forcedeth_probe, forcedeth_disable );
01437 
01438 /*
01439  * Local variables:
01440  *  c-basic-offset: 8
01441  *  c-indent-level: 8
01442  *  tab-width: 8
01443  * End:
01444  */

Generated on Tue Apr 6 20:01:00 2010 for gPXE by  doxygen 1.5.7.1