Changeset 00bf7745 in rtems
- Timestamp:
- Mar 14, 2004, 1:28:08 AM (17 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 528da1c
- Parents:
- 27192b8
- Location:
- c/src/libchip/network
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/libchip/network/cs8900.c
r27192b8 r00bf7745 1 1 /* 2 2 ------------------------------------------------------------------------ 3 $Id$3 cs8900.c,v 1.5 2002/11/13 15:34:39 joel Exp 4 4 ------------------------------------------------------------------------ 5 6 My Right Boot, a boot ROM for embedded hardware. 7 5 8 6 Copyright Cybertec Pty Ltd, 2000 9 7 All rights reserved Cybertec Pty Ltd, 2000 10 8 9 Port to the DIMM PC copyright (c) 2004 Angelo Fraietta 10 This project has been assisted by the Commonwealth Government 11 through the Australia Council, its arts funding and advisory body. 12 11 13 COPYRIGHT (c) 1989-1998. 12 14 On-Line Applications Research Corporation (OAR). 15 Copyright assigned to U.S. Government, 1994. 13 16 14 17 The license and distribution terms for this file may be 15 18 found in the file LICENSE in this distribution or at 16 http://www. rtems.com/license/LICENSE.19 http://www.OARcorp.com/rtems/license.html. 17 20 18 21 ------------------------------------------------------------------------ 19 22 20 CS8900 net boot driver. 21 23 CS8900 RTEMS driver. 24 25 See the header file for details. 26 22 27 */ 23 28 … … 26 31 #include <stdio.h> 27 32 28 /* #include <target.h>29 chris explain what this is to contain and provide a default one */30 33 #include "cs8900.h" 31 32 /***********************************************************33 ***********************************************************34 BEGIN SECTION OF DEFAULT DEFINES35 ***********************************************************36 ***********************************************************/37 38 /*39 * Number of devices supported by this driver40 */41 #ifndef CS8900_DEVICES42 #define CS8900_DEVICES 143 #endif44 45 /*46 * This variable really should come from a per device configuration47 * table so the base can vary by adapter.48 */49 50 #ifndef CS8900_IO_BASE51 extern unsigned int bsp_cs8900_io_base;52 #define CS8900_IO_BASE bsp_cs8900_io_base53 #endif54 55 /*56 * This variable really should come from a per device configuration57 * table so the base can vary by adapter.58 */59 60 #ifndef CS8900_MEMORY_BASE61 extern unsigned int bsp_cs8900_memory_base;62 #define CS8900_MEMORY_BASE bsp_cs8900_memory_base63 #endif64 65 /*66 * This could go to a BSP provided callout.67 */68 #ifndef WATCHDOG_TOGGLE69 #define WATCHDOG_TOGGLE()70 #endif71 72 /*73 * This variable really should come from a per device configuration74 * table so the base can vary by adapter.75 *76 * chris this is probably not a good default --joel77 */78 79 #ifndef CS8900_RX_QUEUE_SIZE80 #define CS8900_RX_QUEUE_SIZE 181 #endif82 83 /***********************************************************84 ***********************************************************85 END SECTION OF DEFAULT DEFINES86 ***********************************************************87 ***********************************************************/88 34 89 35 /* … … 105 51 106 52 /* 107 * Our local data.108 */109 110 static cs8900_device cs8900[CS8900_DEVICES];111 112 /*113 53 * IO Packet Page inteface. 114 54 */ 115 55 116 56 static inline unsigned short 117 io_pp_get_reg_16 (int dev, unsigned short reg) 118 { 119 cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR, 57 io_pp_get_reg_16 (cs8900_device *cs, unsigned short reg) 58 { 59 rtems_interrupt_level level; 60 unsigned short data; 61 rtems_interrupt_disable (level); 62 cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR, 120 63 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg); 121 return cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0); 64 data = cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT0); 65 rtems_interrupt_enable (level); 66 return data; 122 67 } 123 68 124 69 static inline unsigned long 125 io_pp_get_reg_32 (int dev, unsigned short reg) 126 { 127 cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR, 70 io_pp_get_reg_32 (cs8900_device *cs, unsigned short reg) 71 { 72 rtems_interrupt_level level; 73 unsigned long data; 74 rtems_interrupt_disable (level); 75 cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR, 128 76 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg); 129 return ((cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0) << 16) | 130 cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT1)); 77 data = ((cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT0) << 16) | 78 cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT1)); 79 rtems_interrupt_enable (level); 80 return data; 131 81 } 132 82 133 83 static inline void 134 io_pp_set_reg_16 (int dev, unsigned short reg, unsigned short data) 135 { 136 cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR, 84 io_pp_set_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short data) 85 { 86 rtems_interrupt_level level; 87 rtems_interrupt_disable (level); 88 cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR, 137 89 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg); 138 cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0, data); 90 cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT0, data); 91 rtems_interrupt_enable (level); 139 92 } 140 93 141 94 static inline void 142 io_pp_set_reg_32 ( int dev, unsigned short reg, unsigned long data)143 { 144 cs8900_io_set_reg ( dev, CS8900_IO_BASE +CS8900_IO_PACKET_PAGE_PTR,95 io_pp_set_reg_32 (cs8900_device *cs, unsigned short reg, unsigned long data) 96 { 97 cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR, 145 98 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg); 146 cs8900_io_set_reg ( dev, CS8900_IO_BASE +CS8900_IO_PP_DATA_PORT0, data >> 16);147 cs8900_io_set_reg ( dev, CS8900_IO_BASE +CS8900_IO_PP_DATA_PORT1, data);99 cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT0, data >> 16); 100 cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT1, data); 148 101 } 149 102 150 103 static inline void 151 io_pp_bit_set_reg_16 (int dev, unsigned short reg, unsigned short mask) 152 { 153 io_pp_set_reg_16 (dev, reg, io_pp_get_reg_16 (dev, reg) | mask); 104 io_pp_bit_set_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short mask) 105 { 106 rtems_interrupt_level level; 107 rtems_interrupt_disable (level); 108 io_pp_set_reg_16 (cs, reg, io_pp_get_reg_16 (cs, reg) | mask); 109 rtems_interrupt_enable (level); 154 110 } 155 111 156 112 static inline void 157 io_pp_bit_clear_reg_16 (int dev, unsigned short reg, unsigned short mask) 158 { 159 io_pp_set_reg_16 (dev, reg, io_pp_get_reg_16 (dev, reg) & ~mask); 113 io_pp_bit_clear_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short mask) 114 { 115 rtems_interrupt_level level; 116 rtems_interrupt_disable (level); 117 io_pp_set_reg_16 (cs, reg, io_pp_get_reg_16 (cs, reg) & ~mask); 118 rtems_interrupt_enable (level); 160 119 } 161 120 162 121 /* 163 122 * Memory Mapped Packet Page interface. 123 * 124 * If the BSP does not configure mem_base use the I/O register accesses. 164 125 */ 165 126 166 127 static inline unsigned short 167 mem_pp_get_reg (int dev, unsigned short reg) 168 { 169 return cs8900_mem_get_reg (dev, CS8900_MEMORY_BASE + reg); 128 mem_pp_get_reg (cs8900_device *cs, unsigned short reg) 129 { 130 if (!cs->mem_base) 131 return io_pp_get_reg_16 (cs, reg); 132 return cs8900_mem_get_reg (cs, reg); 170 133 } 171 134 172 135 static inline void 173 mem_pp_set_reg (int dev, unsigned short reg, unsigned short data) 174 { 175 cs8900_mem_set_reg (dev, CS8900_MEMORY_BASE + reg, data); 136 mem_pp_set_reg (cs8900_device *cs, unsigned short reg, unsigned short data) 137 { 138 if (!cs->mem_base) 139 io_pp_set_reg_16 (cs, reg, data); 140 else 141 cs8900_mem_set_reg (cs, reg, data); 176 142 } 177 143 178 144 static inline void 179 mem_pp_bit_set_reg (int dev, unsigned short reg, unsigned short mask) 180 { 181 mem_pp_set_reg (dev, reg, mem_pp_get_reg (dev, reg) | mask); 145 mem_pp_bit_set_reg (cs8900_device *cs, unsigned short reg, unsigned short mask) 146 { 147 if (!cs->mem_base) 148 io_pp_bit_set_reg_16 (cs, reg, mask); 149 else 150 { 151 rtems_interrupt_level level; 152 rtems_interrupt_disable (level); 153 mem_pp_set_reg (cs, reg, mem_pp_get_reg (cs, reg) | mask); 154 rtems_interrupt_enable (level); 155 } 182 156 } 183 157 184 158 static inline void 185 mem_pp_bit_clear_reg (int dev, unsigned short reg, unsigned short mask) 186 { 187 mem_pp_set_reg (dev, reg, mem_pp_get_reg (dev, reg) & ~mask); 159 mem_pp_bit_clear_reg (cs8900_device *cs, unsigned short reg, unsigned short mask) 160 { 161 if (!cs->mem_base) 162 io_pp_bit_clear_reg_16 (cs, reg, mask); 163 else 164 { 165 rtems_interrupt_level level; 166 rtems_interrupt_disable (level); 167 mem_pp_set_reg (cs, reg, mem_pp_get_reg (cs, reg) & ~mask); 168 rtems_interrupt_enable (level); 169 } 188 170 } 189 171 … … 191 173 * Trace defines and control structures. 192 174 */ 193 175 194 176 #define CS8900_T_INT (0) 195 177 #define CS8900_T_RX_OK (1) … … 223 205 { 224 206 rtems_interrupt_level level; 225 207 226 208 rtems_interrupt_disable (level); 227 209 228 210 if (cs->trace_in < CS8900_TRACE_SIZE) 229 211 { … … 233 215 cs->trace_in++; 234 216 } 235 217 236 218 rtems_interrupt_enable (level); 237 219 } … … 240 222 #endif 241 223 224 void cs8900_get_mac_addr (cs8900_device *cs, unsigned char *mac_address) 225 { 226 unsigned short ma; 227 228 /* 229 * Only ever use IO calls for this function as it can be 230 * called before memory mode has been enabled. 231 */ 232 233 ma = io_pp_get_reg_16 (cs, CS8900_PP_IA); 234 mac_address[0] = ma >> 8; 235 mac_address[1] = ma; 236 237 ma = io_pp_get_reg_16 (cs, CS8900_PP_IA + 2); 238 mac_address[2] = ma >> 8; 239 mac_address[3] = ma; 240 241 ma = io_pp_get_reg_16 (cs, CS8900_PP_IA + 4); 242 mac_address[4] = ma >> 8; 243 mac_address[5] = ma; 244 } 245 242 246 /* 243 247 * Bring the chip online. … … 249 253 unsigned long prod_id; 250 254 unsigned short status; 251 int dev = cs->dev;252 255 253 256 /* … … 255 258 * We must wait 20msecs. 256 259 */ 257 258 io_pp_bit_set_reg_16 ( dev, CS8900_PP_SelfCTL, CS8900_SELF_CTRL_RESET);260 261 io_pp_bit_set_reg_16 (cs, CS8900_PP_SelfCTL, CS8900_SELF_CTRL_RESET); 259 262 260 263 rtems_task_wake_after (TOD_MILLISECONDS_TO_TICKS (20)); 261 262 status = io_pp_get_reg_16 ( dev, CS8900_PP_SelfST);264 265 status = io_pp_get_reg_16 (cs, CS8900_PP_SelfST); 263 266 if (status == 0) { 264 267 printf("Reading status register again\n"); 265 status = io_pp_get_reg_16 ( dev, CS8900_PP_SelfST);266 } 267 268 status = io_pp_get_reg_16 (cs, CS8900_PP_SelfST); 269 } 270 268 271 if (((status & CS8900_SELF_STATUS_INITD) == 0) || 269 272 ((status & CS8900_SELF_STATUS_INITD) && … … 274 277 (status & CS8900_SELF_STATUS_INITD) ? 275 278 "EEPROM read/write failed to complete" : 276 "Failed to complete to reset"); 279 "Failed to complete to reset"); 277 280 return; 278 281 } 279 282 283 /* Set the RX queue size if not set by the BSP. */ 284 285 if (cs->rx_queue_size == 0) 286 cs->rx_queue_size = 10; 287 280 288 /* Probe the device for its ID */ 281 289 282 prod_id = io_pp_get_reg_32 ( dev, CS8900_PP_PROD_ID);290 prod_id = io_pp_get_reg_32 (cs, CS8900_PP_PROD_ID); 283 291 284 292 if ((prod_id >> 16) != CS8900_ESIA_ID) 285 293 { 286 printf ("CS 9800: Invalid EISA ID, read product code 0x%08lx\n", prod_id);294 printf ("CS8900: Invalid EISA ID, read product code 0x%08lx\n", prod_id); 287 295 return; 288 296 } … … 290 298 if ((prod_id & 0x000000ff) != 0) 291 299 { 292 printf ("CS 9800: Unsupported product id, read product code 0x%08lx\n",300 printf ("CS8900: Unsupported product id, read product code 0x%08lx\n", 293 301 prod_id); 294 302 return; … … 304 312 * Switch to memory base accesses as they are faster. No indirect access. 305 313 */ 306 307 io_pp_set_reg_16 (dev, CS8900_PP_MEM_BASE, CS8900_MEMORY_BASE); 308 io_pp_set_reg_16 (dev, CS8900_PP_MEM_BASE + 2, (CS8900_MEMORY_BASE >> 16) & 0xf); 309 310 io_pp_set_reg_16 (dev, 311 CS8900_PP_BusCTL, 312 CS8900_BUS_CTRL_RESET_RX_DMA | 313 CS8900_BUS_CTRL_USE_SA | 314 CS8900_BUS_CTRL_MEMORY_ENABLE); 315 io_pp_set_reg_16 (dev, 316 CS8900_PP_BusCTL, 317 CS8900_BUS_CTRL_USE_SA | 318 CS8900_BUS_CTRL_MEMORY_ENABLE); 314 315 if (cs->mem_base) 316 { 317 io_pp_set_reg_16 (cs, CS8900_PP_MEM_BASE, cs->mem_base); 318 io_pp_set_reg_16 (cs, CS8900_PP_MEM_BASE + 2, (cs->mem_base >> 16) & 0xf); 319 320 io_pp_set_reg_16 (cs, 321 CS8900_PP_BusCTL, 322 CS8900_BUS_CTRL_RESET_RX_DMA | 323 CS8900_BUS_CTRL_USE_SA | 324 CS8900_BUS_CTRL_MEMORY_ENABLE); 325 io_pp_set_reg_16 (cs, 326 CS8900_PP_BusCTL, 327 CS8900_BUS_CTRL_USE_SA | 328 CS8900_BUS_CTRL_MEMORY_ENABLE); 329 } 319 330 320 331 /* … … 328 339 */ 329 340 330 mem_pp_set_reg ( dev, CS8900_PP_LineCFG, CS8900_LINE_CTRL_10BASET);331 341 mem_pp_set_reg (cs, CS8900_PP_LineCFG, CS8900_LINE_CTRL_10BASET); 342 332 343 /* 333 344 * Ask the user for the MAC address, the program into the device. … … 335 346 336 347 #define MACO(o) cs->arpcom.ac_enaddr[o] 337 338 mem_pp_set_reg ( dev, CS8900_PP_IA,348 349 mem_pp_set_reg (cs, CS8900_PP_IA, 339 350 (((unsigned int) MACO (1)) << 8) | 340 351 ((unsigned int) MACO (0))); 341 mem_pp_set_reg ( dev, CS8900_PP_IA + 2,352 mem_pp_set_reg (cs, CS8900_PP_IA + 2, 342 353 (((unsigned int) MACO (3)) << 8) | 343 354 ((unsigned int) MACO (2))); 344 mem_pp_set_reg ( dev, CS8900_PP_IA + 4,355 mem_pp_set_reg (cs, CS8900_PP_IA + 4, 345 356 (((unsigned int) MACO (5)) << 8) | 346 357 ((unsigned int) MACO (4))); … … 350 361 */ 351 362 352 mem_pp_set_reg ( dev, CS8900_PP_BufCFG,363 mem_pp_set_reg (cs, CS8900_PP_BufCFG, 353 364 CS8900_BUFFER_CONFIG_RDY_FOR_TX | 354 365 CS8900_BUFFER_CONFIG_TX_UNDERRUN | … … 360 371 */ 361 372 362 mem_pp_set_reg ( dev, CS8900_PP_RxCFG,373 mem_pp_set_reg (cs, CS8900_PP_RxCFG, 363 374 CS8900_RX_CONFIG_RX_OK | 364 375 CS8900_RX_CONFIG_CRC_ERROR | … … 370 381 */ 371 382 372 mem_pp_set_reg ( dev, CS8900_PP_RxCTL,383 mem_pp_set_reg (cs, CS8900_PP_RxCTL, 373 384 CS8900_RX_CTRL_RX_OK | 374 385 CS8900_RX_CTRL_MULTICAST | 375 386 CS8900_RX_CTRL_INDIVIDUAL | 376 387 CS8900_RX_CTRL_BROADCAST); 377 388 378 389 /* 379 390 * Set the Transmitter configuration. 380 391 */ 381 392 382 mem_pp_set_reg ( dev, CS8900_PP_TxCFG,393 mem_pp_set_reg (cs, CS8900_PP_TxCFG, 383 394 CS8900_TX_CONFIG_TX_OK | 384 395 CS8900_TX_CONFIG_OUT_OF_WINDOW | … … 390 401 */ 391 402 392 cs8900_attach_interrupt ( dev,cs);393 403 cs8900_attach_interrupt (cs); 404 394 405 /* 395 406 * Program the interrupt level we require then enable interrupts. 396 */ 397 398 mem_pp_set_reg (dev, CS8900_PP_INT, 0); 399 400 mem_pp_bit_set_reg (dev, CS8900_PP_BusCTL, 407 * 408 * Note, this will need to change to support other levels. 409 */ 410 411 mem_pp_set_reg (cs, CS8900_PP_INT, cs->irq_level & 3); 412 413 mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL, 401 414 CS8900_BUS_CTRL_ENABLE_INT); 402 415 } … … 406 419 { 407 420 cs8900_device *cs = csp; 408 int dev = cs->dev;409 421 unsigned short isq = 0; 410 422 struct mbuf *m; … … 415 427 while (1) 416 428 { 417 isq = mem_pp_get_reg ( dev, CS8900_PP_ISQ);429 isq = mem_pp_get_reg (cs, CS8900_PP_ISQ); 418 430 419 431 cs8900_trace (cs, CS8900_T_INT, isq); 420 432 421 WATCHDOG_TOGGLE ();422 423 433 /* 424 434 * No more interrupts to service. … … 427 437 if (isq == 0) 428 438 return; 429 439 430 440 switch (isq & 0x1f) 431 441 { … … 448 458 m->m_nextpkt = 0; 449 459 cs->rx_ready_len--; 450 460 451 461 p = mtod (m, unsigned char *); 452 453 m->m_pkthdr.len = cs8900_get_data_block ( dev, p);462 463 m->m_pkthdr.len = cs8900_get_data_block (cs, p); 454 464 455 465 if (cs->rx_loaded_tail == 0) … … 462 472 if (cs->rx_loaded_len == 1) 463 473 { 464 cs8900_trace (cs, CS8900_T_RX_OK, cs->rx_loaded_len); 474 cs8900_trace (cs, CS8900_T_RX_OK, cs->rx_loaded_len); 465 475 rtems_event_send (cs->rx_task, CS8900_RX_OK_EVENT); 466 476 } … … 469 479 { 470 480 ++cs->eth_stats.rx_dropped; 471 472 cs8900_trace (cs, CS8900_T_RX_DROPPED, cs->rx_loaded_len); 481 482 cs8900_trace (cs, CS8900_T_RX_DROPPED, cs->rx_loaded_len); 473 483 474 484 if (cs->rx_loaded_len == 0) … … 483 493 if (isq & CS8900_RX_EVENT_RUNT) 484 494 ++cs->eth_stats.rx_runt_errors; 485 495 486 496 if (isq & CS8900_RX_EVENT_EXTRA_DATA) 487 497 ++cs->eth_stats.rx_oversize_errors; … … 490 500 491 501 case 0x08: 492 502 493 503 /* 494 504 * TxEvent. … … 503 513 504 514 cs->tx_active = 0; 505 515 506 516 rtems_event_send (cs->tx_task, CS8900_TX_OK_EVENT); 507 517 } … … 509 519 510 520 case 0x0c: 511 521 512 522 /* 513 523 * BufEvent. 514 524 */ 515 525 516 526 if (isq & CS8900_BUFFER_EVENT_RDY_FOR_TX) 517 527 { … … 535 545 536 546 case 0x10: 537 547 538 548 /* 539 549 * RxMiss. 540 550 */ 541 551 542 552 cs->eth_stats.rx_missed_errors += 543 mem_pp_get_reg ( dev, CS8900_PP_RxMISS) >> 6;553 mem_pp_get_reg (cs, CS8900_PP_RxMISS) >> 6; 544 554 break; 545 555 546 556 case 0x12: 547 557 548 558 /* 549 559 * TxCol. … … 551 561 552 562 cs->eth_stats.tx_collisions += 553 mem_pp_get_reg ( dev, CS8900_PP_TxCol) >> 6;563 mem_pp_get_reg (cs, CS8900_PP_TxCol) >> 6; 554 564 break; 555 565 … … 558 568 } 559 569 } 560 570 561 571 } 562 572 563 573 int 564 cs8900_link_active ( int dev)565 { 566 return ((mem_pp_get_reg ( dev, CS8900_PP_LineST) & CS8900_LINE_STATUS_LINK_OK) ?574 cs8900_link_active (cs8900_device *cs) 575 { 576 return ((mem_pp_get_reg (cs, CS8900_PP_LineST) & CS8900_LINE_STATUS_LINK_OK) ? 567 577 1 : 0); 568 578 } … … 574 584 struct mbuf *m; 575 585 rtems_interrupt_level level; 576 586 577 587 /* 578 588 * Hold a single queue of mbuf's at the interface. This … … 580 590 */ 581 591 582 while (cs->rx_ready_len < CS8900_RX_QUEUE_SIZE)592 while (cs->rx_ready_len < cs->rx_queue_size) 583 593 { 584 594 MGETHDR (m, M_DONTWAIT, MT_DATA); 585 595 586 596 if (!m) 587 597 { 588 598 ++cs->eth_stats.rx_no_mbufs; 589 cs8900_trace (cs, CS8900_T_NO_MBUF, cs->eth_stats.rx_no_mbufs); 599 cs8900_trace (cs, CS8900_T_NO_MBUF, cs->eth_stats.rx_no_mbufs); 590 600 return; 591 601 } 592 602 593 603 MCLGET (m, M_DONTWAIT); 594 604 595 605 if (!m->m_ext.ext_buf) 596 606 { 597 607 ++cs->eth_stats.rx_no_clusters; 598 cs8900_trace (cs, CS8900_T_NO_CLUSTERS, cs->eth_stats.rx_no_clusters); 608 cs8900_trace (cs, CS8900_T_NO_CLUSTERS, cs->eth_stats.rx_no_clusters); 599 609 m_free (m); 600 610 return; … … 604 614 605 615 rtems_interrupt_disable (level); 606 616 607 617 if (cs->rx_ready_tail == 0) 608 618 cs->rx_ready_head = m; … … 620 630 { 621 631 cs8900_device *cs = arg; 622 int dev = cs->dev;623 632 struct ifnet *ifp = &cs->arpcom.ac_if; 624 633 rtems_event_set events; … … 631 640 * Turn the receiver and transmitter on. 632 641 */ 633 634 mem_pp_bit_set_reg ( dev, CS8900_PP_LineCFG,642 643 mem_pp_bit_set_reg (cs, CS8900_PP_LineCFG, 635 644 CS8900_LINE_CTRL_RX_ON | 636 645 CS8900_LINE_CTRL_TX_ON); 637 646 638 647 /* 639 648 * Start the software interrupt watchdog. 640 649 */ 641 642 rtems_interrupt_disable (level); 643 mem_pp_bit_set_reg (dev, CS8900_PP_BufCFG, 650 651 mem_pp_bit_set_reg (cs, CS8900_PP_BufCFG, 644 652 CS8900_BUFFER_CONFIG_SW_INT); 645 653 ++cs->eth_stats.int_swint_req; 646 rtems_interrupt_enable (level); 647 654 648 655 /* 649 656 * Loop reading packets. … … 653 660 { 654 661 cs8900_rx_refill_queue (cs); 655 662 656 663 sc = rtems_bsdnet_event_receive (CS8900_RX_OK_EVENT, 657 664 RTEMS_WAIT | RTEMS_EVENT_ANY, … … 660 667 661 668 cs8900_rx_refill_queue (cs); 662 669 663 670 if (sc == RTEMS_TIMEOUT) 664 671 { … … 676 683 printf ("cs8900: int lockup, isq flush\n"); 677 684 678 mem_pp_bit_clear_reg ( dev, CS8900_PP_BusCTL,685 mem_pp_bit_clear_reg (cs, CS8900_PP_BusCTL, 679 686 CS8900_BUS_CTRL_ENABLE_INT); 680 681 while (mem_pp_get_reg ( dev, CS8900_PP_ISQ) != 0);682 687 688 while (mem_pp_get_reg (cs, CS8900_PP_ISQ) != 0); 689 683 690 cs->eth_stats.int_swint_req = cs->eth_stats.int_swint_res = 0; 684 691 ++cs->eth_stats.int_lockup; 685 686 mem_pp_bit_set_reg ( dev, CS8900_PP_BusCTL,692 693 mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL, 687 694 CS8900_BUS_CTRL_ENABLE_INT); 688 695 } 689 690 rtems_interrupt_disable (level); 691 mem_pp_bit_set_reg (dev, CS8900_PP_BufCFG, 696 697 mem_pp_bit_set_reg (cs, CS8900_PP_BufCFG, 692 698 CS8900_BUFFER_CONFIG_SW_INT); 693 699 ++cs->eth_stats.int_swint_req; 694 rtems_interrupt_enable (level);695 700 } 696 701 697 702 cs8900_trace (cs, CS8900_T_RX_BEGIN, cs->rx_loaded_len); 698 703 699 704 while (cs->rx_loaded_len) 700 705 { 701 706 rtems_interrupt_disable (level); 702 707 703 708 m = cs->rx_loaded_head; 704 709 if (m) … … 709 714 m->m_nextpkt = 0; 710 715 cs->rx_loaded_len--; 711 716 712 717 rtems_interrupt_enable (level); 713 718 714 719 m->m_pkthdr.rcvif = ifp; 715 720 716 721 cs->eth_stats.rx_bytes += m->m_pkthdr.len; 717 722 718 723 m->m_len = m->m_pkthdr.len = m->m_pkthdr.len - sizeof (struct ether_header); 719 724 720 725 eh = mtod (m, struct ether_header *); 721 726 m->m_data += sizeof (struct ether_header); 722 727 723 728 ++cs->eth_stats.rx_packets; 724 729 725 730 ether_input (ifp, eh, m); 726 731 } … … 738 743 { 739 744 cs8900_device *cs = arg; 740 int dev = cs->dev;741 745 struct ifnet *ifp = &cs->arpcom.ac_if; 742 746 rtems_event_set events; … … 777 781 else 778 782 { 779 if (cs8900_link_active ( dev))783 if (cs8900_link_active (cs)) 780 784 { 781 785 int resending; 782 786 783 787 do 784 788 { … … 786 790 787 791 resending = 0; 788 792 789 793 cs->tx_active = 1; 790 791 mem_pp_set_reg ( dev, CS8900_PP_TxCMD,794 795 mem_pp_set_reg (cs, CS8900_PP_TxCMD, 792 796 CS8900_TX_CMD_STATUS_TX_START_ENTIRE | 793 797 CS8900_TX_CMD_STATUS_FORCE); 794 mem_pp_set_reg ( dev, CS8900_PP_TxLength, m->m_pkthdr.len);795 796 buf_status = mem_pp_get_reg ( dev, CS8900_PP_BusST);798 mem_pp_set_reg (cs, CS8900_PP_TxLength, m->m_pkthdr.len); 799 800 buf_status = mem_pp_get_reg (cs, CS8900_PP_BusST); 797 801 798 802 /* … … 808 812 * If the buffer is not read enable the interrupt and then wait. 809 813 */ 810 814 811 815 if ((buf_status & CS8900_BUS_STATUS_RDY_FOR_TX_NOW) == 0) 812 816 { … … 831 835 if (!resending) 832 836 { 833 cs8900_tx_load ( dev, m);837 cs8900_tx_load (cs, m); 834 838 cs->eth_stats.tx_packets++; 835 839 cs->eth_stats.tx_bytes += m->m_pkthdr.len; … … 838 842 } 839 843 while (resending); 840 844 841 845 m_freem (m); 842 846 843 847 do 844 848 { … … 876 880 cs8900_stop (cs8900_device *cs) 877 881 { 878 int dev = cs->dev; 879 880 mem_pp_bit_clear_reg (dev, CS8900_PP_LineCFG, 882 mem_pp_bit_clear_reg (cs, CS8900_PP_LineCFG, 881 883 CS8900_LINE_CTRL_RX_ON | 882 884 CS8900_LINE_CTRL_TX_ON); 883 884 mem_pp_bit_clear_reg ( dev, CS8900_PP_BusCTL,885 886 mem_pp_bit_clear_reg (cs, CS8900_PP_BusCTL, 885 887 CS8900_BUS_CTRL_ENABLE_INT); 886 888 } … … 918 920 cs8900_stats (cs8900_device *cs) 919 921 { 920 int dev = cs->dev;921 922 int i; 922 923 int max_label = 0; … … 925 926 926 927 cs->eth_stats.rx_missed_errors += 927 mem_pp_get_reg ( dev, CS8900_PP_RxMISS) >> 6;928 928 mem_pp_get_reg (cs, CS8900_PP_RxMISS) >> 6; 929 929 930 cs->eth_stats.tx_collisions += 930 mem_pp_get_reg ( dev, CS8900_PP_TxCol) >> 6;931 931 mem_pp_get_reg (cs, CS8900_PP_TxCol) >> 6; 932 932 933 printf ("Network Driver Stats for CS8900 :\n"); 933 934 … … 944 945 max_label, "rx ready len", cs->rx_ready_len, 945 946 max_label, "rx loaded len", cs->rx_loaded_len); 946 947 947 948 for (i = 0; 948 949 i < (sizeof (eth_statistics_labels) / sizeof (const char *)); … … 951 952 printf ("%*s - %10lu", 952 953 max_label, eth_statistics_labels[i], value[i]); 953 954 954 955 i++; 955 956 956 957 if (i < (sizeof (eth_statistics_labels) / sizeof (const char *))) 957 958 printf (" %*s - %10lu", … … 961 962 962 963 #if CS8900_TRACE 963 964 964 965 for (i = 0; i < cs->trace_in; i++) 965 966 { 966 967 printf ("%8ld.%03ld ", cs->trace_time[i] / 1000, cs->trace_time[i] % 1000); 967 968 968 969 if (cs->trace_key[i] < sizeof (cs8900_trace_labels) / sizeof (char*)) 969 970 printf ("%s : ", cs8900_trace_labels[cs->trace_key[i]]); … … 1003 1004 printf ("tx request"); 1004 1005 break; 1005 1006 1006 1007 case 0x1e: 1007 1008 printf ("tx wait 4 tx"); 1008 1009 break; 1009 1010 1010 1011 case 0x1d: 1011 1012 printf ("tx already active"); 1012 1013 break; 1013 1014 1014 1015 default: 1015 1016 printf ("unknown event"); … … 1020 1021 else 1021 1022 printf ("0x%08lx", cs->trace_var[i]); 1022 1023 1023 1024 printf ("\n"); 1024 1025 } 1025 1026 1026 1027 cs->trace_in = 0; 1027 1028 1028 1029 #endif 1029 1030 } … … 1033 1034 { 1034 1035 cs8900_device *cs = arg; 1035 int dev = cs->dev;1036 1036 struct ifnet *ifp = &cs->arpcom.ac_if; 1037 1037 … … 1042 1042 * Set up the hardware. 1043 1043 */ 1044 1044 1045 1045 cs8900_hardware_init (cs); 1046 1046 … … 1048 1048 * Start driver task. We have only one task. 1049 1049 */ 1050 1050 1051 1051 cs->rx_task = rtems_bsdnet_newproc ("CSr0", 4096, cs8900_rx_task, cs); 1052 1052 cs->tx_task = rtems_bsdnet_newproc ("CSt0", 4096, cs8900_tx_task, cs); … … 1060 1060 else 1061 1061 #endif 1062 1062 1063 1063 /* 1064 1064 * Tell the world that we're running. 1065 1065 */ 1066 1066 1067 1067 ifp->if_flags |= IFF_RUNNING; 1068 1068 1069 1069 /* 1070 * Set the Line Control to bring the receive and transmitter online. 1071 */ 1072 1073 mem_pp_bit_set_reg ( dev, CS8900_PP_LineCFG,1070 * Set the Line Control to bring the receive and transmitter online. 1071 */ 1072 1073 mem_pp_bit_set_reg (cs, CS8900_PP_LineCFG, 1074 1074 CS8900_LINE_CTRL_RX_ON | 1075 1075 CS8900_LINE_CTRL_TX_ON); 1076 1076 1077 mem_pp_bit_set_reg ( dev, CS8900_PP_BusCTL,1077 mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL, 1078 1078 CS8900_BUS_CTRL_ENABLE_INT); 1079 1079 } … … 1089 1089 case SIOCGIFADDR: 1090 1090 case SIOCSIFADDR: 1091 1091 1092 1092 error = ether_ioctl (ifp, cmd, data); 1093 1093 break; 1094 1094 1095 1095 case SIOCSIFFLAGS: 1096 1096 1097 1097 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) 1098 1098 { 1099 1099 case IFF_RUNNING: 1100 1100 1101 1101 cs8900_stop (cs); 1102 1102 break; 1103 1103 1104 1104 case IFF_UP: 1105 1105 1106 1106 cs8900_init (cs); 1107 1107 break; 1108 1108 1109 1109 case IFF_UP | IFF_RUNNING: 1110 1110 1111 1111 cs8900_stop (cs); 1112 1112 cs8900_init (cs); … … 1119 1119 1120 1120 case SIO_RTEMS_SHOW_STATS: 1121 1121 1122 1122 cs8900_stats (cs); 1123 1123 break; … … 1145 1145 * Parse driver name 1146 1146 */ 1147 1147 1148 1148 if ((unit = rtems_bsdnet_parse_driver_name (config, &name)) < 0) 1149 1149 return 0; 1150 1151 /* 1152 * Is driver free? 1153 */ 1154 1155 if (unit >= CS8900_DEVICES) 1156 { 1157 printf ("Bad CS8900 unit number for device `%s'.\n", config->name); 1158 return 0; 1159 } 1160 1161 cs = &cs8900[unit]; 1150 1151 cs = config->drv_ctrl; 1162 1152 cs->dev = unit; 1163 1153 ifp = &cs->arpcom.ac_if; … … 1174 1164 * Process options 1175 1165 */ 1176 1166 1177 1167 if (config->hardware_address) 1178 1168 memcpy (cs->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); 1179 1169 else 1180 cs8900_get_mac_addr ( unit, cs->arpcom.ac_enaddr);1181 1170 cs8900_get_mac_addr (cs, cs->arpcom.ac_enaddr); 1171 1182 1172 if (config->mtu) 1183 1173 mtu = config->mtu; 1184 1174 else 1185 1175 mtu = ETHERMTU; 1186 1176 1187 1177 cs->accept_bcast = !config->ignore_broadcast; 1188 1178 1189 1179 /* 1190 1180 * Set up network interface values. 1191 1181 */ 1192 1182 1193 1183 ifp->if_softc = cs; 1194 1184 ifp->if_unit = unit; … … 1200 1190 ifp->if_output = ether_output; 1201 1191 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 1202 1192 1203 1193 if (ifp->if_snd.ifq_maxlen == 0) 1204 1194 ifp->if_snd.ifq_maxlen = ifqmaxlen; 1205 1195 1206 1196 /* 1207 1197 * Attach the interface to the stack. 1208 1198 */ 1209 1199 1210 1200 if_attach (ifp); 1211 1201 ether_ifattach (ifp); … … 1220 1210 1221 1211 cs8900_stop (cs); 1222 cs8900_detach_interrupt ( unit);1223 } 1224 1212 cs8900_detach_interrupt (cs); 1213 } 1214 1225 1215 return 1; 1226 1227 } 1216 } -
c/src/libchip/network/cs8900.h
r27192b8 r00bf7745 1 1 /* 2 2 ------------------------------------------------------------------------ 3 $Id$3 cs8900.h,v 1.3 2002/09/07 23:09:47 joel Exp 4 4 ------------------------------------------------------------------------ 5 5 6 My Right Boot, a boot ROM for embedded hardware.7 8 6 Copyright Cybertec Pty Ltd, 2000 9 7 All rights reserved Cybertec Pty Ltd, 2000 10 8 9 Port to the DIMM PC copyright (c) 2004 Angelo Fraietta 10 This project has been assisted by the Commonwealth Government 11 through the Australia Council, its arts funding and advisory body. 12 11 13 COPYRIGHT (c) 1989-1998. 12 14 On-Line Applications Research Corporation (OAR). … … 14 16 The license and distribution terms for this file may be 15 17 found in the file LICENSE in this distribution or at 16 http://www. rtems.com/license/LICENSE.18 http://www.OARcorp.com/rtems/license.html. 17 19 18 20 ------------------------------------------------------------------------ 19 21 20 CS8900 net boot driver. 22 CS8900 RTEMS driver. 23 24 This is a generic driver that requires a BSP backend. The BSP backend 25 provides the glue to the specific bus for the target hardware. It has 26 been tested with Coldfire processors, and the PC. These targets have 27 completely different bus, byte order and interrupt structures. 28 29 An example BSP backend is provided in the pci386 BSP. 30 31 The BSP provides the following functions: 32 33 cs8900_io_set_reg 34 cs8900_io_get_reg 35 cs8900_mem_set_reg 36 cs8900_mem_get_reg 37 cs8900_put_data_block 38 cs8900_get_data_block 39 cs8900_tx_load 40 cs8900_attach_interrupt 41 cs8900_detach_interrupt 42 43 The header file provides documentation for these functions. There 44 are four types of functions. 45 46 The I/O set/get functions access the CS8900 I/O registers via the 47 I/O Mode. For example on a PC with an ISA bus you would use the 48 IA32 in/out port instructions. The cs8900_device structure passed 49 to these functions provide these functions with the I/O base 50 address. The BSP must provide these functions. 51 52 The Memory set/get functions access the CS8900 internal registers 53 and frame buffers directly from a 4K byte block of host memory. 54 Memory mode provides a faster access to the CS8900. The cs8900_device 55 structure passed to these functions provides the memory base 56 address. The BSP needs to provide these functions but they do not 57 need to be implemented if the mem_base field is set to 0. The 58 driver will use I/O mode only. 59 60 The Block transfer functions are used to read or write a block 61 of memory from the CS8900. This saves the driver making a number 62 of small calls. The BSP driver must know if I/O or Memory mode 63 can be used. 64 65 The final group of functions is to handle interrupts. The BSP 66 must take care of save and restoring any interrupt state 67 information. 68 69 The BSP declares a 'cs8900_device' structure for each device being 70 attached to the networking stack. It also creates a 71 'struct rtems_bsdnet_ifconfig' which is used to attach the interface 72 to the networking stack. The following code declares the BSD config: 73 74 static cs8900_device cs8900; 75 76 static struct rtems_bsdnet_ifconfig cs8900_ifconfig = 77 { 78 "cs0", 79 cs8900_driver_attach, 80 NULL, 81 NULL, 82 NULL, 83 NULL, 84 0, 85 0, 86 0, 87 0, 88 0, 89 0, 90 0, 91 0 92 }; 93 94 The device linked to the BSD config structure with: 95 96 cs8900_ifconfig.drv_ctrl = &cs8900; 97 98 If you have a specific hardware address you should point the BSD 99 config structure to that address. If you do not the driver will read 100 the MAC address from the CS8900. This assumes the CS8900 has read 101 the address from an external EEPROM or has been setup by a BIOS or 102 boot monitor. For EEPROM less you need to supply the MAC address. 103 104 Set the I/O and Memory base addresses. If the Memory base address 105 is 0 the driver will use I/O mode only. A typical initialisation 106 looks like: 107 108 printf ("RTEMS BSD Network initialisation.\n"); 109 rtems_bsdnet_initialize_network (); 110 111 #define ETHERNET_IO_BASE 0x300 112 #define ETHERNET_MEM_BASE 0 113 #define ETHERNET_IRQ_LEVEL 0 114 115 cs8900_device *cs = &cs8900; 116 117 memset (cs, 0, sizeof (cs8900_device)); 118 119 cs->dev = 0; 120 cs->io_base = ETHERNET_IO_BASE; 121 cs->mem_base = ETHERNET_MEM_BASE; 122 cs->irq_level = ETHERNET_IRQ_LEVEL; 123 cs->rx_queue_size = 30; 124 125 cs8900_ifconfig.drv_ctrl = &cs8900; 126 127 printf ("CS8900 initialisation\n"); 128 129 rtems_bsdnet_attach (&cs8900_ifconfig); 130 131 flags = IFF_UP; 132 if (rtems_bsdnet_ifconfig (cs8900_ifconfig.name, 133 SIOCSIFFLAGS, 134 &flags) < 0) 135 { 136 printf ("error: can't bring up %s: %s\n", 137 cs8900_ifconfig.name, strerror (errno)); 138 return; 139 } 140 141 rtems_bsdnet_do_bootp_and_rootfs (); 142 143 The IRQ level is the one documented in the CS8900 datasheet and below 144 in the CS8900 device structure. You need to map your target IRQ to the 145 CS8900 in the BSP driver. 21 146 22 147 */ … … 329 454 330 455 /* 456 * The default receive queue size. If the BSP sets this field to 457 * 0 this default is used. 458 */ 459 #define CS8900_RX_QUEUE_SIZE (30) 460 461 /* 331 462 * Stats, more for debugging than anything else. 332 463 */ … … 382 513 383 514 /* 515 * Memory base addresses. Making mem_base 0 forces the 516 * driver to perform only I/O space accesses. 517 */ 518 519 unsigned long io_base; 520 unsigned long mem_base; 521 522 /* 523 * The IRQ level as defined in the datasheet for the CS8900. 524 * 525 * ISA BUS Pin Value 526 * IRQ10 INTRQ0 0 527 * IRQ11 INTRQ1 1 528 * IRQ12 INTRQ2 2 529 * IRQ5 INTRQ3 3 530 */ 531 532 int irq_level; 533 534 /* 535 * The MAC address. 536 */ 537 538 unsigned char mac_address[6]; 539 540 /* 384 541 * The bsdnet information structure. 385 542 */ … … 400 557 * The queues. FIXME : these should be changed to be mbuf lists. 401 558 */ 559 402 560 struct mbuf *rx_ready_head; 403 561 struct mbuf *rx_ready_tail; … … 408 566 int rx_loaded_len; 409 567 568 /* 569 * Number of mbufs queued for the interrupt handler to 570 * loop reading. 571 */ 572 573 int rx_queue_size; 574 410 575 #if CS8900_TRACE 411 576 unsigned short trace_key[CS8900_TRACE_SIZE]; … … 415 580 #endif 416 581 417 /* 582 /** 418 583 * Standard(!) ethernet statistics 419 584 */ … … 424 589 425 590 /* 426 * Link is active, and RX count. 427 */ 428 429 int cs8900_link_active (int dev); 430 int cs8900_driver_attach (struct rtems_bsdnet_ifconfig *config, 431 int attaching); 432 rtems_isr cs8900_interrupt (rtems_vector_number v, void *cs); 433 434 /* 435 * Functions Users Provide to implement the driver. 436 */ 437 438 void cs8900_attach_interrupt (int dev, cs8900_device *cs); 439 void cs8900_detach_interrupt (int dev); 440 void cs8900_get_mac_addr (int dev, unsigned char *mac_address); 441 void cs8900_io_set_reg (int dev, unsigned short reg, unsigned short data); 442 unsigned short cs8900_io_get_reg (int dev, unsigned short reg); 443 void cs8900_mem_set_reg (int dev, unsigned long reg, unsigned short data); 444 unsigned short cs8900_mem_get_reg (int dev, unsigned long reg); 445 void cs8900_put_data_block (int dev, int len, unsigned char *data); 446 unsigned short cs8900_get_data_block (int dev, unsigned char *data); 447 void cs8900_tx_load (int dev, struct mbuf *m); 591 * Link active returns the state of the PHY. 592 * 593 * @param cs Pointer to the device structure. 594 */ 595 596 int cs8900_link_active (cs8900_device *cs); 597 598 /** 599 * The RTEMS network stack driver attach function that is loaded into the 600 * the rtems_bsdnet_ifconfig struct. The network stack will call this 601 * function when attaching the driver. The BSP must load the 'drv_ctrl' 602 * field of the structure before calling the 'rtems_bsdnet_attach' 603 * function. 604 * 605 * @param config The RTEMS BSD config structure. 606 * 607 * @param attaching True is the stack is attaching the interface. 608 * 609 * @retval int Set to 1 if the device has attached. 610 */ 611 612 int cs8900_driver_attach (struct rtems_bsdnet_ifconfig *config, 613 int attaching); 614 615 /** 616 * The BSP specific interrupt wrapper calls this function when a device 617 * interrupt occurs. 618 * 619 * @param v The RTEMS vector number that generated the interrupt. 620 * 621 * @param cs Pointer to the device structure passed to the interrupt 622 * catch function provided by the BSP. 623 * 624 * @retval rtems_isr The standard ISR return type. 625 */ 626 627 rtems_isr cs8900_interrupt (rtems_vector_number v, void *cs); 628 629 /** 630 * Get the MAC address for the interface. 631 * 632 * @param cs Pointer to the device structure. 633 * 634 * @param mac_address Pointer to the memory to load the MAC address. This 635 * is a 6 byte buffer so do not exceeed the bounds. 636 */ 637 638 void cs8900_get_mac_addr (cs8900_device *cs, unsigned char *mac_address); 639 640 /** 641 * Catch the device interrupt. When the interrupt is called call the 642 * function 'cs8900_interrupt'. 643 * 644 * BSP to provide this function. 645 * 646 * @param cs Pointer to the device structure. 647 */ 648 649 void cs8900_attach_interrupt (cs8900_device *cs); 650 651 /** 652 * Detach the device interrupt. 653 * 654 * BSP to provide this function. 655 * 656 * @param cs Pointer to the device structure. 657 */ 658 659 void cs8900_detach_interrupt (cs8900_device *cs); 660 661 /** 662 * Write to an IO space register. 663 * 664 * BSP to provide this function. 665 * 666 * @param cs Pointer to the device structure. 667 * 668 * @param reg Register offset from the IO base. 669 * 670 * @param data The data to be written to the register. 671 */ 672 673 void cs8900_io_set_reg (cs8900_device *cs, 674 unsigned short reg, unsigned short data); 675 676 /** 677 * Read an IO space register. 678 * 679 * BSP to provide this function. 680 * 681 * @param cs Pointer to the device structure. 682 * 683 * @param reg Register offset from the IO base. 684 * 685 * @retval unsigned short The register data. 686 */ 687 688 unsigned short cs8900_io_get_reg (cs8900_device *cs, unsigned short reg); 689 690 /** 691 * Write to a memory space register. Will only be called is the mem_base 692 * field of the 'cs' struct is not 0. 693 * 694 * BSP to provide this function. 695 * 696 * @param cs Pointer to the device structure. 697 * 698 * @param reg Register offset from the memory base. 699 * 700 * @param data The data to be written to the register. 701 */ 702 703 void cs8900_mem_set_reg (cs8900_device *cs, 704 unsigned long reg, unsigned short data); 705 706 /** 707 * Read a memory space register. Will only be called is the mem_base 708 * field of the 'cs' struct is not 0. 709 * 710 * BSP to provide this function. 711 * 712 * @param cs Pointer to the device structure. 713 * 714 * @param reg Register offset from the IO base. 715 * 716 * @retval unsigned short The register data. 717 */ 718 719 unsigned short cs8900_mem_get_reg (cs8900_device *cs, unsigned long reg); 720 721 /** 722 * Write a block of data to the interface. The BSP codes if this is an IO or 723 * memory space write. 724 * 725 * BSP to provide this function. 726 * 727 * @param cs Pointer to the device structure. 728 * 729 * @param len The length of data to write. 730 * 731 * @param data Pointer to the data to be written. 732 */ 733 734 void cs8900_put_data_block (cs8900_device *cs, int len, unsigned char *data); 735 736 /** 737 * Read a block of data from the interface. The BSP codes if this is an IO or 738 * memory space write. The read must not be longer than the MTU size. 739 * 740 * BSP to provide this function. 741 * 742 * @param cs Pointer to the device structure. 743 * 744 * @param data Pointer to the buffer where the data is to be written. 745 * 746 * @retval unsigned short The number of bytes read from the device. 747 */ 748 749 unsigned short cs8900_get_data_block (cs8900_device *cs, unsigned char *data); 750 751 /** 752 * Load a mbuf chain to the device ready for tranmission. 753 * 754 * BSP to provide this function. 755 * 756 * @param cs Pointer to the device structure. 757 * 758 * @param m Pointer to the head of an mbuf chain. 759 */ 760 761 void cs8900_tx_load (cs8900_device *cs, struct mbuf *m); 448 762 449 763 #endif
Note: See TracChangeset
for help on using the changeset viewer.