|
|
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, ®s->MCFG); ! 387: WORD_REG_BITS_ON(MCFG_VIDFR, ®s->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, ®s->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, ®s->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, ®s->CR0Set); ! 618: writew(0xFFFF, ®s->TDCSRClr); ! 619: writeb(0xFF, ®s->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(®s->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, ®s->RBRDU); ! 962: writel(virt_to_le32desc(vptr->rd_ring), ®s->RDBaseLo); ! 963: writew(0, ®s->RDIdx); ! 964: writew(RX_DESC_DEF - 1, ®s->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, ®s->CR0Clr); ! 1012: //writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), ! 1013: writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), ! 1014: ®s->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, ®s->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), ®s->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), ®s->RDBaseLo); ! 1062: writew(vptr->options.numrx - 1, ®s->RDCSize); ! 1063: mac_rx_queue_run(regs); ! 1064: mac_rx_queue_wake(regs); ! 1065: ! 1066: writew(vptr->options.numtx - 1, ®s->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, ®s->CR0Clr); ! 1077: writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), ! 1078: ®s->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, ®s->CR0Set); ! 1117: ! 1118: for (i = 0; i < W_MAX_TIMEOUT; i++) { ! 1119: udelay(5); ! 1120: if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, ®s->CR0Set)) ! 1121: break; ! 1122: } ! 1123: ! 1124: if (i == W_MAX_TIMEOUT) { ! 1125: writel(CR0_FORSRST, ®s->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, ®s->MIICR); ! 1389: for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { ! 1390: udelay(1); ! 1391: if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->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, ®s->MIIADR); ! 1410: ! 1411: for (ii = 0; ii < W_MAX_TIMEOUT; ii++) { ! 1412: udelay(1); ! 1413: if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR)) ! 1414: break; ! 1415: } ! 1416: ! 1417: writeb(MIICR_MAUTO, ®s->MIICR); ! 1418: ! 1419: for (ii = 0; ii < W_MAX_TIMEOUT; ii++) { ! 1420: udelay(1); ! 1421: if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->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, ®s->MIIADR); ! 1447: ! 1448: BYTE_REG_BITS_ON(MIICR_RCMD, ®s->MIICR); ! 1449: ! 1450: for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { ! 1451: if (!(readb(®s->MIICR) & MIICR_RCMD)) ! 1452: break; ! 1453: } ! 1454: ! 1455: *data = readw(®s->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, ®s->MIIADR); ! 1484: /* set MII data */ ! 1485: writew(data, ®s->MIIDATA); ! 1486: ! 1487: /* turn on MIICR_WCMD */ ! 1488: BYTE_REG_BITS_ON(MIICR_WCMD, ®s->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(®s->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, ®s->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, ®s->CHIPGCR); ! 1651: ! 1652: CHIPGCR = readb(®s->CHIPGCR); ! 1653: CHIPGCR &= ~CHIPGCR_FCGMII; ! 1654: ! 1655: if (mii_status & VELOCITY_DUPLEX_FULL) { ! 1656: CHIPGCR |= CHIPGCR_FCFDX; ! 1657: writeb(CHIPGCR, ®s->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, ®s->TCR); ! 1662: } else { ! 1663: CHIPGCR &= ~CHIPGCR_FCFDX; ! 1664: printf ! 1665: ("DEBUG: set Velocity to forced half mode\n"); ! 1666: writeb(CHIPGCR, ®s->CHIPGCR); ! 1667: if (vptr->rev_id < REV_ID_VT3216_A0) ! 1668: BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->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, ®s->TESTCFG); ! 1677: } else { ! 1678: BYTE_REG_BITS_ON(TESTCFG_HBDIS, ®s->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(®s->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, ®s->PHYSR0)) ! 1805: writel(CR0_FDXRFCEN, ®s->CR0Set); ! 1806: else ! 1807: writel(CR0_FDXRFCEN, ®s->CR0Clr); ! 1808: ! 1809: if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, ®s->PHYSR0)) ! 1810: writel(CR0_FDXTFCEN, ®s->CR0Set); ! 1811: else ! 1812: writel(CR0_FDXTFCEN, ®s->CR0Clr); ! 1813: break; ! 1814: ! 1815: case FLOW_CNTL_TX: ! 1816: writel(CR0_FDXTFCEN, ®s->CR0Set); ! 1817: writel(CR0_FDXRFCEN, ®s->CR0Clr); ! 1818: break; ! 1819: ! 1820: case FLOW_CNTL_RX: ! 1821: writel(CR0_FDXRFCEN, ®s->CR0Set); ! 1822: writel(CR0_FDXTFCEN, ®s->CR0Clr); ! 1823: break; ! 1824: ! 1825: case FLOW_CNTL_TX_RX: ! 1826: writel(CR0_FDXTFCEN, ®s->CR0Set); ! 1827: writel(CR0_FDXRFCEN, ®s->CR0Set); ! 1828: break; ! 1829: ! 1830: case FLOW_CNTL_DISABLE: ! 1831: writel(CR0_FDXRFCEN, ®s->CR0Clr); ! 1832: writel(CR0_FDXTFCEN, ®s->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 );
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.