00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "etherboot.h"
00042 #include "nic.h"
00043 #include <gpxe/pci.h>
00044 #include <gpxe/ethernet.h>
00045
00046 #include "via-velocity.h"
00047
00048 typedef int pci_power_t;
00049
00050 #define PCI_D0 ((int) 0)
00051 #define PCI_D1 ((int) 1)
00052 #define PCI_D2 ((int) 2)
00053 #define PCI_D3hot ((int) 3)
00054 #define PCI_D3cold ((int) 4)
00055 #define PCI_POWER_ERROR ((int) -1)
00056
00057
00058
00059 #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
00060 #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
00061
00062
00063 int pci_set_power_state(struct pci_device *dev, int state);
00064
00065
00066 static u32 BASE;
00067
00068
00069 #define VELOCITY_PARAM(N,D) \
00070 static const int N[MAX_UNITS]=OPTION_DEFAULT;
00071
00072
00073
00074 VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors");
00075 VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
00076
00077
00078 #define VLAN_ID_MIN 0
00079 #define VLAN_ID_MAX 4095
00080 #define VLAN_ID_DEF 0
00081
00082
00083
00084
00085 VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
00086
00087 #define RX_THRESH_MIN 0
00088 #define RX_THRESH_MAX 3
00089 #define RX_THRESH_DEF 0
00090
00091
00092
00093
00094
00095
00096 VELOCITY_PARAM(rx_thresh, "Receive fifo threshold");
00097
00098 #define DMA_LENGTH_MIN 0
00099 #define DMA_LENGTH_MAX 7
00100 #define DMA_LENGTH_DEF 0
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 VELOCITY_PARAM(DMA_length, "DMA length");
00113
00114 #define TAGGING_DEF 0
00115
00116
00117
00118
00119 VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
00120
00121 #define IP_ALIG_DEF 0
00122
00123
00124
00125
00126
00127
00128 VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
00129
00130 #define TX_CSUM_DEF 1
00131
00132
00133
00134
00135
00136 VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload");
00137
00138 #define FLOW_CNTL_DEF 1
00139 #define FLOW_CNTL_MIN 1
00140 #define FLOW_CNTL_MAX 5
00141
00142
00143
00144
00145
00146
00147
00148
00149 VELOCITY_PARAM(flow_control, "Enable flow control ability");
00150
00151 #define MED_LNK_DEF 0
00152 #define MED_LNK_MIN 0
00153 #define MED_LNK_MAX 4
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
00166
00167 #define VAL_PKT_LEN_DEF 0
00168
00169
00170
00171
00172 VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
00173
00174 #define WOL_OPT_DEF 0
00175 #define WOL_OPT_MIN 0
00176 #define WOL_OPT_MAX 7
00177
00178
00179
00180
00181
00182
00183
00184 VELOCITY_PARAM(wol_opts, "Wake On Lan options");
00185
00186 #define INT_WORKS_DEF 20
00187 #define INT_WORKS_MIN 10
00188 #define INT_WORKS_MAX 64
00189
00190 VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
00191
00192
00193
00194
00195
00196
00197
00198
00199 static u8 tx_ring[TX_DESC_DEF * sizeof(struct tx_desc) + 64];
00200
00201
00202
00203 static u8 txb[(TX_DESC_DEF * PKT_BUF_SZ) + 64];
00204
00205
00206 static u8 rx_ring[RX_DESC_DEF * sizeof(struct rx_desc) + 64];
00207
00208
00209
00210 static u8 rxb[(RX_DESC_DEF * PKT_BUF_SZ) + 64];
00211
00212 static void velocity_init_info(struct pci_device *pdev,
00213 struct velocity_info *vptr,
00214 struct velocity_info_tbl *info);
00215 static int velocity_get_pci_info(struct velocity_info *,
00216 struct pci_device *pdev);
00217 static int velocity_open(struct nic *nic, struct pci_device *pci);
00218
00219 static int velocity_soft_reset(struct velocity_info *vptr);
00220 static void velocity_init_cam_filter(struct velocity_info *vptr);
00221 static void mii_init(struct velocity_info *vptr, u32 mii_status);
00222 static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
00223 static void velocity_print_link_status(struct velocity_info *vptr);
00224 static void safe_disable_mii_autopoll(struct mac_regs *regs);
00225 static void enable_flow_control_ability(struct velocity_info *vptr);
00226 static void enable_mii_autopoll(struct mac_regs *regs);
00227 static int velocity_mii_read(struct mac_regs *, u8 byIdx, u16 * pdata);
00228 static int velocity_mii_write(struct mac_regs *, u8 byMiiAddr, u16 data);
00229 static u32 mii_check_media_mode(struct mac_regs *regs);
00230 static u32 check_connection_type(struct mac_regs *regs);
00231 static int velocity_set_media_mode(struct velocity_info *vptr,
00232 u32 mii_status);
00233
00234
00235
00236
00237
00238
00239 static struct velocity_info_tbl chip_info_table[] = {
00240 {CHIP_TYPE_VT6110,
00241 "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1,
00242 0x00FFFFFFUL},
00243 {0, NULL, 0, 0, 0}
00244 };
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 static void velocity_set_int_opt(int *opt, int val, int min, int max,
00262 int def, char *name, const char *devname)
00263 {
00264 if (val == -1) {
00265 printf("%s: set value of parameter %s to %d\n",
00266 devname, name, def);
00267 *opt = def;
00268 } else if (val < min || val > max) {
00269 printf
00270 ("%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n",
00271 devname, name, min, max);
00272 *opt = def;
00273 } else {
00274 printf("%s: set value of parameter %s to %d\n",
00275 devname, name, val);
00276 *opt = val;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 static void velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag,
00295 char *name, const char *devname)
00296 {
00297 (*opt) &= (~flag);
00298 if (val == -1) {
00299 printf("%s: set parameter %s to %s\n",
00300 devname, name, def ? "TRUE" : "FALSE");
00301 *opt |= (def ? flag : 0);
00302 } else if (val < 0 || val > 1) {
00303 printf
00304 ("%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
00305 devname, name);
00306 *opt |= (def ? flag : 0);
00307 } else {
00308 printf("%s: set parameter %s to %s\n",
00309 devname, name, val ? "TRUE" : "FALSE");
00310 *opt |= (val ? flag : 0);
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 static void velocity_get_options(struct velocity_opt *opts, int index,
00325 const char *devname)
00326 {
00327
00328
00329 velocity_set_int_opt(&opts->rx_thresh, -1, RX_THRESH_MIN,
00330 RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh",
00331 devname);
00332 velocity_set_int_opt(&opts->DMA_length, DMA_length[index],
00333 DMA_LENGTH_MIN, DMA_LENGTH_MAX,
00334 DMA_LENGTH_DEF, "DMA_length", devname);
00335 velocity_set_int_opt(&opts->numrx, RxDescriptors[index],
00336 RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF,
00337 "RxDescriptors", devname);
00338 velocity_set_int_opt(&opts->numtx, TxDescriptors[index],
00339 TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF,
00340 "TxDescriptors", devname);
00341 velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN,
00342 VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting",
00343 devname);
00344 velocity_set_bool_opt(&opts->flags, enable_tagging[index],
00345 TAGGING_DEF, VELOCITY_FLAGS_TAGGING,
00346 "enable_tagging", devname);
00347 velocity_set_bool_opt(&opts->flags, txcsum_offload[index],
00348 TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM,
00349 "txcsum_offload", devname);
00350 velocity_set_int_opt(&opts->flow_cntl, flow_control[index],
00351 FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF,
00352 "flow_control", devname);
00353 velocity_set_bool_opt(&opts->flags, IP_byte_align[index],
00354 IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN,
00355 "IP_byte_align", devname);
00356 velocity_set_bool_opt(&opts->flags, ValPktLen[index],
00357 VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN,
00358 "ValPktLen", devname);
00359 velocity_set_int_opt((void *) &opts->spd_dpx, speed_duplex[index],
00360 MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF,
00361 "Media link mode", devname);
00362 velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index],
00363 WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF,
00364 "Wake On Lan options", devname);
00365 velocity_set_int_opt((int *) &opts->int_works, int_works[index],
00366 INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF,
00367 "Interrupt service works", devname);
00368 opts->numrx = (opts->numrx & ~3);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 static void velocity_init_cam_filter(struct velocity_info *vptr)
00380 {
00381 struct mac_regs *regs = vptr->mac_regs;
00382
00383
00384 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG);
00385 WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG);
00386
00387
00388 memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
00389 memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
00390 mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
00391 mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
00392
00393
00394 if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
00395
00396
00397 if (vptr->options.vid != 0)
00398 WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
00399
00400 mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid),
00401 VELOCITY_VLAN_ID_CAM);
00402 vptr->vCAMmask[0] |= 1;
00403 mac_set_cam_mask(regs, vptr->vCAMmask,
00404 VELOCITY_VLAN_ID_CAM);
00405 } else {
00406 u16 temp = 0;
00407 mac_set_cam(regs, 0, (u8 *) & temp, VELOCITY_VLAN_ID_CAM);
00408 temp = 1;
00409 mac_set_cam_mask(regs, (u8 *) & temp,
00410 VELOCITY_VLAN_ID_CAM);
00411 }
00412 }
00413
00414 static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
00415 {
00416 struct mac_regs *regs = vptr->mac_regs;
00417 int avail, dirty, unusable;
00418
00419
00420
00421
00422
00423 if (vptr->rd_filled < 4)
00424 return;
00425
00426 wmb();
00427
00428 unusable = vptr->rd_filled & 0x0003;
00429 dirty = vptr->rd_dirty - unusable;
00430 for (avail = vptr->rd_filled & 0xfffc; avail; avail--) {
00431 dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
00432
00433 vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC;
00434 }
00435
00436 writew(vptr->rd_filled & 0xfffc, ®s->RBRDU);
00437 vptr->rd_filled = unusable;
00438 }
00439
00440 static int velocity_rx_refill(struct velocity_info *vptr)
00441 {
00442 int dirty = vptr->rd_dirty, done = 0, ret = 0;
00443
00444
00445 do {
00446 struct rx_desc *rd = vptr->rd_ring + dirty;
00447
00448
00449 if (rd->rdesc0.owner == OWNED_BY_NIC)
00450 break;
00451
00452
00453 rd->inten = 1;
00454 rd->pa_high = 0;
00455 rd->rdesc0.len = cpu_to_le32(vptr->rx_buf_sz);;
00456
00457 done++;
00458 dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
00459 } while (dirty != vptr->rd_curr);
00460
00461 if (done) {
00462
00463 vptr->rd_dirty = dirty;
00464 vptr->rd_filled += done;
00465 velocity_give_many_rx_descs(vptr);
00466 }
00467
00468 return ret;
00469 }
00470
00471 extern void hex_dump(const char *data, const unsigned int len);
00472
00473
00474
00475 static int velocity_poll(struct nic *nic, int retrieve)
00476 {
00477
00478
00479
00480
00481 int rd_curr = vptr->rd_curr % RX_DESC_DEF;
00482 struct rx_desc *rd = &(vptr->rd_ring[rd_curr]);
00483
00484 if (rd->rdesc0.owner == OWNED_BY_NIC)
00485 return 0;
00486 rmb();
00487
00488 if ( ! retrieve ) return 1;
00489
00490
00491
00492
00493 if ((rd->rdesc0.RSR & RSR_RXOK)
00494 || (!(rd->rdesc0.RSR & RSR_RXOK)
00495 && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
00496
00497 nic->packetlen = rd->rdesc0.len;
00498
00499 memcpy(nic->packet, bus_to_virt(rd->pa_low),
00500 nic->packetlen - 4);
00501
00502 vptr->rd_curr++;
00503 vptr->rd_curr = vptr->rd_curr % RX_DESC_DEF;
00504 velocity_rx_refill(vptr);
00505 return 1;
00506 }
00507 return 0;
00508 }
00509
00510 #define TX_TIMEOUT (1000);
00511
00512
00513
00514 static void velocity_transmit(struct nic *nic, const char *dest,
00515 unsigned int type,
00516 unsigned int size,
00517 const char *packet)
00518 {
00519 u16 nstype;
00520 u32 to;
00521 u8 *ptxb;
00522 unsigned int pktlen;
00523 struct tx_desc *td_ptr;
00524
00525 int entry = vptr->td_curr % TX_DESC_DEF;
00526 td_ptr = &(vptr->td_rings[entry]);
00527
00528
00529 ptxb = vptr->txb + (entry * PKT_BUF_SZ);
00530 memcpy(ptxb, dest, ETH_ALEN);
00531 memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);
00532 nstype = htons((u16) type);
00533 memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
00534 memcpy(ptxb + ETH_HLEN, packet, size);
00535
00536 td_ptr->tdesc1.TCPLS = TCPLS_NORMAL;
00537 td_ptr->tdesc1.TCR = TCR0_TIC;
00538 td_ptr->td_buf[0].queue = 0;
00539
00540 size += ETH_HLEN;
00541 while (size < ETH_ZLEN)
00542 ptxb[size++] = '\0';
00543
00544 if (size < ETH_ZLEN) {
00545
00546 pktlen = ETH_ZLEN;
00547
00548 memset(ptxb + size, 0, ETH_ZLEN - size);
00549
00550 vptr->td_rings[entry].tdesc0.pktsize = pktlen;
00551 vptr->td_rings[entry].td_buf[0].pa_low = virt_to_bus(ptxb);
00552 vptr->td_rings[entry].td_buf[0].pa_high &=
00553 cpu_to_le32(0xffff0000UL);
00554 vptr->td_rings[entry].td_buf[0].bufsize =
00555 vptr->td_rings[entry].tdesc0.pktsize;
00556 vptr->td_rings[entry].tdesc1.CMDZ = 2;
00557 } else {
00558
00559 td_ptr->tdesc0.pktsize = size;
00560 td_ptr->td_buf[0].pa_low = virt_to_bus(ptxb);
00561 td_ptr->td_buf[0].pa_high = 0;
00562 td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
00563
00564 td_ptr->tdesc1.CMDZ = 2;
00565 }
00566
00567 if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
00568 td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
00569 td_ptr->tdesc1.pqinf.priority = 0;
00570 td_ptr->tdesc1.pqinf.CFI = 0;
00571 td_ptr->tdesc1.TCR |= TCR0_VETAG;
00572 }
00573
00574 vptr->td_curr = (entry + 1);
00575
00576 {
00577
00578 int prev = entry - 1;
00579
00580 if (prev < 0)
00581 prev = TX_DESC_DEF - 1;
00582 td_ptr->tdesc0.owner |= OWNED_BY_NIC;
00583 td_ptr = &(vptr->td_rings[prev]);
00584 td_ptr->td_buf[0].queue = 1;
00585 mac_tx_queue_wake(vptr->mac_regs, 0);
00586
00587 }
00588
00589 to = currticks() + TX_TIMEOUT;
00590 while ((td_ptr->tdesc0.owner & OWNED_BY_NIC) && (currticks() < to));
00591
00592 if (currticks() >= to) {
00593 printf("TX Time Out");
00594 }
00595
00596 }
00597
00598
00599
00600
00601 static void velocity_disable(struct nic *nic __unused)
00602 {
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 struct mac_regs *regs = vptr->mac_regs;
00614 mac_disable_int(regs);
00615 writel(CR0_STOP, ®s->CR0Set);
00616 writew(0xFFFF, ®s->TDCSRClr);
00617 writeb(0xFF, ®s->RDCSRClr);
00618 safe_disable_mii_autopoll(regs);
00619 mac_clear_isr(regs);
00620
00621
00622
00623
00624 vptr->flags &= (~VELOCITY_FLAGS_OPENED);
00625 }
00626
00627
00628
00629
00630 static void velocity_irq(struct nic *nic __unused, irq_action_t action)
00631 {
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 switch (action) {
00643 case DISABLE:
00644 case ENABLE:
00645
00646
00647
00648
00649
00650 break;
00651 case FORCE:
00652
00653
00654
00655
00656 break;
00657 }
00658 }
00659
00660 static struct nic_operations velocity_operations = {
00661 .connect = dummy_connect,
00662 .poll = velocity_poll,
00663 .transmit = velocity_transmit,
00664 .irq = velocity_irq,
00665 };
00666
00667
00668
00669
00670 static int velocity_probe( struct nic *nic, struct pci_device *pci)
00671 {
00672 int ret, i;
00673 struct mac_regs *regs;
00674
00675 printf("via-velocity.c: Found %s Vendor=0x%hX Device=0x%hX\n",
00676 pci->driver_name, pci->vendor, pci->device);
00677
00678
00679 vptr = &vptx;
00680 info = chip_info_table;
00681
00682 velocity_init_info(pci, vptr, info);
00683
00684
00685
00686
00687 ret = velocity_get_pci_info(vptr, pci);
00688 if (ret < 0) {
00689 printf("Failed to find PCI device.\n");
00690 return 0;
00691 }
00692
00693 regs = ioremap(vptr->memaddr, vptr->io_size);
00694 if (regs == NULL) {
00695 printf("Unable to remap io\n");
00696 return 0;
00697 }
00698
00699 vptr->mac_regs = regs;
00700
00701 BASE = vptr->ioaddr;
00702
00703 printf("Chip ID: %hX\n", vptr->chip_id);
00704
00705 for (i = 0; i < 6; i++)
00706 nic->node_addr[i] = readb(®s->PAR[i]);
00707
00708 DBG ( "%s: %s at ioaddr %#hX\n", pci->driver_name, eth_ntoa ( nic->node_addr ),
00709 (unsigned int) BASE );
00710
00711 velocity_get_options(&vptr->options, 0, pci->driver_name);
00712
00713
00714
00715
00716 vptr->options.flags &= 0x00FFFFFFUL;
00717
00718
00719
00720
00721
00722 vptr->flags =
00723 vptr->options.
00724 flags | (0x00FFFFFFUL & 0xFF000000UL);
00725
00726 vptr->wol_opts = vptr->options.wol_opts;
00727 vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
00728
00729 vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
00730
00731 if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
00732 printf("features missing\n");
00733 }
00734
00735
00736
00737
00738 check_connection_type(vptr->mac_regs);
00739 velocity_open(nic, pci);
00740
00741
00742 nic->nic_op = &velocity_operations;
00743 return 1;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 static void velocity_init_info(struct pci_device *pdev,
00759 struct velocity_info *vptr,
00760 struct velocity_info_tbl *info)
00761 {
00762 memset(vptr, 0, sizeof(struct velocity_info));
00763
00764 vptr->pdev = pdev;
00765 vptr->chip_id = info->chip_id;
00766 vptr->io_size = info->io_size;
00767 vptr->num_txq = info->txqueue;
00768 vptr->multicast_limit = MCAM_SIZE;
00769
00770 printf
00771 ("chip_id: 0x%hX, io_size: %d, num_txq %d, multicast_limit: %d\n",
00772 vptr->chip_id, (unsigned int) vptr->io_size, vptr->num_txq,
00773 vptr->multicast_limit);
00774 printf("Name: %s\n", info->name);
00775
00776
00777
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 #define IORESOURCE_IO 0x00000100
00790 #define IORESOURCE_PREFETCH 0x00001000
00791
00792 #define IORESOURCE_MEM 0x00000200
00793 #define BAR_0 0
00794 #define BAR_1 1
00795 #define BAR_5 5
00796 #define PCI_BASE_ADDRESS_SPACE 0x01
00797 #define PCI_BASE_ADDRESS_SPACE_IO 0x01
00798 #define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
00799 #define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
00800 #define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00
00801 #define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02
00802 #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04
00803 #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08
00804
00805
00806
00807 unsigned long pci_resource_flags(struct pci_device *pdev, unsigned int bar)
00808 {
00809 uint32_t l, sz;
00810 unsigned long flags = 0;
00811
00812 pci_read_config_dword(pdev, bar, &l);
00813 pci_write_config_dword(pdev, bar, ~0);
00814 pci_read_config_dword(pdev, bar, &sz);
00815 pci_write_config_dword(pdev, bar, l);
00816
00817 if (!sz || sz == 0xffffffff)
00818 printf("Weird size\n");
00819 if (l == 0xffffffff)
00820 l = 0;
00821 if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
00822
00823
00824
00825
00826 flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
00827 printf("Memory Resource\n");
00828 } else {
00829
00830
00831
00832
00833 flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
00834 printf("I/O Resource\n");
00835 }
00836 if (flags & PCI_BASE_ADDRESS_SPACE_IO) {
00837 printf("Why is it here\n");
00838 flags |= IORESOURCE_IO;
00839 } else {
00840 printf("here\n");
00841
00842 }
00843
00844
00845 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
00846 flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
00847
00848
00849 return flags;
00850 }
00851 static int velocity_get_pci_info(struct velocity_info *vptr,
00852 struct pci_device *pdev)
00853 {
00854 if (pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0) {
00855 printf("DEBUG: pci_read_config_byte failed\n");
00856 return -1;
00857 }
00858
00859 adjust_pci_device(pdev);
00860
00861 vptr->ioaddr = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
00862 vptr->memaddr = pci_bar_start(pdev, PCI_BASE_ADDRESS_1);
00863
00864 printf("Looking for I/O Resource - Found:");
00865 if (!
00866 (pci_resource_flags(pdev, PCI_BASE_ADDRESS_0) & IORESOURCE_IO))
00867 {
00868 printf
00869 ("DEBUG: region #0 is not an I/O resource, aborting.\n");
00870 return -1;
00871 }
00872
00873 printf("Looking for Memory Resource - Found:");
00874 if ((pci_resource_flags(pdev, PCI_BASE_ADDRESS_1) & IORESOURCE_IO)) {
00875 printf("DEBUG: region #1 is an I/O resource, aborting.\n");
00876 return -1;
00877 }
00878
00879 if (pci_bar_size(pdev, PCI_BASE_ADDRESS_1) < 256) {
00880 printf("DEBUG: region #1 is too small.\n");
00881 return -1;
00882 }
00883 vptr->pdev = pdev;
00884
00885 return 0;
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 static void velocity_print_link_status(struct velocity_info *vptr)
00898 {
00899
00900 if (vptr->mii_status & VELOCITY_LINK_FAIL) {
00901 printf("failed to detect cable link\n");
00902 } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
00903 printf("Link autonegation");
00904
00905 if (vptr->mii_status & VELOCITY_SPEED_1000)
00906 printf(" speed 1000M bps");
00907 else if (vptr->mii_status & VELOCITY_SPEED_100)
00908 printf(" speed 100M bps");
00909 else
00910 printf(" speed 10M bps");
00911
00912 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
00913 printf(" full duplex\n");
00914 else
00915 printf(" half duplex\n");
00916 } else {
00917 printf("Link forced");
00918 switch (vptr->options.spd_dpx) {
00919 case SPD_DPX_100_HALF:
00920 printf(" speed 100M bps half duplex\n");
00921 break;
00922 case SPD_DPX_100_FULL:
00923 printf(" speed 100M bps full duplex\n");
00924 break;
00925 case SPD_DPX_10_HALF:
00926 printf(" speed 10M bps half duplex\n");
00927 break;
00928 case SPD_DPX_10_FULL:
00929 printf(" speed 10M bps full duplex\n");
00930 break;
00931 default:
00932 break;
00933 }
00934 }
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 static void velocity_rx_reset(struct velocity_info *vptr)
00946 {
00947
00948 struct mac_regs *regs = vptr->mac_regs;
00949 int i;
00950
00951
00952
00953
00954
00955
00956 for (i = 0; i < vptr->options.numrx; ++i)
00957 vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC;
00958
00959 writew(RX_DESC_DEF, ®s->RBRDU);
00960 writel(virt_to_le32desc(vptr->rd_ring), ®s->RDBaseLo);
00961 writew(0, ®s->RDIdx);
00962 writew(RX_DESC_DEF - 1, ®s->RDCSize);
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 static void velocity_init_registers(struct nic *nic,
00975 struct velocity_info *vptr,
00976 enum velocity_init_type type)
00977 {
00978 struct mac_regs *regs = vptr->mac_regs;
00979 int i, mii_status;
00980
00981 mac_wol_reset(regs);
00982
00983 switch (type) {
00984 case VELOCITY_INIT_RESET:
00985 case VELOCITY_INIT_WOL:
00986
00987
00988
00989
00990
00991
00992 velocity_rx_reset(vptr);
00993 mac_rx_queue_run(regs);
00994 mac_rx_queue_wake(regs);
00995
00996 mii_status = velocity_get_opt_media_mode(vptr);
00997
00998 if (velocity_set_media_mode(vptr, mii_status) !=
00999 VELOCITY_LINK_CHANGE) {
01000 velocity_print_link_status(vptr);
01001 if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
01002 printf("Link Failed\n");
01003
01004 }
01005
01006 enable_flow_control_ability(vptr);
01007
01008 mac_clear_isr(regs);
01009 writel(CR0_STOP, ®s->CR0Clr);
01010
01011 writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
01012 ®s->CR0Set);
01013 break;
01014
01015 case VELOCITY_INIT_COLD:
01016 default:
01017
01018
01019
01020 velocity_soft_reset(vptr);
01021 mdelay(5);
01022
01023 mac_eeprom_reload(regs);
01024 for (i = 0; i < 6; i++) {
01025 writeb(nic->node_addr[i], &(regs->PAR[i]));
01026 }
01027
01028
01029
01030 BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
01031 mac_set_rx_thresh(regs, vptr->options.rx_thresh);
01032 mac_set_dma_length(regs, vptr->options.DMA_length);
01033
01034 writeb(WOLCFG_SAM | WOLCFG_SAB, ®s->WOLCFGSet);
01035
01036
01037
01038 BYTE_REG_BITS_SET(CFGB_OFSET,
01039 (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA |
01040 CFGB_BAKOPT), ®s->CFGB);
01041
01042
01043
01044
01045 velocity_init_cam_filter(vptr);
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 enable_mii_autopoll(regs);
01056
01057 vptr->int_mask = INT_MASK_DEF;
01058
01059 writel(virt_to_le32desc(vptr->rd_ring), ®s->RDBaseLo);
01060 writew(vptr->options.numrx - 1, ®s->RDCSize);
01061 mac_rx_queue_run(regs);
01062 mac_rx_queue_wake(regs);
01063
01064 writew(vptr->options.numtx - 1, ®s->TDCSize);
01065
01066
01067 writel(virt_to_le32desc(vptr->td_rings),
01068 &(regs->TDBaseLo[0]));
01069 mac_tx_queue_run(regs, 0);
01070
01071
01072 init_flow_control_register(vptr);
01073
01074 writel(CR0_STOP, ®s->CR0Clr);
01075 writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
01076 ®s->CR0Set);
01077
01078 mii_status = velocity_get_opt_media_mode(vptr);
01079
01080
01081 mii_init(vptr, mii_status);
01082
01083 if (velocity_set_media_mode(vptr, mii_status) !=
01084 VELOCITY_LINK_CHANGE) {
01085 velocity_print_link_status(vptr);
01086 if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
01087 printf("Link Faaailll\n");
01088
01089 }
01090
01091 enable_flow_control_ability(vptr);
01092 mac_hw_mibs_init(regs);
01093 mac_write_int_mask(vptr->int_mask, regs);
01094 mac_clear_isr(regs);
01095
01096
01097 }
01098 velocity_print_link_status(vptr);
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 static int velocity_soft_reset(struct velocity_info *vptr)
01110 {
01111 struct mac_regs *regs = vptr->mac_regs;
01112 unsigned int i = 0;
01113
01114 writel(CR0_SFRST, ®s->CR0Set);
01115
01116 for (i = 0; i < W_MAX_TIMEOUT; i++) {
01117 udelay(5);
01118 if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, ®s->CR0Set))
01119 break;
01120 }
01121
01122 if (i == W_MAX_TIMEOUT) {
01123 writel(CR0_FORSRST, ®s->CR0Set);
01124
01125
01126 mdelay(2);
01127 }
01128 return 0;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 static int velocity_init_rings(struct velocity_info *vptr)
01140 {
01141
01142 int idx;
01143
01144 vptr->rd_curr = 0;
01145 vptr->td_curr = 0;
01146 memset(vptr->td_rings, 0, TX_DESC_DEF * sizeof(struct tx_desc));
01147 memset(vptr->rd_ring, 0, RX_DESC_DEF * sizeof(struct rx_desc));
01148
01149
01150
01151 for (idx = 0; idx < RX_DESC_DEF; idx++) {
01152 vptr->rd_ring[idx].rdesc0.RSR = 0;
01153 vptr->rd_ring[idx].rdesc0.len = 0;
01154 vptr->rd_ring[idx].rdesc0.reserved = 0;
01155 vptr->rd_ring[idx].rdesc0.owner = 0;
01156 vptr->rd_ring[idx].len = cpu_to_le32(vptr->rx_buf_sz);
01157 vptr->rd_ring[idx].inten = 1;
01158 vptr->rd_ring[idx].pa_low =
01159 virt_to_bus(vptr->rxb + (RX_DESC_DEF * idx));
01160 vptr->rd_ring[idx].pa_high = 0;
01161 vptr->rd_ring[idx].rdesc0.owner = OWNED_BY_NIC;
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176 return 0;
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 #define PCI_BYTE_REG_BITS_ON(x,i,p) do{\
01191 u8 byReg;\
01192 pci_read_config_byte((p), (i), &(byReg));\
01193 (byReg) |= (x);\
01194 pci_write_config_byte((p), (i), (byReg));\
01195 } while (0)
01196
01197
01198
01199
01200 #define PCI_REG_COMMAND 0x04 //
01201 #define PCI_REG_MODE0 0x60 //
01202 #define PCI_REG_MODE1 0x61 //
01203 #define PCI_REG_MODE2 0x62 //
01204 #define PCI_REG_MODE3 0x63 //
01205 #define PCI_REG_DELAY_TIMER 0x64 //
01206
01207
01208
01209 #define MODE2_PCEROPT 0x80 // take PCI bus ERror as a fatal and shutdown from software control
01210 #define MODE2_TXQ16 0x40 // TX write-back Queue control. 0->32 entries available in Tx write-back queue, 1->16 entries
01211 #define MODE2_TXPOST 0x08 // (Not support in VT3119)
01212 #define MODE2_AUTOOPT 0x04 // (VT3119 GHCI without such behavior)
01213 #define MODE2_MODE10T 0x02 // used to control tx Threshold for 10M case
01214 #define MODE2_TCPLSOPT 0x01 // TCP large send field update disable, hardware will not update related fields, leave it to software.
01215
01216
01217
01218
01219 #define MODE3_MIION 0x04 // MII symbol codine error detect enable ??
01220
01221
01222 #define COMMAND_BUSM 0x04
01223 #define COMMAND_WAIT 0x80
01224 static int velocity_open(struct nic *nic, struct pci_device *pci __unused)
01225 {
01226 int ret;
01227
01228 u8 diff;
01229 u32 TxPhyAddr, RxPhyAddr;
01230 u32 TxBufPhyAddr, RxBufPhyAddr;
01231 vptr->TxDescArrays = tx_ring;
01232 if (vptr->TxDescArrays == 0)
01233 printf("Allot Error");
01234
01235
01236 TxPhyAddr = virt_to_bus(vptr->TxDescArrays);
01237 printf("Unaligned Address : %X\n", TxPhyAddr);
01238 diff = 64 - (TxPhyAddr - ((TxPhyAddr >> 6) << 6));
01239 TxPhyAddr += diff;
01240 vptr->td_rings = (struct tx_desc *) (vptr->TxDescArrays + diff);
01241
01242 printf("Aligned Address: %lX\n", virt_to_bus(vptr->td_rings));
01243 vptr->tx_buffs = txb;
01244
01245 TxBufPhyAddr = virt_to_bus(vptr->tx_buffs);
01246 diff = 64 - (TxBufPhyAddr - ((TxBufPhyAddr >> 6) << 6));
01247 TxBufPhyAddr += diff;
01248 vptr->txb = (unsigned char *) (vptr->tx_buffs + diff);
01249
01250 vptr->RxDescArrays = rx_ring;
01251
01252 RxPhyAddr = virt_to_bus(vptr->RxDescArrays);
01253 diff = 64 - (RxPhyAddr - ((RxPhyAddr >> 6) << 6));
01254 RxPhyAddr += diff;
01255 vptr->rd_ring = (struct rx_desc *) (vptr->RxDescArrays + diff);
01256
01257 vptr->rx_buffs = rxb;
01258
01259 RxBufPhyAddr = virt_to_bus(vptr->rx_buffs);
01260 diff = 64 - (RxBufPhyAddr - ((RxBufPhyAddr >> 6) << 6));
01261 RxBufPhyAddr += diff;
01262 vptr->rxb = (unsigned char *) (vptr->rx_buffs + diff);
01263
01264 if (vptr->RxDescArrays == NULL || vptr->RxDescArrays == NULL) {
01265 printf("Allocate tx_ring or rd_ring failed\n");
01266 return 0;
01267 }
01268
01269 vptr->rx_buf_sz = PKT_BUF_SZ;
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 ret = velocity_init_rings(vptr);
01280
01281
01282
01283
01284 velocity_init_registers(nic, vptr, VELOCITY_INIT_COLD);
01285 mac_write_int_mask(0, vptr->mac_regs);
01286
01287
01288
01289 vptr->flags |= VELOCITY_FLAGS_OPENED;
01290 return 1;
01291
01292 }
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 static void mii_init(struct velocity_info *vptr, u32 mii_status __unused)
01308 {
01309 u16 BMCR;
01310
01311 switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
01312 case PHYID_CICADA_CS8201:
01313
01314
01315
01316 MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
01317 vptr->mac_regs);
01318
01319
01320
01321
01322
01323 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
01324 MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR,
01325 vptr->mac_regs);
01326 else
01327 MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR,
01328 vptr->mac_regs);
01329
01330
01331
01332 MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs);
01333 break;
01334 case PHYID_VT3216_32BIT:
01335 case PHYID_VT3216_64BIT:
01336
01337
01338
01339 MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
01340 vptr->mac_regs);
01341
01342
01343
01344
01345
01346 if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
01347 MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR,
01348 vptr->mac_regs);
01349 else
01350 MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR,
01351 vptr->mac_regs);
01352 break;
01353
01354 case PHYID_MARVELL_1000:
01355 case PHYID_MARVELL_1000S:
01356
01357
01358
01359 MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
01360
01361
01362
01363 MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR,
01364 vptr->mac_regs);
01365 break;
01366 default:
01367 ;
01368 }
01369 velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR);
01370 if (BMCR & BMCR_ISO) {
01371 BMCR &= ~BMCR_ISO;
01372 velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR);
01373 }
01374 }
01375
01376
01377
01378
01379
01380
01381
01382
01383 static void safe_disable_mii_autopoll(struct mac_regs *regs)
01384 {
01385 u16 ww;
01386
01387
01388 writeb(0, ®s->MIICR);
01389 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
01390 udelay(1);
01391 if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR))
01392 break;
01393 }
01394 }
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404 static void enable_mii_autopoll(struct mac_regs *regs)
01405 {
01406 unsigned int ii;
01407
01408 writeb(0, &(regs->MIICR));
01409 writeb(MIIADR_SWMPL, ®s->MIIADR);
01410
01411 for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
01412 udelay(1);
01413 if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR))
01414 break;
01415 }
01416
01417 writeb(MIICR_MAUTO, ®s->MIICR);
01418
01419 for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
01420 udelay(1);
01421 if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR))
01422 break;
01423 }
01424
01425 }
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437 static int velocity_mii_read(struct mac_regs *regs, u8 index, u16 * data)
01438 {
01439 u16 ww;
01440
01441
01442
01443
01444 safe_disable_mii_autopoll(regs);
01445
01446 writeb(index, ®s->MIIADR);
01447
01448 BYTE_REG_BITS_ON(MIICR_RCMD, ®s->MIICR);
01449
01450 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
01451 if (!(readb(®s->MIICR) & MIICR_RCMD))
01452 break;
01453 }
01454
01455 *data = readw(®s->MIIDATA);
01456
01457 enable_mii_autopoll(regs);
01458 if (ww == W_MAX_TIMEOUT)
01459 return -1;
01460 return 0;
01461 }
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 static int velocity_mii_write(struct mac_regs *regs, u8 mii_addr, u16 data)
01474 {
01475 u16 ww;
01476
01477
01478
01479
01480 safe_disable_mii_autopoll(regs);
01481
01482
01483 writeb(mii_addr, ®s->MIIADR);
01484
01485 writew(data, ®s->MIIDATA);
01486
01487
01488 BYTE_REG_BITS_ON(MIICR_WCMD, ®s->MIICR);
01489
01490
01491 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
01492 udelay(5);
01493 if (!(readb(®s->MIICR) & MIICR_WCMD))
01494 break;
01495 }
01496 enable_mii_autopoll(regs);
01497
01498 if (ww == W_MAX_TIMEOUT)
01499 return -1;
01500 return 0;
01501 }
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
01513 {
01514 u32 status = 0;
01515
01516 switch (vptr->options.spd_dpx) {
01517 case SPD_DPX_AUTO:
01518 status = VELOCITY_AUTONEG_ENABLE;
01519 break;
01520 case SPD_DPX_100_FULL:
01521 status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
01522 break;
01523 case SPD_DPX_10_FULL:
01524 status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
01525 break;
01526 case SPD_DPX_100_HALF:
01527 status = VELOCITY_SPEED_100;
01528 break;
01529 case SPD_DPX_10_HALF:
01530 status = VELOCITY_SPEED_10;
01531 break;
01532 }
01533 vptr->mii_status = status;
01534 return status;
01535 }
01536
01537
01538
01539
01540
01541
01542
01543
01544 static void mii_set_auto_on(struct velocity_info *vptr)
01545 {
01546 if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
01547 MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
01548 else
01549 MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
01550 }
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568 static void set_mii_flow_control(struct velocity_info *vptr)
01569 {
01570
01571 switch (vptr->options.flow_cntl) {
01572 case FLOW_CNTL_TX:
01573 MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
01574 MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
01575 break;
01576
01577 case FLOW_CNTL_RX:
01578 MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
01579 MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
01580 break;
01581
01582 case FLOW_CNTL_TX_RX:
01583 MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
01584 MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
01585 break;
01586
01587 case FLOW_CNTL_DISABLE:
01588 MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
01589 MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR,
01590 vptr->mac_regs);
01591 break;
01592 default:
01593 break;
01594 }
01595 }
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606 static int velocity_set_media_mode(struct velocity_info *vptr,
01607 u32 mii_status)
01608 {
01609 u32 curr_status;
01610 struct mac_regs *regs = vptr->mac_regs;
01611
01612 vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
01613 curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
01614
01615
01616 set_mii_flow_control(vptr);
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) {
01630 MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR,
01631 vptr->mac_regs);
01632 }
01633
01634
01635
01636
01637 if (mii_status & VELOCITY_AUTONEG_ENABLE) {
01638 printf("Velocity is AUTO mode\n");
01639
01640 BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR);
01641
01642 MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10,
01643 MII_REG_ANAR, vptr->mac_regs);
01644 MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000,
01645 MII_REG_G1000CR, vptr->mac_regs);
01646 MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR,
01647 vptr->mac_regs);
01648
01649
01650 mii_set_auto_on(vptr);
01651 } else {
01652 u16 ANAR;
01653 u8 CHIPGCR;
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663 BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR);
01664
01665 CHIPGCR = readb(®s->CHIPGCR);
01666 CHIPGCR &= ~CHIPGCR_FCGMII;
01667
01668 if (mii_status & VELOCITY_DUPLEX_FULL) {
01669 CHIPGCR |= CHIPGCR_FCFDX;
01670 writeb(CHIPGCR, ®s->CHIPGCR);
01671 printf
01672 ("DEBUG: set Velocity to forced full mode\n");
01673 if (vptr->rev_id < REV_ID_VT3216_A0)
01674 BYTE_REG_BITS_OFF(TCR_TB2BDIS, ®s->TCR);
01675 } else {
01676 CHIPGCR &= ~CHIPGCR_FCFDX;
01677 printf
01678 ("DEBUG: set Velocity to forced half mode\n");
01679 writeb(CHIPGCR, ®s->CHIPGCR);
01680 if (vptr->rev_id < REV_ID_VT3216_A0)
01681 BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR);
01682 }
01683
01684 MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000,
01685 MII_REG_G1000CR, vptr->mac_regs);
01686
01687 if (!(mii_status & VELOCITY_DUPLEX_FULL)
01688 && (mii_status & VELOCITY_SPEED_10)) {
01689 BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG);
01690 } else {
01691 BYTE_REG_BITS_ON(TESTCFG_HBDIS, ®s->TESTCFG);
01692 }
01693
01694 velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR);
01695 ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10));
01696 if (mii_status & VELOCITY_SPEED_100) {
01697 if (mii_status & VELOCITY_DUPLEX_FULL)
01698 ANAR |= ANAR_TXFD;
01699 else
01700 ANAR |= ANAR_TX;
01701 } else {
01702 if (mii_status & VELOCITY_DUPLEX_FULL)
01703 ANAR |= ANAR_10FD;
01704 else
01705 ANAR |= ANAR_10;
01706 }
01707 velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR);
01708
01709 mii_set_auto_on(vptr);
01710
01711 }
01712
01713
01714 return VELOCITY_LINK_CHANGE;
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 static u32 mii_check_media_mode(struct mac_regs *regs)
01726 {
01727 u32 status = 0;
01728 u16 ANAR;
01729
01730 if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs))
01731 status |= VELOCITY_LINK_FAIL;
01732
01733 if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs))
01734 status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
01735 else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs))
01736 status |= (VELOCITY_SPEED_1000);
01737 else {
01738 velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
01739 if (ANAR & ANAR_TXFD)
01740 status |=
01741 (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
01742 else if (ANAR & ANAR_TX)
01743 status |= VELOCITY_SPEED_100;
01744 else if (ANAR & ANAR_10FD)
01745 status |=
01746 (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
01747 else
01748 status |= (VELOCITY_SPEED_10);
01749 }
01750
01751 if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
01752 velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
01753 if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
01754 == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
01755 if (MII_REG_BITS_IS_ON
01756 (G1000CR_1000 | G1000CR_1000FD,
01757 MII_REG_G1000CR, regs))
01758 status |= VELOCITY_AUTONEG_ENABLE;
01759 }
01760 }
01761
01762 return status;
01763 }
01764
01765 static u32 check_connection_type(struct mac_regs *regs)
01766 {
01767 u32 status = 0;
01768 u8 PHYSR0;
01769 u16 ANAR;
01770 PHYSR0 = readb(®s->PHYSR0);
01771
01772
01773
01774
01775
01776
01777 if (PHYSR0 & PHYSR0_FDPX)
01778 status |= VELOCITY_DUPLEX_FULL;
01779
01780 if (PHYSR0 & PHYSR0_SPDG)
01781 status |= VELOCITY_SPEED_1000;
01782 if (PHYSR0 & PHYSR0_SPD10)
01783 status |= VELOCITY_SPEED_10;
01784 else
01785 status |= VELOCITY_SPEED_100;
01786
01787 if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
01788 velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
01789 if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
01790 == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
01791 if (MII_REG_BITS_IS_ON
01792 (G1000CR_1000 | G1000CR_1000FD,
01793 MII_REG_G1000CR, regs))
01794 status |= VELOCITY_AUTONEG_ENABLE;
01795 }
01796 }
01797
01798 return status;
01799 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 static void enable_flow_control_ability(struct velocity_info *vptr)
01810 {
01811
01812 struct mac_regs *regs = vptr->mac_regs;
01813
01814 switch (vptr->options.flow_cntl) {
01815
01816 case FLOW_CNTL_DEFAULT:
01817 if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, ®s->PHYSR0))
01818 writel(CR0_FDXRFCEN, ®s->CR0Set);
01819 else
01820 writel(CR0_FDXRFCEN, ®s->CR0Clr);
01821
01822 if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, ®s->PHYSR0))
01823 writel(CR0_FDXTFCEN, ®s->CR0Set);
01824 else
01825 writel(CR0_FDXTFCEN, ®s->CR0Clr);
01826 break;
01827
01828 case FLOW_CNTL_TX:
01829 writel(CR0_FDXTFCEN, ®s->CR0Set);
01830 writel(CR0_FDXRFCEN, ®s->CR0Clr);
01831 break;
01832
01833 case FLOW_CNTL_RX:
01834 writel(CR0_FDXRFCEN, ®s->CR0Set);
01835 writel(CR0_FDXTFCEN, ®s->CR0Clr);
01836 break;
01837
01838 case FLOW_CNTL_TX_RX:
01839 writel(CR0_FDXTFCEN, ®s->CR0Set);
01840 writel(CR0_FDXRFCEN, ®s->CR0Set);
01841 break;
01842
01843 case FLOW_CNTL_DISABLE:
01844 writel(CR0_FDXRFCEN, ®s->CR0Clr);
01845 writel(CR0_FDXTFCEN, ®s->CR0Clr);
01846 break;
01847
01848 default:
01849 break;
01850 }
01851
01852 }
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 int pci_set_power_state(struct pci_device *dev, int state)
01871 {
01872 int pm;
01873 u16 pmcsr;
01874 int current_state = 0;
01875
01876
01877 if (state > 3)
01878 state = 3;
01879
01880
01881
01882
01883
01884 if (state > 0 && current_state > state)
01885 return -1;
01886 else if (current_state == state)
01887 return 0;
01888
01889
01890 pm = pci_find_capability(dev, PCI_CAP_ID_PM);
01891
01892
01893 if (!pm)
01894 return -2;
01895
01896
01897 if (state == 1 || state == 2) {
01898 u16 pmc;
01899 pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
01900 if (state == 1 && !(pmc & PCI_PM_CAP_D1))
01901 return -2;
01902 else if (state == 2 && !(pmc & PCI_PM_CAP_D2))
01903 return -2;
01904 }
01905
01906
01907
01908
01909
01910 if (current_state >= 3)
01911 pmcsr = 0;
01912 else {
01913 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
01914 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
01915 pmcsr |= state;
01916 }
01917
01918
01919 pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
01920
01921
01922
01923 if (state == 3 || current_state == 3)
01924 mdelay(10);
01925 else if (state == 2 || current_state == 2)
01926 udelay(200);
01927 current_state = state;
01928
01929 return 0;
01930 }
01931
01932 static struct pci_device_id velocity_nics[] = {
01933 PCI_ROM(0x1106, 0x3119, "via-velocity", "VIA Networking Velocity Family Gigabit Ethernet Adapter", 0),
01934 };
01935
01936 PCI_DRIVER ( velocity_driver, velocity_nics, PCI_NO_CLASS );
01937
01938 DRIVER ( "VIA-VELOCITY/PCI", nic_driver, pci_driver, velocity_driver,
01939 velocity_probe, velocity_disable );