Annotation of qemu/roms/ipxe/src/drivers/net/via-velocity.c, revision 1.1.1.1

1.1       root        1: /**************************************************************************
                      2: *    via-velocity.c: Etherboot device driver for the VIA 6120 Gigabit
                      3: *    Changes for Etherboot port:
                      4: *       Copyright (c) 2006 by Timothy Legge <[email protected]>
                      5: *
                      6: *    This program is free software; you can redistribute it and/or modify
                      7: *    it under the terms of the GNU General Public License as published by
                      8: *    the Free Software Foundation; either version 2 of the License, or
                      9: *    (at your option) any later version.
                     10: *
                     11: *    This program is distributed in the hope that it will be useful,
                     12: *    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: *    GNU General Public License for more details.
                     15: *
                     16: *    You should have received a copy of the GNU General Public License
                     17: *    along with this program; if not, write to the Free Software
                     18: *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     19: *
                     20: *    This driver is based on:
                     21: *         via-velocity.c: VIA Velocity VT6120, VT6122 Ethernet driver 
                     22: *             The changes are (c) Copyright 2004, Red Hat Inc. 
                     23: *                <[email protected]>
                     24: *             Additional fixes and clean up: Francois Romieu
                     25: *
                     26: *     Original code:
                     27: *         Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
                     28: *         All rights reserved.
                     29: *             Author: Chuang Liang-Shing, AJ Jiang
                     30: * 
                     31: *    Linux Driver Version 2.6.15.4
                     32: * 
                     33: *    REVISION HISTORY:
                     34: *    ================
                     35: *
                     36: *    v1.0      03-06-2006      timlegge        Initial port of Linux driver
                     37: *    
                     38: *    Indent Options: indent -kr -i8
                     39: *************************************************************************/
                     40: 
                     41: FILE_LICENCE ( GPL2_OR_LATER );
                     42: 
                     43: #include "etherboot.h"
                     44: #include "nic.h"
                     45: #include <ipxe/pci.h>
                     46: #include <ipxe/ethernet.h>
                     47: 
                     48: #include "via-velocity.h"
                     49: 
                     50: typedef int pci_power_t;
                     51: 
                     52: #define PCI_D0  ((int) 0)
                     53: #define PCI_D1  ((int) 1)
                     54: #define PCI_D2  ((int) 2)
                     55: #define PCI_D3hot       ((int) 3)
                     56: #define PCI_D3cold      ((int) 4)
                     57: #define PCI_POWER_ERROR ((int) -1)
                     58: 
                     59: 
                     60: /* Condensed operations for readability. */
                     61: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
                     62: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
                     63: 
                     64: //FIXME: Move to pci.c
                     65: int pci_set_power_state(struct pci_device *dev, int state);
                     66: 
                     67: /* FIXME: Move BASE to the private structure */
                     68: static u32 BASE;
                     69: 
                     70: /* NIC specific static variables go here */
                     71: #define VELOCITY_PARAM(N,D) \
                     72:         static const int N[MAX_UNITS]=OPTION_DEFAULT;
                     73: /*        MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UNITS) "i");\
                     74:         MODULE_PARM_DESC(N, D); */
                     75: 
                     76: VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors");
                     77: VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
                     78: 
                     79: 
                     80: #define VLAN_ID_MIN     0
                     81: #define VLAN_ID_MAX     4095
                     82: #define VLAN_ID_DEF     0
                     83: /* VID_setting[] is used for setting the VID of NIC.
                     84:    0: default VID.
                     85:    1-4094: other VIDs.
                     86: */
                     87: VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
                     88: 
                     89: #define RX_THRESH_MIN   0
                     90: #define RX_THRESH_MAX   3
                     91: #define RX_THRESH_DEF   0
                     92: /* rx_thresh[] is used for controlling the receive fifo threshold.
                     93:    0: indicate the rxfifo threshold is 128 bytes.
                     94:    1: indicate the rxfifo threshold is 512 bytes.
                     95:    2: indicate the rxfifo threshold is 1024 bytes.
                     96:    3: indicate the rxfifo threshold is store & forward.
                     97: */
                     98: VELOCITY_PARAM(rx_thresh, "Receive fifo threshold");
                     99: 
                    100: #define DMA_LENGTH_MIN  0
                    101: #define DMA_LENGTH_MAX  7
                    102: #define DMA_LENGTH_DEF  0
                    103: 
                    104: /* DMA_length[] is used for controlling the DMA length
                    105:    0: 8 DWORDs
                    106:    1: 16 DWORDs
                    107:    2: 32 DWORDs
                    108:    3: 64 DWORDs
                    109:    4: 128 DWORDs
                    110:    5: 256 DWORDs
                    111:    6: SF(flush till emply)
                    112:    7: SF(flush till emply)
                    113: */
                    114: VELOCITY_PARAM(DMA_length, "DMA length");
                    115: 
                    116: #define TAGGING_DEF     0
                    117: /* enable_tagging[] is used for enabling 802.1Q VID tagging.
                    118:    0: disable VID seeting(default).
                    119:    1: enable VID setting.
                    120: */
                    121: VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
                    122: 
                    123: #define IP_ALIG_DEF     0
                    124: /* IP_byte_align[] is used for IP header DWORD byte aligned
                    125:    0: indicate the IP header won't be DWORD byte aligned.(Default) .
                    126:    1: indicate the IP header will be DWORD byte aligned.
                    127:       In some enviroment, the IP header should be DWORD byte aligned,
                    128:       or the packet will be droped when we receive it. (eg: IPVS)
                    129: */
                    130: VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
                    131: 
                    132: #define TX_CSUM_DEF     1
                    133: /* txcsum_offload[] is used for setting the checksum offload ability of NIC.
                    134:    (We only support RX checksum offload now)
                    135:    0: disable csum_offload[checksum offload
                    136:    1: enable checksum offload. (Default)
                    137: */
                    138: VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload");
                    139: 
                    140: #define FLOW_CNTL_DEF   1
                    141: #define FLOW_CNTL_MIN   1
                    142: #define FLOW_CNTL_MAX   5
                    143: 
                    144: /* flow_control[] is used for setting the flow control ability of NIC.
                    145:    1: hardware deafult - AUTO (default). Use Hardware default value in ANAR.
                    146:    2: enable TX flow control.
                    147:    3: enable RX flow control.
                    148:    4: enable RX/TX flow control.
                    149:    5: disable
                    150: */
                    151: VELOCITY_PARAM(flow_control, "Enable flow control ability");
                    152: 
                    153: #define MED_LNK_DEF 0
                    154: #define MED_LNK_MIN 0
                    155: #define MED_LNK_MAX 4
                    156: /* speed_duplex[] is used for setting the speed and duplex mode of NIC.
                    157:    0: indicate autonegotiation for both speed and duplex mode
                    158:    1: indicate 100Mbps half duplex mode
                    159:    2: indicate 100Mbps full duplex mode
                    160:    3: indicate 10Mbps half duplex mode
                    161:    4: indicate 10Mbps full duplex mode
                    162: 
                    163:    Note:
                    164:         if EEPROM have been set to the force mode, this option is ignored
                    165:             by driver.
                    166: */
                    167: VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
                    168: 
                    169: #define VAL_PKT_LEN_DEF     0
                    170: /* ValPktLen[] is used for setting the checksum offload ability of NIC.
                    171:    0: Receive frame with invalid layer 2 length (Default)
                    172:    1: Drop frame with invalid layer 2 length
                    173: */
                    174: VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
                    175: 
                    176: #define WOL_OPT_DEF     0
                    177: #define WOL_OPT_MIN     0
                    178: #define WOL_OPT_MAX     7
                    179: /* wol_opts[] is used for controlling wake on lan behavior.
                    180:    0: Wake up if recevied a magic packet. (Default)
                    181:    1: Wake up if link status is on/off.
                    182:    2: Wake up if recevied an arp packet.
                    183:    4: Wake up if recevied any unicast packet.
                    184:    Those value can be sumed up to support more than one option.
                    185: */
                    186: VELOCITY_PARAM(wol_opts, "Wake On Lan options");
                    187: 
                    188: #define INT_WORKS_DEF   20
                    189: #define INT_WORKS_MIN   10
                    190: #define INT_WORKS_MAX   64
                    191: 
                    192: VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
                    193: 
                    194: /* The descriptors for this card are required to be aligned on
                    195: 64 byte boundaries.  As the align attribute does not guarantee alignment
                    196: greater than the alignment of the start address (which for Etherboot
                    197: is 16 bytes of alignment) it requires some extra steps.  Add 64 to the 
                    198: size of the array and the init_ring adjusts the alignment */
                    199: 
                    200: /* Define the TX Descriptor */
                    201: static u8 tx_ring[TX_DESC_DEF * sizeof(struct tx_desc) + 64];
                    202: 
                    203: /* Create a static buffer of size PKT_BUF_SZ for each TX Descriptor.  
                    204: All descriptors point to a part of this buffer */
                    205: static u8 txb[(TX_DESC_DEF * PKT_BUF_SZ) + 64];
                    206: 
                    207: /* Define the RX Descriptor */
                    208: static u8 rx_ring[RX_DESC_DEF * sizeof(struct rx_desc) + 64];
                    209: 
                    210: /* Create a static buffer of size PKT_BUF_SZ for each RX Descriptor
                    211:    All descriptors point to a part of this buffer */
                    212: static u8 rxb[(RX_DESC_DEF * PKT_BUF_SZ) + 64];
                    213: 
                    214: static void velocity_init_info(struct pci_device *pdev,
                    215:                               struct velocity_info *vptr,
                    216:                               struct velocity_info_tbl *info);
                    217: static int velocity_get_pci_info(struct velocity_info *,
                    218:                                 struct pci_device *pdev);
                    219: static int velocity_open(struct nic *nic, struct pci_device *pci);
                    220: 
                    221: static int velocity_soft_reset(struct velocity_info *vptr);
                    222: static void velocity_init_cam_filter(struct velocity_info *vptr);
                    223: static void mii_init(struct velocity_info *vptr, u32 mii_status);
                    224: static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
                    225: static void velocity_print_link_status(struct velocity_info *vptr);
                    226: static void safe_disable_mii_autopoll(struct mac_regs *regs);
                    227: static void enable_flow_control_ability(struct velocity_info *vptr);
                    228: static void enable_mii_autopoll(struct mac_regs *regs);
                    229: static int velocity_mii_read(struct mac_regs *, u8 byIdx, u16 * pdata);
                    230: static int velocity_mii_write(struct mac_regs *, u8 byMiiAddr, u16 data);
                    231: static u32 mii_check_media_mode(struct mac_regs *regs);
                    232: static u32 check_connection_type(struct mac_regs *regs);
                    233: static int velocity_set_media_mode(struct velocity_info *vptr,
                    234:                                   u32 mii_status);
                    235: 
                    236: 
                    237: /*
                    238:  *     Internal board variants. At the moment we have only one
                    239:  */
                    240: 
                    241: static struct velocity_info_tbl chip_info_table[] = {
                    242:        {CHIP_TYPE_VT6110,
                    243:         "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1,
                    244:         0x00FFFFFFUL},
                    245:        {0, NULL, 0, 0, 0}
                    246: };
                    247: 
                    248: /**
                    249:  *     velocity_set_int_opt    -       parser for integer options
                    250:  *     @opt: pointer to option value
                    251:  *     @val: value the user requested (or -1 for default)
                    252:  *     @min: lowest value allowed
                    253:  *     @max: highest value allowed
                    254:  *     @def: default value
                    255:  *     @name: property name
                    256:  *     @dev: device name
                    257:  *
                    258:  *     Set an integer property in the module options. This function does
                    259:  *     all the verification and checking as well as reporting so that
                    260:  *     we don't duplicate code for each option.
                    261:  */
                    262: 
                    263: static void velocity_set_int_opt(int *opt, int val, int min, int max,
                    264:                                 int def, char *name, const char *devname)
                    265: {
                    266:        if (val == -1) {
                    267:                printf("%s: set value of parameter %s to %d\n",
                    268:                       devname, name, def);
                    269:                *opt = def;
                    270:        } else if (val < min || val > max) {
                    271:                printf
                    272:                    ("%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n",
                    273:                     devname, name, min, max);
                    274:                *opt = def;
                    275:        } else {
                    276:                printf("%s: set value of parameter %s to %d\n",
                    277:                       devname, name, val);
                    278:                *opt = val;
                    279:        }
                    280: }
                    281: 
                    282: /**
                    283:  *     velocity_set_bool_opt   -       parser for boolean options
                    284:  *     @opt: pointer to option value
                    285:  *     @val: value the user requested (or -1 for default)
                    286:  *     @def: default value (yes/no)
                    287:  *     @flag: numeric value to set for true.
                    288:  *     @name: property name
                    289:  *     @dev: device name
                    290:  *
                    291:  *     Set a boolean property in the module options. This function does
                    292:  *     all the verification and checking as well as reporting so that
                    293:  *     we don't duplicate code for each option.
                    294:  */
                    295: 
                    296: static void velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag,
                    297:                                  char *name, const char *devname)
                    298: {
                    299:        (*opt) &= (~flag);
                    300:        if (val == -1) {
                    301:                printf("%s: set parameter %s to %s\n",
                    302:                       devname, name, def ? "TRUE" : "FALSE");
                    303:                *opt |= (def ? flag : 0);
                    304:        } else if (val < 0 || val > 1) {
                    305:                printf
                    306:                    ("%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
                    307:                     devname, name);
                    308:                *opt |= (def ? flag : 0);
                    309:        } else {
                    310:                printf("%s: set parameter %s to %s\n",
                    311:                       devname, name, val ? "TRUE" : "FALSE");
                    312:                *opt |= (val ? flag : 0);
                    313:        }
                    314: }
                    315: 
                    316: /**
                    317:  *     velocity_get_options    -       set options on device
                    318:  *     @opts: option structure for the device
                    319:  *     @index: index of option to use in module options array
                    320:  *     @devname: device name
                    321:  *
                    322:  *     Turn the module and command options into a single structure
                    323:  *     for the current device
                    324:  */
                    325: 
                    326: static void velocity_get_options(struct velocity_opt *opts, int index,
                    327:                                 const char *devname)
                    328: {
                    329: 
                    330:        /* FIXME Do the options need to be configurable */
                    331:        velocity_set_int_opt(&opts->rx_thresh, -1, RX_THRESH_MIN,
                    332:                             RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh",
                    333:                             devname);
                    334:        velocity_set_int_opt(&opts->DMA_length, DMA_length[index],
                    335:                             DMA_LENGTH_MIN, DMA_LENGTH_MAX,
                    336:                             DMA_LENGTH_DEF, "DMA_length", devname);
                    337:        velocity_set_int_opt(&opts->numrx, RxDescriptors[index],
                    338:                             RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF,
                    339:                             "RxDescriptors", devname);
                    340:        velocity_set_int_opt(&opts->numtx, TxDescriptors[index],
                    341:                             TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF,
                    342:                             "TxDescriptors", devname);
                    343:        velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN,
                    344:                             VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting",
                    345:                             devname);
                    346:        velocity_set_bool_opt(&opts->flags, enable_tagging[index],
                    347:                              TAGGING_DEF, VELOCITY_FLAGS_TAGGING,
                    348:                              "enable_tagging", devname);
                    349:        velocity_set_bool_opt(&opts->flags, txcsum_offload[index],
                    350:                              TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM,
                    351:                              "txcsum_offload", devname);
                    352:        velocity_set_int_opt(&opts->flow_cntl, flow_control[index],
                    353:                             FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF,
                    354:                             "flow_control", devname);
                    355:        velocity_set_bool_opt(&opts->flags, IP_byte_align[index],
                    356:                              IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN,
                    357:                              "IP_byte_align", devname);
                    358:        velocity_set_bool_opt(&opts->flags, ValPktLen[index],
                    359:                              VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN,
                    360:                              "ValPktLen", devname);
                    361:        velocity_set_int_opt((void *) &opts->spd_dpx, speed_duplex[index],
                    362:                             MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF,
                    363:                             "Media link mode", devname);
                    364:        velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index],
                    365:                             WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF,
                    366:                             "Wake On Lan options", devname);
                    367:        velocity_set_int_opt((int *) &opts->int_works, int_works[index],
                    368:                             INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF,
                    369:                             "Interrupt service works", devname);
                    370:        opts->numrx = (opts->numrx & ~3);
                    371: }
                    372: 
                    373: /**
                    374:  *     velocity_init_cam_filter        -       initialise CAM
                    375:  *     @vptr: velocity to program
                    376:  *
                    377:  *     Initialize the content addressable memory used for filters. Load
                    378:  *     appropriately according to the presence of VLAN
                    379:  */
                    380: 
                    381: static void velocity_init_cam_filter(struct velocity_info *vptr)
                    382: {
                    383:        struct mac_regs *regs = vptr->mac_regs;
                    384: 
                    385:        /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
                    386:        WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
                    387:        WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
                    388: 
                    389:        /* Disable all CAMs */
                    390:        memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
                    391:        memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
                    392:        mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
                    393:        mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
                    394: 
                    395:        /* Enable first VCAM */
                    396:        if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
                    397:                /* If Tagging option is enabled and VLAN ID is not zero, then
                    398:                   turn on MCFG_RTGOPT also */
                    399:                if (vptr->options.vid != 0)
                    400:                        WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
                    401: 
                    402:                mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid),
                    403:                            VELOCITY_VLAN_ID_CAM);
                    404:                vptr->vCAMmask[0] |= 1;
                    405:                mac_set_cam_mask(regs, vptr->vCAMmask,
                    406:                                 VELOCITY_VLAN_ID_CAM);
                    407:        } else {
                    408:                u16 temp = 0;
                    409:                mac_set_cam(regs, 0, (u8 *) & temp, VELOCITY_VLAN_ID_CAM);
                    410:                temp = 1;
                    411:                mac_set_cam_mask(regs, (u8 *) & temp,
                    412:                                 VELOCITY_VLAN_ID_CAM);
                    413:        }
                    414: }
                    415: 
                    416: static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
                    417: {
                    418:        struct mac_regs *regs = vptr->mac_regs;
                    419:        int avail, dirty, unusable;
                    420: 
                    421:        /*
                    422:         * RD number must be equal to 4X per hardware spec
                    423:         * (programming guide rev 1.20, p.13)
                    424:         */
                    425:        if (vptr->rd_filled < 4)
                    426:                return;
                    427: 
                    428:        wmb();
                    429: 
                    430:        unusable = vptr->rd_filled & 0x0003;
                    431:        dirty = vptr->rd_dirty - unusable;
                    432:        for (avail = vptr->rd_filled & 0xfffc; avail; avail--) {
                    433:                dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
                    434: //              printf("return dirty: %d\n", dirty);
                    435:                vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC;
                    436:        }
                    437: 
                    438:        writew(vptr->rd_filled & 0xfffc, &regs->RBRDU);
                    439:        vptr->rd_filled = unusable;
                    440: }
                    441: 
                    442: static int velocity_rx_refill(struct velocity_info *vptr)
                    443: {
                    444:        int dirty = vptr->rd_dirty, done = 0, ret = 0;
                    445: 
                    446: //      printf("rx_refill - rd_curr = %d, dirty = %d\n", vptr->rd_curr, dirty);
                    447:        do {
                    448:                struct rx_desc *rd = vptr->rd_ring + dirty;
                    449: 
                    450:                /* Fine for an all zero Rx desc at init time as well */
                    451:                if (rd->rdesc0.owner == OWNED_BY_NIC)
                    452:                        break;
                    453: //              printf("rx_refill - after owner %d\n", dirty);
                    454: 
                    455:                rd->inten = 1;
                    456:                rd->pa_high = 0;
                    457:                rd->rdesc0.len = cpu_to_le32(vptr->rx_buf_sz);;
                    458: 
                    459:                done++;
                    460:                dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
                    461:        } while (dirty != vptr->rd_curr);
                    462: 
                    463:        if (done) {
                    464: //              printf("\nGive Back Desc\n");
                    465:                vptr->rd_dirty = dirty;
                    466:                vptr->rd_filled += done;
                    467:                velocity_give_many_rx_descs(vptr);
                    468:        }
                    469: 
                    470:        return ret;
                    471: }
                    472: 
                    473: extern void hex_dump(const char *data, const unsigned int len);
                    474: /**************************************************************************
                    475: POLL - Wait for a frame
                    476: ***************************************************************************/
                    477: static int velocity_poll(struct nic *nic, int retrieve)
                    478: {
                    479:        /* Work out whether or not there's an ethernet packet ready to
                    480:         * read.  Return 0 if not.
                    481:         */
                    482: 
                    483:        int rd_curr = vptr->rd_curr % RX_DESC_DEF;
                    484:        struct rx_desc *rd = &(vptr->rd_ring[rd_curr]);
                    485: 
                    486:        if (rd->rdesc0.owner == OWNED_BY_NIC)
                    487:                return 0;
                    488:        rmb();
                    489: 
                    490:        if ( ! retrieve ) return 1;
                    491: 
                    492:        /*
                    493:         *      Don't drop CE or RL error frame although RXOK is off
                    494:         */
                    495:        if ((rd->rdesc0.RSR & RSR_RXOK)
                    496:            || (!(rd->rdesc0.RSR & RSR_RXOK)
                    497:                && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
                    498: 
                    499:                nic->packetlen = rd->rdesc0.len;
                    500:                // ptr->rxb + (rd_curr * PKT_BUF_SZ)
                    501:                memcpy(nic->packet, bus_to_virt(rd->pa_low),
                    502:                       nic->packetlen - 4);
                    503: 
                    504:                vptr->rd_curr++;
                    505:                vptr->rd_curr = vptr->rd_curr % RX_DESC_DEF;
                    506:                velocity_rx_refill(vptr);
                    507:                return 1;       /* Remove this line once this method is implemented */
                    508:        }
                    509:        return 0;
                    510: }
                    511: 
                    512: #define TX_TIMEOUT  (1000);
                    513: /**************************************************************************
                    514: TRANSMIT - Transmit a frame
                    515: ***************************************************************************/
                    516: static void velocity_transmit(struct nic *nic, const char *dest,       /* Destination */
                    517:                              unsigned int type,        /* Type */
                    518:                              unsigned int size,        /* size */
                    519:                              const char *packet)
                    520: {                              /* Packet */
                    521:        u16 nstype;
                    522:        u32 to;
                    523:        u8 *ptxb;
                    524:        unsigned int pktlen;
                    525:        struct tx_desc *td_ptr;
                    526: 
                    527:        int entry = vptr->td_curr % TX_DESC_DEF;
                    528:        td_ptr = &(vptr->td_rings[entry]);
                    529: 
                    530:        /* point to the current txb incase multiple tx_rings are used */
                    531:        ptxb = vptr->txb + (entry * PKT_BUF_SZ);
                    532:        memcpy(ptxb, dest, ETH_ALEN);   /* Destination */
                    533:        memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);      /* Source */
                    534:        nstype = htons((u16) type);     /* Type */
                    535:        memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);        /* Type */
                    536:        memcpy(ptxb + ETH_HLEN, packet, size);
                    537: 
                    538:        td_ptr->tdesc1.TCPLS = TCPLS_NORMAL;
                    539:        td_ptr->tdesc1.TCR = TCR0_TIC;
                    540:        td_ptr->td_buf[0].queue = 0;
                    541: 
                    542:        size += ETH_HLEN;
                    543:        while (size < ETH_ZLEN) /* pad to min length */
                    544:                ptxb[size++] = '\0';
                    545: 
                    546:        if (size < ETH_ZLEN) {
                    547: //              printf("Padd that packet\n");
                    548:                pktlen = ETH_ZLEN;
                    549: //                memcpy(ptxb, skb->data, skb->len);
                    550:                memset(ptxb + size, 0, ETH_ZLEN - size);
                    551: 
                    552:                vptr->td_rings[entry].tdesc0.pktsize = pktlen;
                    553:                vptr->td_rings[entry].td_buf[0].pa_low = virt_to_bus(ptxb);
                    554:                vptr->td_rings[entry].td_buf[0].pa_high &=
                    555:                    cpu_to_le32(0xffff0000UL);
                    556:                vptr->td_rings[entry].td_buf[0].bufsize =
                    557:                    vptr->td_rings[entry].tdesc0.pktsize;
                    558:                vptr->td_rings[entry].tdesc1.CMDZ = 2;
                    559:        } else {
                    560: //              printf("Correct size packet\n");
                    561:                td_ptr->tdesc0.pktsize = size;
                    562:                td_ptr->td_buf[0].pa_low = virt_to_bus(ptxb);
                    563:                td_ptr->td_buf[0].pa_high = 0;
                    564:                td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
                    565: //                tdinfo->nskb_dma = 1;
                    566:                td_ptr->tdesc1.CMDZ = 2;
                    567:        }
                    568: 
                    569:        if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
                    570:                td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
                    571:                td_ptr->tdesc1.pqinf.priority = 0;
                    572:                td_ptr->tdesc1.pqinf.CFI = 0;
                    573:                td_ptr->tdesc1.TCR |= TCR0_VETAG;
                    574:        }
                    575: 
                    576:        vptr->td_curr = (entry + 1);
                    577: 
                    578:        {
                    579: 
                    580:                int prev = entry - 1;
                    581: 
                    582:                if (prev < 0)
                    583:                        prev = TX_DESC_DEF - 1;
                    584:                td_ptr->tdesc0.owner |= OWNED_BY_NIC;
                    585:                td_ptr = &(vptr->td_rings[prev]);
                    586:                td_ptr->td_buf[0].queue = 1;
                    587:                mac_tx_queue_wake(vptr->mac_regs, 0);
                    588: 
                    589:        }
                    590: 
                    591:        to = currticks() + TX_TIMEOUT;
                    592:        while ((td_ptr->tdesc0.owner & OWNED_BY_NIC) && (currticks() < to));    /* wait */
                    593: 
                    594:        if (currticks() >= to) {
                    595:                printf("TX Time Out");
                    596:        }
                    597: 
                    598: }
                    599: 
                    600: /**************************************************************************
                    601: DISABLE - Turn off ethernet interface
                    602: ***************************************************************************/
                    603: static void velocity_disable(struct nic *nic __unused)
                    604: {
                    605:        /* put the card in its initial state */
                    606:        /* This function serves 3 purposes.
                    607:         * This disables DMA and interrupts so we don't receive
                    608:         *  unexpected packets or interrupts from the card after
                    609:         *  etherboot has finished. 
                    610:         * This frees resources so etherboot may use
                    611:         *  this driver on another interface
                    612:         * This allows etherboot to reinitialize the interface
                    613:         *  if something is something goes wrong.
                    614:         */
                    615:        struct mac_regs *regs = vptr->mac_regs;
                    616:        mac_disable_int(regs);
                    617:        writel(CR0_STOP, &regs->CR0Set);
                    618:        writew(0xFFFF, &regs->TDCSRClr);
                    619:        writeb(0xFF, &regs->RDCSRClr);
                    620:        safe_disable_mii_autopoll(regs);
                    621:        mac_clear_isr(regs);
                    622: 
                    623:        /* Power down the chip */
                    624: //      pci_set_power_state(vptr->pdev, PCI_D3hot);
                    625: 
                    626:        vptr->flags &= (~VELOCITY_FLAGS_OPENED);
                    627: }
                    628: 
                    629: /**************************************************************************
                    630: IRQ - handle interrupts
                    631: ***************************************************************************/
                    632: static void velocity_irq(struct nic *nic __unused, irq_action_t action)
                    633: {
                    634:        /* This routine is somewhat optional.  Etherboot itself
                    635:         * doesn't use interrupts, but they are required under some
                    636:         * circumstances when we're acting as a PXE stack.
                    637:         *
                    638:         * If you don't implement this routine, the only effect will
                    639:         * be that your driver cannot be used via Etherboot's UNDI
                    640:         * API.  This won't affect programs that use only the UDP
                    641:         * portion of the PXE API, such as pxelinux.
                    642:         */
                    643: 
                    644:        switch (action) {
                    645:        case DISABLE:
                    646:        case ENABLE:
                    647:                /* Set receive interrupt enabled/disabled state */
                    648:                /*
                    649:                   outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
                    650:                   nic->ioaddr + IntrMaskRegister );
                    651:                 */
                    652:                break;
                    653:        case FORCE:
                    654:                /* Force NIC to generate a receive interrupt */
                    655:                /*
                    656:                   outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
                    657:                 */
                    658:                break;
                    659:        }
                    660: }
                    661: 
                    662: static struct nic_operations velocity_operations = {
                    663:        .connect        = dummy_connect,
                    664:        .poll           = velocity_poll,
                    665:        .transmit       = velocity_transmit,
                    666:        .irq            = velocity_irq,
                    667: };
                    668: 
                    669: /**************************************************************************
                    670: PROBE - Look for an adapter, this routine's visible to the outside
                    671: ***************************************************************************/
                    672: static int velocity_probe( struct nic *nic, struct pci_device *pci)
                    673: {
                    674:        int ret, i;
                    675:        struct mac_regs *regs;
                    676: 
                    677:        printf("via-velocity.c: Found %s Vendor=0x%hX Device=0x%hX\n",
                    678:               pci->id->name, pci->vendor, pci->device);
                    679: 
                    680:        /* point to private storage */
                    681:        vptr = &vptx;
                    682:        info = chip_info_table;
                    683: 
                    684:        velocity_init_info(pci, vptr, info);
                    685: 
                    686: //FIXME: pci_enable_device(pci);
                    687: //FIXME: pci_set_power_state(pci, PCI_D0);
                    688: 
                    689:        ret = velocity_get_pci_info(vptr, pci);
                    690:        if (ret < 0) {
                    691:                printf("Failed to find PCI device.\n");
                    692:                return 0;
                    693:        }
                    694: 
                    695:        regs = ioremap(vptr->memaddr, vptr->io_size);
                    696:        if (regs == NULL) {
                    697:                printf("Unable to remap io\n");
                    698:                return 0;
                    699:        }
                    700: 
                    701:        vptr->mac_regs = regs;
                    702: 
                    703:        BASE = vptr->ioaddr;
                    704: 
                    705:        printf("Chip ID: %hX\n", vptr->chip_id);
                    706: 
                    707:        for (i = 0; i < 6; i++)
                    708:                nic->node_addr[i] = readb(&regs->PAR[i]);
                    709: 
                    710:        DBG ( "%s: %s at ioaddr %#hX\n", pci->id->name, eth_ntoa ( nic->node_addr ),
                    711:              (unsigned int) BASE );
                    712: 
                    713:        velocity_get_options(&vptr->options, 0, pci->id->name);
                    714: 
                    715:        /* 
                    716:         *      Mask out the options cannot be set to the chip
                    717:         */
                    718:        vptr->options.flags &= 0x00FFFFFFUL;    //info->flags = 0x00FFFFFFUL;
                    719: 
                    720:        /*
                    721:         *      Enable the chip specified capbilities
                    722:         */
                    723: 
                    724:        vptr->flags =
                    725:            vptr->options.
                    726:            flags | (0x00FFFFFFUL /*info->flags */  & 0xFF000000UL);
                    727: 
                    728:        vptr->wol_opts = vptr->options.wol_opts;
                    729:        vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
                    730: 
                    731:        vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
                    732: 
                    733:        if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
                    734:                printf("features missing\n");
                    735:        }
                    736: 
                    737:        /* and leave the chip powered down */
                    738: // FIXME:       pci_set_power_state(pci, PCI_D3hot);
                    739: 
                    740:        check_connection_type(vptr->mac_regs);
                    741:        velocity_open(nic, pci);
                    742: 
                    743:        /* store NIC parameters */
                    744:        nic->nic_op = &velocity_operations;
                    745:        return 1;
                    746: }
                    747: 
                    748: //#define IORESOURCE_IO              0x00000100      /* Resource type */
                    749: 
                    750: /**
                    751:  *     velocity_init_info      -       init private data
                    752:  *     @pdev: PCI device
                    753:  *     @vptr: Velocity info
                    754:  *     @info: Board type
                    755:  *
                    756:  *     Set up the initial velocity_info struct for the device that has been
                    757:  *     discovered.
                    758:  */
                    759: 
                    760: static void velocity_init_info(struct pci_device *pdev,
                    761:                               struct velocity_info *vptr,
                    762:                               struct velocity_info_tbl *info)
                    763: {
                    764:        memset(vptr, 0, sizeof(struct velocity_info));
                    765: 
                    766:        vptr->pdev = pdev;
                    767:        vptr->chip_id = info->chip_id;
                    768:        vptr->io_size = info->io_size;
                    769:        vptr->num_txq = info->txqueue;
                    770:        vptr->multicast_limit = MCAM_SIZE;
                    771: 
                    772:        printf
                    773:            ("chip_id: 0x%hX, io_size: %d, num_txq %d, multicast_limit: %d\n",
                    774:             vptr->chip_id, (unsigned int) vptr->io_size, vptr->num_txq,
                    775:             vptr->multicast_limit);
                    776:        printf("Name: %s\n", info->name);
                    777: 
                    778: //      spin_lock_init(&vptr->lock);
                    779: //      INIT_LIST_HEAD(&vptr->list);
                    780: }
                    781: 
                    782: /**
                    783:  *     velocity_get_pci_info   -       retrieve PCI info for device
                    784:  *     @vptr: velocity device
                    785:  *     @pdev: PCI device it matches
                    786:  *
                    787:  *     Retrieve the PCI configuration space data that interests us from
                    788:  *     the kernel PCI layer
                    789:  */
                    790: 
                    791: #define IORESOURCE_IO   0x00000100     /* Resource type */
                    792: #define IORESOURCE_PREFETCH        0x00001000  /* No side effects */
                    793: 
                    794: #define IORESOURCE_MEM             0x00000200
                    795: #define BAR_0           0
                    796: #define BAR_1           1
                    797: #define BAR_5           5
                    798: #define  PCI_BASE_ADDRESS_SPACE 0x01   /* 0 = memory, 1 = I/O */
                    799: #define  PCI_BASE_ADDRESS_SPACE_IO 0x01
                    800: #define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
                    801: #define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
                    802: #define  PCI_BASE_ADDRESS_MEM_TYPE_32   0x00   /* 32 bit address */
                    803: #define  PCI_BASE_ADDRESS_MEM_TYPE_1M   0x02   /* Below 1M [obsolete] */
                    804: #define  PCI_BASE_ADDRESS_MEM_TYPE_64   0x04   /* 64 bit address */
                    805: #define  PCI_BASE_ADDRESS_MEM_PREFETCH  0x08   /* prefetchable? */
                    806: //#define  PCI_BASE_ADDRESS_MEM_MASK      (~0x0fUL)
                    807: // #define  PCI_BASE_ADDRESS_IO_MASK       (~0x03UL)
                    808: 
                    809: unsigned long pci_resource_flags(struct pci_device *pdev, unsigned int bar)
                    810: {
                    811:        uint32_t l, sz;
                    812:        unsigned long flags = 0;
                    813: 
                    814:        pci_read_config_dword(pdev, bar, &l);
                    815:        pci_write_config_dword(pdev, bar, ~0);
                    816:        pci_read_config_dword(pdev, bar, &sz);
                    817:        pci_write_config_dword(pdev, bar, l);
                    818: 
                    819:        if (!sz || sz == 0xffffffff)
                    820:                printf("Weird size\n");
                    821:        if (l == 0xffffffff)
                    822:                l = 0;
                    823:        if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
                    824:                /*    sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK);
                    825:                   if (!sz)
                    826:                   continue;
                    827:                   res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
                    828:                 */ flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
                    829:                printf("Memory Resource\n");
                    830:        } else {
                    831:                //            sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
                    832:                ///         if (!sz)
                    833:                ///              continue;
                    834: //              res->start = l & PCI_BASE_ADDRESS_IO_MASK;
                    835:                flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
                    836:                printf("I/O Resource\n");
                    837:        }
                    838:        if (flags & PCI_BASE_ADDRESS_SPACE_IO) {
                    839:                printf("Why is it here\n");
                    840:                flags |= IORESOURCE_IO;
                    841:        } else {
                    842:                printf("here\n");
                    843: //flags &= ~IORESOURCE_IO;
                    844:        }
                    845: 
                    846: 
                    847:        if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
                    848:                flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
                    849: 
                    850: 
                    851:        return flags;
                    852: }
                    853: static int velocity_get_pci_info(struct velocity_info *vptr,
                    854:                                 struct pci_device *pdev)
                    855: {
                    856:        if (pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0) {
                    857:                printf("DEBUG: pci_read_config_byte failed\n");
                    858:                return -1;
                    859:        }
                    860: 
                    861:        adjust_pci_device(pdev);
                    862: 
                    863:        vptr->ioaddr = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
                    864:        vptr->memaddr = pci_bar_start(pdev, PCI_BASE_ADDRESS_1);
                    865: 
                    866:        printf("Looking for I/O Resource - Found:");
                    867:        if (!
                    868:            (pci_resource_flags(pdev, PCI_BASE_ADDRESS_0) & IORESOURCE_IO))
                    869:        {
                    870:                printf
                    871:                    ("DEBUG: region #0 is not an I/O resource, aborting.\n");
                    872:                return -1;
                    873:        }
                    874: 
                    875:        printf("Looking for Memory Resource - Found:");
                    876:        if ((pci_resource_flags(pdev, PCI_BASE_ADDRESS_1) & IORESOURCE_IO)) {
                    877:                printf("DEBUG: region #1 is an I/O resource, aborting.\n");
                    878:                return -1;
                    879:        }
                    880: 
                    881:        if (pci_bar_size(pdev, PCI_BASE_ADDRESS_1) < 256) {
                    882:                printf("DEBUG: region #1 is too small.\n");
                    883:                return -1;
                    884:        }
                    885:        vptr->pdev = pdev;
                    886: 
                    887:        return 0;
                    888: }
                    889: 
                    890: /**
                    891:  *     velocity_print_link_status      -       link status reporting
                    892:  *     @vptr: velocity to report on
                    893:  *
                    894:  *     Turn the link status of the velocity card into a kernel log
                    895:  *     description of the new link state, detailing speed and duplex
                    896:  *     status
                    897:  */
                    898: 
                    899: static void velocity_print_link_status(struct velocity_info *vptr)
                    900: {
                    901: 
                    902:        if (vptr->mii_status & VELOCITY_LINK_FAIL) {
                    903:                printf("failed to detect cable link\n");
                    904:        } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
                    905:                printf("Link autonegation");
                    906: 
                    907:                if (vptr->mii_status & VELOCITY_SPEED_1000)
                    908:                        printf(" speed 1000M bps");
                    909:                else if (vptr->mii_status & VELOCITY_SPEED_100)
                    910:                        printf(" speed 100M bps");
                    911:                else
                    912:                        printf(" speed 10M bps");
                    913: 
                    914:                if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
                    915:                        printf(" full duplex\n");
                    916:                else
                    917:                        printf(" half duplex\n");
                    918:        } else {
                    919:                printf("Link forced");
                    920:                switch (vptr->options.spd_dpx) {
                    921:                case SPD_DPX_100_HALF:
                    922:                        printf(" speed 100M bps half duplex\n");
                    923:                        break;
                    924:                case SPD_DPX_100_FULL:
                    925:                        printf(" speed 100M bps full duplex\n");
                    926:                        break;
                    927:                case SPD_DPX_10_HALF:
                    928:                        printf(" speed 10M bps half duplex\n");
                    929:                        break;
                    930:                case SPD_DPX_10_FULL:
                    931:                        printf(" speed 10M bps full duplex\n");
                    932:                        break;
                    933:                default:
                    934:                        break;
                    935:                }
                    936:        }
                    937: }
                    938: 
                    939: /**
                    940:  *     velocity_rx_reset       -       handle a receive reset
                    941:  *     @vptr: velocity we are resetting
                    942:  *
                    943:  *     Reset the ownership and status for the receive ring side.
                    944:  *     Hand all the receive queue to the NIC.
                    945:  */
                    946: 
                    947: static void velocity_rx_reset(struct velocity_info *vptr)
                    948: {
                    949: 
                    950:        struct mac_regs *regs = vptr->mac_regs;
                    951:        int i;
                    952: 
                    953: //ptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0;
                    954: 
                    955:        /*
                    956:         *      Init state, all RD entries belong to the NIC
                    957:         */
                    958:        for (i = 0; i < vptr->options.numrx; ++i)
                    959:                vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC;
                    960: 
                    961:        writew(RX_DESC_DEF, &regs->RBRDU);
                    962:        writel(virt_to_le32desc(vptr->rd_ring), &regs->RDBaseLo);
                    963:        writew(0, &regs->RDIdx);
                    964:        writew(RX_DESC_DEF - 1, &regs->RDCSize);
                    965: }
                    966: 
                    967: /**
                    968:  *     velocity_init_registers -       initialise MAC registers
                    969:  *     @vptr: velocity to init
                    970:  *     @type: type of initialisation (hot or cold)
                    971:  *
                    972:  *     Initialise the MAC on a reset or on first set up on the
                    973:  *     hardware.
                    974:  */
                    975: 
                    976: static void velocity_init_registers(struct nic *nic,
                    977:                                    struct velocity_info *vptr,
                    978:                                    enum velocity_init_type type)
                    979: {
                    980:        struct mac_regs *regs = vptr->mac_regs;
                    981:        int i, mii_status;
                    982: 
                    983:        mac_wol_reset(regs);
                    984: 
                    985:        switch (type) {
                    986:        case VELOCITY_INIT_RESET:
                    987:        case VELOCITY_INIT_WOL:
                    988: 
                    989: //netif_stop_queue(vptr->dev);
                    990: 
                    991:                /*
                    992:                 *      Reset RX to prevent RX pointer not on the 4X location
                    993:                 */
                    994:                velocity_rx_reset(vptr);
                    995:                mac_rx_queue_run(regs);
                    996:                mac_rx_queue_wake(regs);
                    997: 
                    998:                mii_status = velocity_get_opt_media_mode(vptr);
                    999: 
                   1000:                if (velocity_set_media_mode(vptr, mii_status) !=
                   1001:                    VELOCITY_LINK_CHANGE) {
                   1002:                        velocity_print_link_status(vptr);
                   1003:                        if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
                   1004:                                printf("Link Failed\n");
                   1005: //                              netif_wake_queue(vptr->dev);
                   1006:                }
                   1007: 
                   1008:                enable_flow_control_ability(vptr);
                   1009: 
                   1010:                mac_clear_isr(regs);
                   1011:                writel(CR0_STOP, &regs->CR0Clr);
                   1012:                //writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), 
                   1013:                writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
                   1014:                       &regs->CR0Set);
                   1015:                break;
                   1016: 
                   1017:        case VELOCITY_INIT_COLD:
                   1018:        default:
                   1019:                /*
                   1020:                 *      Do reset
                   1021:                 */
                   1022:                velocity_soft_reset(vptr);
                   1023:                mdelay(5);
                   1024: 
                   1025:                mac_eeprom_reload(regs);
                   1026:                for (i = 0; i < 6; i++) {
                   1027:                        writeb(nic->node_addr[i], &(regs->PAR[i]));
                   1028:                }
                   1029:                /*
                   1030:                 *      clear Pre_ACPI bit.
                   1031:                 */
                   1032:                BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
                   1033:                mac_set_rx_thresh(regs, vptr->options.rx_thresh);
                   1034:                mac_set_dma_length(regs, vptr->options.DMA_length);
                   1035: 
                   1036:                writeb(WOLCFG_SAM | WOLCFG_SAB, &regs->WOLCFGSet);
                   1037:                /*
                   1038:                 *      Back off algorithm use original IEEE standard
                   1039:                 */
                   1040:                BYTE_REG_BITS_SET(CFGB_OFSET,
                   1041:                                  (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA |
                   1042:                                   CFGB_BAKOPT), &regs->CFGB);
                   1043: 
                   1044:                /*
                   1045:                 *      Init CAM filter
                   1046:                 */
                   1047:                velocity_init_cam_filter(vptr);
                   1048: 
                   1049:                /*
                   1050:                 *      Set packet filter: Receive directed and broadcast address
                   1051:                 */
                   1052: //FIXME Multicast               velocity_set_multi(nic);
                   1053: 
                   1054:                /*
                   1055:                 *      Enable MII auto-polling
                   1056:                 */
                   1057:                enable_mii_autopoll(regs);
                   1058: 
                   1059:                vptr->int_mask = INT_MASK_DEF;
                   1060: 
                   1061:                writel(virt_to_le32desc(vptr->rd_ring), &regs->RDBaseLo);
                   1062:                writew(vptr->options.numrx - 1, &regs->RDCSize);
                   1063:                mac_rx_queue_run(regs);
                   1064:                mac_rx_queue_wake(regs);
                   1065: 
                   1066:                writew(vptr->options.numtx - 1, &regs->TDCSize);
                   1067: 
                   1068: //              for (i = 0; i < vptr->num_txq; i++) {
                   1069:                writel(virt_to_le32desc(vptr->td_rings),
                   1070:                       &(regs->TDBaseLo[0]));
                   1071:                mac_tx_queue_run(regs, 0);
                   1072: //              }
                   1073: 
                   1074:                init_flow_control_register(vptr);
                   1075: 
                   1076:                writel(CR0_STOP, &regs->CR0Clr);
                   1077:                writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
                   1078:                       &regs->CR0Set);
                   1079: 
                   1080:                mii_status = velocity_get_opt_media_mode(vptr);
                   1081: //              netif_stop_queue(vptr->dev);
                   1082: 
                   1083:                mii_init(vptr, mii_status);
                   1084: 
                   1085:                if (velocity_set_media_mode(vptr, mii_status) !=
                   1086:                    VELOCITY_LINK_CHANGE) {
                   1087:                        velocity_print_link_status(vptr);
                   1088:                        if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
                   1089:                                printf("Link Faaailll\n");
                   1090: //                              netif_wake_queue(vptr->dev);
                   1091:                }
                   1092: 
                   1093:                enable_flow_control_ability(vptr);
                   1094:                mac_hw_mibs_init(regs);
                   1095:                mac_write_int_mask(vptr->int_mask, regs);
                   1096:                mac_clear_isr(regs);
                   1097: 
                   1098: 
                   1099:        }
                   1100:        velocity_print_link_status(vptr);
                   1101: }
                   1102: 
                   1103: /**
                   1104:  *     velocity_soft_reset     -       soft reset
                   1105:  *     @vptr: velocity to reset
                   1106:  *
                   1107:  *     Kick off a soft reset of the velocity adapter and then poll
                   1108:  *     until the reset sequence has completed before returning.
                   1109:  */
                   1110: 
                   1111: static int velocity_soft_reset(struct velocity_info *vptr)
                   1112: {
                   1113:        struct mac_regs *regs = vptr->mac_regs;
                   1114:        unsigned int i = 0;
                   1115: 
                   1116:        writel(CR0_SFRST, &regs->CR0Set);
                   1117: 
                   1118:        for (i = 0; i < W_MAX_TIMEOUT; i++) {
                   1119:                udelay(5);
                   1120:                if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, &regs->CR0Set))
                   1121:                        break;
                   1122:        }
                   1123: 
                   1124:        if (i == W_MAX_TIMEOUT) {
                   1125:                writel(CR0_FORSRST, &regs->CR0Set);
                   1126:                /* FIXME: PCI POSTING */
                   1127:                /* delay 2ms */
                   1128:                mdelay(2);
                   1129:        }
                   1130:        return 0;
                   1131: }
                   1132: 
                   1133: /**
                   1134:  *     velocity_init_rings     -       set up DMA rings
                   1135:  *     @vptr: Velocity to set up
                   1136:  *
                   1137:  *     Allocate PCI mapped DMA rings for the receive and transmit layer
                   1138:  *     to use.
                   1139:  */
                   1140: 
                   1141: static int velocity_init_rings(struct velocity_info *vptr)
                   1142: {
                   1143: 
                   1144:        int idx;
                   1145: 
                   1146:        vptr->rd_curr = 0;
                   1147:        vptr->td_curr = 0;
                   1148:        memset(vptr->td_rings, 0, TX_DESC_DEF * sizeof(struct tx_desc));
                   1149:        memset(vptr->rd_ring, 0, RX_DESC_DEF * sizeof(struct rx_desc));
                   1150: //      memset(vptr->tx_buffs, 0, TX_DESC_DEF * PKT_BUF_SZ);
                   1151: 
                   1152: 
                   1153:        for (idx = 0; idx < RX_DESC_DEF; idx++) {
                   1154:                vptr->rd_ring[idx].rdesc0.RSR = 0;
                   1155:                vptr->rd_ring[idx].rdesc0.len = 0;
                   1156:                vptr->rd_ring[idx].rdesc0.reserved = 0;
                   1157:                vptr->rd_ring[idx].rdesc0.owner = 0;
                   1158:                vptr->rd_ring[idx].len = cpu_to_le32(vptr->rx_buf_sz);
                   1159:                vptr->rd_ring[idx].inten = 1;
                   1160:                vptr->rd_ring[idx].pa_low =
                   1161:                    virt_to_bus(vptr->rxb + (RX_DESC_DEF * idx));
                   1162:                vptr->rd_ring[idx].pa_high = 0;
                   1163:                vptr->rd_ring[idx].rdesc0.owner = OWNED_BY_NIC;
                   1164:        }
                   1165: 
                   1166: /*     for (i = 0; idx < TX_DESC_DEF; idx++ ) {
                   1167:                vptr->td_rings[idx].tdesc1.TCPLS = TCPLS_NORMAL;
                   1168:                vptr->td_rings[idx].tdesc1.TCR = TCR0_TIC;
                   1169:                vptr->td_rings[idx].td_buf[0].queue = 0;
                   1170:                vptr->td_rings[idx].tdesc0.owner = ~OWNED_BY_NIC;
                   1171:                vptr->td_rings[idx].tdesc0.pktsize = 0;
                   1172:                vptr->td_rings[idx].td_buf[0].pa_low = cpu_to_le32(virt_to_bus(vptr->txb + (idx * PKT_BUF_SZ)));
                   1173:                vptr->td_rings[idx].td_buf[0].pa_high = 0;
                   1174:                vptr->td_rings[idx].td_buf[0].bufsize = 0;
                   1175:                vptr->td_rings[idx].tdesc1.CMDZ = 2;
                   1176:        }
                   1177: */
                   1178:        return 0;
                   1179: }
                   1180: 
                   1181: /**
                   1182:  *     velocity_open           -       interface activation callback
                   1183:  *     @dev: network layer device to open
                   1184:  *
                   1185:  *     Called when the network layer brings the interface up. Returns
                   1186:  *     a negative posix error code on failure, or zero on success.
                   1187:  *
                   1188:  *     All the ring allocation and set up is done on open for this
                   1189:  *     adapter to minimise memory usage when inactive
                   1190:  */
                   1191: 
                   1192: #define PCI_BYTE_REG_BITS_ON(x,i,p) do{\
                   1193:     u8 byReg;\
                   1194:     pci_read_config_byte((p), (i), &(byReg));\
                   1195:     (byReg) |= (x);\
                   1196:     pci_write_config_byte((p), (i), (byReg));\
                   1197: } while (0)
                   1198: 
                   1199: //
                   1200: // Registers in the PCI configuration space
                   1201: //
                   1202: #define PCI_REG_COMMAND         0x04   //
                   1203: #define PCI_REG_MODE0           0x60   //
                   1204: #define PCI_REG_MODE1           0x61   //
                   1205: #define PCI_REG_MODE2           0x62   //
                   1206: #define PCI_REG_MODE3           0x63   //
                   1207: #define PCI_REG_DELAY_TIMER     0x64   //
                   1208: 
                   1209: // Bits in the (MODE2, 0x62) register
                   1210: //
                   1211: #define MODE2_PCEROPT       0x80       // take PCI bus ERror as a fatal and shutdown from software control
                   1212: #define MODE2_TXQ16         0x40       // TX write-back Queue control. 0->32 entries available in Tx write-back queue, 1->16 entries
                   1213: #define MODE2_TXPOST        0x08       // (Not support in VT3119)
                   1214: #define MODE2_AUTOOPT       0x04       // (VT3119 GHCI without such behavior)
                   1215: #define MODE2_MODE10T       0x02       // used to control tx Threshold for 10M case
                   1216: #define MODE2_TCPLSOPT      0x01       // TCP large send field update disable, hardware will not update related fields, leave it to software.
                   1217: 
                   1218: //
                   1219: // Bits in the MODE3 register
                   1220: //
                   1221: #define MODE3_MIION         0x04       // MII symbol codine error detect enable ??
                   1222: 
                   1223: // Bits in the (COMMAND, 0x04) register
                   1224: #define COMMAND_BUSM        0x04
                   1225: #define COMMAND_WAIT        0x80
                   1226: static int velocity_open(struct nic *nic, struct pci_device *pci __unused)
                   1227: {
                   1228:        u8 diff;
                   1229:        u32 TxPhyAddr, RxPhyAddr;
                   1230:        u32 TxBufPhyAddr, RxBufPhyAddr;
                   1231:        vptr->TxDescArrays = tx_ring;
                   1232:        if (vptr->TxDescArrays == 0)
                   1233:                printf("Allot Error");
                   1234: 
                   1235:        /* Tx Descriptor needs 64 bytes alignment; */
                   1236:        TxPhyAddr = virt_to_bus(vptr->TxDescArrays);
                   1237:        printf("Unaligned Address : %X\n", TxPhyAddr);
                   1238:        diff = 64 - (TxPhyAddr - ((TxPhyAddr >> 6) << 6));
                   1239:        TxPhyAddr += diff;
                   1240:        vptr->td_rings = (struct tx_desc *) (vptr->TxDescArrays + diff);
                   1241: 
                   1242:        printf("Aligned Address: %lX\n", virt_to_bus(vptr->td_rings));
                   1243:        vptr->tx_buffs = txb;
                   1244:        /* Rx Buffer needs 64 bytes alignment; */
                   1245:        TxBufPhyAddr = virt_to_bus(vptr->tx_buffs);
                   1246:        diff = 64 - (TxBufPhyAddr - ((TxBufPhyAddr >> 6) << 6));
                   1247:        TxBufPhyAddr += diff;
                   1248:        vptr->txb = (unsigned char *) (vptr->tx_buffs + diff);
                   1249: 
                   1250:        vptr->RxDescArrays = rx_ring;
                   1251:        /* Rx Descriptor needs 64 bytes alignment; */
                   1252:        RxPhyAddr = virt_to_bus(vptr->RxDescArrays);
                   1253:        diff = 64 - (RxPhyAddr - ((RxPhyAddr >> 6) << 6));
                   1254:        RxPhyAddr += diff;
                   1255:        vptr->rd_ring = (struct rx_desc *) (vptr->RxDescArrays + diff);
                   1256: 
                   1257:        vptr->rx_buffs = rxb;
                   1258:        /* Rx Buffer needs 64 bytes alignment; */
                   1259:        RxBufPhyAddr = virt_to_bus(vptr->rx_buffs);
                   1260:        diff = 64 - (RxBufPhyAddr - ((RxBufPhyAddr >> 6) << 6));
                   1261:        RxBufPhyAddr += diff;
                   1262:        vptr->rxb = (unsigned char *) (vptr->rx_buffs + diff);
                   1263: 
                   1264:        if (vptr->RxDescArrays == NULL || vptr->RxDescArrays == NULL) {
                   1265:                printf("Allocate tx_ring or rd_ring failed\n");
                   1266:                return 0;
                   1267:        }
                   1268: 
                   1269:        vptr->rx_buf_sz = PKT_BUF_SZ;
                   1270: /*
                   1271:     // turn this on to avoid retry forever
                   1272:     PCI_BYTE_REG_BITS_ON(MODE2_PCEROPT, PCI_REG_MODE2, pci);
                   1273:     // for some legacy BIOS and OS don't open BusM
                   1274:     // bit in PCI configuration space. So, turn it on.
                   1275:     PCI_BYTE_REG_BITS_ON(COMMAND_BUSM, PCI_REG_COMMAND, pci);
                   1276:     // turn this on to detect MII coding error
                   1277:     PCI_BYTE_REG_BITS_ON(MODE3_MIION, PCI_REG_MODE3, pci);
                   1278:  */
                   1279:        velocity_init_rings(vptr);
                   1280: 
                   1281:        /* Ensure chip is running */
                   1282: //FIXME:        pci_set_power_state(vptr->pdev, PCI_D0);
                   1283: 
                   1284:        velocity_init_registers(nic, vptr, VELOCITY_INIT_COLD);
                   1285:        mac_write_int_mask(0, vptr->mac_regs);
                   1286: //      _int(vptr->mac_regs);
                   1287:        //mac_enable_int(vptr->mac_regs);
                   1288: 
                   1289:        vptr->flags |= VELOCITY_FLAGS_OPENED;
                   1290:        return 1;
                   1291: 
                   1292: }
                   1293: 
                   1294: /*
                   1295:  * MII access , media link mode setting functions
                   1296:  */
                   1297: 
                   1298: 
                   1299: /**
                   1300:  *     mii_init        -       set up MII
                   1301:  *     @vptr: velocity adapter
                   1302:  *     @mii_status:  links tatus
                   1303:  *
                   1304:  *     Set up the PHY for the current link state.
                   1305:  */
                   1306: 
                   1307: static void mii_init(struct velocity_info *vptr, u32 mii_status __unused)
                   1308: {
                   1309:        u16 BMCR;
                   1310: 
                   1311:        switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
                   1312:        case PHYID_CICADA_CS8201:
                   1313:                /*
                   1314:                 *      Reset to hardware default
                   1315:                 */
                   1316:                MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
                   1317:                                 vptr->mac_regs);
                   1318:                /*
                   1319:                 *      Turn on ECHODIS bit in NWay-forced full mode and turn it
                   1320:                 *      off it in NWay-forced half mode for NWay-forced v.s. 
                   1321:                 *      legacy-forced issue.
                   1322:                 */
                   1323:                if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
                   1324:                        MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR,
                   1325:                                        vptr->mac_regs);
                   1326:                else
                   1327:                        MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR,
                   1328:                                         vptr->mac_regs);
                   1329:                /*
                   1330:                 *      Turn on Link/Activity LED enable bit for CIS8201
                   1331:                 */
                   1332:                MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs);
                   1333:                break;
                   1334:        case PHYID_VT3216_32BIT:
                   1335:        case PHYID_VT3216_64BIT:
                   1336:                /*
                   1337:                 *      Reset to hardware default
                   1338:                 */
                   1339:                MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
                   1340:                                vptr->mac_regs);
                   1341:                /*
                   1342:                 *      Turn on ECHODIS bit in NWay-forced full mode and turn it
                   1343:                 *      off it in NWay-forced half mode for NWay-forced v.s. 
                   1344:                 *      legacy-forced issue
                   1345:                 */
                   1346:                if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
                   1347:                        MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR,
                   1348:                                        vptr->mac_regs);
                   1349:                else
                   1350:                        MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR,
                   1351:                                         vptr->mac_regs);
                   1352:                break;
                   1353: 
                   1354:        case PHYID_MARVELL_1000:
                   1355:        case PHYID_MARVELL_1000S:
                   1356:                /*
                   1357:                 *      Assert CRS on Transmit 
                   1358:                 */
                   1359:                MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
                   1360:                /*
                   1361:                 *      Reset to hardware default 
                   1362:                 */
                   1363:                MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
                   1364:                                vptr->mac_regs);
                   1365:                break;
                   1366:        default:
                   1367:                ;
                   1368:        }
                   1369:        velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR);
                   1370:        if (BMCR & BMCR_ISO) {
                   1371:                BMCR &= ~BMCR_ISO;
                   1372:                velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR);
                   1373:        }
                   1374: }
                   1375: 
                   1376: /**
                   1377:  *     safe_disable_mii_autopoll       -       autopoll off
                   1378:  *     @regs: velocity registers
                   1379:  *
                   1380:  *     Turn off the autopoll and wait for it to disable on the chip
                   1381:  */
                   1382: 
                   1383: static void safe_disable_mii_autopoll(struct mac_regs *regs)
                   1384: {
                   1385:        u16 ww;
                   1386: 
                   1387:        /*  turn off MAUTO */
                   1388:        writeb(0, &regs->MIICR);
                   1389:        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
                   1390:                udelay(1);
                   1391:                if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
                   1392:                        break;
                   1393:        }
                   1394: }
                   1395: 
                   1396: /**
                   1397:  *     enable_mii_autopoll     -       turn on autopolling
                   1398:  *     @regs: velocity registers
                   1399:  *
                   1400:  *     Enable the MII link status autopoll feature on the Velocity
                   1401:  *     hardware. Wait for it to enable.
                   1402:  */
                   1403: 
                   1404: static void enable_mii_autopoll(struct mac_regs *regs)
                   1405: {
                   1406:        unsigned int ii;
                   1407: 
                   1408:        writeb(0, &(regs->MIICR));
                   1409:        writeb(MIIADR_SWMPL, &regs->MIIADR);
                   1410: 
                   1411:        for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
                   1412:                udelay(1);
                   1413:                if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
                   1414:                        break;
                   1415:        }
                   1416: 
                   1417:        writeb(MIICR_MAUTO, &regs->MIICR);
                   1418: 
                   1419:        for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
                   1420:                udelay(1);
                   1421:                if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
                   1422:                        break;
                   1423:        }
                   1424: 
                   1425: }
                   1426: 
                   1427: /**
                   1428:  *     velocity_mii_read       -       read MII data
                   1429:  *     @regs: velocity registers
                   1430:  *     @index: MII register index
                   1431:  *     @data: buffer for received data
                   1432:  *
                   1433:  *     Perform a single read of an MII 16bit register. Returns zero
                   1434:  *     on success or -ETIMEDOUT if the PHY did not respond.
                   1435:  */
                   1436: 
                   1437: static int velocity_mii_read(struct mac_regs *regs, u8 index, u16 * data)
                   1438: {
                   1439:        u16 ww;
                   1440: 
                   1441:        /*
                   1442:         *      Disable MIICR_MAUTO, so that mii addr can be set normally
                   1443:         */
                   1444:        safe_disable_mii_autopoll(regs);
                   1445: 
                   1446:        writeb(index, &regs->MIIADR);
                   1447: 
                   1448:        BYTE_REG_BITS_ON(MIICR_RCMD, &regs->MIICR);
                   1449: 
                   1450:        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
                   1451:                if (!(readb(&regs->MIICR) & MIICR_RCMD))
                   1452:                        break;
                   1453:        }
                   1454: 
                   1455:        *data = readw(&regs->MIIDATA);
                   1456: 
                   1457:        enable_mii_autopoll(regs);
                   1458:        if (ww == W_MAX_TIMEOUT)
                   1459:                return -1;
                   1460:        return 0;
                   1461: }
                   1462: 
                   1463: /**
                   1464:  *     velocity_mii_write      -       write MII data
                   1465:  *     @regs: velocity registers
                   1466:  *     @index: MII register index
                   1467:  *     @data: 16bit data for the MII register
                   1468:  *
                   1469:  *     Perform a single write to an MII 16bit register. Returns zero
                   1470:  *     on success or -ETIMEDOUT if the PHY did not respond.
                   1471:  */
                   1472: 
                   1473: static int velocity_mii_write(struct mac_regs *regs, u8 mii_addr, u16 data)
                   1474: {
                   1475:        u16 ww;
                   1476: 
                   1477:        /*
                   1478:         *      Disable MIICR_MAUTO, so that mii addr can be set normally
                   1479:         */
                   1480:        safe_disable_mii_autopoll(regs);
                   1481: 
                   1482:        /* MII reg offset */
                   1483:        writeb(mii_addr, &regs->MIIADR);
                   1484:        /* set MII data */
                   1485:        writew(data, &regs->MIIDATA);
                   1486: 
                   1487:        /* turn on MIICR_WCMD */
                   1488:        BYTE_REG_BITS_ON(MIICR_WCMD, &regs->MIICR);
                   1489: 
                   1490:        /* W_MAX_TIMEOUT is the timeout period */
                   1491:        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
                   1492:                udelay(5);
                   1493:                if (!(readb(&regs->MIICR) & MIICR_WCMD))
                   1494:                        break;
                   1495:        }
                   1496:        enable_mii_autopoll(regs);
                   1497: 
                   1498:        if (ww == W_MAX_TIMEOUT)
                   1499:                return -1;
                   1500:        return 0;
                   1501: }
                   1502: 
                   1503: /**
                   1504:  *     velocity_get_opt_media_mode     -       get media selection
                   1505:  *     @vptr: velocity adapter
                   1506:  *
                   1507:  *     Get the media mode stored in EEPROM or module options and load
                   1508:  *     mii_status accordingly. The requested link state information
                   1509:  *     is also returned.
                   1510:  */
                   1511: 
                   1512: static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
                   1513: {
                   1514:        u32 status = 0;
                   1515: 
                   1516:        switch (vptr->options.spd_dpx) {
                   1517:        case SPD_DPX_AUTO:
                   1518:                status = VELOCITY_AUTONEG_ENABLE;
                   1519:                break;
                   1520:        case SPD_DPX_100_FULL:
                   1521:                status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
                   1522:                break;
                   1523:        case SPD_DPX_10_FULL:
                   1524:                status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
                   1525:                break;
                   1526:        case SPD_DPX_100_HALF:
                   1527:                status = VELOCITY_SPEED_100;
                   1528:                break;
                   1529:        case SPD_DPX_10_HALF:
                   1530:                status = VELOCITY_SPEED_10;
                   1531:                break;
                   1532:        }
                   1533:        vptr->mii_status = status;
                   1534:        return status;
                   1535: }
                   1536: 
                   1537: /**
                   1538:  *     mii_set_auto_on         -       autonegotiate on
                   1539:  *     @vptr: velocity
                   1540:  *
                   1541:  *     Enable autonegotation on this interface
                   1542:  */
                   1543: 
                   1544: static void mii_set_auto_on(struct velocity_info *vptr)
                   1545: {
                   1546:        if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
                   1547:                MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
                   1548:        else
                   1549:                MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
                   1550: }
                   1551: 
                   1552: 
                   1553: /*
                   1554: static void mii_set_auto_off(struct velocity_info * vptr)
                   1555: {
                   1556:     MII_REG_BITS_OFF(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
                   1557: }
                   1558: */
                   1559: 
                   1560: /**
                   1561:  *     set_mii_flow_control    -       flow control setup
                   1562:  *     @vptr: velocity interface
                   1563:  *
                   1564:  *     Set up the flow control on this interface according to
                   1565:  *     the supplied user/eeprom options.
                   1566:  */
                   1567: 
                   1568: static void set_mii_flow_control(struct velocity_info *vptr)
                   1569: {
                   1570:        /*Enable or Disable PAUSE in ANAR */
                   1571:        switch (vptr->options.flow_cntl) {
                   1572:        case FLOW_CNTL_TX:
                   1573:                MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
                   1574:                MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
                   1575:                break;
                   1576: 
                   1577:        case FLOW_CNTL_RX:
                   1578:                MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
                   1579:                MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
                   1580:                break;
                   1581: 
                   1582:        case FLOW_CNTL_TX_RX:
                   1583:                MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
                   1584:                MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
                   1585:                break;
                   1586: 
                   1587:        case FLOW_CNTL_DISABLE:
                   1588:                MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
                   1589:                MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR,
                   1590:                                 vptr->mac_regs);
                   1591:                break;
                   1592:        default:
                   1593:                break;
                   1594:        }
                   1595: }
                   1596: 
                   1597: /**
                   1598:  *     velocity_set_media_mode         -       set media mode
                   1599:  *     @mii_status: old MII link state
                   1600:  *
                   1601:  *     Check the media link state and configure the flow control
                   1602:  *     PHY and also velocity hardware setup accordingly. In particular
                   1603:  *     we need to set up CD polling and frame bursting.
                   1604:  */
                   1605: 
                   1606: static int velocity_set_media_mode(struct velocity_info *vptr,
                   1607:                                   u32 mii_status)
                   1608: {
                   1609:        struct mac_regs *regs = vptr->mac_regs;
                   1610: 
                   1611:        vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
                   1612: 
                   1613:        /* Set mii link status */
                   1614:        set_mii_flow_control(vptr);
                   1615: 
                   1616:        if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) {
                   1617:                MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR,
                   1618:                                vptr->mac_regs);
                   1619:        }
                   1620: 
                   1621:        /*
                   1622:         *      If connection type is AUTO
                   1623:         */
                   1624:        if (mii_status & VELOCITY_AUTONEG_ENABLE) {
                   1625:                printf("Velocity is AUTO mode\n");
                   1626:                /* clear force MAC mode bit */
                   1627:                BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
                   1628:                /* set duplex mode of MAC according to duplex mode of MII */
                   1629:                MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10,
                   1630:                                MII_REG_ANAR, vptr->mac_regs);
                   1631:                MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000,
                   1632:                                MII_REG_G1000CR, vptr->mac_regs);
                   1633:                MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR,
                   1634:                                vptr->mac_regs);
                   1635: 
                   1636:                /* enable AUTO-NEGO mode */
                   1637:                mii_set_auto_on(vptr);
                   1638:        } else {
                   1639:                u16 ANAR;
                   1640:                u8 CHIPGCR;
                   1641: 
                   1642:                /*
                   1643:                 * 1. if it's 3119, disable frame bursting in halfduplex mode
                   1644:                 *    and enable it in fullduplex mode
                   1645:                 * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR
                   1646:                 * 3. only enable CD heart beat counter in 10HD mode
                   1647:                 */
                   1648: 
                   1649:                /* set force MAC mode bit */
                   1650:                BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
                   1651: 
                   1652:                CHIPGCR = readb(&regs->CHIPGCR);
                   1653:                CHIPGCR &= ~CHIPGCR_FCGMII;
                   1654: 
                   1655:                if (mii_status & VELOCITY_DUPLEX_FULL) {
                   1656:                        CHIPGCR |= CHIPGCR_FCFDX;
                   1657:                        writeb(CHIPGCR, &regs->CHIPGCR);
                   1658:                        printf
                   1659:                            ("DEBUG: set Velocity to forced full mode\n");
                   1660:                        if (vptr->rev_id < REV_ID_VT3216_A0)
                   1661:                                BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
                   1662:                } else {
                   1663:                        CHIPGCR &= ~CHIPGCR_FCFDX;
                   1664:                        printf
                   1665:                            ("DEBUG: set Velocity to forced half mode\n");
                   1666:                        writeb(CHIPGCR, &regs->CHIPGCR);
                   1667:                        if (vptr->rev_id < REV_ID_VT3216_A0)
                   1668:                                BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
                   1669:                }
                   1670: 
                   1671:                MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000,
                   1672:                                 MII_REG_G1000CR, vptr->mac_regs);
                   1673: 
                   1674:                if (!(mii_status & VELOCITY_DUPLEX_FULL)
                   1675:                    && (mii_status & VELOCITY_SPEED_10)) {
                   1676:                        BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
                   1677:                } else {
                   1678:                        BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
                   1679:                }
                   1680:                /* MII_REG_BITS_OFF(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); */
                   1681:                velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR);
                   1682:                ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10));
                   1683:                if (mii_status & VELOCITY_SPEED_100) {
                   1684:                        if (mii_status & VELOCITY_DUPLEX_FULL)
                   1685:                                ANAR |= ANAR_TXFD;
                   1686:                        else
                   1687:                                ANAR |= ANAR_TX;
                   1688:                } else {
                   1689:                        if (mii_status & VELOCITY_DUPLEX_FULL)
                   1690:                                ANAR |= ANAR_10FD;
                   1691:                        else
                   1692:                                ANAR |= ANAR_10;
                   1693:                }
                   1694:                velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR);
                   1695:                /* enable AUTO-NEGO mode */
                   1696:                mii_set_auto_on(vptr);
                   1697:                /* MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); */
                   1698:        }
                   1699:        /* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */
                   1700:        /* vptr->mii_status=check_connection_type(vptr->mac_regs); */
                   1701:        return VELOCITY_LINK_CHANGE;
                   1702: }
                   1703: 
                   1704: /**
                   1705:  *     mii_check_media_mode    -       check media state
                   1706:  *     @regs: velocity registers
                   1707:  *
                   1708:  *     Check the current MII status and determine the link status
                   1709:  *     accordingly
                   1710:  */
                   1711: 
                   1712: static u32 mii_check_media_mode(struct mac_regs *regs)
                   1713: {
                   1714:        u32 status = 0;
                   1715:        u16 ANAR;
                   1716: 
                   1717:        if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs))
                   1718:                status |= VELOCITY_LINK_FAIL;
                   1719: 
                   1720:        if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs))
                   1721:                status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
                   1722:        else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs))
                   1723:                status |= (VELOCITY_SPEED_1000);
                   1724:        else {
                   1725:                velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
                   1726:                if (ANAR & ANAR_TXFD)
                   1727:                        status |=
                   1728:                            (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
                   1729:                else if (ANAR & ANAR_TX)
                   1730:                        status |= VELOCITY_SPEED_100;
                   1731:                else if (ANAR & ANAR_10FD)
                   1732:                        status |=
                   1733:                            (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
                   1734:                else
                   1735:                        status |= (VELOCITY_SPEED_10);
                   1736:        }
                   1737: 
                   1738:        if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
                   1739:                velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
                   1740:                if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
                   1741:                    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
                   1742:                        if (MII_REG_BITS_IS_ON
                   1743:                            (G1000CR_1000 | G1000CR_1000FD,
                   1744:                             MII_REG_G1000CR, regs))
                   1745:                                status |= VELOCITY_AUTONEG_ENABLE;
                   1746:                }
                   1747:        }
                   1748: 
                   1749:        return status;
                   1750: }
                   1751: 
                   1752: static u32 check_connection_type(struct mac_regs *regs)
                   1753: {
                   1754:        u32 status = 0;
                   1755:        u8 PHYSR0;
                   1756:        u16 ANAR;
                   1757:        PHYSR0 = readb(&regs->PHYSR0);
                   1758: 
                   1759:        /*
                   1760:           if (!(PHYSR0 & PHYSR0_LINKGD))
                   1761:           status|=VELOCITY_LINK_FAIL;
                   1762:         */
                   1763: 
                   1764:        if (PHYSR0 & PHYSR0_FDPX)
                   1765:                status |= VELOCITY_DUPLEX_FULL;
                   1766: 
                   1767:        if (PHYSR0 & PHYSR0_SPDG)
                   1768:                status |= VELOCITY_SPEED_1000;
                   1769:        if (PHYSR0 & PHYSR0_SPD10)
                   1770:                status |= VELOCITY_SPEED_10;
                   1771:        else
                   1772:                status |= VELOCITY_SPEED_100;
                   1773: 
                   1774:        if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
                   1775:                velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
                   1776:                if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
                   1777:                    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
                   1778:                        if (MII_REG_BITS_IS_ON
                   1779:                            (G1000CR_1000 | G1000CR_1000FD,
                   1780:                             MII_REG_G1000CR, regs))
                   1781:                                status |= VELOCITY_AUTONEG_ENABLE;
                   1782:                }
                   1783:        }
                   1784: 
                   1785:        return status;
                   1786: }
                   1787: 
                   1788: /**
                   1789:  *     enable_flow_control_ability     -       flow control
                   1790:  *     @vptr: veloity to configure
                   1791:  *
                   1792:  *     Set up flow control according to the flow control options
                   1793:  *     determined by the eeprom/configuration.
                   1794:  */
                   1795: 
                   1796: static void enable_flow_control_ability(struct velocity_info *vptr)
                   1797: {
                   1798: 
                   1799:        struct mac_regs *regs = vptr->mac_regs;
                   1800: 
                   1801:        switch (vptr->options.flow_cntl) {
                   1802: 
                   1803:        case FLOW_CNTL_DEFAULT:
                   1804:                if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, &regs->PHYSR0))
                   1805:                        writel(CR0_FDXRFCEN, &regs->CR0Set);
                   1806:                else
                   1807:                        writel(CR0_FDXRFCEN, &regs->CR0Clr);
                   1808: 
                   1809:                if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, &regs->PHYSR0))
                   1810:                        writel(CR0_FDXTFCEN, &regs->CR0Set);
                   1811:                else
                   1812:                        writel(CR0_FDXTFCEN, &regs->CR0Clr);
                   1813:                break;
                   1814: 
                   1815:        case FLOW_CNTL_TX:
                   1816:                writel(CR0_FDXTFCEN, &regs->CR0Set);
                   1817:                writel(CR0_FDXRFCEN, &regs->CR0Clr);
                   1818:                break;
                   1819: 
                   1820:        case FLOW_CNTL_RX:
                   1821:                writel(CR0_FDXRFCEN, &regs->CR0Set);
                   1822:                writel(CR0_FDXTFCEN, &regs->CR0Clr);
                   1823:                break;
                   1824: 
                   1825:        case FLOW_CNTL_TX_RX:
                   1826:                writel(CR0_FDXTFCEN, &regs->CR0Set);
                   1827:                writel(CR0_FDXRFCEN, &regs->CR0Set);
                   1828:                break;
                   1829: 
                   1830:        case FLOW_CNTL_DISABLE:
                   1831:                writel(CR0_FDXRFCEN, &regs->CR0Clr);
                   1832:                writel(CR0_FDXTFCEN, &regs->CR0Clr);
                   1833:                break;
                   1834: 
                   1835:        default:
                   1836:                break;
                   1837:        }
                   1838: 
                   1839: }
                   1840: 
                   1841: /* FIXME: Move to pci.c */
                   1842: /**
                   1843:  * pci_set_power_state - Set the power state of a PCI device
                   1844:  * @dev: PCI device to be suspended
                   1845:  * @state: Power state we're entering
                   1846:  *
                   1847:  * Transition a device to a new power state, using the Power Management 
                   1848:  * Capabilities in the device's config space.
                   1849:  *
                   1850:  * RETURN VALUE: 
                   1851:  * -EINVAL if trying to enter a lower state than we're already in.
                   1852:  * 0 if we're already in the requested state.
                   1853:  * -EIO if device does not support PCI PM.
                   1854:  * 0 if we can successfully change the power state.
                   1855:  */
                   1856: 
                   1857: int pci_set_power_state(struct pci_device *dev, int state)
                   1858: {
                   1859:        int pm;
                   1860:        u16 pmcsr;
                   1861:        int current_state = 0;
                   1862: 
                   1863:        /* bound the state we're entering */
                   1864:        if (state > 3)
                   1865:                state = 3;
                   1866: 
                   1867:        /* Validate current state:
                   1868:         * Can enter D0 from any state, but if we can only go deeper 
                   1869:         * to sleep if we're already in a low power state
                   1870:         */
                   1871:        if (state > 0 && current_state > state)
                   1872:                return -1;
                   1873:        else if (current_state == state)
                   1874:                return 0;       /* we're already there */
                   1875: 
                   1876:        /* find PCI PM capability in list */
                   1877:        pm = pci_find_capability(dev, PCI_CAP_ID_PM);
                   1878: 
                   1879:        /* abort if the device doesn't support PM capabilities */
                   1880:        if (!pm)
                   1881:                return -2;
                   1882: 
                   1883:        /* check if this device supports the desired state */
                   1884:        if (state == 1 || state == 2) {
                   1885:                u16 pmc;
                   1886:                pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
                   1887:                if (state == 1 && !(pmc & PCI_PM_CAP_D1))
                   1888:                        return -2;
                   1889:                else if (state == 2 && !(pmc & PCI_PM_CAP_D2))
                   1890:                        return -2;
                   1891:        }
                   1892: 
                   1893:        /* If we're in D3, force entire word to 0.
                   1894:         * This doesn't affect PME_Status, disables PME_En, and
                   1895:         * sets PowerState to 0.
                   1896:         */
                   1897:        if (current_state >= 3)
                   1898:                pmcsr = 0;
                   1899:        else {
                   1900:                pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
                   1901:                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
                   1902:                pmcsr |= state;
                   1903:        }
                   1904: 
                   1905:        /* enter specified state */
                   1906:        pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
                   1907: 
                   1908:        /* Mandatory power management transition delays */
                   1909:        /* see PCI PM 1.1 5.6.1 table 18 */
                   1910:        if (state == 3 || current_state == 3)
                   1911:                mdelay(10);
                   1912:        else if (state == 2 || current_state == 2)
                   1913:                udelay(200);
                   1914:        current_state = state;
                   1915: 
                   1916:        return 0;
                   1917: }
                   1918: 
                   1919: static struct pci_device_id velocity_nics[] = {
                   1920:        PCI_ROM(0x1106, 0x3119, "via-velocity", "VIA Networking Velocity Family Gigabit Ethernet Adapter", 0),
                   1921: };
                   1922: 
                   1923: PCI_DRIVER ( velocity_driver, velocity_nics, PCI_NO_CLASS );
                   1924: 
                   1925: DRIVER ( "VIA-VELOCITY/PCI", nic_driver, pci_driver, velocity_driver,
                   1926:          velocity_probe, velocity_disable );

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.