|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: /* ! 14: * ! 15: ****************************************************************************** ! 16: * reference: ! 17: * Broadcom 57xx ! 18: * Host Programmer Interface Specification for the ! 19: * NetXtreme Family of Highly-Integrated Media Access Controlers ! 20: */ ! 21: #include "types.h" ! 22: #include "bcm57xx.h" ! 23: ! 24: ! 25: /* ! 26: * local defines ! 27: ****************************************************************************** ! 28: */ ! 29: ! 30: ! 31: // #define BCM_VLAN_TAG ( (u32_t) 0x1 ) ! 32: ! 33: // number of tx/rx rings ! 34: // NOTE: 5714 only uses 1 rx/tx ring, but memory ! 35: // for the other rings is cleaned anyways for ! 36: // sanity & future use ! 37: #define BCM_MAX_TX_RING 16 ! 38: #define BCM_MAX_RXRET_RING 16 ! 39: #define BCM_MAX_RXPROD_RCB 3 ! 40: ! 41: // bd descriptions ! 42: #define BCM_RXPROD_RING_SIZE 512 // don't change ! 43: #define BCM_RXRET_RING_SIZE 512 // don't change ! 44: #define BCM_TX_RING_SIZE 512 // don't change ! 45: #define BCM_BUF_SIZE 1536 // don't change ! 46: #define BCM_MTU_MAX_LEN 1522 ! 47: #define BCM_MAX_RX_BUF 64 ! 48: #define BCM_MAX_TX_BUF 16 ! 49: ! 50: // number of MAC addresses in NIC ! 51: #define BCM_NUM_MAC_ADDR 4 ! 52: #define BCM_NUM_MAC5704_ADDR 12 ! 53: // offset of mac address field(s) in bcm register space ! 54: #define MAC5704_ADDR_OFFS ( (u16_t) 0x0530 ) ! 55: ! 56: // offset of NIC memory start address from base address ! 57: #define BCM_MEMORY_OFFS ( (u64_t) 0x8000 ) ! 58: ! 59: // offset of statistics block in NIC memory ! 60: #define BCM_STATISTIC_OFFS ( (u64_t) 0x0300 ) ! 61: // size of statistic block in NIC memory ! 62: #define BCM_STATISTIC_SIZE 0x800 ! 63: ! 64: // offsets of NIC rx/tx rings in NIC memory ! 65: #define BCM_NIC_TX_OFFS ( (u16_t) 0x4000 ) ! 66: #define BCM_NIC_RX_OFFS ( (u16_t) 0x6000 ) ! 67: #define BCM_NIC_TX_SIZE ( (u16_t) ( ( BCM_TX_RING_SIZE * BCM_RCB_SIZE_u16 ) / 4 ) ) ! 68: ! 69: // device mailboxes ! 70: #define BCM_FW_MBX ( (u16_t) 0x0b50 ) ! 71: #define BCM_FW_MBX_CMD ( (u16_t) 0x0b78 ) ! 72: #define BCM_FW_MBX_LEN ( (u16_t) 0x0b7c ) ! 73: #define BCM_FW_MBX_DATA ( (u16_t) 0x0b80 ) ! 74: #define BCM_NICDRV_STATE_MBX ( (u16_t) 0x0c04 ) ! 75: ! 76: // device mailbox commands ! 77: #define BCM_NICDRV_ALIVE ( (u32_t) 0x00000001 ) ! 78: #define BCM_NICDRV_PAUSE_FW ( (u32_t) 0x00000002 ) ! 79: ! 80: // device values ! 81: #define BCM_MAGIC_NUMBER ( (u32_t) 0x4b657654 ) ! 82: ! 83: // device states ! 84: #define NIC_FWDRV_STATE_START ( (u32_t) 0x00000001 ) ! 85: #define NIC_FWDRV_STATE_START_DONE ( (u32_t) 0x80000001 ) ! 86: #define NIC_FWDRV_STATE_UNLOAD ( (u32_t) 0x00000002 ) ! 87: #define NIC_FWDRV_STATE_UNLOAD_DONE ( (u32_t) 0x80000002 ) ! 88: #define NIC_FWDRV_STATE_SUSPEND ( (u32_t) 0x00000004 ) ! 89: ! 90: // timer prescaler value ! 91: #define BCM_TMR_PRESCALE ( (u32_t) 0x41 ) ! 92: ! 93: // offset of transmit rcb's in NIC memory ! 94: #define BCM_TX_RCB_OFFS ( (u16_t) 0x0100 ) ! 95: // offset of receive return rcb's in NIC memory ! 96: #define BCM_RXRET_RCB_OFFS ( (u16_t) 0x0200 ) ! 97: ! 98: // register offsets for ring indices ! 99: #define TX_PROD_IND ( (u16_t) 0x0304 ) ! 100: #define TX_CONS_IND ( (u16_t) 0x3cc0 ) ! 101: #define RXPROD_PROD_IND ( (u16_t) 0x026c ) ! 102: #define RXPROD_CONS_IND ( (u16_t) 0x3c54 ) ! 103: #define RXRET_PROD_IND ( (u16_t) 0x3c80 ) ! 104: #define RXRET_CONS_IND ( (u16_t) 0x0284 ) ! 105: // NIC producer index only needed for initialization ! 106: #define TX_NIC_PROD_IND ( (u16_t) 0x0384 ) ! 107: ! 108: /* ! 109: * predefined register values used during initialization ! 110: * may be adapted by user ! 111: */ ! 112: #define DMA_RW_CTRL_VAL_5714 ( (u32_t) 0x76144000 ) ! 113: #define DMA_RW_CTRL_VAL ( (u32_t) 0x760F0000 ) ! 114: #define TX_MAC_LEN_VAL ( (u32_t) 0x00002620 ) ! 115: ! 116: #define RX_LST_PLC_CFG_VAL ( (u32_t) 0x00000109 ) ! 117: #define RX_LST_PLC_STAT_EN_VAL ( (u32_t) 0x007e000f ) ! 118: #define NVM_ADDR_MSK ( (u32_t) 0x000fffff ) ! 119: ! 120: // Number of Receive Rules /w or /wo SOL enabled ! 121: #define RX_RULE_CFG_VAL ( (u32_t) 0x00000008 ) ! 122: #define NUM_RX_RULE ( (u32_t) 16 ) ! 123: #define NUM_RX_RULE_ASF ( (u32_t) ( NUM_RX_RULE - 4 ) ) ! 124: ! 125: // RCB register offsets ! 126: #define BCM_RXPROD_RCB_JUM ( (u16_t) 0x2440 ) ! 127: #define BCM_RXPROD_RCB_STD ( (u16_t) 0x2450 ) ! 128: #define BCM_RXPROD_RCB_MIN ( (u16_t) 0x2460 ) ! 129: ! 130: // macros needed for new addressing method ! 131: #define BCM_RCB_HOSTADDR_HI_u16( rcb ) ( (u16_t) rcb + 0x00 ) ! 132: #define BCM_RCB_HOSTADDR_LOW_u16( rcb ) ( (u16_t) rcb + 0x04 ) ! 133: #define BCM_RCB_LENFLAG_u16( rcb ) ( (u16_t) rcb + 0x08 ) ! 134: #define BCM_RCB_NICADDR_u16( rcb ) ( (u16_t) rcb + 0x0c ) ! 135: #define BCM_RCB_SIZE_u16 ( (u16_t) 0x0010 ) ! 136: ! 137: // RCB flags ! 138: #define RCB_FLAG_RING_DISABLED BIT32( 1 ) ! 139: ! 140: // BCM device ID masks ! 141: #define BCM_DEV_5714 ( (u64_t) 0x1 ) ! 142: #define BCM_DEV_5704 ( (u64_t) 0x2 ) ! 143: #define BCM_DEV_5703 ( (u64_t) 0x4 ) ! 144: #define BCM_DEV_SERDES ( (u64_t) 0x80000000 ) ! 145: #define BCM_DEV_COPPER ( (u64_t) 0x40000000 ) ! 146: ! 147: #define IS_5714 ( ( bcm_device_u64 & BCM_DEV_5714 ) != 0 ) ! 148: #define IS_5704 ( ( bcm_device_u64 & BCM_DEV_5704 ) != 0 ) ! 149: #define IS_5703 ( ( bcm_device_u64 & BCM_DEV_5703 ) != 0 ) ! 150: #define IS_SERDES ( ( bcm_device_u64 & BCM_DEV_SERDES ) != 0 ) ! 151: #define IS_COPPER_PHY ( ( bcm_device_u64 & BCM_DEV_COPPER ) != 0 ) ! 152: ! 153: #define BUFFERED_FLASH_PAGE_POS 9 ! 154: #define BUFFERED_FLASH_BYTE_ADDR_MASK ((<<BUFFERED_FLASH_PAGE_POS) - 1) ! 155: #define BUFFERED_FLASH_PAGE_SIZE 264 ! 156: #define BUFFERED_FLASH_PHY_SIZE 512 ! 157: #define MANUFACTURING_INFO_SIZE 140 ! 158: #define CRC32_POLYNOMIAL 0xEDB88320 ! 159: ! 160: /* ! 161: * local types ! 162: ****************************************************************************** ! 163: */ ! 164: typedef struct { ! 165: u32_t m_dev_u32; ! 166: u64_t m_devmsk_u64; ! 167: } bcm_dev_t; ! 168: ! 169: /* ! 170: * BCM common data structures ! 171: * BCM57xx Programmer's Guide: Section 5 ! 172: */ ! 173: ! 174: /* ! 175: * 64bit host address in a way the NIC is able to understand it ! 176: */ ! 177: typedef struct { ! 178: u32_t m_hi_u32; ! 179: u32_t m_lo_u32; ! 180: } bcm_addr64_t; ! 181: /* ! 182: * ring control block ! 183: */ ! 184: typedef struct { ! 185: bcm_addr64_t m_hostaddr_st; ! 186: u32_t m_lenflags_u32; // upper 16b: len, lower 16b: flags ! 187: u32_t m_nicaddr_u32; ! 188: } bcm_rcb_t; ! 189: ! 190: /* ! 191: * tx buffer descriptor ! 192: */ ! 193: typedef struct { ! 194: bcm_addr64_t m_hostaddr_st; ! 195: u32_t m_lenflags_u32; // upper 16b: len, lower 16b: flags ! 196: u32_t m_VLANtag_u32; // lower 16b: vtag ! 197: } bcm_txbd_t; ! 198: ! 199: /* ! 200: * rx buffer descriptor ! 201: */ ! 202: typedef struct { ! 203: bcm_addr64_t m_hostaddr_st; ! 204: u32_t m_idxlen_u32; // upper 16b: idx, lower 16b: len ! 205: u32_t m_typeflags_u32; // upper 16b: type, lower 16b: flags ! 206: u32_t m_chksum_u32; // upper 16b: ip, lower 16b: tcp/udp ! 207: u32_t m_errvlan_u32; // upper 16b: err, lower 16b: vlan tag ! 208: u32_t m_reserved_u32; ! 209: u32_t m_opaque_u32; ! 210: } bcm_rxbd_t; ! 211: ! 212: /* ! 213: * bcm status block ! 214: * NOTE: in fact the status block is not used and configured ! 215: * so that it is not updated by the NIC. Still it has to be ! 216: * set up so the NIC is satisfied ! 217: */ ! 218: typedef struct { ! 219: u32_t m_st_word_u32; ! 220: u32_t m_st_tag_u32; ! 221: u16_t m_rxprod_cons_u16; ! 222: u16_t m_unused_u16; ! 223: u32_t m_unused_u32; ! 224: u16_t m_tx_cons_u16; ! 225: u16_t m_rxret_prod_u16; ! 226: } bcm_status_t; ! 227: ! 228: /* ! 229: * local constants ! 230: ****************************************************************************** ! 231: */ ! 232: static const bcm_dev_t bcm_dev[] = { ! 233: { 0x166b, BCM_DEV_5714 }, ! 234: { 0x1668, BCM_DEV_5714 }, ! 235: { 0x1669, BCM_DEV_5714 }, ! 236: { 0x166a, BCM_DEV_5714 }, ! 237: { 0x1648, BCM_DEV_5704 }, ! 238: { 0x1649, BCM_DEV_5704 | BCM_DEV_SERDES }, ! 239: { 0x16a8, BCM_DEV_5704 | BCM_DEV_SERDES }, ! 240: { 0x16a7, BCM_DEV_5703 | BCM_DEV_SERDES }, ! 241: { 0x16c7, BCM_DEV_5703 | BCM_DEV_SERDES }, ! 242: { 0 , 0 } ! 243: }; ! 244: ! 245: /* ! 246: * local variables ! 247: ****************************************************************************** ! 248: */ ! 249: static u64_t bcm_device_u64; ! 250: static u32_t bcm_rxret_ring_sz; ! 251: static u64_t bcm_baseaddr_u64; ! 252: static u64_t bcm_memaddr_u64; ! 253: ! 254: /* ! 255: * rings & their buffers ! 256: */ ! 257: // the rings made of buffer descriptors ! 258: static bcm_txbd_t bcm_tx_ring[BCM_TX_RING_SIZE]; ! 259: static bcm_rxbd_t bcm_rxprod_ring[BCM_RXPROD_RING_SIZE]; ! 260: static bcm_rxbd_t bcm_rxret_ring[BCM_RXRET_RING_SIZE*2]; ! 261: ! 262: // the buffers used in the rings ! 263: static u08_t bcm_tx_buffer_pu08[BCM_MAX_TX_BUF][BCM_BUF_SIZE]; ! 264: static u08_t bcm_rx_buffer_pu08[BCM_MAX_RX_BUF][BCM_BUF_SIZE]; ! 265: ! 266: // tx ring index of first/last bd ! 267: static u32_t bcm_tx_start_u32; ! 268: static u32_t bcm_tx_stop_u32; ! 269: static u32_t bcm_tx_bufavail_u32; ! 270: ! 271: // PCI device location needed for indirect addressing ! 272: static u64_t bcm_pcicfg_puid; ! 273: static u08_t bcm_pcicfg_bus; ! 274: static u08_t bcm_pcicfg_devfn; ! 275: ! 276: /* ! 277: * status block ! 278: */ ! 279: static bcm_status_t bcm_status; ! 280: ! 281: /* ! 282: * snk module interface ! 283: ****************************************************************************** ! 284: */ ! 285: static int bcm_init ( void ); ! 286: static int bcm_term ( void ); ! 287: static int bcm_xmit ( char *f_buffer_pc, int f_len_i ); ! 288: static int bcm_receive( char *f_buffer_pc, int f_len_i ); ! 289: static int bcm_ioctl ( int request, void* data ); ! 290: ! 291: snk_module_t snk_module_interface = { ! 292: .version = 1, ! 293: .type = MOD_TYPE_NETWORK, ! 294: .running = 0, ! 295: .init = bcm_init, ! 296: .term = bcm_term, ! 297: .write = bcm_xmit, ! 298: .read = bcm_receive, ! 299: .ioctl = bcm_ioctl ! 300: }; ! 301: ! 302: /* ! 303: * implementation ! 304: ****************************************************************************** ! 305: */ ! 306: ! 307: ! 308: /* ! 309: * global functions ! 310: ****************************************************************************** ! 311: */ ! 312: int ! 313: check_driver( pci_config_t *pci_conf ); ! 314: ! 315: ! 316: /* ! 317: * local helper functions ! 318: ****************************************************************************** ! 319: */ ! 320: static char * ! 321: memcpy( char *dest, const char *src, size_t n ) ! 322: { ! 323: char *ret = dest; ! 324: while( n-- ) { ! 325: *dest++ = *src++; ! 326: } ! 327: ! 328: return( ret ); ! 329: } ! 330: ! 331: static char * ! 332: memset_ci( char *dest, int c, size_t n ) ! 333: { ! 334: char *ret = dest; ! 335: ! 336: while( n-- ) { ! 337: wr08( dest, c ); ! 338: dest++; ! 339: } ! 340: ! 341: return( ret ); ! 342: } ! 343: ! 344: static char * ! 345: memset( char *dest, int c, size_t n ) ! 346: { ! 347: char *ret = dest; ! 348: while( n-- ) { ! 349: *dest++ = (char) c; ! 350: } ! 351: ! 352: return( ret ); ! 353: } ! 354: ! 355: static u32_t ! 356: bcm_nvram_logical_to_physical_address(u32_t address) ! 357: { ! 358: u32_t page_no = address / BUFFERED_FLASH_PAGE_SIZE; ! 359: u32_t page_addr = address % BUFFERED_FLASH_PAGE_SIZE; ! 360: ! 361: return (page_no << BUFFERED_FLASH_PAGE_POS) + page_addr; ! 362: } ! 363: ! 364: ! 365: /* ! 366: * local inline functions for endian swapping ! 367: ****************************************************************************** ! 368: */ ! 369: ! 370: static u16_t ! 371: bswap_16 (u16_t x) { ! 372: return ((x&0xff00) >> 8) ! 373: | ((x&0x00ff) << 8); ! 374: } ! 375: ! 376: u32_t ! 377: static bswap_32 (u32_t x) { ! 378: return bswap_16((x&0xffff0000) >> 16) ! 379: | (bswap_16(x&0x0000ffff) << 16); ! 380: } ! 381: ! 382: /* ! 383: * read/write functions to access NIC registers & memory ! 384: * NOTE: all functions are executed with cache inhibitation (dead slow :-) ) ! 385: */ ! 386: static u32_t ! 387: bcm_read_mem32( u16_t f_offs_u16 ) ! 388: { // caution: shall only be used after initialization! ! 389: return rd32( bcm_memaddr_u64 + (u64_t) f_offs_u16 ); ! 390: } ! 391: ! 392: /* not used so far ! 393: static u16_t ! 394: bcm_read_mem16( u16_t f_offs_u16 ) ! 395: { // caution: shall only be used after initialization! ! 396: return rd16( bcm_memaddr_u64 + (u64_t) f_offs_u16 ); ! 397: }*/ ! 398: /* not used so far ! 399: static u08_t ! 400: bcm_read_mem08( u16_t f_offs_u16 ) ! 401: { // caution: shall only be used after initialization! ! 402: return rd08( bcm_memaddr_u64 + (u64_t) f_offs_u16 ); ! 403: }*/ ! 404: ! 405: static u32_t ! 406: bcm_read_reg32_indirect( u16_t f_offs_u16 ) ! 407: { // caution: shall only be used after initialization! ! 408: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 409: 4, ! 410: bcm_pcicfg_bus, ! 411: bcm_pcicfg_devfn, ! 412: REG_BASE_ADDR_REG, ! 413: f_offs_u16 ); ! 414: return (u32_t) bswap_32( snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 415: 4, ! 416: bcm_pcicfg_bus, ! 417: bcm_pcicfg_devfn, ! 418: REG_DATA_REG ) ) ; ! 419: } ! 420: ! 421: static u32_t ! 422: bcm_read_reg32( u16_t f_offs_u16 ) ! 423: { // caution: shall only be used after initialization! ! 424: if(f_offs_u16 >= 0x200 && f_offs_u16 <0x400) ! 425: return bcm_read_reg32_indirect( f_offs_u16 + 0x5600 ); ! 426: return rd32( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 427: } ! 428: ! 429: static u16_t ! 430: bcm_read_reg16( u16_t f_offs_u16 ) ! 431: { // caution: shall only be used after initialization! ! 432: return rd16( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 433: } ! 434: /* not used so far ! 435: static u08_t ! 436: bcm_read_reg08( u16_t f_offs_u16 ) ! 437: { // caution: shall only be used after initialization! ! 438: return rd08( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 439: }*/ ! 440: ! 441: static void ! 442: bcm_write_mem32_indirect( u16_t f_offs_u16, u32_t f_val_u32 ) ! 443: { // caution: shall only be used after initialization! ! 444: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 445: 4, ! 446: bcm_pcicfg_bus, ! 447: bcm_pcicfg_devfn, ! 448: MEM_BASE_ADDR_REG, ! 449: f_offs_u16 ); ! 450: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 451: 4, ! 452: bcm_pcicfg_bus, ! 453: bcm_pcicfg_devfn, ! 454: MEM_DATA_REG, ! 455: bswap_32 ( f_val_u32 ) ); ! 456: } ! 457: ! 458: static void ! 459: bcm_write_mem32( u16_t f_offs_u16, u32_t f_val_u32 ) ! 460: { // caution: shall only be used after initialization! ! 461: if(f_offs_u16 >= BCM_RXRET_RCB_OFFS && ! 462: f_offs_u16 < BCM_RXRET_RCB_OFFS + (BCM_MAX_RXRET_RING*BCM_RCB_SIZE_u16)) ! 463: bcm_write_mem32_indirect( f_offs_u16, f_val_u32 ); ! 464: else if(f_offs_u16 >= BCM_TX_RCB_OFFS && ! 465: f_offs_u16 < BCM_TX_RCB_OFFS + (BCM_MAX_TX_RING*BCM_RCB_SIZE_u16)) ! 466: bcm_write_mem32_indirect( f_offs_u16, f_val_u32 ); ! 467: else ! 468: wr32( bcm_memaddr_u64 + (u64_t) f_offs_u16, f_val_u32 ); ! 469: } ! 470: /* not used so far ! 471: static void ! 472: bcm_write_mem16( u16_t f_offs_u16, u16_t f_val_u16 ) ! 473: { // caution: shall only be used after initialization! ! 474: wr16( bcm_memaddr_u64 + (u64_t) f_offs_u16, f_val_u16 ); ! 475: }*/ ! 476: /* not used so far ! 477: static void ! 478: bcm_write_mem08( u16_t f_offs_u16, u08_t f_val_u08 ) ! 479: { // caution: shall only be used after initialization! ! 480: wr08( bcm_memaddr_u64 + (u64_t) f_offs_u16, f_val_u08 ); ! 481: }*/ ! 482: ! 483: static void ! 484: bcm_write_reg32_indirect( u16_t f_offs_u16, u32_t f_val_u32 ) ! 485: { // caution: shall only be used after initialization! ! 486: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 487: 4, ! 488: bcm_pcicfg_bus, ! 489: bcm_pcicfg_devfn, ! 490: REG_BASE_ADDR_REG, ! 491: f_offs_u16 ); ! 492: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 493: 4, ! 494: bcm_pcicfg_bus, ! 495: bcm_pcicfg_devfn, ! 496: REG_DATA_REG, ! 497: bswap_32 ( f_val_u32 ) ); ! 498: } ! 499: ! 500: static void ! 501: bcm_write_reg32( u16_t f_offs_u16, u32_t f_val_u32 ) ! 502: { // caution: shall only be used after initialization! ! 503: if(f_offs_u16 >= 0x200 && f_offs_u16 <0x400) ! 504: bcm_write_reg32_indirect( f_offs_u16 + 0x5600, f_val_u32 ); ! 505: else ! 506: wr32( bcm_baseaddr_u64 + (u64_t) f_offs_u16, f_val_u32 ); ! 507: } ! 508: ! 509: static void ! 510: bcm_write_reg16( u16_t f_offs_u16, u16_t f_val_u16 ) ! 511: { // caution: shall only be used after initialization! ! 512: wr16( bcm_baseaddr_u64 + (u64_t) f_offs_u16, f_val_u16 ); ! 513: } ! 514: /* not used so far ! 515: static void ! 516: bcm_write_reg08( u16_t f_offs_u16, u08_t f_val_u08 ) ! 517: { // caution: shall only be used after initialization! ! 518: wr08( bcm_baseaddr_u64 + (u64_t) f_offs_u16, f_val_u08 ); ! 519: }*/ ! 520: ! 521: static void ! 522: bcm_setb_reg32( u16_t f_offs_u16, u32_t f_mask_u32 ) ! 523: { ! 524: u32_t v; ! 525: ! 526: v = bcm_read_reg32( f_offs_u16 ); ! 527: v |= f_mask_u32; ! 528: bcm_write_reg32( f_offs_u16, v ); ! 529: } ! 530: /* not used so far ! 531: static void ! 532: bcm_setb_reg16( u16_t f_offs_u16, u16_t f_mask_u16 ) ! 533: { ! 534: u16_t v; ! 535: v = rd16( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 536: v |= f_mask_u16; ! 537: wr16( bcm_baseaddr_u64 + (u64_t) f_offs_u16, v ); ! 538: }*/ ! 539: /* not used so far ! 540: static void ! 541: bcm_setb_reg08( u16_t f_offs_u16, u08_t f_mask_u08 ) ! 542: { ! 543: u08_t v; ! 544: v = rd08( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 545: v |= f_mask_u08; ! 546: wr08( bcm_baseaddr_u64 + (u64_t) f_offs_u16, v ); ! 547: }*/ ! 548: ! 549: static void ! 550: bcm_clrb_reg32( u16_t f_offs_u16, u32_t f_mask_u32 ) ! 551: { ! 552: u32_t v; ! 553: ! 554: v = bcm_read_reg32( f_offs_u16 ); ! 555: v &= ~f_mask_u32; ! 556: bcm_write_reg32( f_offs_u16, v ); ! 557: } ! 558: ! 559: static void ! 560: bcm_clrb_reg16( u16_t f_offs_u16, u16_t f_mask_u16 ) ! 561: { ! 562: u16_t v; ! 563: ! 564: v = bcm_read_reg16( f_offs_u16 ); ! 565: v &= ~f_mask_u16; ! 566: bcm_write_reg16( f_offs_u16, v ); ! 567: } ! 568: /* not used so far ! 569: static void ! 570: bcm_clrb_reg08( u16_t f_offs_u16, u08_t f_mask_u08 ) ! 571: { ! 572: u08_t v; ! 573: v = rd08( bcm_baseaddr_u64 + (u64_t) f_offs_u16 ); ! 574: v &= ~f_mask_u32; ! 575: wr08( bcm_baseaddr_u64 + (u64_t) f_offs_u16, v ); ! 576: }*/ ! 577: ! 578: static void ! 579: bcm_clr_wait_bit32( u16_t r, u32_t b ) ! 580: { ! 581: u32_t i; ! 582: ! 583: bcm_clrb_reg32( r, b ); ! 584: ! 585: i = 1000; ! 586: while( --i ) { ! 587: ! 588: if( ( bcm_read_reg32( r ) & b ) == 0 ) { ! 589: break; ! 590: } ! 591: ! 592: us_delay( 10 ); ! 593: } ! 594: #ifdef BCM_DEBUG ! 595: if( ( bcm_read_reg32( r ) & b ) != 0 ) { ! 596: printk( "bcm57xx: bcm_clear_wait_bit32 failed (0x%04X)!\n", r ); ! 597: } ! 598: #endif ! 599: } ! 600: ! 601: /* ! 602: * (g)mii bus access ! 603: */ ! 604: #if 0 ! 605: // not used so far ! 606: static i32_t ! 607: bcm_mii_write16( u32_t f_reg_u32, u16_t f_value_u16 ) ! 608: { ! 609: static const u32_t WR_VAL = ( ( ((u32_t) 0x1) << 21 ) | BIT32( 29 ) | BIT32( 26 ) ); ! 610: i32_t l_autopoll_i32 = 0; ! 611: u32_t l_wrval_u32; ! 612: u32_t i; ! 613: ! 614: /* ! 615: * only 0x00-0x1f are valid registers ! 616: */ ! 617: if( f_reg_u32 > (u32_t) 0x1f ) { ! 618: return -1; ! 619: } ! 620: ! 621: /* ! 622: * disable auto polling if enabled ! 623: */ ! 624: if( ( bcm_read_reg32( MI_MODE_R ) & BIT32( 4 ) ) != 0 ) { ! 625: l_autopoll_i32 = (i32_t) !0; ! 626: bcm_clrb_reg32( MI_MODE_R, BIT32( 4 ) ); ! 627: us_delay( 40 ); ! 628: } ! 629: ! 630: /* ! 631: * construct & write mi com register value ! 632: */ ! 633: l_wrval_u32 = ( WR_VAL | ( f_reg_u32 << 16 ) | (u32_t) f_value_u16 ); ! 634: bcm_write_reg32( MI_COM_R, l_wrval_u32 ); ! 635: ! 636: /* ! 637: * wait for transaction to complete ! 638: */ ! 639: i = 25; ! 640: while( ( --i ) && ! 641: ( ( bcm_read_reg32( MI_COM_R ) & BIT32( 29 ) ) != 0 ) ) { ! 642: us_delay( 10 ); ! 643: } ! 644: ! 645: /* ! 646: * re-enable auto polling if necessary ! 647: */ ! 648: if( l_autopoll_i32 ) { ! 649: bcm_setb_reg32( MI_MODE_R, BIT32( 4 ) ); ! 650: } ! 651: ! 652: // return on error ! 653: if( i == 0 ) { ! 654: return -1; ! 655: } ! 656: ! 657: return 0; ! 658: } ! 659: #endif ! 660: ! 661: static i32_t ! 662: bcm_mii_read16( u32_t f_reg_u32, u16_t *f_value_pu16 ) ! 663: { ! 664: static const u32_t RD_VAL = ( ( ((u32_t) 0x1) << 21 ) | BIT32( 29 ) | BIT32( 27 ) ); ! 665: i32_t l_autopoll_i32 = 0; ! 666: u32_t l_rdval_u32; ! 667: u32_t i; ! 668: u16_t first_not_busy; ! 669: ! 670: /* ! 671: * only 0x00-0x1f are valid registers ! 672: */ ! 673: if( f_reg_u32 > (u32_t) 0x1f ) { ! 674: return -1; ! 675: } ! 676: ! 677: /* ! 678: * disable auto polling if enabled ! 679: */ ! 680: if( ( bcm_read_reg32( MI_MODE_R ) & BIT32( 4 ) ) != 0 ) { ! 681: l_autopoll_i32 = ( i32_t ) !0; ! 682: bcm_clrb_reg32( MI_MODE_R, BIT32( 4 ) ); ! 683: us_delay( 40 ); ! 684: } ! 685: ! 686: /* ! 687: * construct & write mi com register value ! 688: */ ! 689: l_rdval_u32 = ( RD_VAL | ( f_reg_u32 << 16 ) ); ! 690: bcm_write_reg32( MI_COM_R, l_rdval_u32 ); ! 691: ! 692: /* ! 693: * wait for transaction to complete ! 694: * ERRATA workaround: must read two "not busy" states to indicate transaction complete ! 695: */ ! 696: i = 25; ! 697: first_not_busy = 0; ! 698: l_rdval_u32 = bcm_read_reg32( MI_COM_R ); ! 699: while( ( --i ) && ! 700: ( (first_not_busy == 0) || ( ( l_rdval_u32 & BIT32( 29 ) ) != 0 ) ) ) { ! 701: /* Is this the first clear BUSY state? */ ! 702: if ( ( l_rdval_u32 & BIT32( 29 ) ) == 0 ) ! 703: first_not_busy++; ! 704: us_delay( 10 ); ! 705: l_rdval_u32 = bcm_read_reg32( MI_COM_R ); ! 706: } ! 707: ! 708: /* ! 709: * re-enable autopolling if necessary ! 710: */ ! 711: if( l_autopoll_i32 ) { ! 712: bcm_setb_reg32( MI_MODE_R, BIT32( 4 ) ); ! 713: } ! 714: ! 715: /* ! 716: * return on read transaction error ! 717: * (check read failed bit) ! 718: */ ! 719: if( ( i == 0 ) || ! 720: ( ( l_rdval_u32 & BIT32( 28 ) ) != 0 ) ) { ! 721: return -1; ! 722: } ! 723: ! 724: /* ! 725: * return read value ! 726: */ ! 727: *f_value_pu16 = (u16_t) ( l_rdval_u32 & (u32_t) 0xffff ); ! 728: ! 729: return 0; ! 730: } ! 731: ! 732: /* ! 733: * ht2000 dump (not complete) ! 734: */ ! 735: #if 0 ! 736: static void ! 737: bcm_dump( void ) ! 738: { ! 739: u32_t i, j; ! 740: ! 741: printk( "*** DUMP ***********************************************************************\n\n" ); ! 742: ! 743: printk( "* PCI Configuration Registers:\n" ); ! 744: for( i = 0, j = 0; i < 0x40; i += 4 ) { ! 745: ! 746: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 747: ! 748: if( ( ++j & 0x3 ) == 0 ) { ! 749: printk( "\n" ); ! 750: } ! 751: ! 752: } ! 753: ! 754: printk( "\n* Private PCI Configuration Registers:\n" ); ! 755: for( i = 0x68, j = 0; i < 0x88; i += 4 ) { ! 756: ! 757: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 758: ! 759: if( ( ++j & 0x3 ) == 0 ) { ! 760: printk( "\n" ); ! 761: } ! 762: ! 763: } ! 764: ! 765: printk( "\n* VPD Config:\n" ); ! 766: printk( "%04X: %08X \n", 0x94, bcm_read_reg32( 0x94 ) ); ! 767: ! 768: printk( "\n* Dual MAC Control Registers:\n" ); ! 769: for( i = 0xb8, j = 0; i < 0xd0; i += 4 ) { ! 770: ! 771: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 772: ! 773: if( ( ++j & 0x3 ) == 0 ) { ! 774: printk( "\n" ); ! 775: } ! 776: ! 777: } ! 778: ! 779: printk( "\n* Ethernet MAC Control Registers:\n" ); ! 780: for( i = 0x400, j = 0; i < 0x590; i += 4 ) { ! 781: ! 782: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 783: ! 784: if( ( ++j & 0x3 ) == 0 ) { ! 785: printk( "\n" ); ! 786: } ! 787: ! 788: } ! 789: ! 790: printk( "\n* Send Data Initiator Control:\n" ); ! 791: for( i = 0xc00, j = 0; i < 0xc10; i += 4 ) { ! 792: ! 793: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 794: ! 795: if( ( ++j & 0x3 ) == 0 ) { ! 796: printk( "\n" ); ! 797: } ! 798: ! 799: } ! 800: ! 801: printk( "\n* Send Data Completion Control:\n" ); ! 802: printk( "%04X: %08X ", 0x1000, bcm_read_reg32( 0x1000 ) ); ! 803: printk( "%04X: %08X \n", 0x1008, bcm_read_reg32( 0x1008 ) ); ! 804: ! 805: printk( "\n* Send BD Ring Selector Control:\n" ); ! 806: printk( "%04X: %08X ", 0x1400, bcm_read_reg32( 0x1400 ) ); ! 807: printk( "%04X: %08X ", 0x1404, bcm_read_reg32( 0x1404 ) ); ! 808: printk( "%04X: %08X \n", 0x1408, bcm_read_reg32( 0x1408 ) ); ! 809: ! 810: printk( "\n* Send BD Initiator Control:\n" ); ! 811: printk( "%04X: %08X ", 0x1800, bcm_read_reg32( 0x1800 ) ); ! 812: printk( "%04X: %08X \n", 0x1804, bcm_read_reg32( 0x1804 ) ); ! 813: ! 814: printk( "\n* Send BD Completion Control:\n" ); ! 815: printk( "%04X: %08X ", 0x1c00, bcm_read_reg32( 0x1c00 ) ); ! 816: ! 817: printk( "\n* Receive List Placement Control:\n" ); ! 818: for( i = 0x2000, j = 0; i < 0x2020; i += 4 ) { ! 819: ! 820: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 821: ! 822: if( ( ++j & 0x3 ) == 0 ) { ! 823: printk( "\n" ); ! 824: } ! 825: ! 826: } ! 827: ! 828: printk( "\n* Receive Data & Receive BD Initiator Control:\n" ); ! 829: printk( "%04X: %08X ", 0x2400, bcm_read_reg32( 0x2400 ) ); ! 830: printk( "%04X: %08X \n", 0x2404, bcm_read_reg32( 0x2404 ) ); ! 831: ! 832: printk( "\n* Jumbo Receive BD Ring RCB:\n" ); ! 833: for( i = 0x2440, j = 0; i < 0x2450; i += 4 ) { ! 834: ! 835: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 836: ! 837: if( ( ++j & 0x3 ) == 0 ) { ! 838: printk( "\n" ); ! 839: } ! 840: ! 841: } ! 842: ! 843: printk( "\n* Standard Receive BD Ring RCB:\n" ); ! 844: for( i = 0x2450, j = 0; i < 0x2460; i += 4 ) { ! 845: ! 846: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 847: ! 848: if( ( ++j & 0x3 ) == 0 ) { ! 849: printk( "\n" ); ! 850: } ! 851: ! 852: } ! 853: ! 854: printk( "\n* Mini Receive BD Ring RCB:\n" ); ! 855: for( i = 0x2460, j = 0; i < 0x2470; i += 4 ) { ! 856: ! 857: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 858: ! 859: if( ( ++j & 0x3 ) == 0 ) { ! 860: printk( "\n" ); ! 861: } ! 862: ! 863: } ! 864: ! 865: printk( "\nRDI Timer Mode Register:\n" ); ! 866: printk( "%04X: %08X \n", 0x24f0, bcm_read_reg32( 0x24f0 ) ); ! 867: ! 868: printk( "\n* Receive BD Initiator Control:\n" ); ! 869: for( i = 0x2c00, j = 0; i < 0x2c20; i += 4 ) { ! 870: ! 871: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 872: ! 873: if( ( ++j & 0x3 ) == 0 ) { ! 874: printk( "\n" ); ! 875: } ! 876: ! 877: } ! 878: ! 879: printk( "\n* Receive BD Completion Control:\n" ); ! 880: for( i = 0x3000, j = 0; i < 0x3014; i += 4 ) { ! 881: ! 882: printk( "%04X: %08X ", i, bcm_read_reg32( i ) ); ! 883: ! 884: if( ( ++j & 0x3 ) == 0 ) { ! 885: printk( "\n" ); ! 886: } ! 887: ! 888: } ! 889: } ! 890: #endif ! 891: ! 892: ! 893: ! 894: /* ! 895: * NVRAM access ! 896: */ ! 897: ! 898: static int ! 899: bcm_nvram_lock( void ) ! 900: { ! 901: int i; ! 902: ! 903: /* ! 904: * Acquire NVRam lock (REQ0) & wait for arbitration won (ARB0_WON) ! 905: */ ! 906: // bcm_setb_reg32( SW_ARB_R, BIT32( 0 ) ); ! 907: bcm_setb_reg32( SW_ARB_R, BIT32( 1 ) ); ! 908: ! 909: i = 2000; ! 910: while( ( --i ) && ! 911: // ( bcm_read_reg32( SW_ARB_R ) & BIT32( 8 ) ) == 0 ) { ! 912: ( bcm_read_reg32( SW_ARB_R ) & BIT32( 9 ) ) == 0 ) { ! 913: ms_delay( 1 ); ! 914: } ! 915: ! 916: // return on error ! 917: if( i == 0 ) { ! 918: #ifdef BCM_DEBUG ! 919: printk("bcm57xx: failed to lock nvram"); ! 920: #endif ! 921: return -1; ! 922: } ! 923: ! 924: return 0; ! 925: } ! 926: ! 927: static void ! 928: bcm_nvram_unlock( void ) ! 929: { ! 930: /* ! 931: * release NVRam lock (CLR0) ! 932: */ ! 933: // bcm_setb_reg32( SW_ARB_R, BIT32( 4 ) ); ! 934: bcm_setb_reg32( SW_ARB_R, BIT32( 5 ) ); ! 935: } ! 936: ! 937: static void ! 938: bcm_nvram_init( void ) ! 939: { ! 940: /* ! 941: * enable access to NVRAM registers ! 942: */ ! 943: if(IS_5714) { ! 944: bcm_setb_reg32( NVM_ACC_R, BIT32( 1 ) | BIT32( 0 ) ); ! 945: } ! 946: ! 947: /* ! 948: * disable bit-bang method 19& disable interface bypass ! 949: */ ! 950: bcm_clrb_reg32( NVM_CFG1_R, BIT32( 31 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 14 ) | BIT32( 16 ) ); ! 951: bcm_setb_reg32( NVM_CFG1_R, BIT32 ( 13 ) | BIT32 ( 17 )); ! 952: ! 953: /* ! 954: * enable Auto SEEPROM Access ! 955: */ ! 956: bcm_setb_reg32( MISC_LOCAL_CTRL_R, BIT32 ( 24 ) ); ! 957: ! 958: /* ! 959: * NVRAM write enable ! 960: */ ! 961: bcm_setb_reg32( MODE_CTRL_R, BIT32 ( 21 ) ); ! 962: } ! 963: ! 964: static i32_t ! 965: bcm_nvram_read( u32_t f_addr_u32, u32_t *f_val_pu32, u32_t lock ) ! 966: { ! 967: u32_t i; ! 968: ! 969: /* ! 970: * parameter check ! 971: */ ! 972: if( f_addr_u32 > NVM_ADDR_MSK ) { ! 973: return -1; ! 974: } ! 975: ! 976: /* ! 977: * Acquire NVRam lock (REQ0) & wait for arbitration won (ARB0_WON) ! 978: */ ! 979: if( lock && (bcm_nvram_lock() == -1) ) { ! 980: return -1; ! 981: } ! 982: ! 983: /* ! 984: * setup address to read ! 985: */ ! 986: bcm_write_reg32( NVM_ADDR_R, ! 987: bcm_nvram_logical_to_physical_address(f_addr_u32) ); ! 988: // bcm_write_reg32( NVM_ADDR_R, f_addr_u32 ); ! 989: ! 990: /* ! 991: * get the command going ! 992: */ ! 993: bcm_write_reg32( NVM_COM_R, BIT32( 8 ) | BIT32( 7 ) | ! 994: BIT32( 4 ) | BIT32( 3 ) ); ! 995: ! 996: /* ! 997: * wait for command completion ! 998: */ ! 999: i = 2000; ! 1000: while( ( --i ) && ! 1001: ( ( bcm_read_reg32( NVM_COM_R ) & BIT32( 3 ) ) == 0 ) ) { ! 1002: ms_delay( 1 ); ! 1003: } ! 1004: ! 1005: /* ! 1006: * read back data if no error ! 1007: */ ! 1008: if( i != 0 ) { ! 1009: /* ! 1010: * read back data ! 1011: */ ! 1012: *f_val_pu32 = bcm_read_reg32( NVM_READ_R ); ! 1013: } ! 1014: ! 1015: if(lock) ! 1016: bcm_nvram_unlock(); ! 1017: ! 1018: // error ! 1019: if( i == 0 ) { ! 1020: #ifdef BCM_DEBUG ! 1021: printk("bcm57xx: reading from NVRAM failed\n"); ! 1022: #endif ! 1023: return -1; ! 1024: } ! 1025: ! 1026: // success ! 1027: return 0; ! 1028: } ! 1029: ! 1030: static i32_t ! 1031: bcm_nvram_write( u32_t f_addr_u32, u32_t f_value_u32, u32_t lock ) ! 1032: { ! 1033: u32_t i; ! 1034: ! 1035: /* ! 1036: * parameter check ! 1037: */ ! 1038: if( f_addr_u32 > NVM_ADDR_MSK ) { ! 1039: return -1; ! 1040: } ! 1041: ! 1042: /* ! 1043: * Acquire NVRam lock (REQ0) & wait for arbitration won (ARB0_WON) ! 1044: */ ! 1045: if( lock && (bcm_nvram_lock() == -1) ) { ! 1046: return -1; ! 1047: } ! 1048: ! 1049: /* ! 1050: * setup address to write ! 1051: */ ! 1052: bcm_write_reg32( NVM_ADDR_R, bcm_nvram_logical_to_physical_address( f_addr_u32 ) ); ! 1053: ! 1054: /* ! 1055: * setup write data ! 1056: */ ! 1057: bcm_write_reg32( NVM_WRITE_R, f_value_u32 ); ! 1058: ! 1059: /* ! 1060: * get the command going ! 1061: */ ! 1062: bcm_write_reg32( NVM_COM_R, BIT32( 8 ) | BIT32( 7 ) | ! 1063: BIT32( 5 ) | BIT32( 4 ) | BIT32( 3 ) ); ! 1064: ! 1065: /* ! 1066: * wait for command completion ! 1067: */ ! 1068: i = 2000; ! 1069: while( ( --i ) && ! 1070: ( ( bcm_read_reg32( NVM_COM_R ) & BIT32( 3 ) ) == 0 ) ) { ! 1071: ms_delay( 1 ); ! 1072: } ! 1073: ! 1074: /* ! 1075: * release NVRam lock (CLR0) ! 1076: */ ! 1077: if(lock) ! 1078: bcm_nvram_unlock(); ! 1079: ! 1080: // error ! 1081: if( i == 0 ) { ! 1082: #ifdef BCM_DEBUG ! 1083: printk("bcm57xx: writing to NVRAM failed\n"); ! 1084: #endif ! 1085: return -1; ! 1086: } ! 1087: ! 1088: // success ! 1089: return 0; ! 1090: } ! 1091: ! 1092: /* ! 1093: * PHY initialization ! 1094: */ ! 1095: static i32_t ! 1096: bcm_mii_phy_init( void ) ! 1097: { ! 1098: static const u32_t PHY_STAT_R = (u32_t) 0x01; ! 1099: static const u32_t AUX_STAT_R = (u32_t) 0x19; ! 1100: static const u32_t MODE_GMII = BIT32( 3 ); ! 1101: static const u32_t MODE_MII = BIT32( 2 ); ! 1102: static const u32_t NEG_POLARITY = BIT32( 10 ); ! 1103: static const u32_t MII_MSK = ( MODE_GMII | MODE_MII ); ! 1104: static const u16_t GIGA_ETH = ( BIT16( 10 ) | BIT16( 9 ) ); ! 1105: i32_t i; ! 1106: u16_t v; ! 1107: ! 1108: /* ! 1109: * enable MDI communication ! 1110: */ ! 1111: bcm_write_reg32( MDI_CTRL_R, (u32_t) 0x0 ); ! 1112: ! 1113: /* ! 1114: * check link up ! 1115: */ ! 1116: i = 2500; ! 1117: do { ! 1118: ms_delay( 1 ); ! 1119: // register needs to be read twice! ! 1120: bcm_mii_read16( PHY_STAT_R, &v ); ! 1121: bcm_mii_read16( PHY_STAT_R, &v ); ! 1122: } while( ( --i ) && ! 1123: ( ( v & BIT16( 2 ) ) == 0 ) ); ! 1124: ! 1125: if( i == 0 ) { ! 1126: #ifdef BCM_DEBUG ! 1127: printk( "bcm57xx: link is down\n" ); ! 1128: #endif ! 1129: return -1; ! 1130: } ! 1131: ! 1132: #ifdef BCM_DEBUG ! 1133: printk( "bcm57xx: link is up\n" ); ! 1134: #endif ! 1135: if( !IS_COPPER_PHY ) { ! 1136: return 0; ! 1137: } ! 1138: ! 1139: /* ! 1140: * setup GMII or MII interface ! 1141: */ ! 1142: i = bcm_read_reg32( ETH_MAC_MODE_R ); ! 1143: /* ! 1144: * read status register twice, since the first ! 1145: * read fails once between here and the moon... ! 1146: */ ! 1147: bcm_mii_read16( AUX_STAT_R, &v ); ! 1148: bcm_mii_read16( AUX_STAT_R, &v ); ! 1149: ! 1150: if( ( v & GIGA_ETH ) == GIGA_ETH ) { ! 1151: #ifdef BCM_DEBUG ! 1152: printk( "bcm57xx: running PHY in GMII mode (1000BaseT)\n" ); ! 1153: #endif ! 1154: // GMII device ! 1155: if( ( i & MII_MSK ) != MODE_GMII ) { ! 1156: i &= ~MODE_MII; ! 1157: i |= MODE_GMII; ! 1158: } ! 1159: ! 1160: } else { ! 1161: #ifdef BCM_DEBUG ! 1162: printk( "bcm57xx: running PHY in MII mode (10/100BaseT)\n" ); ! 1163: #endif ! 1164: // MII device ! 1165: if( ( i & MII_MSK ) != MODE_MII ) { ! 1166: i &= ~MODE_GMII; ! 1167: i |= MODE_MII; ! 1168: } ! 1169: ! 1170: } ! 1171: ! 1172: if( IS_5704 && !IS_SERDES ) { ! 1173: #ifdef BCM_DEBUG ! 1174: printk( "bcm57xx: set the link ready signal for 5704C to negative polarity\n" ); ! 1175: #endif ! 1176: i |= NEG_POLARITY; // set the link ready signal for 5704C to negative polarity ! 1177: } ! 1178: ! 1179: bcm_write_reg32( ETH_MAC_MODE_R, i ); ! 1180: ! 1181: return 0; ! 1182: } ! 1183: ! 1184: static i32_t ! 1185: bcm_tbi_phy_init( void ) ! 1186: { ! 1187: i32_t i; ! 1188: #if 0 ! 1189: /* ! 1190: * set TBI mode full duplex ! 1191: */ ! 1192: bcm_clrb_reg32( ETH_MAC_MODE_R, BIT32( 1 ) ); ! 1193: bcm_setb_reg32( ETH_MAC_MODE_R, BIT32( 2 ) | BIT32( 3 ) ); ! 1194: ! 1195: /* ! 1196: * enable MDI communication ! 1197: */ ! 1198: bcm_write_reg32( MDI_CTRL_R, (u32_t) 0x0 ); ! 1199: ! 1200: /* Disable link change interrupt. */ ! 1201: bcm_write_reg32( ETH_MAC_EVT_EN_R, 0 ); ! 1202: ! 1203: /* ! 1204: * set link polarity ! 1205: */ ! 1206: bcm_clrb_reg32( ETH_MAC_MODE_R, BIT32( 10 ) ); ! 1207: ! 1208: /* ! 1209: * wait for sync/config changes ! 1210: */ ! 1211: for( i = 0; i < 100; i++ ) { ! 1212: bcm_write_reg32( ETH_MAC_STAT_R, ! 1213: BIT32( 3 ) | BIT32( 4 ) ); ! 1214: ! 1215: us_delay( 20 ); ! 1216: ! 1217: if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & ! 1218: ( BIT32( 3 ) | BIT32( 4 ) ) ) == 0 ) { ! 1219: break; ! 1220: } ! 1221: ! 1222: } ! 1223: #endif ! 1224: /* ! 1225: * wait for sync to come up ! 1226: */ ! 1227: for( i = 0; i < 100; i++ ) { ! 1228: ! 1229: if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & BIT32( 0 ) ) != 0 ) { ! 1230: break; ! 1231: } ! 1232: ! 1233: us_delay( 20 ); ! 1234: } ! 1235: ! 1236: if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & BIT32( 0 ) ) == 0) { ! 1237: #ifdef BCM_DEBUG ! 1238: printk( "bcm57xx: link is down\n" ); ! 1239: #endif ! 1240: return -1; ! 1241: } ! 1242: #if 0 ! 1243: /* ! 1244: * clear all attentions ! 1245: */ ! 1246: bcm_write_reg32( ETH_MAC_STAT_R, (u32_t) ~0 ); ! 1247: #endif ! 1248: ! 1249: #ifdef BCM_DEBUG ! 1250: printk( "bcm57xx: link is up\n" ); ! 1251: #endif ! 1252: return 0; ! 1253: } ! 1254: ! 1255: static i32_t ! 1256: bcm_phy_init( void ) ! 1257: { ! 1258: static const u16_t SRAM_HW_CFG = (u16_t) 0x0b58; ! 1259: u32_t l_val_u32; ! 1260: i32_t l_ret_i32 = 0; ! 1261: ! 1262: /* ! 1263: * get HW configuration from SRAM ! 1264: */ ! 1265: l_val_u32 = bcm_read_mem32( SRAM_HW_CFG ); ! 1266: l_val_u32 &= ( BIT32( 5 ) | BIT32( 4 ) ); ! 1267: ! 1268: switch( l_val_u32 ) { ! 1269: case 0x10: { ! 1270: #ifdef BCM_DEBUG ! 1271: printk( "bcm57xx: copper PHY detected\n" ); ! 1272: #endif ! 1273: ! 1274: bcm_device_u64 |= BCM_DEV_COPPER; ! 1275: l_ret_i32 = bcm_mii_phy_init(); ! 1276: } break; ! 1277: ! 1278: case 0x20: { ! 1279: #ifdef BCM_DEBUG ! 1280: printk( "bcm57xx: fiber PHY detected\n" ); ! 1281: #endif ! 1282: ! 1283: if( !IS_SERDES ) { ! 1284: #ifdef BCM_DEBUG ! 1285: printk( "bcm57xx: running PHY in gmii/mii mode\n" ); ! 1286: #endif ! 1287: l_ret_i32 = bcm_mii_phy_init(); ! 1288: } else { ! 1289: #ifdef BCM_DEBUG ! 1290: printk( "bcm57xx: running PHY in tbi mode\n" ); ! 1291: #endif ! 1292: l_ret_i32 = bcm_tbi_phy_init(); ! 1293: } ! 1294: ! 1295: } break; ! 1296: ! 1297: default: { ! 1298: #ifdef BCM_DEBUG ! 1299: printk( "bcm57xx: unknown PHY type detected, terminating\n" ); ! 1300: #endif ! 1301: l_ret_i32 = -1; ! 1302: } ! 1303: ! 1304: } ! 1305: ! 1306: return l_ret_i32; ! 1307: } ! 1308: ! 1309: /* ! 1310: * ring initialization ! 1311: */ ! 1312: static void ! 1313: bcm_init_rxprod_ring( void ) ! 1314: { ! 1315: u32_t v; ! 1316: u32_t i; ! 1317: ! 1318: /* ! 1319: * clear out the whole rx prod ring for sanity ! 1320: */ ! 1321: memset( (void *) &bcm_rxprod_ring, ! 1322: 0, ! 1323: BCM_RXPROD_RING_SIZE * sizeof( bcm_rxbd_t ) ); ! 1324: mb(); ! 1325: ! 1326: /* ! 1327: * assign buffers & indices to the ring members ! 1328: */ ! 1329: for( i = 0; i < BCM_MAX_RX_BUF; i++ ) { ! 1330: bcm_rxprod_ring[i].m_hostaddr_st.m_hi_u32 = ! 1331: (u32_t) ( (u64_t) &bcm_rx_buffer_pu08[i] >> 32 ); ! 1332: bcm_rxprod_ring[i].m_hostaddr_st.m_lo_u32 = ! 1333: (u32_t) ( (u64_t) &bcm_rx_buffer_pu08[i] & ! 1334: (u64_t) 0xffffffff ); ! 1335: bcm_rxprod_ring[i].m_idxlen_u32 = ( i << 16 ); ! 1336: bcm_rxprod_ring[i].m_idxlen_u32 += BCM_BUF_SIZE; ! 1337: } ! 1338: ! 1339: /* ! 1340: * clear rcb registers & disable rings ! 1341: * NOTE: mini & jumbo rings are not supported, ! 1342: * still rcb's are cleaned out for sanity ! 1343: */ ! 1344: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_JUM ), RCB_FLAG_RING_DISABLED ); ! 1345: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 1346: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 1347: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 1348: ! 1349: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_STD ), RCB_FLAG_RING_DISABLED ); ! 1350: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 1351: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 1352: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 1353: ! 1354: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_MIN ), RCB_FLAG_RING_DISABLED ); ! 1355: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 1356: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 1357: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 1358: ! 1359: /* ! 1360: * clear rx producer index of std producer ring ! 1361: */ ! 1362: bcm_write_reg32( RXPROD_PROD_IND, 0 ); ! 1363: ! 1364: /* ! 1365: * setup rx standard rcb using recommended NIC addr (hard coded) ! 1366: */ ! 1367: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_STD ), ! 1368: (u32_t) ( (u64_t) &bcm_rxprod_ring >> 32 ) ); ! 1369: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_STD ), ! 1370: (u32_t) ( (u64_t) &bcm_rxprod_ring & (u64_t) 0xffffffff ) ); ! 1371: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_STD ), ! 1372: (u32_t) BCM_NIC_RX_OFFS ); ! 1373: ! 1374: if( IS_5704 || IS_5703 ) { ! 1375: // 5704: length field = max buffer len ! 1376: v = (u32_t) BCM_BUF_SIZE << 16; ! 1377: } else { ! 1378: // 5714: length field = number of ring entries ! 1379: v = (u32_t) BCM_RXPROD_RING_SIZE << 16; ! 1380: } ! 1381: ! 1382: v &= (u32_t) ~RCB_FLAG_RING_DISABLED; ! 1383: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_STD ), v ); ! 1384: } ! 1385: ! 1386: static void ! 1387: bcm_init_rxret_ring( void ) ! 1388: { ! 1389: u32_t i; ! 1390: u16_t v; ! 1391: ! 1392: /* ! 1393: * clear out the whole rx ret ring for sanity ! 1394: */ ! 1395: memset( (void *) &bcm_rxret_ring, ! 1396: 0, ! 1397: 2 * BCM_RXRET_RING_SIZE * sizeof( bcm_rxbd_t ) ); ! 1398: mb(); ! 1399: ! 1400: /* ! 1401: * setup return ring size dependent on installed device ! 1402: */ ! 1403: bcm_rxret_ring_sz = BCM_RXRET_RING_SIZE; ! 1404: if( IS_5704 || IS_5703 ) { ! 1405: bcm_rxret_ring_sz *= 2; ! 1406: } ! 1407: ! 1408: /* ! 1409: * clear rcb memory & disable rings ! 1410: * NOTE: 5714 only supports one return ring, ! 1411: * still all possible rcb's are cleaned out for sanity ! 1412: */ ! 1413: v = BCM_RXRET_RCB_OFFS; ! 1414: for( i = 0; i < BCM_MAX_RXRET_RING; i++ ) { ! 1415: bcm_write_mem32( BCM_RCB_LENFLAG_u16( v ), RCB_FLAG_RING_DISABLED ); ! 1416: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( v ), 0 ); ! 1417: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( v ), 0 ); ! 1418: bcm_write_mem32( BCM_RCB_NICADDR_u16( v ), 0 ); ! 1419: ! 1420: v += BCM_RCB_SIZE_u16; ! 1421: } ! 1422: ! 1423: /* ! 1424: * clear rx consumer index of return ring ! 1425: */ ! 1426: bcm_write_reg32( RXRET_CONS_IND, 0 ); ! 1427: ! 1428: /* ! 1429: * setup rx ret rcb ! 1430: * NOTE: NIC address not aplicable in return rings ! 1431: */ ! 1432: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXRET_RCB_OFFS ), ! 1433: (u32_t) ( (u64_t) &bcm_rxret_ring >> 32 ) ); ! 1434: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXRET_RCB_OFFS ), ! 1435: (u32_t) ( (u64_t) &bcm_rxret_ring & ! 1436: (u64_t) 0xffffffff ) ); ! 1437: bcm_write_mem32( BCM_RCB_NICADDR_u16( BCM_RXRET_RCB_OFFS ), 0 ); ! 1438: ! 1439: i = bcm_rxret_ring_sz; ! 1440: i <<= 16; ! 1441: i &= (u32_t) ~RCB_FLAG_RING_DISABLED; ! 1442: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXRET_RCB_OFFS ), i ); ! 1443: } ! 1444: ! 1445: static void ! 1446: bcm_init_tx_ring( void ) ! 1447: { ! 1448: u32_t i; ! 1449: u16_t v; ! 1450: ! 1451: /* ! 1452: * clear out the whole tx ring for sanity ! 1453: */ ! 1454: memset( (void *) &bcm_tx_ring, ! 1455: 0, ! 1456: BCM_TX_RING_SIZE * sizeof( bcm_txbd_t ) ); ! 1457: mb(); ! 1458: ! 1459: /* ! 1460: * assign buffers to the ring members & setup invariant flags ! 1461: */ ! 1462: for( i = 0; i < BCM_MAX_TX_BUF; i++ ) { ! 1463: bcm_tx_ring[i].m_hostaddr_st.m_hi_u32 = ! 1464: (u32_t) ( (u64_t) &bcm_tx_buffer_pu08[i] >> 32 ); ! 1465: bcm_tx_ring[i].m_hostaddr_st.m_lo_u32 = ! 1466: (u32_t) ( (u64_t) &bcm_tx_buffer_pu08[i] & ! 1467: (u64_t) 0xffffffff ); ! 1468: // flags: indicate last packet & coal now ! 1469: // -last packet is always true (only one send packet supported) ! 1470: // -coal now needed to always get the consumed bd's (since ! 1471: // only a few bd's are set up which permanently are recycled) ! 1472: bcm_tx_ring[i].m_lenflags_u32 = ( BIT32( 2 ) | BIT32( 7 ) ); ! 1473: bcm_tx_ring[i].m_VLANtag_u32 = (u32_t) 0; // not used ! 1474: } ! 1475: ! 1476: /* ! 1477: * clear rcb memory & disable rings ! 1478: * NOTE: 5714 only supports one send ring, ! 1479: * still all possible rcb's are cleaned out for sanity ! 1480: */ ! 1481: v = BCM_TX_RCB_OFFS; ! 1482: for( i = 0; i < BCM_MAX_TX_RING; i++ ) { ! 1483: bcm_write_mem32( BCM_RCB_LENFLAG_u16( v ), RCB_FLAG_RING_DISABLED ); ! 1484: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( v ), 0 ); ! 1485: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( v ), 0 ); ! 1486: bcm_write_mem32( BCM_RCB_NICADDR_u16( v ), 0 ); ! 1487: ! 1488: v += BCM_RCB_SIZE_u16; ! 1489: } ! 1490: ! 1491: /* ! 1492: * clear host/nic producer indices ! 1493: */ ! 1494: bcm_write_reg32( TX_NIC_PROD_IND, 0 ); ! 1495: bcm_write_reg32( TX_PROD_IND, 0 ); ! 1496: ! 1497: /* ! 1498: * setup tx rcb using recommended NIC addr (hard coded) ! 1499: */ ! 1500: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( BCM_TX_RCB_OFFS ), ! 1501: (u32_t) ( (u64_t) &bcm_tx_ring >> 32 ) ); ! 1502: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( BCM_TX_RCB_OFFS ), ! 1503: (u32_t) ( (u64_t) &bcm_tx_ring & ! 1504: (u64_t) 0xffffffff ) ); ! 1505: bcm_write_mem32( BCM_RCB_NICADDR_u16( BCM_TX_RCB_OFFS ), ! 1506: (u32_t) BCM_NIC_TX_OFFS ); ! 1507: ! 1508: if( IS_5704 || IS_5703 ) { ! 1509: // 5704: length field = max buffer len ! 1510: i = (u32_t) BCM_BUF_SIZE << 16; ! 1511: } else { ! 1512: // 5714: length field = number of ring entries ! 1513: i = (u32_t) BCM_TX_RING_SIZE << 16; ! 1514: } ! 1515: ! 1516: i &= ( u32_t ) ~RCB_FLAG_RING_DISABLED; ! 1517: bcm_write_mem32( BCM_RCB_LENFLAG_u16( BCM_TX_RCB_OFFS ), i ); ! 1518: ! 1519: /* ! 1520: * remember the next bd index to be used ! 1521: * & number of available buffers ! 1522: */ ! 1523: bcm_tx_stop_u32 = BCM_MAX_TX_BUF; ! 1524: bcm_tx_bufavail_u32 = BCM_MAX_TX_BUF; ! 1525: } ! 1526: ! 1527: static i32_t ! 1528: bcm_mac_init( u08_t *f_mac_pu08 ) ! 1529: { ! 1530: static const u16_t MEM_MAC_LO = (u16_t) 0x0c18; ! 1531: static const u16_t MEM_MAC_HI = (u16_t) 0x0c14; ! 1532: ! 1533: u32_t NVR_MAC_LO = (u16_t) 0x80; ! 1534: u32_t NVR_MAC_HI = (u16_t) 0x7c; ! 1535: ! 1536: bcm_addr64_t l_mac_st; ! 1537: u32_t i; ! 1538: u32_t v; ! 1539: ! 1540: /* ! 1541: * Use MAC address from device tree if possible ! 1542: */ ! 1543: for( i = 0, v = 0; i < 6; i++ ) { ! 1544: v += (u32_t) f_mac_pu08[i]; ! 1545: } ! 1546: ! 1547: if( v != 0 ) { ! 1548: l_mac_st.m_hi_u32 = ( ( (u32_t) f_mac_pu08[0]) << 8 ); ! 1549: l_mac_st.m_hi_u32 |= ( ( (u32_t) f_mac_pu08[1]) << 0 ); ! 1550: l_mac_st.m_lo_u32 = ( ( (u32_t) f_mac_pu08[2]) << 24 ); ! 1551: l_mac_st.m_lo_u32 |= ( ( (u32_t) f_mac_pu08[3]) << 16 ); ! 1552: l_mac_st.m_lo_u32 |= ( ( (u32_t) f_mac_pu08[4]) << 8 ); ! 1553: l_mac_st.m_lo_u32 |= ( ( (u32_t) f_mac_pu08[5]) << 0 ); ! 1554: } else { ! 1555: /* ! 1556: * try to read MAC address from MAC mailbox ! 1557: */ ! 1558: l_mac_st.m_hi_u32 = bcm_read_mem32( MEM_MAC_HI ); ! 1559: ! 1560: if( ( l_mac_st.m_hi_u32 >> 16 ) == (u32_t) 0x484b ) { ! 1561: l_mac_st.m_hi_u32 &= (u32_t) 0xffff; ! 1562: l_mac_st.m_lo_u32 = bcm_read_mem32( MEM_MAC_LO ); ! 1563: } else { ! 1564: i32_t l_err_i32; ! 1565: ! 1566: /* ! 1567: * otherwise retrieve MAC address from NVRam ! 1568: */ ! 1569: if( ( bcm_read_reg32( MAC_FUNC_R ) & BIT32( 2 ) ) != 0 ) { ! 1570: // secondary MAC is in use, address in NVRAM changes ! 1571: NVR_MAC_LO += 0x50; ! 1572: NVR_MAC_HI += 0x50; ! 1573: } ! 1574: ! 1575: l_err_i32 = bcm_nvram_read( NVR_MAC_LO, &l_mac_st.m_lo_u32, 1 ); ! 1576: l_err_i32 += bcm_nvram_read( NVR_MAC_HI, &l_mac_st.m_hi_u32, 1 ); ! 1577: ! 1578: // return on read error ! 1579: if( l_err_i32 < 0 ) { ! 1580: #ifdef BCM_DEBUG ! 1581: printk( "bcm57xx: failed to retrieve MAC address\n" ); ! 1582: #endif ! 1583: return -1; ! 1584: } ! 1585: } ! 1586: } ! 1587: ! 1588: /* ! 1589: * write the mac addr into the NIC's register area ! 1590: */ ! 1591: bcm_write_reg32( MAC_ADDR_OFFS_HI(0), l_mac_st.m_hi_u32 ); ! 1592: bcm_write_reg32( MAC_ADDR_OFFS_LO(0), l_mac_st.m_lo_u32 ); ! 1593: for( i = 1; i < BCM_NUM_MAC_ADDR; i++ ) { ! 1594: bcm_write_reg32( MAC_ADDR_OFFS_HI(i), 0 ); ! 1595: bcm_write_reg32( MAC_ADDR_OFFS_LO(i), 0 ); ! 1596: } ! 1597: ! 1598: /* ! 1599: * WY 26.01.07 ! 1600: * not needed anymore, s.a. ! 1601: if( IS_5704 != 0 ) { ! 1602: ! 1603: v = MAC5704_ADDR_OFFS; ! 1604: for( i = 0; i < BCM_NUM_MAC5704_ADDR; i++ ) { ! 1605: bcm_write_reg32( v, l_mac_st.m_hi_u32 ); ! 1606: v += sizeof( u32_t ); ! 1607: bcm_write_reg32( v, l_mac_st.m_lo_u32 ); ! 1608: v += sizeof( u32_t ); ! 1609: } ! 1610: ! 1611: } ! 1612: */ ! 1613: ! 1614: /* ! 1615: * return MAC address as string ! 1616: */ ! 1617: f_mac_pu08[0] = (u08_t) ( ( l_mac_st.m_hi_u32 >> 8 ) & (u32_t) 0xff ); ! 1618: f_mac_pu08[1] = (u08_t) ( ( l_mac_st.m_hi_u32 ) & (u32_t) 0xff ); ! 1619: f_mac_pu08[2] = (u08_t) ( ( l_mac_st.m_lo_u32 >> 24 ) & (u32_t) 0xff ); ! 1620: f_mac_pu08[3] = (u08_t) ( ( l_mac_st.m_lo_u32 >> 16 ) & (u32_t) 0xff ); ! 1621: f_mac_pu08[4] = (u08_t) ( ( l_mac_st.m_lo_u32 >> 8 ) & (u32_t) 0xff ); ! 1622: f_mac_pu08[5] = (u08_t) ( ( l_mac_st.m_lo_u32 ) & (u32_t) 0xff ); ! 1623: ! 1624: #ifdef BCM_DEBUG ! 1625: do { ! 1626: i32_t i; ! 1627: printk( "bcm57xx: retrieved MAC address " ); ! 1628: ! 1629: for( i = 0; i < 6; i++ ) { ! 1630: printk( "%02X", f_mac_pu08[i] ); ! 1631: ! 1632: if( i != 5 ) { ! 1633: printk( ":" ); ! 1634: } ! 1635: ! 1636: } ! 1637: ! 1638: printk( "\n" ); ! 1639: } while( 0 ); ! 1640: #endif ! 1641: ! 1642: return 0; ! 1643: } ! 1644: ! 1645: ! 1646: /* ! 1647: ****************************************************************************** ! 1648: * ASF Firmware ! 1649: ****************************************************************************** ! 1650: */ ! 1651: ! 1652: ! 1653: #ifdef BCM_DEBUG ! 1654: #ifdef BCM_SHOW_ASF_REGS ! 1655: static void ! 1656: bcm_asf_check_register( void ) ! 1657: { ! 1658: u32_t i; ! 1659: ! 1660: i = bcm_read_reg32( ASF_CTRL_R ); ! 1661: printk( "bcm57xx: ASF control : %x\n", i ); ! 1662: ! 1663: i = bcm_read_reg32( ASF_WATCHDOG_TIMER_R ); ! 1664: printk( "bcm57xx: ASF Watchdog Timer : %x\n", i ); ! 1665: ! 1666: i = bcm_read_reg32( ASF_HEARTBEAT_TIMER_R ); ! 1667: printk( "bcm57xx: ASF Heartbeat Timer : %x\n", i ); ! 1668: ! 1669: i = bcm_read_reg32( ASF_POLL_TIMER_R ); ! 1670: printk( "bcm57xx: ASF Poll Timer : %x\n", i ); ! 1671: ! 1672: i = bcm_read_reg32( POLL_LEGACY_TIMER_R ); ! 1673: printk( "bcm57xx: Poll Legacy Timer : %x\n", i ); ! 1674: ! 1675: i = bcm_read_reg32( RETRANSMISSION_TIMER_R ); ! 1676: printk( "bcm57xx: Retransmission Timer : %x\n", i ); ! 1677: ! 1678: i = bcm_read_reg32( TIME_STAMP_COUNTER_R ); ! 1679: printk( "bcm57xx: Time Stamp Counter : %x\n", i ); ! 1680: ! 1681: i = bcm_read_reg32( RX_CPU_MODE_R ); ! 1682: printk( "bcm57xx: RX RISC Mode : %x\n", i ); ! 1683: ! 1684: i = bcm_read_reg32( RX_CPU_STATE_R ); ! 1685: printk( "bcm57xx: RX RISC State : %x\n", i ); ! 1686: ! 1687: i = bcm_read_reg32( RX_CPU_PC_R ); ! 1688: printk( "bcm57xx: RX RISC Prg. Counter : %x\n", i ); ! 1689: } ! 1690: #endif ! 1691: #endif ! 1692: ! 1693: static int ! 1694: bcm_fw_halt( void ) ! 1695: { ! 1696: int i; ! 1697: ! 1698: bcm_write_mem32( BCM_FW_MBX_CMD, BCM_NICDRV_PAUSE_FW ); ! 1699: bcm_setb_reg32( RX_CPU_EVENT_R, BIT32( 14 ) ); ! 1700: ! 1701: /* Wait for RX cpu to ACK the event. */ ! 1702: for (i = 0; i < 100; i++) { ! 1703: if(bcm_read_reg32( RX_CPU_EVENT_R ) & BIT32( 14 )) ! 1704: break; ! 1705: ms_delay(1); ! 1706: } ! 1707: if( i>= 100) ! 1708: return -1; ! 1709: return 0; ! 1710: } ! 1711: ! 1712: ! 1713: #ifdef BCM_SW_AUTONEG ! 1714: static void ! 1715: bcm_sw_autoneg( void ) { ! 1716: u32_t i, j, k; ! 1717: u32_t SerDesCfg; ! 1718: u32_t SgDigControl; ! 1719: u32_t SgDigStatus; ! 1720: u32_t ExpectedSgDigControl; ! 1721: int AutoNegJustInitiated = 0; ! 1722: ! 1723: // step 1: init TX 1000BX Autoneg. Register to zero ! 1724: bcm_write_reg32(TX_1000BX_AUTONEG_R, 0); ! 1725: ! 1726: // step 2&3: set TBI mode ! 1727: bcm_setb_reg32( ETH_MAC_MODE_R, BIT32( 2 ) | BIT32( 3 ) ); ! 1728: us_delay(10); ! 1729: ! 1730: // step 4: enable link attention ! 1731: bcm_setb_reg32( ETH_MAC_EVT_EN_R, BIT32( 12 ) ); ! 1732: ! 1733: // step 5: preserve voltage regulator bits ! 1734: SerDesCfg = bcm_read_reg32(SERDES_CTRL_R) & ( BIT32( 20 ) | BIT32( 21 ) ! 1735: | BIT32( 22 ) | BIT32( 23 ) ); ! 1736: ! 1737: // step 6: preserve voltage regulator bits ! 1738: SgDigControl = bcm_read_reg32(HW_AUTONEG_CTRL_R); ! 1739: ! 1740: // step 7: if device is NOT set-up for auto negotiation, then go to step 26 ! 1741: // goto bcm_setup_phy_step26; ! 1742: ! 1743: // We want to use auto negotiation ! 1744: ! 1745: // step 8: we don't want to use flow control ! 1746: ExpectedSgDigControl = 0x81388400; // no flow control ! 1747: ! 1748: // step 9: compare SgDigControl with 0x81388400 ! 1749: if(SgDigControl == ExpectedSgDigControl) { ! 1750: goto bcm_setup_phy_step17; ! 1751: } ! 1752: #ifdef BCM_DEBUG ! 1753: printk("bcm57xx: SgDigControl = %08X\n", SgDigControl); ! 1754: #endif ! 1755: // step 10 ! 1756: bcm_write_reg32(SERDES_CTRL_R, SerDesCfg | 0xC011880); ! 1757: ! 1758: // step 11: restart auto negotiation ! 1759: bcm_write_reg32(HW_AUTONEG_CTRL_R, ExpectedSgDigControl | BIT32( 30 ) ); ! 1760: ! 1761: // step 12: read back HW_AUTONEG_CTRL_R ! 1762: bcm_read_reg32(HW_AUTONEG_CTRL_R); ! 1763: ! 1764: // step 13 ! 1765: us_delay( 5 ); ! 1766: ! 1767: // step 14,15,16: same as step 11, but don't restart auto neg. ! 1768: bcm_write_reg32(HW_AUTONEG_CTRL_R, ExpectedSgDigControl); ! 1769: AutoNegJustInitiated = 1; ! 1770: goto bcm_setup_phy_step30; ! 1771: ! 1772: // step 17: ! 1773: bcm_setup_phy_step17: ! 1774: if( ( bcm_read_reg32(ETH_MAC_STAT_R) & ( BIT32( 1 ) | BIT32( 0 ) ) ) == 0 ) { ! 1775: goto bcm_setup_phy_step30; ! 1776: } ! 1777: ! 1778: // step 18: Get HW Autoneg. Status ! 1779: SgDigStatus = bcm_read_reg32(HW_AUTONEG_STAT_R); ! 1780: ! 1781: // step 19: ! 1782: if( ( SgDigStatus & BIT32(1) ) ! 1783: && ( bcm_read_reg32(ETH_MAC_STAT_R) & BIT32(0) ) ) { ! 1784: // resolve the current flow control? ! 1785: AutoNegJustInitiated = 0; ! 1786: goto bcm_setup_phy_step30; ! 1787: } ! 1788: ! 1789: // step 20 ! 1790: if( SgDigStatus & BIT32(1) ) { ! 1791: goto bcm_setup_phy_step30; ! 1792: } ! 1793: if( AutoNegJustInitiated != 0) { ! 1794: AutoNegJustInitiated = 0; ! 1795: goto bcm_setup_phy_step29; ! 1796: } ! 1797: ! 1798: // step 21, 22, 23, 24: fallback to 1000Mbps-FullDuplex forced mode ! 1799: if( ( bcm_read_reg32( MAC_FUNC_R ) & BIT32( 2 ) ) == 0 ) { ! 1800: // port 0 ! 1801: bcm_write_reg32( SERDES_CTRL_R, 0xC010880 ); ! 1802: } ! 1803: else { // port 1 ! 1804: bcm_write_reg32( SERDES_CTRL_R, 0x4010880 ); ! 1805: } ! 1806: // set to 1000Mbps-FullDuplex ! 1807: bcm_write_reg32(HW_AUTONEG_CTRL_R, 0x1388400); ! 1808: // read back ! 1809: bcm_read_reg32(HW_AUTONEG_CTRL_R); ! 1810: us_delay( 40 ); ! 1811: ! 1812: // step 25: a little bit reduces... ! 1813: goto bcm_setup_phy_step30; ! 1814: ! 1815: // step 26: check if auto negotiation bit is NOT set ! 1816: // bcm_setup_phy_step26: ! 1817: if( ( SgDigControl & BIT32(31) )== 0 ) { ! 1818: printk("No autoneg.\n"); ! 1819: goto bcm_setup_phy_step29; ! 1820: } ! 1821: ! 1822: // step 27: ! 1823: if( ( bcm_read_reg32( MAC_FUNC_R ) & BIT32( 2 ) ) == 0 ) { ! 1824: // port 0 ! 1825: bcm_write_reg32( SERDES_CTRL_R, 0xC010880 ); ! 1826: } ! 1827: else { // port 1 ! 1828: bcm_write_reg32( SERDES_CTRL_R, 0x4010880 ); ! 1829: } ! 1830: ! 1831: // step 28: disable auto neg. and force 1000FD mode ! 1832: bcm_write_reg32(HW_AUTONEG_CTRL_R, 0x1388400); ! 1833: ! 1834: // step 29-31: omitted for 5704S ! 1835: bcm_setup_phy_step29: ! 1836: bcm_setup_phy_step30: ! 1837: ! 1838: // step 32: clear link attentions ! 1839: i = bcm_read_reg32( ETH_MAC_STAT_R ) | BIT32( 3 ) | BIT32( 4 ); ! 1840: k = 100; ! 1841: do { ! 1842: bcm_write_reg32( ETH_MAC_STAT_R, i ); ! 1843: j = bcm_read_reg32( ETH_MAC_STAT_R ); ! 1844: if( ( j & BIT32( 3 ) ) != 0 ) ! 1845: i = i & ~(BIT32( 3 )); ! 1846: if( ( j & BIT32( 4 ) ) != 0 ) ! 1847: i = i & ~(BIT32( 4 )); ! 1848: --k; ! 1849: } while( i & k); ! 1850: ! 1851: // step 33 ! 1852: if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & BIT32( 0 ) ) == 0 ) { ! 1853: goto bcm_setup_phy_step35; ! 1854: } ! 1855: ! 1856: // step 34 ! 1857: i = bcm_read_reg32( ETH_MAC_MODE_R ); ! 1858: i|= BIT32( 17 ); ! 1859: bcm_write_reg32( ETH_MAC_MODE_R, i ); ! 1860: ! 1861: us_delay( 1 ); ! 1862: ! 1863: i = bcm_read_reg32( ETH_MAC_STAT_R ); ! 1864: i&= ~BIT32( 17 ); ! 1865: bcm_write_reg32( ETH_MAC_STAT_R, i ); ! 1866: ! 1867: // step 35 & 36: done ! 1868: bcm_setup_phy_step35: ! 1869: #ifdef BCM_DEBUG ! 1870: printk("bcm57xx: SetupPhy\n"); ! 1871: #endif ! 1872: return; ! 1873: } ! 1874: #endif ! 1875: ! 1876: static int ! 1877: bcm_handle_events( void ) { ! 1878: #ifdef BCM_DEBUG ! 1879: #ifdef BCM_SHOW_ASF_REGS ! 1880: // ASF REGISTER CHECK ! 1881: // ------------------ ! 1882: // check if watchdog timer expired ! 1883: if( bcm_read_reg32( ASF_WATCHDOG_TIMER_R ) == 0 ) { ! 1884: // Show ASF registers ! 1885: bcm_asf_check_register(); ! 1886: ! 1887: // rearm watchdog timer ! 1888: bcm_write_reg32( ASF_WATCHDOG_TIMER_R, 5 ); ! 1889: } ! 1890: #endif ! 1891: #endif ! 1892: ! 1893: #ifdef BCM_SW_AUTONEG ! 1894: // AUTO NEGOTIATION ! 1895: // ---------------- ! 1896: ! 1897: // Check event for Auto Negotiation ! 1898: if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & ! 1899: ( BIT32( 12 ) | BIT32( 3 ) | BIT32( 0 ) ) ) != 0 ) { ! 1900: // link timer procedure ! 1901: bcm_sw_autoneg(); ! 1902: } ! 1903: #endif ! 1904: ! 1905: // ASF FW HEARTBEAT ! 1906: // ---------------- ! 1907: ! 1908: // check if heartsbeat timer expired ! 1909: if( bcm_read_reg32( ASF_HEARTBEAT_TIMER_R ) <= 2) { ! 1910: int i; ! 1911: ! 1912: // Send heartbeat event ! 1913: bcm_write_mem32( BCM_FW_MBX_CMD, BCM_NICDRV_ALIVE ); ! 1914: bcm_write_mem32( BCM_FW_MBX_LEN, 4 ); ! 1915: bcm_write_mem32( BCM_FW_MBX_DATA, 5 ); ! 1916: bcm_setb_reg32( RX_CPU_EVENT_R, BIT32( 14 ) ); ! 1917: ! 1918: // Wait for RX cpu to ACK the event. ! 1919: for (i = 100; i > 0; i--) { ! 1920: if(bcm_read_reg32( RX_CPU_EVENT_R ) & BIT32( 14 )) ! 1921: break; ! 1922: ms_delay(1); ! 1923: } ! 1924: if( i == 0) { ! 1925: #ifdef BCM_DEBUG ! 1926: printk( "bcm57xx: RX cpu did not acknowledge heartbeat event\n" ); ! 1927: #endif ! 1928: return -1; ! 1929: } ! 1930: ! 1931: // rearm heartbeat timer ! 1932: bcm_write_reg32( ASF_HEARTBEAT_TIMER_R, 5 ); ! 1933: } ! 1934: return 0; ! 1935: } ! 1936: ! 1937: /* ! 1938: * interface ! 1939: ****************************************************************************** ! 1940: */ ! 1941: ! 1942: /* ! 1943: * bcm_receive ! 1944: */ ! 1945: static int ! 1946: bcm_receive( char *f_buffer_pc, int f_len_i ) ! 1947: { ! 1948: u32_t l_rxret_prod_u32 = bcm_read_reg32( RXRET_PROD_IND ); ! 1949: u32_t l_rxret_cons_u32 = bcm_read_reg32( RXRET_CONS_IND ); ! 1950: u32_t l_rxprod_prod_u32 = bcm_read_reg32( RXPROD_PROD_IND ); ! 1951: int l_ret_i; ! 1952: #ifdef BCM_DEBUG ! 1953: #ifdef BCM_SHOW_RCV_DATA ! 1954: int i, j; ! 1955: #endif ! 1956: #endif ! 1957: ! 1958: /* ! 1959: * NOTE: dummy read to ensure data has already been DMA'd is ! 1960: * done by the indice reads ! 1961: */ ! 1962: ! 1963: bcm_handle_events(); ! 1964: ! 1965: /* ! 1966: * if producer index == consumer index then nothing was received ! 1967: */ ! 1968: if( l_rxret_prod_u32 == l_rxret_cons_u32 ) { ! 1969: return 0; ! 1970: } ! 1971: ! 1972: /* ! 1973: * discard erroneous packets ! 1974: */ ! 1975: if( ( bcm_rxret_ring[l_rxret_cons_u32].m_typeflags_u32 & BIT32( 10 ) ) != 0 ) { ! 1976: #ifdef BCM_DEBUG ! 1977: printk( "bcm57xx: erroneous frame received\n" ); ! 1978: printk( " : frame discarded\n" ); ! 1979: #endif ! 1980: l_ret_i = 0; ! 1981: } else { ! 1982: /* ! 1983: * get packet length, throw away checksum (last 4 bytes) ! 1984: */ ! 1985: l_ret_i = (int) ( bcm_rxret_ring[l_rxret_cons_u32].m_idxlen_u32 & ! 1986: (u32_t) 0xffff ) - (int) 4; ! 1987: ! 1988: /* ! 1989: * discard oversized packets ! 1990: */ ! 1991: if( l_ret_i > f_len_i ) { ! 1992: #ifdef BCM_DEBUG ! 1993: printk( "bcm57xx: receive packet length error:\n" ); ! 1994: printk( " : incoming 0x%X bytes, available buffer 0x%X bytes\n", l_ret_i, f_len_i ); ! 1995: printk( " : frame discarded\n" ); ! 1996: #endif ! 1997: l_ret_i = 0; ! 1998: } ! 1999: ! 2000: } ! 2001: ! 2002: /* ! 2003: * copy & update data & indices ! 2004: */ ! 2005: if( l_ret_i != 0 ) { ! 2006: u64_t l_cpyaddr_u64; ! 2007: ! 2008: l_cpyaddr_u64 = ! 2009: ( (u64_t) bcm_rxret_ring[l_rxret_cons_u32].m_hostaddr_st.m_hi_u32 << 32 ); ! 2010: l_cpyaddr_u64 += ! 2011: ( (u64_t) bcm_rxret_ring[l_rxret_cons_u32].m_hostaddr_st.m_lo_u32 ); ! 2012: ! 2013: // FIXME: ! 2014: if(l_cpyaddr_u64 == 0) { ! 2015: #ifdef BCM_DEBUG ! 2016: printk("bcm57xx: NULL address\n"); ! 2017: #endif ! 2018: return 0; ! 2019: } ! 2020: // ! 2021: memcpy( (void *) f_buffer_pc, ! 2022: (void *) l_cpyaddr_u64, ! 2023: (size_t) l_ret_i ); ! 2024: ! 2025: } ! 2026: ! 2027: /* ! 2028: * replenish bd to producer ring ! 2029: */ ! 2030: bcm_rxprod_ring[l_rxprod_prod_u32] = ! 2031: bcm_rxret_ring[l_rxret_cons_u32]; ! 2032: bcm_rxprod_ring[l_rxprod_prod_u32].m_idxlen_u32 = ! 2033: ( l_rxprod_prod_u32 << 16 ); ! 2034: bcm_rxprod_ring[l_rxprod_prod_u32].m_idxlen_u32 += ! 2035: (u32_t) BCM_BUF_SIZE; ! 2036: ! 2037: /* ! 2038: * update producer ring's producer index ! 2039: */ ! 2040: l_rxprod_prod_u32 = ( l_rxprod_prod_u32 + 1 ) & ( BCM_RXPROD_RING_SIZE - 1 ); ! 2041: ! 2042: /* ! 2043: * move to the next bd in return ring ! 2044: */ ! 2045: l_rxret_cons_u32 = ( l_rxret_cons_u32 + 1 ) & ( bcm_rxret_ring_sz - 1 ); ! 2046: ! 2047: /* ! 2048: * synchronize before new indices are send to NIC ! 2049: */ ! 2050: mb(); ! 2051: ! 2052: /* ! 2053: * write back new indices ! 2054: */ ! 2055: bcm_write_reg32( RXRET_CONS_IND, l_rxret_cons_u32 ); ! 2056: bcm_write_reg32( RXPROD_PROD_IND, l_rxprod_prod_u32 ); ! 2057: ! 2058: #ifdef BCM_DEBUG ! 2059: #ifdef BCM_SHOW_RCV ! 2060: if( l_ret_i != 0 ) { ! 2061: printk( "bcm57xx: received bytes: %d\n", l_ret_i ); ! 2062: } ! 2063: #ifdef BCM_SHOW_RCV_DATA ! 2064: for( i = 0, j = 0; i < l_ret_i; i++ ) { ! 2065: printk( "%02X ", ( u32_t ) f_buffer_pc[i] ); ! 2066: ! 2067: if( ( ++j % 0x18 ) == 0 ) { ! 2068: printk( "\n" ); ! 2069: } ! 2070: } ! 2071: ! 2072: if( ( i % 0x18 ) != 0 ) { ! 2073: printk( "\n" ); ! 2074: } ! 2075: #endif ! 2076: #endif ! 2077: #endif ! 2078: ! 2079: /* ! 2080: * return packet length ! 2081: */ ! 2082: return l_ret_i; ! 2083: } ! 2084: ! 2085: static int ! 2086: bcm_xmit( char *f_buffer_pc, int f_len_i ) ! 2087: { ! 2088: u32_t l_tx_cons_u32 = bcm_read_reg32( TX_CONS_IND ); ! 2089: u32_t l_tx_prod_u32 = bcm_read_reg32( TX_PROD_IND ); ! 2090: u64_t l_cpyaddr_u64; ! 2091: ! 2092: #ifdef BCM_DEBUG ! 2093: #ifdef BCM_SHOW_XMIT_DATA ! 2094: int i, j; ! 2095: #endif ! 2096: #ifdef BCM_SHOW_IDX ! 2097: printk( "\n" ); ! 2098: printk( "bcm57xx: TX_PROD_IND : 0x%03X\n", l_tx_prod_u32 ); ! 2099: printk( "bcm57xx: TX_CONS_IND : 0x%03X\n", l_tx_cons_u32 ); ! 2100: printk( "bcm57xx: RXPROD_PROD_IND: 0x%03X\n", bcm_read_reg32( RXPROD_PROD_IND ) ); ! 2101: printk( "bcm57xx: RXPROD_CONS_IND: 0x%03X\n", bcm_read_reg32( RXPROD_CONS_IND ) ); ! 2102: printk( "bcm57xx: RXRET_PROD_IND : 0x%03X\n", bcm_read_reg32( RXRET_PROD_IND ) ); ! 2103: printk( "bcm57xx: RXRET_CONS_IND : 0x%03X\n", bcm_read_reg32( RXRET_CONS_IND ) ); ! 2104: printk( "bcm57xx: available txb : 0x%03X\n", bcm_tx_bufavail_u32 ); ! 2105: #endif ! 2106: #ifdef BCM_SHOW_STATS ! 2107: printk( "bcm57xx: bcm_status.m_st_word_u32: %08X\n", bcm_status.m_st_word_u32 ); ! 2108: printk( "bcm57xx: bcm_status.m_st_tag_u32 : %08X\n", bcm_status.m_st_tag_u32 ); ! 2109: printk( "bcm57xx: bcm_status.m_rxprod_cons_u16: %04X\n", ( u32_t ) bcm_status.m_rxprod_cons_u16 ); ! 2110: printk( "bcm57xx: bcm_status.m_unused_u16: %04X\n", ( u32_t ) bcm_status.m_unused_u16 ); ! 2111: printk( "bcm57xx: bcm_status.m_unused_u32: %08X\n", bcm_status.m_unused_u32 ); ! 2112: printk( "bcm57xx: bcm_status.m_tx_cons_u16: %04X\n", ( u32_t ) bcm_status.m_tx_cons_u16 ); ! 2113: printk( "bcm57xx: bcm_status.m_rxret_prod_u16: %04X\n", ( u32_t ) bcm_status.m_rxret_prod_u16 ); ! 2114: #endif ! 2115: #endif ! 2116: ! 2117: bcm_handle_events(); ! 2118: ! 2119: /* ! 2120: * make all consumed bd's available in the ring again ! 2121: * this way only a few buffers are needed instead of ! 2122: * having 512 buffers allocated ! 2123: */ ! 2124: while( bcm_tx_start_u32 != l_tx_cons_u32 ) { ! 2125: bcm_tx_ring[bcm_tx_stop_u32] = bcm_tx_ring[bcm_tx_start_u32]; ! 2126: bcm_tx_stop_u32 = ( bcm_tx_stop_u32 + 1 ) & ( BCM_TX_RING_SIZE - 1 ); ! 2127: bcm_tx_start_u32 = ( bcm_tx_start_u32 + 1 ) & ( BCM_TX_RING_SIZE - 1 ); ! 2128: bcm_tx_bufavail_u32++; ! 2129: } ! 2130: ! 2131: /* ! 2132: * check for tx buffer availability ! 2133: */ ! 2134: if( bcm_tx_bufavail_u32 == 0 ) { ! 2135: #ifdef BCM_DEBUG ! 2136: printk( "bcm57xx: no more transmit buffers available\n" ); ! 2137: #endif ! 2138: return 0; ! 2139: } ! 2140: ! 2141: /* ! 2142: * setup next available bd in tx ring ! 2143: */ ! 2144: bcm_tx_ring[l_tx_prod_u32].m_lenflags_u32 = ( BIT32( 2 ) | BIT32( 7 ) /*| BIT32( 6 )*/ ); ! 2145: bcm_tx_ring[l_tx_prod_u32].m_lenflags_u32 += ( (u32_t) f_len_i << 16 ); ! 2146: // bcm_tx_ring[l_tx_prod_u32].m_VLANtag_u32 = BCM_VLAN_TAG; ! 2147: ! 2148: l_cpyaddr_u64 = ( (u64_t) bcm_tx_ring[l_tx_prod_u32].m_hostaddr_st.m_hi_u32 << 32 ); ! 2149: l_cpyaddr_u64 += ( (u64_t) bcm_tx_ring[l_tx_prod_u32].m_hostaddr_st.m_lo_u32 ); ! 2150: ! 2151: #ifdef BCM_DEBUG ! 2152: #ifdef BCM_SHOW_XMIT_STATS ! 2153: printk("bcm57xx: xmit: l_cpyaddr_u64: 0x%lx\n", l_cpyaddr_u64 ); ! 2154: printk(" f_buffer_pc : 0x%lx\n", f_buffer_pc ); ! 2155: printk(" f_len_i : %d\n", f_len_i ); ! 2156: #endif ! 2157: #endif ! 2158: memcpy( (void *) l_cpyaddr_u64, (void *) f_buffer_pc, (size_t) f_len_i ); ! 2159: ! 2160: /* ! 2161: * update tx producer index & available buffers ! 2162: */ ! 2163: l_tx_prod_u32 = ( l_tx_prod_u32 + 1 ) & ( BCM_TX_RING_SIZE - 1 ); ! 2164: bcm_tx_bufavail_u32--; ! 2165: ! 2166: /* ! 2167: * synchronize before new index is send to NIC ! 2168: */ ! 2169: mb(); ! 2170: ! 2171: bcm_write_reg32( TX_PROD_IND, l_tx_prod_u32 ); ! 2172: ! 2173: #ifdef BCM_DEBUG ! 2174: #ifdef BCM_SHOW_XMIT ! 2175: printk( "bcm57xx: sent bytes: %d\n", f_len_i ); ! 2176: #ifdef BCM_SHOW_XMIT_DATA ! 2177: for( i = 0, j = 0; i < f_len_i; i++ ) { ! 2178: printk( "%02X ", ( u32_t ) f_buffer_pc[i] ); ! 2179: ! 2180: if( ( ++j % 0x18 ) == 0 ) { ! 2181: printk( "\n" ); ! 2182: } ! 2183: ! 2184: } ! 2185: if( ( i % 0x18 ) != 0 ) { ! 2186: printk( "\n" ); ! 2187: } ! 2188: #endif ! 2189: #endif ! 2190: ! 2191: #ifdef BCM_SHOW_STATS ! 2192: // coalesce status block now ! 2193: bcm_setb_reg32( HOST_COAL_MODE_R, BIT32( 3 ) | BIT32( 1 ) ); ! 2194: #endif ! 2195: ! 2196: #endif ! 2197: return f_len_i; ! 2198: } ! 2199: ! 2200: int ! 2201: check_driver( pci_config_t *pci_conf ) ! 2202: { ! 2203: u64_t i; ! 2204: ! 2205: /* ! 2206: * checks whether the driver is handling this device ! 2207: * by verifying vendor & device id ! 2208: * vendor id 0x14e4 == Broadcom ! 2209: */ ! 2210: if( pci_conf->vendor_id != 0x14e4 ) { ! 2211: #ifdef BCM_DEBUG ! 2212: printk( "bcm57xx: netdevice not supported, illegal vendor id\n" ); ! 2213: #endif ! 2214: return -1; ! 2215: } ! 2216: ! 2217: for( i = 0; bcm_dev[i].m_dev_u32 != 0; i++ ) { ! 2218: if( bcm_dev[i].m_dev_u32 == (u32_t) pci_conf->device_id ) { ! 2219: // success ! 2220: break; ! 2221: } ! 2222: } ! 2223: ! 2224: if(bcm_dev[i].m_dev_u32 == 0) { ! 2225: #ifdef BCM_DEBUG ! 2226: printk( "bcm57xx: netdevice not supported, illegal device ID\n" ); ! 2227: #endif ! 2228: return -1; ! 2229: } ! 2230: ! 2231: /* ! 2232: * initialize static variables ! 2233: */ ! 2234: bcm_device_u64 = bcm_dev[i].m_devmsk_u64; ! 2235: bcm_rxret_ring_sz = 0; ! 2236: bcm_baseaddr_u64 = 0; ! 2237: bcm_memaddr_u64 = 0; ! 2238: ! 2239: bcm_tx_start_u32 = 0; ! 2240: bcm_tx_stop_u32 = 0; ! 2241: bcm_tx_bufavail_u32 = 0; ! 2242: ! 2243: bcm_pcicfg_puid = pci_conf->puid; ! 2244: bcm_pcicfg_bus = pci_conf->bus; ! 2245: bcm_pcicfg_devfn = pci_conf->devfn; ! 2246: ! 2247: return 0; ! 2248: } ! 2249: ! 2250: static void ! 2251: bcm_wol_activate(void) ! 2252: { ! 2253: #ifdef BCM_DEBUG ! 2254: u16_t reg_pwr_cap; ! 2255: #endif ! 2256: u16_t reg_pwr_crtl; ! 2257: u32_t wol_mode; ! 2258: ! 2259: wol_mode = bcm_read_reg32( WOL_MODE_R ); ! 2260: bcm_write_reg32( WOL_MODE_R, wol_mode | BIT32(0) ); ! 2261: ! 2262: #ifdef BCM_DEBUG ! 2263: printk( "bcm57xx: WOL activating..." ); ! 2264: #endif ! 2265: ! 2266: // bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_WOL ); ! 2267: // ms_delay( 100 ); ! 2268: ! 2269: #ifdef BCM_DEBUG ! 2270: reg_pwr_cap = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 2271: 2, ! 2272: bcm_pcicfg_bus, ! 2273: bcm_pcicfg_devfn, ! 2274: 0x4a ); ! 2275: printk( "bcm57xx: PM Capability Register: %04X\n", reg_pwr_cap ); ! 2276: #endif ! 2277: /* get curretn power control register */ ! 2278: reg_pwr_crtl = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 2279: 2, ! 2280: bcm_pcicfg_bus, ! 2281: bcm_pcicfg_devfn, ! 2282: 0x4c ); ! 2283: ! 2284: #ifdef BCM_DEBUG ! 2285: printk( "bcm57xx: PM Control/Status Register: %04X\n", reg_pwr_crtl ); ! 2286: #endif ! 2287: ! 2288: /* switch to power state D0 */ ! 2289: reg_pwr_crtl |= 0x8000; ! 2290: reg_pwr_crtl &= ~(0x0003); ! 2291: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2292: 2, ! 2293: bcm_pcicfg_bus, ! 2294: bcm_pcicfg_devfn, ! 2295: 0x4c, ! 2296: reg_pwr_crtl ); ! 2297: ms_delay(10); ! 2298: ! 2299: /* ! 2300: bcm_write_mem32( BCM_NICDRV_WOL_MBX, BCM_WOL_MAGIC_NUMBER | ! 2301: NIC_WOLDRV_STATE_SHUTDOWN | ! 2302: NIC_WOLDRV_WOL | ! 2303: NIC_WOLDRV_SET_MAGIC_PKT ); ! 2304: */ ! 2305: ! 2306: /* switch to power state D3hot */ ! 2307: /* ! 2308: reg_pwr_crtl |= 0x0103; ! 2309: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2310: 2, ! 2311: bcm_pcicfg_bus, ! 2312: bcm_pcicfg_devfn, ! 2313: 0x4c, ! 2314: reg_pwr_crtl ); ! 2315: ms_delay(10); ! 2316: */ ! 2317: ! 2318: #ifdef BCM_DEBUG ! 2319: reg_pwr_crtl = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 2320: 2, ! 2321: bcm_pcicfg_bus, ! 2322: bcm_pcicfg_devfn, ! 2323: 0x4c ); ! 2324: ! 2325: printk( "bcm57xx: PM Control/Status Register: %04X\n", reg_pwr_crtl ); ! 2326: #endif ! 2327: ! 2328: #ifdef BCM_DEBUG ! 2329: printk( "bcm57xx: WOL activated" ); ! 2330: #endif ! 2331: } ! 2332: ! 2333: static int ! 2334: bcm_init( void ) ! 2335: { ! 2336: static const u32_t lc_Maxwait_u32 = (u32_t) 1000; ! 2337: u32_t l_baseaddrL_u32; ! 2338: u32_t l_baseaddrH_u32; ! 2339: u32_t i; ! 2340: char *mac_addr = snk_module_interface.mac_addr; ! 2341: ! 2342: if(snk_module_interface.running != 0) { ! 2343: return 0; ! 2344: } ! 2345: #ifdef BCM_DEBUG ! 2346: printk( "bcm57xx: detected device " ); ! 2347: if( IS_5703 ) { ! 2348: printk( "5703S\n" ); ! 2349: } else if( IS_5704 ) { ! 2350: printk( "5704" ); ! 2351: ! 2352: if( IS_SERDES ) { ! 2353: printk( "S\n" ); ! 2354: } else { ! 2355: printk( "C\n" ); ! 2356: } ! 2357: ! 2358: } else if( IS_5714 ) { ! 2359: printk( "5714\n" ); ! 2360: } ! 2361: #endif ! 2362: /* ! 2363: * setup register & memory base addresses of NIC ! 2364: */ ! 2365: l_baseaddrL_u32 = ( (u32_t) ~0xf & ! 2366: (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 2367: 4, ! 2368: bcm_pcicfg_bus, ! 2369: bcm_pcicfg_devfn, ! 2370: PCI_BAR1_R ) ); ! 2371: ! 2372: l_baseaddrH_u32 = ! 2373: (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 2374: 4, ! 2375: bcm_pcicfg_bus, ! 2376: bcm_pcicfg_devfn, ! 2377: PCI_BAR2_R ); ! 2378: bcm_baseaddr_u64 = (u64_t) l_baseaddrH_u32; ! 2379: bcm_baseaddr_u64 <<= 32; ! 2380: bcm_baseaddr_u64 += (u64_t) l_baseaddrL_u32; ! 2381: snk_kernel_interface->translate_addr(((void *)&(bcm_baseaddr_u64))); ! 2382: bcm_memaddr_u64 = bcm_baseaddr_u64 + BCM_MEMORY_OFFS; ! 2383: ! 2384: #ifdef BCM_DEBUG ! 2385: printk( "bcm57xx: PCI-Puid = 0x%X\n", bcm_pcicfg_puid ); ! 2386: printk( "bcm57xx: PCI-Bus = 0x%X\n", bcm_pcicfg_bus ); ! 2387: printk( "bcm57xx: PCI-DevFn = 0x%X\n", bcm_pcicfg_devfn ); ! 2388: printk( "bcm57xx: device's register base high address = 0x%08X\n", l_baseaddrH_u32 ); ! 2389: printk( "bcm57xx: device's register base low address = 0x%08X\n", l_baseaddrL_u32 ); ! 2390: printk( "bcm57xx: device's register address = 0x%lx\n", bcm_baseaddr_u64 ); ! 2391: #endif ! 2392: ! 2393: /* ! 2394: * 57xx hardware initialization ! 2395: * BCM57xx Programmer's Guide: Section 8, "Initialization" ! 2396: * steps 1 through 101 ! 2397: */ ! 2398: ! 2399: // step 1: enable bus master & memory space in command reg ! 2400: i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 2401: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2402: 2, ! 2403: bcm_pcicfg_bus, ! 2404: bcm_pcicfg_devfn, ! 2405: PCI_COM_R, ! 2406: ( int ) i ); ! 2407: // step 2: disable & mask interrupts & enable pci byte/word swapping & enable indirect addressing mode ! 2408: i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 2409: ! 2410: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2411: 4, ! 2412: bcm_pcicfg_bus, ! 2413: bcm_pcicfg_devfn, ! 2414: PCI_MISC_HCTRL_R, ! 2415: ( int ) i ); ! 2416: ! 2417: /* ! 2418: * from now on access may be made through the local ! 2419: * read/write functions ! 2420: */ ! 2421: ! 2422: // step 3: Save ahche line size register ! 2423: // omitted, because register is not used for 5704 ! 2424: ! 2425: // step 4: acquire the nvram lock ! 2426: if( bcm_nvram_lock() != 0 ) { ! 2427: #ifdef BCM_DEBUG ! 2428: printk( "bcm57xx: locking NVRAM failed\n" ); ! 2429: #endif ! 2430: return -1; ! 2431: } ! 2432: ! 2433: // step 5: prepare the chip for writing TG3_MAGIC_NUMBER ! 2434: bcm_setb_reg32( MEMARB_MODE_R, BIT32( 1 ) ); ! 2435: i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 2436: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2437: 4, ! 2438: bcm_pcicfg_bus, ! 2439: bcm_pcicfg_devfn, ! 2440: PCI_MISC_HCTRL_R, ! 2441: ( int ) i ); ! 2442: bcm_write_reg32( MODE_CTRL_R, BIT32( 23 ) | BIT32( 20 ) | ! 2443: BIT32( 17 ) | BIT32( 16 ) | ! 2444: BIT32( 14 ) | BIT32( 13 ) | ! 2445: BIT32( 5 ) | BIT32( 4 ) | ! 2446: BIT32( 2 ) | BIT32( 1 ) ); ! 2447: ! 2448: // step 6: write TG3_MAGIC_NUMBER ! 2449: bcm_write_mem32( BCM_FW_MBX, BCM_MAGIC_NUMBER ); ! 2450: ! 2451: // step 7: reset core clocks ! 2452: ! 2453: if( IS_5714 ) { ! 2454: bcm_setb_reg32( MISC_CFG_R, BIT32( 26 ) | BIT32( 0 ) ); ! 2455: } else { ! 2456: bcm_setb_reg32( MISC_CFG_R, BIT32( 0 ) ); ! 2457: } ! 2458: // step 8 ! 2459: ms_delay( 20 ); ! 2460: ! 2461: // step 9: disable & mask interrupts & enable indirect addressing mode & ! 2462: // enable pci byte/word swapping initialize the misc host control register ! 2463: i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 2464: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2465: 4, ! 2466: bcm_pcicfg_bus, ! 2467: bcm_pcicfg_devfn, ! 2468: PCI_MISC_HCTRL_R, ! 2469: ( int ) i ); ! 2470: ! 2471: // step 10: set but master et cetera ! 2472: i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 2473: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2474: 2, ! 2475: bcm_pcicfg_bus, ! 2476: bcm_pcicfg_devfn, ! 2477: PCI_COM_R, ! 2478: ( int ) i ); ! 2479: ! 2480: // step 11: disable PCI-X relaxed ordering ! 2481: bcm_clrb_reg16( PCI_X_COM_R, BIT16( 1 ) ); ! 2482: ! 2483: // step 12: enable the MAC memory arbiter ! 2484: bcm_setb_reg32( MEMARB_MODE_R, BIT32( 1 ) ); ! 2485: ! 2486: // step 13: omitted, only for BCM5700 ! 2487: // step 14: s. step 10 ! 2488: i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 2489: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2490: 4, ! 2491: bcm_pcicfg_bus, ! 2492: bcm_pcicfg_devfn, ! 2493: PCI_MISC_HCTRL_R, ! 2494: ( int ) i ); ! 2495: // step 15: set byte swapping (incl. step 27/28/29/30) ! 2496: // included prohibition of tx/rx interrupts ! 2497: bcm_write_reg32( MODE_CTRL_R, BIT32( 23 ) | BIT32( 20 ) | ! 2498: BIT32( 17 ) | BIT32( 16 ) | ! 2499: BIT32( 14 ) | BIT32( 13 ) | ! 2500: BIT32( 5 ) | BIT32( 4 ) | ! 2501: BIT32( 2 ) | BIT32( 1 ) ); ! 2502: // step 16: omitted ! 2503: i = 1000; ! 2504: while( ( --i ) && ! 2505: ( bcm_read_mem32( BCM_FW_MBX ) != ~BCM_MAGIC_NUMBER ) ) { ! 2506: #ifdef BCM_DEBUG ! 2507: printk( "." ); ! 2508: #endif ! 2509: ms_delay( 1 ); ! 2510: } ! 2511: ! 2512: // return on error ! 2513: if( bcm_read_mem32( BCM_FW_MBX ) != ~BCM_MAGIC_NUMBER ) { ! 2514: printk( "bootcode not loaded: %x\n", bcm_read_mem32( BCM_FW_MBX ) ); ! 2515: #ifdef BCM_DEBUG ! 2516: printk( "failed\n" ); ! 2517: #endif ! 2518: return -1; ! 2519: } ! 2520: ! 2521: ! 2522: // if ASF Firmware enabled ! 2523: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_START ); ! 2524: ms_delay( 10 ); ! 2525: ! 2526: // step 17: write ethernet mac mode register ! 2527: /* ! 2528: * WY 07.02.07 ! 2529: * omitted for correct SOL function ! 2530: */ ! 2531: /* ! 2532: if( IS_SERDES ) { ! 2533: bcm_write_reg32( ETH_MAC_MODE_R, (u32_t) 0xc ); ! 2534: } else { ! 2535: bcm_write_reg32( ETH_MAC_MODE_R, (u32_t) 0x0 ); ! 2536: } ! 2537: */ ! 2538: ! 2539: // step 18/19: omitted ! 2540: // step 20: enable hw bugfix for 5704 ! 2541: if( IS_5704 || IS_5703 ) { ! 2542: bcm_setb_reg32( MSG_DATA_R, BIT32( 26 ) | ! 2543: BIT32( 28 ) | ! 2544: BIT32( 29 ) ); ! 2545: } ! 2546: ! 2547: // step 21: omitted ! 2548: // step 22: omitted ! 2549: // step 23: 5704 clear statistics block ! 2550: if( IS_5703 || IS_5704 ) { ! 2551: memset_ci( (void *) ( bcm_memaddr_u64 + BCM_STATISTIC_OFFS ), ! 2552: 0, ! 2553: BCM_STATISTIC_SIZE ); ! 2554: } ! 2555: ! 2556: // step 24/25: omitted ! 2557: // step 26: set DMA Read/Write Control register ! 2558: // NOTE: recommended values from the spec are used here ! 2559: if( IS_5714 ) { ! 2560: bcm_write_reg32( DMA_RW_CTRL_R, DMA_RW_CTRL_VAL_5714 ); ! 2561: } else { ! 2562: u32_t l_PCIState_u32 = bcm_read_reg32( PCI_STATE_R ); ! 2563: u32_t l_DMAVal_u32 = DMA_RW_CTRL_VAL; ! 2564: ! 2565: if( ( l_PCIState_u32 & BIT32( 2 ) ) != 0 ) { // PCI ! 2566: l_DMAVal_u32 |= (u32_t) 0x300000; ! 2567: } else { // PCI-X ! 2568: l_DMAVal_u32 |= (u32_t) 0x900000; ! 2569: ! 2570: if( ( bcm_read_reg32( PCI_CLK_CTRL_R ) & (u32_t) 0x1f ) ! 2571: >= (u32_t) 6 ) { ! 2572: l_DMAVal_u32 |= (u32_t) 0x4000; ! 2573: } ! 2574: ! 2575: } ! 2576: ! 2577: bcm_write_reg32( DMA_RW_CTRL_R, l_DMAVal_u32 ); ! 2578: } ! 2579: ! 2580: // step 27/28/29: s. step 14 ! 2581: ! 2582: // step 30: Configure TCP/UDP pseudo header checksum offloading ! 2583: // already done in step 14: offloading disabled ! 2584: ! 2585: // step 31: setup timer prescaler ! 2586: i = bcm_read_reg32( MISC_CFG_R ); ! 2587: i &= (u32_t) ~0xfe; // clear bits 7-1 first ! 2588: i |= ( BCM_TMR_PRESCALE << 1 ); ! 2589: bcm_write_reg32( MISC_CFG_R, i ); ! 2590: ! 2591: // step 32: 5703/4 configure Mbuf pool address/length ! 2592: // step 33: 5703/4 configure MAC DMA resource pool ! 2593: // step 34: configure MAC memory pool watermarks ! 2594: // step 35: 5703/4 configure DMA resource watermarks ! 2595: // using recommended settings (hard coded) ! 2596: if( IS_5703 || IS_5704 ) { ! 2597: ! 2598: if( IS_5703 ) { ! 2599: bcm_write_reg32( MBUF_POOL_ADDR_R, (u32_t) 0x8000 ); ! 2600: bcm_write_reg32( MBUF_POOL_LEN_R, (u32_t) 0x18000 ); ! 2601: } else { ! 2602: bcm_write_reg32( MBUF_POOL_ADDR_R, (u32_t) 0x10000 ); ! 2603: bcm_write_reg32( MBUF_POOL_LEN_R, (u32_t) 0x10000 ); ! 2604: } ! 2605: ! 2606: bcm_write_reg32( DMA_DESC_POOL_ADDR_R, (u32_t) 0x2000 ); ! 2607: bcm_write_reg32( DMA_DESC_POOL_LEN_R, (u32_t) 0x2000 ); ! 2608: ! 2609: bcm_write_reg32( DMA_RMBUF_LOW_WMARK_R, (u32_t) 0x50 ); ! 2610: bcm_write_reg32( MAC_RXMBUF_LOW_WMARK_R, (u32_t) 0x20 ); ! 2611: bcm_write_reg32( MBUF_HIGH_WMARK_R, (u32_t) 0x60 ); ! 2612: ! 2613: bcm_write_reg32( DMA_DESC_LOW_WM_R, (u32_t) 5 ); ! 2614: bcm_write_reg32( DMA_DESC_HIGH_WM_R, (u32_t) 10 ); ! 2615: } else { ! 2616: bcm_write_reg32( DMA_RMBUF_LOW_WMARK_R, (u32_t) 0x00 ); ! 2617: bcm_write_reg32( MAC_RXMBUF_LOW_WMARK_R, (u32_t) 0x10 ); ! 2618: bcm_write_reg32( MBUF_HIGH_WMARK_R, (u32_t) 0x60 ); ! 2619: } ! 2620: ! 2621: // step 35: omitted ! 2622: // step 36: Configure flow control behaviour ! 2623: // using recommended settings (hard coded) ! 2624: bcm_write_reg32( LOW_WMARK_MAX_RXFRAM_R, (u32_t) 0x02 ); ! 2625: ! 2626: // step 37/38: enable buffer manager & wait for successful start ! 2627: bcm_setb_reg32( BUF_MAN_MODE_R, BIT32( 2 ) | BIT32( 1 ) ); ! 2628: ! 2629: i = lc_Maxwait_u32; ! 2630: while( ( --i ) && ! 2631: ( ( bcm_read_reg32( BUF_MAN_MODE_R ) & BIT32( 1 ) ) == 0 ) ) { ! 2632: us_delay( 10 ); ! 2633: } ! 2634: ! 2635: // return on error ! 2636: if( i == 0 ) { ! 2637: #ifdef BCM_DEBUG ! 2638: printk( "bcm57xx: init step 38: enable buffer manager failed\n" ); ! 2639: #endif ! 2640: return -1; ! 2641: } ! 2642: ! 2643: // step 39: enable internal hardware queues ! 2644: bcm_write_reg32( FTQ_RES_R, (u32_t) ~0 ); ! 2645: bcm_write_reg32( FTQ_RES_R, (u32_t) 0 ); ! 2646: ! 2647: // step 40/41/42: initialize rx producer ring ! 2648: bcm_init_rxprod_ring(); ! 2649: ! 2650: // step 43: set rx producer ring replenish threshhold ! 2651: // using recommended setting of maximum allocated BD's/8 ! 2652: bcm_write_reg32( STD_RXPR_REP_THR_R, (u32_t) BCM_MAX_RX_BUF / 8 ); ! 2653: ! 2654: // step 44/45/46: initialize send rings ! 2655: bcm_init_tx_ring(); ! 2656: bcm_init_rxret_ring(); ! 2657: ! 2658: // steps 47-50 done in ring init functions ! 2659: // step 51: configure MAC unicast address ! 2660: bcm_nvram_init(); ! 2661: if( bcm_mac_init( (u08_t *) mac_addr ) < 0 ) { ! 2662: #ifdef BCM_DEBUG ! 2663: printk( "bcm57xx: init step 51: configure MAC unicast address failed\n" ); ! 2664: #endif ! 2665: return -1; ! 2666: } ! 2667: ! 2668: // step 52: configure backoff random seed for transmit ! 2669: // using recommended algorithm ! 2670: i = (u32_t) mac_addr[0] + (u32_t) mac_addr[1] + ! 2671: (u32_t) mac_addr[2] + (u32_t) mac_addr[3] + ! 2672: (u32_t) mac_addr[4] + (u32_t) mac_addr[5]; ! 2673: i &= (u32_t) 0x03ff; ! 2674: bcm_write_reg32( ETH_TX_RND_BO_R, i ); ! 2675: ! 2676: // step 53: configure message transfer unit MTU size ! 2677: bcm_write_reg32( RX_MTU_SIZE_R, (u32_t) BCM_MTU_MAX_LEN ); ! 2678: ! 2679: // step 54: configure IPG for transmit ! 2680: // using recommended value (through #define) ! 2681: bcm_write_reg32( TX_MAC_LEN_R, TX_MAC_LEN_VAL ); ! 2682: ! 2683: // step 55: configure receive rules ! 2684: ! 2685: // set RX rule default class ! 2686: bcm_write_reg32( RX_RULE_CFG_R, RX_RULE_CFG_VAL ); ! 2687: ! 2688: // step 56: configure the number of receive lists ! 2689: bcm_write_reg32( RX_LST_PLACE_CFG_R, RX_LST_PLC_CFG_VAL ); ! 2690: bcm_write_reg32( RX_LST_PLACE_STAT_EN_R, RX_LST_PLC_STAT_EN_VAL ); ! 2691: ! 2692: /* ! 2693: // rule 1: accept frames for our MAC address ! 2694: bcm_write_reg32( RX_RULE_CTRL_R ( 0 ), ! 2695: BIT32( 31 ) | // enable rule ! 2696: BIT32( 30 ) | // and with next ! 2697: BIT32( 26 ) | // split value register ! 2698: BIT32( 8 ) ); // class 1 ! 2699: bcm_write_reg32( RX_RULE_VAL_R ( 0 ), ! 2700: (u32_t) 0xffff0000 | ! 2701: ( bcm_read_reg32( MAC_ADDR_OFFS_HI(0) ) & ! 2702: (u32_t) 0xffff ) ); ! 2703: ! 2704: bcm_write_reg32( RX_RULE_CTRL_R ( 1 ), ! 2705: BIT32( 31 ) | // enable rule ! 2706: BIT32( 8 ) | // class 1 ! 2707: BIT32( 1 ) ); // offset 2 ! 2708: bcm_write_reg32( RX_RULE_VAL_R ( 1 ), ! 2709: bcm_read_reg32( MAC_ADDR_OFFS_LO(0) ) ); ! 2710: ! 2711: // rule 2: accept broadcast frames ! 2712: bcm_write_reg32( RX_RULE_CTRL_R ( 2 ), ! 2713: BIT32( 31 ) | // enable rule ! 2714: BIT32( 30 ) | // and with next ! 2715: BIT32( 26 ) | // split value register ! 2716: BIT32( 8 ) ); // class 1 ! 2717: bcm_write_reg32( RX_RULE_VAL_R ( 2 ), ! 2718: (u32_t) ~0 ); ! 2719: ! 2720: bcm_write_reg32( RX_RULE_CTRL_R ( 3 ), ! 2721: BIT32( 31 ) | // enable rule ! 2722: BIT32( 8 ) | // class 1 ! 2723: BIT32( 1 ) ); // offset 2 ! 2724: bcm_write_reg32( RX_RULE_VAL_R ( 3 ), ! 2725: (u32_t) ~0 ); ! 2726: */ ! 2727: for( i=0; i<NUM_RX_RULE_ASF; ++i) { ! 2728: bcm_write_reg32( RX_RULE_CTRL_R ( i ), 0 ); ! 2729: bcm_write_reg32( RX_RULE_VAL_R ( i ), 0 ); ! 2730: } ! 2731: ! 2732: // step 57-60: enable rx/tx statistics ! 2733: // omitted, no need for statistics (so far) ! 2734: ! 2735: // step 61/62: disable host coalescing engine/wait 20ms ! 2736: bcm_write_reg32( HOST_COAL_MODE_R, (u32_t) 0 ); ! 2737: ! 2738: i = lc_Maxwait_u32 * 2; ! 2739: while( ( --i ) && ! 2740: ( bcm_read_reg32( HOST_COAL_MODE_R ) != 0 ) ) { ! 2741: us_delay( 10 ); ! 2742: } ! 2743: ! 2744: // return on error ! 2745: if( i == 0 ) { ! 2746: #ifdef BCM_DEBUG ! 2747: printk( "bcm57xx: init step 62: disable host coal. engine failed\n" ); ! 2748: #endif ! 2749: return -1; ! 2750: } ! 2751: ! 2752: // step 63-66: initialize coalescing engine ! 2753: // NOTE: status block is unused in this driver, ! 2754: // therefore the coal. engine status block ! 2755: // automatic update is disabled (by writing ! 2756: // 0 to every counter ! 2757: bcm_write_reg32( RX_COAL_TICKS_R, 0 ); ! 2758: bcm_write_reg32( TX_COAL_TICKS_R, 0 ); ! 2759: bcm_write_reg32( RX_COAL_MAX_BD_R, 0 ); ! 2760: bcm_write_reg32( TX_COAL_MAX_BD_R, 0 ); ! 2761: bcm_write_reg32( RX_COAL_TICKS_INT_R, 0 ); ! 2762: bcm_write_reg32( TX_COAL_TICKS_INT_R, 0 ); ! 2763: bcm_write_reg32( RX_COAL_MAX_BD_INT_R, 0 ); ! 2764: bcm_write_reg32( TX_COAL_MAX_BD_INT_R, 0 ); ! 2765: ! 2766: // step 67: initialize host status block address ! 2767: // NOTE: status block is not needed in this driver, ! 2768: // still it needs to be set up ! 2769: i = (u32_t) ( (u64_t) &bcm_status >> 32 ); ! 2770: bcm_write_reg32( STB_HOST_ADDR_HI_R, i ); ! 2771: i = (u32_t) ( (u64_t) &bcm_status & (u64_t) 0xffffffff ); ! 2772: bcm_write_reg32( STB_HOST_ADDR_LO_R, i ); ! 2773: ! 2774: // 5704/3 adaption ! 2775: if( IS_5703 || IS_5704 ) { ! 2776: // step 68: 5704, for now omitted ! 2777: // step 69: 5704 set the statistics coalescing tick counter ! 2778: bcm_write_reg32( STAT_TICK_CNT_R, 0 ); ! 2779: // step 70: 5704 configure statistics block address in NIC memory ! 2780: // using recommended values (hard coded) ! 2781: bcm_write_reg32( STAT_NIC_ADDR_R, (u32_t) 0x300 ); ! 2782: // step 71: 5704 configure status block address in NIC memory ! 2783: // using recommended values (hard coded) ! 2784: bcm_write_reg32( STB_NIC_ADDR_R, (u32_t) 0xb00 ); ! 2785: } ! 2786: ! 2787: // step 72: enable host coalescing engine ! 2788: bcm_setb_reg32( HOST_COAL_MODE_R, BIT32( 12 ) | BIT32( 11 ) | BIT32( 1 ) ); ! 2789: ! 2790: // step 73: enable rx bd completion functional block ! 2791: bcm_write_reg32( RX_BD_COMPL_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2792: ! 2793: // step 74: enable rx list placement functional block ! 2794: bcm_write_reg32( RX_LST_PLACE_MODE_R, BIT32( 1 ) ); ! 2795: // 5704/3 adaption ! 2796: if( IS_5703 || IS_5704 ) { ! 2797: // step 75: 5704/3 enable receive list selector func block ! 2798: bcm_write_reg32( RX_LST_SEL_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2799: } ! 2800: ! 2801: // step 76: enable DMA engines ! 2802: bcm_setb_reg32( ETH_MAC_MODE_R, BIT32( 23 ) | BIT32( 22 ) | BIT32( 21 ) ); ! 2803: /* ! 2804: * WY 26.10.07 This is wrong for 5714, better leave it alone ! 2805: if( IS_5714 ) { ! 2806: bcm_setb_reg32( ETH_MAC_MODE_R, BIT32( 20 ) ); ! 2807: } ! 2808: */ ! 2809: ! 2810: // step 77: omitted, statistics are not used ! 2811: // step 78: Configure the General Misc Local Control register ! 2812: // NOTE: as known so far nothing needs to be done here, ! 2813: // default values should work fine ! 2814: //bcm_setb_reg32( MISC_LOCAL_CTRL_R, 0 ); ! 2815: ! 2816: // step 79: clear interrupts in INT_MBX0_R low word ! 2817: bcm_write_reg32( INT_MBX0_R, 0 ); ! 2818: // 5704/3 adaption ! 2819: // step 80: 5704/3 enable DMA completion functional block ! 2820: if( IS_5703 || IS_5704 ) { ! 2821: bcm_write_reg32( DMA_COMPL_MODE_R, BIT32( 1 ) ); ! 2822: } ! 2823: ! 2824: // step 81/82: configure write/read DMA mode registers ! 2825: // disable MSI ! 2826: bcm_write_reg32( RD_DMA_MODE_R, BIT32( 10 ) | BIT32( 9 ) | BIT32( 8 ) | ! 2827: BIT32( 7 ) | BIT32( 6 ) | BIT32( 5 ) | ! 2828: BIT32( 4 ) | BIT32( 3 ) | BIT32( 2 ) | ! 2829: BIT32( 1 ) ); ! 2830: bcm_write_reg32( WR_DMA_MODE_R, BIT32( 9 ) | BIT32( 8 ) | BIT32( 7 ) | ! 2831: BIT32( 6 ) | BIT32( 5 ) | BIT32( 4 ) | ! 2832: BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 2833: bcm_clrb_reg32( MSI_MODE_R, BIT32( 1 ) ); ! 2834: us_delay( 100 ); ! 2835: ! 2836: // step 83-91: enable all these functional blocks... ! 2837: bcm_write_reg32( RX_DAT_COMPL_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2838: ! 2839: if( IS_5703 || IS_5704 ) { ! 2840: bcm_write_reg32( MBUF_CLSTR_FREE_MODE_R, BIT32( 1 ) ); ! 2841: } ! 2842: ! 2843: bcm_write_reg32( TX_DAT_COMPL_MODE_R, BIT32( 1 ) ); ! 2844: bcm_write_reg32( TX_BD_COMPL_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2845: bcm_write_reg32( RX_BD_INIT_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2846: bcm_write_reg32( RX_DAT_BD_INIT_MODE_R, BIT32( 1 ) ); ! 2847: bcm_write_reg32( TX_DAT_INIT_MODE_R, BIT32( 1 ) | BIT32( 3 ) ); ! 2848: bcm_write_reg32( TX_BD_INIT_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2849: bcm_write_reg32( TX_BD_RING_SEL_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); ! 2850: ! 2851: // step 92: omitted ! 2852: // step 93/94: Enable Tx/Rx MAC ! 2853: bcm_setb_reg32( TX_MAC_MODE_R, BIT32( 1 ) ); ! 2854: // bcm_setb_reg32( RX_MAC_MODE_R, BIT32( 1 ) | BIT32( 2 ) ); // set BIT32( 8 ) for promiscious mode! ! 2855: bcm_setb_reg32( RX_MAC_MODE_R, BIT32( 1 ) ); // set BIT32( 8 ) for promiscious mode! ! 2856: // set BIT32( 10) for VLAN ! 2857: ! 2858: // step 95: disable auto polling: ! 2859: // bcm_phy_init takes care of this ! 2860: // step 96: omitted ! 2861: // step 97: omitted, may change though, but is not important ! 2862: // step 98: activate link & enable MAC functional block ! 2863: // NOTE autopolling is enabled so bit 0 needs not to be set ! 2864: //bcm_setb_reg32( MI_STATUS_R, BIT32( 0 ) ); ! 2865: ! 2866: // step 99: setup PHY ! 2867: // return if link is down ! 2868: if( bcm_phy_init() < 0 ) { ! 2869: #ifdef BCM_DEBUG ! 2870: printk( "bcm57xx: init step 99: PHY initialization failed\n" ); ! 2871: #endif ! 2872: return -1; ! 2873: } ! 2874: ! 2875: // step 100: setup multicast filters ! 2876: bcm_write_reg32( MAC_HASH0_R, (u32_t) 0 ); ! 2877: bcm_write_reg32( MAC_HASH1_R, (u32_t) 0 ); ! 2878: bcm_write_reg32( MAC_HASH2_R, (u32_t) 0 ); ! 2879: bcm_write_reg32( MAC_HASH3_R, (u32_t) 0 ); ! 2880: /* ! 2881: // accept all multicast frames ! 2882: bcm_write_reg32( MAC_HASH0_R, (u32_t) 0xffffffff ); ! 2883: bcm_write_reg32( MAC_HASH1_R, (u32_t) 0xffffffff ); ! 2884: bcm_write_reg32( MAC_HASH2_R, (u32_t) 0xffffffff ); ! 2885: bcm_write_reg32( MAC_HASH3_R, (u32_t) 0xffffffff ); ! 2886: */ ! 2887: // step 101: omitted, no interrupts used ! 2888: ! 2889: // make initial receive buffers available for NIC ! 2890: // this step has to be done here after RX DMA engine has started (step 94) ! 2891: bcm_write_reg32( RXPROD_PROD_IND, BCM_MAX_RX_BUF ); ! 2892: ! 2893: // if ASF Firmware enabled ! 2894: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_START_DONE ); ! 2895: ms_delay( 10 ); ! 2896: ! 2897: // enable heartbeat timer ! 2898: ! 2899: bcm_write_reg32( ASF_HEARTBEAT_TIMER_R, 0x5 ); ! 2900: ! 2901: snk_module_interface.running = 1; ! 2902: // off we go.. ! 2903: return 0; ! 2904: } ! 2905: ! 2906: static int ! 2907: bcm_reset( void ) ! 2908: { ! 2909: u32_t i; ! 2910: ! 2911: #ifdef BCM_DEBUG ! 2912: printk( "bcm57xx: resetting controller.." ); ! 2913: #endif ! 2914: ! 2915: bcm_write_mem32( BCM_FW_MBX, BCM_MAGIC_NUMBER ); ! 2916: ! 2917: if( IS_5714 ) { ! 2918: bcm_setb_reg32( MISC_CFG_R, BIT32( 26 ) | BIT32( 0 ) ); ! 2919: } else { ! 2920: bcm_setb_reg32( MISC_CFG_R, BIT32( 0 ) ); ! 2921: } ! 2922: ! 2923: ms_delay( 20 ); ! 2924: ! 2925: /* ! 2926: * after reset local read/write functions cannot be used annymore ! 2927: * until bus master & stuff is set up again ! 2928: */ ! 2929: ! 2930: i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 2931: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2932: 2, ! 2933: bcm_pcicfg_bus, ! 2934: bcm_pcicfg_devfn, ! 2935: PCI_COM_R, ! 2936: ( int ) i ); ! 2937: ! 2938: // step 9 & 13: disable & mask interrupts & enable indirect addressing mode & ! 2939: // enable pci byte/word swapping initialize the misc host control register ! 2940: i = ( BIT32( 7 ) | BIT32( 5 ) | BIT32( 4 ) | ! 2941: BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 2942: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 2943: 4, ! 2944: bcm_pcicfg_bus, ! 2945: bcm_pcicfg_devfn, ! 2946: PCI_MISC_HCTRL_R, ! 2947: ( int ) i ); ! 2948: ! 2949: // step 16: poll for bootcode completion by waiting for the one's ! 2950: // complement of the magic number previously written ! 2951: i = 1000; ! 2952: while( ( --i ) && ! 2953: ( bcm_read_mem32( BCM_FW_MBX ) != ~BCM_MAGIC_NUMBER ) ) { ! 2954: #ifdef BCM_DEBUG ! 2955: printk( "." ); ! 2956: #else ! 2957: ms_delay( 1 ); ! 2958: #endif ! 2959: } ! 2960: ! 2961: // return on error ! 2962: if( bcm_read_mem32( BCM_FW_MBX ) != ~BCM_MAGIC_NUMBER ) { ! 2963: #ifdef BCM_DEBUG ! 2964: printk( "failed\n" ); ! 2965: #endif ! 2966: return -1; ! 2967: } ! 2968: ! 2969: #ifdef BCM_DEBUG ! 2970: printk( "done\n" ); ! 2971: #endif ! 2972: return 0; ! 2973: } ! 2974: ! 2975: static int ! 2976: bcm_term( void ) ! 2977: { ! 2978: u32_t i; ! 2979: u16_t v; ! 2980: ! 2981: if(snk_module_interface.running == 0) { ! 2982: return 0; ! 2983: } ! 2984: ! 2985: #ifdef BCM_DEBUG ! 2986: printk( "bcm57xx: driver shutdown.." ); ! 2987: #endif ! 2988: ! 2989: /* ! 2990: * halt ASF firmware ! 2991: */ ! 2992: bcm_fw_halt(); ! 2993: ! 2994: /* ! 2995: * unload ASF firmware ! 2996: */ ! 2997: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_UNLOAD ); ! 2998: ! 2999: /* ! 3000: * disable RX producer rings ! 3001: */ ! 3002: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_JUM ), RCB_FLAG_RING_DISABLED ); ! 3003: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 3004: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 3005: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_JUM ), 0 ); ! 3006: ! 3007: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_STD ), RCB_FLAG_RING_DISABLED ); ! 3008: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 3009: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 3010: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_STD ), 0 ); ! 3011: ! 3012: bcm_write_reg32( BCM_RCB_LENFLAG_u16( BCM_RXPROD_RCB_MIN ), RCB_FLAG_RING_DISABLED ); ! 3013: bcm_write_reg32( BCM_RCB_HOSTADDR_HI_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 3014: bcm_write_reg32( BCM_RCB_HOSTADDR_LOW_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 3015: bcm_write_reg32( BCM_RCB_NICADDR_u16( BCM_RXPROD_RCB_MIN ), 0 ); ! 3016: ! 3017: /* ! 3018: * disable RX return rings ! 3019: */ ! 3020: v = BCM_RXRET_RCB_OFFS; ! 3021: for( i = 0; i < BCM_MAX_RXRET_RING; i++ ) { ! 3022: bcm_write_mem32( BCM_RCB_LENFLAG_u16( v ), RCB_FLAG_RING_DISABLED ); ! 3023: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( v ), 0 ); ! 3024: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( v ), 0 ); ! 3025: bcm_write_mem32( BCM_RCB_NICADDR_u16( v ), 0 ); ! 3026: ! 3027: v += BCM_RCB_SIZE_u16; ! 3028: } ! 3029: ! 3030: /* ! 3031: * disable TX rings ! 3032: */ ! 3033: v = BCM_TX_RCB_OFFS; ! 3034: for( i = 0; i < BCM_MAX_TX_RING; i++ ) { ! 3035: bcm_write_mem32( BCM_RCB_LENFLAG_u16( v ), RCB_FLAG_RING_DISABLED ); ! 3036: bcm_write_mem32( BCM_RCB_HOSTADDR_HI_u16( v ), 0 ); ! 3037: bcm_write_mem32( BCM_RCB_HOSTADDR_LOW_u16( v ), 0 ); ! 3038: bcm_write_mem32( BCM_RCB_NICADDR_u16( v ), 0 ); ! 3039: ! 3040: v += BCM_RCB_SIZE_u16; ! 3041: } ! 3042: ! 3043: /* ! 3044: * remove receive rules ! 3045: */ ! 3046: bcm_write_reg32( RX_RULE_CTRL_R ( 0 ), 0 ); ! 3047: bcm_write_reg32( RX_RULE_VAL_R ( 0 ), 0 ); ! 3048: bcm_write_reg32( RX_RULE_CTRL_R ( 1 ), 0 ); ! 3049: bcm_write_reg32( RX_RULE_VAL_R ( 1 ), 0 ); ! 3050: ! 3051: /* ! 3052: * shutdown sequence ! 3053: * BCM57xx Programmer's Guide: Section 8, "Shutdown" ! 3054: * the enable bit of every state machine of the 57xx ! 3055: * has to be reset. ! 3056: */ ! 3057: ! 3058: /* ! 3059: * receive path shutdown sequence ! 3060: */ ! 3061: bcm_clr_wait_bit32( RX_MAC_MODE_R, BIT32( 1 ) ); ! 3062: bcm_clr_wait_bit32( RX_LST_PLACE_MODE_R, BIT32( 1 ) ); ! 3063: bcm_clr_wait_bit32( RX_BD_INIT_MODE_R, BIT32( 1 ) ); ! 3064: bcm_clr_wait_bit32( RX_DAT_BD_INIT_MODE_R, BIT32( 1 ) ); ! 3065: bcm_clr_wait_bit32( RX_DAT_COMPL_MODE_R, BIT32( 1 ) ); ! 3066: bcm_clr_wait_bit32( RX_BD_COMPL_MODE_R, BIT32( 1 ) ); ! 3067: ! 3068: if( IS_5704 || IS_5703 ) { ! 3069: bcm_clr_wait_bit32( RX_LST_SEL_MODE_R, BIT32( 1 ) ); ! 3070: } ! 3071: ! 3072: /* ! 3073: * transmit path & memory shutdown sequence ! 3074: */ ! 3075: bcm_clr_wait_bit32( TX_BD_RING_SEL_MODE_R, BIT32( 1 ) ); ! 3076: bcm_clr_wait_bit32( TX_BD_INIT_MODE_R, BIT32( 1 ) ); ! 3077: bcm_clr_wait_bit32( TX_DAT_INIT_MODE_R, BIT32( 1 ) ); ! 3078: bcm_clr_wait_bit32( RD_DMA_MODE_R, BIT32( 1 ) ); ! 3079: bcm_clr_wait_bit32( TX_DAT_COMPL_MODE_R, BIT32( 1 ) ); ! 3080: ! 3081: if( IS_5704 ) { ! 3082: bcm_clr_wait_bit32( DMA_COMPL_MODE_R, BIT32( 1 ) ); ! 3083: } ! 3084: ! 3085: bcm_clr_wait_bit32( TX_BD_COMPL_MODE_R, BIT32( 1 ) ); ! 3086: bcm_clr_wait_bit32( ETH_MAC_MODE_R, BIT32( 21 ) ); ! 3087: bcm_clr_wait_bit32( TX_MAC_MODE_R, BIT32( 1 ) ); ! 3088: ! 3089: bcm_clr_wait_bit32( HOST_COAL_MODE_R, BIT32( 1 ) ); ! 3090: bcm_clr_wait_bit32( WR_DMA_MODE_R, BIT32( 1 ) ); ! 3091: ! 3092: if( IS_5704 || IS_5703 ) { ! 3093: bcm_clr_wait_bit32( MBUF_CLSTR_FREE_MODE_R, BIT32( 1 ) ); ! 3094: } ! 3095: ! 3096: bcm_write_reg32( FTQ_RES_R, (u32_t) ~0 ); ! 3097: bcm_write_reg32( FTQ_RES_R, (u32_t) 0 ); ! 3098: ! 3099: if( IS_5704 || IS_5703 ) { ! 3100: bcm_clr_wait_bit32( BUF_MAN_MODE_R, BIT32( 1 ) ); ! 3101: bcm_clr_wait_bit32( MEMARB_MODE_R, BIT32( 1 ) ); ! 3102: } ! 3103: ! 3104: #ifdef BCM_DEBUG ! 3105: printk( "done.\n" ); ! 3106: #endif ! 3107: /* ! 3108: * controller reset ! 3109: */ ! 3110: if( bcm_reset() != 0 ) { ! 3111: return -1; ! 3112: } ! 3113: ! 3114: /* ! 3115: * restart ASF firmware ! 3116: */ ! 3117: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_UNLOAD ); ! 3118: ms_delay( 10 ); ! 3119: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_UNLOAD_DONE ); ! 3120: ms_delay( 100 ); ! 3121: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_START ); ! 3122: ms_delay( 10 ); ! 3123: bcm_write_mem32( BCM_NICDRV_STATE_MBX, NIC_FWDRV_STATE_START_DONE ); ! 3124: ! 3125: /* ! 3126: * activate Wake-on-LAN ! 3127: */ ! 3128: bcm_wol_activate(); ! 3129: ! 3130: /* ! 3131: * PCI shutdown ! 3132: */ ! 3133: bcm_clrb_reg32( PCI_MISC_HCTRL_R, BIT32( 3 ) | BIT32( 2 ) ); ! 3134: ! 3135: /* ! 3136: * from now on local rw functions cannot be used anymore ! 3137: */ ! 3138: ! 3139: // bcm_clrb_reg32( PCI_COM_R, BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 3140: ! 3141: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 3142: 2, ! 3143: bcm_pcicfg_bus, ! 3144: bcm_pcicfg_devfn, ! 3145: PCI_COM_R, ! 3146: BIT32(8) | BIT32(6) ); ! 3147: ! 3148: // no more networking... ! 3149: snk_module_interface.running = 0; ! 3150: return 0; ! 3151: } ! 3152: ! 3153: static int ! 3154: bcm_getmac(u32_t addr, char mac[6]) ! 3155: { ! 3156: u32_t t1, t2; ! 3157: u64_t t3; ! 3158: ! 3159: if (bcm_nvram_read(addr, &t1, 1) != 0) ! 3160: return -1; ! 3161: if (bcm_nvram_read(addr+4, &t2, 1) != 0) ! 3162: return -1; ! 3163: t3 = ((u64_t)t1 << 32) + t2; ! 3164: ! 3165: mac[0] = (t3 >> 40) & 0xFF; ! 3166: mac[1] = (t3 >> 32) & 0xFF; ! 3167: mac[2] = (t3 >> 24) & 0xFF; ! 3168: mac[3] = (t3 >> 16) & 0xFF; ! 3169: mac[4] = (t3 >> 8) & 0xFF; ! 3170: mac[5] = (t3 >> 0) & 0xFF; ! 3171: ! 3172: return 0; ! 3173: } ! 3174: ! 3175: static char* ! 3176: print_itoa(char *text, u32_t value) ! 3177: { ! 3178: if(value >= 10) ! 3179: text = print_itoa(text, value / 10); ! 3180: *text = '0' + (value % 10); ! 3181: ++text; ! 3182: return text; ! 3183: } ! 3184: ! 3185: static int ! 3186: bcm_get_version(char *text) ! 3187: { ! 3188: u32_t t1; ! 3189: ! 3190: if (bcm_nvram_read(0x94, &t1, 1) != 0) ! 3191: return -1; ! 3192: ! 3193: text = print_itoa(text, (t1 >> 8) & 0xFF); ! 3194: text[0] = '.'; ! 3195: text = print_itoa(&text[1], t1 & 0xFF); ! 3196: text[0] = '\n'; ! 3197: return 0; ! 3198: } ! 3199: ! 3200: static u32_t ! 3201: util_gen_crc( char *pcDatabuf, u32_t ulDatalen, u32_t ulCrc_in) ! 3202: { ! 3203: unsigned char data; ! 3204: u32_t idx, bit, crc = ulCrc_in; ! 3205: ! 3206: for(idx = 0; idx < ulDatalen; idx++) { ! 3207: data = *pcDatabuf++; ! 3208: for(bit = 0; bit < 8; bit++, data >>= 1) { ! 3209: crc = (crc >> 1) ^ (((crc ^ data) & 1) ? ! 3210: CRC32_POLYNOMIAL : 0); ! 3211: } ! 3212: } ! 3213: return bswap_32(~crc); ! 3214: } ! 3215: ! 3216: static int ! 3217: bcm_setmac(char mac_addr1[6], char mac_addr2[6]) ! 3218: { ! 3219: u64_t mac1 = 0, mac2 = 0; ! 3220: u32_t manu[MANUFACTURING_INFO_SIZE/4]; ! 3221: int addr, i; ! 3222: u32_t crc, val1, val2, val3, val4; ! 3223: ! 3224: #ifdef BCM_DEBUG ! 3225: printk("Flashing MAC 1: %02X:%02X:%02X:%02X:%02X:%02X\n", ! 3226: ((unsigned int) mac_addr1[0]) & 0xFF, ! 3227: ((unsigned int) mac_addr1[1]) & 0xFF, ! 3228: ((unsigned int) mac_addr1[2]) & 0xFF, ! 3229: ((unsigned int) mac_addr1[3]) & 0xFF, ! 3230: ((unsigned int) mac_addr1[4]) & 0xFF, ! 3231: ((unsigned int) mac_addr1[5]) & 0xFF); ! 3232: ! 3233: printk("Flashing MAC 2: %02X:%02X:%02X:%02X:%02X:%02X\n", ! 3234: ((unsigned int) mac_addr2[0]) & 0xFF, ! 3235: ((unsigned int) mac_addr2[1]) & 0xFF, ! 3236: ((unsigned int) mac_addr2[2]) & 0xFF, ! 3237: ((unsigned int) mac_addr2[3]) & 0xFF, ! 3238: ((unsigned int) mac_addr2[4]) & 0xFF, ! 3239: ((unsigned int) mac_addr2[5]) & 0xFF); ! 3240: #endif ! 3241: ! 3242: mac1 |= ((u64_t) mac_addr1[0]) & 0xFF; mac1 = mac1 << 8; ! 3243: mac1 |= ((u64_t) mac_addr1[1]) & 0xFF; mac1 = mac1 << 8; ! 3244: mac1 |= ((u64_t) mac_addr1[2]) & 0xFF; mac1 = mac1 << 8; ! 3245: mac1 |= ((u64_t) mac_addr1[3]) & 0xFF; mac1 = mac1 << 8; ! 3246: mac1 |= ((u64_t) mac_addr1[4]) & 0xFF; mac1 = mac1 << 8; ! 3247: mac1 |= ((u64_t) mac_addr1[5]) & 0xFF; ! 3248: ! 3249: mac2 |= ((u64_t) mac_addr2[0]) & 0xFF; mac2 = mac2 << 8; ! 3250: mac2 |= ((u64_t) mac_addr2[1]) & 0xFF; mac2 = mac2 << 8; ! 3251: mac2 |= ((u64_t) mac_addr2[2]) & 0xFF; mac2 = mac2 << 8; ! 3252: mac2 |= ((u64_t) mac_addr2[3]) & 0xFF; mac2 = mac2 << 8; ! 3253: mac2 |= ((u64_t) mac_addr2[4]) & 0xFF; mac2 = mac2 << 8; ! 3254: mac2 |= ((u64_t) mac_addr2[5]) & 0xFF; ! 3255: ! 3256: /* Extract the manufacturing data, starts at 0x74 */ ! 3257: if(bcm_nvram_lock() == -1) { ! 3258: return -1; ! 3259: } ! 3260: ! 3261: addr = 0x74; ! 3262: for (i = 0; i < (MANUFACTURING_INFO_SIZE/4); i++) { ! 3263: if (bcm_nvram_read(addr, &manu[i], 0) != 0) { ! 3264: printk("\nREAD FAILED\n"); ! 3265: bcm_nvram_unlock(); ! 3266: return -1; ! 3267: } ! 3268: addr+=4; ! 3269: } ! 3270: bcm_nvram_unlock(); ! 3271: ! 3272: /* Store the new MAC address in the manufacturing data */ ! 3273: val1 = mac1 >> 32; ! 3274: val2 = mac1 & 0xFFFFFFFF; ! 3275: val3 = mac2 >> 32; ! 3276: val4 = mac2 & 0xFFFFFFFF; ! 3277: manu[(0x7C-0x74)/4] = val1; ! 3278: manu[(0x80-0x74)/4] = val2; ! 3279: manu[(0xCC-0x74)/4] = val3; ! 3280: manu[(0xD0-0x74)/4] = val4; ! 3281: ! 3282: /* Calculate the new manufacturing datas CRC */ ! 3283: crc = util_gen_crc(((char *)manu), ! 3284: MANUFACTURING_INFO_SIZE - 4, 0xFFFFFFFF); ! 3285: ! 3286: /* Now write the new MAC addresses and CRC */ ! 3287: if ((bcm_nvram_write(0x7C, val1, 1) != 0) || ! 3288: (bcm_nvram_write(0x80, val2, 1) != 0) || ! 3289: (bcm_nvram_write(0xCC, val3, 1) != 0) || ! 3290: (bcm_nvram_write(0xD0, val4, 1) != 0) || ! 3291: (bcm_nvram_write(0xFC, crc, 1) != 0) ) ! 3292: { ! 3293: /* Disastor ! */ ! 3294: #ifdef BCM_DEBUG ! 3295: printk("failed to write MAC address\n"); ! 3296: #endif ! 3297: return -1; ! 3298: } ! 3299: ! 3300: /* Success !!!! */ ! 3301: return 0; ! 3302: } ! 3303: ! 3304: static int ! 3305: bcm_ioctl( int request, void* data ) ! 3306: { ! 3307: u32_t l_baseaddrL_u32; ! 3308: u32_t l_baseaddrH_u32; ! 3309: u32_t i; ! 3310: int ret_val = 0; ! 3311: char mac_addr[6]; ! 3312: ioctl_net_data_t *ioctl_data = (ioctl_net_data_t*) data; ! 3313: ! 3314: if(request != SIOCETHTOOL) { ! 3315: return -1; ! 3316: } ! 3317: ! 3318: #ifdef BCM_DEBUG ! 3319: printk( "bcm57xx: detected device " ); ! 3320: if( IS_5703 ) { ! 3321: printk( "5703S" ); ! 3322: } else if( IS_5704 ) { ! 3323: printk( "5704" ); ! 3324: if( IS_SERDES ) { ! 3325: printk( "S\n" ); ! 3326: } else { ! 3327: printk( "C\n" ); ! 3328: } ! 3329: } else if( IS_5714 ) { ! 3330: printk( "5714\n" ); ! 3331: } ! 3332: #endif ! 3333: /* ! 3334: * setup register & memory base addresses of NIC ! 3335: */ ! 3336: l_baseaddrL_u32 = ( (u32_t) ~0xf & ! 3337: (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 3338: 4, ! 3339: bcm_pcicfg_bus, ! 3340: bcm_pcicfg_devfn, ! 3341: PCI_BAR1_R ) ); ! 3342: ! 3343: l_baseaddrH_u32 = ! 3344: (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, ! 3345: 4, ! 3346: bcm_pcicfg_bus, ! 3347: bcm_pcicfg_devfn, ! 3348: PCI_BAR2_R ); ! 3349: ! 3350: bcm_baseaddr_u64 = (u64_t) l_baseaddrH_u32; ! 3351: bcm_baseaddr_u64 <<= 32; ! 3352: bcm_baseaddr_u64 += (u64_t) l_baseaddrL_u32; ! 3353: snk_kernel_interface->translate_addr(((void *)&(bcm_baseaddr_u64))); ! 3354: bcm_memaddr_u64 = bcm_baseaddr_u64 + BCM_MEMORY_OFFS; ! 3355: ! 3356: /* ! 3357: * 57xx hardware initialization ! 3358: * BCM57xx Programmer's Guide: Section 8, "Initialization" ! 3359: * steps 1 through 101 ! 3360: */ ! 3361: ! 3362: // step 1: enable bus master & memory space in command reg ! 3363: i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); ! 3364: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 3365: 2, ! 3366: bcm_pcicfg_bus, ! 3367: bcm_pcicfg_devfn, ! 3368: PCI_COM_R, ! 3369: ( int ) i ); ! 3370: ! 3371: // step 2: disable & mask interrupts & enable pci byte/word swapping & enable indirect addressing mode ! 3372: i = ( BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); ! 3373: snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, ! 3374: 4, ! 3375: bcm_pcicfg_bus, ! 3376: bcm_pcicfg_devfn, ! 3377: PCI_MISC_HCTRL_R, ! 3378: ( int ) i ); ! 3379: ! 3380: bcm_nvram_init(); ! 3381: ! 3382: switch(ioctl_data->subcmd) { ! 3383: case ETHTOOL_GMAC: ! 3384: switch(ioctl_data->data.mac.idx) { ! 3385: case 0: ! 3386: ret_val = bcm_getmac(0x7C, ioctl_data->data.mac.address); ! 3387: break; ! 3388: case 1: ! 3389: ret_val = bcm_getmac(0xCC, ioctl_data->data.mac.address); ! 3390: break; ! 3391: default: ! 3392: ret_val = -1; ! 3393: break; ! 3394: } ! 3395: break; ! 3396: case ETHTOOL_SMAC: ! 3397: switch(ioctl_data->data.mac.idx) { ! 3398: case 0: ! 3399: ret_val = bcm_getmac(0xCC, mac_addr); ! 3400: if(ret_val == 0) ! 3401: ret_val = bcm_setmac(ioctl_data->data.mac.address, mac_addr); ! 3402: break; ! 3403: case 1: ! 3404: ret_val = bcm_getmac(0x7C, mac_addr); ! 3405: if(ret_val == 0) ! 3406: ret_val = bcm_setmac(mac_addr, ioctl_data->data.mac.address); ! 3407: break; ! 3408: default: ! 3409: ret_val = -1; ! 3410: break; ! 3411: } ! 3412: break; ! 3413: case ETHTOOL_VERSION: { ! 3414: char *text = ioctl_data->data.version.text; ! 3415: memcpy(text, " BCM57xx Boot code level: ", 27); ! 3416: ret_val = bcm_get_version(&text[27]); ! 3417: break; ! 3418: } ! 3419: default: ! 3420: ret_val = -1; ! 3421: break; ! 3422: } ! 3423: ! 3424: snk_module_interface.running = 1; ! 3425: bcm_term(); ! 3426: return ret_val; ! 3427: } ! 3428:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.