get rid of $Id$ - it has never helped us and it has broken too many patches ;)
[openwrt/openwrt.git] / package / broadcom-57xx / src / tigon3.c
1 /******************************************************************************/
2 /* */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2005 Broadcom */
4 /* Corporation. */
5 /* All rights reserved. */
6 /* */
7 /* This program is free software; you can redistribute it and/or modify */
8 /* it under the terms of the GNU General Public License as published by */
9 /* the Free Software Foundation, located in the file LICENSE. */
10 /* */
11 /* History: */
12 /******************************************************************************/
13
14
15 #include "mm.h"
16 #include "typedefs.h"
17 #include "osl.h"
18 #include "bcmdefs.h"
19 #include "bcmdevs.h"
20 #include "sbutils.h"
21 #include "bcmrobo.h"
22 #include "proto/ethernet.h"
23
24 /******************************************************************************/
25 /* Local functions. */
26 /******************************************************************************/
27
28 LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
29 LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
30
31 static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
32 static LM_VOID LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice);
33
34 LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
35 LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
36
37 static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice);
38 static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
39 STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
40 LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
41 #ifdef INCLUDE_TBI_SUPPORT
42 STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
43 STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
44 #endif
45 STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
46 STATIC LM_VOID LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice);
47 STATIC LM_STATUS LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice);
48 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
49 LM_VOID LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2);
50 STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
51 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
52 STATIC LM_STATUS LM_DisableChip(PLM_DEVICE_BLOCK pDevice);
53 STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
54 STATIC LM_STATUS LM_DisableFW(PLM_DEVICE_BLOCK pDevice);
55 STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
56 PT3_SND_BD pSendBd);
57 STATIC LM_VOID LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice,
58 LM_RESET_TYPE Mode);
59 STATIC LM_VOID LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice,
60 LM_RESET_TYPE Mode);
61 STATIC LM_VOID LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice,
62 LM_RESET_TYPE Mode);
63 STATIC void LM_GetPhyId(LM_DEVICE_BLOCK *pDevice);
64
65 /******************************************************************************/
66 /* External functions. */
67 /******************************************************************************/
68
69 LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
70 #ifdef INCLUDE_TCP_SEG_SUPPORT
71 LM_STATUS LM_LoadStkOffLdFirmware(PLM_DEVICE_BLOCK pDevice);
72 LM_UINT32 LM_GetStkOffLdFirmwareSize(PLM_DEVICE_BLOCK pDevice);
73 #endif
74
75 LM_UINT32
76 LM_RegRd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
77 {
78 #ifdef PCIX_TARGET_WORKAROUND
79 if (pDevice->Flags & UNDI_FIX_FLAG)
80 {
81 return (LM_RegRdInd(pDevice, Register));
82 }
83 else
84 #endif
85 {
86 return (REG_RD_OFFSET(pDevice, Register));
87 }
88 }
89
90 /* Mainly used to flush posted write before delaying */
91 LM_VOID
92 LM_RegRdBack(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
93 {
94 LM_UINT32 dummy;
95
96 #ifdef PCIX_TARGET_WORKAROUND
97 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
98 {
99 return;
100 }
101 else
102 #endif
103 {
104 if (pDevice->Flags & REG_RD_BACK_FLAG)
105 return;
106
107 dummy = REG_RD_OFFSET(pDevice, Register);
108 }
109 }
110
111 LM_VOID
112 LM_RegWr(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32,
113 LM_UINT32 ReadBack)
114 {
115 #ifdef PCIX_TARGET_WORKAROUND
116 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
117 {
118 LM_RegWrInd(pDevice, Register, Value32);
119 }
120 else
121 #endif
122 {
123 LM_UINT32 dummy;
124
125 REG_WR_OFFSET(pDevice, Register, Value32);
126 if (ReadBack && (pDevice->Flags & REG_RD_BACK_FLAG))
127 {
128 dummy = REG_RD_OFFSET(pDevice, Register);
129 }
130 }
131 }
132
133 /******************************************************************************/
134 /* Description: */
135 /* */
136 /* Return: */
137 /******************************************************************************/
138 LM_UINT32
139 LM_RegRdInd(
140 PLM_DEVICE_BLOCK pDevice,
141 LM_UINT32 Register) {
142 LM_UINT32 Value32;
143
144 MM_ACQUIRE_UNDI_LOCK(pDevice);
145 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
146 MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
147 MM_RELEASE_UNDI_LOCK(pDevice);
148
149 return MM_SWAP_LE32(Value32);
150 } /* LM_RegRdInd */
151
152
153
154 /******************************************************************************/
155 /* Description: */
156 /* */
157 /* Return: */
158 /******************************************************************************/
159 LM_VOID
160 LM_RegWrInd(
161 PLM_DEVICE_BLOCK pDevice,
162 LM_UINT32 Register,
163 LM_UINT32 Value32) {
164
165 MM_ACQUIRE_UNDI_LOCK(pDevice);
166 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
167 MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, MM_SWAP_LE32(Value32));
168 MM_RELEASE_UNDI_LOCK(pDevice);
169 } /* LM_RegWrInd */
170
171
172
173 /******************************************************************************/
174 /* Description: */
175 /* */
176 /* Return: */
177 /******************************************************************************/
178 LM_UINT32
179 LM_MemRdInd(
180 PLM_DEVICE_BLOCK pDevice,
181 LM_UINT32 MemAddr) {
182 LM_UINT32 Value32;
183
184 MM_ACQUIRE_UNDI_LOCK(pDevice);
185 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
186 MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
187 MM_RELEASE_UNDI_LOCK(pDevice);
188
189 return MM_SWAP_LE32(Value32);
190 } /* LM_MemRdInd */
191
192
193
194 /******************************************************************************/
195 /* Description: */
196 /* */
197 /* Return: */
198 /******************************************************************************/
199 LM_VOID
200 LM_MemWrInd(
201 PLM_DEVICE_BLOCK pDevice,
202 LM_UINT32 MemAddr,
203 LM_UINT32 Value32) {
204 MM_ACQUIRE_UNDI_LOCK(pDevice);
205 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
206 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, MM_SWAP_LE32(Value32));
207 MM_RELEASE_UNDI_LOCK(pDevice);
208 } /* LM_MemWrInd */
209
210
211 /******************************************************************************/
212 /* Description: */
213 /* */
214 /* Return: */
215 /******************************************************************************/
216 LM_STATUS
217 LM_QueueRxPackets(
218 PLM_DEVICE_BLOCK pDevice) {
219 LM_STATUS Lmstatus;
220 PLM_PACKET pPacket;
221 PT3_RCV_BD pRcvBd = 0;
222 LM_UINT32 StdBdAdded = 0;
223 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
224 LM_UINT32 JumboBdAdded = 0;
225 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
226 LM_UINT32 ConIdx, Idx;
227 LM_UINT32 Diff = 0;
228
229 Lmstatus = LM_STATUS_SUCCESS;
230
231 if (pDevice->Flags & RX_BD_LIMIT_64_FLAG)
232 {
233 ConIdx = pDevice->pStatusBlkVirt->RcvStdConIdx;
234 Diff = (pDevice->RxStdProdIdx - ConIdx) &
235 T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
236 if (Diff >= 56)
237 {
238 if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
239 {
240 pDevice->QueueAgain = TRUE;
241 }
242 return LM_STATUS_SUCCESS;
243 }
244 }
245
246 pDevice->QueueAgain = FALSE;
247
248 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
249 while(pPacket) {
250 switch(pPacket->u.Rx.RcvProdRing) {
251 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
252 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
253 /* Initialize the buffer descriptor. */
254 Idx = pDevice->RxJumboProdIdx;
255 pRcvBd = &pDevice->pRxJumboBdVirt[Idx];
256
257 pPacket->u.Rx.RcvRingProdIdx = Idx;
258 pDevice->RxJumboRing[Idx] = pPacket;
259 /* Update the producer index. */
260 pDevice->RxJumboProdIdx = (Idx + 1) &
261 T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
262
263 JumboBdAdded++;
264 break;
265 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
266
267 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
268 /* Initialize the buffer descriptor. */
269 Idx = pDevice->RxStdProdIdx;
270 pRcvBd = &pDevice->pRxStdBdVirt[Idx];
271
272 pPacket->u.Rx.RcvRingProdIdx = Idx;
273 pDevice->RxStdRing[Idx] = pPacket;
274 /* Update the producer index. */
275 pDevice->RxStdProdIdx = (Idx + 1) &
276 T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
277
278 StdBdAdded++;
279 break;
280
281 case T3_UNKNOWN_RCV_PROD_RING:
282 default:
283 Lmstatus = LM_STATUS_FAILURE;
284 break;
285 } /* switch */
286
287 /* Bail out if there is any error. */
288 if(Lmstatus != LM_STATUS_SUCCESS)
289 {
290 break;
291 }
292
293 /* Initialize the receive buffer pointer */
294 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
295
296 /* The opaque field may point to an offset from a fix addr. */
297 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
298 MM_UINT_PTR(pDevice->pPacketDescBase));
299
300 if ((pDevice->Flags & RX_BD_LIMIT_64_FLAG) &&
301 ((Diff + StdBdAdded) >= 63))
302 {
303 if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
304 {
305 pDevice->QueueAgain = TRUE;
306 }
307 break;
308 }
309 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
310 } /* while */
311
312 MM_WMB();
313 /* Update the procedure index. */
314 if(StdBdAdded)
315 {
316 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low,
317 pDevice->RxStdProdIdx);
318 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
319 {
320 MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
321 }
322 }
323 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
324 if(JumboBdAdded)
325 {
326 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
327 pDevice->RxJumboProdIdx);
328 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
329 {
330 MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
331 }
332 }
333 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
334
335 return Lmstatus;
336 } /* LM_QueueRxPackets */
337
338
339
340
341 #define EEPROM_CMD_TIMEOUT 100000
342 #define NVRAM_CMD_TIMEOUT 100000
343
344
345 /******************************************************************************/
346 /* Description: */
347 /* */
348 /* Return: */
349 /******************************************************************************/
350 STATIC LM_STATUS LM_NVRAM_AcquireLock( PLM_DEVICE_BLOCK pDevice )
351 {
352 LM_UINT i;
353 LM_UINT32 value32;
354 LM_STATUS status;
355
356 status = LM_STATUS_SUCCESS;
357
358 /* BCM4785: Avoid all access to NVRAM & EEPROM. */
359 if (pDevice->Flags & SB_CORE_FLAG)
360 return status;
361
362 /* Request access to the flash interface. */
363 REG_WR( pDevice, Nvram.SwArb, SW_ARB_REQ_SET1 );
364
365 /*
366 * The worst case wait time for Nvram arbitration
367 * using serial eprom is about 45 msec on a 5704
368 * with the other channel loading boot code.
369 */
370 for( i = 0; i < NVRAM_CMD_TIMEOUT; i++ )
371 {
372 value32 = REG_RD( pDevice, Nvram.SwArb );
373 if( value32 & SW_ARB_GNT1 )
374 {
375 break;
376 }
377 MM_Wait(20);
378 }
379
380
381 return status;
382 } /* LM_NVRAM_AcquireLock */
383
384
385
386 /******************************************************************************/
387 /* Description: */
388 /* */
389 /* Return: */
390 /******************************************************************************/
391 STATIC LM_STATUS LM_NVRAM_ReleaseLock( PLM_DEVICE_BLOCK pDevice )
392 {
393 /* BCM4785: Avoid all access to NVRAM & EEPROM. */
394 if (pDevice->Flags & SB_CORE_FLAG)
395 return LM_STATUS_SUCCESS;
396
397 /* Relinquish nvram interface. */
398 REG_WR( pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1 );
399 REG_RD_BACK( pDevice, Nvram.SwArb );
400
401 return LM_STATUS_SUCCESS;
402 } /* LM_NVRAM_ReleaseLock */
403
404
405
406 /******************************************************************************/
407 /* Description: */
408 /* */
409 /* Return: */
410 /******************************************************************************/
411 STATIC LM_STATUS
412 LM_EEPROM_ExecuteCommand( PLM_DEVICE_BLOCK pDevice, LM_UINT32 cmd )
413 {
414 LM_UINT32 i;
415 LM_UINT32 value32;
416 LM_STATUS status;
417
418 status = LM_STATUS_SUCCESS;
419
420 REG_WR( pDevice, Grc.EepromAddr, cmd );
421
422 for( i = 0; i < EEPROM_CMD_TIMEOUT; i++ )
423 {
424 value32 = REG_RD( pDevice, Grc.EepromAddr );
425 if( value32 & SEEPROM_ADDR_COMPLETE )
426 {
427 break;
428 }
429 MM_Wait(20);
430 }
431
432 if( i == EEPROM_CMD_TIMEOUT )
433 {
434 B57_ERR(("EEPROM command (0x%x) timed out!\n", cmd));
435 status = LM_STATUS_FAILURE;
436 }
437
438 return status;
439 } /* LM_EEPROM_ExecuteCommand */
440
441
442
443 /******************************************************************************/
444 /* Description: */
445 /* */
446 /* Return: */
447 /******************************************************************************/
448 STATIC LM_STATUS
449 LM_NVRAM_ExecuteCommand( PLM_DEVICE_BLOCK pDevice, LM_UINT32 cmd )
450 {
451 LM_UINT32 i;
452 LM_UINT32 value32;
453 LM_STATUS status;
454
455 status = LM_STATUS_SUCCESS;
456
457 REG_WR( pDevice, Nvram.Cmd, cmd );
458 REG_RD_BACK( pDevice, Nvram.Cmd );
459 MM_Wait(10);
460
461 /* Wait for the command to complete. */
462 for( i = 0; i < NVRAM_CMD_TIMEOUT; i++ )
463 {
464 value32 = REG_RD( pDevice, Nvram.Cmd );
465 if( value32 & NVRAM_CMD_DONE )
466 {
467 break;
468 }
469 MM_Wait(1);
470 }
471
472 if( i == NVRAM_CMD_TIMEOUT )
473 {
474 B57_ERR(("NVRAM command (0x%x) timed out!\n", cmd));
475 status = LM_STATUS_FAILURE;
476 }
477
478 return status;
479 } /* LM_NVRAM_ExecuteCommand */
480
481
482
483 /******************************************************************************/
484 /* Description: */
485 /* */
486 /* Return: */
487 /******************************************************************************/
488 STATIC LM_STATUS
489 LM_EEPROM_Read_UINT32( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
490 LM_UINT32 * data )
491 {
492 LM_UINT32 value32;
493 LM_UINT32 Addr;
494 LM_UINT32 Dev;
495 LM_STATUS status;
496
497 Dev = offset / pDevice->flashinfo.chipsize;
498 Addr = offset % pDevice->flashinfo.chipsize;
499
500 value32 = REG_RD( pDevice, Grc.EepromAddr );
501 value32 &= ~(SEEPROM_ADDR_DEV_ID_MASK | SEEPROM_ADDR_ADDRESS_MASK |
502 SEEPROM_ADDR_RW_MASK);
503 value32 |= SEEPROM_ADDR_DEV_ID(Dev) | SEEPROM_ADDR_ADDRESS(Addr) |
504 SEEPROM_ADDR_START | SEEPROM_ADDR_READ;
505
506 status = LM_EEPROM_ExecuteCommand( pDevice, value32 );
507 if( status == LM_STATUS_SUCCESS )
508 {
509 value32 = REG_RD( pDevice, Grc.EepromData );
510
511 /* The endianess of the eeprom and flash interface is different */
512 *data = MM_SWAP_LE32( value32 );
513 }
514
515 return status;
516 } /* LM_EEPROM_Read_UINT32 */
517
518
519
520 /******************************************************************************/
521 /* Description: */
522 /* */
523 /* Return: */
524 /******************************************************************************/
525 STATIC LM_STATUS
526 LM_NVRAM_Read_UINT32( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
527 LM_UINT32 * data )
528 {
529 LM_UINT32 physaddr;
530 LM_UINT32 ctrlreg;
531 LM_UINT32 value32;
532 LM_STATUS status;
533
534 if( pDevice->flashinfo.jedecnum == JEDEC_ATMEL &&
535 pDevice->flashinfo.buffered == TRUE )
536 {
537 /*
538 * One supported flash part has 9 address bits to address a
539 * particular page and another 9 address bits to address a
540 * particular byte within that page.
541 */
542 LM_UINT32 pagenmbr;
543
544 pagenmbr = offset / pDevice->flashinfo.pagesize;
545 pagenmbr = pagenmbr << ATMEL_AT45DB0X1B_PAGE_POS;
546
547 physaddr = pagenmbr + (offset % pDevice->flashinfo.pagesize);
548 }
549 else
550 {
551 physaddr = offset;
552 }
553
554 REG_WR( pDevice, Nvram.Addr, physaddr );
555
556 ctrlreg = NVRAM_CMD_DONE | NVRAM_CMD_DO_IT |
557 NVRAM_CMD_LAST | NVRAM_CMD_FIRST | NVRAM_CMD_RD;
558
559 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
560 if( status == LM_STATUS_SUCCESS )
561 {
562 value32 = REG_RD( pDevice, Nvram.ReadData );
563
564 /*
565 * Data is swapped so that the byte stream is the same
566 * in big and little endian systems. Caller will do
567 * additional swapping depending on how it wants to
568 * look at the data.
569 */
570 *data = MM_SWAP_BE32( value32 );
571 }
572
573 return status;
574 } /* LM_NVRAM_Read_UINT32 */
575
576
577 /******************************************************************************/
578 /* Description: */
579 /* */
580 /* Return: */
581 /******************************************************************************/
582 STATIC LM_VOID
583 LM_EEPROM_ReadSize( PLM_DEVICE_BLOCK pDevice, LM_UINT32 * size )
584 {
585 LM_UINT32 cursize;
586 LM_UINT32 value32;
587 LM_STATUS status;
588
589 /*
590 * Initialize the chipsize to the largest EEPROM size we support.
591 * This will intentionally restrict our sizing operations to the
592 * first EEPROM chip.
593 */
594 pDevice->flashinfo.chipsize = ATMEL_AT24C512_CHIP_SIZE;
595
596 value32 = 0;
597
598 /* If anything fails, use the smallest chip as the default chip size. */
599 cursize = ATMEL_AT24C64_CHIP_SIZE;
600
601 status = LM_NvramRead(pDevice, 0, &value32);
602 if( status != LM_STATUS_SUCCESS )
603 {
604 goto done;
605 }
606
607 value32 = MM_SWAP_BE32(value32);
608 if( value32 != 0x669955aa )
609 {
610 goto done;
611 }
612
613 /*
614 * Size the chip by reading offsets at increasing powers of two.
615 * When we encounter our validation signature, we know the addressing
616 * has wrapped around, and thus have our chip size.
617 */
618 while( cursize < ATMEL_AT24C64_CHIP_SIZE )
619 {
620 status = LM_NvramRead(pDevice, cursize, &value32);
621 if( status != LM_STATUS_SUCCESS )
622 {
623 cursize = ATMEL_AT24C64_CHIP_SIZE;
624 break;
625 }
626
627 value32 = MM_SWAP_BE32(value32);
628 if( value32 == 0x669955aa )
629 {
630 break;
631 }
632 cursize <<= 1;
633 }
634
635 done:
636
637 *size = cursize;
638 pDevice->flashinfo.pagesize = cursize;
639
640
641 } /* LM_EEPROM_ReadSize */
642
643 /******************************************************************************/
644 /* Description: */
645 /* */
646 /* Return: */
647 /******************************************************************************/
648 STATIC LM_STATUS
649 LM_FLASH_Atmel_Buffered_ReadSize( PLM_DEVICE_BLOCK pDevice, LM_UINT32 * size )
650 {
651 LM_UINT32 config3;
652 LM_UINT32 value32;
653 LM_STATUS status;
654
655 /* Temporarily replace the read command with a "read ID" command. */
656 config3 = REG_RD( pDevice, Nvram.Config3 );
657 value32 = config3 & ~NVRAM_READ_COMMAND(NVRAM_COMMAND_MASK);
658 value32 |= NVRAM_READ_COMMAND(0x57);
659 REG_WR( pDevice, Nvram.Config3, value32 );
660
661 REG_WR( pDevice, Nvram.Addr, 0x0 );
662
663 status = LM_NVRAM_Read_UINT32(pDevice, 0x0, &value32);
664
665 /* Restore the original read command. */
666 REG_WR( pDevice, Nvram.Config3, config3 );
667 if( status == LM_STATUS_SUCCESS )
668 {
669 switch( value32 & 0x3c )
670 {
671 case 0x0c:
672 *size = (1 * (1<<20))/8;
673 break;
674 case 0x14:
675 *size = (2 * (1<<20))/8;
676 break;
677 case 0x1c:
678 *size = (4 * (1<<20))/8;
679 break;
680 case 0x24:
681 *size = (8 * (1<<20))/8;
682 break;
683 }
684 }
685
686 return status;
687 } /* LM_FLASH_Atmel_Buffered_ReadSize */
688
689
690
691 /******************************************************************************/
692 /* Description: */
693 /* */
694 /* Return: */
695 /******************************************************************************/
696 STATIC LM_STATUS
697 LM_FLASH_ST_ReadSize( PLM_DEVICE_BLOCK pDevice, LM_UINT32 * size )
698 {
699 LM_STATUS status;
700 LM_UINT32 i;
701 LM_UINT32 ctrlreg;
702 LM_UINT32 value32;
703 LM_UINT32 config1;
704
705 /* We need to get the size through pass-thru mode. */
706 config1 = REG_RD( pDevice, Nvram.Config1 );
707 value32 = config1 | FLASH_PASS_THRU_MODE;
708 REG_WR( pDevice, Nvram.Config1, value32 );
709
710 /* Issue the "read ID" command. */
711 REG_WR( pDevice, Nvram.WriteData, 0x9f );
712
713 ctrlreg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_FIRST | NVRAM_CMD_WR;
714 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
715 if( status == LM_STATUS_FAILURE )
716 {
717 goto done;
718 }
719
720 /* Read in the "read ID" response. */
721 ctrlreg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE;
722
723 /* Discard the first three bytes. */
724 for( i = 0; i < 2; i++ )
725 {
726 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
727 if( status == LM_STATUS_FAILURE )
728 {
729 goto done;
730 }
731
732 value32 = REG_RD(pDevice, Nvram.ReadData);
733 }
734
735 ctrlreg |= NVRAM_CMD_LAST;
736
737 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
738 if( status == LM_STATUS_SUCCESS )
739 {
740 value32 = REG_RD(pDevice, Nvram.ReadData) & 0xff;
741 switch( value32 )
742 {
743 case 0x11:
744 *size = (1 * (1<<20)) / 8;
745 break;
746 case 0x12:
747 *size = (2 * (1<<20)) / 8;
748 break;
749 case 0x13:
750 *size = (4 * (1<<20)) / 8;
751 break;
752 case 0x14:
753 *size = (8 * (1<<20)) / 8;
754 break;
755 }
756 }
757
758 done:
759
760 /* Restore the previous flash mode. */
761 REG_WR( pDevice, Nvram.Config1, config1 );
762
763 return status;
764 } /* LM_FLASH_ST_ReadSize */
765
766
767
768 /******************************************************************************/
769 /* Description: */
770 /* */
771 /* Return: */
772 /******************************************************************************/
773 STATIC LM_STATUS
774 LM_FLASH_Saifun_ReadSize( PLM_DEVICE_BLOCK pDevice, LM_UINT32 * size )
775 {
776 LM_UINT32 config3;
777 LM_UINT32 value32;
778 LM_STATUS status;
779
780 /* Temporarily replace the read command with a "read ID" command. */
781 config3 = REG_RD( pDevice, Nvram.Config3 );
782 value32 = config3 & ~NVRAM_READ_COMMAND(NVRAM_COMMAND_MASK);
783 value32 |= NVRAM_READ_COMMAND(0xab);
784 REG_WR( pDevice, Nvram.Config3, value32 );
785
786 REG_WR( pDevice, Nvram.Addr, 0x0 );
787
788 status = LM_NVRAM_Read_UINT32(pDevice, 0x0, &value32);
789
790 /* Restore the original read command. */
791 REG_WR( pDevice, Nvram.Config3, config3 );
792
793 if( status == LM_STATUS_SUCCESS )
794 {
795 switch( value32 & 0xff )
796 {
797 case 0x05:
798 *size = (512 * (1<<10)/8);
799 break;
800 case 0x10:
801 *size = (1 * (1<<20)/8);
802 break;
803 case 0x11:
804 *size = (2 * (1<<20)/8);
805 break;
806 }
807 }
808
809 return status;
810 } /* LM_FLASH_Saifun_ReadSize */
811
812
813
814 /******************************************************************************/
815 /* Description: */
816 /* */
817 /* Return: */
818 /******************************************************************************/
819 STATIC LM_STATUS
820 LM_FLASH_ReadSize( PLM_DEVICE_BLOCK pDevice, LM_UINT32 * size )
821 {
822 LM_UINT32 value32;
823 LM_STATUS status;
824
825 status = LM_NVRAM_AcquireLock( pDevice );
826 if( status == LM_STATUS_FAILURE )
827 {
828 return status;
829 }
830
831 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
832 {
833 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
834 {
835 value32 = REG_RD( pDevice, Nvram.NvmAccess );
836 value32 |= NVRAM_ACCESS_ENABLE | NVRAM_ACCESS_WRITE_ENABLE;
837 REG_WR( pDevice, Nvram.NvmAccess, value32 );
838 }
839 }
840
841 switch( pDevice->flashinfo.jedecnum )
842 {
843 case JEDEC_ST:
844 status = LM_FLASH_ST_ReadSize( pDevice, size );
845 break;
846 case JEDEC_ATMEL:
847 if( pDevice->flashinfo.buffered == TRUE )
848 {
849 status = LM_FLASH_Atmel_Buffered_ReadSize( pDevice, size );
850 }
851 else
852 {
853 status = LM_STATUS_FAILURE;
854 }
855 break;
856 case JEDEC_SAIFUN:
857 status = LM_FLASH_Saifun_ReadSize( pDevice, size );
858 break;
859 case JEDEC_SST:
860 default:
861 status = LM_STATUS_FAILURE;
862 }
863
864 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
865 {
866 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
867 {
868 value32 = REG_RD( pDevice, Nvram.NvmAccess );
869 value32 &= ~(NVRAM_ACCESS_ENABLE | NVRAM_ACCESS_WRITE_ENABLE);
870 REG_WR( pDevice, Nvram.NvmAccess, value32 );
871 }
872 }
873
874 LM_NVRAM_ReleaseLock( pDevice );
875
876 return status;
877 } /* LM_FLASH_ReadSize */
878
879 STATIC LM_VOID LM_NVRAM_Detect_570X( PLM_DEVICE_BLOCK pDevice )
880 {
881 LM_UINT32 value32;
882
883 value32 = REG_RD(pDevice, Nvram.Config1);
884
885 if( (value32 & FLASH_INTERFACE_ENABLE) == 0 )
886 {
887 pDevice->flashinfo.romtype = ROM_TYPE_EEPROM;
888 }
889 else
890 {
891 /*
892 * 5705 and older products do not have bits 24 and 25 defined.
893 * If we've gotten here, then we can guarantee the flash is
894 * an Atmel AT45DB011DB.
895 */
896 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
897 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
898 pDevice->flashinfo.pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
899 pDevice->flashinfo.buffered = TRUE;
900 }
901 } /* LM_NVRAM_Detect_570X */
902
903 STATIC LM_VOID LM_NVRAM_Detect_5750( PLM_DEVICE_BLOCK pDevice )
904 {
905 LM_UINT32 value32;
906
907 value32 = REG_RD(pDevice, Nvram.Config1);
908
909 if( (value32 & FLASH_INTERFACE_ENABLE) == 0 )
910 {
911 pDevice->flashinfo.romtype = ROM_TYPE_EEPROM;
912 return;
913 }
914
915 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
916
917 switch( value32 & FLASH_PART_5750_TYPEMASK )
918 {
919 case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
920 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
921 pDevice->flashinfo.pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
922 pDevice->flashinfo.buffered = TRUE;
923 break;
924 case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
925 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
926 pDevice->flashinfo.pagesize = ATMEL_AT25F512_PAGE_SIZE;
927 pDevice->flashinfo.buffered = FALSE;
928 break;
929 case FLASH_VENDOR_ST:
930 pDevice->flashinfo.jedecnum = JEDEC_ST;
931 pDevice->flashinfo.pagesize = ST_M45PEX0_PAGE_SIZE;
932 pDevice->flashinfo.buffered = TRUE;
933 break;
934 case FLASH_VENDOR_SAIFUN:
935 pDevice->flashinfo.jedecnum = JEDEC_SAIFUN;
936 pDevice->flashinfo.pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
937 pDevice->flashinfo.buffered = FALSE;
938 break;
939 case FLASH_VENDOR_SST_SMALL:
940 case FLASH_VENDOR_SST_LARGE:
941 pDevice->flashinfo.jedecnum = JEDEC_SST;
942 pDevice->flashinfo.pagesize = SST_25VF0X0_PAGE_SIZE;
943 pDevice->flashinfo.buffered = FALSE;
944 break;
945 default:
946 B57_ERR(("bcm57xx : Unknown NVRAM type.\n"));
947 pDevice->flashinfo.jedecnum = 0;
948 pDevice->flashinfo.romtype = 0;
949 pDevice->flashinfo.buffered = FALSE;
950 pDevice->flashinfo.pagesize = 0;
951 }
952 } /* LM_NVRAM_Detect_5750 */
953
954 STATIC LM_VOID LM_NVRAM_Detect_5752( PLM_DEVICE_BLOCK pDevice )
955 {
956 LM_BOOL supported;
957 LM_UINT32 value32;
958
959 supported = FALSE;
960
961 value32 = REG_RD(pDevice, Nvram.Config1);
962
963 if(value32 & BIT_27)
964 pDevice->Flags |= PROTECTED_NVRAM_FLAG;
965
966 switch( value32 & FLASH_PART_5752_TYPEMASK )
967 {
968 case FLASH_PART_5752_EEPROM_ATMEL_64K:
969 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
970 pDevice->flashinfo.romtype = ROM_TYPE_EEPROM;
971 pDevice->flashinfo.buffered = FALSE;
972 pDevice->flashinfo.chipsize = (64 * (1<<10)/8);
973 supported = TRUE;
974 break;
975
976 case FLASH_PART_5752_EEPROM_ATMEL_376K:
977 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
978 pDevice->flashinfo.romtype = ROM_TYPE_EEPROM;
979 pDevice->flashinfo.buffered = FALSE;
980 pDevice->flashinfo.chipsize = (512 * (1<<10)/8);
981 supported = TRUE;
982 break;
983
984 case FLASH_PART_5752_FLASH_ATMEL_AT45DB041:
985 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
986 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
987 pDevice->flashinfo.buffered = TRUE;
988 pDevice->flashinfo.chipsize = (4 * (1<<20)) / 8;
989 supported = TRUE;
990 break;
991
992 case FLASH_PART_5752_FLASH_ATMEL_AT25F512:
993 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
994 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
995 pDevice->flashinfo.buffered = FALSE;
996 pDevice->flashinfo.chipsize = (512 * (1<<10)/8);
997 supported = TRUE;
998 break;
999
1000 case FLASH_PART_5752_FLASH_ST_M25P10A:
1001 pDevice->flashinfo.jedecnum = JEDEC_ST;
1002 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
1003 pDevice->flashinfo.buffered = TRUE;
1004 pDevice->flashinfo.chipsize = (1 * (1<<20)) / 8;
1005 supported = TRUE;
1006 break;
1007 case FLASH_PART_5752_FLASH_ST_M25P05A:
1008 pDevice->flashinfo.jedecnum = JEDEC_ST;
1009 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
1010 pDevice->flashinfo.buffered = TRUE;
1011 pDevice->flashinfo.chipsize = (512 * (1<<10)/8);
1012 supported = TRUE;
1013 break;
1014
1015 case FLASH_PART_5752_FLASH_ST_M45PE10:
1016 pDevice->flashinfo.jedecnum = JEDEC_ST;
1017 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
1018 pDevice->flashinfo.buffered = TRUE;
1019 pDevice->flashinfo.chipsize = (1 * (1<<20)) / 8;
1020 supported = TRUE;
1021 break;
1022
1023 case FLASH_PART_5752_FLASH_ST_M45PE20:
1024 pDevice->flashinfo.jedecnum = JEDEC_ST;
1025 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
1026 pDevice->flashinfo.buffered = TRUE;
1027 pDevice->flashinfo.chipsize = (2 * (1<<20)) / 8;
1028 supported = TRUE;
1029 break;
1030
1031 case FLASH_PART_5752_FLASH_ST_M45PE40:
1032 pDevice->flashinfo.jedecnum = JEDEC_ST;
1033 pDevice->flashinfo.romtype = ROM_TYPE_FLASH;
1034 pDevice->flashinfo.buffered = TRUE;
1035 pDevice->flashinfo.chipsize = (4 * (1<<20)) / 8;
1036 supported = TRUE;
1037 break;
1038 default:
1039 B57_ERR(("bcm57xx : Unknown NVRAM type.\n"));
1040 }
1041
1042 if( pDevice->flashinfo.romtype == ROM_TYPE_FLASH )
1043 {
1044 switch( value32 & FLASH_PART_5752_PAGEMASK )
1045 {
1046 case FLASH_PART_5752_PAGE_SIZE_256B:
1047 pDevice->flashinfo.pagesize = 256;
1048 break;
1049 case FLASH_PART_5752_PAGE_SIZE_512B:
1050 pDevice->flashinfo.pagesize = 512;
1051 break;
1052 case FLASH_PART_5752_PAGE_SIZE_1K:
1053 pDevice->flashinfo.pagesize = 1024;
1054 break;
1055 case FLASH_PART_5752_PAGE_SIZE_2K:
1056 pDevice->flashinfo.pagesize = 2048;
1057 break;
1058 case FLASH_PART_5752_PAGE_SIZE_4K:
1059 pDevice->flashinfo.pagesize = 4096;
1060 break;
1061 case FLASH_PART_5752_PAGE_SIZE_264B:
1062 pDevice->flashinfo.pagesize = 264;
1063 break;
1064 default:
1065 B57_ERR(("bcm57xx : Unknown NVRAM page size.\n"));
1066 supported = FALSE;
1067 }
1068 }
1069
1070 if( supported != TRUE )
1071 {
1072 B57_ERR(("Flash type unsupported!!!\n"));
1073 pDevice->flashinfo.jedecnum = 0;
1074 pDevice->flashinfo.romtype = 0;
1075 pDevice->flashinfo.buffered = FALSE;
1076 pDevice->flashinfo.pagesize = 0;
1077 }
1078
1079
1080 } /* LM_NVRAM_Detect_5752 */
1081
1082
1083 /******************************************************************************/
1084 /* Description: */
1085 /* */
1086 /* Return: */
1087 /******************************************************************************/
1088 STATIC LM_VOID LM_NVRAM_Init( PLM_DEVICE_BLOCK pDevice )
1089 {
1090 LM_UINT32 Value32;
1091
1092 /* BCM4785: Avoid all access to NVRAM & EEPROM. */
1093 if (pDevice->Flags & SB_CORE_FLAG)
1094 return;
1095
1096 pDevice->NvramSize = 0;
1097
1098 /* Intialize clock period and state machine. */
1099 Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
1100 SEEPROM_ADDR_FSM_RESET;
1101 REG_WR(pDevice, Grc.EepromAddr, Value32);
1102 REG_RD_BACK(pDevice, Grc.EepromAddr);
1103
1104 MM_Wait(100);
1105
1106 /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
1107 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
1108 REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
1109
1110 switch( T3_ASIC_REV(pDevice->ChipRevId) )
1111 {
1112 case T3_ASIC_REV_5700:
1113 case T3_ASIC_REV_5701:
1114 pDevice->flashinfo.romtype = ROM_TYPE_EEPROM;
1115 break;
1116 case T3_ASIC_REV_5752:
1117 LM_NVRAM_Detect_5752(pDevice);
1118 break;
1119 case T3_ASIC_REV_5714_A0:
1120 case T3_ASIC_REV_5780:
1121 case T3_ASIC_REV_5714:
1122 case T3_ASIC_REV_5750:
1123 LM_NVRAM_Detect_5750(pDevice);
1124 break;
1125 default:
1126 LM_NVRAM_Detect_570X(pDevice);
1127 }
1128
1129 /* Set the 5701 compatibility mode if we are using EEPROM. */
1130 if( T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
1131 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701 &&
1132 pDevice->flashinfo.romtype == ROM_TYPE_EEPROM )
1133 {
1134 Value32 = REG_RD(pDevice, Nvram.Config1);
1135
1136 if( T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1137 {
1138 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1139 {
1140 REG_WR(pDevice, Nvram.NvmAccess,
1141 REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
1142 }
1143 }
1144
1145 /* Use the new interface to read EEPROM. */
1146 Value32 &= ~FLASH_COMPAT_BYPASS;
1147
1148 REG_WR(pDevice, Nvram.Config1, Value32);
1149
1150 if( T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1151 {
1152 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1153 {
1154 REG_WR(pDevice, Nvram.NvmAccess,
1155 REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
1156 }
1157 }
1158 }
1159
1160 if( !(T3_ASIC_5752(pDevice->ChipRevId)) )
1161 {
1162 if( pDevice->flashinfo.romtype == ROM_TYPE_EEPROM )
1163 {
1164 /* The only EEPROM we support is an ATMEL */
1165 pDevice->flashinfo.jedecnum = JEDEC_ATMEL;
1166 pDevice->flashinfo.pagesize = 0;
1167 pDevice->flashinfo.buffered = FALSE;
1168
1169 LM_EEPROM_ReadSize( pDevice, &pDevice->flashinfo.chipsize );
1170 }
1171 else
1172 {
1173 LM_FLASH_ReadSize( pDevice, &pDevice->flashinfo.chipsize );
1174 pDevice->Flags |= FLASH_DETECTED_FLAG;
1175 }
1176 }
1177
1178 pDevice->NvramSize = pDevice->flashinfo.chipsize;
1179
1180 B57_INFO(("*nvram:size=0x%x jnum=0x%x page=0x%x buff=0x%x \n",
1181 pDevice->NvramSize, pDevice->flashinfo.jedecnum,
1182 pDevice->flashinfo.pagesize, pDevice->flashinfo.buffered));
1183
1184 } /* LM_NVRAM_Init */
1185
1186
1187
1188 /******************************************************************************/
1189 /* Description: */
1190 /* */
1191 /* Return: */
1192 /******************************************************************************/
1193 LM_STATUS
1194 LM_NvramRead( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset, LM_UINT32 * data )
1195 {
1196 LM_UINT32 value32;
1197 LM_STATUS status;
1198
1199 /* BCM4785: Avoid all access to NVRAM & EEPROM. */
1200 if (pDevice->Flags & SB_CORE_FLAG) {
1201 *data = 0xffffffff;
1202 return LM_STATUS_FAILURE;
1203 }
1204
1205 if( offset >= pDevice->flashinfo.chipsize )
1206 {
1207 return LM_STATUS_FAILURE;
1208 }
1209
1210 if( T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1211 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 )
1212 {
1213 status = LM_EEPROM_Read_UINT32( pDevice, offset, data );
1214 }
1215 else
1216 {
1217 status = LM_NVRAM_AcquireLock( pDevice );
1218 if( status == LM_STATUS_FAILURE )
1219 {
1220 return status;
1221 }
1222
1223 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1224 {
1225 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1226 {
1227 value32 = REG_RD( pDevice, Nvram.NvmAccess );
1228 value32 |= NVRAM_ACCESS_ENABLE;
1229 REG_WR( pDevice, Nvram.NvmAccess, value32 );
1230 }
1231 }
1232
1233 status = LM_NVRAM_Read_UINT32(pDevice, offset, data);
1234
1235 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1236 {
1237 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1238 {
1239 value32 = REG_RD( pDevice, Nvram.NvmAccess );
1240 value32 &= ~NVRAM_ACCESS_ENABLE;
1241 REG_WR( pDevice, Nvram.NvmAccess, value32 );
1242 }
1243 }
1244
1245 LM_NVRAM_ReleaseLock( pDevice );
1246 }
1247
1248 return status;
1249 } /* LM_NvramRead */
1250
1251
1252
1253 #ifdef ETHTOOL_SEEPROM
1254
1255 /******************************************************************************/
1256 /* Description: */
1257 /* */
1258 /* Return: */
1259 /******************************************************************************/
1260 STATIC LM_STATUS
1261 LM_NVRAM_ReadBlock(PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
1262 LM_UINT8 *data, LM_UINT32 size)
1263 {
1264 LM_STATUS status;
1265 LM_UINT32 value32;
1266 LM_UINT32 bytecnt;
1267 LM_UINT8 * srcptr;
1268
1269 status = LM_STATUS_SUCCESS;
1270
1271 while( size > 0 )
1272 {
1273 /* Make sure the read is word aligned. */
1274 value32 = offset & 0x3;
1275 if( value32 )
1276 {
1277 bytecnt = sizeof(LM_UINT32) - value32;
1278 offset -= value32;
1279 srcptr = (LM_UINT8 *)(&value32) + value32;
1280 }
1281 else
1282 {
1283 bytecnt = sizeof(LM_UINT32);
1284 srcptr = (LM_UINT8 *)(&value32);
1285 }
1286
1287 if( bytecnt > size )
1288 {
1289 bytecnt = size;
1290 }
1291
1292 if( T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
1293 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701 )
1294 {
1295 status = LM_NVRAM_Read_UINT32( pDevice, offset, &value32 );
1296 }
1297 else
1298 {
1299 status = LM_EEPROM_Read_UINT32( pDevice, offset, &value32 );
1300 }
1301
1302 if( status != LM_STATUS_SUCCESS )
1303 {
1304 break;
1305 }
1306
1307 memcpy( data, srcptr, bytecnt );
1308
1309 offset += sizeof(LM_UINT32);
1310 data += bytecnt;
1311 size -= bytecnt;
1312 }
1313
1314 return status;
1315 } /* LM_NVRAM_ReadBlock */
1316
1317 /******************************************************************************/
1318 /* Description: */
1319 /* */
1320 /* Return: */
1321 /******************************************************************************/
1322 STATIC LM_STATUS
1323 LM_EEPROM_WriteBlock( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
1324 LM_UINT8 * data, LM_UINT32 size )
1325 {
1326 LM_UINT8 * dstptr;
1327 LM_UINT32 value32;
1328 LM_UINT32 bytecnt;
1329 LM_UINT32 subword1;
1330 LM_UINT32 subword2;
1331 LM_UINT32 Addr;
1332 LM_UINT32 Dev;
1333 LM_STATUS status;
1334
1335 if( offset > pDevice->flashinfo.chipsize )
1336 {
1337 return LM_STATUS_FAILURE;
1338 }
1339
1340 status = LM_STATUS_SUCCESS;
1341
1342 if( size == 0 )
1343 {
1344 return status;
1345 }
1346
1347 if( offset & 0x3 )
1348 {
1349 /*
1350 * If our initial offset does not fall on a word boundary, we
1351 * have to do a read / modify / write to preserve the
1352 * preceding bits we are not interested in.
1353 */
1354 status = LM_EEPROM_Read_UINT32(pDevice, offset & ~0x3, &subword1);
1355 if( status == LM_STATUS_FAILURE )
1356 {
1357 return status;
1358 }
1359 }
1360
1361 if( (offset + size) & 0x3 )
1362 {
1363 /*
1364 * Likewise, if our ending offset does not fall on a word
1365 * boundary, we have to do a read / modify / write to
1366 * preserve the trailing bits we are not interested in.
1367 */
1368 status = LM_EEPROM_Read_UINT32( pDevice, (offset + size) & ~0x3,
1369 &subword2 );
1370 if( status == LM_STATUS_FAILURE )
1371 {
1372 return status;
1373 }
1374 }
1375
1376 /* Enable EEPROM write. */
1377 if( pDevice->Flags & EEPROM_WP_FLAG )
1378 {
1379 REG_WR( pDevice, Grc.LocalCtrl,
1380 pDevice->GrcLocalCtrl | GRC_MISC_LOCAL_CTRL_GPIO_OE1 );
1381 REG_RD_BACK( pDevice, Grc.LocalCtrl );
1382 MM_Wait(40);
1383
1384 value32 = REG_RD( pDevice, Grc.LocalCtrl );
1385 if( value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 )
1386 {
1387 return LM_STATUS_FAILURE;
1388 }
1389 }
1390
1391 while( size > 0 )
1392 {
1393 value32 = offset & 0x3;
1394 if( value32 )
1395 {
1396 /*
1397 * We have to read / modify / write the data to
1398 * preserve the flash contents preceding the offset.
1399 */
1400 offset &= ~0x3;
1401
1402 dstptr = ((LM_UINT8 *)(&value32)) + value32;
1403 bytecnt = sizeof(LM_UINT32) - value32;
1404 value32 = subword1;
1405 }
1406 else if( size < sizeof(LM_UINT32) )
1407 {
1408 dstptr = (LM_UINT8 *)(&value32);
1409 bytecnt = size;
1410 value32 = subword2;
1411 }
1412 else
1413 {
1414 dstptr = (LM_UINT8 *)(&value32);
1415 bytecnt = sizeof(LM_UINT32);
1416 }
1417
1418 if( size < bytecnt )
1419 {
1420 bytecnt = size;
1421 }
1422
1423 memcpy( dstptr, (void *)data, bytecnt );
1424
1425 data += bytecnt;
1426 size -= bytecnt;
1427
1428 /*
1429 * Swap the data so that the byte stream will be
1430 * written the same in little and big endian systems.
1431 */
1432 value32 = MM_SWAP_LE32(value32);
1433
1434 /* Set the write value to the eeprom */
1435 REG_WR( pDevice, Grc.EepromData, value32 );
1436
1437 Dev = offset / pDevice->flashinfo.chipsize;
1438 Addr = offset % pDevice->flashinfo.chipsize;
1439
1440 value32 = REG_RD( pDevice, Grc.EepromAddr );
1441 value32 &= ~(SEEPROM_ADDR_DEV_ID_MASK | SEEPROM_ADDR_ADDRESS_MASK |
1442 SEEPROM_ADDR_RW_MASK);
1443 value32 |= SEEPROM_ADDR_DEV_ID(Dev) | SEEPROM_ADDR_ADDRESS(Addr) |
1444 SEEPROM_ADDR_START | SEEPROM_ADDR_WRITE;
1445
1446 status = LM_EEPROM_ExecuteCommand( pDevice, value32 );
1447 if( status != LM_STATUS_SUCCESS )
1448 {
1449 break;
1450 }
1451
1452 offset += sizeof(LM_UINT32);
1453 }
1454
1455 /* Write-protect EEPROM. */
1456 if( pDevice->Flags & EEPROM_WP_FLAG )
1457 {
1458 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
1459 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
1460 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
1461 REG_RD_BACK(pDevice, Grc.LocalCtrl);
1462 MM_Wait(40);
1463 }
1464
1465 return status;
1466 } /* LM_EEPROM_WriteBlock */
1467
1468
1469
1470 /******************************************************************************/
1471 /* Description: */
1472 /* */
1473 /* Return: */
1474 /******************************************************************************/
1475 STATIC LM_STATUS
1476 LM_NVRAM_WriteBlockUnBuffered( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
1477 LM_UINT8 * data, LM_UINT32 size )
1478 {
1479 LM_UINT i;
1480 LM_STATUS status;
1481 LM_UINT32 tgtoff;
1482 LM_UINT32 value32;
1483 LM_UINT32 ctrlreg;
1484 LM_UINT32 pagesize;
1485 LM_UINT32 pagemask;
1486 LM_UINT32 physaddr;
1487
1488 /* Cache the pagesize. */
1489 pagesize = pDevice->flashinfo.pagesize;
1490
1491 if( pDevice->flashinfo.jedecnum == JEDEC_SAIFUN )
1492 {
1493 /* Config2 = 0x500d8 */
1494 /* Config3 = 0x3840253 */
1495 /* Write1 = 0xaf000400 */
1496
1497 /* Configure the erase command to be "page erase". */
1498 /* Configure the status command to be "read status register". */
1499 value32 = REG_RD( pDevice, Nvram.Config2 );
1500 value32 &= ~(NVRAM_STATUS_COMMAND( NVRAM_COMMAND_MASK ) |
1501 NVRAM_ERASE_COMMAND( NVRAM_COMMAND_MASK ));
1502 value32 |= NVRAM_STATUS_COMMAND( SAIFUN_SA25F0XX_READ_STATUS_CMD ) |
1503 NVRAM_ERASE_COMMAND( SAIFUN_SA25F0XX_PAGE_ERASE_CMD );
1504 REG_WR( pDevice, Nvram.Config2, value32 );
1505
1506 /* Configure the write command to be "page write". */
1507 value32 = REG_RD( pDevice, Nvram.Config3 );
1508 value32 &= ~NVRAM_WRITE_UNBUFFERED_COMMAND( NVRAM_COMMAND_MASK );
1509 value32 |= NVRAM_WRITE_UNBUFFERED_COMMAND( SAIFUN_SA25F0XX_PAGE_WRITE_CMD );
1510 REG_WR( pDevice, Nvram.Config3, value32 );
1511
1512 /* Make sure the "write enable" command is correct. */
1513 value32 = REG_RD( pDevice, Nvram.Write1 );
1514 value32 &= ~NVRAM_WRITE1_WRENA_CMD( NVRAM_COMMAND_MASK );
1515 value32 |= NVRAM_WRITE1_WRENA_CMD( SAIFUN_SA25F0XX_WRENA_CMD );
1516 REG_WR( pDevice, Nvram.Write1, value32 );
1517
1518 pagemask = SAIFUN_SA25F0XX_PAGE_MASK;
1519 }
1520 else
1521 {
1522 /* Unsupported flash type */
1523 return LM_STATUS_FAILURE;
1524 }
1525
1526 if( size == 0 )
1527 {
1528 status = LM_STATUS_SUCCESS;
1529 goto done;
1530 }
1531
1532 while( size > 0 )
1533 {
1534 /* Align the offset to a page boundary. */
1535 physaddr = offset & ~pagemask;
1536
1537 status = LM_NVRAM_ReadBlock( pDevice, physaddr,
1538 pDevice->flashbuffer,
1539 pagesize );
1540 if( status == LM_STATUS_FAILURE )
1541 {
1542 break;
1543 }
1544
1545 /* Calculate the target index. */
1546 tgtoff = offset & pagemask;
1547
1548 /* Copy the new data into the save buffer. */
1549 for( i = tgtoff; i < pagesize && size > 0; i++ )
1550 {
1551 pDevice->flashbuffer[i] = *data++;
1552 size--;
1553 }
1554
1555 /* Move the offset to the next page. */
1556 offset = offset + (pagesize - tgtoff);
1557
1558 /*
1559 * The LM_NVRAM_ReadBlock() function releases
1560 * the access enable bit. Reacquire it.
1561 */
1562 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1563 REG_WR(pDevice, Nvram.NvmAccess, NVRAM_ACCESS_ENABLE);
1564
1565
1566 /*
1567 * Before we can erase the flash page, we need
1568 * to issue a special "write enable" command.
1569 */
1570 ctrlreg = NVRAM_CMD_WRITE_ENABLE | NVRAM_CMD_DO_IT | NVRAM_CMD_DONE;
1571
1572 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1573 if( status == LM_STATUS_FAILURE )
1574 {
1575 break;
1576 }
1577
1578 /* Erase the target page */
1579 REG_WR(pDevice, Nvram.Addr, physaddr);
1580
1581 ctrlreg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_WR |
1582 NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
1583
1584 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1585 if( status == LM_STATUS_FAILURE )
1586 {
1587 break;
1588 }
1589
1590 /* Issue another write enable to start the write. */
1591 ctrlreg = NVRAM_CMD_WRITE_ENABLE | NVRAM_CMD_DO_IT | NVRAM_CMD_DONE;
1592
1593 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1594 if( status == LM_STATUS_FAILURE )
1595 {
1596 break;
1597 }
1598
1599 /* Copy the data into our NIC's buffers. */
1600 for( i = 0; i < pagesize; i+= 4 )
1601 {
1602 value32 = *((LM_UINT32 *)(&pDevice->flashbuffer[i]));
1603 value32 = MM_SWAP_BE32( value32 );
1604
1605 /* Write the location we wish to write to. */
1606 REG_WR( pDevice, Nvram.Addr, physaddr );
1607
1608 /* Write the data we wish to write. */
1609 REG_WR( pDevice, Nvram.WriteData, value32 );
1610
1611 ctrlreg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_WR;
1612
1613 if( i == 0 )
1614 {
1615 ctrlreg |= NVRAM_CMD_FIRST;
1616 }
1617 else if( i == (pagesize - 4) )
1618 {
1619 ctrlreg |= NVRAM_CMD_LAST;
1620 }
1621
1622 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1623 if( status == LM_STATUS_FAILURE )
1624 {
1625 size = 0;
1626 break;
1627 }
1628
1629 physaddr += sizeof(LM_UINT32);
1630 }
1631 }
1632
1633 /* Paranoia. Turn off the "write enable" flag. */
1634 ctrlreg = NVRAM_CMD_WRITE_DISABLE | NVRAM_CMD_DO_IT | NVRAM_CMD_DONE;
1635
1636 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1637
1638 done:
1639
1640 return status;
1641 } /* LM_NVRAM_WriteBlockUnBuffered */
1642
1643
1644
1645 /******************************************************************************/
1646 /* Description: */
1647 /* */
1648 /* Return: */
1649 /******************************************************************************/
1650 STATIC LM_STATUS
1651 LM_NVRAM_WriteBlockBuffered( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
1652 LM_UINT8 * data, LM_UINT32 size )
1653 {
1654 LM_STATUS status;
1655 LM_UINT32 value32;
1656 LM_UINT32 bytecnt;
1657 LM_UINT32 ctrlreg;
1658 LM_UINT32 pageoff;
1659 LM_UINT32 physaddr;
1660 LM_UINT32 subword1;
1661 LM_UINT32 subword2;
1662 LM_UINT8 * dstptr;
1663
1664 if(T3_ASIC_5752(pDevice->ChipRevId) &&
1665 (pDevice->flashinfo.jedecnum == JEDEC_ST ||
1666 pDevice->flashinfo.jedecnum == JEDEC_ATMEL ))
1667 {
1668 /* Do nothing as the 5752 does will take care of it */
1669 }
1670 else if( pDevice->flashinfo.jedecnum == JEDEC_ST )
1671 {
1672 /*
1673 * Program our chip to look at bit0 of the NVRAM's status
1674 * register when polling the write or erase operation status.
1675 */
1676 value32 = REG_RD(pDevice, Nvram.Config1);
1677 value32 &= ~FLASH_STATUS_BITS_MASK;
1678 REG_WR( pDevice, Nvram.Config1, value32 );
1679
1680 /* Program the "read status" and "page erase" commands. */
1681 value32 = NVRAM_STATUS_COMMAND( ST_M45PEX0_READ_STATUS_CMD ) |
1682 NVRAM_ERASE_COMMAND( ST_M45PEX0_PAGE_ERASE_CMD );
1683 REG_WR( pDevice, Nvram.Config2, value32 );
1684
1685 /* Set the write command to be "page program". */
1686 value32 = REG_RD(pDevice, Nvram.Config3); /* default = 0x03840a53 */
1687 value32 &= ~NVRAM_WRITE_UNBUFFERED_COMMAND( NVRAM_COMMAND_MASK );
1688 value32 |= NVRAM_WRITE_UNBUFFERED_COMMAND( ST_M45PEX0_PAGE_PRGM_CMD );
1689 REG_WR( pDevice, Nvram.Config3, value32 );
1690
1691 /* Set the "write enable" and "write disable" commands. */
1692 value32 = NVRAM_WRITE1_WRENA_CMD( ST_M45PEX0_WRENA_CMD ) |
1693 NVRAM_WRITE1_WRDIS_CMD( ST_M45PEX0_WRDIS_CMD );
1694 REG_WR( pDevice, Nvram.Write1, value32 );
1695 }
1696 else if( pDevice->flashinfo.jedecnum == JEDEC_ATMEL )
1697 {
1698 if( pDevice->flashinfo.romtype == ROM_TYPE_EEPROM )
1699 {
1700 #if 0
1701 Config1 = 0x2008200
1702 Config2 = 0x9f0081
1703 Config3 = 0xa184a053
1704 Write1 = 0xaf000400
1705 #endif
1706 }
1707 else if( pDevice->flashinfo.buffered == TRUE )
1708 {
1709 /*
1710 * Program our chip to look at bit7 of the NVRAM's status
1711 * register when polling the write operation status.
1712 */
1713 value32 = REG_RD(pDevice, Nvram.Config1);
1714 value32 |= FLASH_STATUS_BITS_MASK;
1715 REG_WR( pDevice, Nvram.Config1, value32 );
1716
1717 /* Set the write command to be "page program". */
1718 value32 = REG_RD(pDevice, Nvram.Config3); /* default = 0x03840a53 */
1719 value32 &= ~NVRAM_WRITE_UNBUFFERED_COMMAND( NVRAM_COMMAND_MASK );
1720 value32 |= NVRAM_WRITE_UNBUFFERED_COMMAND( ATMEL_AT45DB0X1B_BUFFER_WRITE_CMD );
1721 REG_WR( pDevice, Nvram.Config3, value32 );
1722 /* Config1 = 0x2008273 */
1723 /* Config2 = 0x00570081 */
1724 /* Config3 = 0x68848353 */
1725 }
1726 else
1727 {
1728 /* NVRAM type unsupported. */
1729 return LM_STATUS_FAILURE;
1730 }
1731 }
1732 else
1733 {
1734 /* NVRAM type unsupported. */
1735 return LM_STATUS_FAILURE;
1736 }
1737
1738 status = LM_STATUS_SUCCESS;
1739
1740 if( offset & 0x3 )
1741 {
1742 /*
1743 * If our initial offset does not fall on a word boundary, we
1744 * have to do a read / modify / write to preserve the
1745 * preceding bits we are not interested in.
1746 */
1747 status = LM_NVRAM_ReadBlock( pDevice, offset & ~0x3,
1748 (LM_UINT8 *)&subword1,
1749 sizeof(subword1) );
1750 if( status == LM_STATUS_FAILURE )
1751 {
1752 return status;
1753 }
1754 }
1755
1756 if( (offset + size) & 0x3 )
1757 {
1758 /*
1759 * Likewise, if our ending offset does not fall on a word
1760 * boundary, we have to do a read / modify / write to
1761 * preserve the trailing bits we are not interested in.
1762 */
1763 status = LM_NVRAM_ReadBlock( pDevice, (offset + size) & ~0x3,
1764 (LM_UINT8 *)&subword2,
1765 sizeof(subword2) );
1766 if( status == LM_STATUS_FAILURE )
1767 {
1768 return status;
1769 }
1770 }
1771
1772 ctrlreg = NVRAM_CMD_FIRST;
1773
1774 while( size > 0 )
1775 {
1776 value32 = offset & 0x3;
1777 if( value32 )
1778 {
1779 /*
1780 * We have to read / modify / write the data to
1781 * preserve the flash contents preceding the offset.
1782 */
1783 offset &= ~0x3;
1784
1785 dstptr = ((LM_UINT8 *)(&value32)) + value32;
1786 bytecnt = sizeof(LM_UINT32) - value32;
1787 value32 = subword1;
1788 }
1789 else if( size < sizeof(LM_UINT32) )
1790 {
1791 dstptr = (LM_UINT8 *)(&value32);
1792 bytecnt = size;
1793 value32 = subword2;
1794 }
1795 else
1796 {
1797 dstptr = (LM_UINT8 *)(&value32);
1798 bytecnt = sizeof(LM_UINT32);
1799 }
1800
1801 if( size < bytecnt )
1802 {
1803 bytecnt = size;
1804 }
1805
1806 memcpy( dstptr, (void *)data, bytecnt );
1807
1808 data += bytecnt;
1809 size -= bytecnt;
1810
1811 /*
1812 * Swap the data so that the byte stream will be
1813 * written the same in little and big endian systems.
1814 */
1815 value32 = MM_SWAP_BE32(value32);
1816
1817 /* Set the desired write data value to the flash. */
1818 REG_WR(pDevice, Nvram.WriteData, value32);
1819
1820 pageoff = offset % pDevice->flashinfo.pagesize;
1821
1822 /* Set the target address. */
1823 if( pDevice->flashinfo.jedecnum == JEDEC_ATMEL &&
1824 pDevice->flashinfo.romtype == ROM_TYPE_FLASH )
1825 {
1826 /*
1827 * If we're dealing with the special ATMEL part, we need to
1828 * convert the submitted offset before it can be considered
1829 * a physical address.
1830 */
1831 LM_UINT32 pagenmbr;
1832
1833 pagenmbr = offset / pDevice->flashinfo.pagesize;
1834 pagenmbr = pagenmbr << ATMEL_AT45DB0X1B_PAGE_POS;
1835
1836 physaddr = pagenmbr + pageoff;
1837 }
1838 else
1839 {
1840 physaddr = offset;
1841 }
1842
1843 REG_WR(pDevice, Nvram.Addr, physaddr);
1844
1845 ctrlreg |= (NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_WR);
1846
1847 if( pageoff == 0 )
1848 {
1849 /* Set CMD_FIRST when we are at the beginning of a page. */
1850 ctrlreg |= NVRAM_CMD_FIRST;
1851 }
1852 else if( pageoff == (pDevice->flashinfo.pagesize - 4) )
1853 {
1854 /*
1855 * Enable the write to the current page
1856 * before moving on to the next one.
1857 */
1858 ctrlreg |= NVRAM_CMD_LAST;
1859 }
1860
1861 if( size == 0 )
1862 {
1863 ctrlreg |= NVRAM_CMD_LAST;
1864 }
1865
1866 if( pDevice->flashinfo.jedecnum == JEDEC_ST &&
1867 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750) ||
1868 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5714)) &&
1869 (ctrlreg & NVRAM_CMD_FIRST) )
1870 {
1871 LM_UINT32 wrencmd;
1872
1873 REG_WR(pDevice, Nvram.Write1, ST_M45PEX0_WRENA_CMD);
1874
1875 /* We need to issue a special "write enable" command first. */
1876 wrencmd = NVRAM_CMD_WRITE_ENABLE | NVRAM_CMD_DO_IT | NVRAM_CMD_DONE;
1877
1878 status = LM_NVRAM_ExecuteCommand( pDevice, wrencmd );
1879 if( status == LM_STATUS_FAILURE )
1880 {
1881 return status;
1882 }
1883 }
1884
1885 if( pDevice->flashinfo.romtype == ROM_TYPE_EEPROM )
1886 {
1887 /* We always do complete word writes to eeprom. */
1888 ctrlreg |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
1889 }
1890
1891 status = LM_NVRAM_ExecuteCommand( pDevice, ctrlreg );
1892 if( status == LM_STATUS_FAILURE )
1893 {
1894 break;
1895 }
1896
1897 offset += sizeof(LM_UINT32);
1898 ctrlreg = 0;
1899 }
1900
1901 return status;
1902 } /* LM_NVRAM_WriteBlockBuffered */
1903
1904
1905
1906 /******************************************************************************/
1907 /* Description: */
1908 /* */
1909 /* Return: */
1910 /******************************************************************************/
1911 LM_STATUS LM_NVRAM_WriteBlock( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
1912 LM_UINT8 * data, LM_UINT32 size )
1913 {
1914 LM_UINT32 value32;
1915 LM_STATUS status;
1916
1917 if( offset > pDevice->flashinfo.chipsize ||
1918 (offset + size) > pDevice->flashinfo.chipsize )
1919 {
1920 return LM_STATUS_FAILURE;
1921 }
1922
1923 if( size == 0 )
1924 {
1925 return LM_STATUS_SUCCESS;
1926 }
1927
1928 if( T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1929 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 )
1930 {
1931 status = LM_EEPROM_WriteBlock( pDevice, offset, data, size );
1932 }
1933 else
1934 {
1935 status = LM_NVRAM_AcquireLock( pDevice );
1936 if( status == LM_STATUS_FAILURE )
1937 {
1938 return status;
1939 }
1940
1941 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1942 {
1943 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1944 {
1945 value32 = REG_RD( pDevice, Nvram.NvmAccess );
1946 value32 |= (NVRAM_ACCESS_ENABLE | NVRAM_ACCESS_WRITE_ENABLE);
1947 REG_WR( pDevice, Nvram.NvmAccess, value32 );
1948 }
1949 }
1950
1951 /* Enable EEPROM write. */
1952 if( pDevice->Flags & EEPROM_WP_FLAG )
1953 {
1954 REG_WR(pDevice, Grc.LocalCtrl,
1955 pDevice->GrcLocalCtrl | GRC_MISC_LOCAL_CTRL_GPIO_OE1);
1956 REG_RD_BACK(pDevice, Grc.LocalCtrl);
1957 MM_Wait(40);
1958
1959 value32 = REG_RD(pDevice, Grc.LocalCtrl);
1960 if( value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 )
1961 {
1962 status = LM_STATUS_FAILURE;
1963 goto error;
1964 }
1965 }
1966
1967 value32 = REG_RD(pDevice, Grc.Mode);
1968 value32 |= GRC_MODE_NVRAM_WRITE_ENABLE;
1969 REG_WR(pDevice, Grc.Mode, value32);
1970
1971 if( pDevice->flashinfo.buffered == TRUE ||
1972 pDevice->flashinfo.romtype == ROM_TYPE_EEPROM )
1973 {
1974 status = LM_NVRAM_WriteBlockBuffered(pDevice, offset, data, size);
1975 }
1976 else
1977 {
1978 status = LM_NVRAM_WriteBlockUnBuffered(pDevice, offset, data, size);
1979 }
1980
1981 value32 = REG_RD(pDevice, Grc.Mode);
1982 value32 &= ~GRC_MODE_NVRAM_WRITE_ENABLE;
1983 REG_WR(pDevice, Grc.Mode, value32);
1984
1985 if( pDevice->Flags & EEPROM_WP_FLAG )
1986 {
1987 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
1988 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
1989 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
1990 REG_RD_BACK(pDevice, Grc.LocalCtrl);
1991 MM_Wait(40);
1992 }
1993
1994 error:
1995
1996 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
1997 {
1998 if( (pDevice->Flags & PROTECTED_NVRAM_FLAG) == 0)
1999 {
2000 value32 = REG_RD(pDevice, Nvram.NvmAccess);
2001 value32 &= ~(NVRAM_ACCESS_ENABLE | NVRAM_ACCESS_WRITE_ENABLE);
2002 REG_WR(pDevice, Nvram.NvmAccess, value32);
2003 }
2004 }
2005
2006 LM_NVRAM_ReleaseLock( pDevice );
2007 }
2008
2009 return status;
2010 } /* LM_NVRAM_WriteBlock */
2011
2012
2013 LM_STATUS LM_NvramWriteBlock( PLM_DEVICE_BLOCK pDevice, LM_UINT32 offset,
2014 LM_UINT32 * data, LM_UINT32 size )
2015 {
2016 /* BCM4785: Avoid all access to NVRAM & EEPROM. */
2017 if (pDevice->Flags & SB_CORE_FLAG)
2018 return LM_STATUS_FAILURE;
2019
2020 return LM_NVRAM_WriteBlock( pDevice, offset, (LM_UINT8 *)data, size * 4 );
2021 }
2022
2023 #endif /* ETHTOOL_SEEPROM */
2024
2025
2026 static int
2027 bcm_ether_atoe(char *p, struct ether_addr *ea)
2028 {
2029 int i = 0;
2030
2031 for (;;) {
2032 ea->octet[i++] = (char) simple_strtoul(p, &p, 16);
2033 if (!*p++ || i == 6)
2034 break;
2035 }
2036
2037 return (i == 6);
2038 }
2039
2040 /******************************************************************************/
2041 /* Description: */
2042 /* This routine initializes default parameters and reads the PCI */
2043 /* configurations. */
2044 /* */
2045 /* Return: */
2046 /* LM_STATUS_SUCCESS */
2047 /******************************************************************************/
2048 LM_STATUS
2049 LM_GetAdapterInfo(
2050 PLM_DEVICE_BLOCK pDevice)
2051 {
2052 PLM_ADAPTER_INFO pAdapterInfo;
2053 LM_UINT32 Value32, LedCfg, Ver;
2054 LM_STATUS Status;
2055 LM_UINT32 EeSigFound;
2056 LM_UINT32 EePhyTypeSerdes = 0;
2057 LM_UINT32 EePhyId = 0;
2058
2059 /* Get Device Id and Vendor Id */
2060 Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
2061 if(Status != LM_STATUS_SUCCESS)
2062 {
2063 return Status;
2064 }
2065 pDevice->PciVendorId = (LM_UINT16) Value32;
2066 pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
2067
2068 Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
2069 if(Status != LM_STATUS_SUCCESS)
2070 {
2071 return Status;
2072 }
2073 pDevice->PciRevId = (LM_UINT8) Value32;
2074
2075 /* Get chip revision id. */
2076 Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
2077 pDevice->ChipRevId = Value32 >> 16;
2078
2079 /* determine if it is PCIE system */
2080 if( (Value32 = MM_FindCapability(pDevice, T3_PCIE_CAPABILITY_ID)) != 0)
2081 {
2082 pDevice->Flags |= PCI_EXPRESS_FLAG;
2083 }
2084
2085 /* Get subsystem vendor. */
2086 Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
2087 if(Status != LM_STATUS_SUCCESS)
2088 {
2089 return Status;
2090 }
2091 pDevice->SubsystemVendorId = (LM_UINT16) Value32;
2092
2093 /* Get PCI subsystem id. */
2094 pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
2095
2096 /* Read bond id for baxter A0 since it has same rev id as hamilton A0*/
2097
2098 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5714_A0) {
2099 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, Value32 | MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS);
2100
2101 Value32 = LM_RegRdInd(pDevice, 0x6804);
2102 Value32 &= GRC_MISC_BD_ID_MASK;
2103
2104 if((Value32 == 0)||(Value32 == 0x8000)) {
2105 pDevice->ChipRevId = T3_CHIP_ID_5752_A0;
2106 }else{
2107 pDevice->ChipRevId = T3_CHIP_ID_5714_A0;
2108 }
2109
2110 Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
2111 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, Value32 & ~ MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS);
2112 }
2113
2114
2115 /* Get the cache line size. */
2116 MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
2117 pDevice->CacheLineSize = (LM_UINT8) Value32;
2118 pDevice->SavedCacheLineReg = Value32;
2119
2120 if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
2121 pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
2122 pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
2123 {
2124 pDevice->Flags &= ~UNDI_FIX_FLAG;
2125 }
2126 #ifndef PCIX_TARGET_WORKAROUND
2127 pDevice->Flags &= ~UNDI_FIX_FLAG;
2128 #endif
2129 /* Map the memory base to system address space. */
2130 if (!(pDevice->Flags & UNDI_FIX_FLAG))
2131 {
2132 Status = MM_MapMemBase(pDevice);
2133 if(Status != LM_STATUS_SUCCESS)
2134 {
2135 return Status;
2136 }
2137 /* Initialize the memory view pointer. */
2138 pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
2139 }
2140
2141 if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) ||
2142 (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
2143 {
2144 pDevice->Flags |= TX_4G_WORKAROUND_FLAG;
2145 }
2146 if ( (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
2147 (pDevice->Flags == PCI_EXPRESS_FLAG))
2148 {
2149 pDevice->Flags |= REG_RD_BACK_FLAG;
2150 }
2151
2152 if(pDevice->ChipRevId==T3_CHIP_ID_5750_A0)
2153 return LM_STATUS_UNKNOWN_ADAPTER;
2154
2155 #ifdef PCIX_TARGET_WORKAROUND
2156 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
2157 if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
2158 {
2159 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
2160 {
2161 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
2162 }
2163 }
2164 if (pDevice->Flags & UNDI_FIX_FLAG)
2165 {
2166 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
2167 }
2168 #endif
2169 /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
2170 /* management register may be clobbered which may cause the */
2171 /* BCM5700 to go into D3 state. While in this state, we will */
2172 /* need to restore the device to D0 state. */
2173 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
2174 Value32 |= T3_PM_PME_ASSERTED;
2175 Value32 &= ~T3_PM_POWER_STATE_MASK;
2176 Value32 |= T3_PM_POWER_STATE_D0;
2177 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
2178
2179 /* read the current PCI command word */
2180 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
2181
2182 /* Make sure bus-mastering is enabled. */
2183 Value32 |= PCI_BUSMASTER_ENABLE;
2184
2185 #ifdef PCIX_TARGET_WORKAROUND
2186 /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
2187 are enabled */
2188 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG) {
2189 Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
2190 PCI_PARITY_ERROR_ENABLE);
2191 }
2192 if (pDevice->Flags & UNDI_FIX_FLAG)
2193 {
2194 Value32 &= ~PCI_MEM_SPACE_ENABLE;
2195 }
2196
2197 #endif
2198
2199 if (pDevice->Flags & ENABLE_MWI_FLAG)
2200 {
2201 Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
2202 }
2203 else {
2204 Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
2205 }
2206
2207 /* save the value we are going to write into the PCI command word */
2208 pDevice->PciCommandStatusWords = Value32;
2209
2210 Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
2211 if(Status != LM_STATUS_SUCCESS)
2212 {
2213 return Status;
2214 }
2215
2216 /* Setup the mode registers. */
2217 pDevice->MiscHostCtrl =
2218 MISC_HOST_CTRL_MASK_PCI_INT |
2219 MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
2220 #ifdef BIG_ENDIAN_HOST
2221 MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
2222 #endif /* BIG_ENDIAN_HOST */
2223 MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
2224 MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
2225 /* write to PCI misc host ctr first in order to enable indirect accesses */
2226 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
2227
2228 /* Set power state to D0. */
2229 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
2230
2231 /* Preserve HOST_STACK_UP bit in case ASF firmware is running */
2232 Value32 = REG_RD(pDevice, Grc.Mode) & GRC_MODE_HOST_STACK_UP;
2233 #ifdef BIG_ENDIAN_HOST
2234 Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2235 GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
2236 #else
2237 Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
2238 #endif
2239 REG_WR(pDevice, Grc.Mode, Value32);
2240
2241 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2242 {
2243 REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
2244 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
2245 REG_RD_BACK(pDevice, Grc.LocalCtrl);
2246 }
2247 MM_Wait(40);
2248
2249 /* Enable memory arbiter*/
2250 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
2251 {
2252 Value32 = REG_RD(pDevice,MemArbiter.Mode);
2253 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE | Value32);
2254 }
2255 else
2256 {
2257 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
2258 }
2259
2260
2261 LM_SwitchClocks(pDevice);
2262
2263 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
2264
2265 /* Check to see if PXE ran and did not shutdown properly */
2266 if ((REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE) ||
2267 !(REG_RD(pDevice, PciCfg.MiscHostCtrl) & MISC_HOST_CTRL_MASK_PCI_INT))
2268 {
2269 LM_DisableInterrupt(pDevice);
2270 /* assume ASF is enabled */
2271 pDevice->AsfFlags = ASF_ENABLED;
2272 if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
2273 {
2274 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
2275 }
2276 LM_ShutdownChip(pDevice, LM_SHUTDOWN_RESET);
2277 pDevice->AsfFlags = 0;
2278 }
2279 #ifdef PCIX_TARGET_WORKAROUND
2280 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
2281 if (!(pDevice->Flags & ENABLE_PCIX_FIX_FLAG) &&
2282 ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
2283 {
2284 if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
2285 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
2286 pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
2287 pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
2288 {
2289 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300]), 0);
2290 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]), 0);
2291 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]),
2292 0xffffffff);
2293 if (MM_MEMREADL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
2294 {
2295 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
2296 }
2297 }
2298 }
2299 #endif
2300
2301 LM_NVRAM_Init(pDevice);
2302
2303 Status = LM_STATUS_FAILURE;
2304
2305 /* BCM4785: Use the MAC address stored in the main flash. */
2306 if (pDevice->Flags & SB_CORE_FLAG) {
2307 bcm_ether_atoe(getvar(NULL, "et0macaddr"), (struct ether_addr *)pDevice->NodeAddress);
2308 Status = LM_STATUS_SUCCESS;
2309 } else {
2310 /* Get the node address. First try to get in from the shared memory. */
2311 /* If the signature is not present, then get it from the NVRAM. */
2312 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
2313 if((Value32 >> 16) == 0x484b)
2314 {
2315 int i;
2316
2317 pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
2318 pDevice->NodeAddress[1] = (LM_UINT8) Value32;
2319
2320 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
2321
2322 pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
2323 pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
2324 pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
2325 pDevice->NodeAddress[5] = (LM_UINT8) Value32;
2326
2327 /* Check for null MAC address which can happen with older boot code */
2328 for (i = 0; i < 6; i++)
2329 {
2330 if (pDevice->NodeAddress[i] != 0)
2331 {
2332 Status = LM_STATUS_SUCCESS;
2333 break;
2334 }
2335 }
2336 }
2337 }
2338
2339 if (Status != LM_STATUS_SUCCESS)
2340 {
2341 int MacOffset;
2342
2343 MacOffset = 0x7c;
2344 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
2345 (T3_ASIC_5714_FAMILY(pDevice->ChipRevId)) )
2346 {
2347 if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
2348 {
2349 MacOffset = 0xcc;
2350 }
2351 /* the boot code is not running */
2352 if (LM_NVRAM_AcquireLock(pDevice) != LM_STATUS_SUCCESS)
2353 {
2354 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
2355 }
2356 else
2357 {
2358 LM_NVRAM_ReleaseLock(pDevice);
2359 }
2360 }
2361
2362 Status = LM_NvramRead(pDevice, MacOffset, &Value32);
2363 if(Status == LM_STATUS_SUCCESS)
2364 {
2365 LM_UINT8 *c = (LM_UINT8 *) &Value32;
2366
2367 pDevice->NodeAddress[0] = c[2];
2368 pDevice->NodeAddress[1] = c[3];
2369
2370 Status = LM_NvramRead(pDevice, MacOffset + 4, &Value32);
2371
2372 c = (LM_UINT8 *) &Value32;
2373 pDevice->NodeAddress[2] = c[0];
2374 pDevice->NodeAddress[3] = c[1];
2375 pDevice->NodeAddress[4] = c[2];
2376 pDevice->NodeAddress[5] = c[3];
2377 }
2378 }
2379
2380 if(Status != LM_STATUS_SUCCESS)
2381 {
2382 Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].High);
2383 pDevice->NodeAddress[0] = (Value32 >> 8) & 0xff;
2384 pDevice->NodeAddress[1] = Value32 & 0xff;
2385 Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].Low);
2386 pDevice->NodeAddress[2] = (Value32 >> 24) & 0xff;
2387 pDevice->NodeAddress[3] = (Value32 >> 16) & 0xff;
2388 pDevice->NodeAddress[4] = (Value32 >> 8) & 0xff;
2389 pDevice->NodeAddress[5] = Value32 & 0xff;
2390 B57_ERR(("WARNING: Cannot get MAC addr from NVRAM, using %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2391 pDevice->NodeAddress[0], pDevice->NodeAddress[1],
2392 pDevice->NodeAddress[2], pDevice->NodeAddress[3],
2393 pDevice->NodeAddress[4], pDevice->NodeAddress[5]));
2394 }
2395
2396 memcpy(pDevice->PermanentNodeAddress, pDevice->NodeAddress, 6);
2397
2398 /* Initialize the default values. */
2399 pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
2400 pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
2401 pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
2402 pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
2403 pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
2404 pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
2405 pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
2406 pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
2407 pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
2408 pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
2409 pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
2410 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
2411 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
2412 pDevice->DisableAutoNeg = FALSE;
2413 pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
2414 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
2415
2416 pDevice->PhyFlags = 0;
2417
2418 if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
2419 pDevice->Flags |= DELAY_PCI_GRANT_FLAG;
2420
2421 pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO;
2422 pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
2423 pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
2424 pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
2425 #ifdef INCLUDE_TBI_SUPPORT
2426 pDevice->TbiFlags = 0;
2427 pDevice->IgnoreTbiLinkChange = FALSE;
2428 #endif
2429 #ifdef INCLUDE_TCP_SEG_SUPPORT
2430 pDevice->LargeSendMaxSize = T3_TCP_SEG_MAX_OFFLOAD_SIZE;
2431 pDevice->LargeSendMinNumSeg = T3_TCP_SEG_MIN_NUM_SEG;
2432 #endif
2433
2434 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2435 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
2436 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
2437 {
2438 pDevice->PhyFlags |= PHY_RESET_ON_LINKDOWN;
2439 pDevice->PhyFlags |= PHY_CHECK_TAPS_AFTER_RESET;
2440 }
2441 if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5703_AX) ||
2442 (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
2443 {
2444 pDevice->PhyFlags |= PHY_ADC_FIX;
2445 }
2446 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2447 {
2448 pDevice->PhyFlags |= PHY_5704_A0_FIX;
2449 }
2450 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
2451 {
2452 pDevice->PhyFlags |= PHY_5705_5750_FIX;
2453 }
2454 /* Ethernet@Wirespeed is supported on 5701,5702,5703,5704,5705a0,5705a1 */
2455 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
2456 !((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
2457 (pDevice->ChipRevId != T3_CHIP_ID_5705_A0) &&
2458 (pDevice->ChipRevId != T3_CHIP_ID_5705_A1)))
2459 {
2460 pDevice->PhyFlags |= PHY_ETHERNET_WIRESPEED;
2461 }
2462
2463 switch (T3_ASIC_REV(pDevice->ChipRevId))
2464 {
2465 case T3_ASIC_REV_5704:
2466 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
2467 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
2468 break;
2469 default:
2470 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
2471 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
2472 break;
2473 }
2474
2475 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
2476 pDevice->QueueRxPackets = TRUE;
2477
2478 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2479
2480 if(T3_ASIC_IS_JUMBO_CAPABLE(pDevice->ChipRevId)){
2481 if( ! T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
2482 pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
2483 pDevice->Flags |= JUMBO_CAPABLE_FLAG;
2484 }
2485
2486 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2487
2488 pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
2489
2490 if(((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
2491 ((pDevice->BondId == 0x10000) || (pDevice->BondId == 0x18000))) ||
2492 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) &&
2493 ((pDevice->BondId == 0x14000) || (pDevice->BondId == 0x1c000))))
2494 {
2495 return LM_STATUS_UNKNOWN_ADAPTER;
2496 }
2497 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
2498 {
2499 if ((pDevice->BondId == 0x8000) || (pDevice->BondId == 0x4000))
2500 {
2501 pDevice->PhyFlags |= PHY_NO_GIGABIT;
2502 }
2503 }
2504 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
2505 {
2506 if ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
2507 (pDevice->BondId == GRC_MISC_BD_ID_5788M))
2508 {
2509 pDevice->Flags |= BCM5788_FLAG;
2510 }
2511
2512 if ((pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901)) ||
2513 (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901A2)) ||
2514 (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5705F)))
2515 {
2516 pDevice->PhyFlags |= PHY_NO_GIGABIT;
2517 }
2518 }
2519
2520 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
2521 {
2522 if ( (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5751F))||
2523 (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5753F)))
2524 {
2525 pDevice->PhyFlags |= PHY_NO_GIGABIT;
2526 }
2527 }
2528
2529 /* CIOBE multisplit has a bug */
2530
2531 /* Get Eeprom info. */
2532 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
2533 if (Value32 == T3_NIC_DATA_SIG)
2534 {
2535 EeSigFound = TRUE;
2536 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
2537
2538 /* For now the 5753 cannot drive gpio2 or ASF will blow */
2539 if(Value32 & T3_NIC_GPIO2_NOT_AVAILABLE)
2540 {
2541 pDevice->Flags |= GPIO2_DONOT_OUTPUT;
2542 }
2543
2544 if (Value32 & T3_NIC_MINI_PCI)
2545 {
2546 pDevice->Flags |= MINI_PCI_FLAG;
2547 }
2548 /* Determine PHY type. */
2549 switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
2550 {
2551 case T3_NIC_CFG_PHY_TYPE_COPPER:
2552 EePhyTypeSerdes = FALSE;
2553 break;
2554
2555 case T3_NIC_CFG_PHY_TYPE_FIBER:
2556 EePhyTypeSerdes = TRUE;
2557 break;
2558
2559 default:
2560 EePhyTypeSerdes = FALSE;
2561 break;
2562 }
2563
2564 if ( T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
2565 {
2566 LedCfg = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2);
2567 LedCfg = LedCfg & (T3_NIC_CFG_LED_MODE_MASK |
2568 T3_SHASTA_EXT_LED_MODE_MASK);
2569 }
2570 else
2571 {
2572 /* Determine PHY led mode. for legacy devices */
2573 LedCfg = Value32 & T3_NIC_CFG_LED_MODE_MASK;
2574 }
2575
2576 switch (LedCfg)
2577 {
2578 default:
2579 case T3_NIC_CFG_LED_PHY_MODE_1:
2580 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
2581 break;
2582
2583 case T3_NIC_CFG_LED_PHY_MODE_2:
2584 pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
2585 break;
2586
2587 case T3_NIC_CFG_LED_MAC_MODE:
2588 pDevice->LedCtrl = LED_CTRL_MAC_MODE;
2589 break;
2590
2591 case T3_SHASTA_EXT_LED_SHARED_TRAFFIC_LINK_MODE:
2592 pDevice->LedCtrl = LED_CTRL_SHARED_TRAFFIC_LINK;
2593 if ((pDevice->ChipRevId != T3_CHIP_ID_5750_A0) &&
2594 (pDevice->ChipRevId != T3_CHIP_ID_5750_A1))
2595 {
2596 pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
2597 LED_CTRL_PHY_MODE_2;
2598 }
2599 break;
2600
2601 case T3_SHASTA_EXT_LED_MAC_MODE:
2602 pDevice->LedCtrl = LED_CTRL_SHASTA_MAC_MODE;
2603 break;
2604
2605 case T3_SHASTA_EXT_LED_WIRELESS_COMBO_MODE:
2606 pDevice->LedCtrl = LED_CTRL_WIRELESS_COMBO;
2607 if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
2608 {
2609 pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
2610 LED_CTRL_PHY_MODE_2;
2611 }
2612 break;
2613
2614 }
2615
2616 if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2617 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)) &&
2618 (pDevice->SubsystemVendorId == T3_SVID_DELL))
2619 {
2620 pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
2621 }
2622
2623 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2624 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
2625 (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId)) )
2626 {
2627 /* Enable EEPROM write protection. */
2628 if(Value32 & T3_NIC_EEPROM_WP)
2629 {
2630 pDevice->Flags |= EEPROM_WP_FLAG;
2631 }
2632 }
2633 pDevice->AsfFlags = 0;
2634 #ifdef BCM_ASF
2635 if (Value32 & T3_NIC_CFG_ENABLE_ASF)
2636 {
2637 pDevice->AsfFlags |= ASF_ENABLED;
2638 if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
2639 {
2640 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
2641 }
2642 }
2643 #endif
2644 if (Value32 & T3_NIC_FIBER_WOL_CAPABLE)
2645 {
2646 pDevice->Flags |= FIBER_WOL_CAPABLE_FLAG;
2647 }
2648 if (Value32 & T3_NIC_WOL_LIMIT_10)
2649 {
2650 pDevice->Flags |= WOL_LIMIT_10MBPS_FLAG;
2651 }
2652
2653 /* Get the PHY Id. */
2654 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
2655 if (Value32)
2656 {
2657 EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
2658 PHY_ID1_OUI_MASK) << 10;
2659
2660 Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
2661
2662 EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
2663 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
2664 }
2665 else
2666 {
2667 EePhyId = 0;
2668 if (!EePhyTypeSerdes && !(pDevice->AsfFlags & ASF_ENABLED))
2669 {
2670 /* reset PHY if boot code couldn't read the PHY ID */
2671 LM_ResetPhy(pDevice);
2672 }
2673 }
2674
2675 Ver = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_VER);
2676 Ver >>= T3_NIC_DATA_VER_SHIFT;
2677
2678 Value32 = 0;
2679 if((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
2680 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) &&
2681 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5703) &&
2682 (Ver > 0) && (Ver < 0x100)){
2683
2684 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2);
2685
2686 if (Value32 & T3_NIC_CFG_CAPACITIVE_COUPLING)
2687 {
2688 pDevice->PhyFlags |= PHY_CAPACITIVE_COUPLING;
2689 }
2690
2691 if (Value32 & T3_NIC_CFG_PRESERVE_PREEMPHASIS)
2692 {
2693 pDevice->TbiFlags |= TBI_DO_PREEMPHASIS;
2694 }
2695
2696 }
2697
2698 }
2699 else
2700 {
2701 EeSigFound = FALSE;
2702 }
2703
2704 /* Set the PHY address. */
2705 pDevice->PhyAddr = PHY_DEVICE_ID;
2706
2707 /* Disable auto polling. */
2708 pDevice->MiMode = 0xc0000;
2709 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
2710 REG_RD_BACK(pDevice, MacCtrl.MiMode);
2711 MM_Wait(80);
2712
2713 if (pDevice->AsfFlags & ASF_ENABLED)
2714 {
2715 /* Reading PHY registers will contend with ASF */
2716 pDevice->PhyId = 0;
2717 }
2718 else
2719 {
2720 /* Get the PHY id. */
2721 LM_GetPhyId(pDevice);
2722 }
2723
2724 /* Set the EnableTbi flag to false if we have a copper PHY. */
2725 switch(pDevice->PhyId & PHY_ID_MASK)
2726 {
2727 case PHY_BCM5400_PHY_ID:
2728 case PHY_BCM5401_PHY_ID:
2729 case PHY_BCM5411_PHY_ID:
2730 case PHY_BCM5461_PHY_ID:
2731 case PHY_BCM5701_PHY_ID:
2732 case PHY_BCM5703_PHY_ID:
2733 case PHY_BCM5704_PHY_ID:
2734 case PHY_BCM5705_PHY_ID:
2735 case PHY_BCM5750_PHY_ID:
2736 break;
2737 case PHY_BCM5714_PHY_ID:
2738 case PHY_BCM5780_PHY_ID:
2739 if(EePhyTypeSerdes == TRUE)
2740 {
2741 pDevice->PhyFlags |= PHY_IS_FIBER;
2742 }
2743 break;
2744 case PHY_BCM5752_PHY_ID:
2745 break;
2746
2747 case PHY_BCM8002_PHY_ID:
2748 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
2749 break;
2750
2751 default:
2752
2753 if (EeSigFound)
2754 {
2755 pDevice->PhyId = EePhyId;
2756
2757 if (EePhyTypeSerdes && ((pDevice->PhyId == PHY_BCM5780_PHY_ID)) )
2758 {
2759 pDevice->PhyFlags |= PHY_IS_FIBER;
2760 }
2761 else if (EePhyTypeSerdes)
2762 {
2763 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
2764 }
2765 }
2766 else if ((pAdapterInfo = LM_GetAdapterInfoBySsid(
2767 pDevice->SubsystemVendorId,
2768 pDevice->SubsystemId)))
2769 {
2770 pDevice->PhyId = pAdapterInfo->PhyId;
2771 if (pAdapterInfo->Serdes)
2772 {
2773 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
2774 }
2775 }
2776 else
2777 {
2778 if (UNKNOWN_PHY_ID(pDevice->PhyId))
2779 {
2780 LM_ResetPhy(pDevice);
2781 LM_GetPhyId(pDevice);
2782 }
2783 }
2784 break;
2785 }
2786
2787 if(UNKNOWN_PHY_ID(pDevice->PhyId) &&
2788 !(pDevice->TbiFlags & ENABLE_TBI_FLAG))
2789 {
2790 if (pDevice->Flags & ROBO_SWITCH_FLAG) {
2791 B57_ERR(("PHY ID unknown, assume it is a copper PHY.\n"));
2792 } else {
2793 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
2794 B57_ERR(("PHY ID unknown, assume it is SerDes\n"));
2795 }
2796 }
2797
2798 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
2799 {
2800 if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
2801 {
2802 pDevice->SavedCacheLineReg &= 0xffff00ff;
2803 pDevice->SavedCacheLineReg |= 0x4000;
2804 }
2805 }
2806
2807 pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
2808 LM_ACCEPT_UNICAST;
2809
2810 pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
2811 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM | LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |
2812 LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;
2813
2814 if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
2815 {
2816 pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
2817 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
2818 }
2819
2820 #ifdef INCLUDE_TCP_SEG_SUPPORT
2821 pDevice->TaskOffloadCap |= LM_TASK_OFFLOAD_TCP_SEGMENTATION;
2822
2823 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
2824 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
2825 (pDevice->ChipRevId == T3_CHIP_ID_5705_A0))
2826 {
2827 pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
2828 }
2829 #endif
2830
2831 #ifdef BCM_ASF
2832 if (pDevice->AsfFlags & ASF_ENABLED)
2833 {
2834 if (!T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
2835 {
2836 pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
2837 }
2838 }
2839 #endif
2840
2841 /* Change driver parameters. */
2842 Status = MM_GetConfig(pDevice);
2843 if(Status != LM_STATUS_SUCCESS)
2844 {
2845 return Status;
2846 }
2847
2848 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
2849 {
2850 pDevice->Flags &= ~NIC_SEND_BD_FLAG;
2851 }
2852
2853 /* Save the current phy link status. */
2854 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
2855 !(pDevice->AsfFlags & ASF_ENABLED))
2856 {
2857 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
2858 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
2859
2860 /* If we don't have link reset the PHY. */
2861 if(!(Value32 & PHY_STATUS_LINK_PASS) ||
2862 (pDevice->PhyFlags & PHY_RESET_ON_INIT))
2863 {
2864
2865 LM_ResetPhy(pDevice);
2866
2867 if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
2868 {
2869 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
2870 PHY_AN_AD_ALL_SPEEDS;
2871 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
2872 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
2873
2874 if(!(pDevice->PhyFlags & PHY_NO_GIGABIT))
2875 Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS ;
2876 else
2877 Value32 =0;
2878
2879 #ifdef INCLUDE_5701_AX_FIX
2880 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
2881 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
2882 {
2883 Value32 |= BCM540X_CONFIG_AS_MASTER |
2884 BCM540X_ENABLE_CONFIG_AS_MASTER;
2885 }
2886 #endif
2887 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
2888
2889 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
2890 PHY_CTRL_RESTART_AUTO_NEG);
2891 }
2892
2893 }
2894 LM_SetEthWireSpeed(pDevice);
2895
2896 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &pDevice->advertising);
2897 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG,
2898 &pDevice->advertising1000);
2899
2900 }
2901 /* Currently 5401 phy only */
2902 LM_PhyTapPowerMgmt(pDevice);
2903
2904 #ifdef INCLUDE_TBI_SUPPORT
2905 if(pDevice->TbiFlags & ENABLE_TBI_FLAG)
2906 {
2907 if (!(pDevice->Flags & FIBER_WOL_CAPABLE_FLAG))
2908 {
2909 pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
2910 }
2911 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
2912 if (pDevice->TbiFlags & TBI_PURE_POLLING_FLAG)
2913 {
2914 pDevice->IgnoreTbiLinkChange = TRUE;
2915 }
2916 }
2917 else
2918 {
2919 pDevice->TbiFlags = 0;
2920 }
2921
2922 #endif /* INCLUDE_TBI_SUPPORT */
2923
2924 /* UseTaggedStatus is only valid for 5701 and later. */
2925 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
2926 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
2927 ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
2928 (pDevice->BondId == GRC_MISC_BD_ID_5788M))))
2929 {
2930 pDevice->Flags &= ~USE_TAGGED_STATUS_FLAG;
2931 pDevice->CoalesceMode = 0;
2932 }
2933 else
2934 {
2935 pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
2936 HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
2937 }
2938
2939 /* Set the status block size. */
2940 if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
2941 T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
2942 {
2943 pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
2944 }
2945
2946 /* Check the DURING_INT coalescing ticks parameters. */
2947 if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
2948 {
2949 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
2950 {
2951 pDevice->RxCoalescingTicksDuringInt =
2952 DEFAULT_RX_COALESCING_TICKS_DURING_INT;
2953 }
2954
2955 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
2956 {
2957 pDevice->TxCoalescingTicksDuringInt =
2958 DEFAULT_TX_COALESCING_TICKS_DURING_INT;
2959 }
2960
2961 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
2962 {
2963 pDevice->RxMaxCoalescedFramesDuringInt =
2964 DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
2965 }
2966
2967 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
2968 {
2969 pDevice->TxMaxCoalescedFramesDuringInt =
2970 DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
2971 }
2972 }
2973 else
2974 {
2975 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
2976 {
2977 pDevice->RxCoalescingTicksDuringInt = 0;
2978 }
2979
2980 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
2981 {
2982 pDevice->TxCoalescingTicksDuringInt = 0;
2983 }
2984
2985 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
2986 {
2987 pDevice->RxMaxCoalescedFramesDuringInt = 0;
2988 }
2989
2990 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
2991 {
2992 pDevice->TxMaxCoalescedFramesDuringInt = 0;
2993 }
2994 }
2995
2996 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2997 if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
2998 {
2999 pDevice->RxJumboDescCnt = 0;
3000 if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
3001 {
3002 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
3003 }
3004 }
3005 else if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
3006 {
3007 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
3008 pDevice->RxJumboDescCnt = 0;
3009 }
3010 else
3011 {
3012 pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
3013 COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
3014
3015 if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
3016 {
3017 pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
3018 pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
3019 }
3020 pDevice->TxMtu = pDevice->RxMtu;
3021 }
3022 #else
3023 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
3024 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3025
3026 pDevice->RxPacketDescCnt =
3027 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3028 pDevice->RxJumboDescCnt +
3029 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3030 pDevice->RxStdDescCnt;
3031
3032 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
3033 {
3034 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
3035 }
3036
3037 if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
3038 {
3039 pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
3040 }
3041
3042 /* Configure the proper ways to get link change interrupt. */
3043 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
3044 {
3045 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3046 {
3047 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
3048 }
3049 else
3050 {
3051 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
3052 }
3053 }
3054 else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
3055 {
3056 /* Auto-polling does not work on 5700_AX and 5700_BX. */
3057 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3058 {
3059 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
3060 }
3061 }
3062
3063 /* Determine the method to get link change status. */
3064 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
3065 {
3066 /* The link status bit in the status block does not work on 5700_AX */
3067 /* and 5700_BX chips. */
3068 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3069 {
3070 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
3071 }
3072 else
3073 {
3074 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
3075 }
3076 }
3077
3078 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
3079 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3080 {
3081 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
3082 }
3083
3084 if (!EeSigFound)
3085 {
3086 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
3087 }
3088
3089 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
3090 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
3091 {
3092 /* bug? 5701 in LINK10 mode does not seem to work when */
3093 /* PhyIntMode is LINK_READY. */
3094 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
3095 #ifdef INCLUDE_TBI_SUPPORT
3096 !(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
3097 #endif
3098 pDevice->LedCtrl == LED_CTRL_PHY_MODE_2)
3099 {
3100 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
3101 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
3102 }
3103 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
3104 {
3105 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
3106 }
3107 }
3108
3109 #ifdef BCM_WOL
3110 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
3111 pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
3112 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
3113 pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
3114 {
3115 pDevice->WolSpeed = WOL_SPEED_10MB;
3116 }
3117 else
3118 {
3119 if (pDevice->Flags & WOL_LIMIT_10MBPS_FLAG)
3120 {
3121 pDevice->WolSpeed = WOL_SPEED_10MB;
3122 }
3123 else
3124 {
3125 pDevice->WolSpeed = WOL_SPEED_100MB;
3126 }
3127 }
3128 #endif
3129
3130 pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
3131
3132 pDevice->DmaReadFifoSize = 0;
3133 if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
3134 (pDevice->ChipRevId != T3_CHIP_ID_5705_A0)) ||
3135 T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId) )
3136 {
3137 #ifdef INCLUDE_TCP_SEG_SUPPORT
3138 if ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION) &&
3139 ((pDevice->ChipRevId == T3_CHIP_ID_5705_A1) ||
3140 (pDevice->ChipRevId == T3_CHIP_ID_5705_A2)))
3141 {
3142 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_SIZE_128;
3143 }
3144 else
3145 #endif
3146 {
3147 if (!(pDevice->PciState & T3_PCI_STATE_HIGH_BUS_SPEED) &&
3148 !(pDevice->Flags & BCM5788_FLAG) &&
3149 !(pDevice->Flags & PCI_EXPRESS_FLAG))
3150 {
3151 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
3152 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A1)
3153 {
3154 pDevice->Flags |= RX_BD_LIMIT_64_FLAG;
3155 }
3156 pDevice->Flags |= DMA_WR_MODE_RX_ACCELERATE_FLAG;
3157 }
3158 else if (pDevice->Flags & PCI_EXPRESS_FLAG)
3159 {
3160 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
3161 }
3162 }
3163 }
3164
3165 pDevice->Flags &= ~T3_HAS_TWO_CPUS;
3166 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
3167 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
3168 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 ||
3169 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3170 {
3171 pDevice->Flags |= T3_HAS_TWO_CPUS;
3172 }
3173
3174 return LM_STATUS_SUCCESS;
3175 } /* LM_GetAdapterInfo */
3176
3177 STATIC PLM_ADAPTER_INFO
3178 LM_GetAdapterInfoBySsid(
3179 LM_UINT16 Svid,
3180 LM_UINT16 Ssid)
3181 {
3182 static LM_ADAPTER_INFO AdapterArr[] =
3183 {
3184 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
3185 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
3186 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
3187 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
3188 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
3189 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
3190 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
3191 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
3192 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
3193 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5703_PHY_ID, 0},
3194 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5703_PHY_ID, 0},
3195
3196 { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
3197 { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
3198 { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
3199 { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
3200 { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
3201
3202 { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
3203 { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
3204 { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
3205 { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
3206
3207 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
3208 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
3209 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
3210 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
3211 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
3212
3213 { 0x1014, 0x0281, 0, 1 },
3214 };
3215 LM_UINT32 j;
3216
3217 for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
3218 {
3219 if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
3220 {
3221 return &AdapterArr[j];
3222 }
3223 }
3224
3225 return NULL;
3226 }
3227
3228
3229
3230 /******************************************************************************/
3231 /* Description: */
3232 /* This routine sets up receive/transmit buffer descriptions queues. */
3233 /* */
3234 /* Return: */
3235 /* LM_STATUS_SUCCESS */
3236 /******************************************************************************/
3237 LM_STATUS
3238 LM_InitializeAdapter(
3239 PLM_DEVICE_BLOCK pDevice)
3240 {
3241 LM_PHYSICAL_ADDRESS MemPhy;
3242 PLM_UINT8 pMemVirt;
3243 PLM_PACKET pPacket;
3244 LM_STATUS Status;
3245 LM_UINT32 Size;
3246 LM_UINT32 Value32, j;
3247 LM_UINT32 DmaWrCmd, DmaRdCmd, DmaWrBdry, DmaRdBdry;
3248
3249 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
3250 j = 0;
3251 while (((Value32 & 0x3ff) != (pDevice->PciCommandStatusWords & 0x3ff)) &&
3252 (j < 1000))
3253 {
3254 /* On PCIE devices, there are some rare cases where the device */
3255 /* is in the process of link-training at this point */
3256 MM_Wait(200);
3257 MM_WriteConfig32(pDevice, PCI_COMMAND_REG, pDevice->PciCommandStatusWords);
3258 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
3259 j++;
3260 }
3261 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
3262 /* Set power state to D0. */
3263 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
3264
3265 /* Intialize the queues. */
3266 QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
3267 MAX_RX_PACKET_DESC_COUNT);
3268 QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
3269 MAX_RX_PACKET_DESC_COUNT);
3270
3271 QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
3272 QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
3273
3274 if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
3275 {
3276 pDevice->RcvRetRcbEntryCount = 512;
3277 pDevice->RcvRetRcbEntryCountMask = 511;
3278 }
3279 else
3280 {
3281 pDevice->RcvRetRcbEntryCount = T3_RCV_RETURN_RCB_ENTRY_COUNT;
3282 pDevice->RcvRetRcbEntryCountMask = T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
3283 }
3284
3285 /* Allocate shared memory for: status block, the buffers for receive */
3286 /* rings -- standard, mini, jumbo, and return rings. */
3287 Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
3288 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
3289 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3290 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
3291 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3292 (pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
3293
3294 /* Memory for host based Send BD. */
3295 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3296 {
3297 Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
3298 }
3299
3300 /* Allocate the memory block. */
3301 Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
3302 if(Status != LM_STATUS_SUCCESS)
3303 {
3304 return Status;
3305 }
3306
3307 DmaWrCmd = DMA_CTRL_WRITE_CMD;
3308 DmaRdCmd = DMA_CTRL_READ_CMD;
3309 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_DISABLE;
3310 DmaRdBdry = DMA_CTRL_READ_BOUNDARY_DISABLE;
3311 #ifdef BCM_DISCONNECT_AT_CACHELINE
3312 /* This code is intended for PPC64 and other similar architectures */
3313 /* Only the following chips support this */
3314 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
3315 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
3316 (pDevice->Flags & PCI_EXPRESS_FLAG))
3317 {
3318 switch(pDevice->CacheLineSize * 4)
3319 {
3320 case 16:
3321 case 32:
3322 case 64:
3323 case 128:
3324 if (!(pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
3325 !(pDevice->Flags & PCI_EXPRESS_FLAG))
3326 {
3327 /* PCI-X */
3328 /* use 384 which is a multiple of 16,32,64,128 */
3329 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_384_PCIX;
3330 break;
3331 }
3332 else if (pDevice->Flags & PCI_EXPRESS_FLAG)
3333 {
3334 /* PCI Express */
3335 /* use 128 which is a multiple of 16,32,64,128 */
3336 DmaWrCmd = DMA_CTRL_WRITE_BOUNDARY_128_PCIE;
3337 break;
3338 }
3339 /* fall through */
3340 case 256:
3341 /* use 256 which is a multiple of 16,32,64,128,256 */
3342 if ((pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
3343 !(pDevice->Flags & PCI_EXPRESS_FLAG))
3344 {
3345 /* PCI */
3346 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256;
3347 }
3348 else if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
3349 {
3350 /* PCI-X */
3351 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256_PCIX;
3352 }
3353 break;
3354 }
3355 }
3356 #endif
3357 pDevice->DmaReadWriteCtrl = DmaWrCmd | DmaRdCmd | DmaWrBdry | DmaRdBdry;
3358 /* Program DMA Read/Write */
3359 if (pDevice->Flags & PCI_EXPRESS_FLAG)
3360 {
3361
3362 /* !=0 is 256 max or greater payload size so set water mark accordingly*/
3363 Value32 = (REG_RD(pDevice, PciCfg.DeviceCtrl) & MAX_PAYLOAD_SIZE_MASK);
3364 if (Value32)
3365 {
3366 pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_PCIE_H20MARK_256;
3367 }else
3368 {
3369 pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_PCIE_H20MARK_128;
3370 }
3371
3372 }
3373 else if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
3374 {
3375 if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3376 {
3377 pDevice->DmaReadWriteCtrl |= 0x003f0000;
3378 }
3379 else
3380 {
3381 pDevice->DmaReadWriteCtrl |= 0x003f000f;
3382 }
3383 }
3384 else /* pci-x */
3385 {
3386 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3387 {
3388 pDevice->DmaReadWriteCtrl |= 0x009f0000;
3389 }
3390
3391 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
3392 {
3393 pDevice->DmaReadWriteCtrl |= 0x009C0000;
3394 }
3395
3396 if( T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
3397 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 )
3398 {
3399 Value32 = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
3400 if ((Value32 == 0x6) || (Value32 == 0x7))
3401 {
3402 pDevice->Flags |= ONE_DMA_AT_ONCE_FLAG;
3403 }
3404 }
3405 else if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
3406 {
3407 pDevice->DmaReadWriteCtrl &= ~DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
3408 if( T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5780)
3409 pDevice->DmaReadWriteCtrl |= (BIT_20 | BIT_18 | DMA_CTRL_WRITE_ONE_DMA_AT_ONCE);
3410 else
3411 pDevice->DmaReadWriteCtrl |= (BIT_20 | BIT_18 | BIT_15);
3412 /* bit 15 is the current CQ 13140 Fix */
3413 }
3414 else
3415 {
3416 pDevice->DmaReadWriteCtrl |= 0x001b000f;
3417 }
3418 }
3419 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
3420 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
3421 {
3422 pDevice->DmaReadWriteCtrl &= 0xfffffff0;
3423 }
3424
3425 if (pDevice->Flags & ONE_DMA_AT_ONCE_FLAG)
3426 {
3427 pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
3428 }
3429
3430 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
3431
3432 LM_SwitchClocks(pDevice);
3433
3434 if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
3435 {
3436 return LM_STATUS_FAILURE;
3437 }
3438
3439 /* Status block. */
3440 pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
3441 pDevice->StatusBlkPhy = MemPhy;
3442 pMemVirt += T3_STATUS_BLOCK_SIZE;
3443 LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
3444
3445 /* Statistics block. */
3446 pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
3447 pDevice->StatsBlkPhy = MemPhy;
3448 pMemVirt += sizeof(T3_STATS_BLOCK);
3449 LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
3450
3451 /* Receive standard BD buffer. */
3452 pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
3453 pDevice->RxStdBdPhy = MemPhy;
3454
3455 pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
3456 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
3457 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
3458
3459 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3460 /* Receive jumbo BD buffer. */
3461 pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
3462 pDevice->RxJumboBdPhy = MemPhy;
3463
3464 pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
3465 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
3466 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
3467 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3468
3469 /* Receive return BD buffer. */
3470 pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
3471 pDevice->RcvRetBdPhy = MemPhy;
3472
3473 pMemVirt += pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD);
3474 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
3475 pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
3476
3477 /* Set up Send BD. */
3478 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3479 {
3480 pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
3481 pDevice->SendBdPhy = MemPhy;
3482
3483 pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
3484 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
3485 sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
3486 }
3487 #ifdef BCM_NIC_SEND_BD
3488 else
3489 {
3490 pDevice->pSendBdVirt = (PT3_SND_BD)
3491 pDevice->pMemView->uIntMem.First32k.BufferDesc;
3492 pDevice->SendBdPhy.High = 0;
3493 pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
3494 }
3495 #endif
3496
3497 /* Allocate memory for packet descriptors. */
3498 Size = (pDevice->RxPacketDescCnt +
3499 pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
3500 Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
3501 if(Status != LM_STATUS_SUCCESS)
3502 {
3503 return Status;
3504 }
3505 pDevice->pPacketDescBase = (PLM_VOID) pPacket;
3506
3507 /* Create transmit packet descriptors from the memory block and add them */
3508 /* to the TxPacketFreeQ for each send ring. */
3509 for(j = 0; j < pDevice->TxPacketDescCnt; j++)
3510 {
3511 /* Ring index. */
3512 pPacket->Flags = 0;
3513
3514 /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
3515 QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
3516
3517 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
3518 /* is the total size of the packet descriptor including the */
3519 /* os-specific extensions in the UM_PACKET structure. */
3520 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
3521 } /* for(j.. */
3522
3523 /* Create receive packet descriptors from the memory block and add them */
3524 /* to the RxPacketFreeQ. Create the Standard packet descriptors. */
3525 for(j = 0; j < pDevice->RxStdDescCnt; j++)
3526 {
3527 /* Receive producer ring. */
3528 pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
3529
3530 /* Receive buffer size. */
3531 if (T3_ASIC_5714_FAMILY(pDevice->ChipRevId) &&
3532 (pDevice->RxJumboBufferSize) )
3533 {
3534 pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
3535 }else{
3536 pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
3537 }
3538
3539 /* Add the descriptor to RxPacketFreeQ. */
3540 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3541
3542 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
3543 /* is the total size of the packet descriptor including the */
3544 /* os-specific extensions in the UM_PACKET structure. */
3545 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
3546 } /* for */
3547
3548
3549 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3550 /* Create the Jumbo packet descriptors. */
3551 for(j = 0; j < pDevice->RxJumboDescCnt; j++)
3552 {
3553 /* Receive producer ring. */
3554 pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
3555
3556 /* Receive buffer size. */
3557 pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
3558
3559 /* Add the descriptor to RxPacketFreeQ. */
3560 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3561
3562 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
3563 /* is the total size of the packet descriptor including the */
3564 /* os-specific extensions in the UM_PACKET structure. */
3565 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
3566 } /* for */
3567 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3568
3569 /* Initialize the rest of the packet descriptors. */
3570 Status = MM_InitializeUmPackets(pDevice);
3571 if(Status != LM_STATUS_SUCCESS)
3572 {
3573 return Status;
3574 } /* if */
3575
3576 /* Default receive mask. */
3577 pDevice->ReceiveMask &= LM_KEEP_VLAN_TAG;
3578 pDevice->ReceiveMask |= LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
3579 LM_ACCEPT_UNICAST;
3580
3581 /* Make sure we are in the first 32k memory window or NicSendBd. */
3582 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
3583
3584 /* Initialize the hardware. */
3585 Status = LM_ResetAdapter(pDevice);
3586 if(Status != LM_STATUS_SUCCESS)
3587 {
3588 return Status;
3589 }
3590
3591 /* We are done with initialization. */
3592 pDevice->InitDone = TRUE;
3593
3594 return LM_STATUS_SUCCESS;
3595 } /* LM_InitializeAdapter */
3596
3597
3598 LM_STATUS
3599 LM_DisableChip(PLM_DEVICE_BLOCK pDevice)
3600 {
3601 LM_UINT32 data;
3602
3603 pDevice->RxMode &= ~RX_MODE_ENABLE;
3604 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
3605 if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
3606 {
3607 MM_Wait(20);
3608 }
3609 data = REG_RD(pDevice, RcvBdIn.Mode);
3610 data &= ~RCV_BD_IN_MODE_ENABLE;
3611 REG_WR(pDevice, RcvBdIn.Mode,data);
3612 if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
3613 {
3614 MM_Wait(20);
3615 }
3616 data = REG_RD(pDevice, RcvListPlmt.Mode);
3617 data &= ~RCV_LIST_PLMT_MODE_ENABLE;
3618 REG_WR(pDevice, RcvListPlmt.Mode,data);
3619 if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
3620 {
3621 MM_Wait(20);
3622 }
3623 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3624 {
3625 data = REG_RD(pDevice, RcvListSel.Mode);
3626 data &= ~RCV_LIST_SEL_MODE_ENABLE;
3627 REG_WR(pDevice, RcvListSel.Mode,data);
3628 if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
3629 {
3630 MM_Wait(20);
3631 }
3632 }
3633 data = REG_RD(pDevice, RcvDataBdIn.Mode);
3634 data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
3635 REG_WR(pDevice, RcvDataBdIn.Mode,data);
3636 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
3637 {
3638 MM_Wait(20);
3639 }
3640 data = REG_RD(pDevice, RcvDataComp.Mode);
3641 data &= ~RCV_DATA_COMP_MODE_ENABLE;
3642 REG_WR(pDevice, RcvDataComp.Mode,data);
3643 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
3644 {
3645 MM_Wait(20);
3646 }
3647 data = REG_RD(pDevice, RcvBdComp.Mode);
3648 data &= ~RCV_BD_COMP_MODE_ENABLE;
3649 REG_WR(pDevice, RcvBdComp.Mode,data);
3650 if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
3651 {
3652 MM_Wait(20);
3653 }
3654 data = REG_RD(pDevice, SndBdSel.Mode);
3655 data &= ~SND_BD_SEL_MODE_ENABLE;
3656 REG_WR(pDevice, SndBdSel.Mode, data);
3657 if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
3658 {
3659 MM_Wait(20);
3660 }
3661 data = REG_RD(pDevice, SndBdIn.Mode);
3662 data &= ~SND_BD_IN_MODE_ENABLE;
3663 REG_WR(pDevice, SndBdIn.Mode, data);
3664 if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
3665 {
3666 MM_Wait(20);
3667 }
3668 data = REG_RD(pDevice, SndDataIn.Mode);
3669 data &= ~T3_SND_DATA_IN_MODE_ENABLE;
3670 REG_WR(pDevice, SndDataIn.Mode,data);
3671 if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
3672 {
3673 MM_Wait(20);
3674 }
3675 data = REG_RD(pDevice, DmaRead.Mode);
3676 data &= ~DMA_READ_MODE_ENABLE;
3677 REG_WR(pDevice, DmaRead.Mode, data);
3678 if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
3679 {
3680 MM_Wait(20);
3681 }
3682 data = REG_RD(pDevice, SndDataComp.Mode);
3683 data &= ~SND_DATA_COMP_MODE_ENABLE;
3684 REG_WR(pDevice, SndDataComp.Mode, data);
3685 if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
3686 {
3687 MM_Wait(20);
3688 }
3689
3690 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3691 {
3692 data = REG_RD(pDevice,DmaComp.Mode);
3693 data &= ~DMA_COMP_MODE_ENABLE;
3694 REG_WR(pDevice, DmaComp.Mode, data);
3695 if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
3696 {
3697 MM_Wait(20);
3698 }
3699 }
3700 data = REG_RD(pDevice, SndBdComp.Mode);
3701 data &= ~SND_BD_COMP_MODE_ENABLE;
3702 REG_WR(pDevice, SndBdComp.Mode, data);
3703 if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
3704 {
3705 MM_Wait(20);
3706 }
3707 /* Clear TDE bit */
3708 pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
3709 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
3710 pDevice->TxMode &= ~TX_MODE_ENABLE;
3711 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
3712 if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
3713 {
3714 MM_Wait(20);
3715 }
3716 data = REG_RD(pDevice, HostCoalesce.Mode);
3717 data &= ~HOST_COALESCE_ENABLE;
3718 REG_WR(pDevice, HostCoalesce.Mode, data);
3719 if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
3720 {
3721 MM_Wait(20);
3722 }
3723 data = REG_RD(pDevice, DmaWrite.Mode);
3724 data &= ~DMA_WRITE_MODE_ENABLE;
3725 REG_WR(pDevice, DmaWrite.Mode,data);
3726 if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
3727 {
3728 MM_Wait(20);
3729 }
3730
3731 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3732 {
3733 data = REG_RD(pDevice, MbufClusterFree.Mode);
3734 data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
3735 REG_WR(pDevice, MbufClusterFree.Mode,data);
3736 if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
3737 {
3738 MM_Wait(20);
3739 }
3740 }
3741 /* Reset all FTQs */
3742 REG_WR(pDevice, Ftq.Reset, 0xffffffff);
3743 REG_WR(pDevice, Ftq.Reset, 0x0);
3744
3745 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3746 {
3747 data = REG_RD(pDevice, BufMgr.Mode);
3748 data &= ~BUFMGR_MODE_ENABLE;
3749 REG_WR(pDevice, BufMgr.Mode,data);
3750 if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
3751 {
3752 MM_Wait(20);
3753 }
3754 data = REG_RD(pDevice, MemArbiter.Mode);
3755 data &= ~T3_MEM_ARBITER_MODE_ENABLE;
3756 REG_WR(pDevice, MemArbiter.Mode, data);
3757 if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
3758 {
3759 MM_Wait(20);
3760 }
3761 }
3762 return LM_STATUS_SUCCESS;
3763 }
3764
3765 LM_STATUS
3766 LM_DisableFW(PLM_DEVICE_BLOCK pDevice)
3767 {
3768 #ifdef BCM_ASF
3769 int j;
3770 LM_UINT32 Value32;
3771
3772 if (pDevice->AsfFlags & ASF_ENABLED)
3773 {
3774 MEM_WR_OFFSET(pDevice, T3_CMD_MAILBOX, T3_CMD_NICDRV_PAUSE_FW);
3775 Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
3776 REG_WR(pDevice, Grc.RxCpuEvent, Value32 | BIT_14);
3777 for (j = 0; j < 100; j++)
3778 {
3779 Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
3780 if (!(Value32 & BIT_14))
3781 {
3782 break;
3783 }
3784 MM_Wait(1);
3785 }
3786 }
3787 #endif
3788 return LM_STATUS_SUCCESS;
3789 }
3790
3791 /******************************************************************************/
3792 /* Description: */
3793 /* This function reinitializes the adapter. */
3794 /* */
3795 /* Return: */
3796 /* LM_STATUS_SUCCESS */
3797 /******************************************************************************/
3798 LM_STATUS
3799 LM_ResetAdapter(
3800 PLM_DEVICE_BLOCK pDevice)
3801 {
3802 LM_UINT32 Value32;
3803 LM_UINT32 j, k;
3804 int reset_count = 0;
3805
3806 /* Disable interrupt. */
3807 LM_DisableInterrupt(pDevice);
3808
3809 restart_reset:
3810 LM_DisableFW(pDevice);
3811
3812 /* May get a spurious interrupt */
3813 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
3814
3815 LM_WritePreResetSignatures(pDevice, LM_INIT_RESET);
3816 /* Disable transmit and receive DMA engines. Abort all pending requests. */
3817 if(pDevice->InitDone)
3818 {
3819 LM_Abort(pDevice);
3820 }
3821
3822 pDevice->ShuttingDown = FALSE;
3823
3824 LM_ResetChip(pDevice);
3825
3826 LM_WriteLegacySignatures(pDevice, LM_INIT_RESET);
3827
3828 /* Bug: Athlon fix for B3 silicon only. This bit does not do anything */
3829 /* in other chip revisions except 5750 */
3830 if ((pDevice->Flags & DELAY_PCI_GRANT_FLAG) &&
3831 !(pDevice->Flags & PCI_EXPRESS_FLAG))
3832 {
3833 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | BIT_31);
3834 }
3835
3836 if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
3837 {
3838 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
3839 {
3840 Value32 = REG_RD(pDevice, PciCfg.PciState);
3841 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
3842 REG_WR(pDevice, PciCfg.PciState, Value32);
3843 }
3844 }
3845 if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_BX)
3846 {
3847 /* New bits defined in register 0x64 to enable some h/w fixes */
3848 /* These new bits are 'write-only' */
3849 Value32 = REG_RD(pDevice, PciCfg.MsiData);
3850 REG_WR(pDevice, PciCfg.MsiData, Value32 | BIT_26 | BIT_28 | BIT_29);
3851 }
3852
3853 /* Enable TaggedStatus mode. */
3854 if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
3855 {
3856 pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
3857 }
3858
3859 /* Restore PCI configuration registers. */
3860 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
3861 pDevice->SavedCacheLineReg);
3862 MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
3863 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
3864
3865 /* Initialize the statistis Block */
3866 pDevice->pStatusBlkVirt->Status = 0;
3867 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
3868 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
3869 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
3870
3871 for(j = 0; j < 16; j++)
3872 {
3873 pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
3874 pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
3875 }
3876
3877 for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
3878 {
3879 pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
3880 pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
3881 pDevice->pRxStdBdVirt[k].Flags = RCV_BD_FLAG_END;
3882 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) &&
3883 (pDevice->RxJumboBufferSize) )
3884 pDevice->pRxStdBdVirt[k].Len = pDevice->RxJumboBufferSize;
3885 else
3886 pDevice->pRxStdBdVirt[k].Len = MAX_STD_RCV_BUFFER_SIZE;
3887 }
3888
3889 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3890 /* Receive jumbo BD buffer. */
3891 for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
3892 {
3893 pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
3894 pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
3895 pDevice->pRxJumboBdVirt[k].Flags = RCV_BD_FLAG_END |
3896 RCV_BD_FLAG_JUMBO_RING;
3897 pDevice->pRxJumboBdVirt[k].Len = (LM_UINT16) pDevice->RxJumboBufferSize;
3898 }
3899 #endif
3900
3901 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
3902
3903 /* GRC mode control register. */
3904 Value32 =
3905 #ifdef BIG_ENDIAN_HOST
3906 GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
3907 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3908 GRC_MODE_BYTE_SWAP_DATA |
3909 GRC_MODE_WORD_SWAP_DATA |
3910 #else
3911 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3912 GRC_MODE_BYTE_SWAP_DATA |
3913 GRC_MODE_WORD_SWAP_DATA |
3914 #endif
3915 GRC_MODE_INT_ON_MAC_ATTN |
3916 GRC_MODE_HOST_STACK_UP;
3917
3918 /* Configure send BD mode. */
3919 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3920 {
3921 Value32 |= GRC_MODE_HOST_SEND_BDS;
3922 }
3923 #ifdef BCM_NIC_SEND_BD
3924 else
3925 {
3926 Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
3927 }
3928 #endif
3929
3930 /* Configure pseudo checksum mode. */
3931 if (pDevice->Flags & NO_TX_PSEUDO_HDR_CSUM_FLAG)
3932 {
3933 Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
3934 }
3935
3936 if (pDevice->Flags & NO_RX_PSEUDO_HDR_CSUM_FLAG)
3937 {
3938 Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
3939 }
3940
3941 pDevice->GrcMode = Value32;
3942 REG_WR(pDevice, Grc.Mode, Value32);
3943
3944 /* Setup the timer prescalar register. */
3945 Value32 = REG_RD(pDevice, Grc.MiscCfg) & ~0xff;
3946 /* Clock is always 66Mhz. */
3947 REG_WR(pDevice, Grc.MiscCfg, Value32 | (65 << 1));
3948
3949 /* Set up the MBUF pool base address and size. */
3950 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
3951 {
3952 #ifdef INCLUDE_TCP_SEG_SUPPORT
3953 if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
3954 {
3955 Value32 = LM_GetStkOffLdFirmwareSize(pDevice);
3956 Value32 = (Value32 + 0x7f) & ~0x7f;
3957 pDevice->MbufBase = T3_NIC_BCM5705_MBUF_POOL_ADDR + Value32;
3958 pDevice->MbufSize = T3_NIC_BCM5705_MBUF_POOL_SIZE - Value32 - 0xa00;
3959 REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
3960 REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
3961 }
3962 #endif
3963 }
3964 else if (!T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
3965 {
3966 REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
3967 REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
3968
3969 /* Set up the DMA descriptor pool base address and size. */
3970 REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
3971 REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
3972
3973 }
3974
3975 /* Configure MBUF and Threshold watermarks */
3976 /* Configure the DMA read MBUF low water mark. */
3977 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
3978 {
3979 if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
3980 {
3981 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
3982 T3_DEF_DMA_MBUF_LOW_WMARK_5705);
3983 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
3984 T3_DEF_RX_MAC_MBUF_LOW_WMARK_5705);
3985 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
3986 T3_DEF_MBUF_HIGH_WMARK_5705);
3987 }
3988 else
3989 {
3990 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
3991 T3_DEF_DMA_MBUF_LOW_WMARK);
3992 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
3993 T3_DEF_RX_MAC_MBUF_LOW_WMARK);
3994 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
3995 T3_DEF_MBUF_HIGH_WMARK);
3996 }
3997 }else if( T3_ASIC_5714_FAMILY(pDevice->ChipRevId)){
3998
3999 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,0);
4000 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,0x4b);
4001 REG_WR(pDevice, BufMgr.MbufHighWaterMark,0x96);
4002 }
4003 else
4004 {
4005 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
4006 T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
4007 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
4008 T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
4009 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
4010 T3_DEF_MBUF_HIGH_WMARK_JUMBO);
4011 }
4012
4013 REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
4014 REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
4015
4016 /* Enable buffer manager. */
4017 REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
4018
4019 for(j = 0 ;j < 2000; j++)
4020 {
4021 if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
4022 break;
4023 MM_Wait(10);
4024 }
4025
4026 if(j >= 2000)
4027 {
4028 return LM_STATUS_FAILURE;
4029 }
4030
4031 /* GRC reset will reset FTQ */
4032
4033 /* Receive BD Ring replenish threshold. */
4034 REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
4035
4036 /* Initialize the Standard Receive RCB. */
4037 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
4038 pDevice->RxStdBdPhy.High);
4039 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
4040 pDevice->RxStdBdPhy.Low);
4041 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
4042 (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
4043
4044 if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4045 {
4046 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
4047 512 << 16);
4048 }
4049 else
4050 {
4051 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
4052 MAX_STD_RCV_BUFFER_SIZE << 16);
4053
4054 /* Initialize the Jumbo Receive RCB. */
4055 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
4056 T3_RCB_FLAG_RING_DISABLED);
4057 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4058 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
4059 pDevice->RxJumboBdPhy.High);
4060 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
4061 pDevice->RxJumboBdPhy.Low);
4062 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
4063 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
4064 (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
4065
4066 REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
4067
4068 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
4069
4070 /* Initialize the Mini Receive RCB. */
4071 REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
4072 T3_RCB_FLAG_RING_DISABLED);
4073
4074 /* Disable all the unused rings. */
4075 for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
4076 MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags,
4077 T3_RCB_FLAG_RING_DISABLED);
4078 } /* for */
4079
4080 }
4081
4082 /* Initialize the indices. */
4083 pDevice->SendProdIdx = 0;
4084 pDevice->SendConIdx = 0;
4085
4086 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
4087 MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
4088 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
4089 MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
4090
4091 /* Set up host or NIC based send RCB. */
4092 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
4093 {
4094 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
4095 pDevice->SendBdPhy.High);
4096 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
4097 pDevice->SendBdPhy.Low);
4098
4099 /* Setup the RCB. */
4100 MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
4101 T3_SEND_RCB_ENTRY_COUNT << 16);
4102
4103 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4104 {
4105 /* Set up the NIC ring address in the RCB. */
4106 MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
4107 }
4108 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
4109 {
4110 pDevice->pSendBdVirt[k].HostAddr.High = 0;
4111 pDevice->pSendBdVirt[k].HostAddr.Low = 0;
4112 }
4113 }
4114 #ifdef BCM_NIC_SEND_BD
4115 else
4116 {
4117 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
4118 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
4119 MEM_WR(pDevice, SendRcb[0].NicRingAddr,
4120 pDevice->SendBdPhy.Low);
4121
4122 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
4123 {
4124 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.High), 0);
4125 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.Low), 0);
4126 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].u1.Len_Flags), 0);
4127 pDevice->ShadowSendBd[k].HostAddr.High = 0;
4128 pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
4129 }
4130 }
4131 #endif
4132 MM_ATOMIC_SET(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
4133
4134 /* Configure the receive return rings. */
4135 for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
4136 {
4137 MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
4138 }
4139
4140 pDevice->RcvRetConIdx = 0;
4141
4142 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
4143 pDevice->RcvRetBdPhy.High);
4144 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
4145 pDevice->RcvRetBdPhy.Low);
4146
4147 MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
4148
4149 /* Setup the RCB. */
4150 MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
4151 pDevice->RcvRetRcbEntryCount << 16);
4152
4153 /* Reinitialize RX ring producer index */
4154 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
4155 MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
4156 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
4157 MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
4158 MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
4159 MB_REG_RD(pDevice, Mailbox.RcvMiniProdIdx.Low);
4160
4161 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4162 pDevice->RxJumboProdIdx = 0;
4163 pDevice->RxJumboQueuedCnt = 0;
4164 #endif
4165
4166 /* Reinitialize our copy of the indices. */
4167 pDevice->RxStdProdIdx = 0;
4168 pDevice->RxStdQueuedCnt = 0;
4169
4170 #if T3_JUMBO_RCV_ENTRY_COUNT
4171 pDevice->RxJumboProdIdx = 0;
4172 #endif /* T3_JUMBO_RCV_ENTRY_COUNT */
4173
4174 /* Configure the MAC address. */
4175 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
4176
4177 /* Initialize the transmit random backoff seed. */
4178 Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
4179 pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
4180 pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
4181 MAC_TX_BACKOFF_SEED_MASK;
4182 REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
4183
4184 /* Receive MTU. Frames larger than the MTU is marked as oversized. */
4185 REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8); /* CRC + VLAN. */
4186
4187 /* Configure Time slot/IPG per 802.3 */
4188 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
4189
4190 /*
4191 * Configure Receive Rules so that packets don't match
4192 * Programmble rule will be queued to Return Ring 1
4193 */
4194 REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
4195
4196 /*
4197 * Configure to have 16 Classes of Services (COS) and one
4198 * queue per class. Bad frames are queued to RRR#1.
4199 * And frames don't match rules are also queued to COS#1.
4200 */
4201 REG_WR(pDevice, RcvListPlmt.Config, 0x181);
4202
4203 /* Enable Receive Placement Statistics */
4204 if ((pDevice->DmaReadFifoSize == DMA_READ_MODE_FIFO_LONG_BURST) &&
4205 (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION))
4206 {
4207 Value32 = REG_RD(pDevice, RcvListPlmt.StatsEnableMask);
4208 Value32 &= ~T3_DISABLE_LONG_BURST_READ_DYN_FIX;
4209 REG_WR(pDevice, RcvListPlmt.StatsEnableMask, Value32);
4210 }
4211 else
4212 {
4213 REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
4214 }
4215 REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
4216
4217 /* Enable Send Data Initator Statistics */
4218 REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
4219 REG_WR(pDevice, SndDataIn.StatsCtrl,
4220 T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
4221 T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
4222
4223 /* Disable the host coalescing state machine before configuring it's */
4224 /* parameters. */
4225 REG_WR(pDevice, HostCoalesce.Mode, 0);
4226 for(j = 0; j < 2000; j++)
4227 {
4228 Value32 = REG_RD(pDevice, HostCoalesce.Mode);
4229 if(!(Value32 & HOST_COALESCE_ENABLE))
4230 {
4231 break;
4232 }
4233 MM_Wait(10);
4234 }
4235
4236 /* Host coalescing configurations. */
4237 REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
4238 REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
4239 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
4240 pDevice->RxMaxCoalescedFrames);
4241 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
4242 pDevice->TxMaxCoalescedFrames);
4243
4244 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4245 {
4246 REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
4247 pDevice->RxCoalescingTicksDuringInt);
4248 REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
4249 pDevice->TxCoalescingTicksDuringInt);
4250 }
4251 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
4252 pDevice->RxMaxCoalescedFramesDuringInt);
4253 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
4254 pDevice->TxMaxCoalescedFramesDuringInt);
4255
4256 /* Initialize the address of the status block. The NIC will DMA */
4257 /* the status block to this memory which resides on the host. */
4258 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
4259 pDevice->StatusBlkPhy.High);
4260 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
4261 pDevice->StatusBlkPhy.Low);
4262
4263 /* Initialize the address of the statistics block. The NIC will DMA */
4264 /* the statistics to this block of memory. */
4265 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4266 {
4267 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
4268 pDevice->StatsBlkPhy.High);
4269 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
4270 pDevice->StatsBlkPhy.Low);
4271
4272 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
4273 pDevice->StatsCoalescingTicks);
4274
4275 REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
4276 REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
4277 }
4278
4279 /* Enable Host Coalesing state machine */
4280 REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
4281 pDevice->CoalesceMode);
4282
4283 /* Enable the Receive BD Completion state machine. */
4284 REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
4285 RCV_BD_COMP_MODE_ATTN_ENABLE);
4286
4287 /* Enable the Receive List Placement state machine. */
4288 REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
4289
4290 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4291 {
4292 /* Enable the Receive List Selector state machine. */
4293 REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
4294 RCV_LIST_SEL_MODE_ATTN_ENABLE);
4295 }
4296
4297 /* Reset the Rx MAC State Machine.
4298 *
4299 * The Rx MAC State Machine must be reset when using fiber to prevent the
4300 * first packet being lost. This is needed primarily so that the loopback
4301 * test (which currently only sends one packet) doesn't fail.
4302 *
4303 * Also note that the Rx MAC State Machine (0x468) should be reset _before_
4304 * writting to the MAC Mode register (0x400). Failures have been seen on
4305 * 5780/5714's using fiber where they stopped receiving packets in a simple
4306 * ping test when the Rx MAC State Machine was reset _after_ the MAC Mode
4307 * register was set.
4308 */
4309
4310 if ((pDevice->TbiFlags & ENABLE_TBI_FLAG) ||
4311 (pDevice->PhyFlags & PHY_IS_FIBER))
4312 {
4313 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
4314 REG_RD_BACK(pDevice, MacCtrl.RxMode);
4315 MM_Wait(10);
4316 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
4317 REG_RD_BACK(pDevice, MacCtrl.RxMode);
4318 }
4319
4320 /* Clear the statistics block. */
4321 for(j = 0x0300; j < 0x0b00; j = j + 4)
4322 {
4323 MEM_WR_OFFSET(pDevice, j, 0);
4324 }
4325
4326 /* Set Mac Mode */
4327 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
4328 {
4329 pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
4330 }
4331 else if(pDevice->PhyFlags & PHY_IS_FIBER)
4332 {
4333 pDevice->MacMode = MAC_MODE_PORT_MODE_GMII;
4334 }
4335 else
4336 {
4337 pDevice->MacMode = 0;
4338 }
4339
4340 /* Enable transmit DMA, clear statistics. */
4341 pDevice->MacMode |= MAC_MODE_ENABLE_TX_STATISTICS |
4342 MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
4343 MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
4344 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4345 MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
4346
4347 /* GRC miscellaneous local control register. */
4348 pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
4349 GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
4350
4351 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
4352 {
4353 pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
4354 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
4355 }
4356 else if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) &&
4357 !(pDevice->Flags & EEPROM_WP_FLAG))
4358 {
4359 /* Make sure we're on Vmain */
4360 /* The other port may cause us to be on Vaux */
4361 pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
4362 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2;
4363 }
4364
4365 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
4366 MM_Wait(40);
4367
4368 /* Reset RX counters. */
4369 for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
4370 {
4371 ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
4372 }
4373
4374 /* Reset TX counters. */
4375 for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
4376 {
4377 ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
4378 }
4379
4380 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
4381 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
4382 pDevice->LastTag = 0;
4383
4384 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4385 {
4386 /* Enable the DMA Completion state machine. */
4387 REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
4388 }
4389
4390 /* Enable the DMA Write state machine. */
4391 Value32 = DMA_WRITE_MODE_ENABLE |
4392 DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
4393 DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
4394 DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
4395 DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
4396 DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
4397 DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
4398 DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
4399 DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
4400
4401 if (pDevice->Flags & DMA_WR_MODE_RX_ACCELERATE_FLAG)
4402 {
4403 Value32 |= DMA_WRITE_MODE_RECEIVE_ACCELERATE;
4404 }
4405
4406 if (pDevice->Flags & HOST_COALESCING_BUG_FIX)
4407 {
4408 Value32 |= (1 << 29);
4409 }
4410
4411 REG_WR(pDevice, DmaWrite.Mode, Value32);
4412
4413 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
4414 {
4415 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
4416 {
4417 Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
4418 Value32 &= ~PCIX_CMD_MAX_BURST_MASK;
4419 Value32 |= PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL;
4420 REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
4421 }
4422 else if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
4423 {
4424 Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
4425 Value32 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
4426 Value32 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
4427 PCIX_CMD_MAX_BURST_MASK);
4428 if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
4429 {
4430 Value32 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
4431 & PCIX_CMD_MAX_SPLIT_MASK;
4432 }
4433 REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
4434 }
4435 }
4436
4437 /* Enable the Read DMA state machine. */
4438 Value32 = DMA_READ_MODE_ENABLE |
4439 DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
4440 DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
4441 DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
4442 DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
4443 DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
4444 DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
4445 DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
4446 DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
4447
4448 if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
4449 {
4450 Value32 |= DMA_READ_MODE_MULTI_SPLIT_ENABLE;
4451 }
4452
4453 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4454 {
4455 Value32 |= pDevice->DmaReadFifoSize;
4456 }
4457 #ifdef INCLUDE_TCP_SEG_SUPPORT
4458 if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
4459 {
4460 Value32 |= BIT_27;
4461 }
4462 #endif
4463
4464
4465 REG_WR(pDevice, DmaRead.Mode, Value32);
4466
4467 /* Enable the Receive Data Completion state machine. */
4468 REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
4469 RCV_DATA_COMP_MODE_ATTN_ENABLE);
4470
4471 if (!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
4472 {
4473 /* Enable the Mbuf Cluster Free state machine. */
4474 REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
4475 }
4476
4477 /* Enable the Send Data Completion state machine. */
4478 REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
4479
4480 /* Enable the Send BD Completion state machine. */
4481 REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
4482 SND_BD_COMP_MODE_ATTN_ENABLE);
4483
4484 /* Enable the Receive BD Initiator state machine. */
4485 REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
4486 RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
4487
4488 /* Enable the Receive Data and Receive BD Initiator state machine. */
4489 REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
4490 RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
4491
4492 /* Enable the Send Data Initiator state machine. */
4493 REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
4494
4495 #ifdef INCLUDE_TCP_SEG_SUPPORT
4496 if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
4497 {
4498 REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE | 0x8);
4499 }
4500 #endif
4501
4502 /* Enable the Send BD Initiator state machine. */
4503 REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
4504 SND_BD_IN_MODE_ATTN_ENABLE);
4505
4506 /* Enable the Send BD Selector state machine. */
4507 REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
4508 SND_BD_SEL_MODE_ATTN_ENABLE);
4509
4510 #ifdef INCLUDE_5701_AX_FIX
4511 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
4512 {
4513 LM_LoadRlsFirmware(pDevice);
4514 }
4515 #endif
4516
4517 /* Queue Rx packet buffers. */
4518 if(pDevice->QueueRxPackets)
4519 {
4520 LM_QueueRxPackets(pDevice);
4521 }
4522
4523 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
4524 {
4525 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
4526 j = 0;
4527 while ((Value32 != MAX_STD_RCV_BUFFER_SIZE) && (j < 10))
4528 {
4529 MM_Wait(20);
4530 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
4531 j++;
4532 }
4533 if (j >= 10)
4534 {
4535 reset_count++;
4536 LM_Abort(pDevice);
4537 if (reset_count > 5)
4538 return LM_STATUS_FAILURE;
4539 goto restart_reset;
4540 }
4541 }
4542
4543 /* Enable the transmitter. */
4544 pDevice->TxMode = TX_MODE_ENABLE;
4545 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
4546
4547 /* Enable the receiver. */
4548 pDevice->RxMode = (pDevice->RxMode & RX_MODE_KEEP_VLAN_TAG) |
4549 RX_MODE_ENABLE;
4550 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
4551
4552 #ifdef BCM_WOL
4553 if (pDevice->RestoreOnWakeUp)
4554 {
4555 pDevice->RestoreOnWakeUp = FALSE;
4556 pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
4557 pDevice->RequestedLineSpeed = pDevice->WakeUpRequestedLineSpeed;
4558 pDevice->RequestedDuplexMode = pDevice->WakeUpRequestedDuplexMode;
4559 }
4560 #endif
4561
4562 /* Disable auto polling. */
4563 pDevice->MiMode = 0xc0000;
4564 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
4565
4566 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
4567
4568 /* Activate Link to enable MAC state machine */
4569 REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
4570
4571 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
4572 {
4573 if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
4574 {
4575 REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
4576 }
4577 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
4578 {
4579
4580 if(!(pDevice->TbiFlags & TBI_DO_PREEMPHASIS))
4581 {
4582 /* Set SerDes drive transmission level to 1.2V */
4583 Value32 = REG_RD(pDevice, MacCtrl.SerdesCfg) & 0xfffff000;
4584 REG_WR(pDevice, MacCtrl.SerdesCfg, Value32 | 0x880);
4585 }
4586 }
4587 }
4588
4589 REG_WR(pDevice, MacCtrl.LowWaterMarkMaxRxFrame, 2);
4590
4591 if(pDevice->PhyFlags & PHY_IS_FIBER)
4592 {
4593 Value32 = REG_RD_OFFSET(pDevice, 0x5b0);
4594 REG_WR_OFFSET(pDevice, 0x5b0, Value32 | BIT_10 );
4595
4596 pDevice->GrcLocalCtrl |= BIT_4 ;
4597 pDevice->GrcLocalCtrl &= ~BIT_5 ;
4598
4599 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
4600 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
4601 MM_Wait(40);
4602 }
4603
4604 if (!pDevice->InitDone)
4605 {
4606 if(UNKNOWN_PHY_ID(pDevice->PhyId) && (pDevice->Flags & ROBO_SWITCH_FLAG)) {
4607 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
4608 } else {
4609 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
4610 }
4611 }
4612
4613 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
4614 ( ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5401_PHY_ID)&&
4615 ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) ))
4616 {
4617 /* 5401/5411 PHY needs a delay of about 1 second after PHY reset */
4618 /* Without the delay, it has problem linking at forced 10 half */
4619 /* So skip the reset... */
4620 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5780)
4621 for(j =0; j<0x5000; j++)
4622 MM_Wait(1);
4623
4624 LM_ResetPhy(pDevice);
4625 }
4626
4627 /* Setup the phy chip. */
4628 LM_SetupPhy(pDevice);
4629
4630 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG)){
4631 /* Clear CRC stats */
4632 LM_ReadPhy(pDevice, 0x1e, &Value32);
4633 LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
4634 LM_ReadPhy(pDevice, 0x14, &Value32);
4635 }
4636
4637 /* Set up the receive mask. */
4638 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
4639
4640 #ifdef INCLUDE_TCP_SEG_SUPPORT
4641 if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
4642 {
4643 if (LM_LoadStkOffLdFirmware(pDevice) == LM_STATUS_FAILURE)
4644 {
4645 return LM_STATUS_FAILURE;
4646 }
4647 }
4648 #endif
4649 LM_WritePostResetSignatures(pDevice, LM_INIT_RESET);
4650
4651 return LM_STATUS_SUCCESS;
4652 } /* LM_ResetAdapter */
4653
4654
4655 /******************************************************************************/
4656 /* Description: */
4657 /* This routine disables the adapter from generating interrupts. */
4658 /* */
4659 /* Return: */
4660 /* LM_STATUS_SUCCESS */
4661 /******************************************************************************/
4662 LM_STATUS
4663 LM_DisableInterrupt(
4664 PLM_DEVICE_BLOCK pDevice)
4665 {
4666 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
4667 MISC_HOST_CTRL_MASK_PCI_INT);
4668 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
4669 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4670 {
4671 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
4672 }
4673
4674 return LM_STATUS_SUCCESS;
4675 }
4676
4677
4678
4679 /******************************************************************************/
4680 /* Description: */
4681 /* This routine enables the adapter to generate interrupts. */
4682 /* */
4683 /* Return: */
4684 /* LM_STATUS_SUCCESS */
4685 /******************************************************************************/
4686 LM_STATUS
4687 LM_EnableInterrupt(
4688 PLM_DEVICE_BLOCK pDevice)
4689 {
4690 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, pDevice->LastTag << 24);
4691 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4692 {
4693 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
4694 }
4695
4696 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
4697 ~MISC_HOST_CTRL_MASK_PCI_INT);
4698
4699 REG_WR(pDevice, HostCoalesce.Mode, pDevice->CoalesceMode |
4700 HOST_COALESCE_ENABLE | HOST_COALESCE_NOW);
4701
4702 return LM_STATUS_SUCCESS;
4703 }
4704
4705
4706
4707 /******************************************************************************/
4708 /* Description: */
4709 /* This routine puts a packet on the wire if there is a transmit DMA */
4710 /* descriptor available; otherwise the packet is queued for later */
4711 /* transmission. If the second argue is NULL, this routine will put */
4712 /* the queued packet on the wire if possible. */
4713 /* */
4714 /* Return: */
4715 /* LM_STATUS_SUCCESS */
4716 /******************************************************************************/
4717 LM_STATUS
4718 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
4719 {
4720 LM_UINT32 FragCount;
4721 PT3_SND_BD pSendBd, pTmpSendBd;
4722 #ifdef BCM_NIC_SEND_BD
4723 PT3_SND_BD pShadowSendBd;
4724 T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
4725 #endif
4726 LM_UINT32 StartIdx, Idx;
4727
4728 while (1)
4729 {
4730 /* Initalize the send buffer descriptors. */
4731 StartIdx = Idx = pDevice->SendProdIdx;
4732
4733 #ifdef BCM_NIC_SEND_BD
4734 if (pDevice->Flags & NIC_SEND_BD_FLAG)
4735 {
4736 pTmpSendBd = pSendBd = &NicSendBdArr[0];
4737 }
4738 else
4739 #endif
4740 {
4741 pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
4742 }
4743
4744 /* Next producer index. */
4745 for(FragCount = 0; ; )
4746 {
4747 LM_UINT32 Value32, Len;
4748
4749 /* Initialize the pointer to the send buffer fragment. */
4750 MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
4751
4752 pSendBd->u2.VlanTag = pPacket->VlanTag;
4753
4754 /* Setup the control flags and send buffer size. */
4755 Value32 = (Len << 16) | pPacket->Flags;
4756
4757 #ifdef INCLUDE_TCP_SEG_SUPPORT
4758 if (Value32 & (SND_BD_FLAG_CPU_PRE_DMA | SND_BD_FLAG_CPU_POST_DMA))
4759 {
4760 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
4761 {
4762 pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
4763 }
4764 else if (FragCount == 0)
4765 {
4766 pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
4767 }
4768 else
4769 {
4770 pSendBd->u2.s2.Reserved = 0;
4771 Value32 &= 0xffff0fff;
4772 }
4773 }
4774 #endif
4775 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
4776
4777 FragCount++;
4778 if (FragCount >= pPacket->u.Tx.FragCount)
4779 {
4780 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
4781 break;
4782 }
4783 else
4784 {
4785 pSendBd->u1.Len_Flags = Value32;
4786 }
4787
4788 pSendBd++;
4789 if ((Idx == 0) &&
4790 !(pDevice->Flags & NIC_SEND_BD_FLAG))
4791 {
4792 pSendBd = &pDevice->pSendBdVirt[0];
4793 }
4794
4795 pDevice->SendRing[Idx] = 0;
4796
4797 } /* for */
4798 if (pDevice->Flags & TX_4G_WORKAROUND_FLAG)
4799 {
4800 if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
4801 LM_STATUS_SUCCESS)
4802 {
4803 if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
4804 {
4805 QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
4806 return LM_STATUS_FAILURE;
4807 }
4808 continue;
4809 }
4810 }
4811 break;
4812 }
4813 /* Put the packet descriptor in the ActiveQ. */
4814 pDevice->SendRing[StartIdx] = pPacket;
4815
4816 #ifdef BCM_NIC_SEND_BD
4817 if (pDevice->Flags & NIC_SEND_BD_FLAG)
4818 {
4819 pSendBd = &pDevice->pSendBdVirt[StartIdx];
4820 pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
4821
4822 while (StartIdx != Idx)
4823 {
4824 LM_UINT32 Value32;
4825
4826 if ((Value32 = pTmpSendBd->HostAddr.High) !=
4827 pShadowSendBd->HostAddr.High)
4828 {
4829 MM_MEMWRITEL(&(pSendBd->HostAddr.High), Value32);
4830 pShadowSendBd->HostAddr.High = Value32;
4831 }
4832
4833 MM_MEMWRITEL(&(pSendBd->HostAddr.Low), pTmpSendBd->HostAddr.Low);
4834
4835 if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
4836 pShadowSendBd->u1.Len_Flags)
4837 {
4838 MM_MEMWRITEL(&(pSendBd->u1.Len_Flags), Value32);
4839 pShadowSendBd->u1.Len_Flags = Value32;
4840 }
4841
4842 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
4843 {
4844 MM_MEMWRITEL(&(pSendBd->u2.VlanTag), pTmpSendBd->u2.VlanTag);
4845 }
4846
4847 StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
4848 if (StartIdx == 0)
4849 {
4850 pSendBd = &pDevice->pSendBdVirt[0];
4851 pShadowSendBd = &pDevice->ShadowSendBd[0];
4852 }
4853 else
4854 {
4855 pSendBd++;
4856 pShadowSendBd++;
4857 }
4858 pTmpSendBd++;
4859 }
4860 MM_WMB();
4861 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
4862
4863 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
4864 {
4865 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
4866 }
4867 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4868 {
4869 MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
4870 }
4871 else
4872 {
4873 MM_MMIOWB();
4874 }
4875 }
4876 else
4877 #endif
4878 {
4879 MM_WMB();
4880 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
4881
4882 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
4883 {
4884 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
4885 }
4886 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4887 {
4888 MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
4889 }
4890 else
4891 {
4892 MM_MMIOWB();
4893 }
4894 }
4895
4896 /* Update the SendBdLeft count. */
4897 MM_ATOMIC_SUB(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
4898
4899 /* Update the producer index. */
4900 pDevice->SendProdIdx = Idx;
4901
4902 return LM_STATUS_SUCCESS;
4903 }
4904
4905 STATIC LM_STATUS
4906 LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
4907 PT3_SND_BD pSendBd)
4908 {
4909 int FragCount;
4910 LM_UINT32 Idx, Base, Len;
4911
4912 Idx = pDevice->SendProdIdx;
4913 for(FragCount = 0; ; )
4914 {
4915 Len = pSendBd->u1.Len_Flags >> 16;
4916 if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
4917 ((Base + 8 + Len) < Base))
4918 {
4919 return LM_STATUS_SUCCESS;
4920 }
4921 FragCount++;
4922 if (FragCount >= pPacket->u.Tx.FragCount)
4923 {
4924 break;
4925 }
4926 pSendBd++;
4927 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
4928 {
4929 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
4930 if (Idx == 0)
4931 {
4932 pSendBd = &pDevice->pSendBdVirt[0];
4933 }
4934 }
4935 }
4936 return LM_STATUS_FAILURE;
4937 }
4938
4939 /******************************************************************************/
4940 /* Description: */
4941 /* */
4942 /* Return: */
4943 /******************************************************************************/
4944 LM_UINT32
4945 ComputeCrc32(LM_UINT8 *pBuffer, LM_UINT32 BufferSize)
4946 {
4947 LM_UINT32 Reg;
4948 LM_UINT32 Tmp;
4949 int j, k;
4950
4951 Reg = 0xffffffff;
4952
4953 for(j = 0; j < BufferSize; j++)
4954 {
4955 Reg ^= pBuffer[j];
4956
4957 for(k = 0; k < 8; k++)
4958 {
4959 Tmp = Reg & 0x01;
4960
4961 Reg >>= 1;
4962
4963 if(Tmp)
4964 {
4965 Reg ^= 0xedb88320;
4966 }
4967 }
4968 }
4969
4970 return ~Reg;
4971 } /* ComputeCrc32 */
4972
4973
4974
4975 /******************************************************************************/
4976 /* Description: */
4977 /* This routine sets the receive control register according to ReceiveMask */
4978 /* */
4979 /* Return: */
4980 /* LM_STATUS_SUCCESS */
4981 /******************************************************************************/
4982 LM_STATUS
4983 LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
4984 {
4985 LM_UINT32 ReceiveMask;
4986 LM_UINT32 RxMode;
4987 LM_UINT32 j, k;
4988
4989 ReceiveMask = Mask;
4990
4991 RxMode = pDevice->RxMode;
4992
4993 if(Mask & LM_ACCEPT_UNICAST)
4994 {
4995 Mask &= ~LM_ACCEPT_UNICAST;
4996 }
4997
4998 if(Mask & LM_ACCEPT_MULTICAST)
4999 {
5000 Mask &= ~LM_ACCEPT_MULTICAST;
5001 }
5002
5003 if(Mask & LM_ACCEPT_ALL_MULTICAST)
5004 {
5005 Mask &= ~LM_ACCEPT_ALL_MULTICAST;
5006 }
5007
5008 if(Mask & LM_ACCEPT_BROADCAST)
5009 {
5010 Mask &= ~LM_ACCEPT_BROADCAST;
5011 }
5012
5013 RxMode &= ~RX_MODE_KEEP_VLAN_TAG;
5014 if (Mask & LM_KEEP_VLAN_TAG)
5015 {
5016 RxMode |= RX_MODE_KEEP_VLAN_TAG;
5017 Mask &= ~LM_KEEP_VLAN_TAG;
5018 }
5019
5020 RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
5021 if(Mask & LM_PROMISCUOUS_MODE)
5022 {
5023 RxMode |= RX_MODE_PROMISCUOUS_MODE;
5024 Mask &= ~LM_PROMISCUOUS_MODE;
5025 }
5026
5027 RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
5028 if(Mask & LM_ACCEPT_ERROR_PACKET)
5029 {
5030 RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
5031 Mask &= ~LM_ACCEPT_ERROR_PACKET;
5032 }
5033
5034 /* Make sure all the bits are valid before committing changes. */
5035 if(Mask)
5036 {
5037 return LM_STATUS_FAILURE;
5038 }
5039
5040 /* Commit the new filter. */
5041 pDevice->ReceiveMask = ReceiveMask;
5042
5043 pDevice->RxMode = RxMode;
5044
5045 if (pDevice->PowerLevel != LM_POWER_STATE_D0)
5046 {
5047 return LM_STATUS_SUCCESS;
5048 }
5049
5050 REG_WR(pDevice, MacCtrl.RxMode, RxMode);
5051
5052 /* Set up the MC hash table. */
5053 if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
5054 {
5055 for(k = 0; k < 4; k++)
5056 {
5057 REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
5058 }
5059 }
5060 else if(ReceiveMask & LM_ACCEPT_MULTICAST)
5061 {
5062 for(k = 0; k < 4; k++)
5063 {
5064 REG_WR(pDevice, MacCtrl.HashReg[k], pDevice->MulticastHash[k]);
5065 }
5066 }
5067 else
5068 {
5069 /* Reject all multicast frames. */
5070 for(j = 0; j < 4; j++)
5071 {
5072 REG_WR(pDevice, MacCtrl.HashReg[j], 0);
5073 }
5074 }
5075
5076 /* By default, Tigon3 will accept broadcast frames. We need to setup */
5077 if(ReceiveMask & LM_ACCEPT_BROADCAST)
5078 {
5079 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
5080 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
5081 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
5082 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
5083 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
5084 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
5085 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
5086 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
5087 }
5088 else
5089 {
5090 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
5091 REJECT_BROADCAST_RULE1_RULE);
5092 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
5093 REJECT_BROADCAST_RULE1_VALUE);
5094 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
5095 REJECT_BROADCAST_RULE2_RULE);
5096 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
5097 REJECT_BROADCAST_RULE2_VALUE);
5098 }
5099
5100 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
5101 {
5102 k = 16;
5103 }
5104 else if (!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
5105 {
5106 k = 16;
5107 }
5108 else
5109 {
5110 k = 8;
5111 }
5112 #ifdef BCM_ASF
5113 if (pDevice->AsfFlags & ASF_ENABLED)
5114 {
5115 k -= 4;
5116 }
5117 #endif
5118
5119 /* disable the rest of the rules. */
5120 for(j = RCV_LAST_RULE_IDX; j < k; j++)
5121 {
5122 REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
5123 REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
5124 }
5125
5126 return LM_STATUS_SUCCESS;
5127 } /* LM_SetReceiveMask */
5128
5129
5130
5131 /******************************************************************************/
5132 /* Description: */
5133 /* Disable the interrupt and put the transmitter and receiver engines in */
5134 /* an idle state. Also aborts all pending send requests and receive */
5135 /* buffers. */
5136 /* */
5137 /* Return: */
5138 /* LM_STATUS_SUCCESS */
5139 /******************************************************************************/
5140 LM_STATUS
5141 LM_Abort(
5142 PLM_DEVICE_BLOCK pDevice)
5143 {
5144 PLM_PACKET pPacket;
5145 LM_UINT Idx;
5146
5147 LM_DisableInterrupt(pDevice);
5148
5149 LM_DisableChip(pDevice);
5150
5151 /*
5152 * If we do not have a status block pointer, then
5153 * the device hasn't really been opened. Do not
5154 * attempt to clean up packets.
5155 */
5156 if (pDevice->pStatusBlkVirt == NULL)
5157 return LM_STATUS_SUCCESS;
5158
5159 /* Abort packets that have already queued to go out. */
5160 Idx = pDevice->SendConIdx;
5161 for ( ; ; )
5162 {
5163 if ((pPacket = pDevice->SendRing[Idx]))
5164 {
5165 pDevice->SendRing[Idx] = 0;
5166 pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
5167 pDevice->TxCounters.TxPacketAbortedCnt++;
5168
5169 MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
5170 Idx = (Idx + pPacket->u.Tx.FragCount) &
5171 T3_SEND_RCB_ENTRY_COUNT_MASK;
5172
5173 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
5174 }
5175 else
5176 {
5177 break;
5178 }
5179 }
5180
5181 /* Cleanup the receive return rings. */
5182 #ifdef BCM_NAPI_RXPOLL
5183 LM_ServiceRxPoll(pDevice, T3_RCV_RETURN_RCB_ENTRY_COUNT);
5184 #else
5185 LM_ServiceRxInterrupt(pDevice);
5186 #endif
5187
5188 /* Indicate packets to the protocol. */
5189 MM_IndicateTxPackets(pDevice);
5190
5191 #ifdef BCM_NAPI_RXPOLL
5192
5193 /* Move the receive packet descriptors in the ReceivedQ to the */
5194 /* free queue. */
5195 for(; ;)
5196 {
5197 pPacket = (PLM_PACKET) QQ_PopHead(
5198 &pDevice->RxPacketReceivedQ.Container);
5199 if(pPacket == NULL)
5200 {
5201 break;
5202 }
5203 MM_UnmapRxDma(pDevice, pPacket);
5204 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5205 }
5206 #else
5207 /* Indicate received packets to the protocols. */
5208 MM_IndicateRxPackets(pDevice);
5209 #endif
5210
5211 /* Clean up the Std Receive Producer ring. */
5212 /* Don't always trust the consumer idx in the status block in case of */
5213 /* hw failure */
5214 Idx = 0;
5215
5216 while(Idx < T3_STD_RCV_RCB_ENTRY_COUNT)
5217 {
5218 if ((pPacket = pDevice->RxStdRing[Idx]))
5219 {
5220 MM_UnmapRxDma(pDevice, pPacket);
5221 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5222 pDevice->RxStdRing[Idx] = 0;
5223 }
5224
5225 Idx++;
5226 } /* while */
5227
5228 /* Reinitialize our copy of the indices. */
5229 pDevice->RxStdProdIdx = 0;
5230
5231 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
5232 /* Clean up the Jumbo Receive Producer ring. */
5233 Idx = 0;
5234
5235 while(Idx < T3_JUMBO_RCV_RCB_ENTRY_COUNT)
5236 {
5237 if ((pPacket = pDevice->RxJumboRing[Idx]))
5238 {
5239 MM_UnmapRxDma(pDevice, pPacket);
5240 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5241 pDevice->RxJumboRing[Idx] = 0;
5242 }
5243 Idx++;
5244 } /* while */
5245
5246 /* Reinitialize our copy of the indices. */
5247 pDevice->RxJumboProdIdx = 0;
5248 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
5249
5250 /* Initialize the statistis Block */
5251 pDevice->pStatusBlkVirt->Status = 0;
5252 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
5253 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
5254 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
5255
5256 return LM_STATUS_SUCCESS;
5257 } /* LM_Abort */
5258
5259
5260
5261 /******************************************************************************/
5262 /* Description: */
5263 /* Disable the interrupt and put the transmitter and receiver engines in */
5264 /* an idle state. Aborts all pending send requests and receive buffers. */
5265 /* Also free all the receive buffers. */
5266 /* */
5267 /* Return: */
5268 /* LM_STATUS_SUCCESS */
5269 /******************************************************************************/
5270 LM_STATUS
5271 LM_DoHalt(LM_DEVICE_BLOCK *pDevice)
5272 {
5273 PLM_PACKET pPacket;
5274 LM_UINT32 EntryCnt;
5275
5276 LM_DisableFW(pDevice);
5277
5278 LM_WritePreResetSignatures(pDevice, LM_SHUTDOWN_RESET);
5279 LM_Abort(pDevice);
5280
5281 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5461_PHY_ID)
5282 LM_WritePhy(pDevice, BCM546X_1c_SHADOW_REG,
5283 (BCM546X_1c_SPR_CTRL_1 | BCM546X_1c_WR_EN));
5284
5285 /* Get the number of entries in the queue. */
5286 EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
5287
5288 /* Make sure all the packets have been accounted for. */
5289 for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
5290 {
5291 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
5292 if (pPacket == 0)
5293 break;
5294
5295 MM_FreeRxBuffer(pDevice, pPacket);
5296
5297 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5298 }
5299
5300 LM_ResetChip(pDevice);
5301 LM_WriteLegacySignatures(pDevice, LM_SHUTDOWN_RESET);
5302
5303 /* Restore PCI configuration registers. */
5304 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
5305 pDevice->SavedCacheLineReg);
5306 LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
5307 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
5308
5309 /* Reprogram the MAC address. */
5310 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
5311
5312 return LM_STATUS_SUCCESS;
5313 } /* LM_DoHalt */
5314
5315
5316 LM_STATUS
5317 LM_Halt(LM_DEVICE_BLOCK *pDevice)
5318 {
5319 LM_STATUS status;
5320
5321 status = LM_DoHalt(pDevice);
5322 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
5323 return status;
5324 }
5325
5326
5327 STATIC LM_VOID
5328 LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5329 {
5330 MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,T3_MAGIC_NUM_FIRMWARE_INIT_DONE);
5331 #ifdef BCM_ASF
5332 if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
5333 {
5334 if (Mode == LM_INIT_RESET)
5335 {
5336 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
5337 }
5338 else if (Mode == LM_SHUTDOWN_RESET)
5339 {
5340 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
5341 }
5342 else if (Mode == LM_SUSPEND_RESET)
5343 {
5344 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
5345 }
5346 }
5347 #endif
5348 }
5349
5350 STATIC LM_VOID
5351 LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5352 {
5353 #ifdef BCM_ASF
5354 if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
5355 {
5356 if (Mode == LM_INIT_RESET)
5357 {
5358 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
5359 T3_DRV_STATE_START_DONE);
5360 }
5361 else if (Mode == LM_SHUTDOWN_RESET)
5362 {
5363 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
5364 T3_DRV_STATE_UNLOAD_DONE);
5365 }
5366 }
5367 #endif
5368 }
5369
5370 STATIC LM_VOID
5371 LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5372 {
5373 #ifdef BCM_ASF
5374 if (pDevice->AsfFlags & ASF_ENABLED)
5375 {
5376 if (Mode == LM_INIT_RESET)
5377 {
5378 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
5379 }
5380 else if (Mode == LM_SHUTDOWN_RESET)
5381 {
5382 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
5383 }
5384 else if (Mode == LM_SUSPEND_RESET)
5385 {
5386 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
5387 }
5388 }
5389 #endif
5390 }
5391
5392 STATIC LM_STATUS
5393 LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
5394 {
5395 LM_UINT32 Value32;
5396 LM_UINT32 j, tmp1 = 0, tmp2 = 0;
5397
5398 /* Wait for access to the nvram interface before resetting. This is */
5399 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
5400 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
5401 {
5402 /* Request access to the flash interface. */
5403 LM_NVRAM_AcquireLock(pDevice);
5404 }
5405
5406 Value32 = GRC_MISC_CFG_CORE_CLOCK_RESET;
5407 if (pDevice->Flags & PCI_EXPRESS_FLAG)
5408 {
5409 if (REG_RD_OFFSET(pDevice, 0x7e2c) == 0x60) /* PCIE 1.0 system */
5410 {
5411 REG_WR_OFFSET(pDevice, 0x7e2c, 0x20);
5412 }
5413 if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
5414 {
5415 /* This bit prevents PCIE link training during GRC reset */
5416 REG_WR(pDevice, Grc.MiscCfg, BIT_29); /* Write bit 29 first */
5417 Value32 |= BIT_29; /* and keep bit 29 set during GRC reset */
5418 }
5419 }
5420 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
5421 {
5422 Value32 |= GRC_MISC_GPHY_KEEP_POWER_DURING_RESET;
5423 }
5424
5425 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
5426 {
5427 /* Save the MSI ENABLE bit (may need to save the message as well) */
5428 tmp1 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5429 }
5430
5431 /* Global reset. */
5432 RAW_REG_WR(pDevice, Grc.MiscCfg, Value32);
5433 MM_Wait(120);
5434
5435 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
5436
5437 MM_Wait(120);
5438
5439 /* make sure we re-enable indirect accesses */
5440 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
5441 pDevice->MiscHostCtrl);
5442
5443 /* Set MAX PCI retry to zero. */
5444 Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
5445 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
5446 {
5447 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
5448 {
5449 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
5450 }
5451 }
5452 MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
5453
5454 /* Restore PCI command register. */
5455 MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
5456 pDevice->PciCommandStatusWords);
5457
5458 /* Disable PCI-X relaxed ordering bit. */
5459 MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
5460 Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
5461 MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
5462
5463 /* Enable memory arbiter */
5464 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
5465 {
5466 Value32 = REG_RD(pDevice,MemArbiter.Mode);
5467 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE | Value32);
5468 }
5469 else
5470 {
5471 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
5472 }
5473
5474 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
5475 {
5476 /* restore the MSI ENABLE bit (may need to restore the message also) */
5477 tmp2 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5478 tmp2 |= (tmp1 & (1 << 16));
5479 LM_RegWr( pDevice, T3_PCI_MSI_ENABLE, tmp2, TRUE );
5480 tmp2 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5481 }
5482
5483
5484 if (pDevice->ChipRevId == T3_CHIP_ID_5750_A3)
5485 {
5486 /* Because of chip bug on A3, we need to kill the CPU */
5487 LM_DisableFW(pDevice);
5488 REG_WR_OFFSET(pDevice, 0x5000, 0x400);
5489 }
5490
5491 /*
5492 * BCM4785: In order to avoid repercussions from using potentially
5493 * defective internal ROM, stop the Rx RISC CPU, which is not
5494 * required.
5495 */
5496 if (pDevice->Flags & SB_CORE_FLAG) {
5497 LM_DisableFW(pDevice);
5498 LM_HaltCpu(pDevice, T3_RX_CPU_ID);
5499 }
5500
5501 #ifdef BIG_ENDIAN_HOST
5502 /* Reconfigure the mode register. */
5503 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
5504 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
5505 GRC_MODE_BYTE_SWAP_DATA |
5506 GRC_MODE_WORD_SWAP_DATA;
5507 #else
5508 /* Reconfigure the mode register. */
5509 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
5510 #endif
5511 REG_WR(pDevice, Grc.Mode, Value32);
5512
5513 if ((pDevice->Flags & MINI_PCI_FLAG) &&
5514 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
5515 {
5516 pDevice->ClockCtrl |= T3_PCI_CLKRUN_OUTPUT_EN;
5517 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
5518 {
5519 pDevice->ClockCtrl |= T3_PCI_FORCE_CLKRUN;
5520 }
5521 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
5522 }
5523
5524 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
5525 {
5526 pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
5527 }
5528 else if(pDevice->PhyFlags & PHY_IS_FIBER)
5529 {
5530 pDevice->MacMode = MAC_MODE_PORT_MODE_GMII;
5531 }
5532 else
5533 {
5534 pDevice->MacMode = 0;
5535 }
5536
5537 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5538 REG_RD_BACK(pDevice, MacCtrl.Mode);
5539 MM_Wait(40);
5540
5541 /* BCM4785: Don't use any firmware, so don't wait */
5542 if (!pDevice->Flags & SB_CORE_FLAG) {
5543 /* Wait for the firmware to finish initialization. */
5544 for(j = 0; j < 100000; j++) {
5545 MM_Wait(10);
5546
5547 if (j < 100)
5548 continue;
5549
5550 Value32 = MEM_RD_OFFSET(pDevice, T3_FIRMWARE_MAILBOX);
5551 if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE) {
5552 break;
5553 }
5554 }
5555 if ((j >= 0x100000) && (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)) {
5556 /* if the boot code is not running */
5557 if (LM_NVRAM_AcquireLock(pDevice) != LM_STATUS_SUCCESS) {
5558 LM_DEVICE_BLOCK *pDevice2;
5559
5560 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
5561 pDevice2 = MM_FindPeerDev(pDevice);
5562 if (pDevice2 && !pDevice2->InitDone)
5563 REG_WR(pDevice2, Nvram.Cmd, NVRAM_CMD_RESET);
5564 } else {
5565 LM_NVRAM_ReleaseLock(pDevice);
5566 }
5567 }
5568 }
5569
5570 if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
5571 (pDevice->ChipRevId != T3_CHIP_ID_5750_A0))
5572 {
5573 /* Enable PCIE bug fix */
5574 Value32 = REG_RD_OFFSET(pDevice, 0x7c00);
5575 REG_WR_OFFSET(pDevice, 0x7c00, Value32 | BIT_25 | BIT_29);
5576 }
5577
5578 #ifdef BCM_ASF
5579 pDevice->AsfFlags = 0;
5580 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
5581
5582 if (Value32 == T3_NIC_DATA_SIG)
5583 {
5584 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
5585 if (Value32 & T3_NIC_CFG_ENABLE_ASF)
5586 {
5587 pDevice->AsfFlags = ASF_ENABLED;
5588 if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
5589 {
5590 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
5591 }
5592 }
5593 }
5594 #endif
5595
5596 return LM_STATUS_SUCCESS;
5597 }
5598
5599
5600 LM_STATUS
5601 LM_ShutdownChip(PLM_DEVICE_BLOCK pDevice, LM_RESET_TYPE Mode)
5602 {
5603 LM_DisableFW(pDevice);
5604 LM_WritePreResetSignatures(pDevice, Mode);
5605 if (pDevice->InitDone)
5606 {
5607 LM_Abort(pDevice);
5608 }
5609 else
5610 {
5611 LM_DisableChip(pDevice);
5612 }
5613 LM_ResetChip(pDevice);
5614 LM_WriteLegacySignatures(pDevice, Mode);
5615 LM_WritePostResetSignatures(pDevice, Mode);
5616 return LM_STATUS_SUCCESS;
5617 }
5618
5619 /******************************************************************************/
5620 /* Description: */
5621 /* */
5622 /* Return: */
5623 /******************************************************************************/
5624 void
5625 LM_ServiceTxInterrupt(
5626 PLM_DEVICE_BLOCK pDevice) {
5627 PLM_PACKET pPacket;
5628 LM_UINT32 HwConIdx;
5629 LM_UINT32 SwConIdx;
5630
5631 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
5632
5633 /* Get our copy of the consumer index. The buffer descriptors */
5634 /* that are in between the consumer indices are freed. */
5635 SwConIdx = pDevice->SendConIdx;
5636
5637 /* Move the packets from the TxPacketActiveQ that are sent out to */
5638 /* the TxPacketXmittedQ. Packets that are sent use the */
5639 /* descriptors that are between SwConIdx and HwConIdx. */
5640 while(SwConIdx != HwConIdx)
5641 {
5642 pPacket = pDevice->SendRing[SwConIdx];
5643 pDevice->SendRing[SwConIdx] = 0;
5644
5645 /* Set the return status. */
5646 pPacket->PacketStatus = LM_STATUS_SUCCESS;
5647
5648 /* Put the packet in the TxPacketXmittedQ for indication later. */
5649 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
5650
5651 /* Move to the next packet's BD. */
5652 SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
5653 T3_SEND_RCB_ENTRY_COUNT_MASK;
5654
5655 /* Update the number of unused BDs. */
5656 MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
5657
5658 /* Get the new updated HwConIdx. */
5659 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
5660 } /* while */
5661
5662 /* Save the new SwConIdx. */
5663 pDevice->SendConIdx = SwConIdx;
5664
5665 } /* LM_ServiceTxInterrupt */
5666
5667
5668 #ifdef BCM_NAPI_RXPOLL
5669 /******************************************************************************/
5670 /* Description: */
5671 /* */
5672 /* Return: */
5673 /******************************************************************************/
5674 int
5675 LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit)
5676 {
5677 PLM_PACKET pPacket=NULL;
5678 PT3_RCV_BD pRcvBd;
5679 LM_UINT32 HwRcvRetProdIdx;
5680 LM_UINT32 SwRcvRetConIdx;
5681 int received = 0;
5682
5683 /* Loop thru the receive return rings for received packets. */
5684 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
5685
5686 SwRcvRetConIdx = pDevice->RcvRetConIdx;
5687 MM_RMB();
5688 while (SwRcvRetConIdx != HwRcvRetProdIdx)
5689 {
5690 pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
5691
5692 /* Get the received packet descriptor. */
5693 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
5694 MM_UINT_PTR(pRcvBd->Opaque));
5695
5696 switch(pPacket->u.Rx.RcvProdRing) {
5697 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
5698 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
5699 pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5700 break;
5701 #endif
5702 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
5703 pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5704 break;
5705 }
5706
5707 /* Check the error flag. */
5708 if(pRcvBd->ErrorFlag &&
5709 pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
5710 {
5711 pPacket->PacketStatus = LM_STATUS_FAILURE;
5712
5713 pDevice->RxCounters.RxPacketErrCnt++;
5714
5715 if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
5716 {
5717 pDevice->RxCounters.RxErrCrcCnt++;
5718 }
5719
5720 if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
5721 {
5722 pDevice->RxCounters.RxErrCollCnt++;
5723 }
5724
5725 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
5726 {
5727 pDevice->RxCounters.RxErrLinkLostCnt++;
5728 }
5729
5730 if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
5731 {
5732 pDevice->RxCounters.RxErrPhyDecodeCnt++;
5733 }
5734
5735 if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
5736 {
5737 pDevice->RxCounters.RxErrOddNibbleCnt++;
5738 }
5739
5740 if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
5741 {
5742 pDevice->RxCounters.RxErrMacAbortCnt++;
5743 }
5744
5745 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
5746 {
5747 pDevice->RxCounters.RxErrShortPacketCnt++;
5748 }
5749
5750 if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
5751 {
5752 pDevice->RxCounters.RxErrNoResourceCnt++;
5753 }
5754
5755 if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
5756 {
5757 pDevice->RxCounters.RxErrLargePacketCnt++;
5758 }
5759 }
5760 else
5761 {
5762 pPacket->PacketStatus = LM_STATUS_SUCCESS;
5763 pPacket->PacketSize = pRcvBd->Len - 4;
5764
5765 pPacket->Flags = pRcvBd->Flags;
5766 if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
5767 {
5768 pPacket->VlanTag = pRcvBd->VlanTag;
5769 }
5770
5771 pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
5772 }
5773
5774 /* Put the packet descriptor containing the received packet */
5775 /* buffer in the RxPacketReceivedQ for indication later. */
5776 QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
5777
5778 /* Go to the next buffer descriptor. */
5779 SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
5780 pDevice->RcvRetRcbEntryCountMask;
5781
5782 if (++received >= limit)
5783 {
5784 break;
5785 }
5786 } /* while */
5787
5788 pDevice->RcvRetConIdx = SwRcvRetConIdx;
5789
5790 /* Update the receive return ring consumer index. */
5791 MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
5792 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
5793 {
5794 MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
5795 }
5796 else
5797 {
5798 MM_MMIOWB();
5799 }
5800 return received;
5801 } /* LM_ServiceRxPoll */
5802 #endif /* BCM_NAPI_RXPOLL */
5803
5804
5805 /******************************************************************************/
5806 /* Description: */
5807 /* */
5808 /* Return: */
5809 /******************************************************************************/
5810 void
5811 LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice)
5812 {
5813 #ifndef BCM_NAPI_RXPOLL
5814 PLM_PACKET pPacket;
5815 PT3_RCV_BD pRcvBd;
5816 #endif
5817 LM_UINT32 HwRcvRetProdIdx;
5818 LM_UINT32 SwRcvRetConIdx;
5819
5820 /* Loop thru the receive return rings for received packets. */
5821 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
5822
5823 SwRcvRetConIdx = pDevice->RcvRetConIdx;
5824 #ifdef BCM_NAPI_RXPOLL
5825 if (!pDevice->RxPoll)
5826 {
5827 if (SwRcvRetConIdx != HwRcvRetProdIdx)
5828 {
5829 if (MM_ScheduleRxPoll(pDevice) == LM_STATUS_SUCCESS)
5830 {
5831 pDevice->RxPoll = TRUE;
5832 REG_WR(pDevice, Grc.Mode,
5833 pDevice->GrcMode | GRC_MODE_NO_INTERRUPT_ON_RECEIVE);
5834 }
5835 }
5836 }
5837 #else
5838 MM_RMB();
5839 while(SwRcvRetConIdx != HwRcvRetProdIdx)
5840 {
5841 pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
5842
5843 /* Get the received packet descriptor. */
5844 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
5845 MM_UINT_PTR(pRcvBd->Opaque));
5846
5847 switch(pPacket->u.Rx.RcvProdRing) {
5848 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
5849 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
5850 pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5851 break;
5852 #endif
5853 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
5854 pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5855 break;
5856 }
5857
5858 /* Check the error flag. */
5859 if(pRcvBd->ErrorFlag &&
5860 pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
5861 {
5862 pPacket->PacketStatus = LM_STATUS_FAILURE;
5863
5864 pDevice->RxCounters.RxPacketErrCnt++;
5865
5866 if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
5867 {
5868 pDevice->RxCounters.RxErrCrcCnt++;
5869 }
5870
5871 if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
5872 {
5873 pDevice->RxCounters.RxErrCollCnt++;
5874 }
5875
5876 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
5877 {
5878 pDevice->RxCounters.RxErrLinkLostCnt++;
5879 }
5880
5881 if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
5882 {
5883 pDevice->RxCounters.RxErrPhyDecodeCnt++;
5884 }
5885
5886 if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
5887 {
5888 pDevice->RxCounters.RxErrOddNibbleCnt++;
5889 }
5890
5891 if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
5892 {
5893 pDevice->RxCounters.RxErrMacAbortCnt++;
5894 }
5895
5896 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
5897 {
5898 pDevice->RxCounters.RxErrShortPacketCnt++;
5899 }
5900
5901 if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
5902 {
5903 pDevice->RxCounters.RxErrNoResourceCnt++;
5904 }
5905
5906 if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
5907 {
5908 pDevice->RxCounters.RxErrLargePacketCnt++;
5909 }
5910 }
5911 else
5912 {
5913 pPacket->PacketStatus = LM_STATUS_SUCCESS;
5914 pPacket->PacketSize = pRcvBd->Len - 4;
5915
5916 pPacket->Flags = pRcvBd->Flags;
5917 if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
5918 {
5919 pPacket->VlanTag = pRcvBd->VlanTag;
5920 }
5921
5922 pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
5923 }
5924
5925 /* Put the packet descriptor containing the received packet */
5926 /* buffer in the RxPacketReceivedQ for indication later. */
5927 QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
5928
5929 /* Go to the next buffer descriptor. */
5930 SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
5931 pDevice->RcvRetRcbEntryCountMask;
5932
5933 } /* while */
5934
5935 pDevice->RcvRetConIdx = SwRcvRetConIdx;
5936
5937 /* Update the receive return ring consumer index. */
5938 MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
5939 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
5940 {
5941 MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
5942 }
5943 else
5944 {
5945 MM_MMIOWB();
5946 }
5947
5948 #endif
5949 } /* LM_ServiceRxInterrupt */
5950
5951
5952
5953 /******************************************************************************/
5954 /* Description: */
5955 /* This is the interrupt event handler routine. It acknowledges all */
5956 /* pending interrupts and process all pending events. */
5957 /* */
5958 /* Return: */
5959 /* LM_STATUS_SUCCESS */
5960 /******************************************************************************/
5961 LM_STATUS
5962 LM_ServiceInterrupts(
5963 PLM_DEVICE_BLOCK pDevice)
5964 {
5965 LM_UINT32 Value32;
5966 int ServicePhyInt = FALSE;
5967
5968 /* Setup the phy chip whenever the link status changes. */
5969 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
5970 {
5971 Value32 = REG_RD(pDevice, MacCtrl.Status);
5972 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5973 {
5974 if (Value32 & MAC_STATUS_MI_INTERRUPT)
5975 {
5976 ServicePhyInt = TRUE;
5977 }
5978 }
5979 else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
5980 {
5981 ServicePhyInt = TRUE;
5982 }
5983 }
5984 else
5985 {
5986 if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
5987 {
5988 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
5989 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
5990 ServicePhyInt = TRUE;
5991 }
5992 }
5993 #ifdef INCLUDE_TBI_SUPPORT
5994 if (pDevice->IgnoreTbiLinkChange == TRUE)
5995 {
5996 ServicePhyInt = FALSE;
5997 }
5998 #endif
5999 if (ServicePhyInt == TRUE)
6000 {
6001 MM_ACQUIRE_PHY_LOCK_IN_IRQ(pDevice);
6002 LM_SetupPhy(pDevice);
6003 MM_RELEASE_PHY_LOCK_IN_IRQ(pDevice);
6004 }
6005
6006 /* Service receive and transmit interrupts. */
6007 LM_ServiceRxInterrupt(pDevice);
6008 LM_ServiceTxInterrupt(pDevice);
6009
6010 #ifndef BCM_NAPI_RXPOLL
6011 /* No spinlock for this queue since this routine is serialized. */
6012 if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
6013 {
6014 /* Indicate receive packets. */
6015 MM_IndicateRxPackets(pDevice);
6016 }
6017 #endif
6018
6019 /* No spinlock for this queue since this routine is serialized. */
6020 if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
6021 {
6022 MM_IndicateTxPackets(pDevice);
6023 }
6024
6025 return LM_STATUS_SUCCESS;
6026 } /* LM_ServiceInterrupts */
6027
6028
6029 /******************************************************************************/
6030 /* Description: Add a Multicast address. Note that MC addresses, once added, */
6031 /* cannot be individually deleted. All addresses must be */
6032 /* cleared. */
6033 /* */
6034 /* Return: */
6035 /******************************************************************************/
6036 LM_STATUS
6037 LM_MulticastAdd(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
6038 {
6039
6040 LM_UINT32 RegIndex;
6041 LM_UINT32 Bitpos;
6042 LM_UINT32 Crc32;
6043
6044 Crc32 = ComputeCrc32(pMcAddress, ETHERNET_ADDRESS_SIZE);
6045
6046 /* The most significant 7 bits of the CRC32 (no inversion), */
6047 /* are used to index into one of the possible 128 bit positions. */
6048 Bitpos = ~Crc32 & 0x7f;
6049
6050 /* Hash register index. */
6051 RegIndex = (Bitpos & 0x60) >> 5;
6052
6053 /* Bit to turn on within a hash register. */
6054 Bitpos &= 0x1f;
6055
6056 /* Enable the multicast bit. */
6057 pDevice->MulticastHash[RegIndex] |= (1 << Bitpos);
6058
6059 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
6060
6061 return LM_STATUS_SUCCESS;
6062 }
6063
6064
6065 /******************************************************************************/
6066 /* Description: */
6067 /* */
6068 /* Return: */
6069 /******************************************************************************/
6070 LM_STATUS
6071 LM_MulticastDel(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
6072 {
6073 return LM_STATUS_FAILURE;
6074 } /* LM_MulticastDel */
6075
6076
6077
6078 /******************************************************************************/
6079 /* Description: */
6080 /* */
6081 /* Return: */
6082 /******************************************************************************/
6083 LM_STATUS
6084 LM_MulticastClear(LM_DEVICE_BLOCK *pDevice)
6085 {
6086 int i;
6087
6088 for (i = 0; i < 4; i++)
6089 {
6090 pDevice->MulticastHash[i] = 0;
6091 }
6092 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
6093
6094 return LM_STATUS_SUCCESS;
6095 } /* LM_MulticastClear */
6096
6097
6098
6099 /******************************************************************************/
6100 /* Description: */
6101 /* */
6102 /* Return: */
6103 /******************************************************************************/
6104 LM_STATUS
6105 LM_SetMacAddress(
6106 PLM_DEVICE_BLOCK pDevice,
6107 PLM_UINT8 pMacAddress)
6108 {
6109 LM_UINT32 j;
6110
6111 for(j = 0; j < 4; j++)
6112 {
6113 REG_WR(pDevice, MacCtrl.MacAddr[j].High,
6114 (pMacAddress[0] << 8) | pMacAddress[1]);
6115 REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
6116 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
6117 (pMacAddress[4] << 8) | pMacAddress[5]);
6118 }
6119
6120 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
6121 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
6122 {
6123 for (j = 0; j < 12; j++)
6124 {
6125 REG_WR(pDevice, MacCtrl.MacAddrExt[j].High,
6126 (pMacAddress[0] << 8) | pMacAddress[1]);
6127 REG_WR(pDevice, MacCtrl.MacAddrExt[j].Low,
6128 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
6129 (pMacAddress[4] << 8) | pMacAddress[5]);
6130 }
6131 }
6132 return LM_STATUS_SUCCESS;
6133 }
6134
6135 LM_VOID
6136 LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice)
6137 {
6138 /* Turn off tap power management. */
6139 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6140 {
6141 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
6142 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
6143 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
6144 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
6145 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
6146 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
6147 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
6148 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
6149 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
6150 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
6151 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
6152
6153 MM_Wait(40);
6154 }
6155 }
6156
6157 /******************************************************************************/
6158 /* Description: */
6159 /* */
6160 /* Return: */
6161 /* LM_STATUS_LINK_ACTIVE */
6162 /* LM_STATUS_LINK_DOWN */
6163 /******************************************************************************/
6164 static LM_STATUS
6165 LM_InitBcm540xPhy(
6166 PLM_DEVICE_BLOCK pDevice)
6167 {
6168 LM_LINE_SPEED CurrentLineSpeed;
6169 LM_DUPLEX_MODE CurrentDuplexMode;
6170 LM_STATUS CurrentLinkStatus;
6171 LM_UINT32 Value32;
6172 LM_UINT32 j;
6173 robo_info_t *robo;
6174
6175 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
6176
6177 if ((pDevice->PhyFlags & PHY_RESET_ON_LINKDOWN) &&
6178 (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE))
6179 {
6180 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6181 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6182 if(!(Value32 & PHY_STATUS_LINK_PASS))
6183 {
6184 LM_ResetPhy(pDevice);
6185 }
6186 }
6187 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6188 {
6189 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6190 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6191
6192 if(!pDevice->InitDone)
6193 {
6194 Value32 = 0;
6195 }
6196
6197 if(!(Value32 & PHY_STATUS_LINK_PASS))
6198 {
6199 LM_PhyTapPowerMgmt(pDevice);
6200
6201 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6202 for(j = 0; j < 1000; j++)
6203 {
6204 MM_Wait(10);
6205
6206 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6207 if(Value32 & PHY_STATUS_LINK_PASS)
6208 {
6209 MM_Wait(40);
6210 break;
6211 }
6212 }
6213
6214 if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
6215 {
6216 if(!(Value32 & PHY_STATUS_LINK_PASS) &&
6217 (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
6218 {
6219 LM_ResetPhy(pDevice);
6220 }
6221 }
6222 }
6223 }
6224 else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
6225 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
6226 {
6227 LM_WritePhy(pDevice, 0x15, 0x0a75);
6228 LM_WritePhy(pDevice, 0x1c, 0x8c68);
6229 LM_WritePhy(pDevice, 0x1c, 0x8d68);
6230 LM_WritePhy(pDevice, 0x1c, 0x8c68);
6231 }
6232
6233 /* Acknowledge interrupts. */
6234 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
6235 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
6236
6237 /* Configure the interrupt mask. */
6238 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
6239 {
6240 LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
6241 }
6242
6243 /* Configure PHY led mode. */
6244 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
6245 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
6246 {
6247 if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_1)
6248 {
6249 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
6250 BCM540X_EXT_CTRL_LINK3_LED_MODE);
6251 }
6252 else
6253 {
6254 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
6255 }
6256 }
6257 else if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5461_PHY_ID)
6258 {
6259 /*
6260 ** Set up the 'link' LED for the 4785+5461 combo,
6261 ** using the INTR/ENERGYDET pin (on the BCM4785 bringup board).
6262 */
6263 LM_WritePhy( pDevice,
6264 BCM546X_1c_SHADOW_REG,
6265 (BCM546X_1c_SPR_CTRL_2 | BCM546X_1c_WR_EN | BCM546X_1c_SP2_NRG_DET) );
6266
6267 /*
6268 ** Set up the LINK LED mode for the 4785+5461 combo,
6269 ** using the 5461 SLAVE/ANEN pin (on the BCM4785 bringup board) as
6270 ** active low link status (phy ready) feedback to the 4785
6271 */
6272 LM_WritePhy( pDevice,
6273 BCM546X_1c_SHADOW_REG,
6274 (BCM546X_1c_SPR_CTRL_1 | BCM546X_1c_WR_EN | BCM546X_1c_SP1_LINK_LED) );
6275 }
6276
6277 if (pDevice->PhyFlags & PHY_CAPACITIVE_COUPLING)
6278 {
6279 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4007);
6280 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &Value32);
6281 if (!(Value32 & BIT_10))
6282 {
6283 /* set the bit and re-link */
6284 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, Value32 | BIT_10);
6285 return LM_STATUS_LINK_SETTING_MISMATCH;
6286 }
6287 }
6288
6289 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
6290
6291 if(UNKNOWN_PHY_ID(pDevice->PhyId) && (pDevice->Flags & ROBO_SWITCH_FLAG)) {
6292 B57_INFO(("Force to active link of 1000 MBPS and full duplex mod.\n"));
6293 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6294
6295 /* Set the line speed based on the robo switch type */
6296 robo = ((PUM_DEVICE_BLOCK)pDevice)->robo;
6297 if (robo->devid == DEVID5325)
6298 {
6299 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
6300 }
6301 else
6302 {
6303 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
6304 }
6305 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6306
6307 /* Save line settings. */
6308 pDevice->LineSpeed = CurrentLineSpeed;
6309 pDevice->DuplexMode = CurrentDuplexMode;
6310 } else {
6311
6312 /* Get current link and duplex mode. */
6313 for(j = 0; j < 100; j++)
6314 {
6315 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6316 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6317
6318 if(Value32 & PHY_STATUS_LINK_PASS)
6319 {
6320 break;
6321 }
6322 MM_Wait(40);
6323 }
6324
6325 if(Value32 & PHY_STATUS_LINK_PASS)
6326 {
6327
6328 /* Determine the current line and duplex settings. */
6329 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
6330 for(j = 0; j < 2000; j++)
6331 {
6332 MM_Wait(10);
6333
6334 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
6335 if(Value32)
6336 {
6337 break;
6338 }
6339 }
6340
6341 switch(Value32 & BCM540X_AUX_SPEED_MASK)
6342 {
6343 case BCM540X_AUX_10BASET_HD:
6344 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
6345 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6346 break;
6347
6348 case BCM540X_AUX_10BASET_FD:
6349 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
6350 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6351 break;
6352
6353 case BCM540X_AUX_100BASETX_HD:
6354 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
6355 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6356 break;
6357
6358 case BCM540X_AUX_100BASETX_FD:
6359 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
6360 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6361 break;
6362
6363 case BCM540X_AUX_100BASET_HD:
6364 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
6365 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6366 break;
6367
6368 case BCM540X_AUX_100BASET_FD:
6369 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
6370 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6371 break;
6372
6373 default:
6374
6375 CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
6376 CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
6377 break;
6378 }
6379
6380 /* Make sure we are in auto-neg mode. */
6381 for (j = 0; j < 200; j++)
6382 {
6383 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
6384 if(Value32 && Value32 != 0x7fff)
6385 {
6386 break;
6387 }
6388
6389 if(Value32 == 0 &&
6390 pDevice->RequestedLineSpeed == LM_LINE_SPEED_10MBPS &&
6391 pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_HALF)
6392 {
6393 break;
6394 }
6395
6396 MM_Wait(10);
6397 }
6398
6399 /* Use the current line settings for "auto" mode. */
6400 if(pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
6401 {
6402 if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
6403 {
6404 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6405
6406 /* We may be exiting low power mode and the link is in */
6407 /* 10mb. In this case, we need to restart autoneg. */
6408
6409 if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
6410 {
6411 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6412 }
6413 }
6414 else
6415 {
6416 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6417 }
6418 }
6419 else
6420 {
6421 /* Force line settings. */
6422 /* Use the current setting if it matches the user's requested */
6423 /* setting. */
6424 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
6425 if((pDevice->LineSpeed == CurrentLineSpeed) &&
6426 (pDevice->DuplexMode == CurrentDuplexMode))
6427 {
6428 if ((pDevice->DisableAutoNeg &&
6429 !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
6430 (!pDevice->DisableAutoNeg &&
6431 (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
6432 {
6433 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6434 }
6435 else
6436 {
6437 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6438 }
6439 }
6440 else
6441 {
6442 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6443 }
6444 }
6445
6446 /* Save line settings. */
6447 pDevice->LineSpeed = CurrentLineSpeed;
6448 pDevice->DuplexMode = CurrentDuplexMode;
6449 }
6450 }
6451
6452 return CurrentLinkStatus;
6453 } /* LM_InitBcm540xPhy */
6454
6455 /******************************************************************************/
6456 /* Description: */
6457 /* */
6458 /* Return: */
6459 /******************************************************************************/
6460 LM_STATUS
6461 LM_SetFlowControl(
6462 PLM_DEVICE_BLOCK pDevice,
6463 LM_UINT32 LocalPhyAd,
6464 LM_UINT32 RemotePhyAd)
6465 {
6466 LM_FLOW_CONTROL FlowCap;
6467
6468 /* Resolve flow control. */
6469 FlowCap = LM_FLOW_CONTROL_NONE;
6470
6471 /* See Table 28B-3 of 802.3ab-1999 spec. */
6472 if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
6473 {
6474 if(pDevice->PhyFlags & PHY_IS_FIBER){
6475 LocalPhyAd &= ~(PHY_AN_AD_ASYM_PAUSE |
6476 PHY_AN_AD_PAUSE_CAPABLE);
6477 RemotePhyAd &= ~(PHY_AN_AD_ASYM_PAUSE |
6478 PHY_AN_AD_PAUSE_CAPABLE);
6479
6480 if (LocalPhyAd & PHY_AN_AD_1000XPAUSE)
6481 LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
6482 if (LocalPhyAd & PHY_AN_AD_1000XPSE_ASYM)
6483 LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
6484 if (RemotePhyAd & PHY_AN_AD_1000XPAUSE)
6485 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
6486 if (RemotePhyAd & PHY_AN_AD_1000XPSE_ASYM)
6487 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
6488 }
6489
6490 if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
6491 {
6492 if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6493 {
6494 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
6495 {
6496 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
6497 LM_FLOW_CONTROL_RECEIVE_PAUSE;
6498 }
6499 else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
6500 {
6501 FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
6502 }
6503 }
6504 else
6505 {
6506 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
6507 {
6508 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
6509 LM_FLOW_CONTROL_RECEIVE_PAUSE;
6510 }
6511 }
6512 }
6513 else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6514 {
6515 if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
6516 (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
6517 {
6518 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
6519 }
6520 }
6521 }
6522 else
6523 {
6524 FlowCap = pDevice->FlowControlCap;
6525 }
6526
6527 pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
6528
6529 /* Enable/disable rx PAUSE. */
6530 pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
6531 if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
6532 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
6533 pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
6534 {
6535 pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
6536 pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
6537
6538 }
6539 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
6540
6541 /* Enable/disable tx PAUSE. */
6542 pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
6543 if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
6544 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
6545 pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
6546 {
6547 pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
6548 pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
6549
6550 }
6551 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
6552
6553 return LM_STATUS_SUCCESS;
6554 }
6555
6556
6557 #ifdef INCLUDE_TBI_SUPPORT
6558 /******************************************************************************/
6559 /* Description: */
6560 /* */
6561 /* Return: */
6562 /******************************************************************************/
6563 STATIC LM_STATUS
6564 LM_InitBcm800xPhy(
6565 PLM_DEVICE_BLOCK pDevice)
6566 {
6567 LM_UINT32 Value32;
6568 LM_UINT32 j;
6569
6570
6571 Value32 = REG_RD(pDevice, MacCtrl.Status);
6572
6573 /* Reset the SERDES during init and when we have link. */
6574 if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
6575 {
6576 /* Set PLL lock range. */
6577 LM_WritePhy(pDevice, 0x16, 0x8007);
6578
6579 /* Software reset. */
6580 LM_WritePhy(pDevice, 0x00, 0x8000);
6581
6582 /* Wait for reset to complete. */
6583 for(j = 0; j < 500; j++)
6584 {
6585 MM_Wait(10);
6586 }
6587
6588 /* Config mode; seletct PMA/Ch 1 regs. */
6589 LM_WritePhy(pDevice, 0x10, 0x8411);
6590
6591 /* Enable auto-lock and comdet, select txclk for tx. */
6592 LM_WritePhy(pDevice, 0x11, 0x0a10);
6593
6594 LM_WritePhy(pDevice, 0x18, 0x00a0);
6595 LM_WritePhy(pDevice, 0x16, 0x41ff);
6596
6597 /* Assert and deassert POR. */
6598 LM_WritePhy(pDevice, 0x13, 0x0400);
6599 MM_Wait(40);
6600 LM_WritePhy(pDevice, 0x13, 0x0000);
6601
6602 LM_WritePhy(pDevice, 0x11, 0x0a50);
6603 MM_Wait(40);
6604 LM_WritePhy(pDevice, 0x11, 0x0a10);
6605
6606 /* Delay for signal to stabilize. */
6607 for(j = 0; j < 15000; j++)
6608 {
6609 MM_Wait(10);
6610 }
6611
6612 /* Deselect the channel register so we can read the PHY id later. */
6613 LM_WritePhy(pDevice, 0x10, 0x8011);
6614 }
6615
6616 return LM_STATUS_SUCCESS;
6617 }
6618
6619
6620
6621 /******************************************************************************/
6622 /* Description: */
6623 /* */
6624 /* Return: */
6625 /******************************************************************************/
6626 STATIC LM_STATUS
6627 LM_SetupFiberPhy(
6628 PLM_DEVICE_BLOCK pDevice)
6629 {
6630 LM_STATUS CurrentLinkStatus;
6631 AUTONEG_STATUS AnStatus = 0;
6632 LM_UINT32 Value32;
6633 LM_UINT32 Cnt;
6634 LM_UINT32 j, k;
6635 LM_UINT32 MacStatus, RemotePhyAd, LocalPhyAd;
6636 LM_FLOW_CONTROL PreviousFlowControl = pDevice->FlowControl;
6637
6638
6639 if (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE)
6640 {
6641 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
6642 MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
6643 return LM_STATUS_SUCCESS;
6644 }
6645
6646
6647 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
6648 (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) && pDevice->InitDone)
6649 {
6650 MacStatus = REG_RD(pDevice, MacCtrl.Status);
6651 if ((MacStatus & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED |
6652 MAC_STATUS_CFG_CHANGED | MAC_STATUS_RECEIVING_CFG))
6653 == (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED))
6654 {
6655
6656 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
6657 MAC_STATUS_CFG_CHANGED);
6658 return LM_STATUS_SUCCESS;
6659 }
6660 }
6661 pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
6662
6663 /* Initialize the send_config register. */
6664 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
6665
6666 pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
6667 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6668 MM_Wait(10);
6669
6670 /* Initialize the BCM8002 SERDES PHY. */
6671 switch(pDevice->PhyId & PHY_ID_MASK)
6672 {
6673 case PHY_BCM8002_PHY_ID:
6674 LM_InitBcm800xPhy(pDevice);
6675 break;
6676
6677 default:
6678 break;
6679 }
6680
6681 /* Enable link change interrupt. */
6682 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
6683
6684 /* Default to link down. */
6685 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
6686
6687 /* Get the link status. */
6688 MacStatus = REG_RD(pDevice, MacCtrl.Status);
6689
6690 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
6691 {
6692 LM_UINT32 SgDigCtrl, SgDigStatus;
6693 LM_UINT32 SerdesCfg = 0;
6694 LM_UINT32 ExpectedSgDigCtrl = 0;
6695 LM_UINT32 WorkAround = 0;
6696 LM_UINT32 PortA = 1;
6697
6698 if ((pDevice->ChipRevId != T3_CHIP_ID_5704_A0) &&
6699 (pDevice->ChipRevId != T3_CHIP_ID_5704_A1))
6700 {
6701 WorkAround = 1;
6702 if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
6703 {
6704 PortA = 0;
6705 }
6706
6707 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6708 {
6709 /* Save voltage reg bits & bits 14:0 */
6710 SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
6711 (BIT_23 | BIT_22 | BIT_21 | BIT_20 | 0x7fff );
6712
6713 }
6714 else
6715 {
6716 /* preserve the voltage regulator bits */
6717 SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
6718 (BIT_23 | BIT_22 | BIT_21 | BIT_20);
6719 }
6720 }
6721 SgDigCtrl = REG_RD(pDevice, MacCtrl.SgDigControl);
6722 if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
6723 (pDevice->DisableAutoNeg == FALSE))
6724 {
6725
6726 ExpectedSgDigCtrl = 0x81388400;
6727 LocalPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
6728 if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
6729 {
6730 ExpectedSgDigCtrl |= BIT_11;
6731 }
6732 if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6733 {
6734 ExpectedSgDigCtrl |= BIT_12;
6735 }
6736 if (SgDigCtrl != ExpectedSgDigCtrl)
6737 {
6738 if (WorkAround)
6739 {
6740 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6741 {
6742 REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011000 | SerdesCfg);
6743 }
6744 else
6745 {
6746 REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011880 | SerdesCfg);
6747 }
6748 }
6749 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl |
6750 BIT_30);
6751 REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
6752 MM_Wait(5);
6753 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl);
6754 pDevice->AutoNegJustInited = TRUE;
6755 }
6756 /* If autoneg is off, you only get SD when link is up */
6757 else if(MacStatus & (MAC_STATUS_PCS_SYNCED |
6758 MAC_STATUS_SIGNAL_DETECTED))
6759 {
6760 SgDigStatus = REG_RD(pDevice, MacCtrl.SgDigStatus);
6761 if ((SgDigStatus & BIT_1) &&
6762 (MacStatus & MAC_STATUS_PCS_SYNCED))
6763 {
6764 /* autoneg. completed */
6765 RemotePhyAd = 0;
6766 if(SgDigStatus & BIT_19)
6767 {
6768 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
6769 }
6770
6771 if(SgDigStatus & BIT_20)
6772 {
6773 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
6774 }
6775
6776 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
6777 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6778 pDevice->AutoNegJustInited = FALSE;
6779 }
6780 else if (!(SgDigStatus & BIT_1))
6781 {
6782 if (pDevice->AutoNegJustInited == TRUE)
6783 {
6784 /* we may be checking too soon, so check again */
6785 /* at the next poll interval */
6786 pDevice->AutoNegJustInited = FALSE;
6787 }
6788 else
6789 {
6790 /* autoneg. failed */
6791 if (WorkAround)
6792 {
6793 if (PortA)
6794 {
6795 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6796 {
6797 REG_WR(pDevice, MacCtrl.SerdesCfg,
6798 0xc010000 | (SerdesCfg & ~0x00001000));
6799 }
6800 else
6801 {
6802 REG_WR(pDevice, MacCtrl.SerdesCfg,
6803 0xc010880 | SerdesCfg);
6804 }
6805 }
6806 else
6807 {
6808 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6809 {
6810 REG_WR(pDevice, MacCtrl.SerdesCfg,
6811 0x4010000 | (SerdesCfg & ~0x00001000));
6812 }
6813 else
6814 {
6815 REG_WR(pDevice, MacCtrl.SerdesCfg,
6816 0x4010880 | SerdesCfg);
6817 }
6818 }
6819 }
6820 /* turn off autoneg. to allow traffic to pass */
6821 REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
6822 REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
6823 MM_Wait(40);
6824 MacStatus = REG_RD(pDevice, MacCtrl.Status);
6825 if ((MacStatus & MAC_STATUS_PCS_SYNCED) && !(MacStatus & MAC_STATUS_RECEIVING_CFG))
6826 {
6827 LM_SetFlowControl(pDevice, 0, 0);
6828 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6829 }
6830 }
6831 }
6832 }
6833 }
6834 else
6835 {
6836 if (SgDigCtrl & BIT_31) {
6837 if (WorkAround)
6838 {
6839 if (PortA)
6840 {
6841
6842 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6843 {
6844 REG_WR(pDevice, MacCtrl.SerdesCfg,
6845 0xc010000 | (SerdesCfg & ~0x00001000));
6846 }
6847 else
6848 {
6849 REG_WR(pDevice, MacCtrl.SerdesCfg,
6850 0xc010880 | SerdesCfg);
6851 }
6852 }
6853 else
6854 {
6855 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6856 {
6857 REG_WR(pDevice, MacCtrl.SerdesCfg,
6858 0x4010000 | (SerdesCfg & ~0x00001000));
6859 }
6860 else
6861 {
6862 REG_WR(pDevice, MacCtrl.SerdesCfg,
6863 0x4010880 | SerdesCfg);
6864 }
6865 }
6866 }
6867 REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
6868 }
6869 if(MacStatus & MAC_STATUS_PCS_SYNCED)
6870 {
6871 LM_SetFlowControl(pDevice, 0, 0);
6872 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6873 }
6874 }
6875 }
6876 else if(MacStatus & MAC_STATUS_PCS_SYNCED)
6877 {
6878 if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
6879 (pDevice->DisableAutoNeg == FALSE))
6880 {
6881 /* auto-negotiation mode. */
6882 /* Initialize the autoneg default capaiblities. */
6883 AutonegInit(&pDevice->AnInfo);
6884
6885 /* Set the context pointer to point to the main device structure. */
6886 pDevice->AnInfo.pContext = pDevice;
6887
6888 /* Setup flow control advertisement register. */
6889 Value32 = GetPhyAdFlowCntrlSettings(pDevice);
6890 if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
6891 {
6892 pDevice->AnInfo.mr_adv_sym_pause = 1;
6893 }
6894 else
6895 {
6896 pDevice->AnInfo.mr_adv_sym_pause = 0;
6897 }
6898
6899 if(Value32 & PHY_AN_AD_ASYM_PAUSE)
6900 {
6901 pDevice->AnInfo.mr_adv_asym_pause = 1;
6902 }
6903 else
6904 {
6905 pDevice->AnInfo.mr_adv_asym_pause = 0;
6906 }
6907
6908 /* Try to autoneg up to six times. */
6909 if (pDevice->IgnoreTbiLinkChange)
6910 {
6911 Cnt = 1;
6912 }
6913 else
6914 {
6915 Cnt = 6;
6916 }
6917 for (j = 0; j < Cnt; j++)
6918 {
6919 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
6920
6921 Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
6922 REG_WR(pDevice, MacCtrl.Mode, Value32);
6923 REG_RD_BACK(pDevice, MacCtrl.Mode);
6924 MM_Wait(20);
6925
6926 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
6927 MAC_MODE_SEND_CONFIGS);
6928 REG_RD_BACK(pDevice, MacCtrl.Mode);
6929
6930 MM_Wait(20);
6931
6932 pDevice->AnInfo.State = AN_STATE_UNKNOWN;
6933 pDevice->AnInfo.CurrentTime_us = 0;
6934
6935 REG_WR(pDevice, Grc.Timer, 0);
6936 for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
6937 (k < 75000); k++)
6938 {
6939 AnStatus = Autoneg8023z(&pDevice->AnInfo);
6940
6941 if((AnStatus == AUTONEG_STATUS_DONE) ||
6942 (AnStatus == AUTONEG_STATUS_FAILED))
6943 {
6944 break;
6945 }
6946
6947 pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
6948
6949 }
6950 if((AnStatus == AUTONEG_STATUS_DONE) ||
6951 (AnStatus == AUTONEG_STATUS_FAILED))
6952 {
6953 break;
6954 }
6955 if (j >= 1)
6956 {
6957 if (!(REG_RD(pDevice, MacCtrl.Status) &
6958 MAC_STATUS_PCS_SYNCED)) {
6959 break;
6960 }
6961 }
6962 }
6963
6964 /* Stop sending configs. */
6965 MM_AnTxIdle(&pDevice->AnInfo);
6966
6967 /* Resolve flow control settings. */
6968 if((AnStatus == AUTONEG_STATUS_DONE) &&
6969 pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
6970 pDevice->AnInfo.mr_lp_adv_full_duplex)
6971 {
6972 LM_UINT32 RemotePhyAd;
6973 LM_UINT32 LocalPhyAd;
6974
6975 LocalPhyAd = 0;
6976 if(pDevice->AnInfo.mr_adv_sym_pause)
6977 {
6978 LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
6979 }
6980
6981 if(pDevice->AnInfo.mr_adv_asym_pause)
6982 {
6983 LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
6984 }
6985
6986 RemotePhyAd = 0;
6987 if(pDevice->AnInfo.mr_lp_adv_sym_pause)
6988 {
6989 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
6990 }
6991
6992 if(pDevice->AnInfo.mr_lp_adv_asym_pause)
6993 {
6994 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
6995 }
6996
6997 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
6998
6999 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7000 }
7001 else
7002 {
7003 LM_SetFlowControl(pDevice, 0, 0);
7004 }
7005 for (j = 0; j < 30; j++)
7006 {
7007 MM_Wait(20);
7008 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7009 MAC_STATUS_CFG_CHANGED);
7010 REG_RD_BACK(pDevice, MacCtrl.Status);
7011 MM_Wait(20);
7012 if ((REG_RD(pDevice, MacCtrl.Status) &
7013 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
7014 break;
7015 }
7016 if (pDevice->TbiFlags & TBI_POLLING_FLAGS)
7017 {
7018 Value32 = REG_RD(pDevice, MacCtrl.Status);
7019 if (Value32 & MAC_STATUS_RECEIVING_CFG)
7020 {
7021 pDevice->IgnoreTbiLinkChange = TRUE;
7022 }
7023 else if (pDevice->TbiFlags & TBI_POLLING_INTR_FLAG)
7024 {
7025 pDevice->IgnoreTbiLinkChange = FALSE;
7026 }
7027 }
7028 Value32 = REG_RD(pDevice, MacCtrl.Status);
7029 if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
7030 (Value32 & MAC_STATUS_PCS_SYNCED) &&
7031 ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
7032 {
7033 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7034 }
7035 }
7036 else
7037 {
7038 /* We are forcing line speed. */
7039 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
7040 LM_SetFlowControl(pDevice, 0, 0);
7041
7042 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7043 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
7044 MAC_MODE_SEND_CONFIGS);
7045 }
7046 }
7047 /* Set the link polarity bit. */
7048 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7049 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7050
7051 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7052 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7053
7054 for (j = 0; j < 100; j++)
7055 {
7056 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7057 MAC_STATUS_CFG_CHANGED);
7058 REG_RD_BACK(pDevice, MacCtrl.Status);
7059 MM_Wait(5);
7060 if ((REG_RD(pDevice, MacCtrl.Status) &
7061 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
7062 break;
7063 }
7064
7065 Value32 = REG_RD(pDevice, MacCtrl.Status);
7066 if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
7067 {
7068 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7069 if (pDevice->DisableAutoNeg == FALSE)
7070 {
7071 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
7072 MAC_MODE_SEND_CONFIGS);
7073 REG_RD_BACK(pDevice, MacCtrl.Mode);
7074 MM_Wait(1);
7075 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7076 }
7077 }
7078
7079 /* Initialize the current link status. */
7080 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7081 {
7082 pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
7083 pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
7084 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
7085 LED_CTRL_OVERRIDE_LINK_LED |
7086 LED_CTRL_1000MBPS_LED_ON);
7087 }
7088 else
7089 {
7090 pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
7091 pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
7092 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
7093 LED_CTRL_OVERRIDE_LINK_LED |
7094 LED_CTRL_OVERRIDE_TRAFFIC_LED);
7095 }
7096
7097 /* Indicate link status. */
7098 if ((pDevice->LinkStatus != CurrentLinkStatus) ||
7099 ((CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
7100 (PreviousFlowControl != pDevice->FlowControl)))
7101 {
7102 pDevice->LinkStatus = CurrentLinkStatus;
7103 MM_IndicateStatus(pDevice, CurrentLinkStatus);
7104 }
7105
7106 return LM_STATUS_SUCCESS;
7107 }
7108 #endif /* INCLUDE_TBI_SUPPORT */
7109
7110
7111 /******************************************************************************/
7112 /* Description: */
7113 /* */
7114 /* Return: */
7115 /******************************************************************************/
7116 LM_STATUS
7117 LM_SetupCopperPhy(
7118 PLM_DEVICE_BLOCK pDevice)
7119 {
7120 LM_STATUS CurrentLinkStatus;
7121 LM_UINT32 Value32;
7122
7123 /* Assume there is not link first. */
7124 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7125
7126 /* Disable phy link change attention. */
7127 REG_WR(pDevice, MacCtrl.MacEvent, 0);
7128
7129 /* Clear link change attention. */
7130 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7131 MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
7132 MAC_STATUS_LINK_STATE_CHANGED);
7133
7134 /* Disable auto-polling for the moment. */
7135 pDevice->MiMode = 0xc0000;
7136 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
7137 REG_RD_BACK(pDevice, MacCtrl.MiMode);
7138 MM_Wait(40);
7139
7140 /* Determine the requested line speed and duplex. */
7141 pDevice->OldLineSpeed = pDevice->LineSpeed;
7142 /* Set line and duplex only if we don't have a Robo switch */
7143 if (!(pDevice->Flags & ROBO_SWITCH_FLAG)) {
7144 pDevice->LineSpeed = pDevice->RequestedLineSpeed;
7145 pDevice->DuplexMode = pDevice->RequestedDuplexMode;
7146 }
7147
7148 /* Set the phy to loopback mode. */
7149 if ((pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE) ||
7150 (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE))
7151 {
7152 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7153 if(!(Value32 & PHY_CTRL_LOOPBACK_MODE) &&
7154 (pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE))
7155 {
7156 /* Disable link change and PHY interrupts. */
7157 REG_WR(pDevice, MacCtrl.MacEvent, 0);
7158
7159 /* Clear link change attention. */
7160 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7161 MAC_STATUS_CFG_CHANGED);
7162
7163 LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
7164 MM_Wait(40);
7165
7166 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7167 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
7168 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 ||
7169 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
7170 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705 ||
7171 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 &&
7172 (pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID))
7173 {
7174 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7175 }
7176
7177 /* Prevent the interrupt handling from being called. */
7178 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7179 (pDevice->pStatusBlkVirt->Status &
7180 ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7181
7182 /* GMII interface. */
7183 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
7184 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7185 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7186 REG_RD_BACK(pDevice, MacCtrl.Mode);
7187 MM_Wait(40);
7188
7189 /* Configure PHY led mode. */
7190 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
7191 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
7192 {
7193 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
7194 BCM540X_EXT_CTRL_LINK3_LED_MODE);
7195 MM_Wait(40);
7196 }
7197
7198 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
7199 {
7200 int j = 0;
7201
7202 while (REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE)
7203 {
7204 MM_Wait(40);
7205 j++;
7206 if (j > 20)
7207 break;
7208 }
7209
7210 Value32 = DMA_WRITE_MODE_ENABLE |
7211 DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
7212 DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
7213 DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
7214 DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
7215 DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
7216 DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
7217 DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
7218 DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
7219 REG_WR(pDevice, DmaWrite.Mode, Value32);
7220 }
7221 }
7222
7223 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7224 MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
7225
7226 return LM_STATUS_SUCCESS;
7227 }
7228
7229 /* For Robo switch read PHY_CTRL_REG value as zero */
7230 if (pDevice->Flags & ROBO_SWITCH_FLAG)
7231 Value32 = 0;
7232 else
7233 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7234
7235 if(Value32 & PHY_CTRL_LOOPBACK_MODE)
7236 {
7237 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7238
7239 /* Re-enable link change interrupt. This was disabled when we */
7240 /* enter loopback mode. */
7241 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
7242 {
7243 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
7244 }
7245 else
7246 {
7247 REG_WR(pDevice, MacCtrl.MacEvent,
7248 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7249 }
7250 }
7251 else
7252 {
7253 /* Initialize the phy chip. */
7254 CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
7255 }
7256
7257 if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
7258 {
7259 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7260 }
7261
7262 /* Setup flow control. */
7263 pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
7264 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7265 {
7266 LM_FLOW_CONTROL FlowCap; /* Flow control capability. */
7267
7268 FlowCap = LM_FLOW_CONTROL_NONE;
7269
7270 if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
7271 {
7272 if(pDevice->DisableAutoNeg == FALSE ||
7273 pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
7274 {
7275 LM_UINT32 ExpectedPhyAd;
7276 LM_UINT32 LocalPhyAd;
7277 LM_UINT32 RemotePhyAd;
7278
7279 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
7280 pDevice->advertising = LocalPhyAd;
7281 LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
7282
7283 ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
7284
7285 if(LocalPhyAd != ExpectedPhyAd)
7286 {
7287 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7288 }
7289 else
7290 {
7291 LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
7292 &RemotePhyAd);
7293
7294 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
7295 }
7296 }
7297 else
7298 {
7299 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
7300 LM_SetFlowControl(pDevice, 0, 0);
7301 }
7302 }
7303 }
7304
7305 if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
7306 {
7307 LM_ForceAutoNeg(pDevice);
7308
7309 /* If we force line speed, we make get link right away. */
7310 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7311 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7312 if(Value32 & PHY_STATUS_LINK_PASS)
7313 {
7314 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7315 }
7316 }
7317
7318 /* GMII interface. */
7319 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
7320 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7321 {
7322 if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
7323 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
7324 {
7325 pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
7326 }
7327 else
7328 {
7329 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7330 }
7331 }
7332 else {
7333 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7334 }
7335
7336 /* In order for the 5750 core in BCM4785 chip to work properly
7337 * in RGMII mode, the Led Control Register must be set up.
7338 */
7339 if (pDevice->Flags & RGMII_MODE_FLAG)
7340 {
7341 LM_UINT32 LedCtrl_Reg;
7342
7343 LedCtrl_Reg = REG_RD(pDevice, MacCtrl.LedCtrl);
7344 LedCtrl_Reg &= ~(LED_CTRL_1000MBPS_LED_ON | LED_CTRL_100MBPS_LED_ON);
7345
7346 if(pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
7347 LedCtrl_Reg |= LED_CTRL_OVERRIDE_LINK_LED;
7348 else if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS)
7349 LedCtrl_Reg |= (LED_CTRL_OVERRIDE_LINK_LED | LED_CTRL_100MBPS_LED_ON);
7350 else /* LM_LINE_SPEED_1000MBPS */
7351 LedCtrl_Reg |= (LED_CTRL_OVERRIDE_LINK_LED | LED_CTRL_1000MBPS_LED_ON);
7352
7353 REG_WR(pDevice, MacCtrl.LedCtrl, LedCtrl_Reg);
7354
7355 MM_Wait(40);
7356 }
7357
7358 /* Set the MAC to operate in the appropriate duplex mode. */
7359 pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
7360 if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
7361 {
7362 pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
7363 }
7364
7365 /* Set the link polarity bit. */
7366 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7367 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
7368 {
7369 if((pDevice->LedCtrl == LED_CTRL_PHY_MODE_2) ||
7370 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
7371 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
7372 {
7373 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7374 }
7375 }
7376 else
7377 {
7378 if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7379 {
7380 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7381 }
7382 }
7383
7384 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7385
7386 /* Enable auto polling. */
7387 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
7388 {
7389 pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
7390 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
7391 }
7392 /* if using MAC led mode and not using auto polling, need to configure */
7393 /* mi status register */
7394 else if ((pDevice->LedCtrl &
7395 (LED_CTRL_PHY_MODE_1 | LED_CTRL_PHY_MODE_2)) == 0)
7396 {
7397 if (CurrentLinkStatus != LM_STATUS_LINK_ACTIVE)
7398 {
7399 REG_WR(pDevice, MacCtrl.MiStatus, 0);
7400 }
7401 else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
7402 {
7403 REG_WR(pDevice, MacCtrl.MiStatus,
7404 MI_STATUS_ENABLE_LINK_STATUS_ATTN | MI_STATUS_10MBPS);
7405 }
7406 else
7407 {
7408 REG_WR(pDevice, MacCtrl.MiStatus,
7409 MI_STATUS_ENABLE_LINK_STATUS_ATTN);
7410 }
7411 }
7412
7413 /* Enable phy link change attention. */
7414 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
7415 {
7416 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
7417 }
7418 else
7419 {
7420 REG_WR(pDevice, MacCtrl.MacEvent,
7421 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7422 }
7423 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
7424 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
7425 (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
7426 (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
7427 (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
7428 !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
7429 {
7430 MM_Wait(120);
7431 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7432 MAC_STATUS_CFG_CHANGED);
7433 MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
7434 T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
7435 }
7436
7437 /* Indicate link status. */
7438 if (pDevice->LinkStatus != CurrentLinkStatus) {
7439 pDevice->LinkStatus = CurrentLinkStatus;
7440 MM_IndicateStatus(pDevice, CurrentLinkStatus);
7441 }
7442
7443 return LM_STATUS_SUCCESS;
7444 } /* LM_SetupCopperPhy */
7445
7446
7447 void
7448 LM_5714_FamForceFiber(
7449 PLM_DEVICE_BLOCK pDevice)
7450 {
7451 LM_UINT32 Creg, new_bmcr;
7452 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7453
7454 new_bmcr = Creg & ~PHY_CTRL_AUTO_NEG_ENABLE;
7455
7456 if ( pDevice->RequestedDuplexMode == 0 ||
7457 pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_FULL){
7458
7459 new_bmcr |= PHY_CTRL_FULL_DUPLEX_MODE;
7460 }
7461
7462 if(Creg == new_bmcr)
7463 return;
7464
7465 new_bmcr |= PHY_CTRL_SPEED_SELECT_1000MBPS; /* Reserve bit */
7466
7467 /* Force a linkdown */
7468 LM_WritePhy(pDevice, PHY_AN_AD_REG, 0);
7469 LM_WritePhy(pDevice, PHY_CTRL_REG, new_bmcr |
7470 PHY_CTRL_RESTART_AUTO_NEG |
7471 PHY_CTRL_AUTO_NEG_ENABLE |
7472 PHY_CTRL_SPEED_SELECT_1000MBPS);
7473 MM_Wait(10);
7474
7475 /* Force it */
7476 LM_WritePhy(pDevice, PHY_CTRL_REG, new_bmcr);
7477 MM_Wait(10);
7478
7479 return;
7480
7481 }/* LM_5714_FamForceFiber */
7482
7483
7484 void
7485 LM_5714_FamGoFiberAutoNeg(
7486 PLM_DEVICE_BLOCK pDevice)
7487 {
7488 LM_UINT32 adv,Creg,new;
7489
7490 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7491 LM_ReadPhy(pDevice,PHY_AN_AD_REG, &adv);
7492
7493 new = adv & ~( PHY_AN_AD_1000XFULL |
7494 PHY_AN_AD_1000XHALF |
7495 PHY_AN_AD_1000XPAUSE |
7496 PHY_AN_AD_1000XPSE_ASYM |
7497 0x1f);
7498
7499 new |= PHY_AN_AD_1000XPAUSE;
7500
7501 new |= PHY_AN_AD_1000XFULL;
7502 new |= PHY_AN_AD_1000XHALF;
7503
7504 if ((new != adv) || !(Creg & PHY_CTRL_AUTO_NEG_ENABLE)){
7505 LM_WritePhy(pDevice, PHY_AN_AD_REG, new);
7506 MM_Wait(5);
7507 pDevice->AutoNegJustInited=1;
7508 LM_WritePhy(pDevice, PHY_CTRL_REG, (Creg |
7509 PHY_CTRL_RESTART_AUTO_NEG |
7510 PHY_CTRL_SPEED_SELECT_1000MBPS |
7511 PHY_CTRL_AUTO_NEG_ENABLE) );
7512 }
7513
7514 return;
7515 } /* 5714_FamGoFiberAutoNeg */
7516
7517
7518 void
7519 LM_5714_FamDoFiberLoopback(PLM_DEVICE_BLOCK pDevice)
7520 {
7521 LM_UINT32 Value32;
7522
7523 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7524
7525 if( !(Value32 & PHY_CTRL_LOOPBACK_MODE) )
7526 {
7527 LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
7528
7529 /* Prevent the interrupt handling from being called. */
7530 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7531 (pDevice->pStatusBlkVirt->Status &
7532 ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7533 }
7534
7535 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7536 MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
7537
7538 return;
7539
7540 }/* 5714_FamDoFiberLoopBack */
7541
7542
7543 /******************************************************************************/
7544 /* Description: */
7545 /* */
7546 /* Return: */
7547 /******************************************************************************/
7548
7549 LM_STATUS
7550 LM_SetupNewFiberPhy(
7551 PLM_DEVICE_BLOCK pDevice)
7552 {
7553 LM_STATUS LmStatus = LM_STATUS_SUCCESS;
7554 LM_UINT32 Creg,Sreg,rsav;
7555
7556 rsav = pDevice->LinkStatus;
7557
7558 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7559 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7560 MM_Wait(40);
7561
7562 /* Disable phy link change attention. */
7563 REG_WR(pDevice, MacCtrl.MacEvent, 0);
7564
7565 /* Clear link change attention. */
7566 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7567 MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
7568 MAC_STATUS_LINK_STATE_CHANGED);
7569
7570
7571 if( (pDevice->PhyFlags & PHY_FIBER_FALLBACK) &&
7572 ( pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ){
7573
7574 /* do nothing */
7575 }else if ( pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE){
7576
7577 LM_5714_FamDoFiberLoopback(pDevice);
7578 goto fiberloopbackreturn;
7579
7580 } else if( pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) {
7581
7582 LM_5714_FamGoFiberAutoNeg(pDevice);
7583
7584
7585 }else {
7586
7587 LM_5714_FamForceFiber(pDevice);
7588 }
7589 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Sreg);
7590 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Sreg);
7591
7592 if(Sreg & PHY_STATUS_LINK_PASS){
7593
7594 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7595 pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
7596
7597 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7598
7599 if(Creg & PHY_CTRL_FULL_DUPLEX_MODE) {
7600 pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
7601 }else{
7602 pDevice->DuplexMode = LM_DUPLEX_MODE_HALF;
7603 pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
7604 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7605 }
7606
7607 if(Creg & PHY_CTRL_AUTO_NEG_ENABLE){
7608 LM_UINT32 ours,partner;
7609
7610 LM_ReadPhy(pDevice,PHY_AN_AD_REG, &ours);
7611 LM_ReadPhy(pDevice,PHY_LINK_PARTNER_ABILITY_REG, &partner);
7612 LM_SetFlowControl(pDevice, ours, partner);
7613 }
7614
7615 }else{
7616 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
7617 pDevice->LineSpeed = 0;
7618 }
7619
7620 if(rsav != pDevice->LinkStatus)
7621 MM_IndicateStatus(pDevice, pDevice->LinkStatus);
7622
7623 fiberloopbackreturn:
7624 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7625 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7626 MM_Wait(40);
7627 /* Enable link change interrupt. */
7628 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7629
7630 return LmStatus;
7631 } /* Setup New phy */
7632
7633 void
7634 LM_5714_FamFiberCheckLink(
7635 PLM_DEVICE_BLOCK pDevice)
7636 {
7637
7638 if(pDevice->AutoNegJustInited){
7639 pDevice->AutoNegJustInited=0;
7640 return;
7641 }
7642
7643 if ((pDevice->LinkStatus != LM_STATUS_LINK_ACTIVE) &&
7644 (pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) &&
7645 !(pDevice->PhyFlags & PHY_FIBER_FALLBACK)){
7646 LM_UINT32 bmcr;
7647
7648 LM_ReadPhy(pDevice, PHY_CTRL_REG, &bmcr);
7649 if (bmcr & PHY_CTRL_AUTO_NEG_ENABLE) {
7650 LM_UINT32 phy1, phy2;
7651
7652 LM_WritePhy(pDevice, 0x1c, 0x7c00);
7653 LM_ReadPhy(pDevice, 0x1c, &phy1);
7654
7655 LM_WritePhy(pDevice, 0x17, 0x0f01);
7656 LM_ReadPhy(pDevice, 0x15, &phy2);
7657 LM_ReadPhy(pDevice, 0x15, &phy2);
7658
7659 if ((phy1 & 0x10) && !(phy2 & 0x20)) {
7660
7661 /* We have signal detect and not receiving
7662 * configs.
7663 */
7664
7665 pDevice->PhyFlags |= PHY_FIBER_FALLBACK;
7666 LM_5714_FamForceFiber(pDevice);
7667 }
7668 }
7669 }
7670 else if ( (pDevice->PhyFlags & PHY_FIBER_FALLBACK) &&
7671 (pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)) {
7672 LM_UINT32 phy2;
7673
7674 LM_WritePhy(pDevice, 0x17, 0x0f01);
7675 LM_ReadPhy(pDevice, 0x15, &phy2);
7676 if (phy2 & 0x20) {
7677 /* Receiving configs. */
7678
7679 pDevice->PhyFlags &= ~PHY_FIBER_FALLBACK;
7680 LM_5714_FamGoFiberAutoNeg(pDevice);
7681 }
7682 }
7683
7684 } /* LM_5714_FamFiberCheckLink */
7685
7686
7687 /******************************************************************************/
7688 /* Description: */
7689 /* */
7690 /* Return: */
7691 /******************************************************************************/
7692 LM_STATUS
7693 LM_SetupPhy(
7694 PLM_DEVICE_BLOCK pDevice)
7695 {
7696 LM_STATUS LmStatus;
7697 LM_UINT32 Value32;
7698
7699 if(pDevice->PhyFlags & PHY_IS_FIBER)
7700 {
7701 LmStatus = LM_SetupNewFiberPhy(pDevice);
7702 }else
7703 #ifdef INCLUDE_TBI_SUPPORT
7704 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
7705 {
7706 LmStatus = LM_SetupFiberPhy(pDevice);
7707 }
7708 else
7709 #endif /* INCLUDE_TBI_SUPPORT */
7710 {
7711 LmStatus = LM_SetupCopperPhy(pDevice);
7712 }
7713 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
7714 {
7715 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
7716 {
7717 Value32 = REG_RD(pDevice, PciCfg.PciState);
7718 REG_WR(pDevice, PciCfg.PciState,
7719 Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
7720 }
7721 }
7722 if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
7723 (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
7724 {
7725 REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
7726 }
7727 else
7728 {
7729 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
7730 }
7731 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
7732 {
7733 if (pDevice->LinkStatus == LM_STATUS_LINK_DOWN)
7734 {
7735 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks, 0);
7736 }
7737 else
7738 {
7739 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
7740 pDevice->StatsCoalescingTicks);
7741 }
7742 }
7743
7744 return LmStatus;
7745 }
7746
7747
7748 /* test data pattern */
7749 static LM_UINT32 pattern[4][6] = {
7750 /* For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
7751 For 5705 , each DFE TAP has 19-bits (low word 15, hi word 4)
7752 For simplicity, we check only 19-bits, so we don't have to
7753 distinguish which chip it is.
7754 the LO word contains 15 bits, make sure pattern data is < 0x7fff
7755 the HI word contains 6 bits, make sure pattern data is < 0x003f */
7756 {0x00005555, 0x00000005, /* ch0, TAP 0, LO/HI pattern */
7757 0x00002aaa, 0x0000000a, /* ch0, TAP 1, LO/HI pattern */
7758 0x00003456, 0x00000003}, /* ch0, TAP 2, LO/HI pattern */
7759
7760 {0x00002aaa, 0x0000000a, /* ch1, TAP 0, LO/HI pattern */
7761 0x00003333, 0x00000003, /* ch1, TAP 1, LO/HI pattern */
7762 0x0000789a, 0x00000005}, /* ch1, TAP 2, LO/HI pattern */
7763
7764 {0x00005a5a, 0x00000005, /* ch2, TAP 0, LO/HI pattern */
7765 0x00002a6a, 0x0000000a, /* ch2, TAP 1, LO/HI pattern */
7766 0x00001bcd, 0x00000003}, /* ch2, TAP 2, LO/HI pattern */
7767
7768 {0x00002a5a, 0x0000000a, /* ch3, TAP 0, LO/HI pattern */
7769 0x000033c3, 0x00000003, /* ch3, TAP 1, LO/HI pattern */
7770 0x00002ef1, 0x00000005}, /* ch3, TAP 2, LO/HI pattern */
7771 };
7772
7773 /********************************************************/
7774 /* Routine to wait for PHY Macro Command to complete */
7775 /* */
7776 /* If PHY's Macro operation keeps stay busy, nothing we */
7777 /* can do anyway. The timeout is there so we won't */
7778 /* stay in this routine indefinitly. */
7779 /********************************************************/
7780 static LM_UINT32 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice);
7781
7782 static LM_UINT32
7783 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice)
7784 {
7785 LM_UINT32 timeout;
7786 LM_UINT32 val32;
7787
7788 timeout = 100;
7789 while (timeout--)
7790 {
7791 /* make sure the MACRO operation is complete */
7792 LM_ReadPhy(pDevice, 0x16, &val32);
7793 if ((val32 & 0x1000) == 0) break;
7794 }
7795
7796 return( timeout > 0 );
7797 }
7798
7799 /********************************************************/
7800 /* This routine resets the PHY on following chips: */
7801 /* 5703, 04, CIOB-E and 5705 */
7802 /* */
7803 /* This routine will issue PHY_RESET and check if */
7804 /* the reset is sucessful. If not, another PHY RESET */
7805 /* will be issued, until max "retry" reaches */
7806 /* */
7807 /* Input: */
7808 /* pDevice - device's context */
7809 /* retry - number of retries */
7810 /* reset - TRUE=will cause a PHY reset initially */
7811 /* FALSE = will not issue a PHY reset */
7812 /* unless TAP lockup detected */
7813 /* */
7814 /* Output: */
7815 /* TRUE - PHY Reset is done sucessfully */
7816 /* FALSE - PHY Reset had failed, after "retry" */
7817 /* has reached */
7818 /* */
7819 /* Dependencies: */
7820 /* void LM_wait_macro_done() */
7821 /* LM_UINT32 pattern[] */
7822 /* */
7823 /* Usage: */
7824 /* a. Before calling this routine, caller must */
7825 /* determine if the chip is a 5702/03/04 or */
7826 /* CIOB-E, and only call this routine if the */
7827 /* is one of these. */
7828 /* or its derivatives. */
7829 /* b. Instead of using MII register write to reset */
7830 /* the PHY, call this routine instead */
7831 /* c. Upon return from this routine, check return */
7832 /* value (TRUE/FALSE) to determine if PHY reset */
7833 /* is successful of not and "optionally" take */
7834 /* appropriate action (such as: event log) */
7835 /* d. Regardless of the return TRUE or FALSE, */
7836 /* proceed with PHY setup as you normally would */
7837 /* after a PHY_RESET. */
7838 /* e. It is recommended that the caller will give */
7839 /* 10 "retry", however, caller can change to a */
7840 /* different number, depending on you code. */
7841 /* */
7842 /********************************************************/
7843 LM_STATUS LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset);
7844
7845 LM_STATUS
7846 LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset)
7847 {
7848 LM_UINT32 val32, save9;
7849 LM_UINT32 dataLo, dataHi;
7850 int i, channel;
7851 int reset_success = LM_STATUS_FAILURE;
7852 int force_reset;
7853
7854 /* to actually do a PHY_RESET or not is dictated by the caller */
7855 force_reset = reset;
7856
7857 while (retry-- && (reset_success != LM_STATUS_SUCCESS))
7858 {
7859 if (force_reset)
7860 {
7861 /* issue a phy reset, and wait for reset to complete */
7862 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
7863 for(i = 0; i < 100; i++)
7864 {
7865 MM_Wait(10);
7866
7867 LM_ReadPhy(pDevice, PHY_CTRL_REG, &val32);
7868 if(val32 && !(val32 & PHY_CTRL_PHY_RESET))
7869 {
7870 MM_Wait(20);
7871 break;
7872 }
7873 }
7874
7875 /* no more phy reset unless lockup detected */
7876 force_reset = FALSE;
7877 }
7878
7879 /* assuming reset is successful first */
7880 reset_success = LM_STATUS_SUCCESS;
7881
7882 /* now go check the DFE TAPs to see if locked up, but
7883 first, we need to set up PHY so we can read DFE TAPs */
7884
7885 /* Disable Transmitter and Interrupt, while we play with
7886 the PHY registers, so the link partner won't see any
7887 strange data and the Driver won't see any interrupts. */
7888 LM_ReadPhy(pDevice, 0x10, &val32);
7889 LM_WritePhy(pDevice, 0x10, val32 | 0x3000);
7890
7891 /* Setup Full-Duplex, 1000 mbps */
7892 LM_WritePhy(pDevice, 0x0, 0x0140);
7893
7894 /* Set to Master mode */
7895 LM_ReadPhy(pDevice, 0x9, &save9);
7896 LM_WritePhy(pDevice, 0x9, 0x1800);
7897
7898 /* Enable SM_DSP_CLOCK & 6dB */
7899 LM_WritePhy(pDevice, 0x18, 0x0c00);
7900
7901 /* blocks the PHY control access */
7902 LM_WritePhy(pDevice, 0x17, 0x8005);
7903 LM_WritePhy(pDevice, 0x15, 0x0800);
7904
7905 /* check TAPs for all 4 channels, as soon
7906 as we see a lockup we'll stop checking */
7907 for (channel=0; (channel<4) && (reset_success == LM_STATUS_SUCCESS);
7908 channel++)
7909 {
7910 /* select channel and set TAP index to 0 */
7911 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
7912 /* freeze filter again just to be safe */
7913 LM_WritePhy(pDevice, 0x16, 0x0002);
7914
7915 /* write fixed pattern to the RAM, 3 TAPs for
7916 each channel, each TAP have 2 WORDs (LO/HI) */
7917 for (i=0; i<6; i++)
7918 LM_WritePhy(pDevice, 0x15, pattern[channel][i]);
7919
7920 /* Activate PHY's Macro operation to write DFE TAP from RAM,
7921 and wait for Macro to complete */
7922 LM_WritePhy(pDevice, 0x16, 0x0202);
7923 if (!LM_wait_macro_done(pDevice))
7924 {
7925 reset_success = LM_STATUS_FAILURE;
7926 force_reset = TRUE;
7927 break;
7928 }
7929
7930 /* --- done with write phase, now begin read phase --- */
7931
7932 /* select channel and set TAP index to 0 */
7933 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
7934
7935 /* Active PHY's Macro operation to load DFE TAP to RAM,
7936 and wait for Macro to complete */
7937 LM_WritePhy(pDevice, 0x16, 0x0082);
7938 if (!LM_wait_macro_done(pDevice))
7939 {
7940 reset_success = LM_STATUS_FAILURE;
7941 force_reset = TRUE;
7942 break;
7943 }
7944
7945 /* enable "pre-fetch" */
7946 LM_WritePhy(pDevice, 0x16, 0x0802);
7947 if (!LM_wait_macro_done(pDevice))
7948 {
7949 reset_success = LM_STATUS_FAILURE;
7950 force_reset = TRUE;
7951 break;
7952 }
7953
7954 /* read back the TAP values.
7955 3 TAPs for each channel, each TAP have 2 WORDs (LO/HI) */
7956 for (i=0; i<6; i+=2)
7957 {
7958 /* read Lo/Hi then wait for 'done' is faster */
7959 LM_ReadPhy(pDevice, 0x15, &dataLo);
7960 LM_ReadPhy(pDevice, 0x15, &dataHi);
7961 if (!LM_wait_macro_done(pDevice))
7962 {
7963 reset_success = LM_STATUS_FAILURE;
7964 force_reset = TRUE;
7965 break;
7966 }
7967
7968 /* For 5703/04, each DFE TAP has 21-bits (low word 15,
7969 * hi word 6) For 5705, each DFE TAP pas 19-bits (low word 15,
7970 * hi word 4) For simplicity, we check only 19-bits, so we
7971 * don't have to distinguish which chip it is. */
7972 dataLo &= 0x7fff;
7973 dataHi &= 0x000f;
7974
7975 /* check if what we wrote is what we read back */
7976 if ( (dataLo != pattern[channel][i]) || (dataHi != pattern[channel][i+1]) )
7977 {
7978 /* if failed, then the PHY is locked up,
7979 we need to do PHY reset again */
7980 reset_success = LM_STATUS_FAILURE;
7981 force_reset = TRUE;
7982 /* 04/25/2003. sb. do these writes before issueing a reset. */
7983 /* these steps will reduce the chance of back-to-back
7984 * phy lockup after reset */
7985 LM_WritePhy(pDevice, 0x17, 0x000B);
7986 LM_WritePhy(pDevice, 0x15, 0x4001);
7987 LM_WritePhy(pDevice, 0x15, 0x4005);
7988 break;
7989 }
7990 } /* for i */
7991 } /* for channel */
7992 } /* while */
7993
7994 /* restore dfe coeff back to zeros */
7995 for (channel=0; channel<4 ; channel++)
7996 {
7997 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
7998 LM_WritePhy(pDevice, 0x16, 0x0002);
7999 for (i=0; i<6; i++)
8000 LM_WritePhy(pDevice, 0x15, 0x0000);
8001 LM_WritePhy(pDevice, 0x16, 0x0202);
8002 if (!LM_wait_macro_done(pDevice))
8003 {
8004 reset_success = LM_STATUS_FAILURE;
8005 break;
8006 }
8007 }
8008
8009 /* remove block phy control */
8010 LM_WritePhy(pDevice, 0x17, 0x8005);
8011 LM_WritePhy(pDevice, 0x15, 0x0000);
8012
8013 /* unfreeze DFE TAP filter for all channels */
8014 LM_WritePhy(pDevice, 0x17, 0x8200);
8015 LM_WritePhy(pDevice, 0x16, 0x0000);
8016
8017 /* Restore PHY back to operating state */
8018 LM_WritePhy(pDevice, 0x18, 0x0400);
8019
8020 /* Restore register 9 */
8021 LM_WritePhy(pDevice, 0x9, save9);
8022
8023 /* enable transmitter and interrupt */
8024 LM_ReadPhy(pDevice, 0x10, &val32);
8025 LM_WritePhy(pDevice, 0x10, (val32 & ~0x3000));
8026
8027 return reset_success;
8028 }
8029
8030 LM_VOID
8031 LM_ResetPhy(LM_DEVICE_BLOCK *pDevice)
8032 {
8033 int j;
8034 LM_UINT32 miireg;
8035
8036 if (pDevice->PhyFlags & PHY_CHECK_TAPS_AFTER_RESET)
8037 {
8038 LM_ResetPhy_5703_4_5(pDevice, 5, 1);
8039 }
8040 else
8041 {
8042 int wait_val = 100;
8043 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
8044
8045 if( pDevice->PhyFlags & PHY_IS_FIBER )
8046 wait_val = 5000;
8047
8048 for(j = 0; j < wait_val; j++)
8049 {
8050 MM_Wait(10);
8051
8052 LM_ReadPhy(pDevice, PHY_CTRL_REG, &miireg);
8053 if(miireg && !(miireg & PHY_CTRL_PHY_RESET))
8054 {
8055 MM_Wait(20);
8056 break;
8057 }
8058 }
8059
8060 LM_PhyTapPowerMgmt(pDevice);
8061 }
8062 if ( (pDevice->PhyFlags & PHY_ADC_FIX) &&
8063 !( pDevice->PhyFlags & PHY_IS_FIBER) )
8064 {
8065 LM_WritePhy(pDevice, 0x18, 0x0c00);
8066 LM_WritePhy(pDevice, 0x17, 0x201f);
8067 LM_WritePhy(pDevice, 0x15, 0x2aaa);
8068 LM_WritePhy(pDevice, 0x17, 0x000a);
8069 LM_WritePhy(pDevice, 0x15, 0x0323);
8070 LM_WritePhy(pDevice, 0x18, 0x0400);
8071 }
8072 if ( (pDevice->PhyFlags & PHY_5705_5750_FIX) &&
8073 !( pDevice->PhyFlags & PHY_IS_FIBER) )
8074 {
8075 LM_WritePhy(pDevice, 0x18, 0x0c00);
8076 LM_WritePhy(pDevice, 0x17, 0x000a);
8077 LM_WritePhy(pDevice, 0x15, 0x310b);
8078 LM_WritePhy(pDevice, 0x17, 0x201f);
8079 LM_WritePhy(pDevice, 0x15, 0x9506);
8080 LM_WritePhy(pDevice, 0x17, 0x401f);
8081 LM_WritePhy(pDevice, 0x15, 0x14e2);
8082 LM_WritePhy(pDevice, 0x18, 0x0400);
8083 }
8084 if ( (pDevice->PhyFlags & PHY_5704_A0_FIX) &&
8085 !( pDevice->PhyFlags & PHY_IS_FIBER) )
8086 {
8087 LM_WritePhy(pDevice, 0x1c, 0x8d68);
8088 LM_WritePhy(pDevice, 0x1c, 0x8d68);
8089 }
8090 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
8091 {
8092 LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &miireg);
8093 miireg |= 1; /* set tx elastic fifo */
8094 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, miireg);
8095
8096 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
8097 }
8098 else if (pDevice->Flags & JUMBO_CAPABLE_FLAG)
8099 {
8100 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
8101 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &miireg);
8102 miireg |= 0x4000; /* set rx extended packet length */
8103 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, miireg);
8104
8105 LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &miireg);
8106 miireg |= 1; /* set tx elastic fifo */
8107 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, miireg);
8108
8109 }
8110
8111 LM_SetEthWireSpeed(pDevice);
8112 pDevice->PhyFlags &= ~PHY_FIBER_FALLBACK;
8113 }
8114
8115 STATIC LM_VOID
8116 LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice)
8117 {
8118 LM_UINT32 Value32;
8119
8120 if( pDevice->PhyFlags & PHY_IS_FIBER)
8121 return;
8122
8123 /* Enable Ethernet@WireSpeed. */
8124 if (pDevice->PhyFlags & PHY_ETHERNET_WIRESPEED)
8125 {
8126 LM_WritePhy(pDevice, 0x18, 0x7007);
8127 LM_ReadPhy(pDevice, 0x18, &Value32);
8128 LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
8129 }
8130 }
8131
8132 STATIC LM_STATUS
8133 LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice)
8134 {
8135 LM_UINT32 miireg;
8136
8137 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &miireg);
8138 pDevice->advertising = miireg;
8139 if ((miireg & PHY_AN_AD_ALL_SPEEDS) != PHY_AN_AD_ALL_SPEEDS)
8140 {
8141 return LM_STATUS_FAILURE;
8142 }
8143
8144 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &miireg);
8145 pDevice->advertising1000 = miireg;
8146
8147 if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
8148 {
8149 if ((miireg & BCM540X_AN_AD_ALL_1G_SPEEDS) !=
8150 BCM540X_AN_AD_ALL_1G_SPEEDS)
8151 {
8152 return LM_STATUS_FAILURE;
8153 }
8154 }else{
8155
8156 if(miireg)
8157 {
8158 return LM_STATUS_FAILURE;
8159 }
8160 }
8161 return LM_STATUS_SUCCESS;
8162 }
8163
8164 /******************************************************************************/
8165 /* Description: */
8166 /* */
8167 /* Return: */
8168 /******************************************************************************/
8169 LM_VOID
8170 LM_ReadPhy(
8171 PLM_DEVICE_BLOCK pDevice,
8172 LM_UINT32 PhyReg,
8173 PLM_UINT32 pData32) {
8174 LM_UINT32 Value32;
8175 LM_UINT32 j;
8176
8177 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8178 {
8179 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
8180 ~MI_MODE_AUTO_POLLING_ENABLE);
8181 REG_RD_BACK(pDevice, MacCtrl.MiMode);
8182 MM_Wait(40);
8183 }
8184
8185 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
8186 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
8187 MI_COM_CMD_READ | MI_COM_START;
8188
8189 REG_WR(pDevice, MacCtrl.MiCom, Value32);
8190
8191 for(j = 0; j < 200; j++)
8192 {
8193 MM_Wait(1);
8194
8195 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8196
8197 if(!(Value32 & MI_COM_BUSY))
8198 {
8199 MM_Wait(5);
8200 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8201 Value32 &= MI_COM_PHY_DATA_MASK;
8202 break;
8203 }
8204 }
8205
8206 if(Value32 & MI_COM_BUSY)
8207 {
8208 Value32 = 0;
8209 }
8210
8211 *pData32 = Value32;
8212
8213 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8214 {
8215 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
8216 REG_RD_BACK(pDevice, MacCtrl.MiMode);
8217 MM_Wait(40);
8218 }
8219 } /* LM_ReadPhy */
8220
8221
8222
8223 /******************************************************************************/
8224 /* Description: */
8225 /* */
8226 /* Return: */
8227 /******************************************************************************/
8228 LM_VOID
8229 LM_WritePhy(
8230 PLM_DEVICE_BLOCK pDevice,
8231 LM_UINT32 PhyReg,
8232 LM_UINT32 Data32) {
8233 LM_UINT32 Value32;
8234 LM_UINT32 j;
8235
8236 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8237 {
8238 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
8239 ~MI_MODE_AUTO_POLLING_ENABLE);
8240 REG_RD_BACK(pDevice, MacCtrl.MiMode);
8241 MM_Wait(40);
8242 }
8243
8244 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
8245 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
8246 (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
8247
8248 REG_WR(pDevice, MacCtrl.MiCom, Value32);
8249
8250 for(j = 0; j < 200; j++)
8251 {
8252 MM_Wait(1);
8253
8254 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8255
8256 if(!(Value32 & MI_COM_BUSY))
8257 {
8258 MM_Wait(5);
8259 break;
8260 }
8261 }
8262
8263 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8264 {
8265 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
8266 REG_RD_BACK(pDevice, MacCtrl.MiMode);
8267 MM_Wait(40);
8268 }
8269 } /* LM_WritePhy */
8270
8271 /* MII read/write functions to export to the robo support code */
8272 LM_UINT16
8273 robo_miird(void *h, int phyadd, int regoff)
8274 {
8275 PLM_DEVICE_BLOCK pdev = h;
8276 LM_UINT32 savephyaddr, val32;
8277
8278 savephyaddr = pdev->PhyAddr;
8279 pdev->PhyAddr = phyadd;
8280
8281 LM_ReadPhy(pdev, regoff, &val32);
8282
8283 pdev->PhyAddr = savephyaddr;
8284
8285 return ((LM_UINT16)(val32 & 0xffff));
8286 }
8287
8288 void
8289 robo_miiwr(void *h, int phyadd, int regoff, LM_UINT16 value)
8290 {
8291 PLM_DEVICE_BLOCK pdev = h;
8292 LM_UINT32 val32, savephyaddr;
8293
8294 savephyaddr = pdev->PhyAddr;
8295 pdev->PhyAddr = phyadd;
8296
8297 val32 = (LM_UINT32)value;
8298 LM_WritePhy(pdev, regoff, val32);
8299
8300 pdev->PhyAddr = savephyaddr;
8301 }
8302
8303 STATIC void
8304 LM_GetPhyId(LM_DEVICE_BLOCK *pDevice)
8305 {
8306 LM_UINT32 Value32;
8307
8308 LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
8309 pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
8310
8311 LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
8312 pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
8313 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
8314
8315 }
8316
8317 LM_STATUS
8318 LM_EnableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
8319 {
8320 pDevice->LoopBackMode = LM_MAC_LOOP_BACK_MODE;
8321 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
8322 pDevice->MacMode |= (MAC_MODE_PORT_INTERNAL_LOOPBACK |
8323 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII);
8324 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
8325 MM_Wait(40);
8326 LM_SetupPhy(pDevice);
8327 return LM_STATUS_SUCCESS;
8328 }
8329
8330 LM_STATUS
8331 LM_DisableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
8332 {
8333 pDevice->LoopBackMode = 0;
8334
8335 pDevice->MacMode &= ~(MAC_MODE_PORT_INTERNAL_LOOPBACK |
8336 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_MASK);
8337 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
8338 MM_Wait(40);
8339 if(pDevice->PhyFlags & PHY_IS_FIBER)
8340 LM_ResetPhy(pDevice);
8341
8342 LM_SetupPhy(pDevice);
8343 return LM_STATUS_SUCCESS;
8344 }
8345
8346 LM_STATUS
8347 LM_EnablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
8348 {
8349 pDevice->LoopBackMode = LM_PHY_LOOP_BACK_MODE;
8350 LM_SetupPhy(pDevice);
8351 return LM_STATUS_SUCCESS;
8352 }
8353
8354 LM_STATUS
8355 LM_DisablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
8356 {
8357 pDevice->LoopBackMode = 0;
8358 LM_SetupPhy(pDevice);
8359 return LM_STATUS_SUCCESS;
8360 }
8361
8362 LM_STATUS
8363 LM_EnableExtLoopBack(PLM_DEVICE_BLOCK pDevice, LM_LINE_SPEED LineSpeed)
8364 {
8365 pDevice->LoopBackMode = LM_EXT_LOOP_BACK_MODE;
8366
8367 pDevice->SavedDisableAutoNeg = pDevice->DisableAutoNeg;
8368 pDevice->SavedRequestedLineSpeed = pDevice->RequestedLineSpeed;
8369 pDevice->SavedRequestedDuplexMode = pDevice->RequestedDuplexMode;
8370
8371 pDevice->DisableAutoNeg = TRUE;
8372 pDevice->RequestedLineSpeed = LineSpeed;
8373 pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
8374 LM_SetupPhy(pDevice);
8375 return LM_STATUS_SUCCESS;
8376 }
8377
8378 LM_STATUS
8379 LM_DisableExtLoopBack(PLM_DEVICE_BLOCK pDevice)
8380 {
8381 pDevice->LoopBackMode = 0;
8382
8383 pDevice->DisableAutoNeg = pDevice->SavedDisableAutoNeg;
8384 pDevice->RequestedLineSpeed = pDevice->SavedRequestedLineSpeed;
8385 pDevice->RequestedDuplexMode = pDevice->SavedRequestedDuplexMode;
8386
8387 LM_SetupPhy(pDevice);
8388 return LM_STATUS_SUCCESS;
8389 }
8390
8391 /******************************************************************************/
8392 /* Description: */
8393 /* */
8394 /* Return: */
8395 /******************************************************************************/
8396 LM_STATUS
8397 LM_SetPowerState(
8398 PLM_DEVICE_BLOCK pDevice,
8399 LM_POWER_STATE PowerLevel)
8400 {
8401 #ifdef BCM_WOL
8402 LM_UINT32 PmeSupport;
8403 PLM_DEVICE_BLOCK pDevice2 = 0;
8404 int j;
8405 #endif
8406 LM_UINT32 Value32;
8407 LM_UINT32 PmCtrl;
8408
8409 /* make sureindirect accesses are enabled*/
8410 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
8411
8412 /* Clear the PME_ASSERT bit and the power state bits. Also enable */
8413 /* the PME bit. */
8414 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
8415
8416 PmCtrl |= T3_PM_PME_ASSERTED;
8417 PmCtrl &= ~T3_PM_POWER_STATE_MASK;
8418
8419 /* Set the appropriate power state. */
8420 if(PowerLevel == LM_POWER_STATE_D0)
8421 {
8422 /* Bring the card out of low power mode. */
8423 PmCtrl |= T3_PM_POWER_STATE_D0;
8424 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
8425
8426 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
8427
8428 if(T3_ASIC_5752(pDevice->ChipRevId)){
8429 Value32 |= (GRC_MISC_LOCAL_CTRL_GPIO_OE3 |
8430 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT3 |
8431 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8432 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8433 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8434 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8435 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8436 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8437 }
8438 else
8439 {
8440 Value32 &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8441 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8442 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8443 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8444 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8445 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8446 }
8447
8448 RAW_REG_WR(pDevice, Grc.LocalCtrl, Value32);
8449
8450 MM_Wait(40); /* Required delay is about 20us. */
8451
8452 pDevice->PowerLevel = PowerLevel;
8453 return LM_STATUS_SUCCESS;
8454 }
8455 #ifdef BCM_WOL
8456 else if(PowerLevel == LM_POWER_STATE_D1)
8457 {
8458 PmCtrl |= T3_PM_POWER_STATE_D1;
8459 }
8460 else if(PowerLevel == LM_POWER_STATE_D2)
8461 {
8462 PmCtrl |= T3_PM_POWER_STATE_D2;
8463 }
8464 else if(PowerLevel == LM_POWER_STATE_D3)
8465 {
8466 PmCtrl |= T3_PM_POWER_STATE_D3;
8467 }
8468 else
8469 {
8470 return LM_STATUS_FAILURE;
8471 }
8472 PmCtrl |= T3_PM_PME_ENABLE;
8473
8474 /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
8475 /* setting new line speed. */
8476 Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
8477 REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
8478
8479 if(!pDevice->RestoreOnWakeUp)
8480 {
8481 pDevice->RestoreOnWakeUp = TRUE;
8482 pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
8483 pDevice->WakeUpRequestedLineSpeed = pDevice->RequestedLineSpeed;
8484 pDevice->WakeUpRequestedDuplexMode = pDevice->RequestedDuplexMode;
8485 }
8486
8487 /* Force auto-negotiation to 10 line speed. */
8488 pDevice->DisableAutoNeg = FALSE;
8489
8490 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
8491 {
8492 pDevice->RequestedLineSpeed = LM_LINE_SPEED_10MBPS;
8493 LM_SetupPhy(pDevice);
8494 }
8495
8496 /* Put the driver in the initial state, and go through the power down */
8497 /* sequence. */
8498 LM_DoHalt(pDevice);
8499
8500 if (!(pDevice->AsfFlags & ASF_ENABLED))
8501 {
8502 for(j = 0; j < 20000; j++)
8503 {
8504 MM_Wait(10);
8505
8506 Value32 = MEM_RD_OFFSET(pDevice, T3_ASF_FW_STATUS_MAILBOX);
8507 if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
8508 {
8509 break;
8510 }
8511 }
8512 }
8513
8514 MEM_WR_OFFSET(pDevice, DRV_WOL_MAILBOX, DRV_WOL_SIGNATURE |
8515 DRV_DOWN_STATE_SHUTDOWN | 0x2 | DRV_WOL_SET_MAGIC_PKT);
8516
8517 MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
8518
8519 if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
8520 {
8521
8522 /* Enable WOL. */
8523 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
8524 {
8525 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
8526 MM_Wait(40);
8527 }
8528
8529 if (! T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
8530 {
8531 /* Let boot code deal with LED mode on shasta */
8532 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
8533 }
8534
8535 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
8536 {
8537 Value32 = MAC_MODE_PORT_MODE_TBI;
8538 }
8539 else
8540 {
8541 Value32 = MAC_MODE_PORT_MODE_MII;
8542 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
8543 {
8544 if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_2 ||
8545 pDevice->WolSpeed == WOL_SPEED_10MB)
8546 {
8547 Value32 |= MAC_MODE_LINK_POLARITY;
8548 }
8549 }
8550 else
8551 {
8552 Value32 |= MAC_MODE_LINK_POLARITY;
8553 }
8554 }
8555 REG_WR(pDevice, MacCtrl.Mode, Value32);
8556 REG_RD_BACK(pDevice, MacCtrl.Mode);
8557 MM_Wait(40); MM_Wait(40); MM_Wait(40);
8558
8559 /* Always enable magic packet wake-up if we have vaux. */
8560 if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
8561 (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
8562 {
8563 Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
8564 }
8565
8566 #ifdef BCM_ASF
8567 if (pDevice->AsfFlags & ASF_ENABLED)
8568 {
8569 Value32 &= ~MAC_MODE_ACPI_POWER_ON_ENABLE;
8570 }
8571 #endif
8572 REG_WR(pDevice, MacCtrl.Mode, Value32);
8573
8574 /* Enable the receiver. */
8575 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
8576 }
8577 else if (!(pDevice->AsfFlags & ASF_ENABLED))
8578 {
8579 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
8580 {
8581 REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
8582 LED_CTRL_OVERRIDE_TRAFFIC_LED);
8583 }
8584 else
8585 {
8586 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
8587 BCM540X_EXT_CTRL_FORCE_LED_OFF);
8588 LM_WritePhy(pDevice, 0x18, 0x01b2);
8589 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
8590 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
8591 !T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
8592 {
8593 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOWER_POWER_MODE);
8594 }
8595 }
8596 }
8597
8598 /* Disable tx/rx clocks, and select an alternate clock. */
8599 if (T3_ASIC_5714_FAMILY(pDevice->ChipRevId)){
8600 /* Do nothing */
8601 }
8602 else if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
8603 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
8604 (pDevice->WolSpeed == WOL_SPEED_10MB)))
8605 {
8606 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8607 T3_PCI_SELECT_ALTERNATE_CLOCK |
8608 T3_PCI_POWER_DOWN_PCI_PLL133;
8609
8610 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8611 }
8612 /* ASF on 5750 will not run properly on slow core clock */
8613 else if( !(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId) &&
8614 (pDevice->AsfFlags & ASF_ENABLED) ))
8615 {
8616 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8617 {
8618 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8619 T3_PCI_SELECT_ALTERNATE_CLOCK;
8620 }
8621 else if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
8622 {
8623 Value32 = T3_PCI_625_CORE_CLOCK;
8624 }
8625 else
8626 {
8627 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
8628 }
8629 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8630
8631 MM_Wait(40);
8632
8633 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8634 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8635 {
8636 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8637 T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
8638 }
8639 else if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
8640 {
8641 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_625_CORE_CLOCK;
8642 }
8643 else if(!T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
8644 {
8645 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
8646 }
8647
8648 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8649
8650 if (!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
8651 {
8652 MM_Wait(40);
8653
8654 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8655 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8656 {
8657 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8658 T3_PCI_44MHZ_CORE_CLOCK;
8659 }
8660 else
8661 {
8662 Value32 = T3_PCI_44MHZ_CORE_CLOCK;
8663 }
8664
8665 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8666 }
8667 }
8668
8669 MM_Wait(40);
8670
8671 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
8672 {
8673 pDevice2 = MM_FindPeerDev(pDevice);
8674 }
8675 if (!(pDevice->Flags & EEPROM_WP_FLAG))
8676 {
8677 LM_SwitchVaux(pDevice, pDevice2);
8678 }
8679
8680 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
8681
8682 if((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5750_AX) ||
8683 (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5750_BX)) {
8684
8685 Value32= REG_RD_OFFSET(pDevice, 0x7d00);
8686 REG_WR_OFFSET(pDevice, 0x7d00,Value32 & ~(BIT_16 | BIT_4 | BIT_2 | BIT_1 | BIT_0));
8687
8688 if(!(pDevice->AsfFlags & ASF_ENABLED))
8689 LM_HaltCpu(pDevice, T3_RX_CPU_ID);
8690
8691 }
8692
8693 /* Put the the hardware in low power mode. */
8694 if (!(pDevice->Flags & DISABLE_D3HOT_FLAG))
8695 {
8696 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
8697 MM_Wait(200); /* Wait 200us for state transition */
8698 }
8699
8700 pDevice->PowerLevel = PowerLevel;
8701
8702 #else
8703 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
8704 #endif /* BCM_WOL */
8705
8706 return LM_STATUS_SUCCESS;
8707 } /* LM_SetPowerState */
8708
8709
8710 LM_VOID
8711 LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2)
8712 {
8713 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
8714 return;
8715
8716 pDevice->GrcLocalCtrl &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8717 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8718 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8719 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8720 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8721 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8722
8723 /* Switch adapter to auxilliary power if WOL enabled */
8724 if ((pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
8725 (pDevice->AsfFlags & ASF_ENABLED) ||
8726 (pDevice2 && ((pDevice2->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
8727 (pDevice2->AsfFlags & ASF_ENABLED))))
8728 {
8729 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8730 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8731 {
8732 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
8733 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8734 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8735 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8736 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8737 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8738 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8739 MM_Wait(40);
8740 }
8741 else
8742 {
8743 if (pDevice2 && pDevice2->InitDone)
8744 {
8745 return;
8746 }
8747
8748 /* On NICs GPIOs are used for vaux.
8749 The transition of GPIO0 from 0-1 causes vaux
8750 to power up. Transition of GPIO1 from 1-0 turns vaux off.
8751 GPIO2 transition from 1-0 enables a non-glitch vaux
8752 transition from one state to another.
8753 On certain designs we should not output GPIO2.
8754 */
8755 if(pDevice->Flags & GPIO2_DONOT_OUTPUT)
8756 {
8757 /* GPIO0 = 0, GPIO1 = 1. */
8758 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8759 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8760 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8761 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8762
8763 MM_Wait(40);
8764
8765 /* GPIO0 = 1, GPIO1 = 1. */
8766 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8767 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8768 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8769 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8770 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8771
8772 MM_Wait(40);
8773 }
8774 else
8775 {
8776
8777 /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
8778 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8779 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8780 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8781 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8782 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8783 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8784
8785 MM_Wait(40);
8786
8787 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
8788 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8789 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8790 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8791 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8792 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8793 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8794 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8795 MM_Wait(40);
8796
8797 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
8798 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8799 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8800 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8801 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8802 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8803 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8804 MM_Wait(40);
8805 } /* GPIO2 OK */
8806 } /* Not 5700||5701 */
8807 } /* WOL disabled */
8808 else
8809 {
8810 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
8811 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
8812 {
8813 if (pDevice2 && pDevice2->InitDone)
8814 {
8815 return;
8816 }
8817
8818 /* GPIO1 = 1 */
8819 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8820 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8821 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8822 MM_Wait(40);
8823
8824 /* GPIO1 = 0 */
8825 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8826 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
8827 MM_Wait(40);
8828
8829 /* GPIO1 = 1 */
8830 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8831 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8832 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8833 MM_Wait(40);
8834 }
8835 }
8836 }
8837
8838
8839 /******************************************************************************/
8840 /* Description: */
8841 /* */
8842 /* Return: */
8843 /******************************************************************************/
8844 static LM_UINT32
8845 GetPhyAdFlowCntrlSettings(
8846 PLM_DEVICE_BLOCK pDevice)
8847 {
8848 LM_UINT32 Value32;
8849
8850 Value32 = 0;
8851
8852 /* Auto negotiation flow control only when autonegotiation is enabled. */
8853 if(pDevice->DisableAutoNeg == FALSE ||
8854 pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
8855 {
8856 if (T3_ASIC_5714_FAMILY(pDevice->ChipRevId) &&
8857 (pDevice->PhyFlags & PHY_IS_FIBER)) {
8858
8859 /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
8860 if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
8861 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
8862 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
8863 {
8864 Value32 |=PHY_AN_AD_1000XPAUSE;
8865 }
8866 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
8867 {
8868 Value32 |= PHY_AN_AD_1000XPSE_ASYM;
8869 }
8870 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
8871 {
8872 Value32 |= (PHY_AN_AD_1000XPSE_ASYM | PHY_AN_AD_1000XPAUSE);
8873 }
8874
8875 }else{
8876
8877 /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
8878 if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
8879 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
8880 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
8881 {
8882 Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
8883 }
8884 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
8885 {
8886 Value32 |= PHY_AN_AD_ASYM_PAUSE;
8887 }
8888 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
8889 {
8890 Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
8891 }
8892 }
8893 }
8894
8895 return Value32;
8896 }
8897
8898
8899
8900 /******************************************************************************/
8901 /* Description: */
8902 /* */
8903 /* Return: */
8904 /* LM_STATUS_FAILURE */
8905 /* LM_STATUS_SUCCESS */
8906 /* */
8907 /******************************************************************************/
8908 static LM_STATUS
8909 LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice)
8910 {
8911 LM_LINE_SPEED LineSpeed;
8912 LM_DUPLEX_MODE DuplexMode;
8913 LM_UINT32 NewPhyCtrl;
8914 LM_UINT32 Value32, PhyReg18;
8915 LM_UINT32 Cnt;
8916
8917 /* Get the interface type, line speed, and duplex mode. */
8918 LineSpeed = pDevice->RequestedLineSpeed;
8919 DuplexMode = pDevice->RequestedDuplexMode;
8920
8921 /* Exit ext. loop back, in case it was in ext. loopback mode */
8922 /* Set Extended packet length bit on chips that support jumbo frames */
8923 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
8924 {
8925 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
8926
8927 LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &Value32);
8928 Value32 |= 1; /* set tx elastic fifo */
8929 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, Value32);
8930
8931 }
8932 else
8933 {
8934 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
8935 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
8936 PhyReg18 &= ~0x8000; /* clear external loop back */
8937
8938 if (pDevice->Flags & JUMBO_CAPABLE_FLAG)
8939 {
8940 PhyReg18 |= 0x4000; /* set extended packet length */
8941 LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &Value32);
8942 Value32 |= 1; /* set tx elastic fifo */
8943 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, Value32);
8944 }
8945 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
8946 }
8947
8948 #ifdef BCM_WOL
8949 if (pDevice->RestoreOnWakeUp)
8950 {
8951 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
8952 pDevice->advertising1000 = 0;
8953 Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
8954 if (pDevice->WolSpeed == WOL_SPEED_100MB)
8955 {
8956 Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
8957 }
8958 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
8959 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
8960 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
8961 pDevice->advertising = Value32;
8962 }
8963 /* Setup the auto-negotiation advertisement register. */
8964 else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
8965 #else
8966 /* Setup the auto-negotiation advertisement register. */
8967 if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
8968 #endif
8969 {
8970 /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
8971 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD | PHY_AN_AD_ALL_SPEEDS;
8972 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
8973
8974 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
8975 pDevice->advertising = Value32;
8976
8977 /* Advertise 1000Mbps */
8978 if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
8979 {
8980 Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS;
8981
8982 #ifdef INCLUDE_5701_AX_FIX
8983 /* slave mode. This will force the PHY to operate in */
8984 /* master mode. */
8985 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
8986 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
8987 {
8988 Value32 |= BCM540X_CONFIG_AS_MASTER |
8989 BCM540X_ENABLE_CONFIG_AS_MASTER;
8990 }
8991 #endif
8992
8993 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
8994 pDevice->advertising1000 = Value32;
8995 }
8996 else
8997 {
8998 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
8999 pDevice->advertising1000 = 0;
9000 }
9001 }
9002 else
9003 {
9004 if ((pDevice->PhyFlags & PHY_NO_GIGABIT) &&
9005 (LineSpeed == LM_LINE_SPEED_1000MBPS))
9006 {
9007 LineSpeed = LM_LINE_SPEED_100MBPS;
9008 }
9009 if(LineSpeed == LM_LINE_SPEED_1000MBPS)
9010 {
9011 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9012 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9013
9014 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9015 pDevice->advertising = Value32;
9016
9017 if(DuplexMode != LM_DUPLEX_MODE_FULL)
9018 {
9019 Value32 = BCM540X_AN_AD_1000BASET_HALF;
9020 }
9021 else
9022 {
9023 Value32 = BCM540X_AN_AD_1000BASET_FULL;
9024 }
9025
9026 #ifdef INCLUDE_5701_AX_FIX
9027 if ((pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE) ||
9028 (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
9029 pDevice->ChipRevId == T3_CHIP_ID_5701_B0))
9030 #else
9031 if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
9032 #endif
9033 {
9034 Value32 |= BCM540X_CONFIG_AS_MASTER |
9035 BCM540X_ENABLE_CONFIG_AS_MASTER;
9036 }
9037 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
9038 pDevice->advertising1000 = Value32;
9039 if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
9040 {
9041 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
9042 {
9043 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x8c20);
9044 }
9045 else
9046 {
9047 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
9048 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
9049 PhyReg18 |= 0x8000; /* set loop back */
9050 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
9051 }
9052 }
9053 }
9054 else if(LineSpeed == LM_LINE_SPEED_100MBPS)
9055 {
9056 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9057 pDevice->advertising1000 = 0;
9058
9059 if(DuplexMode != LM_DUPLEX_MODE_FULL)
9060 {
9061 Value32 = PHY_AN_AD_100BASETX_HALF;
9062 }
9063 else
9064 {
9065 Value32 = PHY_AN_AD_100BASETX_FULL;
9066 }
9067
9068 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9069 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9070
9071 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9072 pDevice->advertising = Value32;
9073 }
9074 else if(LineSpeed == LM_LINE_SPEED_10MBPS)
9075 {
9076 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9077 pDevice->advertising1000 = 0;
9078
9079 if(DuplexMode != LM_DUPLEX_MODE_FULL)
9080 {
9081 Value32 = PHY_AN_AD_10BASET_HALF;
9082 }
9083 else
9084 {
9085 Value32 = PHY_AN_AD_10BASET_FULL;
9086 }
9087
9088 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9089 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9090
9091 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9092 pDevice->advertising = Value32;
9093 }
9094 }
9095
9096 /* Force line speed if auto-negotiation is disabled. */
9097 if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
9098 {
9099 /* This code path is executed only when there is link. */
9100 pDevice->LineSpeed = LineSpeed;
9101 pDevice->DuplexMode = DuplexMode;
9102
9103 /* Force line seepd. */
9104 NewPhyCtrl = 0;
9105 switch(LineSpeed)
9106 {
9107 case LM_LINE_SPEED_10MBPS:
9108 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
9109 break;
9110 case LM_LINE_SPEED_100MBPS:
9111 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
9112 break;
9113 case LM_LINE_SPEED_1000MBPS:
9114 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
9115 break;
9116 default:
9117 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
9118 break;
9119 }
9120
9121 if(DuplexMode == LM_DUPLEX_MODE_FULL)
9122 {
9123 NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
9124 }
9125
9126 /* Don't do anything if the PHY_CTRL is already what we wanted. */
9127 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
9128 if(Value32 != NewPhyCtrl)
9129 {
9130 /* Temporary bring the link down before forcing line speed. */
9131 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
9132
9133 /* Wait for link to go down. */
9134 for(Cnt = 0; Cnt < 1500; Cnt++)
9135 {
9136 MM_Wait(10);
9137
9138 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
9139 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
9140
9141 if(!(Value32 & PHY_STATUS_LINK_PASS))
9142 {
9143 MM_Wait(40);
9144 break;
9145 }
9146 }
9147
9148 LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
9149 MM_Wait(40);
9150 }
9151 }
9152 else
9153 {
9154 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
9155 PHY_CTRL_RESTART_AUTO_NEG);
9156 }
9157
9158 return LM_STATUS_SUCCESS;
9159 } /* LM_ForceAutoNegBcm540xPhy */
9160
9161 /******************************************************************************/
9162 /* Description: */
9163 /* */
9164 /* Return: */
9165 /******************************************************************************/
9166 LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
9167 PT3_FWIMG_INFO pFwImg,
9168 LM_UINT32 LoadCpu,
9169 LM_UINT32 StartCpu)
9170 {
9171 LM_UINT32 i;
9172 LM_UINT32 address;
9173 LM_VOID (*Wr_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32);
9174 LM_UINT32 (*Rd_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register);
9175 LM_UINT32 len;
9176 LM_UINT32 base_addr;
9177
9178 /* BCM4785: Avoid all use of firmware. */
9179 if (pDevice->Flags & SB_CORE_FLAG)
9180 return LM_STATUS_FAILURE;
9181
9182 #ifdef INCLUDE_TCP_SEG_SUPPORT
9183 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
9184 {
9185 Wr_fn = LM_MemWrInd;
9186 Rd_fn = LM_MemRdInd;
9187 len = LM_GetStkOffLdFirmwareSize(pDevice);
9188 base_addr = T3_NIC_BCM5705_MBUF_POOL_ADDR;
9189 }
9190 else
9191 #endif
9192 {
9193 Wr_fn = LM_RegWrInd;
9194 Rd_fn = LM_RegRdInd;
9195 len = T3_RX_CPU_SPAD_SIZE;
9196 base_addr = T3_RX_CPU_SPAD_ADDR;
9197 }
9198
9199 if (LoadCpu & T3_RX_CPU_ID)
9200 {
9201 if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
9202 {
9203 return LM_STATUS_FAILURE;
9204 }
9205
9206 /* First of all clear scrach pad memory */
9207 for (i = 0; i < len; i+=4)
9208 {
9209 Wr_fn(pDevice,base_addr+i,0);
9210 }
9211
9212 /* Copy code first */
9213 address = base_addr + (pFwImg->Text.Offset & 0xffff);
9214 for (i = 0; i <= pFwImg->Text.Length; i+=4)
9215 {
9216 Wr_fn(pDevice,address+i,
9217 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
9218 }
9219
9220 address = base_addr + (pFwImg->ROnlyData.Offset & 0xffff);
9221 for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
9222 {
9223 Wr_fn(pDevice,address+i,
9224 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
9225 }
9226
9227 address = base_addr + (pFwImg->Data.Offset & 0xffff);
9228 for (i= 0; i <= pFwImg->Data.Length; i+=4)
9229 {
9230 Wr_fn(pDevice,address+i,
9231 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
9232 }
9233 }
9234
9235 if ((LoadCpu & T3_TX_CPU_ID) &&
9236 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
9237 {
9238 if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
9239 {
9240 return LM_STATUS_FAILURE;
9241 }
9242
9243 /* First of all clear scrach pad memory */
9244 for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
9245 {
9246 Wr_fn(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
9247 }
9248
9249 /* Copy code first */
9250 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
9251 for (i= 0; i <= pFwImg->Text.Length; i+=4)
9252 {
9253 Wr_fn(pDevice,address+i,
9254 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
9255 }
9256
9257 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
9258 for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
9259 {
9260 Wr_fn(pDevice,address+i,
9261 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
9262 }
9263
9264 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
9265 for (i= 0; i <= pFwImg->Data.Length; i+=4)
9266 {
9267 Wr_fn(pDevice,address+i,
9268 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
9269 }
9270 }
9271
9272 if (StartCpu & T3_RX_CPU_ID)
9273 {
9274 /* Start Rx CPU */
9275 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9276 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
9277 for (i = 0 ; i < 5; i++)
9278 {
9279 if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
9280 break;
9281
9282 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9283 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9284 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
9285 REG_RD_BACK(pDevice,rxCpu.reg.PC);
9286 MM_Wait(1000);
9287 }
9288
9289 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9290 REG_WR(pDevice,rxCpu.reg.mode, 0);
9291 }
9292
9293 if ((StartCpu & T3_TX_CPU_ID) &&
9294 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
9295 {
9296 /* Start Tx CPU */
9297 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9298 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
9299 for (i = 0 ; i < 5; i++)
9300 {
9301 if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
9302 break;
9303
9304 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9305 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
9306 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
9307 REG_RD_BACK(pDevice,txCpu.reg.PC);
9308 MM_Wait(1000);
9309 }
9310
9311 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9312 REG_WR(pDevice,txCpu.reg.mode, 0);
9313 }
9314
9315 return LM_STATUS_SUCCESS;
9316 }
9317
9318 LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
9319 {
9320 LM_UINT32 i;
9321 LM_STATUS status;
9322
9323 status = LM_STATUS_SUCCESS;
9324
9325 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) &&
9326 !(cpu_number & T3_RX_CPU_ID))
9327 {
9328 return status;
9329 }
9330
9331 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
9332 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
9333 {
9334 status = LM_NVRAM_AcquireLock(pDevice);
9335 }
9336
9337 if (cpu_number & T3_RX_CPU_ID)
9338 {
9339 for (i = 0 ; i < 10000; i++)
9340 {
9341 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9342 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9343
9344 if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
9345 break;
9346 }
9347
9348 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9349 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9350 REG_RD_BACK(pDevice,rxCpu.reg.mode);
9351 MM_Wait(10);
9352
9353 if (i == 10000)
9354 status = LM_STATUS_FAILURE;
9355 }
9356
9357 /*
9358 * BCM4785: There is only an Rx CPU for the 5750 derivative in
9359 * the 4785. Don't go any further in this code in order to
9360 * avoid access to the NVRAM arbitration register.
9361 */
9362 if (pDevice->Flags & SB_CORE_FLAG)
9363 return status;
9364
9365 if ((pDevice->Flags & T3_HAS_TWO_CPUS) &&
9366 (cpu_number & T3_TX_CPU_ID))
9367 {
9368 for (i = 0 ; i < 10000; i++)
9369 {
9370 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9371 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
9372
9373 if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
9374 break;
9375 }
9376
9377 if (i == 10000)
9378 status = LM_STATUS_FAILURE;
9379 }
9380
9381 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
9382 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
9383 {
9384 if (status != LM_STATUS_SUCCESS)
9385 {
9386 /*
9387 * Some part of this operation failed.
9388 * Just undo our own actions.
9389 */
9390 LM_NVRAM_ReleaseLock(pDevice);
9391 }
9392 else if (!(pDevice->Flags & T3_HAS_TWO_CPUS) ||
9393 cpu_number == (T3_TX_CPU_ID | T3_RX_CPU_ID))
9394 {
9395 /*
9396 * Release our NVRAM arbitration grant along
9397 * with the firmware's arbitration request bit.
9398 */
9399 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1 | SW_ARB_REQ_CLR0);
9400 REG_RD_BACK(pDevice, Nvram.SwArb);
9401 }
9402 else
9403 {
9404 LM_NVRAM_ReleaseLock(pDevice);
9405
9406 if (LM_NVRAM_AcquireLock(pDevice) == LM_STATUS_SUCCESS)
9407 {
9408 /* All is well. Release the arbitration and continue. */
9409 LM_NVRAM_ReleaseLock(pDevice);
9410 }
9411 else
9412 {
9413 /*
9414 * We've timed out while attempting to get the
9415 * NVRAM arbitration. Assume the cause is that
9416 * the NVRAM has requested arbitration after we
9417 * acquired arbitration the first time, but before
9418 * the CPU was actually halted.
9419 */
9420
9421 /*
9422 * Release our NVRAM arbitration grant along
9423 * with the firmware's arbitration request bit.
9424 */
9425 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1 | SW_ARB_REQ_CLR0);
9426 REG_RD_BACK(pDevice, Nvram.SwArb);
9427 }
9428 }
9429 }
9430
9431 return status;
9432 }
9433
9434
9435 LM_STATUS
9436 LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
9437 {
9438 int j;
9439 int ret = LM_STATUS_SUCCESS;
9440
9441 if(BlinkDurationSec == 0)
9442 {
9443 BlinkDurationSec = 1;
9444 }
9445 if(BlinkDurationSec > 120)
9446 {
9447 BlinkDurationSec = 120;
9448 }
9449
9450 for(j = 0; j < BlinkDurationSec * 2; j++)
9451 {
9452 if(j % 2)
9453 {
9454 // Turn on the LEDs.
9455 REG_WR(pDevice, MacCtrl.LedCtrl,
9456 LED_CTRL_OVERRIDE_LINK_LED |
9457 LED_CTRL_1000MBPS_LED_ON |
9458 LED_CTRL_100MBPS_LED_ON |
9459 LED_CTRL_10MBPS_LED_ON |
9460 LED_CTRL_OVERRIDE_TRAFFIC_LED |
9461 LED_CTRL_BLINK_TRAFFIC_LED |
9462 LED_CTRL_TRAFFIC_LED);
9463 }
9464 else
9465 {
9466 // Turn off the LEDs.
9467 REG_WR(pDevice, MacCtrl.LedCtrl,
9468 LED_CTRL_OVERRIDE_LINK_LED |
9469 LED_CTRL_OVERRIDE_TRAFFIC_LED);
9470 }
9471 if (MM_Sleep(pDevice, 500) != LM_STATUS_SUCCESS)/* 0.5 second */
9472 {
9473 ret = LM_STATUS_FAILURE;
9474 break;
9475 }
9476 }
9477 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
9478 return ret;
9479 }
9480
9481 LM_STATUS
9482 LM_SwitchClocks(PLM_DEVICE_BLOCK pDevice)
9483 {
9484 LM_UINT32 ClockCtrl;
9485
9486 if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
9487 return LM_STATUS_SUCCESS;
9488
9489 ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl);
9490 pDevice->ClockCtrl = ClockCtrl & (T3_PCI_FORCE_CLKRUN |
9491 T3_PCI_CLKRUN_OUTPUT_EN | 0x1f);
9492 if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
9493 {
9494 if (ClockCtrl & T3_PCI_625_CORE_CLOCK)
9495 {
9496 /* clear ALT clock first */
9497 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9498 T3_PCI_625_CORE_CLOCK);
9499 MM_Wait(40); /* required delay is 27usec */
9500 }
9501 }
9502 else
9503 {
9504 if (ClockCtrl & T3_PCI_44MHZ_CORE_CLOCK)
9505 {
9506 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9507 T3_PCI_44MHZ_CORE_CLOCK | T3_PCI_SELECT_ALTERNATE_CLOCK);
9508 MM_Wait(40); /* required delay is 27usec */
9509 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9510 T3_PCI_SELECT_ALTERNATE_CLOCK);
9511 MM_Wait(40); /* required delay is 27usec */
9512 }
9513 }
9514
9515 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
9516 MM_Wait(40); /* required delay is 27usec */
9517 return LM_STATUS_SUCCESS;
9518 }
9519
9520 int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
9521 LM_PHYSICAL_ADDRESS host_addr_phy, int length,
9522 int dma_read)
9523 {
9524 T3_DMA_DESC dma_desc;
9525 int i;
9526 LM_UINT32 dma_desc_addr;
9527 LM_UINT32 value32;
9528
9529 REG_WR(pDevice, BufMgr.Mode, 0);
9530 REG_WR(pDevice, Ftq.Reset, 0);
9531
9532 dma_desc.host_addr.High = host_addr_phy.High;
9533 dma_desc.host_addr.Low = host_addr_phy.Low;
9534 dma_desc.nic_mbuf = 0x2100;
9535 dma_desc.len = length;
9536 dma_desc.flags = 0x00000005; /* Generate Rx-CPU event */
9537
9538 if (dma_read)
9539 {
9540 dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
9541 T3_QID_DMA_HIGH_PRI_READ;
9542 REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
9543 }
9544 else
9545 {
9546 dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
9547 T3_QID_DMA_HIGH_PRI_WRITE;
9548 REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
9549 }
9550
9551 dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
9552
9553 /* Writing this DMA descriptor to DMA memory */
9554 for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
9555 {
9556 value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
9557 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
9558 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG,
9559 MM_SWAP_LE32(value32));
9560 }
9561 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
9562
9563 if (dma_read)
9564 REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
9565 else
9566 REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
9567
9568 for (i = 0; i < 40; i++)
9569 {
9570 if (dma_read)
9571 value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
9572 else
9573 value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
9574
9575 if ((value32 & 0xffff) == dma_desc_addr)
9576 break;
9577
9578 MM_Wait(10);
9579 }
9580
9581 return LM_STATUS_SUCCESS;
9582 }
9583
9584 STATIC LM_STATUS
9585 LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
9586 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
9587 {
9588 int j;
9589 LM_UINT32 *ptr;
9590 int dma_success = 0;
9591 LM_STATUS ret = LM_STATUS_FAILURE;
9592
9593 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
9594 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
9595 {
9596 return LM_STATUS_SUCCESS;
9597 }
9598 while (!dma_success)
9599 {
9600 /* Fill data with incremental patterns */
9601 ptr = (LM_UINT32 *)pBufferVirt;
9602 for (j = 0; j < BufferSize/4; j++)
9603 *ptr++ = j;
9604
9605 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
9606 {
9607 goto LM_DmaTestDone;
9608 }
9609
9610 MM_Wait(40);
9611 ptr = (LM_UINT32 *)pBufferVirt;
9612 /* Fill data with zero */
9613 for (j = 0; j < BufferSize/4; j++)
9614 *ptr++ = 0;
9615
9616 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
9617 {
9618 goto LM_DmaTestDone;
9619 }
9620
9621 MM_Wait(40);
9622 /* Check for data */
9623 ptr = (LM_UINT32 *)pBufferVirt;
9624 for (j = 0; j < BufferSize/4; j++)
9625 {
9626 if (*ptr++ != j)
9627 {
9628 if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
9629 != DMA_CTRL_WRITE_BOUNDARY_16)
9630 {
9631 pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
9632 ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
9633 DMA_CTRL_WRITE_BOUNDARY_16;
9634 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
9635 pDevice->DmaReadWriteCtrl);
9636 break;
9637 }
9638 else
9639 {
9640 goto LM_DmaTestDone;
9641 }
9642 }
9643 }
9644 if (j == (BufferSize/4))
9645 dma_success = 1;
9646 }
9647 ret = LM_STATUS_SUCCESS;
9648 LM_DmaTestDone:
9649 memset(pBufferVirt, 0, BufferSize);
9650 return ret;
9651 }
9652
9653 void
9654 LM_Add32To64Counter(LM_UINT32 Counter32, T3_64BIT_REGISTER *Counter64)
9655 {
9656 Counter64->Low += Counter32;
9657 if (Counter64->Low < Counter32)
9658 {
9659 Counter64->High++;
9660 }
9661 }
9662
9663 LM_STATUS
9664 LM_GetStats(PLM_DEVICE_BLOCK pDevice)
9665 {
9666 PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
9667
9668 if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
9669 {
9670 return LM_STATUS_FAILURE;
9671 }
9672
9673 if (pStats == 0)
9674 {
9675 return LM_STATUS_FAILURE;
9676 }
9677 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutOctets),
9678 &pStats->ifHCOutOctets);
9679 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsCollisions),
9680 &pStats->etherStatsCollisions);
9681 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXonSent),
9682 &pStats->outXonSent);
9683 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXoffSent),
9684 &pStats->outXoffSent);
9685 LM_Add32To64Counter(REG_RD(pDevice,
9686 MacCtrl.dot3StatsInternalMacTransmitErrors),
9687 &pStats->dot3StatsInternalMacTransmitErrors);
9688 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsSingleCollisionFrames),
9689 &pStats->dot3StatsSingleCollisionFrames);
9690 LM_Add32To64Counter(REG_RD(pDevice,
9691 MacCtrl.dot3StatsMultipleCollisionFrames),
9692 &pStats->dot3StatsMultipleCollisionFrames);
9693 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsDeferredTransmissions),
9694 &pStats->dot3StatsDeferredTransmissions);
9695 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsExcessiveCollisions),
9696 &pStats->dot3StatsExcessiveCollisions);
9697 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsLateCollisions),
9698 &pStats->dot3StatsLateCollisions);
9699 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutUcastPkts),
9700 &pStats->ifHCOutUcastPkts);
9701 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutMulticastPkts),
9702 &pStats->ifHCOutMulticastPkts);
9703 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutBroadcastPkts),
9704 &pStats->ifHCOutBroadcastPkts);
9705 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInOctets),
9706 &pStats->ifHCInOctets);
9707 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsFragments),
9708 &pStats->etherStatsFragments);
9709 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInUcastPkts),
9710 &pStats->ifHCInUcastPkts);
9711 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInMulticastPkts),
9712 &pStats->ifHCInMulticastPkts);
9713 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInBroadcastPkts),
9714 &pStats->ifHCInBroadcastPkts);
9715 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFCSErrors),
9716 &pStats->dot3StatsFCSErrors);
9717 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsAlignmentErrors),
9718 &pStats->dot3StatsAlignmentErrors);
9719 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xonPauseFramesReceived),
9720 &pStats->xonPauseFramesReceived);
9721 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffPauseFramesReceived),
9722 &pStats->xoffPauseFramesReceived);
9723 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.macControlFramesReceived),
9724 &pStats->macControlFramesReceived);
9725 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffStateEntered),
9726 &pStats->xoffStateEntered);
9727 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFramesTooLong),
9728 &pStats->dot3StatsFramesTooLong);
9729 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsJabbers),
9730 &pStats->etherStatsJabbers);
9731 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsUndersizePkts),
9732 &pStats->etherStatsUndersizePkts);
9733
9734 return LM_STATUS_SUCCESS;
9735 }