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