Mercurial > flash_v2
comparison packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c @ 941:01d8c3c977d9
* src/if_cs8900a.c (cs8900a_send): Allow for data not being 16-bit
aligned. Thanks to Laurent Gonzalez <laurent.gonzalez@ri.silicomp.fr>
for reporting this and his initial patch.
* src/if_cs8900a.c:
* include/cs8900a.h:
Changes to support both little and big endian targets
| author | jlarmour |
|---|---|
| date | Sat, 12 Apr 2003 03:50:18 +0000 |
| parents | ae8511176102 |
| children | 9c818dd5d9fa |
comparison
equal
deleted
inserted
replaced
| 940:26aa16c08c2e | 941:01d8c3c977d9 |
|---|---|
| 73 #include <pkgconf/io_eth_drivers.h> | 73 #include <pkgconf/io_eth_drivers.h> |
| 74 | 74 |
| 75 #include <cyg/infra/cyg_type.h> | 75 #include <cyg/infra/cyg_type.h> |
| 76 #include <cyg/hal/hal_arch.h> | 76 #include <cyg/hal/hal_arch.h> |
| 77 #include <cyg/hal/hal_intr.h> | 77 #include <cyg/hal/hal_intr.h> |
| 78 #include <cyg/hal/hal_endian.h> | |
| 78 #include <cyg/infra/diag.h> | 79 #include <cyg/infra/diag.h> |
| 79 #include <cyg/hal/drv_api.h> | 80 #include <cyg/hal/drv_api.h> |
| 80 #undef __ECOS | 81 #undef __ECOS |
| 81 #define __ECOS | 82 #define __ECOS |
| 82 #include <cyg/io/eth/eth_drv.h> | 83 #include <cyg/io/eth/eth_drv.h> |
| 166 { | 167 { |
| 167 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; | 168 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; |
| 168 cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private; | 169 cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private; |
| 169 cyg_addrword_t base = cpd->base; | 170 cyg_addrword_t base = cpd->base; |
| 170 cyg_uint16 chip_type, chip_rev, chip_status; | 171 cyg_uint16 chip_type, chip_rev, chip_status; |
| 171 int i; | 172 cyg_uint16 i; |
| 172 long timeout = 500000; | 173 long timeout = 500000; |
| 173 cyg_bool esa_configured = false; | 174 cyg_bool esa_configured = false; |
| 174 | 175 |
| 175 cpd->tab = tab; | 176 cpd->tab = tab; |
| 176 | 177 |
| 210 chip_type = get_reg(base, PP_ChipID); | 211 chip_type = get_reg(base, PP_ChipID); |
| 211 chip_rev = get_reg(base, PP_ChipRev); | 212 chip_rev = get_reg(base, PP_ChipRev); |
| 212 #if DEBUG & 8 | 213 #if DEBUG & 8 |
| 213 diag_printf("CS8900A[%p] - type: 0x%04x, rev: 0x%04x\n", base, chip_type, chip_rev); | 214 diag_printf("CS8900A[%p] - type: 0x%04x, rev: 0x%04x\n", base, chip_type, chip_rev); |
| 214 #endif | 215 #endif |
| 215 if (chip_type != 0x630e) { | 216 if (chip_type != PP_ChipID_CL) { |
| 216 #if DEBUG & 8 | 217 #if DEBUG & 8 |
| 217 diag_printf("CS8900 - invalid type (0x%04x), must be 0x630e\n", chip_type); | 218 diag_printf("CS8900 - invalid type (0x%04x), must be 0x630e\n", chip_type); |
| 218 #endif | 219 #endif |
| 219 return false; | 220 return false; |
| 220 } | 221 } |
| 261 } | 262 } |
| 262 if (!esa_configured && (chip_status & PP_SelfStat_EEPROM)) { | 263 if (!esa_configured && (chip_status & PP_SelfStat_EEPROM)) { |
| 263 // Get ESA from EEPROM - via the PP_IA registers | 264 // Get ESA from EEPROM - via the PP_IA registers |
| 264 cyg_uint16 esa_word; | 265 cyg_uint16 esa_word; |
| 265 for (i = 0; i < sizeof(cpd->esa); i += 2) { | 266 for (i = 0; i < sizeof(cpd->esa); i += 2) { |
| 267 #if(CYG_BYTEORDER == CYG_LSBFIRST) | |
| 266 esa_word = get_reg(base, PP_IA+i); | 268 esa_word = get_reg(base, PP_IA+i); |
| 267 cpd->esa[i] = (esa_word & 0xFF); | 269 cpd->esa[i] = (esa_word & 0xFF); |
| 268 cpd->esa[i+1] = (esa_word >> 8) & 0xFF; | 270 cpd->esa[i+1] = (esa_word >> 8) & 0xFF; |
| 271 #elif(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 272 esa_word = get_reg(base, PP_IA+CYG_SWAP16(i)); | |
| 273 cpd->esa[i+1] = (esa_word & 0xFF); | |
| 274 cpd->esa[i] = (esa_word >> 8) & 0xFF; | |
| 275 #else | |
| 276 # error You must define CYG_BYTEORDER to equal CYG_LSBFIRST or CYG_MSBFIRST | |
| 277 #endif | |
| 269 } | 278 } |
| 270 esa_configured = true; | 279 esa_configured = true; |
| 271 } | 280 } |
| 272 if (!esa_configured) { | 281 if (!esa_configured) { |
| 273 # if DEBUG & 8 | 282 # if DEBUG & 8 |
| 276 return false; | 285 return false; |
| 277 } | 286 } |
| 278 | 287 |
| 279 // Tell the chip what ESA to use | 288 // Tell the chip what ESA to use |
| 280 for (i = 0; i < sizeof(cpd->esa); i += 2) { | 289 for (i = 0; i < sizeof(cpd->esa); i += 2) { |
| 290 #if(CYG_BYTEORDER == CYG_LSBFIRST) | |
| 281 put_reg(base, PP_IA+i, cpd->esa[i] | (cpd->esa[i+1] << 8)); | 291 put_reg(base, PP_IA+i, cpd->esa[i] | (cpd->esa[i+1] << 8)); |
| 292 #elif(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 293 put_reg(base, PP_IA+CYG_SWAP16(i), cpd->esa[i+1] | (cpd->esa[i] << 8)); | |
| 294 #endif | |
| 282 } | 295 } |
| 283 // Set logical address mask | 296 // Set logical address mask |
| 284 for (i = 0; i < 8; i += 2) { | 297 for (i = 0; i < 8; i += 2) { |
| 298 #if(CYG_BYTEORDER == CYG_LSBFIRST) | |
| 285 put_reg(base, PP_LAF+i, 0xFFFF); | 299 put_reg(base, PP_LAF+i, 0xFFFF); |
| 300 #elif(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 301 put_reg(base, PP_LAF+CYG_SWAP16(i), 0xFFFF); | |
| 302 #endif | |
| 286 } | 303 } |
| 287 # if DEBUG & 8 | 304 # if DEBUG & 8 |
| 288 diag_printf("ESA %02x:%02x:%02x:%02x:%02x:%02x\n", | 305 diag_printf("ESA %02x:%02x:%02x:%02x:%02x:%02x\n", |
| 289 cpd->esa[0], cpd->esa[1], cpd->esa[2], | 306 cpd->esa[0], cpd->esa[1], cpd->esa[2], |
| 290 cpd->esa[3], cpd->esa[4], cpd->esa[5]); | 307 cpd->esa[3], cpd->esa[4], cpd->esa[5]); |
| 417 cpd->txbusy = true; | 434 cpd->txbusy = true; |
| 418 cpd->txkey = key; | 435 cpd->txkey = key; |
| 419 #ifdef CYGPKG_KERNEL | 436 #ifdef CYGPKG_KERNEL |
| 420 cpd->txstart = cyg_current_time(); | 437 cpd->txstart = cyg_current_time(); |
| 421 #endif | 438 #endif |
| 439 | |
| 422 // Start the xmit sequence | 440 // Start the xmit sequence |
| 423 | 441 #if(CYG_BYTEORDER == CYG_MSBFIRST) |
| 442 total_len = CYG_SWAP16(total_len); | |
| 443 #endif | |
| 444 | |
| 424 // The hardware indicates that there are options as to when the actual | 445 // The hardware indicates that there are options as to when the actual |
| 425 // packet transmission will start wrt moving of data into the transmit | 446 // packet transmission will start wrt moving of data into the transmit |
| 426 // buffer. However, impirical results seem to indicate that if the | 447 // buffer. However, impirical results seem to indicate that if the |
| 427 // packet is large and transmission is allowed to start before the | 448 // packet is large and transmission is allowed to start before the |
| 428 // entire packet has been pushed into the buffer, the hardware gets | 449 // entire packet has been pushed into the buffer, the hardware gets |
| 449 len = sg_list[i].len; | 470 len = sg_list[i].len; |
| 450 | 471 |
| 451 if (len > 0) { | 472 if (len > 0) { |
| 452 /* Finish the last word. */ | 473 /* Finish the last word. */ |
| 453 if (odd_byte) { | 474 if (odd_byte) { |
| 475 // Add data to the most significant byte | |
| 476 #if(CYG_BYTEORDER == CYG_LSBFIRST) | |
| 454 saved_data |= ((cyg_uint16)*data++) << 8; | 477 saved_data |= ((cyg_uint16)*data++) << 8; |
| 478 #elif(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 479 saved_data = ((cyg_uint16)*data++) | (saved_data << 8); | |
| 480 #endif | |
| 455 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); | 481 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); |
| 456 len--; | 482 len--; |
| 457 odd_byte = false; | 483 odd_byte = false; |
| 458 } | 484 } |
| 459 /* Output contiguous words. */ | 485 if ((CYG_ADDRESS)data & 0x1 == 0) { |
| 460 sdata = (cyg_uint16 *)data; | 486 /* Aligned on 16-bit boundary, so output contiguous words. */ |
| 461 while (len > 1) { | 487 sdata = (cyg_uint16 *)data; |
| 462 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, *sdata++); | 488 while (len > 1) { |
| 463 len -= sizeof(cyg_uint16); | 489 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, *sdata++); |
| 490 len -= sizeof(cyg_uint16); | |
| 491 } | |
| 492 data = (cyg_uint8 *)sdata; | |
| 493 } else { | |
| 494 /* Not 16-bit aligned, so byte copy */ | |
| 495 while (len > 1) { | |
| 496 saved_data = (cyg_uint16)*data++; // reuse saved_data | |
| 497 #if CYG_BYTEORDER == CYG_MSBFIRST | |
| 498 saved_data = ((cyg_uint16)*data++) | (saved_data << 8); | |
| 499 #else | |
| 500 saved_data |= ((cyg_uint16)*data++) << 8; | |
| 501 #endif | |
| 502 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); | |
| 503 len -= sizeof(cyg_uint16); | |
| 504 } | |
| 464 } | 505 } |
| 465 /* Save last byte, if necessary. */ | 506 /* Save last byte, if necessary. */ |
| 466 if (len == 1) { | 507 if (len == 1) { |
| 467 data = (cyg_uint8 *)sdata; | |
| 468 saved_data = (cyg_uint16)*data; | 508 saved_data = (cyg_uint16)*data; |
| 469 odd_byte = true; | 509 odd_byte = true; |
| 470 } | 510 } |
| 471 } | 511 } |
| 472 } | 512 } |
| 487 cyg_addrword_t base = cpd->base; | 527 cyg_addrword_t base = cpd->base; |
| 488 cyg_uint16 stat, len; | 528 cyg_uint16 stat, len; |
| 489 | 529 |
| 490 HAL_READ_UINT16(base+CS8900A_RTDATA, stat); | 530 HAL_READ_UINT16(base+CS8900A_RTDATA, stat); |
| 491 HAL_READ_UINT16(base+CS8900A_RTDATA, len); | 531 HAL_READ_UINT16(base+CS8900A_RTDATA, len); |
| 532 | |
| 533 #if(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 534 len = CYG_SWAP16(len); | |
| 535 #endif | |
| 536 | |
| 492 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG | 537 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG |
| 493 if (cyg_io_eth_net_debug) { | 538 if (cyg_io_eth_net_debug) { |
| 494 diag_printf("RxEvent - stat: %x, len: %d\n", stat, len); | 539 diag_printf("RxEvent - stat: %x, len: %d\n", stat, len); |
| 495 } | 540 } |
| 496 #endif | 541 #endif |
| 520 *data++ = val; | 565 *data++ = val; |
| 521 } | 566 } |
| 522 mlen -= sizeof(*data); | 567 mlen -= sizeof(*data); |
| 523 } | 568 } |
| 524 if (mlen) { | 569 if (mlen) { |
| 525 // Fetch last odd byte | 570 HAL_READ_UINT16(base+CS8900A_RTDATA, val); |
| 526 HAL_READ_UINT16(base+CS8900A_RTDATA, cval); | 571 #if(CYG_BYTEORDER == CYG_LSBFIRST) |
| 527 cval &= 0xFF; | 572 // last odd byte will be in the LSB |
| 573 cval = (cyg_uint8)(val); | |
| 574 #elif(CYG_BYTEORDER == CYG_MSBFIRST) | |
| 575 // last odd byte will be in the MSB | |
| 576 cval = (cyg_uint8)(val >> 8); | |
| 577 #endif | |
| 578 cval &= 0xff; | |
| 528 if ((cp = (cyg_uint8 *)data) != 0) { | 579 if ((cp = (cyg_uint8 *)data) != 0) { |
| 529 *cp = cval; | 580 *cp = cval; |
| 530 } | 581 } |
| 531 } | 582 } |
| 532 } | 583 } |
