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 FILE_LICENCE ( GPL2_OR_LATER );
00039
00040
00041 #include "etherboot.h"
00042
00043 #include "nic.h"
00044
00045 #include <gpxe/pci.h>
00046
00047 #if ARCH == ia64
00048 #define USE_64BIT_ADDR
00049 #endif
00050
00051
00052 #ifdef DDEBUG
00053 #define dprintf(x) printf x
00054 #else
00055 #define dprintf(x)
00056 #endif
00057
00058 #define HZ 100
00059
00060
00061 #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
00062 #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
00063
00064
00065
00066
00067
00068 static int reset_phy = 0;
00069 static int lnksts = 0;
00070
00071 #if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
00072 #define USE_64BIT_ADDR "+"
00073 #endif
00074
00075 #if defined(USE_64BIT_ADDR)
00076 #define TRY_DAC 1
00077 #else
00078 #define TRY_DAC 0
00079 #endif
00080
00081
00082 #define RX_BUF_SIZE 1500
00083
00084
00085 #define NR_RX_DESC 64
00086 #define NR_TX_DESC 1
00087
00088
00089 #define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14 + 6)
00090
00091 #define MIN_TX_DESC_FREE 8
00092
00093
00094 #define CFGCS 0x04
00095
00096 #define CR_TXE 0x00000001
00097 #define CR_TXD 0x00000002
00098
00099
00100
00101 #define CR_RXE 0x00000004
00102 #define CR_RXD 0x00000008
00103 #define CR_TXR 0x00000010
00104 #define CR_RXR 0x00000020
00105 #define CR_SWI 0x00000080
00106 #define CR_RST 0x00000100
00107
00108 #define PTSCR_EEBIST_FAIL 0x00000001
00109 #define PTSCR_EEBIST_EN 0x00000002
00110 #define PTSCR_EELOAD_EN 0x00000004
00111 #define PTSCR_RBIST_FAIL 0x000001b8
00112 #define PTSCR_RBIST_DONE 0x00000200
00113 #define PTSCR_RBIST_EN 0x00000400
00114 #define PTSCR_RBIST_RST 0x00002000
00115
00116 #define MEAR_EEDI 0x00000001
00117 #define MEAR_EEDO 0x00000002
00118 #define MEAR_EECLK 0x00000004
00119 #define MEAR_EESEL 0x00000008
00120 #define MEAR_MDIO 0x00000010
00121 #define MEAR_MDDIR 0x00000020
00122 #define MEAR_MDC 0x00000040
00123
00124 #define ISR_TXDESC3 0x40000000
00125 #define ISR_TXDESC2 0x20000000
00126 #define ISR_TXDESC1 0x10000000
00127 #define ISR_TXDESC0 0x08000000
00128 #define ISR_RXDESC3 0x04000000
00129 #define ISR_RXDESC2 0x02000000
00130 #define ISR_RXDESC1 0x01000000
00131 #define ISR_RXDESC0 0x00800000
00132 #define ISR_TXRCMP 0x00400000
00133 #define ISR_RXRCMP 0x00200000
00134 #define ISR_DPERR 0x00100000
00135 #define ISR_SSERR 0x00080000
00136 #define ISR_RMABT 0x00040000
00137 #define ISR_RTABT 0x00020000
00138 #define ISR_RXSOVR 0x00010000
00139 #define ISR_HIBINT 0x00008000
00140 #define ISR_PHY 0x00004000
00141 #define ISR_PME 0x00002000
00142 #define ISR_SWI 0x00001000
00143 #define ISR_MIB 0x00000800
00144 #define ISR_TXURN 0x00000400
00145 #define ISR_TXIDLE 0x00000200
00146 #define ISR_TXERR 0x00000100
00147 #define ISR_TXDESC 0x00000080
00148 #define ISR_TXOK 0x00000040
00149 #define ISR_RXORN 0x00000020
00150 #define ISR_RXIDLE 0x00000010
00151 #define ISR_RXEARLY 0x00000008
00152 #define ISR_RXERR 0x00000004
00153 #define ISR_RXDESC 0x00000002
00154 #define ISR_RXOK 0x00000001
00155
00156 #define TXCFG_CSI 0x80000000
00157 #define TXCFG_HBI 0x40000000
00158 #define TXCFG_MLB 0x20000000
00159 #define TXCFG_ATP 0x10000000
00160 #define TXCFG_ECRETRY 0x00800000
00161 #define TXCFG_BRST_DIS 0x00080000
00162 #define TXCFG_MXDMA1024 0x00000000
00163 #define TXCFG_MXDMA512 0x00700000
00164 #define TXCFG_MXDMA256 0x00600000
00165 #define TXCFG_MXDMA128 0x00500000
00166 #define TXCFG_MXDMA64 0x00400000
00167 #define TXCFG_MXDMA32 0x00300000
00168 #define TXCFG_MXDMA16 0x00200000
00169 #define TXCFG_MXDMA8 0x00100000
00170
00171 #define CFG_LNKSTS 0x80000000
00172 #define CFG_SPDSTS 0x60000000
00173 #define CFG_SPDSTS1 0x40000000
00174 #define CFG_SPDSTS0 0x20000000
00175 #define CFG_DUPSTS 0x10000000
00176 #define CFG_TBI_EN 0x01000000
00177 #define CFG_MODE_1000 0x00400000
00178
00179
00180 #define CFG_AUTO_1000 0x00200000
00181 #define CFG_PINT_CTL 0x001c0000
00182 #define CFG_PINT_DUPSTS 0x00100000
00183 #define CFG_PINT_LNKSTS 0x00080000
00184 #define CFG_PINT_SPDSTS 0x00040000
00185 #define CFG_TMRTEST 0x00020000
00186 #define CFG_MRM_DIS 0x00010000
00187 #define CFG_MWI_DIS 0x00008000
00188 #define CFG_T64ADDR 0x00004000
00189 #define CFG_PCI64_DET 0x00002000
00190 #define CFG_DATA64_EN 0x00001000
00191 #define CFG_M64ADDR 0x00000800
00192 #define CFG_PHY_RST 0x00000400
00193 #define CFG_PHY_DIS 0x00000200
00194 #define CFG_EXTSTS_EN 0x00000100
00195 #define CFG_REQALG 0x00000080
00196 #define CFG_SB 0x00000040
00197 #define CFG_POW 0x00000020
00198 #define CFG_EXD 0x00000010
00199 #define CFG_PESEL 0x00000008
00200 #define CFG_BROM_DIS 0x00000004
00201 #define CFG_EXT_125 0x00000002
00202 #define CFG_BEM 0x00000001
00203
00204 #define EXTSTS_UDPPKT 0x00200000
00205 #define EXTSTS_TCPPKT 0x00080000
00206 #define EXTSTS_IPPKT 0x00020000
00207
00208 #define SPDSTS_POLARITY (CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0))
00209
00210 #define MIBC_MIBS 0x00000008
00211 #define MIBC_ACLR 0x00000004
00212 #define MIBC_FRZ 0x00000002
00213 #define MIBC_WRN 0x00000001
00214
00215 #define PCR_PSEN (1 << 31)
00216 #define PCR_PS_MCAST (1 << 30)
00217 #define PCR_PS_DA (1 << 29)
00218 #define PCR_STHI_8 (3 << 23)
00219 #define PCR_STLO_4 (1 << 23)
00220 #define PCR_FFHI_8K (3 << 21)
00221 #define PCR_FFLO_4K (1 << 21)
00222 #define PCR_PAUSE_CNT 0xFFFE
00223
00224 #define RXCFG_AEP 0x80000000
00225 #define RXCFG_ARP 0x40000000
00226 #define RXCFG_STRIPCRC 0x20000000
00227 #define RXCFG_RX_FD 0x10000000
00228 #define RXCFG_ALP 0x08000000
00229 #define RXCFG_AIRL 0x04000000
00230 #define RXCFG_MXDMA512 0x00700000
00231 #define RXCFG_DRTH 0x0000003e
00232 #define RXCFG_DRTH0 0x00000002
00233
00234 #define RFCR_RFEN 0x80000000
00235 #define RFCR_AAB 0x40000000
00236 #define RFCR_AAM 0x20000000
00237 #define RFCR_AAU 0x10000000
00238 #define RFCR_APM 0x08000000
00239 #define RFCR_APAT 0x07800000
00240 #define RFCR_APAT3 0x04000000
00241 #define RFCR_APAT2 0x02000000
00242 #define RFCR_APAT1 0x01000000
00243 #define RFCR_APAT0 0x00800000
00244 #define RFCR_AARP 0x00400000
00245 #define RFCR_MHEN 0x00200000
00246 #define RFCR_UHEN 0x00100000
00247 #define RFCR_ULM 0x00080000
00248
00249 #define VRCR_RUDPE 0x00000080
00250 #define VRCR_RTCPE 0x00000040
00251 #define VRCR_RIPE 0x00000020
00252 #define VRCR_IPEN 0x00000010
00253 #define VRCR_DUTF 0x00000008
00254 #define VRCR_DVTF 0x00000004
00255 #define VRCR_VTREN 0x00000002
00256 #define VRCR_VTDEN 0x00000001
00257
00258 #define VTCR_PPCHK 0x00000008
00259 #define VTCR_GCHK 0x00000004
00260 #define VTCR_VPPTI 0x00000002
00261 #define VTCR_VGTI 0x00000001
00262
00263 #define CR 0x00
00264 #define CFG 0x04
00265 #define MEAR 0x08
00266 #define PTSCR 0x0c
00267 #define ISR 0x10
00268 #define IMR 0x14
00269 #define IER 0x18
00270 #define IHR 0x1c
00271 #define TXDP 0x20
00272 #define TXDP_HI 0x24
00273 #define TXCFG 0x28
00274 #define GPIOR 0x2c
00275 #define RXDP 0x30
00276 #define RXDP_HI 0x34
00277 #define RXCFG 0x38
00278 #define PQCR 0x3c
00279 #define WCSR 0x40
00280 #define PCR 0x44
00281 #define RFCR 0x48
00282 #define RFDR 0x4c
00283
00284 #define SRR 0x58
00285
00286 #define VRCR 0xbc
00287 #define VTCR 0xc0
00288 #define VDR 0xc4
00289 #define CCSR 0xcc
00290
00291 #define TBICR 0xe0
00292 #define TBISR 0xe4
00293 #define TANAR 0xe8
00294 #define TANLPAR 0xec
00295 #define TANER 0xf0
00296 #define TESR 0xf4
00297
00298 #define TBICR_MR_AN_ENABLE 0x00001000
00299 #define TBICR_MR_RESTART_AN 0x00000200
00300
00301 #define TBISR_MR_LINK_STATUS 0x00000020
00302 #define TBISR_MR_AN_COMPLETE 0x00000004
00303
00304 #define TANAR_PS2 0x00000100
00305 #define TANAR_PS1 0x00000080
00306 #define TANAR_HALF_DUP 0x00000040
00307 #define TANAR_FULL_DUP 0x00000020
00308
00309 #define GPIOR_GP5_OE 0x00000200
00310 #define GPIOR_GP4_OE 0x00000100
00311 #define GPIOR_GP3_OE 0x00000080
00312 #define GPIOR_GP2_OE 0x00000040
00313 #define GPIOR_GP1_OE 0x00000020
00314 #define GPIOR_GP3_OUT 0x00000004
00315 #define GPIOR_GP1_OUT 0x00000001
00316
00317 #define LINK_AUTONEGOTIATE 0x01
00318 #define LINK_DOWN 0x02
00319 #define LINK_UP 0x04
00320
00321
00322 #define __kick_rx() writel(CR_RXE, ns->base + CR)
00323
00324 #define kick_rx() do { \
00325 dprintf(("kick_rx: maybe kicking\n")); \
00326 writel(virt_to_le32desc(&rx_ring[ns->cur_rx]), ns->base + RXDP); \
00327 if (ns->next_rx == ns->next_empty) \
00328 printf("uh-oh: next_rx == next_empty???\n"); \
00329 __kick_rx(); \
00330 } while(0)
00331
00332
00333 #ifdef USE_64BIT_ADDR
00334 #define HW_ADDR_LEN 8
00335 #else
00336 #define HW_ADDR_LEN 4
00337 #endif
00338
00339 #define CMDSTS_OWN 0x80000000
00340 #define CMDSTS_MORE 0x40000000
00341 #define CMDSTS_INTR 0x20000000
00342 #define CMDSTS_ERR 0x10000000
00343 #define CMDSTS_OK 0x08000000
00344 #define CMDSTS_LEN_MASK 0x0000ffff
00345
00346 #define CMDSTS_DEST_MASK 0x01800000
00347 #define CMDSTS_DEST_SELF 0x00800000
00348 #define CMDSTS_DEST_MULTI 0x01000000
00349
00350 #define DESC_SIZE 8
00351
00352 #ifdef USE_64BIT_ADDR
00353 struct ring_desc {
00354 uint64_t link;
00355 uint64_t bufptr;
00356 u32 cmdsts;
00357 u32 extsts;
00358 };
00359 #else
00360 struct ring_desc {
00361 u32 link;
00362 u32 bufptr;
00363 u32 cmdsts;
00364 u32 extsts;
00365 };
00366 #endif
00367
00368
00369 static struct ns83820_private {
00370 u8 *base;
00371 int up;
00372 long idle;
00373 u32 *next_rx_desc;
00374 u16 next_rx, next_empty;
00375 u32 cur_rx;
00376 u32 *descs;
00377 unsigned ihr;
00378 u32 CFG_cache;
00379 u32 MEAR_cache;
00380 u32 IMR_cache;
00381 int linkstate;
00382 u16 tx_done_idx;
00383 u16 tx_idx;
00384 u16 tx_intr_idx;
00385 u32 phy_descs;
00386 u32 *tx_descs;
00387
00388 } nsx;
00389 static struct ns83820_private *ns;
00390
00391
00392 struct {
00393 struct ring_desc tx_ring[NR_TX_DESC] __attribute__ ((aligned(8)));
00394 unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE];
00395 struct ring_desc rx_ring[NR_RX_DESC] __attribute__ ((aligned(8)));
00396 unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE]
00397 __attribute__ ((aligned(8)));
00398 } ns83820_bufs __shared;
00399 #define tx_ring ns83820_bufs.tx_ring
00400 #define rx_ring ns83820_bufs.rx_ring
00401 #define txb ns83820_bufs.txb
00402 #define rxb ns83820_bufs.rxb
00403
00404 static void phy_intr(struct nic *nic __unused)
00405 {
00406 static char *speeds[] =
00407 { "10", "100", "1000", "1000(?)", "1000F" };
00408 u32 cfg, new_cfg;
00409 u32 tbisr, tanar, tanlpar;
00410 int speed, fullduplex, newlinkstate;
00411
00412 cfg = readl(ns->base + CFG) ^ SPDSTS_POLARITY;
00413 if (ns->CFG_cache & CFG_TBI_EN) {
00414
00415 tbisr = readl(ns->base + TBISR);
00416 tanar = readl(ns->base + TANAR);
00417 tanlpar = readl(ns->base + TANLPAR);
00418 dprintf(("phy_intr: tbisr=%hX, tanar=%hX, tanlpar=%hX\n",
00419 tbisr, tanar, tanlpar));
00420
00421 if ((fullduplex = (tanlpar & TANAR_FULL_DUP)
00422 && (tanar & TANAR_FULL_DUP))) {
00423
00424
00425 writel(readl(ns->base + TXCFG)
00426 | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
00427 ns->base + TXCFG);
00428 writel(readl(ns->base + RXCFG) | RXCFG_RX_FD,
00429 ns->base + RXCFG);
00430
00431 writel(readl(ns->base + GPIOR) | GPIOR_GP1_OUT,
00432 ns->base + GPIOR);
00433
00434 } else if (((tanlpar & TANAR_HALF_DUP)
00435 && (tanar & TANAR_HALF_DUP))
00436 || ((tanlpar & TANAR_FULL_DUP)
00437 && (tanar & TANAR_HALF_DUP))
00438 || ((tanlpar & TANAR_HALF_DUP)
00439 && (tanar & TANAR_FULL_DUP))) {
00440
00441
00442 writel((readl(ns->base + TXCFG)
00443 & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
00444 ns->base + TXCFG);
00445 writel(readl(ns->base + RXCFG) & ~RXCFG_RX_FD,
00446 ns->base + RXCFG);
00447
00448 writel(readl(ns->base + GPIOR) & ~GPIOR_GP1_OUT,
00449 ns->base + GPIOR);
00450 }
00451
00452 speed = 4;
00453
00454 } else {
00455
00456 new_cfg =
00457 ns->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
00458
00459 if (cfg & CFG_SPDSTS1)
00460 new_cfg |= CFG_MODE_1000;
00461 else
00462 new_cfg &= ~CFG_MODE_1000;
00463
00464 speed = ((cfg / CFG_SPDSTS0) & 3);
00465 fullduplex = (cfg & CFG_DUPSTS);
00466
00467 if (fullduplex)
00468 new_cfg |= CFG_SB;
00469
00470 if ((cfg & CFG_LNKSTS) &&
00471 ((new_cfg ^ ns->CFG_cache) & CFG_MODE_1000)) {
00472 writel(new_cfg, ns->base + CFG);
00473 ns->CFG_cache = new_cfg;
00474 }
00475
00476 ns->CFG_cache &= ~CFG_SPDSTS;
00477 ns->CFG_cache |= cfg & CFG_SPDSTS;
00478 }
00479
00480 newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
00481
00482 if (newlinkstate & LINK_UP && ns->linkstate != newlinkstate) {
00483 printf("link now %s mbps, %s duplex and up.\n",
00484 speeds[speed], fullduplex ? "full" : "half");
00485 } else if (newlinkstate & LINK_DOWN
00486 && ns->linkstate != newlinkstate) {
00487 printf("link now down.\n");
00488 }
00489 ns->linkstate = newlinkstate;
00490 }
00491 static void ns83820_set_multicast(struct nic *nic __unused);
00492 static void ns83820_setup_rx(struct nic *nic)
00493 {
00494 unsigned i;
00495 ns->idle = 1;
00496 ns->next_rx = 0;
00497 ns->next_rx_desc = ns->descs;
00498 ns->next_empty = 0;
00499 ns->cur_rx = 0;
00500
00501
00502 for (i = 0; i < NR_RX_DESC; i++) {
00503 rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]);
00504 rx_ring[i].bufptr =
00505 virt_to_le32desc(&rxb[i * REAL_RX_BUF_SIZE]);
00506 rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
00507 rx_ring[i].extsts = cpu_to_le32(0);
00508 }
00509
00510
00511 writel(0, ns->base + RXDP_HI);
00512 writel(virt_to_le32desc(&rx_ring[0]), ns->base + RXDP);
00513
00514 dprintf(("starting receiver\n"));
00515
00516 writel(0x0001, ns->base + CCSR);
00517 writel(0, ns->base + RFCR);
00518 writel(0x7fc00000, ns->base + RFCR);
00519 writel(0xffc00000, ns->base + RFCR);
00520
00521 ns->up = 1;
00522
00523 phy_intr(nic);
00524
00525
00526 ns->IMR_cache |= ISR_PHY;
00527 ns->IMR_cache |= ISR_RXRCMP;
00528
00529
00530 ns->IMR_cache |= ISR_RXORN;
00531 ns->IMR_cache |= ISR_RXSOVR;
00532 ns->IMR_cache |= ISR_RXDESC;
00533 ns->IMR_cache |= ISR_RXIDLE;
00534 ns->IMR_cache |= ISR_TXDESC;
00535 ns->IMR_cache |= ISR_TXIDLE;
00536
00537
00538
00539
00540 ns83820_set_multicast(nic);
00541 kick_rx();
00542 }
00543
00544
00545 static void ns83820_do_reset(struct nic *nic __unused, u32 which)
00546 {
00547 dprintf(("resetting chip...\n"));
00548 writel(which, ns->base + CR);
00549 do {
00550
00551 } while (readl(ns->base + CR) & which);
00552 dprintf(("okay!\n"));
00553 }
00554
00555 static void ns83820_reset(struct nic *nic)
00556 {
00557 unsigned i;
00558 dprintf(("ns83820_reset\n"));
00559
00560 writel(0, ns->base + PQCR);
00561
00562 ns83820_setup_rx(nic);
00563
00564 for (i = 0; i < NR_TX_DESC; i++) {
00565 tx_ring[i].link = 0;
00566 tx_ring[i].bufptr = 0;
00567 tx_ring[i].cmdsts = cpu_to_le32(0);
00568 tx_ring[i].extsts = cpu_to_le32(0);
00569 }
00570
00571 ns->tx_idx = 0;
00572 ns->tx_done_idx = 0;
00573 writel(0, ns->base + TXDP_HI);
00574 return;
00575 }
00576 static void ns83820_getmac(struct nic *nic __unused, u8 * mac)
00577 {
00578 unsigned i;
00579 for (i = 0; i < 3; i++) {
00580 u32 data;
00581
00582
00583
00584 writel(i * 2, ns->base + RFCR);
00585 data = readl(ns->base + RFDR);
00586 *mac++ = data;
00587 *mac++ = data >> 8;
00588 }
00589 }
00590
00591 static void ns83820_set_multicast(struct nic *nic __unused)
00592 {
00593 u8 *rfcr = ns->base + RFCR;
00594 u32 and_mask = 0xffffffff;
00595 u32 or_mask = 0;
00596 u32 val;
00597
00598
00599 and_mask &= ~(RFCR_AAU | RFCR_AAM);
00600 or_mask |= RFCR_AAM;
00601 val = (readl(rfcr) & and_mask) | or_mask;
00602
00603 writel(val & ~RFCR_RFEN, rfcr);
00604 writel(val, rfcr);
00605
00606 }
00607 static void ns83820_run_bist(struct nic *nic __unused, const char *name,
00608 u32 enable, u32 done, u32 fail)
00609 {
00610 int timed_out = 0;
00611 long start;
00612 u32 status;
00613 int loops = 0;
00614
00615 dprintf(("start %s\n", name))
00616
00617 start = currticks();
00618
00619 writel(enable, ns->base + PTSCR);
00620 for (;;) {
00621 loops++;
00622 status = readl(ns->base + PTSCR);
00623 if (!(status & enable))
00624 break;
00625 if (status & done)
00626 break;
00627 if (status & fail)
00628 break;
00629 if ((currticks() - start) >= HZ) {
00630 timed_out = 1;
00631 break;
00632 }
00633 }
00634
00635 if (status & fail)
00636 printf("%s failed! (0x%hX & 0x%hX)\n", name, (unsigned int) status,
00637 (unsigned int) fail);
00638 else if (timed_out)
00639 printf("run_bist %s timed out! (%hX)\n", name, (unsigned int) status);
00640 dprintf(("done %s in %d loops\n", name, loops));
00641 }
00642
00643
00644
00645
00646 static void ns83820_check_intr(struct nic *nic) {
00647 int i;
00648 u32 isr = readl(ns->base + ISR);
00649 if(ISR_PHY & isr)
00650 phy_intr(nic);
00651 if(( ISR_RXIDLE | ISR_RXDESC | ISR_RXERR) & isr)
00652 kick_rx();
00653 for (i = 0; i < NR_RX_DESC; i++) {
00654 if (rx_ring[i].cmdsts == CMDSTS_OWN) {
00655
00656 rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
00657 }
00658 }
00659 }
00660
00661
00662
00663 static int ns83820_poll(struct nic *nic, int retrieve)
00664 {
00665
00666
00667
00668 u32 cmdsts;
00669 int entry = ns->cur_rx;
00670
00671 ns83820_check_intr(nic);
00672
00673 cmdsts = le32_to_cpu(rx_ring[entry].cmdsts);
00674
00675 if ( ! ( (CMDSTS_OWN & (cmdsts)) && (cmdsts != (CMDSTS_OWN)) ) )
00676 return 0;
00677
00678 if ( ! retrieve ) return 1;
00679
00680 if (! (CMDSTS_OK & cmdsts) )
00681 return 0;
00682
00683 nic->packetlen = cmdsts & 0xffff;
00684 memcpy(nic->packet,
00685 rxb + (entry * REAL_RX_BUF_SIZE),
00686 nic->packetlen);
00687
00688 rx_ring[entry].cmdsts = cpu_to_le32(CMDSTS_OWN);
00689
00690 ns->cur_rx = ++ns->cur_rx % NR_RX_DESC;
00691
00692 if (ns->cur_rx == 0)
00693 kick_rx();
00694
00695 return 1;
00696 }
00697
00698 static inline void kick_tx(struct nic *nic __unused)
00699 {
00700 dprintf(("kick_tx\n"));
00701 writel(CR_TXE, ns->base + CR);
00702 }
00703
00704
00705
00706
00707 static void ns83820_transmit(struct nic *nic, const char *d,
00708 unsigned int t,
00709 unsigned int s,
00710 const char *p)
00711 {
00712
00713
00714 u16 nstype;
00715 u32 cmdsts, extsts;
00716 int cur_tx = 0;
00717 u32 isr = readl(ns->base + ISR);
00718 if (ISR_TXIDLE & isr)
00719 kick_tx(nic);
00720
00721 memcpy(txb, d, ETH_ALEN);
00722 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
00723 nstype = htons((u16) t);
00724 memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
00725 memcpy(txb + ETH_HLEN, p, s);
00726 s += ETH_HLEN;
00727 s &= 0x0FFF;
00728 while (s < ETH_ZLEN)
00729 txb[s++] = '\0';
00730
00731
00732 extsts = 0;
00733 extsts |= EXTSTS_UDPPKT;
00734
00735 tx_ring[cur_tx].bufptr = virt_to_le32desc(&txb);
00736 tx_ring[cur_tx].extsts = cpu_to_le32(extsts);
00737
00738 cmdsts = cpu_to_le32(0);
00739 cmdsts |= cpu_to_le32(CMDSTS_OWN | s);
00740 tx_ring[cur_tx].cmdsts = cpu_to_le32(cmdsts);
00741
00742 writel(virt_to_le32desc(&tx_ring[0]), ns->base + TXDP);
00743 kick_tx(nic);
00744 }
00745
00746
00747
00748
00749 static void ns83820_disable ( struct nic *nic ) {
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 writel(0, ns->base + IMR);
00763 writel(0, ns->base + IER);
00764 readl(ns->base + IER);
00765
00766 ns->up = 0;
00767
00768 ns83820_do_reset(nic, CR_RST);
00769
00770 ns->IMR_cache &=
00771 ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY |
00772 ISR_RXIDLE);
00773 writel(ns->IMR_cache, ns->base + IMR);
00774
00775
00776 readl(ns->base + IMR);
00777
00778
00779 writel(0, ns->base + RXDP_HI);
00780 writel(0, ns->base + RXDP);
00781 }
00782
00783
00784
00785
00786 static void ns83820_irq(struct nic *nic __unused, irq_action_t action __unused)
00787 {
00788 switch ( action ) {
00789 case DISABLE :
00790 break;
00791 case ENABLE :
00792 break;
00793 case FORCE :
00794 break;
00795 }
00796 }
00797
00798 static struct nic_operations ns83820_operations = {
00799 .connect = dummy_connect,
00800 .poll = ns83820_poll,
00801 .transmit = ns83820_transmit,
00802 .irq = ns83820_irq,
00803
00804 };
00805
00806 static struct pci_device_id ns83820_nics[] = {
00807 PCI_ROM(0x100b, 0x0022, "ns83820", "National Semiconductor 83820", 0),
00808 };
00809
00810 PCI_DRIVER ( ns83820_driver, ns83820_nics, PCI_NO_CLASS );
00811
00812
00813
00814
00815
00816 #define board_found 1
00817 #define valid_link 0
00818 static int ns83820_probe ( struct nic *nic, struct pci_device *pci ) {
00819
00820 long addr;
00821 int using_dac = 0;
00822
00823 if (pci->ioaddr == 0)
00824 return 0;
00825
00826 printf("ns83820.c: Found %s, vendor=0x%hX, device=0x%hX\n",
00827 pci->driver_name, pci->vendor, pci->device);
00828
00829
00830 ns = &nsx;
00831
00832 adjust_pci_device(pci);
00833
00834 addr = pci_bar_start(pci, PCI_BASE_ADDRESS_1);
00835
00836 ns->base = ioremap(addr, (1UL << 12));
00837
00838 if (!ns->base)
00839 return 0;
00840
00841 nic->irqno = 0;
00842 nic->ioaddr = pci->ioaddr & ~3;
00843
00844
00845 writel(0, ns->base + IMR);
00846 writel(0, ns->base + IER);
00847 readl(ns->base + IER);
00848
00849 ns->IMR_cache = 0;
00850
00851 ns83820_do_reset(nic, CR_RST);
00852
00853
00854 writel(PTSCR_RBIST_RST, ns->base + PTSCR);
00855 ns83820_run_bist(nic, "sram bist", PTSCR_RBIST_EN,
00856 PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
00857 ns83820_run_bist(nic, "eeprom bist", PTSCR_EEBIST_EN, 0,
00858 PTSCR_EEBIST_FAIL);
00859 ns83820_run_bist(nic, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
00860
00861
00862 ns->CFG_cache = readl(ns->base + CFG);
00863
00864 if ((ns->CFG_cache & CFG_PCI64_DET)) {
00865 printf("%s: detected 64 bit PCI data bus.\n", pci->driver_name);
00866
00867 if (!(ns->CFG_cache & CFG_DATA64_EN))
00868 printf
00869 ("%s: EEPROM did not enable 64 bit bus. Disabled.\n",
00870 pci->driver_name);
00871 } else
00872 ns->CFG_cache &= ~(CFG_DATA64_EN);
00873
00874 ns->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS |
00875 CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
00876 CFG_M64ADDR);
00877 ns->CFG_cache |=
00878 CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS |
00879 CFG_EXTSTS_EN | CFG_EXD | CFG_PESEL;
00880 ns->CFG_cache |= CFG_REQALG;
00881 ns->CFG_cache |= CFG_POW;
00882 ns->CFG_cache |= CFG_TMRTEST;
00883
00884
00885
00886
00887 #ifdef USE_64BIT_ADDR
00888 ns->CFG_cache |= CFG_M64ADDR;
00889 #endif
00890
00891
00892 if (using_dac)
00893 ns->CFG_cache |= CFG_T64ADDR;
00894
00895
00896 ns->CFG_cache &= ~CFG_BEM;
00897
00898
00899 if (ns->CFG_cache & CFG_TBI_EN) {
00900 dprintf(("%s: enabling optical transceiver\n", pci->driver_name));
00901 writel(readl(ns->base + GPIOR) | 0x3e8, ns->base + GPIOR);
00902
00903
00904 writel(readl(ns->base + TANAR)
00905 | TANAR_HALF_DUP | TANAR_FULL_DUP,
00906 ns->base + TANAR);
00907
00908
00909 writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN,
00910 ns->base + TBICR);
00911 writel(TBICR_MR_AN_ENABLE, ns->base + TBICR);
00912 ns->linkstate = LINK_AUTONEGOTIATE;
00913
00914 ns->CFG_cache |= CFG_MODE_1000;
00915 }
00916 writel(ns->CFG_cache, ns->base + CFG);
00917 dprintf(("CFG: %hX\n", ns->CFG_cache));
00918
00919
00920 if (reset_phy) {
00921 dprintf(("%s: resetting phy\n", pci->driver_name));
00922 writel(ns->CFG_cache | CFG_PHY_RST, ns->base + CFG);
00923 writel(ns->CFG_cache, ns->base + CFG);
00924 }
00925 #if 0
00926
00927
00928 if (readl(dev->base + SRR))
00929 writel(readl(dev->base + 0x20c) | 0xfe00,
00930 dev->base + 0x20c);
00931 #endif
00932
00933
00934
00935
00936
00937
00938
00939
00940 writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512
00941 | ((1600 / 32) * 0x100), ns->base + TXCFG);
00942
00943
00944
00945
00946
00947
00948
00949 writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
00950 | RXCFG_STRIPCRC
00951
00952 | (RXCFG_MXDMA512) | 0, ns->base + RXCFG);
00953
00954
00955 writel(0, ns->base + PQCR);
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 writel(VRCR_IPEN | VRCR_VTDEN, ns->base + VRCR);
00970
00971
00972 writel(VTCR_PPCHK, ns->base + VTCR);
00973
00974
00975
00976 writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K |
00977 PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT),
00978 ns->base + PCR);
00979
00980
00981 writel(0, ns->base + WCSR);
00982
00983 ns83820_getmac(nic, nic->node_addr);
00984
00985 if (using_dac) {
00986 dprintf(("%s: using 64 bit addressing.\n", pci->driver_name));
00987 }
00988
00989 dprintf(("%s: DP83820 %d.%d: %! io=0x%hX\n",
00990 pci->driver_name,
00991 (unsigned) readl(ns->base + SRR) >> 8,
00992 (unsigned) readl(ns->base + SRR) & 0xff,
00993 nic->node_addr, pci->ioaddr));
00994
00995 #ifdef PHY_CODE_IS_FINISHED
00996 ns83820_probe_phy(dev);
00997 #endif
00998
00999 ns83820_reset(nic);
01000
01001 nic->nic_op = &ns83820_operations;
01002 return 1;
01003 }
01004
01005 DRIVER ( "NS83820/PCI", nic_driver, pci_driver, ns83820_driver,
01006 ns83820_probe, ns83820_disable );
01007
01008
01009
01010
01011
01012
01013
01014