Mercurial > ecos
comparison packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @ 101:c37d3a9e1b28 ecos-sw-2000-06-16
Merge from eCos master repository on 2000-06-16-07:47:03-BST
| author | jlarmour |
|---|---|
| date | Fri, 16 Jun 2000 16:43:59 +0000 |
| parents | afdeb44241de |
| children | 5a0cc6c243a9 |
comparison
equal
deleted
inserted
replaced
| 100:991657282121 | 101:c37d3a9e1b28 |
|---|---|
| 68 #include <cyg/io/pci.h> | 68 #include <cyg/io/pci.h> |
| 69 #else | 69 #else |
| 70 #error "Need PCI package here" | 70 #error "Need PCI package here" |
| 71 #endif | 71 #endif |
| 72 | 72 |
| 73 #include CYGBLD_DEVS_ETH_INFO_H // some state we must export | |
| 74 | |
| 73 // ------------------------------------------------------------------------ | 75 // ------------------------------------------------------------------------ |
| 74 | 76 |
| 75 #ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_CHATTER | 77 #ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_CHATTER |
| 76 #define notDEBUG_82559 // This one prints stuff as packets come and go | 78 #define notDEBUG_82559 // This one prints stuff as packets come and go |
| 77 #define DEBUG // Startup printing mainly | 79 #define DEBUG // Startup printing mainly |
| 78 #define DEBUG_EE // Some EEPROM specific retries &c | 80 #define DEBUG_EE // Some EEPROM specific retries &c |
| 79 #endif | 81 #endif |
| 80 | 82 |
| 81 #define nKEEP_STATISTICS | |
| 82 #define nDISPLAY_STATISTICS | |
| 83 #define nDISPLAY_82559_STATISTICS | |
| 84 | 83 |
| 85 | 84 |
| 86 #define os_printf diag_printf | 85 #define os_printf diag_printf |
| 87 #define db_printf diag_printf | 86 #define db_printf diag_printf |
| 88 | 87 |
| 164 | 163 |
| 165 | 164 |
| 166 | 165 |
| 167 // ------------------------------------------------------------------------ | 166 // ------------------------------------------------------------------------ |
| 168 // | 167 // |
| 169 // 82559 GENERAL STATUS REGISTER | |
| 170 // | |
| 171 // ------------------------------------------------------------------------ | |
| 172 #define GEN_STATUS_FDX 0x04 // 1 = full duplex, 0 = half | |
| 173 #define GEN_STATUS_100MBPS 0x02 // 1 = 100 Mbps, 0 = 10 Mbps | |
| 174 #define GEN_STATUS_LINK 0x01 // 1 = link up, 0 = link down | |
| 175 | |
| 176 | |
| 177 // ------------------------------------------------------------------------ | |
| 178 // | |
| 179 // 82559 EEPROM INTERFACE | 168 // 82559 EEPROM INTERFACE |
| 180 // | 169 // |
| 181 // ------------------------------------------------------------------------ | 170 // ------------------------------------------------------------------------ |
| 182 // EEPROM_Ctrl bits. | 171 // EEPROM_Ctrl bits. |
| 183 #define EE_SHIFT_CLK 0x01 // EEPROM shift clock. | 172 #define EE_SHIFT_CLK 0x01 // EEPROM shift clock. |
| 280 #define RFD_RX_NO_ADR_MATCH 0x00000004 // no address match | 269 #define RFD_RX_NO_ADR_MATCH 0x00000004 // no address match |
| 281 #define RFD_RX_IA_MATCH 0x00000002 // individual address does not match | 270 #define RFD_RX_IA_MATCH 0x00000002 // individual address does not match |
| 282 #define RFD_RX_TCO 0x00000001 // TCO indication | 271 #define RFD_RX_TCO 0x00000001 // TCO indication |
| 283 | 272 |
| 284 | 273 |
| 285 typedef struct { | 274 typedef struct rbd { |
| 286 volatile cyg_uint32 count:14, // bytes used in buffer | 275 volatile cyg_uint32 count:14, // bytes used in buffer |
| 287 f:1, // buffer has been used (filled) | 276 f:1, // buffer has been used (filled) |
| 288 eof:1; // last receive buffer in frame | 277 eof:1; // last receive buffer in frame |
| 289 volatile cyg_uint32 next_rbd; // next RBD (RU base relative) | 278 volatile cyg_uint32 next_rbd; // next RBD (RU base relative) |
| 290 volatile cyg_uint32 buffer_address; // address of receive data buffer | 279 volatile cyg_uint32 buffer_address; // address of receive data buffer |
| 296 // ------------------------------------------------------------------------ | 285 // ------------------------------------------------------------------------ |
| 297 // | 286 // |
| 298 // TRANSMIT FRAME DESCRIPTORS | 287 // TRANSMIT FRAME DESCRIPTORS |
| 299 // | 288 // |
| 300 // ------------------------------------------------------------------------ | 289 // ------------------------------------------------------------------------ |
| 301 typedef struct { | 290 typedef struct txcb { |
| 302 volatile cyg_uint32 status:16, // result of transmit operation | 291 volatile cyg_uint32 status:16, // result of transmit operation |
| 303 command:16; // transmit command | 292 command:16; // transmit command |
| 304 volatile cyg_uint32 link; // offset from RU base to next RFD | 293 volatile cyg_uint32 link; // offset from RU base to next RFD |
| 305 volatile cyg_uint32 tbd_address; // pointer to Rx data buffer | 294 volatile cyg_uint32 tbd_address; // pointer to Rx data buffer |
| 306 volatile cyg_uint32 count:15, // number of bytes in transmit buffer | 295 volatile cyg_uint32 count:15, // number of bytes in transmit buffer |
| 347 // | 336 // |
| 348 // STATISTICAL COUNTER STRUCTURE | 337 // STATISTICAL COUNTER STRUCTURE |
| 349 // | 338 // |
| 350 // ------------------------------------------------------------------------ | 339 // ------------------------------------------------------------------------ |
| 351 #ifdef KEEP_STATISTICS | 340 #ifdef KEEP_STATISTICS |
| 352 typedef struct { | |
| 353 cyg_uint32 tx_good; | |
| 354 cyg_uint32 tx_max_collisions; | |
| 355 cyg_uint32 tx_late_collisions; | |
| 356 cyg_uint32 tx_underrun; | |
| 357 cyg_uint32 tx_carrier_loss; | |
| 358 cyg_uint32 tx_deferred; | |
| 359 cyg_uint32 tx_single_collisions; | |
| 360 cyg_uint32 tx_mult_collisions; | |
| 361 cyg_uint32 tx_total_collisions; | |
| 362 cyg_uint32 rx_good; | |
| 363 cyg_uint32 rx_crc_errors; | |
| 364 cyg_uint32 rx_align_errors; | |
| 365 cyg_uint32 rx_resource_errors; | |
| 366 cyg_uint32 rx_overrun_errors; | |
| 367 cyg_uint32 rx_collisions; | |
| 368 cyg_uint32 rx_short_frames; | |
| 369 cyg_uint32 done; | |
| 370 } I82559_COUNTERS; | |
| 371 | |
| 372 | |
| 373 typedef struct { | |
| 374 cyg_uint32 interrupts; | |
| 375 cyg_uint32 rx_count; | |
| 376 cyg_uint32 rx_deliver; | |
| 377 cyg_uint32 rx_resource; | |
| 378 cyg_uint32 rx_restart; | |
| 379 cyg_uint32 tx_count; | |
| 380 cyg_uint32 tx_complete; | |
| 381 cyg_uint32 tx_dropped; | |
| 382 } STATISTICS; | |
| 383 | |
| 384 | |
| 385 STATISTICS statistics[2]; | 341 STATISTICS statistics[2]; |
| 386 I82559_COUNTERS i82559_counters[2]; | 342 I82559_COUNTERS i82559_counters[2]; |
| 387 | |
| 388 #endif // KEEP_STATISTICS | 343 #endif // KEEP_STATISTICS |
| 389 | 344 |
| 345 // ------------------------------------------------------------------------ | |
| 346 // | |
| 347 // DEVICES AND PACKET QUEUES | |
| 348 // | |
| 390 // ------------------------------------------------------------------------ | 349 // ------------------------------------------------------------------------ |
| 391 | 350 |
| 392 #define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size | 351 #define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size |
| 393 #define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size | 352 #define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size |
| 394 | |
| 395 // The system seems to work OK with as few as 8 of RX and TX descriptors. | |
| 396 // It limps very painfully with only 4. | |
| 397 // Performance is better with more than 8. | |
| 398 // But the size of non-cached (so useless for anything else) | |
| 399 // memory window is 1Mb, so we might as well use it all. | |
| 400 // | |
| 401 // 128 for these uses the whole 1Mb, near enough. | |
| 402 | |
| 403 #ifndef MAX_RX_DESCRIPTORS | |
| 404 #define MAX_RX_DESCRIPTORS 128 // number of Rx descriptors | |
| 405 #endif | |
| 406 #ifndef MAX_TX_DESCRIPTORS | |
| 407 #define MAX_TX_DESCRIPTORS 128 // number of Tx descriptors | |
| 408 #endif | |
| 409 | |
| 410 | |
| 411 | |
| 412 typedef struct i82559 { | |
| 413 cyg_uint8 // (split up for atomic byte access) | |
| 414 found:1, // was hardware discovered? | |
| 415 mac_addr_ok:1, // can we bring up? | |
| 416 active:1, // has this if been brung up? | |
| 417 spare1:5; | |
| 418 cyg_uint8 | |
| 419 spare2:8; | |
| 420 cyg_uint8 | |
| 421 tx_in_progress:1, // transmit in progress flag | |
| 422 tx_queue_full:1, // all Tx descriptors used flag | |
| 423 spare3:6; | |
| 424 cyg_uint8 index; // 0 or 1 or whatever | |
| 425 cyg_uint32 devid; // PCI device id | |
| 426 cyg_uint32 memory_address; // PCI memory address | |
| 427 cyg_uint32 io_address; // memory mapped I/O address | |
| 428 cyg_uint8 mac_address[6]; // mac (hardware) address | |
| 429 void *ndp; // Network Device Pointer | |
| 430 | |
| 431 int next_rx_descriptor; // descriptor index for RFDs | |
| 432 RFD *rx_ring[MAX_RX_DESCRIPTORS]; // location of Rx descriptors | |
| 433 | |
| 434 int tx_descriptor_add; // descriptor index for additions | |
| 435 int tx_descriptor_active; // descriptor index for active tx | |
| 436 int tx_descriptor_remove; // descriptor index for remove | |
| 437 | |
| 438 TxCB *tx_ring[MAX_TX_DESCRIPTORS]; // location of Tx descriptors | |
| 439 unsigned long tx_keys[MAX_TX_DESCRIPTORS]; | |
| 440 // keys for tx q management | |
| 441 | |
| 442 // Interrupt handling stuff | |
| 443 cyg_vector_t vector; // interrupt vector | |
| 444 cyg_handle_t interrupt_handle; // handle for int.handler | |
| 445 cyg_interrupt interrupt_object; | |
| 446 | |
| 447 #ifdef KEEP_STATISTICS | |
| 448 void *p_statistics; // pointer to statistical counters | |
| 449 #endif | |
| 450 | |
| 451 } I82559; | |
| 452 | 353 |
| 453 | 354 |
| 454 // This is encapsulated here so that a change to > 2 interfaces can | 355 // This is encapsulated here so that a change to > 2 interfaces can |
| 455 // easily be accommodated. | 356 // easily be accommodated. |
| 456 | 357 |
| 550 static int eth_set_promiscuous_mode(struct i82559* p_i82559); | 451 static int eth_set_promiscuous_mode(struct i82559* p_i82559); |
| 551 | 452 |
| 552 // debugging/logging only: | 453 // debugging/logging only: |
| 553 void dump_txcb(TxCB *p_txcb); | 454 void dump_txcb(TxCB *p_txcb); |
| 554 void DisplayStatistics(void); | 455 void DisplayStatistics(void); |
| 456 void update_statistics(struct i82559* p_i82559); | |
| 555 void dump_rfd(RFD *p_rfd, int anyway ); | 457 void dump_rfd(RFD *p_rfd, int anyway ); |
| 556 void dump_all_rfds( int intf ); | 458 void dump_all_rfds( int intf ); |
| 557 void dump_packet(cyg_uint8 *p_buffer, int length); | 459 void dump_packet(cyg_uint8 *p_buffer, int length); |
| 558 | 460 |
| 559 // ------------------------------------------------------------------------ | 461 // ------------------------------------------------------------------------ |
| 1000 unsigned char *enaddr, int flags ) | 902 unsigned char *enaddr, int flags ) |
| 1001 { | 903 { |
| 1002 struct i82559 *p_i82559; | 904 struct i82559 *p_i82559; |
| 1003 cyg_uint32 ioaddr; | 905 cyg_uint32 ioaddr; |
| 1004 #ifdef KEEP_STATISTICS | 906 #ifdef KEEP_STATISTICS |
| 1005 #ifdef DISPLAY_82559_STATISTICS | |
| 1006 void *p_statistics; | 907 void *p_statistics; |
| 1007 #endif | |
| 1008 #endif | 908 #endif |
| 1009 | 909 |
| 1010 p_i82559 = (struct i82559 *)sc->driver_private; | 910 p_i82559 = (struct i82559 *)sc->driver_private; |
| 1011 | 911 |
| 1012 IF_BAD_82559( p_i82559 ) { | 912 IF_BAD_82559( p_i82559 ) { |
| 1029 i82559_stop( sc ); | 929 i82559_stop( sc ); |
| 1030 | 930 |
| 1031 ioaddr = p_i82559->io_address; // get 82559's I/O address | 931 ioaddr = p_i82559->io_address; // get 82559's I/O address |
| 1032 | 932 |
| 1033 #ifdef KEEP_STATISTICS | 933 #ifdef KEEP_STATISTICS |
| 1034 #ifdef DISPLAY_82559_STATISTICS | |
| 1035 p_i82559->p_statistics = | 934 p_i82559->p_statistics = |
| 1036 p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS)); | 935 p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS)); |
| 1037 memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS)); | 936 memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS)); |
| 1038 wait_for_cmd_done(ioaddr); // make sure no command operating | 937 wait_for_cmd_done(ioaddr); // make sure no command operating |
| 1039 // set statistics dump address | 938 // set statistics dump address |
| 1041 OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd); | 940 OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd); |
| 1042 | 941 |
| 1043 wait_for_cmd_done(ioaddr); // make sure no command operating | 942 wait_for_cmd_done(ioaddr); // make sure no command operating |
| 1044 OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump | 943 OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump |
| 1045 #endif | 944 #endif |
| 1046 #endif | |
| 1047 | 945 |
| 1048 // Set the base address | 946 // Set the base address |
| 1049 wait_for_cmd_done(ioaddr); | 947 wait_for_cmd_done(ioaddr); |
| 1050 OUTL(0, ioaddr + SCBPointer); // load ru base address = 0 | 948 OUTL(0, ioaddr + SCBPointer); // load ru base address = 0 |
| 1051 OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd); | 949 OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd); |
| 1062 ) { | 960 ) { |
| 1063 eth_set_promiscuous_mode(p_i82559); | 961 eth_set_promiscuous_mode(p_i82559); |
| 1064 } | 962 } |
| 1065 #ifdef DEBUG | 963 #ifdef DEBUG |
| 1066 { | 964 { |
| 1067 int status; | 965 int status = i82559_status( sc ); |
| 1068 status = INB(ioaddr + SCBGenStatus); | |
| 1069 os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n", | 966 os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n", |
| 1070 p_i82559->index, | 967 p_i82559->index, |
| 1071 *(int *)p_i82559, | 968 *(int *)p_i82559, |
| 1072 status & GEN_STATUS_LINK ? "Up" : "Down", | 969 status & GEN_STATUS_LINK ? "Up" : "Down", |
| 1073 status & GEN_STATUS_100MBPS ? "100" : "10", | 970 status & GEN_STATUS_100MBPS ? "100" : "10", |
| 1074 status & GEN_STATUS_FDX ? "Full" : "Half"); | 971 status & GEN_STATUS_FDX ? "Full" : "Half"); |
| 1075 } | 972 } |
| 1076 #endif | 973 #endif |
| 974 } | |
| 975 | |
| 976 // ------------------------------------------------------------------------ | |
| 977 // | |
| 978 // Function : i82559_status | |
| 979 // | |
| 980 // ------------------------------------------------------------------------ | |
| 981 int i82559_status( struct eth_drv_sc *sc ) | |
| 982 { | |
| 983 int status; | |
| 984 struct i82559 *p_i82559; | |
| 985 cyg_uint32 ioaddr; | |
| 986 p_i82559 = (struct i82559 *)sc->driver_private; | |
| 987 | |
| 988 IF_BAD_82559( p_i82559 ) { | |
| 989 #ifdef DEBUG | |
| 990 os_printf( "i82559_status: Bad device pointer %x\n", p_i82559 ); | |
| 991 #endif | |
| 992 return 0; | |
| 993 } | |
| 994 | |
| 995 ioaddr = p_i82559->io_address; // get 82559's I/O address | |
| 996 | |
| 997 status = INB(ioaddr + SCBGenStatus); | |
| 998 | |
| 999 return status; | |
| 1077 } | 1000 } |
| 1078 | 1001 |
| 1079 // ------------------------------------------------------------------------ | 1002 // ------------------------------------------------------------------------ |
| 1080 // | 1003 // |
| 1081 // Function : BringDown82559 | 1004 // Function : BringDown82559 |
| 2014 ccs->config_bytes[1]=0x8; | 1937 ccs->config_bytes[1]=0x8; |
| 2015 ccs->config_bytes[2]=0x0; | 1938 ccs->config_bytes[2]=0x0; |
| 2016 ccs->config_bytes[3]=0x0; | 1939 ccs->config_bytes[3]=0x0; |
| 2017 ccs->config_bytes[4]=0x0; | 1940 ccs->config_bytes[4]=0x0; |
| 2018 ccs->config_bytes[5]=0x0; | 1941 ccs->config_bytes[5]=0x0; |
| 2019 ccs->config_bytes[6]=0xb2; | 1942 ccs->config_bytes[6]=0xb2; // (promisc ? 0x80 : 0) | 0x32 for small stats, |
| 2020 ccs->config_bytes[7]=0x0; | 1943 ccs->config_bytes[7]=0x0; // \ ditto | 0x12 for stats with PAUSE stats |
| 2021 ccs->config_bytes[8]=0x0; | 1944 ccs->config_bytes[8]=0x0; // \ ditto | 0x16 for PAUSE + TCO stats |
| 2022 ccs->config_bytes[9]=0x0; | 1945 ccs->config_bytes[9]=0x0; |
| 2023 ccs->config_bytes[10]=0x28; | 1946 ccs->config_bytes[10]=0x28; |
| 2024 ccs->config_bytes[11]=0x0; | 1947 ccs->config_bytes[11]=0x0; |
| 2025 ccs->config_bytes[12]=0x60; | 1948 ccs->config_bytes[12]=0x60; |
| 2026 ccs->config_bytes[13]=0x0; // arp | 1949 ccs->config_bytes[13]=0x0; // arp |
| 2027 ccs->config_bytes[14]=0x0; // arp | 1950 ccs->config_bytes[14]=0x0; // arp |
| 2028 | 1951 |
| 2029 ccs->config_bytes[15]=0x81; // promiscuous mode set | 1952 ccs->config_bytes[15]=0x81; // promiscuous mode set |
| 2030 | 1953 // \ or 0x80 for normal mode. |
| 2031 ccs->config_bytes[16]=0x0; | 1954 ccs->config_bytes[16]=0x0; |
| 2032 ccs->config_bytes[17]=0x40; | 1955 ccs->config_bytes[17]=0x40; |
| 2033 ccs->config_bytes[18]=0x70; | 1956 ccs->config_bytes[18]=0x70; |
| 2034 | 1957 |
| 2035 // wait for SCB command complete | 1958 // wait for SCB command complete |
| 2371 default: | 2294 default: |
| 2372 break; | 2295 break; |
| 2373 } | 2296 } |
| 2374 return -1; | 2297 return -1; |
| 2375 } | 2298 } |
| 2299 | |
| 2300 // ------------------------------------------------------------------------ | |
| 2301 // | |
| 2302 // Statistics update... | |
| 2303 // | |
| 2304 // ------------------------------------------------------------------------ | |
| 2305 | |
| 2306 #ifdef KEEP_STATISTICS | |
| 2307 void update_statistics(struct i82559* p_i82559) | |
| 2308 { | |
| 2309 I82559_COUNTERS *p_statistics; | |
| 2310 cyg_uint32 *p_counter; | |
| 2311 cyg_uint32 *p_register; | |
| 2312 int reg_count; | |
| 2313 | |
| 2314 Mask82559Interrupt(p_i82559); | |
| 2315 | |
| 2316 // This points to the sthared memory stats area/command block | |
| 2317 p_statistics = (I82559_COUNTERS *)(p_i82559->p_statistics); | |
| 2318 | |
| 2319 if ( (p_statistics->done & 0xFFFF) == 0xA007 ) { | |
| 2320 p_counter = (cyg_uint32 *)&i82559_counters[ p_i82559->index ]; | |
| 2321 p_register = (cyg_uint32 *)p_statistics; | |
| 2322 for ( reg_count = 0; | |
| 2323 reg_count < sizeof( I82559_COUNTERS ) / sizeof( cyg_uint32 ) - 1; | |
| 2324 reg_count++ ) { | |
| 2325 *p_counter += *p_register; | |
| 2326 p_counter++; | |
| 2327 p_register++; | |
| 2328 } | |
| 2329 p_statistics->done = 0; | |
| 2330 // make sure no command operating | |
| 2331 wait_for_cmd_done(p_i82559->io_address); | |
| 2332 // start register dump | |
| 2333 OUTW(CU_DUMPSTATS, p_i82559->io_address + SCBCmd); | |
| 2334 } | |
| 2335 Acknowledge82559Interrupt(p_i82559); | |
| 2336 UnMask82559Interrupt(p_i82559); | |
| 2337 } | |
| 2338 #endif // KEEP_STATISTICS | |
| 2376 | 2339 |
| 2377 // ------------------------------------------------------------------------ | 2340 // ------------------------------------------------------------------------ |
| 2378 // | 2341 // |
| 2379 // | 2342 // |
| 2380 // CODE FOR DEBUGGING PURPOSES ONLY | 2343 // CODE FOR DEBUGGING PURPOSES ONLY |
