Annotation of qemu/roms/SLOF/other-licence/bcm/bcm57xx.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.