1 /******************************************************************************/
2 /*                                                                            */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 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 #include <common.h>
14 #include <asm/types.h>
15 
16 #ifdef CONFIG_BMW
17 #include <mpc824x.h>
18 #endif
19 #include <malloc.h>
20 #include <linux/byteorder/big_endian.h>
21 #include "bcm570x_mm.h"
22 
23 #define EMBEDDED 1
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_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE
32 						 RequestedMediaType,
33 						 PLM_MEDIA_TYPE pMediaType,
34 						 PLM_LINE_SPEED pLineSpeed,
35 						 PLM_DUPLEX_MODE pDuplexMode);
36 
37 static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice);
38 
39 __inline static LM_VOID LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice);
40 __inline static LM_VOID LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice);
41 
42 static LM_STATUS LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
43 					    LM_REQUESTED_MEDIA_TYPE
44 					    RequestedMediaType);
45 static LM_STATUS LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
46 				  LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
47 static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice);
48 STATIC LM_STATUS LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
49 				    LM_UINT32 LocalPhyAd,
50 				    LM_UINT32 RemotePhyAd);
51 #if INCLUDE_TBI_SUPPORT
52 STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice);
53 STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice);
54 #endif
55 STATIC LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice);
56 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid,
57 						 LM_UINT16 Ssid);
58 STATIC LM_STATUS LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
59 			     LM_PHYSICAL_ADDRESS BufferPhy,
60 			     LM_UINT32 BufferSize);
61 STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number);
62 STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice);
63 STATIC LM_STATUS LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice,
64 				    PLM_PACKET pPacket, PT3_SND_BD pSendBd);
65 
66 /******************************************************************************/
67 /* External functions. */
68 /******************************************************************************/
69 
70 LM_STATUS LM_LoadRlsFirmware (PLM_DEVICE_BLOCK pDevice);
71 
72 /******************************************************************************/
73 /* Description:                                                               */
74 /*                                                                            */
75 /* Return:                                                                    */
76 /******************************************************************************/
LM_RegRdInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register)77 LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
78 {
79 	LM_UINT32 Value32;
80 
81 #if PCIX_TARGET_WORKAROUND
82 	MM_ACQUIRE_UNDI_LOCK (pDevice);
83 #endif
84 	MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
85 	MM_ReadConfig32 (pDevice, T3_PCI_REG_DATA_REG, &Value32);
86 #if PCIX_TARGET_WORKAROUND
87 	MM_RELEASE_UNDI_LOCK (pDevice);
88 #endif
89 
90 	return Value32;
91 }				/* LM_RegRdInd */
92 
93 /******************************************************************************/
94 /* Description:                                                               */
95 /*                                                                            */
96 /* Return:                                                                    */
97 /******************************************************************************/
98 LM_VOID
LM_RegWrInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32)99 LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32)
100 {
101 
102 #if PCIX_TARGET_WORKAROUND
103 	MM_ACQUIRE_UNDI_LOCK (pDevice);
104 #endif
105 	MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
106 	MM_WriteConfig32 (pDevice, T3_PCI_REG_DATA_REG, Value32);
107 #if PCIX_TARGET_WORKAROUND
108 	MM_RELEASE_UNDI_LOCK (pDevice);
109 #endif
110 }				/* LM_RegWrInd */
111 
112 /******************************************************************************/
113 /* Description:                                                               */
114 /*                                                                            */
115 /* Return:                                                                    */
116 /******************************************************************************/
LM_MemRdInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 MemAddr)117 LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr)
118 {
119 	LM_UINT32 Value32;
120 
121 	MM_ACQUIRE_UNDI_LOCK (pDevice);
122 #ifdef BIG_ENDIAN_HOST
123 	MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
124 	Value32 = REG_RD (pDevice, PciCfg.MemWindowData);
125 	/*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
126 #else
127 	MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
128 	MM_ReadConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
129 #endif
130 	MM_RELEASE_UNDI_LOCK (pDevice);
131 
132 	return Value32;
133 }				/* LM_MemRdInd */
134 
135 /******************************************************************************/
136 /* Description:                                                               */
137 /*                                                                            */
138 /* Return:                                                                    */
139 /******************************************************************************/
140 LM_VOID
LM_MemWrInd(PLM_DEVICE_BLOCK pDevice,LM_UINT32 MemAddr,LM_UINT32 Value32)141 LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr, LM_UINT32 Value32)
142 {
143 	MM_ACQUIRE_UNDI_LOCK (pDevice);
144 #ifdef BIG_ENDIAN_HOST
145 	REG_WR (pDevice, PciCfg.MemWindowBaseAddr, MemAddr);
146 	REG_WR (pDevice, uIntMem.Mbuf[(MemAddr & 0x7fff) / 4], Value32);
147 #else
148 	MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
149 	MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
150 #endif
151 	MM_RELEASE_UNDI_LOCK (pDevice);
152 }				/* LM_MemWrInd */
153 
154 /******************************************************************************/
155 /* Description:                                                               */
156 /*                                                                            */
157 /* Return:                                                                    */
158 /******************************************************************************/
LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice)159 LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice)
160 {
161 	LM_STATUS Lmstatus;
162 	PLM_PACKET pPacket;
163 	PT3_RCV_BD pRcvBd;
164 	LM_UINT32 StdBdAdded = 0;
165 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
166 	LM_UINT32 JumboBdAdded = 0;
167 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
168 
169 	Lmstatus = LM_STATUS_SUCCESS;
170 
171 	pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
172 	while (pPacket) {
173 		switch (pPacket->u.Rx.RcvProdRing) {
174 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
175 		case T3_JUMBO_RCV_PROD_RING:	/* Jumbo Receive Ring. */
176 			/* Initialize the buffer descriptor. */
177 			pRcvBd =
178 			    &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
179 			pRcvBd->Flags =
180 			    RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
181 			pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
182 
183 			/* Initialize the receive buffer pointer */
184 #if 0				/* Jimmy, deleted in new */
185 			pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
186 			pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
187 #endif
188 			MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
189 
190 			/* The opaque field may point to an offset from a fix addr. */
191 			pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
192 						      MM_UINT_PTR (pDevice->
193 								   pPacketDescBase));
194 
195 			/* Update the producer index. */
196 			pDevice->RxJumboProdIdx =
197 			    (pDevice->RxJumboProdIdx +
198 			     1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
199 
200 			JumboBdAdded++;
201 			break;
202 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
203 
204 		case T3_STD_RCV_PROD_RING:	/* Standard Receive Ring. */
205 			/* Initialize the buffer descriptor. */
206 			pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
207 			pRcvBd->Flags = RCV_BD_FLAG_END;
208 			pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
209 
210 			/* Initialize the receive buffer pointer */
211 #if 0				/* Jimmy, deleted in new replaced with MM_MapRxDma */
212 			pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
213 			pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
214 #endif
215 			MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
216 
217 			/* The opaque field may point to an offset from a fix addr. */
218 			pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
219 						      MM_UINT_PTR (pDevice->
220 								   pPacketDescBase));
221 
222 			/* Update the producer index. */
223 			pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
224 			    T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
225 
226 			StdBdAdded++;
227 			break;
228 
229 		case T3_UNKNOWN_RCV_PROD_RING:
230 		default:
231 			Lmstatus = LM_STATUS_FAILURE;
232 			break;
233 		}		/* switch */
234 
235 		/* Bail out if there is any error. */
236 		if (Lmstatus != LM_STATUS_SUCCESS) {
237 			break;
238 		}
239 
240 		pPacket =
241 		    (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
242 	}			/* while */
243 
244 	wmb ();
245 	/* Update the procedure index. */
246 	if (StdBdAdded) {
247 		MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low,
248 			   pDevice->RxStdProdIdx);
249 	}
250 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
251 	if (JumboBdAdded) {
252 		MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low,
253 			   pDevice->RxJumboProdIdx);
254 	}
255 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
256 
257 	return Lmstatus;
258 }				/* LM_QueueRxPackets */
259 
260 /******************************************************************************/
261 /* Description:                                                               */
262 /*                                                                            */
263 /* Return:                                                                    */
264 /******************************************************************************/
LM_NvramInit(PLM_DEVICE_BLOCK pDevice)265 STATIC LM_VOID LM_NvramInit (PLM_DEVICE_BLOCK pDevice)
266 {
267 	LM_UINT32 Value32;
268 	LM_UINT32 j;
269 
270 	/* Intialize clock period and state machine. */
271 	Value32 = SEEPROM_ADDR_CLK_PERD (SEEPROM_CLOCK_PERIOD) |
272 	    SEEPROM_ADDR_FSM_RESET;
273 	REG_WR (pDevice, Grc.EepromAddr, Value32);
274 
275 	for (j = 0; j < 100; j++) {
276 		MM_Wait (10);
277 	}
278 
279 	/* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
280 	Value32 = REG_RD (pDevice, Grc.LocalCtrl);
281 	REG_WR (pDevice, Grc.LocalCtrl,
282 		Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
283 
284 	/* Set the 5701 compatibility mode if we are using EEPROM. */
285 	if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
286 	    T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
287 		Value32 = REG_RD (pDevice, Nvram.Config1);
288 		if ((Value32 & FLASH_INTERFACE_ENABLE) == 0) {
289 			/* Use the new interface to read EEPROM. */
290 			Value32 &= ~FLASH_COMPAT_BYPASS;
291 
292 			REG_WR (pDevice, Nvram.Config1, Value32);
293 		}
294 	}
295 }				/* LM_NvRamInit */
296 
297 /******************************************************************************/
298 /* Description:                                                               */
299 /*                                                                            */
300 /* Return:                                                                    */
301 /******************************************************************************/
302 STATIC LM_STATUS
LM_EepromRead(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Offset,LM_UINT32 * pData)303 LM_EepromRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
304 {
305 	LM_UINT32 Value32;
306 	LM_UINT32 Addr;
307 	LM_UINT32 Dev;
308 	LM_UINT32 j;
309 
310 	if (Offset > SEEPROM_CHIP_SIZE) {
311 		return LM_STATUS_FAILURE;
312 	}
313 
314 	Dev = Offset / SEEPROM_CHIP_SIZE;
315 	Addr = Offset % SEEPROM_CHIP_SIZE;
316 
317 	Value32 = REG_RD (pDevice, Grc.EepromAddr);
318 	Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
319 		     SEEPROM_ADDR_RW_MASK);
320 	REG_WR (pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID (Dev) |
321 		SEEPROM_ADDR_ADDRESS (Addr) | SEEPROM_ADDR_START |
322 		SEEPROM_ADDR_READ);
323 
324 	for (j = 0; j < 1000; j++) {
325 		Value32 = REG_RD (pDevice, Grc.EepromAddr);
326 		if (Value32 & SEEPROM_ADDR_COMPLETE) {
327 			break;
328 		}
329 		MM_Wait (10);
330 	}
331 
332 	if (Value32 & SEEPROM_ADDR_COMPLETE) {
333 		Value32 = REG_RD (pDevice, Grc.EepromData);
334 		*pData = Value32;
335 
336 		return LM_STATUS_SUCCESS;
337 	}
338 
339 	return LM_STATUS_FAILURE;
340 }				/* LM_EepromRead */
341 
342 /******************************************************************************/
343 /* Description:                                                               */
344 /*                                                                            */
345 /* Return:                                                                    */
346 /******************************************************************************/
347 STATIC LM_STATUS
LM_NvramRead(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Offset,LM_UINT32 * pData)348 LM_NvramRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
349 {
350 	LM_UINT32 Value32;
351 	LM_STATUS Status;
352 	LM_UINT32 j;
353 
354 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
355 	    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
356 		Status = LM_EepromRead (pDevice, Offset, pData);
357 	} else {
358 		/* Determine if we have flash or EEPROM. */
359 		Value32 = REG_RD (pDevice, Nvram.Config1);
360 		if (Value32 & FLASH_INTERFACE_ENABLE) {
361 			if (Value32 & FLASH_SSRAM_BUFFERRED_MODE) {
362 				Offset = ((Offset / BUFFERED_FLASH_PAGE_SIZE) <<
363 					  BUFFERED_FLASH_PAGE_POS) +
364 				    (Offset % BUFFERED_FLASH_PAGE_SIZE);
365 			}
366 		}
367 
368 		REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
369 		for (j = 0; j < 1000; j++) {
370 			if (REG_RD (pDevice, Nvram.SwArb) & SW_ARB_GNT1) {
371 				break;
372 			}
373 			MM_Wait (20);
374 		}
375 		if (j == 1000) {
376 			return LM_STATUS_FAILURE;
377 		}
378 
379 		/* Read from flash or EEPROM with the new 5703/02 interface. */
380 		REG_WR (pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
381 
382 		REG_WR (pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
383 			NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
384 
385 		/* Wait for the done bit to clear. */
386 		for (j = 0; j < 500; j++) {
387 			MM_Wait (10);
388 
389 			Value32 = REG_RD (pDevice, Nvram.Cmd);
390 			if (!(Value32 & NVRAM_CMD_DONE)) {
391 				break;
392 			}
393 		}
394 
395 		/* Wait for the done bit. */
396 		if (!(Value32 & NVRAM_CMD_DONE)) {
397 			for (j = 0; j < 500; j++) {
398 				MM_Wait (10);
399 
400 				Value32 = REG_RD (pDevice, Nvram.Cmd);
401 				if (Value32 & NVRAM_CMD_DONE) {
402 					MM_Wait (10);
403 
404 					*pData =
405 					    REG_RD (pDevice, Nvram.ReadData);
406 
407 					/* Change the endianess. */
408 					*pData =
409 					    ((*pData & 0xff) << 24) |
410 					    ((*pData & 0xff00) << 8) |
411 					    ((*pData & 0xff0000) >> 8) |
412 					    ((*pData >> 24) & 0xff);
413 
414 					break;
415 				}
416 			}
417 		}
418 
419 		REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
420 		if (Value32 & NVRAM_CMD_DONE) {
421 			Status = LM_STATUS_SUCCESS;
422 		} else {
423 			Status = LM_STATUS_FAILURE;
424 		}
425 	}
426 
427 	return Status;
428 }				/* LM_NvramRead */
429 
LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)430 STATIC void LM_ReadVPD (PLM_DEVICE_BLOCK pDevice)
431 {
432 	LM_UINT32 Vpd_arr[256 / 4];
433 	LM_UINT8 *Vpd = (LM_UINT8 *) & Vpd_arr[0];
434 	LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
435 	LM_UINT32 Value32;
436 	unsigned int j;
437 
438 	/* Read PN from VPD */
439 	for (j = 0; j < 256; j += 4, Vpd_dptr++) {
440 		if (LM_NvramRead (pDevice, 0x100 + j, &Value32) !=
441 		    LM_STATUS_SUCCESS) {
442 			printf ("BCM570x: LM_ReadVPD: VPD read failed"
443 				" (no EEPROM onboard)\n");
444 			return;
445 		}
446 		*Vpd_dptr = cpu_to_le32 (Value32);
447 	}
448 	for (j = 0; j < 256;) {
449 		unsigned int Vpd_r_len;
450 		unsigned int Vpd_r_end;
451 
452 		if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91)) {
453 			j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
454 		} else if (Vpd[j] == 0x90) {
455 			Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
456 			j += 3;
457 			Vpd_r_end = Vpd_r_len + j;
458 			while (j < Vpd_r_end) {
459 				if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N')) {
460 					unsigned int len = Vpd[j + 2];
461 
462 					if (len <= 24) {
463 						memcpy (pDevice->PartNo,
464 							&Vpd[j + 3], len);
465 					}
466 					break;
467 				} else {
468 					if (Vpd[j + 2] == 0) {
469 						break;
470 					}
471 					j = j + Vpd[j + 2];
472 				}
473 			}
474 			break;
475 		} else {
476 			break;
477 		}
478 	}
479 }
480 
LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)481 STATIC void LM_ReadBootCodeVersion (PLM_DEVICE_BLOCK pDevice)
482 {
483 	LM_UINT32 Value32, offset, ver_offset;
484 	int i;
485 
486 	if (LM_NvramRead (pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
487 		return;
488 	if (Value32 != 0xaa559966)
489 		return;
490 	if (LM_NvramRead (pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
491 		return;
492 
493 	offset = ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) |
494 	    ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
495 	if (LM_NvramRead (pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
496 		return;
497 	if ((Value32 == 0x0300000e) &&
498 	    (LM_NvramRead (pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS)
499 	    && (Value32 == 0)) {
500 
501 		if (LM_NvramRead (pDevice, offset + 8, &ver_offset) !=
502 		    LM_STATUS_SUCCESS)
503 			return;
504 		ver_offset = ((ver_offset & 0xff0000) >> 8) |
505 		    ((ver_offset >> 24) & 0xff);
506 		for (i = 0; i < 16; i += 4) {
507 			if (LM_NvramRead
508 			    (pDevice, offset + ver_offset + i,
509 			     &Value32) != LM_STATUS_SUCCESS) {
510 				return;
511 			}
512 			*((LM_UINT32 *) & pDevice->BootCodeVer[i]) =
513 			    cpu_to_le32 (Value32);
514 		}
515 	} else {
516 		char c;
517 
518 		if (LM_NvramRead (pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
519 			return;
520 
521 		i = 0;
522 		c = ((Value32 & 0xff0000) >> 16);
523 
524 		if (c < 10) {
525 			pDevice->BootCodeVer[i++] = c + '0';
526 		} else {
527 			pDevice->BootCodeVer[i++] = (c / 10) + '0';
528 			pDevice->BootCodeVer[i++] = (c % 10) + '0';
529 		}
530 		pDevice->BootCodeVer[i++] = '.';
531 		c = (Value32 & 0xff000000) >> 24;
532 		if (c < 10) {
533 			pDevice->BootCodeVer[i++] = c + '0';
534 		} else {
535 			pDevice->BootCodeVer[i++] = (c / 10) + '0';
536 			pDevice->BootCodeVer[i++] = (c % 10) + '0';
537 		}
538 		pDevice->BootCodeVer[i] = 0;
539 	}
540 }
541 
LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)542 STATIC void LM_GetBusSpeed (PLM_DEVICE_BLOCK pDevice)
543 {
544 	LM_UINT32 PciState = pDevice->PciState;
545 	LM_UINT32 ClockCtrl;
546 	char *SpeedStr = "";
547 
548 	if (PciState & T3_PCI_STATE_32BIT_PCI_BUS) {
549 		strcpy (pDevice->BusSpeedStr, "32-bit ");
550 	} else {
551 		strcpy (pDevice->BusSpeedStr, "64-bit ");
552 	}
553 	if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) {
554 		strcat (pDevice->BusSpeedStr, "PCI ");
555 		if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED) {
556 			SpeedStr = "66MHz";
557 		} else {
558 			SpeedStr = "33MHz";
559 		}
560 	} else {
561 		strcat (pDevice->BusSpeedStr, "PCIX ");
562 		if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE) {
563 			SpeedStr = "133MHz";
564 		} else {
565 			ClockCtrl = REG_RD (pDevice, PciCfg.ClockCtrl) & 0x1f;
566 			switch (ClockCtrl) {
567 			case 0:
568 				SpeedStr = "33MHz";
569 				break;
570 
571 			case 2:
572 				SpeedStr = "50MHz";
573 				break;
574 
575 			case 4:
576 				SpeedStr = "66MHz";
577 				break;
578 
579 			case 6:
580 				SpeedStr = "100MHz";
581 				break;
582 
583 			case 7:
584 				SpeedStr = "133MHz";
585 				break;
586 			}
587 		}
588 	}
589 	strcat (pDevice->BusSpeedStr, SpeedStr);
590 }
591 
592 /******************************************************************************/
593 /* Description:                                                               */
594 /*    This routine initializes default parameters and reads the PCI           */
595 /*    configurations.                                                         */
596 /*                                                                            */
597 /* Return:                                                                    */
598 /*    LM_STATUS_SUCCESS                                                       */
599 /******************************************************************************/
LM_GetAdapterInfo(PLM_DEVICE_BLOCK pDevice)600 LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice)
601 {
602 	PLM_ADAPTER_INFO pAdapterInfo;
603 	LM_UINT32 Value32;
604 	LM_STATUS Status;
605 	LM_UINT32 j;
606 	LM_UINT32 EeSigFound;
607 	LM_UINT32 EePhyTypeSerdes = 0;
608 	LM_UINT32 EePhyLedMode = 0;
609 	LM_UINT32 EePhyId = 0;
610 
611 	/* Get Device Id and Vendor Id */
612 	Status = MM_ReadConfig32 (pDevice, PCI_VENDOR_ID_REG, &Value32);
613 	if (Status != LM_STATUS_SUCCESS) {
614 		return Status;
615 	}
616 	pDevice->PciVendorId = (LM_UINT16) Value32;
617 	pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
618 
619 	/* If we are not getting the write adapter, exit. */
620 	if ((Value32 != T3_PCI_ID_BCM5700) &&
621 	    (Value32 != T3_PCI_ID_BCM5701) &&
622 	    (Value32 != T3_PCI_ID_BCM5702) &&
623 	    (Value32 != T3_PCI_ID_BCM5702x) &&
624 	    (Value32 != T3_PCI_ID_BCM5702FE) &&
625 	    (Value32 != T3_PCI_ID_BCM5703) &&
626 	    (Value32 != T3_PCI_ID_BCM5703x) && (Value32 != T3_PCI_ID_BCM5704)) {
627 		return LM_STATUS_FAILURE;
628 	}
629 
630 	Status = MM_ReadConfig32 (pDevice, PCI_REV_ID_REG, &Value32);
631 	if (Status != LM_STATUS_SUCCESS) {
632 		return Status;
633 	}
634 	pDevice->PciRevId = (LM_UINT8) Value32;
635 
636 	/* Get IRQ. */
637 	Status = MM_ReadConfig32 (pDevice, PCI_INT_LINE_REG, &Value32);
638 	if (Status != LM_STATUS_SUCCESS) {
639 		return Status;
640 	}
641 	pDevice->Irq = (LM_UINT8) Value32;
642 
643 	/* Get interrupt pin. */
644 	pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
645 
646 	/* Get chip revision id. */
647 	Status = MM_ReadConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
648 	pDevice->ChipRevId = Value32 >> 16;
649 
650 	/* Get subsystem vendor. */
651 	Status =
652 	    MM_ReadConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
653 	if (Status != LM_STATUS_SUCCESS) {
654 		return Status;
655 	}
656 	pDevice->SubsystemVendorId = (LM_UINT16) Value32;
657 
658 	/* Get PCI subsystem id. */
659 	pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
660 
661 	/* Get the cache line size. */
662 	MM_ReadConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
663 	pDevice->CacheLineSize = (LM_UINT8) Value32;
664 	pDevice->SavedCacheLineReg = Value32;
665 
666 	if (pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
667 	    pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
668 	    pDevice->ChipRevId != T3_CHIP_ID_5704_A0) {
669 		pDevice->UndiFix = FALSE;
670 	}
671 #if !PCIX_TARGET_WORKAROUND
672 	pDevice->UndiFix = FALSE;
673 #endif
674 	/* Map the memory base to system address space. */
675 	if (!pDevice->UndiFix) {
676 		Status = MM_MapMemBase (pDevice);
677 		if (Status != LM_STATUS_SUCCESS) {
678 			return Status;
679 		}
680 		/* Initialize the memory view pointer. */
681 		pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
682 	}
683 #if PCIX_TARGET_WORKAROUND
684 	/* store whether we are in PCI are PCI-X mode */
685 	pDevice->EnablePciXFix = FALSE;
686 
687 	MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
688 	if ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0) {
689 		/* Enable PCI-X workaround only if we are running on 5700 BX. */
690 		if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
691 			pDevice->EnablePciXFix = TRUE;
692 		}
693 	}
694 	if (pDevice->UndiFix) {
695 		pDevice->EnablePciXFix = TRUE;
696 	}
697 #endif
698 	/* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
699 	/* management register may be clobbered which may cause the */
700 	/* BCM5700 to go into D3 state.  While in this state, we will */
701 	/* not have memory mapped register access.  As a workaround, we */
702 	/* need to restore the device to D0 state. */
703 	MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
704 	Value32 |= T3_PM_PME_ASSERTED;
705 	Value32 &= ~T3_PM_POWER_STATE_MASK;
706 	Value32 |= T3_PM_POWER_STATE_D0;
707 	MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
708 
709 	/* read the current PCI command word */
710 	MM_ReadConfig32 (pDevice, PCI_COMMAND_REG, &Value32);
711 
712 	/* Make sure bus-mastering is enabled. */
713 	Value32 |= PCI_BUSMASTER_ENABLE;
714 
715 #if PCIX_TARGET_WORKAROUND
716 	/* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
717 	   are enabled */
718 	if (pDevice->EnablePciXFix == TRUE) {
719 		Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
720 			    PCI_PARITY_ERROR_ENABLE);
721 	}
722 	if (pDevice->UndiFix) {
723 		Value32 &= ~PCI_MEM_SPACE_ENABLE;
724 	}
725 #endif
726 
727 	if (pDevice->EnableMWI) {
728 		Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
729 	} else {
730 		Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
731 	}
732 
733 	/* Error out if mem-mapping is NOT enabled for PCI systems */
734 	if (!(Value32 | PCI_MEM_SPACE_ENABLE)) {
735 		return LM_STATUS_FAILURE;
736 	}
737 
738 	/* save the value we are going to write into the PCI command word */
739 	pDevice->PciCommandStatusWords = Value32;
740 
741 	Status = MM_WriteConfig32 (pDevice, PCI_COMMAND_REG, Value32);
742 	if (Status != LM_STATUS_SUCCESS) {
743 		return Status;
744 	}
745 
746 	/* Set power state to D0. */
747 	LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
748 
749 #ifdef BIG_ENDIAN_PCI
750 	pDevice->MiscHostCtrl =
751 	    MISC_HOST_CTRL_MASK_PCI_INT |
752 	    MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
753 	    MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
754 	    MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
755 #else				/* No CPU Swap modes for PCI IO */
756 
757 	/* Setup the mode registers. */
758 	pDevice->MiscHostCtrl =
759 	    MISC_HOST_CTRL_MASK_PCI_INT |
760 	    MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
761 #ifdef BIG_ENDIAN_HOST
762 	    MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
763 #endif				/* BIG_ENDIAN_HOST */
764 	    MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
765 	    MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
766 #endif				/* !BIG_ENDIAN_PCI */
767 
768 	/* write to PCI misc host ctr first in order to enable indirect accesses */
769 	MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
770 			  pDevice->MiscHostCtrl);
771 
772 	REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
773 
774 #ifdef BIG_ENDIAN_PCI
775 	Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
776 #else
777 /* No CPU Swap modes for PCI IO */
778 #ifdef BIG_ENDIAN_HOST
779 	Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
780 	    GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
781 #else
782 	Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
783 #endif
784 #endif				/* !BIG_ENDIAN_PCI */
785 
786 	REG_WR (pDevice, Grc.Mode, Value32);
787 
788 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
789 		REG_WR (pDevice, Grc.LocalCtrl,
790 			GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
791 			GRC_MISC_LOCAL_CTRL_GPIO_OE1);
792 	}
793 	MM_Wait (40);
794 
795 	/* Enable indirect memory access */
796 	REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
797 
798 	if (REG_RD (pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK) {
799 		REG_WR (pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
800 			T3_PCI_SELECT_ALTERNATE_CLOCK);
801 		REG_WR (pDevice, PciCfg.ClockCtrl,
802 			T3_PCI_SELECT_ALTERNATE_CLOCK);
803 		MM_Wait (40);	/* required delay is 27usec */
804 	}
805 	REG_WR (pDevice, PciCfg.ClockCtrl, 0);
806 	REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
807 
808 #if PCIX_TARGET_WORKAROUND
809 	MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
810 	if ((pDevice->EnablePciXFix == FALSE) &&
811 	    ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)) {
812 		if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
813 		    pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
814 		    pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
815 		    pDevice->ChipRevId == T3_CHIP_ID_5701_B5) {
816 			__raw_writel (0,
817 				      &(pDevice->pMemView->uIntMem.
818 					MemBlock32K[0x300]));
819 			__raw_writel (0,
820 				      &(pDevice->pMemView->uIntMem.
821 					MemBlock32K[0x301]));
822 			__raw_writel (0xffffffff,
823 				      &(pDevice->pMemView->uIntMem.
824 					MemBlock32K[0x301]));
825 			if (__raw_readl
826 			    (&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
827 			{
828 				pDevice->EnablePciXFix = TRUE;
829 			}
830 		}
831 	}
832 #endif
833 #if 1
834 	/*
835 	 *  This code was at the beginning of else block below, but that's
836 	 *  a bug if node address in shared memory.
837 	 */
838 	MM_Wait (50);
839 	LM_NvramInit (pDevice);
840 #endif
841 	/* Get the node address.  First try to get in from the shared memory. */
842 	/* If the signature is not present, then get it from the NVRAM. */
843 	Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
844 	if ((Value32 >> 16) == 0x484b) {
845 
846 		pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
847 		pDevice->NodeAddress[1] = (LM_UINT8) Value32;
848 
849 		Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_LOW_MAILBOX);
850 
851 		pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
852 		pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
853 		pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
854 		pDevice->NodeAddress[5] = (LM_UINT8) Value32;
855 
856 		Status = LM_STATUS_SUCCESS;
857 	} else {
858 		Status = LM_NvramRead (pDevice, 0x7c, &Value32);
859 		if (Status == LM_STATUS_SUCCESS) {
860 			pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
861 			pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
862 
863 			Status = LM_NvramRead (pDevice, 0x80, &Value32);
864 
865 			pDevice->NodeAddress[2] = (LM_UINT8) Value32;
866 			pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
867 			pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
868 			pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
869 		}
870 	}
871 
872 	/* Assign a default address. */
873 	if (Status != LM_STATUS_SUCCESS) {
874 #ifndef EMBEDDED
875 		printk (KERN_ERR
876 			"Cannot get MAC addr from NVRAM. Using default.\n");
877 #endif
878 		pDevice->NodeAddress[0] = 0x00;
879 		pDevice->NodeAddress[1] = 0x10;
880 		pDevice->NodeAddress[2] = 0x18;
881 		pDevice->NodeAddress[3] = 0x68;
882 		pDevice->NodeAddress[4] = 0x61;
883 		pDevice->NodeAddress[5] = 0x76;
884 	}
885 
886 	pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
887 	pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
888 	pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
889 	pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
890 	pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
891 	pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
892 
893 	/* Initialize the default values. */
894 	pDevice->NoTxPseudoHdrChksum = FALSE;
895 	pDevice->NoRxPseudoHdrChksum = FALSE;
896 	pDevice->NicSendBd = FALSE;
897 	pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
898 	pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
899 	pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
900 	pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
901 	pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
902 	pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
903 	pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
904 	pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
905 	pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
906 	pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
907 	pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
908 	pDevice->EnableMWI = FALSE;
909 	pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
910 	pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
911 	pDevice->DisableAutoNeg = FALSE;
912 	pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
913 	pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
914 	pDevice->LedMode = LED_MODE_AUTO;
915 	pDevice->ResetPhyOnInit = TRUE;
916 	pDevice->DelayPciGrant = TRUE;
917 	pDevice->UseTaggedStatus = FALSE;
918 	pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
919 
920 	pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
921 	pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
922 	pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
923 
924 	pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
925 	pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
926 	pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
927 	pDevice->EnableTbi = FALSE;
928 #if INCLUDE_TBI_SUPPORT
929 	pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
930 #endif
931 
932 	switch (T3_ASIC_REV (pDevice->ChipRevId)) {
933 	case T3_ASIC_REV_5704:
934 		pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
935 		pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
936 		break;
937 	default:
938 		pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
939 		pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
940 		break;
941 	}
942 
943 	pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
944 	pDevice->QueueRxPackets = TRUE;
945 
946 	pDevice->EnableWireSpeed = TRUE;
947 
948 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
949 	pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
950 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
951 
952 	/* Make this is a known adapter. */
953 	pAdapterInfo = LM_GetAdapterInfoBySsid (pDevice->SubsystemVendorId,
954 						pDevice->SubsystemId);
955 
956 	pDevice->BondId = REG_RD (pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
957 	if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
958 	    pDevice->BondId != GRC_MISC_BD_ID_5701 &&
959 	    pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
960 	    pDevice->BondId != GRC_MISC_BD_ID_5703 &&
961 	    pDevice->BondId != GRC_MISC_BD_ID_5703S &&
962 	    pDevice->BondId != GRC_MISC_BD_ID_5704 &&
963 	    pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE) {
964 		return LM_STATUS_UNKNOWN_ADAPTER;
965 	}
966 
967 	pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
968 	if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
969 	    (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)) {
970 		pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
971 		pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
972 	}
973 
974 	/* Get Eeprom info. */
975 	Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_SIG_ADDR);
976 	if (Value32 == T3_NIC_DATA_SIG) {
977 		EeSigFound = TRUE;
978 		Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
979 
980 		/* Determine PHY type. */
981 		switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK) {
982 		case T3_NIC_CFG_PHY_TYPE_COPPER:
983 			EePhyTypeSerdes = FALSE;
984 			break;
985 
986 		case T3_NIC_CFG_PHY_TYPE_FIBER:
987 			EePhyTypeSerdes = TRUE;
988 			break;
989 
990 		default:
991 			EePhyTypeSerdes = FALSE;
992 			break;
993 		}
994 
995 		/* Determine PHY led mode. */
996 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
997 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
998 			switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
999 			case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
1000 				EePhyLedMode = LED_MODE_THREE_LINK;
1001 				break;
1002 
1003 			case T3_NIC_CFG_LED_MODE_LINK_SPEED:
1004 				EePhyLedMode = LED_MODE_LINK10;
1005 				break;
1006 
1007 			default:
1008 				EePhyLedMode = LED_MODE_AUTO;
1009 				break;
1010 			}
1011 		} else {
1012 			switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
1013 			case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
1014 				EePhyLedMode = LED_MODE_OPEN_DRAIN;
1015 				break;
1016 
1017 			case T3_NIC_CFG_LED_MODE_OUTPUT:
1018 				EePhyLedMode = LED_MODE_OUTPUT;
1019 				break;
1020 
1021 			default:
1022 				EePhyLedMode = LED_MODE_AUTO;
1023 				break;
1024 			}
1025 		}
1026 		if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1027 		    pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
1028 			/* Enable EEPROM write protection. */
1029 			if (Value32 & T3_NIC_EEPROM_WP) {
1030 				pDevice->EepromWp = TRUE;
1031 			}
1032 		}
1033 
1034 		/* Get the PHY Id. */
1035 		Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1036 		if (Value32) {
1037 			EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1038 				   PHY_ID1_OUI_MASK) << 10;
1039 
1040 			Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1041 
1042 			EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1043 			    (Value32 & PHY_ID2_MODEL_MASK) | (Value32 &
1044 							      PHY_ID2_REV_MASK);
1045 		} else {
1046 			EePhyId = 0;
1047 		}
1048 	} else {
1049 		EeSigFound = FALSE;
1050 	}
1051 
1052 	/* Set the PHY address. */
1053 	pDevice->PhyAddr = PHY_DEVICE_ID;
1054 
1055 	/* Disable auto polling. */
1056 	pDevice->MiMode = 0xc0000;
1057 	REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
1058 	MM_Wait (40);
1059 
1060 	/* Get the PHY id. */
1061 	LM_ReadPhy (pDevice, PHY_ID1_REG, &Value32);
1062 	pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
1063 
1064 	LM_ReadPhy (pDevice, PHY_ID2_REG, &Value32);
1065 	pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1066 	    (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1067 
1068 	/* Set the EnableTbi flag to false if we have a copper PHY. */
1069 	switch (pDevice->PhyId & PHY_ID_MASK) {
1070 	case PHY_BCM5400_PHY_ID:
1071 		pDevice->EnableTbi = FALSE;
1072 		break;
1073 
1074 	case PHY_BCM5401_PHY_ID:
1075 		pDevice->EnableTbi = FALSE;
1076 		break;
1077 
1078 	case PHY_BCM5411_PHY_ID:
1079 		pDevice->EnableTbi = FALSE;
1080 		break;
1081 
1082 	case PHY_BCM5701_PHY_ID:
1083 		pDevice->EnableTbi = FALSE;
1084 		break;
1085 
1086 	case PHY_BCM5703_PHY_ID:
1087 		pDevice->EnableTbi = FALSE;
1088 		break;
1089 
1090 	case PHY_BCM5704_PHY_ID:
1091 		pDevice->EnableTbi = FALSE;
1092 		break;
1093 
1094 	case PHY_BCM8002_PHY_ID:
1095 		pDevice->EnableTbi = TRUE;
1096 		break;
1097 
1098 	default:
1099 
1100 		if (pAdapterInfo) {
1101 			pDevice->PhyId = pAdapterInfo->PhyId;
1102 			pDevice->EnableTbi = pAdapterInfo->Serdes;
1103 		} else if (EeSigFound) {
1104 			pDevice->PhyId = EePhyId;
1105 			pDevice->EnableTbi = EePhyTypeSerdes;
1106 		}
1107 		break;
1108 	}
1109 
1110 	/* Bail out if we don't know the copper PHY id. */
1111 	if (UNKNOWN_PHY_ID (pDevice->PhyId) && !pDevice->EnableTbi) {
1112 		return LM_STATUS_FAILURE;
1113 	}
1114 
1115 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
1116 		if ((pDevice->SavedCacheLineReg & 0xff00) < 0x4000) {
1117 			pDevice->SavedCacheLineReg &= 0xffff00ff;
1118 			pDevice->SavedCacheLineReg |= 0x4000;
1119 		}
1120 	}
1121 	/* Change driver parameters. */
1122 	Status = MM_GetConfig (pDevice);
1123 	if (Status != LM_STATUS_SUCCESS) {
1124 		return Status;
1125 	}
1126 #if INCLUDE_5701_AX_FIX
1127 	if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1128 	    pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
1129 		pDevice->ResetPhyOnInit = TRUE;
1130 	}
1131 #endif
1132 
1133 	/* Save the current phy link status. */
1134 	if (!pDevice->EnableTbi) {
1135 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
1136 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
1137 
1138 		/* If we don't have link reset the PHY. */
1139 		if (!(Value32 & PHY_STATUS_LINK_PASS)
1140 		    || pDevice->ResetPhyOnInit) {
1141 
1142 			LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
1143 
1144 			for (j = 0; j < 100; j++) {
1145 				MM_Wait (10);
1146 
1147 				LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
1148 				if (Value32 && !(Value32 & PHY_CTRL_PHY_RESET)) {
1149 					MM_Wait (40);
1150 					break;
1151 				}
1152 			}
1153 
1154 #if INCLUDE_5701_AX_FIX
1155 			/* 5701_AX_BX bug:  only advertises 10mb speed. */
1156 			if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1157 			    pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
1158 
1159 				Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1160 				    PHY_AN_AD_10BASET_HALF |
1161 				    PHY_AN_AD_10BASET_FULL |
1162 				    PHY_AN_AD_100BASETX_FULL |
1163 				    PHY_AN_AD_100BASETX_HALF;
1164 				Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
1165 				LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
1166 				pDevice->advertising = Value32;
1167 
1168 				Value32 = BCM540X_AN_AD_1000BASET_HALF |
1169 				    BCM540X_AN_AD_1000BASET_FULL |
1170 				    BCM540X_CONFIG_AS_MASTER |
1171 				    BCM540X_ENABLE_CONFIG_AS_MASTER;
1172 				LM_WritePhy (pDevice,
1173 					     BCM540X_1000BASET_CTRL_REG,
1174 					     Value32);
1175 				pDevice->advertising1000 = Value32;
1176 
1177 				LM_WritePhy (pDevice, PHY_CTRL_REG,
1178 					     PHY_CTRL_AUTO_NEG_ENABLE |
1179 					     PHY_CTRL_RESTART_AUTO_NEG);
1180 			}
1181 #endif
1182 			if (T3_ASIC_REV (pDevice->ChipRevId) ==
1183 			    T3_ASIC_REV_5703) {
1184 				LM_WritePhy (pDevice, 0x18, 0x0c00);
1185 				LM_WritePhy (pDevice, 0x17, 0x201f);
1186 				LM_WritePhy (pDevice, 0x15, 0x2aaa);
1187 			}
1188 			if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
1189 				LM_WritePhy (pDevice, 0x1c, 0x8d68);
1190 				LM_WritePhy (pDevice, 0x1c, 0x8d68);
1191 			}
1192 			/* Enable Ethernet@WireSpeed. */
1193 			if (pDevice->EnableWireSpeed) {
1194 				LM_WritePhy (pDevice, 0x18, 0x7007);
1195 				LM_ReadPhy (pDevice, 0x18, &Value32);
1196 				LM_WritePhy (pDevice, 0x18,
1197 					     Value32 | BIT_15 | BIT_4);
1198 			}
1199 		}
1200 	}
1201 
1202 	/* Turn off tap power management. */
1203 	if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
1204 		LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
1205 		LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
1206 		LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
1207 		LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
1208 		LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
1209 		LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1210 		LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
1211 		LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1212 		LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
1213 		LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
1214 		LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
1215 
1216 		MM_Wait (40);
1217 	}
1218 #if INCLUDE_TBI_SUPPORT
1219 	pDevice->IgnoreTbiLinkChange = FALSE;
1220 
1221 	if (pDevice->EnableTbi) {
1222 		pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1223 		pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1224 		if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
1225 		    pDevice->DisableAutoNeg) {
1226 			pDevice->PollTbiLink = FALSE;
1227 		}
1228 	} else {
1229 		pDevice->PollTbiLink = FALSE;
1230 	}
1231 #endif				/* INCLUDE_TBI_SUPPORT */
1232 
1233 	/* UseTaggedStatus is only valid for 5701 and later. */
1234 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1235 		pDevice->UseTaggedStatus = FALSE;
1236 
1237 		pDevice->CoalesceMode = 0;
1238 	} else {
1239 		pDevice->CoalesceMode =
1240 		    HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1241 		    HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1242 	}
1243 
1244 	/* Set the status block size. */
1245 	if (T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1246 	    T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_BX) {
1247 		pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1248 	}
1249 
1250 	/* Check the DURING_INT coalescing ticks parameters. */
1251 	if (pDevice->UseTaggedStatus) {
1252 		if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1253 			pDevice->RxCoalescingTicksDuringInt =
1254 			    DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1255 		}
1256 
1257 		if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1258 			pDevice->TxCoalescingTicksDuringInt =
1259 			    DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1260 		}
1261 
1262 		if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1263 			pDevice->RxMaxCoalescedFramesDuringInt =
1264 			    DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1265 		}
1266 
1267 		if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1268 			pDevice->TxMaxCoalescedFramesDuringInt =
1269 			    DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1270 		}
1271 	} else {
1272 		if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1273 			pDevice->RxCoalescingTicksDuringInt = 0;
1274 		}
1275 
1276 		if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1277 			pDevice->TxCoalescingTicksDuringInt = 0;
1278 		}
1279 
1280 		if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1281 			pDevice->RxMaxCoalescedFramesDuringInt = 0;
1282 		}
1283 
1284 		if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1285 			pDevice->TxMaxCoalescedFramesDuringInt = 0;
1286 		}
1287 	}
1288 
1289 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1290 	if (pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */ )) {
1291 		pDevice->RxJumboDescCnt = 0;
1292 		if (pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
1293 			pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1294 		}
1295 	} else {
1296 		pDevice->RxJumboBufferSize =
1297 		    (pDevice->RxMtu + 8 /* CRC + VLAN */  +
1298 		     COMMON_CACHE_LINE_SIZE - 1) & ~COMMON_CACHE_LINE_MASK;
1299 
1300 		if (pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE) {
1301 			pDevice->RxJumboBufferSize =
1302 			    DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1303 			pDevice->RxMtu =
1304 			    pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */ ;
1305 		}
1306 		pDevice->TxMtu = pDevice->RxMtu;
1307 
1308 	}
1309 #else
1310 	pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1311 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1312 
1313 	pDevice->RxPacketDescCnt =
1314 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1315 	    pDevice->RxJumboDescCnt +
1316 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1317 	    pDevice->RxStdDescCnt;
1318 
1319 	if (pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
1320 		pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1321 	}
1322 
1323 	if (pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE) {
1324 		pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1325 	}
1326 
1327 	/* Configure the proper ways to get link change interrupt. */
1328 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO) {
1329 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1330 			pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1331 		} else {
1332 			pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1333 		}
1334 	} else if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
1335 		/* Auto-polling does not work on 5700_AX and 5700_BX. */
1336 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1337 			pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1338 		}
1339 	}
1340 
1341 	/* Determine the method to get link change status. */
1342 	if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO) {
1343 		/* The link status bit in the status block does not work on 5700_AX */
1344 		/* and 5700_BX chips. */
1345 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1346 			pDevice->LinkChngMode =
1347 			    T3_LINK_CHNG_MODE_USE_STATUS_REG;
1348 		} else {
1349 			pDevice->LinkChngMode =
1350 			    T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
1351 		}
1352 	}
1353 
1354 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
1355 	    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1356 		pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1357 	}
1358 
1359 	/* Configure PHY led mode. */
1360 	if (pDevice->LedMode == LED_MODE_AUTO) {
1361 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1362 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
1363 			if (pDevice->SubsystemVendorId == T3_SVID_DELL) {
1364 				pDevice->LedMode = LED_MODE_LINK10;
1365 			} else {
1366 				pDevice->LedMode = LED_MODE_THREE_LINK;
1367 
1368 				if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
1369 					pDevice->LedMode = EePhyLedMode;
1370 				}
1371 			}
1372 
1373 			/* bug? 5701 in LINK10 mode does not seem to work when */
1374 			/* PhyIntMode is LINK_READY. */
1375 			if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700
1376 			    &&
1377 #if INCLUDE_TBI_SUPPORT
1378 			    pDevice->EnableTbi == FALSE &&
1379 #endif
1380 			    pDevice->LedMode == LED_MODE_LINK10) {
1381 				pDevice->PhyIntMode =
1382 				    T3_PHY_INT_MODE_MI_INTERRUPT;
1383 				pDevice->LinkChngMode =
1384 				    T3_LINK_CHNG_MODE_USE_STATUS_REG;
1385 			}
1386 
1387 			if (pDevice->EnableTbi) {
1388 				pDevice->LedMode = LED_MODE_THREE_LINK;
1389 			}
1390 		} else {
1391 			if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
1392 				pDevice->LedMode = EePhyLedMode;
1393 			} else {
1394 				pDevice->LedMode = LED_MODE_OPEN_DRAIN;
1395 			}
1396 		}
1397 	}
1398 
1399 	/* Enable OneDmaAtOnce. */
1400 	if (pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE) {
1401 		pDevice->OneDmaAtOnce = FALSE;
1402 	}
1403 
1404 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1405 	    pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1406 	    pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1407 	    pDevice->ChipRevId == T3_CHIP_ID_5701_B2) {
1408 		pDevice->WolSpeed = WOL_SPEED_10MB;
1409 	} else {
1410 		pDevice->WolSpeed = WOL_SPEED_100MB;
1411 	}
1412 
1413 	/* Offloadings. */
1414 	pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1415 
1416 	/* Turn off task offloading on Ax. */
1417 	if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
1418 		pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1419 					     LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1420 	}
1421 	pDevice->PciState = REG_RD (pDevice, PciCfg.PciState);
1422 	LM_ReadVPD (pDevice);
1423 	LM_ReadBootCodeVersion (pDevice);
1424 	LM_GetBusSpeed (pDevice);
1425 
1426 	return LM_STATUS_SUCCESS;
1427 }				/* LM_GetAdapterInfo */
1428 
LM_GetAdapterInfoBySsid(LM_UINT16 Svid,LM_UINT16 Ssid)1429 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid, LM_UINT16 Ssid)
1430 {
1431 	static LM_ADAPTER_INFO AdapterArr[] = {
1432 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6,
1433 		 PHY_BCM5401_PHY_ID, 0},
1434 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5,
1435 		 PHY_BCM5701_PHY_ID, 0},
1436 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6,
1437 		 PHY_BCM8002_PHY_ID, 1},
1438 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1},
1439 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1,
1440 		 PHY_BCM5701_PHY_ID, 0},
1441 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8,
1442 		 PHY_BCM5701_PHY_ID, 0},
1443 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
1444 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10,
1445 		 PHY_BCM5701_PHY_ID, 0},
1446 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12,
1447 		 PHY_BCM5701_PHY_ID, 0},
1448 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1,
1449 		 PHY_BCM5701_PHY_ID, 0},
1450 		{T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2,
1451 		 PHY_BCM5701_PHY_ID, 0},
1452 
1453 		{T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0},
1454 		{T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0},
1455 		{T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1},
1456 		{T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0},
1457 		{T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0},
1458 
1459 		{T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0},
1460 		{T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0},
1461 		{T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0},
1462 		{T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0},
1463 
1464 		{T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0},
1465 		{T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID,
1466 		 0},
1467 		{T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1},
1468 		{T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0},
1469 		{T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID,
1470 		 0},
1471 
1472 	};
1473 	LM_UINT32 j;
1474 
1475 	for (j = 0; j < sizeof (AdapterArr) / sizeof (LM_ADAPTER_INFO); j++) {
1476 		if (AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid) {
1477 			return &AdapterArr[j];
1478 		}
1479 	}
1480 
1481 	return NULL;
1482 }
1483 
1484 /******************************************************************************/
1485 /* Description:                                                               */
1486 /*    This routine sets up receive/transmit buffer descriptions queues.       */
1487 /*                                                                            */
1488 /* Return:                                                                    */
1489 /*    LM_STATUS_SUCCESS                                                       */
1490 /******************************************************************************/
LM_InitializeAdapter(PLM_DEVICE_BLOCK pDevice)1491 LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice)
1492 {
1493 	LM_PHYSICAL_ADDRESS MemPhy;
1494 	PLM_UINT8 pMemVirt;
1495 	PLM_PACKET pPacket;
1496 	LM_STATUS Status;
1497 	LM_UINT32 Size;
1498 	LM_UINT32 j;
1499 
1500 	/* Set power state to D0. */
1501 	LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
1502 
1503 	/* Intialize the queues. */
1504 	QQ_InitQueue (&pDevice->RxPacketReceivedQ.Container,
1505 		      MAX_RX_PACKET_DESC_COUNT);
1506 	QQ_InitQueue (&pDevice->RxPacketFreeQ.Container,
1507 		      MAX_RX_PACKET_DESC_COUNT);
1508 
1509 	QQ_InitQueue (&pDevice->TxPacketFreeQ.Container,
1510 		      MAX_TX_PACKET_DESC_COUNT);
1511 	QQ_InitQueue (&pDevice->TxPacketActiveQ.Container,
1512 		      MAX_TX_PACKET_DESC_COUNT);
1513 	QQ_InitQueue (&pDevice->TxPacketXmittedQ.Container,
1514 		      MAX_TX_PACKET_DESC_COUNT);
1515 
1516 	/* Allocate shared memory for: status block, the buffers for receive */
1517 	/* rings -- standard, mini, jumbo, and return rings. */
1518 	Size = T3_STATUS_BLOCK_SIZE + sizeof (T3_STATS_BLOCK) +
1519 	    T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
1520 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1521 	    T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
1522 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1523 	    T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1524 
1525 	/* Memory for host based Send BD. */
1526 	if (pDevice->NicSendBd == FALSE) {
1527 		Size += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1528 	}
1529 
1530 	/* Allocate the memory block. */
1531 	Status =
1532 	    MM_AllocateSharedMemory (pDevice, Size, (PLM_VOID) & pMemVirt,
1533 				     &MemPhy, FALSE);
1534 	if (Status != LM_STATUS_SUCCESS) {
1535 		return Status;
1536 	}
1537 
1538 	/* Program DMA Read/Write */
1539 	if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) {
1540 		pDevice->DmaReadWriteCtrl = 0x763f000f;
1541 	} else {
1542 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5704) {
1543 			pDevice->DmaReadWriteCtrl = 0x761f0000;
1544 		} else {
1545 			pDevice->DmaReadWriteCtrl = 0x761b000f;
1546 		}
1547 		if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1548 		    pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
1549 			pDevice->OneDmaAtOnce = TRUE;
1550 		}
1551 	}
1552 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
1553 		pDevice->DmaReadWriteCtrl &= 0xfffffff0;
1554 	}
1555 
1556 	if (pDevice->OneDmaAtOnce) {
1557 		pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
1558 	}
1559 	REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
1560 
1561 	if (LM_DmaTest (pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS) {
1562 		return LM_STATUS_FAILURE;
1563 	}
1564 
1565 	/* Status block. */
1566 	pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
1567 	pDevice->StatusBlkPhy = MemPhy;
1568 	pMemVirt += T3_STATUS_BLOCK_SIZE;
1569 	LM_INC_PHYSICAL_ADDRESS (&MemPhy, T3_STATUS_BLOCK_SIZE);
1570 
1571 	/* Statistics block. */
1572 	pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
1573 	pDevice->StatsBlkPhy = MemPhy;
1574 	pMemVirt += sizeof (T3_STATS_BLOCK);
1575 	LM_INC_PHYSICAL_ADDRESS (&MemPhy, sizeof (T3_STATS_BLOCK));
1576 
1577 	/* Receive standard BD buffer. */
1578 	pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
1579 	pDevice->RxStdBdPhy = MemPhy;
1580 
1581 	pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1582 	LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1583 				 T3_STD_RCV_RCB_ENTRY_COUNT *
1584 				 sizeof (T3_RCV_BD));
1585 
1586 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1587 	/* Receive jumbo BD buffer. */
1588 	pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
1589 	pDevice->RxJumboBdPhy = MemPhy;
1590 
1591 	pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1592 	LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1593 				 T3_JUMBO_RCV_RCB_ENTRY_COUNT *
1594 				 sizeof (T3_RCV_BD));
1595 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1596 
1597 	/* Receive return BD buffer. */
1598 	pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
1599 	pDevice->RcvRetBdPhy = MemPhy;
1600 
1601 	pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1602 	LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1603 				 T3_RCV_RETURN_RCB_ENTRY_COUNT *
1604 				 sizeof (T3_RCV_BD));
1605 
1606 	/* Set up Send BD. */
1607 	if (pDevice->NicSendBd == FALSE) {
1608 		pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
1609 		pDevice->SendBdPhy = MemPhy;
1610 
1611 		pMemVirt += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1612 		LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1613 					 sizeof (T3_SND_BD) *
1614 					 T3_SEND_RCB_ENTRY_COUNT);
1615 	} else {
1616 		pDevice->pSendBdVirt = (PT3_SND_BD)
1617 		    pDevice->pMemView->uIntMem.First32k.BufferDesc;
1618 		pDevice->SendBdPhy.High = 0;
1619 		pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
1620 	}
1621 
1622 	/* Allocate memory for packet descriptors. */
1623 	Size = (pDevice->RxPacketDescCnt +
1624 		pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
1625 	Status = MM_AllocateMemory (pDevice, Size, (PLM_VOID *) & pPacket);
1626 	if (Status != LM_STATUS_SUCCESS) {
1627 		return Status;
1628 	}
1629 	pDevice->pPacketDescBase = (PLM_VOID) pPacket;
1630 
1631 	/* Create transmit packet descriptors from the memory block and add them */
1632 	/* to the TxPacketFreeQ for each send ring. */
1633 	for (j = 0; j < pDevice->TxPacketDescCnt; j++) {
1634 		/* Ring index. */
1635 		pPacket->Flags = 0;
1636 
1637 		/* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
1638 		QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
1639 
1640 		/* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1641 		/* is the total size of the packet descriptor including the */
1642 		/* os-specific extensions in the UM_PACKET structure. */
1643 		pPacket =
1644 		    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1645 	}			/* for(j.. */
1646 
1647 	/* Create receive packet descriptors from the memory block and add them */
1648 	/* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
1649 	for (j = 0; j < pDevice->RxStdDescCnt; j++) {
1650 		/* Receive producer ring. */
1651 		pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
1652 
1653 		/* Receive buffer size. */
1654 		pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
1655 
1656 		/* Add the descriptor to RxPacketFreeQ. */
1657 		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
1658 
1659 		/* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1660 		/* is the total size of the packet descriptor including the */
1661 		/* os-specific extensions in the UM_PACKET structure. */
1662 		pPacket =
1663 		    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1664 	}			/* for */
1665 
1666 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1667 	/* Create the Jumbo packet descriptors. */
1668 	for (j = 0; j < pDevice->RxJumboDescCnt; j++) {
1669 		/* Receive producer ring. */
1670 		pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
1671 
1672 		/* Receive buffer size. */
1673 		pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
1674 
1675 		/* Add the descriptor to RxPacketFreeQ. */
1676 		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
1677 
1678 		/* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1679 		/* is the total size of the packet descriptor including the */
1680 		/* os-specific extensions in the UM_PACKET structure. */
1681 		pPacket =
1682 		    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1683 	}			/* for */
1684 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1685 
1686 	/* Initialize the rest of the packet descriptors. */
1687 	Status = MM_InitializeUmPackets (pDevice);
1688 	if (Status != LM_STATUS_SUCCESS) {
1689 		return Status;
1690 	}
1691 
1692 	/* if */
1693 	/* Default receive mask. */
1694 	pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1695 	    LM_ACCEPT_UNICAST;
1696 
1697 	/* Make sure we are in the first 32k memory window or NicSendBd. */
1698 	REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
1699 
1700 	/* Initialize the hardware. */
1701 	Status = LM_ResetAdapter (pDevice);
1702 	if (Status != LM_STATUS_SUCCESS) {
1703 		return Status;
1704 	}
1705 
1706 	/* We are done with initialization. */
1707 	pDevice->InitDone = TRUE;
1708 
1709 	return LM_STATUS_SUCCESS;
1710 }				/* LM_InitializeAdapter */
1711 
1712 /******************************************************************************/
1713 /* Description:                                                               */
1714 /*    This function Enables/Disables a given block.                          */
1715 /*                                                                            */
1716 /* Return:                                                                    */
1717 /*    LM_STATUS_SUCCESS                                                       */
1718 /******************************************************************************/
1719 LM_STATUS
LM_CntrlBlock(PLM_DEVICE_BLOCK pDevice,LM_UINT32 mask,LM_UINT32 cntrl)1720 LM_CntrlBlock (PLM_DEVICE_BLOCK pDevice, LM_UINT32 mask, LM_UINT32 cntrl)
1721 {
1722 	LM_UINT32 j, i, data;
1723 	LM_UINT32 MaxWaitCnt;
1724 
1725 	MaxWaitCnt = 2;
1726 	j = 0;
1727 
1728 	for (i = 0; i < 32; i++) {
1729 		if (!(mask & (1 << i)))
1730 			continue;
1731 
1732 		switch (1 << i) {
1733 		case T3_BLOCK_DMA_RD:
1734 			data = REG_RD (pDevice, DmaRead.Mode);
1735 			if (cntrl == LM_DISABLE) {
1736 				data &= ~DMA_READ_MODE_ENABLE;
1737 				REG_WR (pDevice, DmaRead.Mode, data);
1738 				for (j = 0; j < MaxWaitCnt; j++) {
1739 					if (!
1740 					    (REG_RD (pDevice, DmaRead.Mode) &
1741 					     DMA_READ_MODE_ENABLE))
1742 						break;
1743 					MM_Wait (10);
1744 				}
1745 			} else
1746 				REG_WR (pDevice, DmaRead.Mode,
1747 					data | DMA_READ_MODE_ENABLE);
1748 			break;
1749 
1750 		case T3_BLOCK_DMA_COMP:
1751 			data = REG_RD (pDevice, DmaComp.Mode);
1752 			if (cntrl == LM_DISABLE) {
1753 				data &= ~DMA_COMP_MODE_ENABLE;
1754 				REG_WR (pDevice, DmaComp.Mode, data);
1755 				for (j = 0; j < MaxWaitCnt; j++) {
1756 					if (!
1757 					    (REG_RD (pDevice, DmaComp.Mode) &
1758 					     DMA_COMP_MODE_ENABLE))
1759 						break;
1760 					MM_Wait (10);
1761 				}
1762 			} else
1763 				REG_WR (pDevice, DmaComp.Mode,
1764 					data | DMA_COMP_MODE_ENABLE);
1765 			break;
1766 
1767 		case T3_BLOCK_RX_BD_INITIATOR:
1768 			data = REG_RD (pDevice, RcvBdIn.Mode);
1769 			if (cntrl == LM_DISABLE) {
1770 				data &= ~RCV_BD_IN_MODE_ENABLE;
1771 				REG_WR (pDevice, RcvBdIn.Mode, data);
1772 				for (j = 0; j < MaxWaitCnt; j++) {
1773 					if (!
1774 					    (REG_RD (pDevice, RcvBdIn.Mode) &
1775 					     RCV_BD_IN_MODE_ENABLE))
1776 						break;
1777 					MM_Wait (10);
1778 				}
1779 			} else
1780 				REG_WR (pDevice, RcvBdIn.Mode,
1781 					data | RCV_BD_IN_MODE_ENABLE);
1782 			break;
1783 
1784 		case T3_BLOCK_RX_BD_COMP:
1785 			data = REG_RD (pDevice, RcvBdComp.Mode);
1786 			if (cntrl == LM_DISABLE) {
1787 				data &= ~RCV_BD_COMP_MODE_ENABLE;
1788 				REG_WR (pDevice, RcvBdComp.Mode, data);
1789 				for (j = 0; j < MaxWaitCnt; j++) {
1790 					if (!
1791 					    (REG_RD (pDevice, RcvBdComp.Mode) &
1792 					     RCV_BD_COMP_MODE_ENABLE))
1793 						break;
1794 					MM_Wait (10);
1795 				}
1796 			} else
1797 				REG_WR (pDevice, RcvBdComp.Mode,
1798 					data | RCV_BD_COMP_MODE_ENABLE);
1799 			break;
1800 
1801 		case T3_BLOCK_DMA_WR:
1802 			data = REG_RD (pDevice, DmaWrite.Mode);
1803 			if (cntrl == LM_DISABLE) {
1804 				data &= ~DMA_WRITE_MODE_ENABLE;
1805 				REG_WR (pDevice, DmaWrite.Mode, data);
1806 
1807 				for (j = 0; j < MaxWaitCnt; j++) {
1808 					if (!
1809 					    (REG_RD (pDevice, DmaWrite.Mode) &
1810 					     DMA_WRITE_MODE_ENABLE))
1811 						break;
1812 					MM_Wait (10);
1813 				}
1814 			} else
1815 				REG_WR (pDevice, DmaWrite.Mode,
1816 					data | DMA_WRITE_MODE_ENABLE);
1817 			break;
1818 
1819 		case T3_BLOCK_MSI_HANDLER:
1820 			data = REG_RD (pDevice, Msi.Mode);
1821 			if (cntrl == LM_DISABLE) {
1822 				data &= ~MSI_MODE_ENABLE;
1823 				REG_WR (pDevice, Msi.Mode, data);
1824 				for (j = 0; j < MaxWaitCnt; j++) {
1825 					if (!
1826 					    (REG_RD (pDevice, Msi.Mode) &
1827 					     MSI_MODE_ENABLE))
1828 						break;
1829 					MM_Wait (10);
1830 				}
1831 			} else
1832 				REG_WR (pDevice, Msi.Mode,
1833 					data | MSI_MODE_ENABLE);
1834 			break;
1835 
1836 		case T3_BLOCK_RX_LIST_PLMT:
1837 			data = REG_RD (pDevice, RcvListPlmt.Mode);
1838 			if (cntrl == LM_DISABLE) {
1839 				data &= ~RCV_LIST_PLMT_MODE_ENABLE;
1840 				REG_WR (pDevice, RcvListPlmt.Mode, data);
1841 				for (j = 0; j < MaxWaitCnt; j++) {
1842 					if (!
1843 					    (REG_RD (pDevice, RcvListPlmt.Mode)
1844 					     & RCV_LIST_PLMT_MODE_ENABLE))
1845 						break;
1846 					MM_Wait (10);
1847 				}
1848 			} else
1849 				REG_WR (pDevice, RcvListPlmt.Mode,
1850 					data | RCV_LIST_PLMT_MODE_ENABLE);
1851 			break;
1852 
1853 		case T3_BLOCK_RX_LIST_SELECTOR:
1854 			data = REG_RD (pDevice, RcvListSel.Mode);
1855 			if (cntrl == LM_DISABLE) {
1856 				data &= ~RCV_LIST_SEL_MODE_ENABLE;
1857 				REG_WR (pDevice, RcvListSel.Mode, data);
1858 				for (j = 0; j < MaxWaitCnt; j++) {
1859 					if (!
1860 					    (REG_RD (pDevice, RcvListSel.Mode) &
1861 					     RCV_LIST_SEL_MODE_ENABLE))
1862 						break;
1863 					MM_Wait (10);
1864 				}
1865 			} else
1866 				REG_WR (pDevice, RcvListSel.Mode,
1867 					data | RCV_LIST_SEL_MODE_ENABLE);
1868 			break;
1869 
1870 		case T3_BLOCK_RX_DATA_INITIATOR:
1871 			data = REG_RD (pDevice, RcvDataBdIn.Mode);
1872 			if (cntrl == LM_DISABLE) {
1873 				data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
1874 				REG_WR (pDevice, RcvDataBdIn.Mode, data);
1875 				for (j = 0; j < MaxWaitCnt; j++) {
1876 					if (!
1877 					    (REG_RD (pDevice, RcvDataBdIn.Mode)
1878 					     & RCV_DATA_BD_IN_MODE_ENABLE))
1879 						break;
1880 					MM_Wait (10);
1881 				}
1882 			} else
1883 				REG_WR (pDevice, RcvDataBdIn.Mode,
1884 					data | RCV_DATA_BD_IN_MODE_ENABLE);
1885 			break;
1886 
1887 		case T3_BLOCK_RX_DATA_COMP:
1888 			data = REG_RD (pDevice, RcvDataComp.Mode);
1889 			if (cntrl == LM_DISABLE) {
1890 				data &= ~RCV_DATA_COMP_MODE_ENABLE;
1891 				REG_WR (pDevice, RcvDataComp.Mode, data);
1892 				for (j = 0; j < MaxWaitCnt; j++) {
1893 					if (!
1894 					    (REG_RD (pDevice, RcvDataBdIn.Mode)
1895 					     & RCV_DATA_COMP_MODE_ENABLE))
1896 						break;
1897 					MM_Wait (10);
1898 				}
1899 			} else
1900 				REG_WR (pDevice, RcvDataComp.Mode,
1901 					data | RCV_DATA_COMP_MODE_ENABLE);
1902 			break;
1903 
1904 		case T3_BLOCK_HOST_COALESING:
1905 			data = REG_RD (pDevice, HostCoalesce.Mode);
1906 			if (cntrl == LM_DISABLE) {
1907 				data &= ~HOST_COALESCE_ENABLE;
1908 				REG_WR (pDevice, HostCoalesce.Mode, data);
1909 				for (j = 0; j < MaxWaitCnt; j++) {
1910 					if (!
1911 					    (REG_RD (pDevice, SndBdIn.Mode) &
1912 					     HOST_COALESCE_ENABLE))
1913 						break;
1914 					MM_Wait (10);
1915 				}
1916 			} else
1917 				REG_WR (pDevice, HostCoalesce.Mode,
1918 					data | HOST_COALESCE_ENABLE);
1919 			break;
1920 
1921 		case T3_BLOCK_MAC_RX_ENGINE:
1922 			if (cntrl == LM_DISABLE) {
1923 				pDevice->RxMode &= ~RX_MODE_ENABLE;
1924 				REG_WR (pDevice, MacCtrl.RxMode,
1925 					pDevice->RxMode);
1926 				for (j = 0; j < MaxWaitCnt; j++) {
1927 					if (!
1928 					    (REG_RD (pDevice, MacCtrl.RxMode) &
1929 					     RX_MODE_ENABLE)) {
1930 						break;
1931 					}
1932 					MM_Wait (10);
1933 				}
1934 			} else {
1935 				pDevice->RxMode |= RX_MODE_ENABLE;
1936 				REG_WR (pDevice, MacCtrl.RxMode,
1937 					pDevice->RxMode);
1938 			}
1939 			break;
1940 
1941 		case T3_BLOCK_MBUF_CLUSTER_FREE:
1942 			data = REG_RD (pDevice, MbufClusterFree.Mode);
1943 			if (cntrl == LM_DISABLE) {
1944 				data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
1945 				REG_WR (pDevice, MbufClusterFree.Mode, data);
1946 				for (j = 0; j < MaxWaitCnt; j++) {
1947 					if (!
1948 					    (REG_RD
1949 					     (pDevice,
1950 					      MbufClusterFree.
1951 					      Mode) &
1952 					     MBUF_CLUSTER_FREE_MODE_ENABLE))
1953 						break;
1954 					MM_Wait (10);
1955 				}
1956 			} else
1957 				REG_WR (pDevice, MbufClusterFree.Mode,
1958 					data | MBUF_CLUSTER_FREE_MODE_ENABLE);
1959 			break;
1960 
1961 		case T3_BLOCK_SEND_BD_INITIATOR:
1962 			data = REG_RD (pDevice, SndBdIn.Mode);
1963 			if (cntrl == LM_DISABLE) {
1964 				data &= ~SND_BD_IN_MODE_ENABLE;
1965 				REG_WR (pDevice, SndBdIn.Mode, data);
1966 				for (j = 0; j < MaxWaitCnt; j++) {
1967 					if (!
1968 					    (REG_RD (pDevice, SndBdIn.Mode) &
1969 					     SND_BD_IN_MODE_ENABLE))
1970 						break;
1971 					MM_Wait (10);
1972 				}
1973 			} else
1974 				REG_WR (pDevice, SndBdIn.Mode,
1975 					data | SND_BD_IN_MODE_ENABLE);
1976 			break;
1977 
1978 		case T3_BLOCK_SEND_BD_COMP:
1979 			data = REG_RD (pDevice, SndBdComp.Mode);
1980 			if (cntrl == LM_DISABLE) {
1981 				data &= ~SND_BD_COMP_MODE_ENABLE;
1982 				REG_WR (pDevice, SndBdComp.Mode, data);
1983 				for (j = 0; j < MaxWaitCnt; j++) {
1984 					if (!
1985 					    (REG_RD (pDevice, SndBdComp.Mode) &
1986 					     SND_BD_COMP_MODE_ENABLE))
1987 						break;
1988 					MM_Wait (10);
1989 				}
1990 			} else
1991 				REG_WR (pDevice, SndBdComp.Mode,
1992 					data | SND_BD_COMP_MODE_ENABLE);
1993 			break;
1994 
1995 		case T3_BLOCK_SEND_BD_SELECTOR:
1996 			data = REG_RD (pDevice, SndBdSel.Mode);
1997 			if (cntrl == LM_DISABLE) {
1998 				data &= ~SND_BD_SEL_MODE_ENABLE;
1999 				REG_WR (pDevice, SndBdSel.Mode, data);
2000 				for (j = 0; j < MaxWaitCnt; j++) {
2001 					if (!
2002 					    (REG_RD (pDevice, SndBdSel.Mode) &
2003 					     SND_BD_SEL_MODE_ENABLE))
2004 						break;
2005 					MM_Wait (10);
2006 				}
2007 			} else
2008 				REG_WR (pDevice, SndBdSel.Mode,
2009 					data | SND_BD_SEL_MODE_ENABLE);
2010 			break;
2011 
2012 		case T3_BLOCK_SEND_DATA_INITIATOR:
2013 			data = REG_RD (pDevice, SndDataIn.Mode);
2014 			if (cntrl == LM_DISABLE) {
2015 				data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2016 				REG_WR (pDevice, SndDataIn.Mode, data);
2017 				for (j = 0; j < MaxWaitCnt; j++) {
2018 					if (!
2019 					    (REG_RD (pDevice, SndDataIn.Mode) &
2020 					     T3_SND_DATA_IN_MODE_ENABLE))
2021 						break;
2022 					MM_Wait (10);
2023 				}
2024 			} else
2025 				REG_WR (pDevice, SndDataIn.Mode,
2026 					data | T3_SND_DATA_IN_MODE_ENABLE);
2027 			break;
2028 
2029 		case T3_BLOCK_SEND_DATA_COMP:
2030 			data = REG_RD (pDevice, SndDataComp.Mode);
2031 			if (cntrl == LM_DISABLE) {
2032 				data &= ~SND_DATA_COMP_MODE_ENABLE;
2033 				REG_WR (pDevice, SndDataComp.Mode, data);
2034 				for (j = 0; j < MaxWaitCnt; j++) {
2035 					if (!
2036 					    (REG_RD (pDevice, SndDataComp.Mode)
2037 					     & SND_DATA_COMP_MODE_ENABLE))
2038 						break;
2039 					MM_Wait (10);
2040 				}
2041 			} else
2042 				REG_WR (pDevice, SndDataComp.Mode,
2043 					data | SND_DATA_COMP_MODE_ENABLE);
2044 			break;
2045 
2046 		case T3_BLOCK_MAC_TX_ENGINE:
2047 			if (cntrl == LM_DISABLE) {
2048 				pDevice->TxMode &= ~TX_MODE_ENABLE;
2049 				REG_WR (pDevice, MacCtrl.TxMode,
2050 					pDevice->TxMode);
2051 				for (j = 0; j < MaxWaitCnt; j++) {
2052 					if (!
2053 					    (REG_RD (pDevice, MacCtrl.TxMode) &
2054 					     TX_MODE_ENABLE))
2055 						break;
2056 					MM_Wait (10);
2057 				}
2058 			} else {
2059 				pDevice->TxMode |= TX_MODE_ENABLE;
2060 				REG_WR (pDevice, MacCtrl.TxMode,
2061 					pDevice->TxMode);
2062 			}
2063 			break;
2064 
2065 		case T3_BLOCK_MEM_ARBITOR:
2066 			data = REG_RD (pDevice, MemArbiter.Mode);
2067 			if (cntrl == LM_DISABLE) {
2068 				data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2069 				REG_WR (pDevice, MemArbiter.Mode, data);
2070 				for (j = 0; j < MaxWaitCnt; j++) {
2071 					if (!
2072 					    (REG_RD (pDevice, MemArbiter.Mode) &
2073 					     T3_MEM_ARBITER_MODE_ENABLE))
2074 						break;
2075 					MM_Wait (10);
2076 				}
2077 			} else
2078 				REG_WR (pDevice, MemArbiter.Mode,
2079 					data | T3_MEM_ARBITER_MODE_ENABLE);
2080 			break;
2081 
2082 		case T3_BLOCK_MBUF_MANAGER:
2083 			data = REG_RD (pDevice, BufMgr.Mode);
2084 			if (cntrl == LM_DISABLE) {
2085 				data &= ~BUFMGR_MODE_ENABLE;
2086 				REG_WR (pDevice, BufMgr.Mode, data);
2087 				for (j = 0; j < MaxWaitCnt; j++) {
2088 					if (!
2089 					    (REG_RD (pDevice, BufMgr.Mode) &
2090 					     BUFMGR_MODE_ENABLE))
2091 						break;
2092 					MM_Wait (10);
2093 				}
2094 			} else
2095 				REG_WR (pDevice, BufMgr.Mode,
2096 					data | BUFMGR_MODE_ENABLE);
2097 			break;
2098 
2099 		case T3_BLOCK_MAC_GLOBAL:
2100 			if (cntrl == LM_DISABLE) {
2101 				pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
2102 						      MAC_MODE_ENABLE_RDE |
2103 						      MAC_MODE_ENABLE_FHDE);
2104 			} else {
2105 				pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
2106 						     MAC_MODE_ENABLE_RDE |
2107 						     MAC_MODE_ENABLE_FHDE);
2108 			}
2109 			REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
2110 			break;
2111 
2112 		default:
2113 			return LM_STATUS_FAILURE;
2114 		}		/* switch */
2115 
2116 		if (j >= MaxWaitCnt) {
2117 			return LM_STATUS_FAILURE;
2118 		}
2119 	}
2120 
2121 	return LM_STATUS_SUCCESS;
2122 }
2123 
2124 /******************************************************************************/
2125 /* Description:                                                               */
2126 /*    This function reinitializes the adapter.                                */
2127 /*                                                                            */
2128 /* Return:                                                                    */
2129 /*    LM_STATUS_SUCCESS                                                       */
2130 /******************************************************************************/
LM_ResetAdapter(PLM_DEVICE_BLOCK pDevice)2131 LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice)
2132 {
2133 	LM_UINT32 Value32;
2134 	LM_UINT16 Value16;
2135 	LM_UINT32 j, k;
2136 
2137 	/* Disable interrupt. */
2138 	LM_DisableInterrupt (pDevice);
2139 
2140 	/* May get a spurious interrupt */
2141 	pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2142 
2143 	/* Disable transmit and receive DMA engines.  Abort all pending requests. */
2144 	if (pDevice->InitDone) {
2145 		LM_Abort (pDevice);
2146 	}
2147 
2148 	pDevice->ShuttingDown = FALSE;
2149 
2150 	LM_ResetChip (pDevice);
2151 
2152 	/* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
2153 	/* in other chip revisions. */
2154 	if (pDevice->DelayPciGrant) {
2155 		Value32 = REG_RD (pDevice, PciCfg.ClockCtrl);
2156 		REG_WR (pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
2157 	}
2158 
2159 	if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
2160 		if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
2161 			Value32 = REG_RD (pDevice, PciCfg.PciState);
2162 			Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2163 			REG_WR (pDevice, PciCfg.PciState, Value32);
2164 		}
2165 	}
2166 
2167 	/* Enable TaggedStatus mode. */
2168 	if (pDevice->UseTaggedStatus) {
2169 		pDevice->MiscHostCtrl |=
2170 		    MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2171 	}
2172 
2173 	/* Restore PCI configuration registers. */
2174 	MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
2175 			  pDevice->SavedCacheLineReg);
2176 	MM_WriteConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2177 			  (pDevice->SubsystemId << 16) | pDevice->
2178 			  SubsystemVendorId);
2179 
2180 	/* Clear the statistics block. */
2181 	for (j = 0x0300; j < 0x0b00; j++) {
2182 		MEM_WR_OFFSET (pDevice, j, 0);
2183 	}
2184 
2185 	/* Initialize the statistis Block */
2186 	pDevice->pStatusBlkVirt->Status = 0;
2187 	pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2188 	pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2189 	pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2190 
2191 	for (j = 0; j < 16; j++) {
2192 		pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2193 		pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2194 	}
2195 
2196 	for (k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT; k++) {
2197 		pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2198 		pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2199 	}
2200 
2201 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2202 	/* Receive jumbo BD buffer. */
2203 	for (k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++) {
2204 		pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2205 		pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2206 	}
2207 #endif
2208 
2209 	REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2210 
2211 	/* GRC mode control register. */
2212 #ifdef BIG_ENDIAN_PCI		/* Jimmy, this ifdef block deleted in new code! */
2213 	Value32 =
2214 	    GRC_MODE_WORD_SWAP_DATA |
2215 	    GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2216 	    GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
2217 #else
2218 	/* No CPU Swap modes for PCI IO */
2219 	Value32 =
2220 #ifdef BIG_ENDIAN_HOST
2221 	    GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2222 	    GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2223 	    GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
2224 #else
2225 	    GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2226 	    GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
2227 #endif
2228 	    GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
2229 #endif				/* !BIG_ENDIAN_PCI */
2230 
2231 	/* Configure send BD mode. */
2232 	if (pDevice->NicSendBd == FALSE) {
2233 		Value32 |= GRC_MODE_HOST_SEND_BDS;
2234 	} else {
2235 		Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2236 	}
2237 
2238 	/* Configure pseudo checksum mode. */
2239 	if (pDevice->NoTxPseudoHdrChksum) {
2240 		Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2241 	}
2242 
2243 	if (pDevice->NoRxPseudoHdrChksum) {
2244 		Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2245 	}
2246 
2247 	REG_WR (pDevice, Grc.Mode, Value32);
2248 
2249 	/* Setup the timer prescalar register. */
2250 	REG_WR (pDevice, Grc.MiscCfg, 65 << 1);	/* Clock is alwasy 66MHz. */
2251 
2252 	/* Set up the MBUF pool base address and size. */
2253 	REG_WR (pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2254 	REG_WR (pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2255 
2256 	/* Set up the DMA descriptor pool base address and size. */
2257 	REG_WR (pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2258 	REG_WR (pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2259 
2260 	/* Configure MBUF and Threshold watermarks */
2261 	/* Configure the DMA read MBUF low water mark. */
2262 	if (pDevice->DmaMbufLowMark) {
2263 		REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2264 			pDevice->DmaMbufLowMark);
2265 	} else {
2266 		if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2267 			REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2268 				T3_DEF_DMA_MBUF_LOW_WMARK);
2269 		} else {
2270 			REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2271 				T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2272 		}
2273 	}
2274 
2275 	/* Configure the MAC Rx MBUF low water mark. */
2276 	if (pDevice->RxMacMbufLowMark) {
2277 		REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2278 			pDevice->RxMacMbufLowMark);
2279 	} else {
2280 		if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2281 			REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2282 				T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2283 		} else {
2284 			REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2285 				T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2286 		}
2287 	}
2288 
2289 	/* Configure the MBUF high water mark. */
2290 	if (pDevice->MbufHighMark) {
2291 		REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2292 			pDevice->MbufHighMark);
2293 	} else {
2294 		if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2295 			REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2296 				T3_DEF_MBUF_HIGH_WMARK);
2297 		} else {
2298 			REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2299 				T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2300 		}
2301 	}
2302 
2303 	REG_WR (pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2304 	REG_WR (pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2305 
2306 	/* Enable buffer manager. */
2307 	REG_WR (pDevice, BufMgr.Mode,
2308 		BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2309 
2310 	for (j = 0; j < 2000; j++) {
2311 		if (REG_RD (pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2312 			break;
2313 		MM_Wait (10);
2314 	}
2315 
2316 	if (j >= 2000) {
2317 		return LM_STATUS_FAILURE;
2318 	}
2319 
2320 	/* Enable the FTQs. */
2321 	REG_WR (pDevice, Ftq.Reset, 0xffffffff);
2322 	REG_WR (pDevice, Ftq.Reset, 0);
2323 
2324 	/* Wait until FTQ is ready */
2325 	for (j = 0; j < 2000; j++) {
2326 		if (REG_RD (pDevice, Ftq.Reset) == 0)
2327 			break;
2328 		MM_Wait (10);
2329 	}
2330 
2331 	if (j >= 2000) {
2332 		return LM_STATUS_FAILURE;
2333 	}
2334 
2335 	/* Initialize the Standard Receive RCB. */
2336 	REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2337 		pDevice->RxStdBdPhy.High);
2338 	REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2339 		pDevice->RxStdBdPhy.Low);
2340 	REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2341 		MAX_STD_RCV_BUFFER_SIZE << 16);
2342 
2343 	/* Initialize the Jumbo Receive RCB. */
2344 	REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2345 		T3_RCB_FLAG_RING_DISABLED);
2346 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2347 	REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2348 		pDevice->RxJumboBdPhy.High);
2349 	REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2350 		pDevice->RxJumboBdPhy.Low);
2351 
2352 	REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2353 
2354 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2355 
2356 	/* Initialize the Mini Receive RCB. */
2357 	REG_WR (pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2358 		T3_RCB_FLAG_RING_DISABLED);
2359 
2360 	{
2361 		REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2362 			(LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2363 		REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2364 			(LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2365 	}
2366 
2367 	/* Receive BD Ring replenish threshold. */
2368 	REG_WR (pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt / 8);
2369 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2370 	REG_WR (pDevice, RcvBdIn.JumboRcvThreshold,
2371 		pDevice->RxJumboDescCnt / 8);
2372 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2373 
2374 	/* Disable all the unused rings. */
2375 	for (j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2376 		MEM_WR (pDevice, SendRcb[j].u.MaxLen_Flags,
2377 			T3_RCB_FLAG_RING_DISABLED);
2378 	}			/* for */
2379 
2380 	/* Initialize the indices. */
2381 	pDevice->SendProdIdx = 0;
2382 	pDevice->SendConIdx = 0;
2383 
2384 	MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2385 	MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2386 
2387 	/* Set up host or NIC based send RCB. */
2388 	if (pDevice->NicSendBd == FALSE) {
2389 		MEM_WR (pDevice, SendRcb[0].HostRingAddr.High,
2390 			pDevice->SendBdPhy.High);
2391 		MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low,
2392 			pDevice->SendBdPhy.Low);
2393 
2394 		/* Set up the NIC ring address in the RCB. */
2395 		MEM_WR (pDevice, SendRcb[0].NicRingAddr,
2396 			T3_NIC_SND_BUFFER_DESC_ADDR);
2397 
2398 		/* Setup the RCB. */
2399 		MEM_WR (pDevice, SendRcb[0].u.MaxLen_Flags,
2400 			T3_SEND_RCB_ENTRY_COUNT << 16);
2401 
2402 		for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
2403 			pDevice->pSendBdVirt[k].HostAddr.High = 0;
2404 			pDevice->pSendBdVirt[k].HostAddr.Low = 0;
2405 		}
2406 	} else {
2407 		MEM_WR (pDevice, SendRcb[0].HostRingAddr.High, 0);
2408 		MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low, 0);
2409 		MEM_WR (pDevice, SendRcb[0].NicRingAddr,
2410 			pDevice->SendBdPhy.Low);
2411 
2412 		for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
2413 			__raw_writel (0,
2414 				      &(pDevice->pSendBdVirt[k].HostAddr.High));
2415 			__raw_writel (0,
2416 				      &(pDevice->pSendBdVirt[k].HostAddr.Low));
2417 			__raw_writel (0,
2418 				      &(pDevice->pSendBdVirt[k].u1.Len_Flags));
2419 			pDevice->ShadowSendBd[k].HostAddr.High = 0;
2420 			pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
2421 		}
2422 	}
2423 	atomic_set (&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT - 1);
2424 
2425 	/* Configure the receive return rings. */
2426 	for (j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++) {
2427 		MEM_WR (pDevice, RcvRetRcb[j].u.MaxLen_Flags,
2428 			T3_RCB_FLAG_RING_DISABLED);
2429 	}
2430 
2431 	pDevice->RcvRetConIdx = 0;
2432 
2433 	MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.High,
2434 		pDevice->RcvRetBdPhy.High);
2435 	MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.Low,
2436 		pDevice->RcvRetBdPhy.Low);
2437 
2438 	/* Set up the NIC ring address in the RCB. */
2439 	/* Not very clear from the spec.  I am guessing that for Receive */
2440 	/* Return Ring, NicRingAddr is not used. */
2441 	MEM_WR (pDevice, RcvRetRcb[0].NicRingAddr, 0);
2442 
2443 	/* Setup the RCB. */
2444 	MEM_WR (pDevice, RcvRetRcb[0].u.MaxLen_Flags,
2445 		T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
2446 
2447 	/* Reinitialize RX ring producer index */
2448 	MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low, 0);
2449 	MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
2450 	MB_REG_WR (pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
2451 
2452 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2453 	pDevice->RxJumboProdIdx = 0;
2454 	pDevice->RxJumboQueuedCnt = 0;
2455 #endif
2456 
2457 	/* Reinitialize our copy of the indices. */
2458 	pDevice->RxStdProdIdx = 0;
2459 	pDevice->RxStdQueuedCnt = 0;
2460 
2461 #if T3_JUMBO_RCV_ENTRY_COUNT
2462 	pDevice->RxJumboProdIdx = 0;
2463 #endif				/* T3_JUMBO_RCV_ENTRY_COUNT */
2464 
2465 	/* Configure the MAC address. */
2466 	LM_SetMacAddress (pDevice);
2467 
2468 	/* Initialize the transmit random backoff seed. */
2469 	Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
2470 		   pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
2471 		   pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
2472 	    MAC_TX_BACKOFF_SEED_MASK;
2473 	REG_WR (pDevice, MacCtrl.TxBackoffSeed, Value32);
2474 
2475 	/* Receive MTU.  Frames larger than the MTU is marked as oversized. */
2476 	REG_WR (pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);	/* CRC + VLAN. */
2477 
2478 	/* Configure Time slot/IPG per 802.3 */
2479 	REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
2480 
2481 	/*
2482 	 * Configure Receive Rules so that packets don't match
2483 	 * Programmble rule will be queued to Return Ring 1
2484 	 */
2485 	REG_WR (pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
2486 
2487 	/*
2488 	 * Configure to have 16 Classes of Services (COS) and one
2489 	 * queue per class.  Bad frames are queued to RRR#1.
2490 	 * And frames don't match rules are also queued to COS#1.
2491 	 */
2492 	REG_WR (pDevice, RcvListPlmt.Config, 0x181);
2493 
2494 	/* Enable Receive Placement Statistics */
2495 	REG_WR (pDevice, RcvListPlmt.StatsEnableMask, 0xffffff);
2496 	REG_WR (pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
2497 
2498 	/* Enable Send Data Initator Statistics */
2499 	REG_WR (pDevice, SndDataIn.StatsEnableMask, 0xffffff);
2500 	REG_WR (pDevice, SndDataIn.StatsCtrl,
2501 		T3_SND_DATA_IN_STATS_CTRL_ENABLE |
2502 		T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
2503 
2504 	/* Disable the host coalescing state machine before configuring it's */
2505 	/* parameters. */
2506 	REG_WR (pDevice, HostCoalesce.Mode, 0);
2507 	for (j = 0; j < 2000; j++) {
2508 		Value32 = REG_RD (pDevice, HostCoalesce.Mode);
2509 		if (!(Value32 & HOST_COALESCE_ENABLE)) {
2510 			break;
2511 		}
2512 		MM_Wait (10);
2513 	}
2514 
2515 	/* Host coalescing configurations. */
2516 	REG_WR (pDevice, HostCoalesce.RxCoalescingTicks,
2517 		pDevice->RxCoalescingTicks);
2518 	REG_WR (pDevice, HostCoalesce.TxCoalescingTicks,
2519 		pDevice->TxCoalescingTicks);
2520 	REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFrames,
2521 		pDevice->RxMaxCoalescedFrames);
2522 	REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFrames,
2523 		pDevice->TxMaxCoalescedFrames);
2524 	REG_WR (pDevice, HostCoalesce.RxCoalescedTickDuringInt,
2525 		pDevice->RxCoalescingTicksDuringInt);
2526 	REG_WR (pDevice, HostCoalesce.TxCoalescedTickDuringInt,
2527 		pDevice->TxCoalescingTicksDuringInt);
2528 	REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
2529 		pDevice->RxMaxCoalescedFramesDuringInt);
2530 	REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
2531 		pDevice->TxMaxCoalescedFramesDuringInt);
2532 
2533 	/* Initialize the address of the status block.  The NIC will DMA */
2534 	/* the status block to this memory which resides on the host. */
2535 	REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.High,
2536 		pDevice->StatusBlkPhy.High);
2537 	REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.Low,
2538 		pDevice->StatusBlkPhy.Low);
2539 
2540 	/* Initialize the address of the statistics block.  The NIC will DMA */
2541 	/* the statistics to this block of memory. */
2542 	REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.High,
2543 		pDevice->StatsBlkPhy.High);
2544 	REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.Low,
2545 		pDevice->StatsBlkPhy.Low);
2546 
2547 	REG_WR (pDevice, HostCoalesce.StatsCoalescingTicks,
2548 		pDevice->StatsCoalescingTicks);
2549 
2550 	REG_WR (pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
2551 	REG_WR (pDevice, HostCoalesce.StatusBlkNicAddr, 0xb00);
2552 
2553 	/* Enable Host Coalesing state machine */
2554 	REG_WR (pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
2555 		pDevice->CoalesceMode);
2556 
2557 	/* Enable the Receive BD Completion state machine. */
2558 	REG_WR (pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
2559 		RCV_BD_COMP_MODE_ATTN_ENABLE);
2560 
2561 	/* Enable the Receive List Placement state machine. */
2562 	REG_WR (pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
2563 
2564 	/* Enable the Receive List Selector state machine. */
2565 	REG_WR (pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
2566 		RCV_LIST_SEL_MODE_ATTN_ENABLE);
2567 
2568 	/* Enable transmit DMA, clear statistics. */
2569 	pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
2570 	    MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
2571 	    MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
2572 	REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
2573 		MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
2574 
2575 	/* GRC miscellaneous local control register. */
2576 	pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
2577 	    GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
2578 
2579 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2580 		pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
2581 		    GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
2582 	}
2583 
2584 	REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
2585 	MM_Wait (40);
2586 
2587 	/* Reset RX counters. */
2588 	for (j = 0; j < sizeof (LM_RX_COUNTERS); j++) {
2589 		((PLM_UINT8) & pDevice->RxCounters)[j] = 0;
2590 	}
2591 
2592 	/* Reset TX counters. */
2593 	for (j = 0; j < sizeof (LM_TX_COUNTERS); j++) {
2594 		((PLM_UINT8) & pDevice->TxCounters)[j] = 0;
2595 	}
2596 
2597 	MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
2598 
2599 	/* Enable the DMA Completion state machine. */
2600 	REG_WR (pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
2601 
2602 	/* Enable the DMA Write state machine. */
2603 	Value32 = DMA_WRITE_MODE_ENABLE |
2604 	    DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
2605 	    DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
2606 	    DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
2607 	    DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2608 	    DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2609 	    DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2610 	    DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2611 	    DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
2612 	REG_WR (pDevice, DmaWrite.Mode, Value32);
2613 
2614 	if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
2615 		if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
2616 			Value16 = REG_RD (pDevice, PciCfg.PciXCommand);
2617 			Value16 &=
2618 			    ~(PCIX_CMD_MAX_SPLIT_MASK |
2619 			      PCIX_CMD_MAX_BURST_MASK);
2620 			Value16 |=
2621 			    ((PCIX_CMD_MAX_BURST_CPIOB <<
2622 			      PCIX_CMD_MAX_BURST_SHL) &
2623 			     PCIX_CMD_MAX_BURST_MASK);
2624 			if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
2625 				Value16 |=
2626 				    (pDevice->
2627 				     SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
2628 				    & PCIX_CMD_MAX_SPLIT_MASK;
2629 			}
2630 			REG_WR (pDevice, PciCfg.PciXCommand, Value16);
2631 		}
2632 	}
2633 
2634 	/* Enable the Read DMA state machine. */
2635 	Value32 = DMA_READ_MODE_ENABLE |
2636 	    DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
2637 	    DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
2638 	    DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
2639 	    DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2640 	    DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2641 	    DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2642 	    DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2643 	    DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
2644 
2645 	if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
2646 		Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
2647 	}
2648 	REG_WR (pDevice, DmaRead.Mode, Value32);
2649 
2650 	/* Enable the Receive Data Completion state machine. */
2651 	REG_WR (pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
2652 		RCV_DATA_COMP_MODE_ATTN_ENABLE);
2653 
2654 	/* Enable the Mbuf Cluster Free state machine. */
2655 	REG_WR (pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
2656 
2657 	/* Enable the Send Data Completion state machine. */
2658 	REG_WR (pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
2659 
2660 	/* Enable the Send BD Completion state machine. */
2661 	REG_WR (pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
2662 		SND_BD_COMP_MODE_ATTN_ENABLE);
2663 
2664 	/* Enable the Receive BD Initiator state machine. */
2665 	REG_WR (pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
2666 		RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
2667 
2668 	/* Enable the Receive Data and Receive BD Initiator state machine. */
2669 	REG_WR (pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
2670 		RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
2671 
2672 	/* Enable the Send Data Initiator state machine. */
2673 	REG_WR (pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
2674 
2675 	/* Enable the Send BD Initiator state machine. */
2676 	REG_WR (pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
2677 		SND_BD_IN_MODE_ATTN_ENABLE);
2678 
2679 	/* Enable the Send BD Selector state machine. */
2680 	REG_WR (pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
2681 		SND_BD_SEL_MODE_ATTN_ENABLE);
2682 
2683 #if INCLUDE_5701_AX_FIX
2684 	/* Load the firmware for the 5701_A0 workaround. */
2685 	if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0) {
2686 		LM_LoadRlsFirmware (pDevice);
2687 	}
2688 #endif
2689 
2690 	/* Enable the transmitter. */
2691 	pDevice->TxMode = TX_MODE_ENABLE;
2692 	REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
2693 
2694 	/* Enable the receiver. */
2695 	pDevice->RxMode = RX_MODE_ENABLE;
2696 	REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
2697 
2698 	if (pDevice->RestoreOnWakeUp) {
2699 		pDevice->RestoreOnWakeUp = FALSE;
2700 		pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
2701 		pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
2702 	}
2703 
2704 	/* Disable auto polling. */
2705 	pDevice->MiMode = 0xc0000;
2706 	REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
2707 
2708 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2709 	    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
2710 		Value32 = LED_CTRL_PHY_MODE_1;
2711 	} else {
2712 		if (pDevice->LedMode == LED_MODE_OUTPUT) {
2713 			Value32 = LED_CTRL_PHY_MODE_2;
2714 		} else {
2715 			Value32 = LED_CTRL_PHY_MODE_1;
2716 		}
2717 	}
2718 	REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
2719 
2720 	/* Activate Link to enable MAC state machine */
2721 	REG_WR (pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
2722 
2723 	if (pDevice->EnableTbi) {
2724 		REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_RESET);
2725 		MM_Wait (10);
2726 		REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
2727 		if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1) {
2728 			REG_WR (pDevice, MacCtrl.SerdesCfg, 0x616000);
2729 		}
2730 	}
2731 	/* Setup the phy chip. */
2732 	LM_SetupPhy (pDevice);
2733 
2734 	if (!pDevice->EnableTbi) {
2735 		/* Clear CRC stats */
2736 		LM_ReadPhy (pDevice, 0x1e, &Value32);
2737 		LM_WritePhy (pDevice, 0x1e, Value32 | 0x8000);
2738 		LM_ReadPhy (pDevice, 0x14, &Value32);
2739 	}
2740 
2741 	/* Set up the receive mask. */
2742 	LM_SetReceiveMask (pDevice, pDevice->ReceiveMask);
2743 
2744 	/* Queue Rx packet buffers. */
2745 	if (pDevice->QueueRxPackets) {
2746 		LM_QueueRxPackets (pDevice);
2747 	}
2748 
2749 	/* Enable interrupt to the host. */
2750 	if (pDevice->InitDone) {
2751 		LM_EnableInterrupt (pDevice);
2752 	}
2753 
2754 	return LM_STATUS_SUCCESS;
2755 }				/* LM_ResetAdapter */
2756 
2757 /******************************************************************************/
2758 /* Description:                                                               */
2759 /*    This routine disables the adapter from generating interrupts.           */
2760 /*                                                                            */
2761 /* Return:                                                                    */
2762 /*    LM_STATUS_SUCCESS                                                       */
2763 /******************************************************************************/
LM_DisableInterrupt(PLM_DEVICE_BLOCK pDevice)2764 LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice)
2765 {
2766 	REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
2767 		MISC_HOST_CTRL_MASK_PCI_INT);
2768 	MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
2769 
2770 	return LM_STATUS_SUCCESS;
2771 }
2772 
2773 /******************************************************************************/
2774 /* Description:                                                               */
2775 /*    This routine enables the adapter to generate interrupts.                */
2776 /*                                                                            */
2777 /* Return:                                                                    */
2778 /*    LM_STATUS_SUCCESS                                                       */
2779 /******************************************************************************/
LM_EnableInterrupt(PLM_DEVICE_BLOCK pDevice)2780 LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice)
2781 {
2782 	REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
2783 		~MISC_HOST_CTRL_MASK_PCI_INT);
2784 	MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
2785 
2786 	if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
2787 		REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
2788 			GRC_MISC_LOCAL_CTRL_SET_INT);
2789 	}
2790 
2791 	return LM_STATUS_SUCCESS;
2792 }
2793 
2794 /******************************************************************************/
2795 /* Description:                                                               */
2796 /*    This routine puts a packet on the wire if there is a transmit DMA       */
2797 /*    descriptor available; otherwise the packet is queued for later          */
2798 /*    transmission.  If the second argue is NULL, this routine will put       */
2799 /*    the queued packet on the wire if possible.                              */
2800 /*                                                                            */
2801 /* Return:                                                                    */
2802 /*    LM_STATUS_SUCCESS                                                       */
2803 /******************************************************************************/
2804 #if 0
2805 LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
2806 {
2807 	LM_UINT32 FragCount;
2808 	PT3_SND_BD pSendBd;
2809 	PT3_SND_BD pShadowSendBd;
2810 	LM_UINT32 Value32, Len;
2811 	LM_UINT32 Idx;
2812 
2813 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2814 		return LM_5700SendPacket (pDevice, pPacket);
2815 	}
2816 
2817 	/* Update the SendBdLeft count. */
2818 	atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
2819 
2820 	/* Initalize the send buffer descriptors. */
2821 	Idx = pDevice->SendProdIdx;
2822 
2823 	pSendBd = &pDevice->pSendBdVirt[Idx];
2824 
2825 	/* Next producer index. */
2826 	if (pDevice->NicSendBd == TRUE) {
2827 		T3_64BIT_HOST_ADDR paddr;
2828 
2829 		pShadowSendBd = &pDevice->ShadowSendBd[Idx];
2830 		for (FragCount = 0;;) {
2831 			MM_MapTxDma (pDevice, pPacket, &paddr, &Len, FragCount);
2832 			/* Initialize the pointer to the send buffer fragment. */
2833 			if (paddr.High != pShadowSendBd->HostAddr.High) {
2834 				__raw_writel (paddr.High,
2835 					      &(pSendBd->HostAddr.High));
2836 				pShadowSendBd->HostAddr.High = paddr.High;
2837 			}
2838 			__raw_writel (paddr.Low, &(pSendBd->HostAddr.Low));
2839 
2840 			/* Setup the control flags and send buffer size. */
2841 			Value32 = (Len << 16) | pPacket->Flags;
2842 
2843 			Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2844 
2845 			FragCount++;
2846 			if (FragCount >= pPacket->u.Tx.FragCount) {
2847 				Value32 |= SND_BD_FLAG_END;
2848 				if (Value32 != pShadowSendBd->u1.Len_Flags) {
2849 					__raw_writel (Value32,
2850 						      &(pSendBd->u1.Len_Flags));
2851 					pShadowSendBd->u1.Len_Flags = Value32;
2852 				}
2853 				if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
2854 					__raw_writel (pPacket->VlanTag,
2855 						      &(pSendBd->u2.VlanTag));
2856 				}
2857 				break;
2858 			} else {
2859 				if (Value32 != pShadowSendBd->u1.Len_Flags) {
2860 					__raw_writel (Value32,
2861 						      &(pSendBd->u1.Len_Flags));
2862 					pShadowSendBd->u1.Len_Flags = Value32;
2863 				}
2864 				if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
2865 					__raw_writel (pPacket->VlanTag,
2866 						      &(pSendBd->u2.VlanTag));
2867 				}
2868 			}
2869 
2870 			pSendBd++;
2871 			pShadowSendBd++;
2872 			if (Idx == 0) {
2873 				pSendBd = &pDevice->pSendBdVirt[0];
2874 				pShadowSendBd = &pDevice->ShadowSendBd[0];
2875 			}
2876 		}		/* for */
2877 
2878 		/* Put the packet descriptor in the ActiveQ. */
2879 		QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2880 
2881 		wmb ();
2882 		MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
2883 
2884 	} else {
2885 		for (FragCount = 0;;) {
2886 			/* Initialize the pointer to the send buffer fragment. */
2887 			MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
2888 				     FragCount);
2889 
2890 			pSendBd->u2.VlanTag = pPacket->VlanTag;
2891 
2892 			/* Setup the control flags and send buffer size. */
2893 			Value32 = (Len << 16) | pPacket->Flags;
2894 
2895 			Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2896 
2897 			FragCount++;
2898 			if (FragCount >= pPacket->u.Tx.FragCount) {
2899 				pSendBd->u1.Len_Flags =
2900 				    Value32 | SND_BD_FLAG_END;
2901 				break;
2902 			} else {
2903 				pSendBd->u1.Len_Flags = Value32;
2904 			}
2905 			pSendBd++;
2906 			if (Idx == 0) {
2907 				pSendBd = &pDevice->pSendBdVirt[0];
2908 			}
2909 		}		/* for */
2910 
2911 		/* Put the packet descriptor in the ActiveQ. */
2912 		QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2913 
2914 		wmb ();
2915 		MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
2916 
2917 	}
2918 
2919 	/* Update the producer index. */
2920 	pDevice->SendProdIdx = Idx;
2921 
2922 	return LM_STATUS_SUCCESS;
2923 }
2924 #endif
2925 
LM_SendPacket(PLM_DEVICE_BLOCK pDevice,PLM_PACKET pPacket)2926 LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
2927 {
2928 	LM_UINT32 FragCount;
2929 	PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
2930 	T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
2931 	LM_UINT32 StartIdx, Idx;
2932 
2933 	while (1) {
2934 		/* Initalize the send buffer descriptors. */
2935 		StartIdx = Idx = pDevice->SendProdIdx;
2936 
2937 		if (pDevice->NicSendBd) {
2938 			pTmpSendBd = pSendBd = &NicSendBdArr[0];
2939 		} else {
2940 			pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
2941 		}
2942 
2943 		/* Next producer index. */
2944 		for (FragCount = 0;;) {
2945 			LM_UINT32 Value32, Len;
2946 
2947 			/* Initialize the pointer to the send buffer fragment. */
2948 			MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
2949 				     FragCount);
2950 
2951 			pSendBd->u2.VlanTag = pPacket->VlanTag;
2952 
2953 			/* Setup the control flags and send buffer size. */
2954 			Value32 = (Len << 16) | pPacket->Flags;
2955 
2956 			Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2957 
2958 			FragCount++;
2959 			if (FragCount >= pPacket->u.Tx.FragCount) {
2960 				pSendBd->u1.Len_Flags =
2961 				    Value32 | SND_BD_FLAG_END;
2962 				break;
2963 			} else {
2964 				pSendBd->u1.Len_Flags = Value32;
2965 			}
2966 			pSendBd++;
2967 			if ((Idx == 0) && !pDevice->NicSendBd) {
2968 				pSendBd = &pDevice->pSendBdVirt[0];
2969 			}
2970 		}		/* for */
2971 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2972 			if (LM_Test4GBoundary (pDevice, pPacket, pTmpSendBd) ==
2973 			    LM_STATUS_SUCCESS) {
2974 				if (MM_CoalesceTxBuffer (pDevice, pPacket) !=
2975 				    LM_STATUS_SUCCESS) {
2976 					QQ_PushHead (&pDevice->TxPacketFreeQ.
2977 						     Container, pPacket);
2978 					return LM_STATUS_FAILURE;
2979 				}
2980 				continue;
2981 			}
2982 		}
2983 		break;
2984 	}
2985 	/* Put the packet descriptor in the ActiveQ. */
2986 	QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2987 
2988 	if (pDevice->NicSendBd) {
2989 		pSendBd = &pDevice->pSendBdVirt[StartIdx];
2990 		pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
2991 
2992 		while (StartIdx != Idx) {
2993 			LM_UINT32 Value32;
2994 
2995 			if ((Value32 = pTmpSendBd->HostAddr.High) !=
2996 			    pShadowSendBd->HostAddr.High) {
2997 				__raw_writel (Value32,
2998 					      &(pSendBd->HostAddr.High));
2999 				pShadowSendBd->HostAddr.High = Value32;
3000 			}
3001 
3002 			__raw_writel (pTmpSendBd->HostAddr.Low,
3003 				      &(pSendBd->HostAddr.Low));
3004 
3005 			if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3006 			    pShadowSendBd->u1.Len_Flags) {
3007 				__raw_writel (Value32,
3008 					      &(pSendBd->u1.Len_Flags));
3009 				pShadowSendBd->u1.Len_Flags = Value32;
3010 			}
3011 
3012 			if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3013 				__raw_writel (pTmpSendBd->u2.VlanTag,
3014 					      &(pSendBd->u2.VlanTag));
3015 			}
3016 
3017 			StartIdx =
3018 			    (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3019 			if (StartIdx == 0)
3020 				pSendBd = &pDevice->pSendBdVirt[0];
3021 			else
3022 				pSendBd++;
3023 			pTmpSendBd++;
3024 		}
3025 		wmb ();
3026 		MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3027 
3028 		if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
3029 			MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3030 		}
3031 	} else {
3032 		wmb ();
3033 		MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3034 
3035 		if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
3036 			MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low,
3037 				   Idx);
3038 		}
3039 	}
3040 
3041 	/* Update the SendBdLeft count. */
3042 	atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3043 
3044 	/* Update the producer index. */
3045 	pDevice->SendProdIdx = Idx;
3046 
3047 	return LM_STATUS_SUCCESS;
3048 }
3049 
3050 STATIC LM_STATUS
LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice,PLM_PACKET pPacket,PT3_SND_BD pSendBd)3051 LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3052 		   PT3_SND_BD pSendBd)
3053 {
3054 	int FragCount;
3055 	LM_UINT32 Idx, Base, Len;
3056 
3057 	Idx = pDevice->SendProdIdx;
3058 	for (FragCount = 0;;) {
3059 		Len = pSendBd->u1.Len_Flags >> 16;
3060 		if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3061 		    (pSendBd->HostAddr.High == 0) &&
3062 		    ((Base + 8 + Len) < Base)) {
3063 			return LM_STATUS_SUCCESS;
3064 		}
3065 		FragCount++;
3066 		if (FragCount >= pPacket->u.Tx.FragCount) {
3067 			break;
3068 		}
3069 		pSendBd++;
3070 		if (!pDevice->NicSendBd) {
3071 			Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3072 			if (Idx == 0) {
3073 				pSendBd = &pDevice->pSendBdVirt[0];
3074 			}
3075 		}
3076 	}
3077 	return LM_STATUS_FAILURE;
3078 }
3079 
3080 /******************************************************************************/
3081 /* Description:                                                               */
3082 /*                                                                            */
3083 /* Return:                                                                    */
3084 /******************************************************************************/
3085 __inline static unsigned long
ComputeCrc32(unsigned char * pBuffer,unsigned long BufferSize)3086 ComputeCrc32 (unsigned char *pBuffer, unsigned long BufferSize)
3087 {
3088 	unsigned long Reg;
3089 	unsigned long Tmp;
3090 	unsigned long j, k;
3091 
3092 	Reg = 0xffffffff;
3093 
3094 	for (j = 0; j < BufferSize; j++) {
3095 		Reg ^= pBuffer[j];
3096 
3097 		for (k = 0; k < 8; k++) {
3098 			Tmp = Reg & 0x01;
3099 
3100 			Reg >>= 1;
3101 
3102 			if (Tmp) {
3103 				Reg ^= 0xedb88320;
3104 			}
3105 		}
3106 	}
3107 
3108 	return ~Reg;
3109 }				/* ComputeCrc32 */
3110 
3111 /******************************************************************************/
3112 /* Description:                                                               */
3113 /*    This routine sets the receive control register according to ReceiveMask */
3114 /*                                                                            */
3115 /* Return:                                                                    */
3116 /*    LM_STATUS_SUCCESS                                                       */
3117 /******************************************************************************/
LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Mask)3118 LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
3119 {
3120 	LM_UINT32 ReceiveMask;
3121 	LM_UINT32 RxMode;
3122 	LM_UINT32 j, k;
3123 
3124 	ReceiveMask = Mask;
3125 
3126 	RxMode = pDevice->RxMode;
3127 
3128 	if (Mask & LM_ACCEPT_UNICAST) {
3129 		Mask &= ~LM_ACCEPT_UNICAST;
3130 	}
3131 
3132 	if (Mask & LM_ACCEPT_MULTICAST) {
3133 		Mask &= ~LM_ACCEPT_MULTICAST;
3134 	}
3135 
3136 	if (Mask & LM_ACCEPT_ALL_MULTICAST) {
3137 		Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3138 	}
3139 
3140 	if (Mask & LM_ACCEPT_BROADCAST) {
3141 		Mask &= ~LM_ACCEPT_BROADCAST;
3142 	}
3143 
3144 	RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3145 	if (Mask & LM_PROMISCUOUS_MODE) {
3146 		RxMode |= RX_MODE_PROMISCUOUS_MODE;
3147 		Mask &= ~LM_PROMISCUOUS_MODE;
3148 	}
3149 
3150 	RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3151 	if (Mask & LM_ACCEPT_ERROR_PACKET) {
3152 		RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3153 		Mask &= ~LM_ACCEPT_ERROR_PACKET;
3154 	}
3155 
3156 	/* Make sure all the bits are valid before committing changes. */
3157 	if (Mask) {
3158 		return LM_STATUS_FAILURE;
3159 	}
3160 
3161 	/* Commit the new filter. */
3162 	pDevice->RxMode = RxMode;
3163 	REG_WR (pDevice, MacCtrl.RxMode, RxMode);
3164 
3165 	pDevice->ReceiveMask = ReceiveMask;
3166 
3167 	/* Set up the MC hash table. */
3168 	if (ReceiveMask & LM_ACCEPT_ALL_MULTICAST) {
3169 		for (k = 0; k < 4; k++) {
3170 			REG_WR (pDevice, MacCtrl.HashReg[k], 0xffffffff);
3171 		}
3172 	} else if (ReceiveMask & LM_ACCEPT_MULTICAST) {
3173 		LM_UINT32 HashReg[4];
3174 
3175 		HashReg[0] = 0;
3176 		HashReg[1] = 0;
3177 		HashReg[2] = 0;
3178 		HashReg[3] = 0;
3179 		for (j = 0; j < pDevice->McEntryCount; j++) {
3180 			LM_UINT32 RegIndex;
3181 			LM_UINT32 Bitpos;
3182 			LM_UINT32 Crc32;
3183 
3184 			Crc32 =
3185 			    ComputeCrc32 (pDevice->McTable[j],
3186 					  ETHERNET_ADDRESS_SIZE);
3187 
3188 			/* The most significant 7 bits of the CRC32 (no inversion), */
3189 			/* are used to index into one of the possible 128 bit positions. */
3190 			Bitpos = ~Crc32 & 0x7f;
3191 
3192 			/* Hash register index. */
3193 			RegIndex = (Bitpos & 0x60) >> 5;
3194 
3195 			/* Bit to turn on within a hash register. */
3196 			Bitpos &= 0x1f;
3197 
3198 			/* Enable the multicast bit. */
3199 			HashReg[RegIndex] |= (1 << Bitpos);
3200 		}
3201 
3202 		/* REV_AX has problem with multicast filtering where it uses both */
3203 		/* DA and SA to perform hashing. */
3204 		for (k = 0; k < 4; k++) {
3205 			REG_WR (pDevice, MacCtrl.HashReg[k], HashReg[k]);
3206 		}
3207 	} else {
3208 		/* Reject all multicast frames. */
3209 		for (j = 0; j < 4; j++) {
3210 			REG_WR (pDevice, MacCtrl.HashReg[j], 0);
3211 		}
3212 	}
3213 
3214 	/* By default, Tigon3 will accept broadcast frames.  We need to setup */
3215 	if (ReceiveMask & LM_ACCEPT_BROADCAST) {
3216 		REG_WR (pDevice,
3217 			MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3218 			REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3219 		REG_WR (pDevice,
3220 			MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3221 			REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3222 		REG_WR (pDevice,
3223 			MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3224 			REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3225 		REG_WR (pDevice,
3226 			MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3227 			REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3228 	} else {
3229 		REG_WR (pDevice,
3230 			MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3231 			REJECT_BROADCAST_RULE1_RULE);
3232 		REG_WR (pDevice,
3233 			MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3234 			REJECT_BROADCAST_RULE1_VALUE);
3235 		REG_WR (pDevice,
3236 			MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3237 			REJECT_BROADCAST_RULE2_RULE);
3238 		REG_WR (pDevice,
3239 			MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3240 			REJECT_BROADCAST_RULE2_VALUE);
3241 	}
3242 
3243 	/* disable the rest of the rules. */
3244 	for (j = RCV_LAST_RULE_IDX; j < 16; j++) {
3245 		REG_WR (pDevice, MacCtrl.RcvRules[j].Rule, 0);
3246 		REG_WR (pDevice, MacCtrl.RcvRules[j].Value, 0);
3247 	}
3248 
3249 	return LM_STATUS_SUCCESS;
3250 }				/* LM_SetReceiveMask */
3251 
3252 /******************************************************************************/
3253 /* Description:                                                               */
3254 /*    Disable the interrupt and put the transmitter and receiver engines in   */
3255 /*    an idle state.  Also aborts all pending send requests and receive       */
3256 /*    buffers.                                                                */
3257 /*                                                                            */
3258 /* Return:                                                                    */
3259 /*    LM_STATUS_SUCCESS                                                       */
3260 /******************************************************************************/
LM_Abort(PLM_DEVICE_BLOCK pDevice)3261 LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice)
3262 {
3263 	PLM_PACKET pPacket;
3264 	LM_UINT Idx;
3265 
3266 	LM_DisableInterrupt (pDevice);
3267 
3268 	/* Disable all the state machines. */
3269 	LM_CntrlBlock (pDevice, T3_BLOCK_MAC_RX_ENGINE, LM_DISABLE);
3270 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_INITIATOR, LM_DISABLE);
3271 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_PLMT, LM_DISABLE);
3272 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_SELECTOR, LM_DISABLE);
3273 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_INITIATOR, LM_DISABLE);
3274 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_COMP, LM_DISABLE);
3275 	LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_COMP, LM_DISABLE);
3276 
3277 	LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_SELECTOR, LM_DISABLE);
3278 	LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_INITIATOR, LM_DISABLE);
3279 	LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_INITIATOR, LM_DISABLE);
3280 	LM_CntrlBlock (pDevice, T3_BLOCK_DMA_RD, LM_DISABLE);
3281 	LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_COMP, LM_DISABLE);
3282 	LM_CntrlBlock (pDevice, T3_BLOCK_DMA_COMP, LM_DISABLE);
3283 	LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_COMP, LM_DISABLE);
3284 
3285 	/* Clear TDE bit */
3286 	pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
3287 	REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
3288 
3289 	LM_CntrlBlock (pDevice, T3_BLOCK_MAC_TX_ENGINE, LM_DISABLE);
3290 	LM_CntrlBlock (pDevice, T3_BLOCK_HOST_COALESING, LM_DISABLE);
3291 	LM_CntrlBlock (pDevice, T3_BLOCK_DMA_WR, LM_DISABLE);
3292 	LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_CLUSTER_FREE, LM_DISABLE);
3293 
3294 	/* Reset all FTQs */
3295 	REG_WR (pDevice, Ftq.Reset, 0xffffffff);
3296 	REG_WR (pDevice, Ftq.Reset, 0x0);
3297 
3298 	LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_MANAGER, LM_DISABLE);
3299 	LM_CntrlBlock (pDevice, T3_BLOCK_MEM_ARBITOR, LM_DISABLE);
3300 
3301 	MM_ACQUIRE_INT_LOCK (pDevice);
3302 
3303 	/* Abort packets that have already queued to go out. */
3304 	pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
3305 	while (pPacket) {
3306 
3307 		pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3308 		pDevice->TxCounters.TxPacketAbortedCnt++;
3309 
3310 		atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3311 
3312 		QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
3313 
3314 		pPacket = (PLM_PACKET)
3315 		    QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
3316 	}
3317 
3318 	/* Cleanup the receive return rings. */
3319 	LM_ServiceRxInterrupt (pDevice);
3320 
3321 	/* Don't want to indicate rx packets in Ndis miniport shutdown context. */
3322 	/* Doing so may cause system crash. */
3323 	if (!pDevice->ShuttingDown) {
3324 		/* Indicate packets to the protocol. */
3325 		MM_IndicateTxPackets (pDevice);
3326 
3327 		/* Indicate received packets to the protocols. */
3328 		MM_IndicateRxPackets (pDevice);
3329 	} else {
3330 		/* Move the receive packet descriptors in the ReceivedQ to the */
3331 		/* free queue. */
3332 		for (;;) {
3333 			pPacket =
3334 			    (PLM_PACKET) QQ_PopHead (&pDevice->
3335 						     RxPacketReceivedQ.
3336 						     Container);
3337 			if (pPacket == NULL) {
3338 				break;
3339 			}
3340 			QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
3341 				     pPacket);
3342 		}
3343 	}
3344 
3345 	/* Clean up the Std Receive Producer ring. */
3346 	Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
3347 
3348 	while (Idx != pDevice->RxStdProdIdx) {
3349 		pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3350 					MM_UINT_PTR (pDevice->pRxStdBdVirt[Idx].
3351 						     Opaque));
3352 
3353 		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3354 
3355 		Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
3356 	}			/* while */
3357 
3358 	/* Reinitialize our copy of the indices. */
3359 	pDevice->RxStdProdIdx = 0;
3360 
3361 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3362 	/* Clean up the Jumbo Receive Producer ring. */
3363 	Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
3364 
3365 	while (Idx != pDevice->RxJumboProdIdx) {
3366 		pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3367 					MM_UINT_PTR (pDevice->
3368 						     pRxJumboBdVirt[Idx].
3369 						     Opaque));
3370 
3371 		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3372 
3373 		Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
3374 	}			/* while */
3375 
3376 	/* Reinitialize our copy of the indices. */
3377 	pDevice->RxJumboProdIdx = 0;
3378 #endif				/* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3379 
3380 	MM_RELEASE_INT_LOCK (pDevice);
3381 
3382 	/* Initialize the statistis Block */
3383 	pDevice->pStatusBlkVirt->Status = 0;
3384 	pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
3385 	pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
3386 	pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
3387 
3388 	return LM_STATUS_SUCCESS;
3389 }				/* LM_Abort */
3390 
3391 /******************************************************************************/
3392 /* Description:                                                               */
3393 /*    Disable the interrupt and put the transmitter and receiver engines in   */
3394 /*    an idle state.  Aborts all pending send requests and receive buffers.   */
3395 /*    Also free all the receive buffers.                                      */
3396 /*                                                                            */
3397 /* Return:                                                                    */
3398 /*    LM_STATUS_SUCCESS                                                       */
3399 /******************************************************************************/
LM_Halt(PLM_DEVICE_BLOCK pDevice)3400 LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice)
3401 {
3402 	PLM_PACKET pPacket;
3403 	LM_UINT32 EntryCnt;
3404 
3405 	LM_Abort (pDevice);
3406 
3407 	/* Get the number of entries in the queue. */
3408 	EntryCnt = QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container);
3409 
3410 	/* Make sure all the packets have been accounted for. */
3411 	for (EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++) {
3412 		pPacket =
3413 		    (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
3414 		if (pPacket == 0)
3415 			break;
3416 
3417 		MM_FreeRxBuffer (pDevice, pPacket);
3418 
3419 		QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3420 	}
3421 
3422 	LM_ResetChip (pDevice);
3423 
3424 	/* Restore PCI configuration registers. */
3425 	MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
3426 			  pDevice->SavedCacheLineReg);
3427 	LM_RegWrInd (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
3428 		     (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
3429 
3430 	/* Reprogram the MAC address. */
3431 	LM_SetMacAddress (pDevice);
3432 
3433 	return LM_STATUS_SUCCESS;
3434 }				/* LM_Halt */
3435 
LM_ResetChip(PLM_DEVICE_BLOCK pDevice)3436 STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice)
3437 {
3438 	LM_UINT32 Value32;
3439 	LM_UINT32 j;
3440 
3441 	/* Wait for access to the nvram interface before resetting.  This is */
3442 	/* a workaround to prevent EEPROM corruption. */
3443 	if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
3444 	    T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
3445 		/* Request access to the flash interface. */
3446 		REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
3447 
3448 		for (j = 0; j < 100000; j++) {
3449 			Value32 = REG_RD (pDevice, Nvram.SwArb);
3450 			if (Value32 & SW_ARB_GNT1) {
3451 				break;
3452 			}
3453 			MM_Wait (10);
3454 		}
3455 	}
3456 
3457 	/* Global reset. */
3458 	REG_WR (pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
3459 	MM_Wait (40);
3460 	MM_Wait (40);
3461 	MM_Wait (40);
3462 
3463 	/* make sure we re-enable indirect accesses */
3464 	MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
3465 			  pDevice->MiscHostCtrl);
3466 
3467 	/* Set MAX PCI retry to zero. */
3468 	Value32 =
3469 	    T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
3470 	if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
3471 		if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
3472 			Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
3473 		}
3474 	}
3475 	MM_WriteConfig32 (pDevice, T3_PCI_STATE_REG, Value32);
3476 
3477 	/* Restore PCI command register. */
3478 	MM_WriteConfig32 (pDevice, PCI_COMMAND_REG,
3479 			  pDevice->PciCommandStatusWords);
3480 
3481 	/* Disable PCI-X relaxed ordering bit. */
3482 	MM_ReadConfig32 (pDevice, PCIX_CAP_REG, &Value32);
3483 	Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
3484 	MM_WriteConfig32 (pDevice, PCIX_CAP_REG, Value32);
3485 
3486 	/* Enable memory arbiter. */
3487 	REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
3488 
3489 #ifdef BIG_ENDIAN_PCI		/* This from jfd */
3490 	Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
3491 #else
3492 #ifdef BIG_ENDIAN_HOST
3493 	/* Reconfigure the mode register. */
3494 	Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
3495 	    GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3496 	    GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA;
3497 #else
3498 	/* Reconfigure the mode register. */
3499 	Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
3500 #endif
3501 #endif
3502 	REG_WR (pDevice, Grc.Mode, Value32);
3503 
3504 	/* Prevent PXE from restarting. */
3505 	MEM_WR_OFFSET (pDevice, 0x0b50, T3_MAGIC_NUM);
3506 
3507 	if (pDevice->EnableTbi) {
3508 		pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
3509 		REG_WR (pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
3510 	} else {
3511 		REG_WR (pDevice, MacCtrl.Mode, 0);
3512 	}
3513 
3514 	/* Wait for the firmware to finish initialization. */
3515 	for (j = 0; j < 100000; j++) {
3516 		MM_Wait (10);
3517 
3518 		Value32 = MEM_RD_OFFSET (pDevice, 0x0b50);
3519 		if (Value32 == ~T3_MAGIC_NUM) {
3520 			break;
3521 		}
3522 	}
3523 	return LM_STATUS_SUCCESS;
3524 }
3525 
3526 /******************************************************************************/
3527 /* Description:                                                               */
3528 /*                                                                            */
3529 /* Return:                                                                    */
3530 /******************************************************************************/
LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice)3531 __inline static void LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice)
3532 {
3533 	PLM_PACKET pPacket;
3534 	LM_UINT32 HwConIdx;
3535 	LM_UINT32 SwConIdx;
3536 
3537 	HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3538 
3539 	/* Get our copy of the consumer index.  The buffer descriptors */
3540 	/* that are in between the consumer indices are freed. */
3541 	SwConIdx = pDevice->SendConIdx;
3542 
3543 	/* Move the packets from the TxPacketActiveQ that are sent out to */
3544 	/* the TxPacketXmittedQ.  Packets that are sent use the */
3545 	/* descriptors that are between SwConIdx and HwConIdx. */
3546 	while (SwConIdx != HwConIdx) {
3547 		/* Get the packet that was sent from the TxPacketActiveQ. */
3548 		pPacket =
3549 		    (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.
3550 					     Container);
3551 
3552 		/* Set the return status. */
3553 		pPacket->PacketStatus = LM_STATUS_SUCCESS;
3554 
3555 		/* Put the packet in the TxPacketXmittedQ for indication later. */
3556 		QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
3557 
3558 		/* Move to the next packet's BD. */
3559 		SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
3560 		    T3_SEND_RCB_ENTRY_COUNT_MASK;
3561 
3562 		/* Update the number of unused BDs. */
3563 		atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3564 
3565 		/* Get the new updated HwConIdx. */
3566 		HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3567 	}			/* while */
3568 
3569 	/* Save the new SwConIdx. */
3570 	pDevice->SendConIdx = SwConIdx;
3571 
3572 }				/* LM_ServiceTxInterrupt */
3573 
3574 /******************************************************************************/
3575 /* Description:                                                               */
3576 /*                                                                            */
3577 /* Return:                                                                    */
3578 /******************************************************************************/
LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice)3579 __inline static void LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice)
3580 {
3581 	PLM_PACKET pPacket;
3582 	PT3_RCV_BD pRcvBd;
3583 	LM_UINT32 HwRcvRetProdIdx;
3584 	LM_UINT32 SwRcvRetConIdx;
3585 
3586 	/* Loop thru the receive return rings for received packets. */
3587 	HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3588 
3589 	SwRcvRetConIdx = pDevice->RcvRetConIdx;
3590 	while (SwRcvRetConIdx != HwRcvRetProdIdx) {
3591 		pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
3592 
3593 		/* Get the received packet descriptor. */
3594 		pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3595 					MM_UINT_PTR (pRcvBd->Opaque));
3596 
3597 		/* Check the error flag. */
3598 		if (pRcvBd->ErrorFlag &&
3599 		    pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
3600 			pPacket->PacketStatus = LM_STATUS_FAILURE;
3601 
3602 			pDevice->RxCounters.RxPacketErrCnt++;
3603 
3604 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC) {
3605 				pDevice->RxCounters.RxErrCrcCnt++;
3606 			}
3607 
3608 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT) {
3609 				pDevice->RxCounters.RxErrCollCnt++;
3610 			}
3611 
3612 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT) {
3613 				pDevice->RxCounters.RxErrLinkLostCnt++;
3614 			}
3615 
3616 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR) {
3617 				pDevice->RxCounters.RxErrPhyDecodeCnt++;
3618 			}
3619 
3620 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
3621 				pDevice->RxCounters.RxErrOddNibbleCnt++;
3622 			}
3623 
3624 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT) {
3625 				pDevice->RxCounters.RxErrMacAbortCnt++;
3626 			}
3627 
3628 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64) {
3629 				pDevice->RxCounters.RxErrShortPacketCnt++;
3630 			}
3631 
3632 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES) {
3633 				pDevice->RxCounters.RxErrNoResourceCnt++;
3634 			}
3635 
3636 			if (pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD) {
3637 				pDevice->RxCounters.RxErrLargePacketCnt++;
3638 			}
3639 		} else {
3640 			pPacket->PacketStatus = LM_STATUS_SUCCESS;
3641 			pPacket->PacketSize = pRcvBd->Len - 4;
3642 
3643 			pPacket->Flags = pRcvBd->Flags;
3644 			if (pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG) {
3645 				pPacket->VlanTag = pRcvBd->VlanTag;
3646 			}
3647 
3648 			pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
3649 		}
3650 
3651 		/* Put the packet descriptor containing the received packet */
3652 		/* buffer in the RxPacketReceivedQ for indication later. */
3653 		QQ_PushTail (&pDevice->RxPacketReceivedQ.Container, pPacket);
3654 
3655 		/* Go to the next buffer descriptor. */
3656 		SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
3657 		    T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
3658 
3659 		/* Get the updated HwRcvRetProdIdx. */
3660 		HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3661 	}			/* while */
3662 
3663 	pDevice->RcvRetConIdx = SwRcvRetConIdx;
3664 
3665 	/* Update the receive return ring consumer index. */
3666 	MB_REG_WR (pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
3667 }				/* LM_ServiceRxInterrupt */
3668 
3669 /******************************************************************************/
3670 /* Description:                                                               */
3671 /*    This is the interrupt event handler routine. It acknowledges all        */
3672 /*    pending interrupts and process all pending events.                      */
3673 /*                                                                            */
3674 /* Return:                                                                    */
3675 /*    LM_STATUS_SUCCESS                                                       */
3676 /******************************************************************************/
LM_ServiceInterrupts(PLM_DEVICE_BLOCK pDevice)3677 LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice)
3678 {
3679 	LM_UINT32 Value32;
3680 	int ServicePhyInt = FALSE;
3681 
3682 	/* Setup the phy chip whenever the link status changes. */
3683 	if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG) {
3684 		Value32 = REG_RD (pDevice, MacCtrl.Status);
3685 		if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
3686 			if (Value32 & MAC_STATUS_MI_INTERRUPT) {
3687 				ServicePhyInt = TRUE;
3688 			}
3689 		} else if (Value32 & MAC_STATUS_LINK_STATE_CHANGED) {
3690 			ServicePhyInt = TRUE;
3691 		}
3692 	} else {
3693 		if (pDevice->pStatusBlkVirt->
3694 		    Status & STATUS_BLOCK_LINK_CHANGED_STATUS) {
3695 			pDevice->pStatusBlkVirt->Status =
3696 			    STATUS_BLOCK_UPDATED | (pDevice->pStatusBlkVirt->
3697 						    Status &
3698 						    ~STATUS_BLOCK_LINK_CHANGED_STATUS);
3699 			ServicePhyInt = TRUE;
3700 		}
3701 	}
3702 #if INCLUDE_TBI_SUPPORT
3703 	if (pDevice->IgnoreTbiLinkChange == TRUE) {
3704 		ServicePhyInt = FALSE;
3705 	}
3706 #endif
3707 	if (ServicePhyInt == TRUE) {
3708 		LM_SetupPhy (pDevice);
3709 	}
3710 
3711 	/* Service receive and transmit interrupts. */
3712 	LM_ServiceRxInterrupt (pDevice);
3713 	LM_ServiceTxInterrupt (pDevice);
3714 
3715 	/* No spinlock for this queue since this routine is serialized. */
3716 	if (!QQ_Empty (&pDevice->RxPacketReceivedQ.Container)) {
3717 		/* Indicate receive packets. */
3718 		MM_IndicateRxPackets (pDevice);
3719 		/*       LM_QueueRxPackets(pDevice); */
3720 	}
3721 
3722 	/* No spinlock for this queue since this routine is serialized. */
3723 	if (!QQ_Empty (&pDevice->TxPacketXmittedQ.Container)) {
3724 		MM_IndicateTxPackets (pDevice);
3725 	}
3726 
3727 	return LM_STATUS_SUCCESS;
3728 }				/* LM_ServiceInterrupts */
3729 
3730 /******************************************************************************/
3731 /* Description:                                                               */
3732 /*                                                                            */
3733 /* Return:                                                                    */
3734 /******************************************************************************/
LM_MulticastAdd(PLM_DEVICE_BLOCK pDevice,PLM_UINT8 pMcAddress)3735 LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
3736 {
3737 	PLM_UINT8 pEntry;
3738 	LM_UINT32 j;
3739 
3740 	pEntry = pDevice->McTable[0];
3741 	for (j = 0; j < pDevice->McEntryCount; j++) {
3742 		if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
3743 			/* Found a match, increment the instance count. */
3744 			pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
3745 
3746 			return LM_STATUS_SUCCESS;
3747 		}
3748 
3749 		pEntry += LM_MC_ENTRY_SIZE;
3750 	}
3751 
3752 	if (pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE) {
3753 		return LM_STATUS_FAILURE;
3754 	}
3755 
3756 	pEntry = pDevice->McTable[pDevice->McEntryCount];
3757 
3758 	COPY_ETH_ADDRESS (pMcAddress, pEntry);
3759 	pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
3760 
3761 	pDevice->McEntryCount++;
3762 
3763 	LM_SetReceiveMask (pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
3764 
3765 	return LM_STATUS_SUCCESS;
3766 }				/* LM_MulticastAdd */
3767 
3768 /******************************************************************************/
3769 /* Description:                                                               */
3770 /*                                                                            */
3771 /* Return:                                                                    */
3772 /******************************************************************************/
LM_MulticastDel(PLM_DEVICE_BLOCK pDevice,PLM_UINT8 pMcAddress)3773 LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
3774 {
3775 	PLM_UINT8 pEntry;
3776 	LM_UINT32 j;
3777 
3778 	pEntry = pDevice->McTable[0];
3779 	for (j = 0; j < pDevice->McEntryCount; j++) {
3780 		if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
3781 			/* Found a match, decrement the instance count. */
3782 			pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
3783 
3784 			/* No more instance left, remove the address from the table. */
3785 			/* Move the last entry in the table to the delete slot. */
3786 			if (pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
3787 			    pDevice->McEntryCount > 1) {
3788 
3789 				COPY_ETH_ADDRESS (pDevice->
3790 						  McTable[pDevice->
3791 							  McEntryCount - 1],
3792 						  pEntry);
3793 				pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
3794 				    pDevice->McTable[pDevice->McEntryCount - 1]
3795 				    [LM_MC_INSTANCE_COUNT_INDEX];
3796 			}
3797 			pDevice->McEntryCount--;
3798 
3799 			/* Update the receive mask if the table is empty. */
3800 			if (pDevice->McEntryCount == 0) {
3801 				LM_SetReceiveMask (pDevice,
3802 						   pDevice->
3803 						   ReceiveMask &
3804 						   ~LM_ACCEPT_MULTICAST);
3805 			}
3806 
3807 			return LM_STATUS_SUCCESS;
3808 		}
3809 
3810 		pEntry += LM_MC_ENTRY_SIZE;
3811 	}
3812 
3813 	return LM_STATUS_FAILURE;
3814 }				/* LM_MulticastDel */
3815 
3816 /******************************************************************************/
3817 /* Description:                                                               */
3818 /*                                                                            */
3819 /* Return:                                                                    */
3820 /******************************************************************************/
LM_MulticastClear(PLM_DEVICE_BLOCK pDevice)3821 LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice)
3822 {
3823 	pDevice->McEntryCount = 0;
3824 
3825 	LM_SetReceiveMask (pDevice,
3826 			   pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
3827 
3828 	return LM_STATUS_SUCCESS;
3829 }				/* LM_MulticastClear */
3830 
3831 /******************************************************************************/
3832 /* Description:                                                               */
3833 /*                                                                            */
3834 /* Return:                                                                    */
3835 /******************************************************************************/
LM_SetMacAddress(PLM_DEVICE_BLOCK pDevice)3836 LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice)
3837 {
3838 	LM_UINT32 j;
3839 	PLM_UINT8 pMacAddress = pDevice->NodeAddress;
3840 
3841 	for (j = 0; j < 4; j++) {
3842 		REG_WR (pDevice, MacCtrl.MacAddr[j].High,
3843 			(pMacAddress[0] << 8) | pMacAddress[1]);
3844 		REG_WR (pDevice, MacCtrl.MacAddr[j].Low,
3845 			(pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
3846 			(pMacAddress[4] << 8) | pMacAddress[5]);
3847 	}
3848 
3849 	return LM_STATUS_SUCCESS;
3850 }
3851 
3852 /******************************************************************************/
3853 /* Description:                                                               */
3854 /*    Sets up the default line speed, and duplex modes based on the requested */
3855 /*    media type.                                                             */
3856 /*                                                                            */
3857 /* Return:                                                                    */
3858 /*    None.                                                                   */
3859 /******************************************************************************/
3860 static LM_STATUS
LM_TranslateRequestedMediaType(LM_REQUESTED_MEDIA_TYPE RequestedMediaType,PLM_MEDIA_TYPE pMediaType,PLM_LINE_SPEED pLineSpeed,PLM_DUPLEX_MODE pDuplexMode)3861 LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
3862 				PLM_MEDIA_TYPE pMediaType,
3863 				PLM_LINE_SPEED pLineSpeed,
3864 				PLM_DUPLEX_MODE pDuplexMode)
3865 {
3866 	*pMediaType = LM_MEDIA_TYPE_AUTO;
3867 	*pLineSpeed = LM_LINE_SPEED_UNKNOWN;
3868 	*pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
3869 
3870 	/* determine media type */
3871 	switch (RequestedMediaType) {
3872 	case LM_REQUESTED_MEDIA_TYPE_BNC:
3873 		*pMediaType = LM_MEDIA_TYPE_BNC;
3874 		*pLineSpeed = LM_LINE_SPEED_10MBPS;
3875 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3876 		break;
3877 
3878 	case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
3879 		*pMediaType = LM_MEDIA_TYPE_UTP;
3880 		break;
3881 
3882 	case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
3883 		*pMediaType = LM_MEDIA_TYPE_UTP;
3884 		*pLineSpeed = LM_LINE_SPEED_10MBPS;
3885 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3886 		break;
3887 
3888 	case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
3889 		*pMediaType = LM_MEDIA_TYPE_UTP;
3890 		*pLineSpeed = LM_LINE_SPEED_10MBPS;
3891 		*pDuplexMode = LM_DUPLEX_MODE_FULL;
3892 		break;
3893 
3894 	case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
3895 		*pMediaType = LM_MEDIA_TYPE_UTP;
3896 		*pLineSpeed = LM_LINE_SPEED_100MBPS;
3897 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3898 		break;
3899 
3900 	case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
3901 		*pMediaType = LM_MEDIA_TYPE_UTP;
3902 		*pLineSpeed = LM_LINE_SPEED_100MBPS;
3903 		*pDuplexMode = LM_DUPLEX_MODE_FULL;
3904 		break;
3905 
3906 	case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
3907 		*pMediaType = LM_MEDIA_TYPE_UTP;
3908 		*pLineSpeed = LM_LINE_SPEED_1000MBPS;
3909 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3910 		break;
3911 
3912 	case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
3913 		*pMediaType = LM_MEDIA_TYPE_UTP;
3914 		*pLineSpeed = LM_LINE_SPEED_1000MBPS;
3915 		*pDuplexMode = LM_DUPLEX_MODE_FULL;
3916 		break;
3917 
3918 	case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
3919 		*pMediaType = LM_MEDIA_TYPE_FIBER;
3920 		*pLineSpeed = LM_LINE_SPEED_100MBPS;
3921 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3922 		break;
3923 
3924 	case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
3925 		*pMediaType = LM_MEDIA_TYPE_FIBER;
3926 		*pLineSpeed = LM_LINE_SPEED_100MBPS;
3927 		*pDuplexMode = LM_DUPLEX_MODE_FULL;
3928 		break;
3929 
3930 	case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
3931 		*pMediaType = LM_MEDIA_TYPE_FIBER;
3932 		*pLineSpeed = LM_LINE_SPEED_1000MBPS;
3933 		*pDuplexMode = LM_DUPLEX_MODE_HALF;
3934 		break;
3935 
3936 	case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
3937 		*pMediaType = LM_MEDIA_TYPE_FIBER;
3938 		*pLineSpeed = LM_LINE_SPEED_1000MBPS;
3939 		*pDuplexMode = LM_DUPLEX_MODE_FULL;
3940 		break;
3941 
3942 	default:
3943 		break;
3944 	}			/* switch */
3945 
3946 	return LM_STATUS_SUCCESS;
3947 }				/* LM_TranslateRequestedMediaType */
3948 
3949 /******************************************************************************/
3950 /* Description:                                                               */
3951 /*                                                                            */
3952 /* Return:                                                                    */
3953 /*    LM_STATUS_LINK_ACTIVE                                                   */
3954 /*    LM_STATUS_LINK_DOWN                                                     */
3955 /******************************************************************************/
LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice)3956 static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice)
3957 {
3958 	LM_LINE_SPEED CurrentLineSpeed;
3959 	LM_DUPLEX_MODE CurrentDuplexMode;
3960 	LM_STATUS CurrentLinkStatus;
3961 	LM_UINT32 Value32;
3962 	LM_UINT32 j;
3963 
3964 #if 1				/* jmb: bugfix -- moved here, out of code that sets initial pwr state */
3965 	LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x2);
3966 #endif
3967 	if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
3968 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3969 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3970 
3971 		if (!pDevice->InitDone) {
3972 			Value32 = 0;
3973 		}
3974 
3975 		if (!(Value32 & PHY_STATUS_LINK_PASS)) {
3976 			LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
3977 
3978 			LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
3979 			LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
3980 
3981 			LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
3982 			LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
3983 
3984 			LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
3985 			LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
3986 
3987 			LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
3988 			LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
3989 
3990 			LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
3991 			LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
3992 
3993 			LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3994 			for (j = 0; j < 1000; j++) {
3995 				MM_Wait (10);
3996 
3997 				LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3998 				if (Value32 & PHY_STATUS_LINK_PASS) {
3999 					MM_Wait (40);
4000 					break;
4001 				}
4002 			}
4003 
4004 			if ((pDevice->PhyId & PHY_ID_REV_MASK) ==
4005 			    PHY_BCM5401_B0_REV) {
4006 				if (!(Value32 & PHY_STATUS_LINK_PASS)
4007 				    && (pDevice->OldLineSpeed ==
4008 					LM_LINE_SPEED_1000MBPS)) {
4009 					LM_WritePhy (pDevice, PHY_CTRL_REG,
4010 						     PHY_CTRL_PHY_RESET);
4011 					for (j = 0; j < 100; j++) {
4012 						MM_Wait (10);
4013 
4014 						LM_ReadPhy (pDevice,
4015 							    PHY_CTRL_REG,
4016 							    &Value32);
4017 						if (!
4018 						    (Value32 &
4019 						     PHY_CTRL_PHY_RESET)) {
4020 							MM_Wait (40);
4021 							break;
4022 						}
4023 					}
4024 
4025 					LM_WritePhy (pDevice, BCM5401_AUX_CTRL,
4026 						     0x0c20);
4027 
4028 					LM_WritePhy (pDevice,
4029 						     BCM540X_DSP_ADDRESS_REG,
4030 						     0x0012);
4031 					LM_WritePhy (pDevice,
4032 						     BCM540X_DSP_RW_PORT,
4033 						     0x1804);
4034 
4035 					LM_WritePhy (pDevice,
4036 						     BCM540X_DSP_ADDRESS_REG,
4037 						     0x0013);
4038 					LM_WritePhy (pDevice,
4039 						     BCM540X_DSP_RW_PORT,
4040 						     0x1204);
4041 
4042 					LM_WritePhy (pDevice,
4043 						     BCM540X_DSP_ADDRESS_REG,
4044 						     0x8006);
4045 					LM_WritePhy (pDevice,
4046 						     BCM540X_DSP_RW_PORT,
4047 						     0x0132);
4048 
4049 					LM_WritePhy (pDevice,
4050 						     BCM540X_DSP_ADDRESS_REG,
4051 						     0x8006);
4052 					LM_WritePhy (pDevice,
4053 						     BCM540X_DSP_RW_PORT,
4054 						     0x0232);
4055 
4056 					LM_WritePhy (pDevice,
4057 						     BCM540X_DSP_ADDRESS_REG,
4058 						     0x201f);
4059 					LM_WritePhy (pDevice,
4060 						     BCM540X_DSP_RW_PORT,
4061 						     0x0a20);
4062 				}
4063 			}
4064 		}
4065 	} else if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
4066 		   pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
4067 		/* Bug: 5701 A0, B0 TX CRC workaround. */
4068 		LM_WritePhy (pDevice, 0x15, 0x0a75);
4069 		LM_WritePhy (pDevice, 0x1c, 0x8c68);
4070 		LM_WritePhy (pDevice, 0x1c, 0x8d68);
4071 		LM_WritePhy (pDevice, 0x1c, 0x8c68);
4072 	}
4073 
4074 	/* Acknowledge interrupts. */
4075 	LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
4076 	LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
4077 
4078 	/* Configure the interrupt mask. */
4079 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
4080 		LM_WritePhy (pDevice, BCM540X_INT_MASK_REG,
4081 			     ~BCM540X_INT_LINK_CHANGE);
4082 	}
4083 
4084 	/* Configure PHY led mode. */
4085 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
4086 	    (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700)) {
4087 		if (pDevice->LedMode == LED_MODE_THREE_LINK) {
4088 			LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG,
4089 				     BCM540X_EXT_CTRL_LINK3_LED_MODE);
4090 		} else {
4091 			LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG, 0);
4092 		}
4093 	}
4094 
4095 	CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4096 
4097 	/* Get current link and duplex mode. */
4098 	for (j = 0; j < 100; j++) {
4099 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4100 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4101 
4102 		if (Value32 & PHY_STATUS_LINK_PASS) {
4103 			break;
4104 		}
4105 		MM_Wait (40);
4106 	}
4107 
4108 	if (Value32 & PHY_STATUS_LINK_PASS) {
4109 
4110 		/* Determine the current line and duplex settings. */
4111 		LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4112 		for (j = 0; j < 2000; j++) {
4113 			MM_Wait (10);
4114 
4115 			LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4116 			if (Value32) {
4117 				break;
4118 			}
4119 		}
4120 
4121 		switch (Value32 & BCM540X_AUX_SPEED_MASK) {
4122 		case BCM540X_AUX_10BASET_HD:
4123 			CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4124 			CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4125 			break;
4126 
4127 		case BCM540X_AUX_10BASET_FD:
4128 			CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4129 			CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4130 			break;
4131 
4132 		case BCM540X_AUX_100BASETX_HD:
4133 			CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4134 			CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4135 			break;
4136 
4137 		case BCM540X_AUX_100BASETX_FD:
4138 			CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4139 			CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4140 			break;
4141 
4142 		case BCM540X_AUX_100BASET_HD:
4143 			CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4144 			CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4145 			break;
4146 
4147 		case BCM540X_AUX_100BASET_FD:
4148 			CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4149 			CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4150 			break;
4151 
4152 		default:
4153 
4154 			CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
4155 			CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4156 			break;
4157 		}
4158 
4159 		/* Make sure we are in auto-neg mode. */
4160 		for (j = 0; j < 200; j++) {
4161 			LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
4162 			if (Value32 && Value32 != 0x7fff) {
4163 				break;
4164 			}
4165 
4166 			if (Value32 == 0 && pDevice->RequestedMediaType ==
4167 			    LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS) {
4168 				break;
4169 			}
4170 
4171 			MM_Wait (10);
4172 		}
4173 
4174 		/* Use the current line settings for "auto" mode. */
4175 		if (pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO
4176 		    || pDevice->RequestedMediaType ==
4177 		    LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
4178 			if (Value32 & PHY_CTRL_AUTO_NEG_ENABLE) {
4179 				CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4180 
4181 				/* We may be exiting low power mode and the link is in */
4182 				/* 10mb.  In this case, we need to restart autoneg. */
4183 				LM_ReadPhy (pDevice, BCM540X_1000BASET_CTRL_REG,
4184 					    &Value32);
4185 				pDevice->advertising1000 = Value32;
4186 				/* 5702FE supports 10/100Mb only. */
4187 				if (T3_ASIC_REV (pDevice->ChipRevId) !=
4188 				    T3_ASIC_REV_5703
4189 				    || pDevice->BondId !=
4190 				    GRC_MISC_BD_ID_5702FE) {
4191 					if (!
4192 					    (Value32 &
4193 					     (BCM540X_AN_AD_1000BASET_HALF |
4194 					      BCM540X_AN_AD_1000BASET_FULL))) {
4195 						CurrentLinkStatus =
4196 						    LM_STATUS_LINK_SETTING_MISMATCH;
4197 					}
4198 				}
4199 			} else {
4200 				CurrentLinkStatus =
4201 				    LM_STATUS_LINK_SETTING_MISMATCH;
4202 			}
4203 		} else {
4204 			/* Force line settings. */
4205 			/* Use the current setting if it matches the user's requested */
4206 			/* setting. */
4207 			LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
4208 			if ((pDevice->LineSpeed == CurrentLineSpeed) &&
4209 			    (pDevice->DuplexMode == CurrentDuplexMode)) {
4210 				if ((pDevice->DisableAutoNeg &&
4211 				     !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
4212 				    (!pDevice->DisableAutoNeg &&
4213 				     (Value32 & PHY_CTRL_AUTO_NEG_ENABLE))) {
4214 					CurrentLinkStatus =
4215 					    LM_STATUS_LINK_ACTIVE;
4216 				} else {
4217 					CurrentLinkStatus =
4218 					    LM_STATUS_LINK_SETTING_MISMATCH;
4219 				}
4220 			} else {
4221 				CurrentLinkStatus =
4222 				    LM_STATUS_LINK_SETTING_MISMATCH;
4223 			}
4224 		}
4225 
4226 		/* Save line settings. */
4227 		pDevice->LineSpeed = CurrentLineSpeed;
4228 		pDevice->DuplexMode = CurrentDuplexMode;
4229 		pDevice->MediaType = LM_MEDIA_TYPE_UTP;
4230 	}
4231 
4232 	return CurrentLinkStatus;
4233 }				/* LM_InitBcm540xPhy */
4234 
4235 /******************************************************************************/
4236 /* Description:                                                               */
4237 /*                                                                            */
4238 /* Return:                                                                    */
4239 /******************************************************************************/
4240 LM_STATUS
LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,LM_UINT32 LocalPhyAd,LM_UINT32 RemotePhyAd)4241 LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
4242 		   LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd)
4243 {
4244 	LM_FLOW_CONTROL FlowCap;
4245 
4246 	/* Resolve flow control. */
4247 	FlowCap = LM_FLOW_CONTROL_NONE;
4248 
4249 	/* See Table 28B-3 of 802.3ab-1999 spec. */
4250 	if (pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE) {
4251 		if (LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE) {
4252 			if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
4253 				if (RemotePhyAd &
4254 				    PHY_LINK_PARTNER_PAUSE_CAPABLE) {
4255 					FlowCap =
4256 					    LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4257 					    LM_FLOW_CONTROL_RECEIVE_PAUSE;
4258 				} else if (RemotePhyAd &
4259 					   PHY_LINK_PARTNER_ASYM_PAUSE) {
4260 					FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
4261 				}
4262 			} else {
4263 				if (RemotePhyAd &
4264 				    PHY_LINK_PARTNER_PAUSE_CAPABLE) {
4265 					FlowCap =
4266 					    LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4267 					    LM_FLOW_CONTROL_RECEIVE_PAUSE;
4268 				}
4269 			}
4270 		} else if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
4271 			if ((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
4272 			    (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)) {
4273 				FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4274 			}
4275 		}
4276 	} else {
4277 		FlowCap = pDevice->FlowControlCap;
4278 	}
4279 
4280 	/* Enable/disable rx PAUSE. */
4281 	pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
4282 	if (FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
4283 	    (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4284 	     pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)) {
4285 		pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
4286 		pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
4287 
4288 	}
4289 	REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
4290 
4291 	/* Enable/disable tx PAUSE. */
4292 	pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
4293 	if (FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
4294 	    (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4295 	     pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
4296 		pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4297 		pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
4298 
4299 	}
4300 	REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
4301 
4302 	return LM_STATUS_SUCCESS;
4303 }
4304 
4305 #if INCLUDE_TBI_SUPPORT
4306 /******************************************************************************/
4307 /* Description:                                                               */
4308 /*                                                                            */
4309 /* Return:                                                                    */
4310 /******************************************************************************/
LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice)4311 STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice)
4312 {
4313 	LM_UINT32 Value32;
4314 	LM_UINT32 j;
4315 
4316 	Value32 = REG_RD (pDevice, MacCtrl.Status);
4317 
4318 	/* Reset the SERDES during init and when we have link. */
4319 	if (!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED) {
4320 		/* Set PLL lock range. */
4321 		LM_WritePhy (pDevice, 0x16, 0x8007);
4322 
4323 		/* Software reset. */
4324 		LM_WritePhy (pDevice, 0x00, 0x8000);
4325 
4326 		/* Wait for reset to complete. */
4327 		for (j = 0; j < 500; j++) {
4328 			MM_Wait (10);
4329 		}
4330 
4331 		/* Config mode; seletct PMA/Ch 1 regs. */
4332 		LM_WritePhy (pDevice, 0x10, 0x8411);
4333 
4334 		/* Enable auto-lock and comdet, select txclk for tx. */
4335 		LM_WritePhy (pDevice, 0x11, 0x0a10);
4336 
4337 		LM_WritePhy (pDevice, 0x18, 0x00a0);
4338 		LM_WritePhy (pDevice, 0x16, 0x41ff);
4339 
4340 		/* Assert and deassert POR. */
4341 		LM_WritePhy (pDevice, 0x13, 0x0400);
4342 		MM_Wait (40);
4343 		LM_WritePhy (pDevice, 0x13, 0x0000);
4344 
4345 		LM_WritePhy (pDevice, 0x11, 0x0a50);
4346 		MM_Wait (40);
4347 		LM_WritePhy (pDevice, 0x11, 0x0a10);
4348 
4349 		/* Delay for signal to stabilize. */
4350 		for (j = 0; j < 15000; j++) {
4351 			MM_Wait (10);
4352 		}
4353 
4354 		/* Deselect the channel register so we can read the PHY id later. */
4355 		LM_WritePhy (pDevice, 0x10, 0x8011);
4356 	}
4357 
4358 	return LM_STATUS_SUCCESS;
4359 }
4360 
4361 /******************************************************************************/
4362 /* Description:                                                               */
4363 /*                                                                            */
4364 /* Return:                                                                    */
4365 /******************************************************************************/
LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice)4366 STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice)
4367 {
4368 	LM_STATUS CurrentLinkStatus;
4369 	AUTONEG_STATUS AnStatus = 0;
4370 	LM_UINT32 Value32;
4371 	LM_UINT32 Cnt;
4372 	LM_UINT32 j, k;
4373 
4374 	pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
4375 
4376 	/* Initialize the send_config register. */
4377 	REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
4378 
4379 	/* Enable TBI and full duplex mode. */
4380 	pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
4381 	REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4382 
4383 	/* Initialize the BCM8002 SERDES PHY. */
4384 	switch (pDevice->PhyId & PHY_ID_MASK) {
4385 	case PHY_BCM8002_PHY_ID:
4386 		LM_InitBcm800xPhy (pDevice);
4387 		break;
4388 
4389 	default:
4390 		break;
4391 	}
4392 
4393 	/* Enable link change interrupt. */
4394 	REG_WR (pDevice, MacCtrl.MacEvent,
4395 		MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4396 
4397 	/* Default to link down. */
4398 	CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4399 
4400 	/* Get the link status. */
4401 	Value32 = REG_RD (pDevice, MacCtrl.Status);
4402 	if (Value32 & MAC_STATUS_PCS_SYNCED) {
4403 		if ((pDevice->RequestedMediaType ==
4404 		     LM_REQUESTED_MEDIA_TYPE_AUTO)
4405 		    || (pDevice->DisableAutoNeg == FALSE)) {
4406 			/* auto-negotiation mode. */
4407 			/* Initialize the autoneg default capaiblities. */
4408 			AutonegInit (&pDevice->AnInfo);
4409 
4410 			/* Set the context pointer to point to the main device structure. */
4411 			pDevice->AnInfo.pContext = pDevice;
4412 
4413 			/* Setup flow control advertisement register. */
4414 			Value32 = GetPhyAdFlowCntrlSettings (pDevice);
4415 			if (Value32 & PHY_AN_AD_PAUSE_CAPABLE) {
4416 				pDevice->AnInfo.mr_adv_sym_pause = 1;
4417 			} else {
4418 				pDevice->AnInfo.mr_adv_sym_pause = 0;
4419 			}
4420 
4421 			if (Value32 & PHY_AN_AD_ASYM_PAUSE) {
4422 				pDevice->AnInfo.mr_adv_asym_pause = 1;
4423 			} else {
4424 				pDevice->AnInfo.mr_adv_asym_pause = 0;
4425 			}
4426 
4427 			/* Try to autoneg up to six times. */
4428 			if (pDevice->IgnoreTbiLinkChange) {
4429 				Cnt = 1;
4430 			} else {
4431 				Cnt = 6;
4432 			}
4433 			for (j = 0; j < Cnt; j++) {
4434 				REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
4435 
4436 				Value32 =
4437 				    pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
4438 				REG_WR (pDevice, MacCtrl.Mode, Value32);
4439 				MM_Wait (20);
4440 
4441 				REG_WR (pDevice, MacCtrl.Mode,
4442 					pDevice->
4443 					MacMode | MAC_MODE_SEND_CONFIGS);
4444 
4445 				MM_Wait (20);
4446 
4447 				pDevice->AnInfo.State = AN_STATE_UNKNOWN;
4448 				pDevice->AnInfo.CurrentTime_us = 0;
4449 
4450 				REG_WR (pDevice, Grc.Timer, 0);
4451 				for (k = 0;
4452 				     (pDevice->AnInfo.CurrentTime_us < 75000)
4453 				     && (k < 75000); k++) {
4454 					AnStatus =
4455 					    Autoneg8023z (&pDevice->AnInfo);
4456 
4457 					if ((AnStatus == AUTONEG_STATUS_DONE) ||
4458 					    (AnStatus == AUTONEG_STATUS_FAILED))
4459 					{
4460 						break;
4461 					}
4462 
4463 					pDevice->AnInfo.CurrentTime_us =
4464 					    REG_RD (pDevice, Grc.Timer);
4465 
4466 				}
4467 				if ((AnStatus == AUTONEG_STATUS_DONE) ||
4468 				    (AnStatus == AUTONEG_STATUS_FAILED)) {
4469 					break;
4470 				}
4471 				if (j >= 1) {
4472 					if (!(REG_RD (pDevice, MacCtrl.Status) &
4473 					      MAC_STATUS_PCS_SYNCED)) {
4474 						break;
4475 					}
4476 				}
4477 			}
4478 
4479 			/* Stop sending configs. */
4480 			MM_AnTxIdle (&pDevice->AnInfo);
4481 
4482 			/* Resolve flow control settings. */
4483 			if ((AnStatus == AUTONEG_STATUS_DONE) &&
4484 			    pDevice->AnInfo.mr_an_complete
4485 			    && pDevice->AnInfo.mr_link_ok
4486 			    && pDevice->AnInfo.mr_lp_adv_full_duplex) {
4487 				LM_UINT32 RemotePhyAd;
4488 				LM_UINT32 LocalPhyAd;
4489 
4490 				LocalPhyAd = 0;
4491 				if (pDevice->AnInfo.mr_adv_sym_pause) {
4492 					LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
4493 				}
4494 
4495 				if (pDevice->AnInfo.mr_adv_asym_pause) {
4496 					LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
4497 				}
4498 
4499 				RemotePhyAd = 0;
4500 				if (pDevice->AnInfo.mr_lp_adv_sym_pause) {
4501 					RemotePhyAd |=
4502 					    PHY_LINK_PARTNER_PAUSE_CAPABLE;
4503 				}
4504 
4505 				if (pDevice->AnInfo.mr_lp_adv_asym_pause) {
4506 					RemotePhyAd |=
4507 					    PHY_LINK_PARTNER_ASYM_PAUSE;
4508 				}
4509 
4510 				LM_SetFlowControl (pDevice, LocalPhyAd,
4511 						   RemotePhyAd);
4512 
4513 				CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4514 			}
4515 			for (j = 0; j < 30; j++) {
4516 				MM_Wait (20);
4517 				REG_WR (pDevice, MacCtrl.Status,
4518 					MAC_STATUS_SYNC_CHANGED |
4519 					MAC_STATUS_CFG_CHANGED);
4520 				MM_Wait (20);
4521 				if ((REG_RD (pDevice, MacCtrl.Status) &
4522 				     (MAC_STATUS_SYNC_CHANGED |
4523 				      MAC_STATUS_CFG_CHANGED)) == 0)
4524 					break;
4525 			}
4526 			if (pDevice->PollTbiLink) {
4527 				Value32 = REG_RD (pDevice, MacCtrl.Status);
4528 				if (Value32 & MAC_STATUS_RECEIVING_CFG) {
4529 					pDevice->IgnoreTbiLinkChange = TRUE;
4530 				} else {
4531 					pDevice->IgnoreTbiLinkChange = FALSE;
4532 				}
4533 			}
4534 			Value32 = REG_RD (pDevice, MacCtrl.Status);
4535 			if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
4536 			    (Value32 & MAC_STATUS_PCS_SYNCED) &&
4537 			    ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0)) {
4538 				CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4539 			}
4540 		} else {
4541 			/* We are forcing line speed. */
4542 			pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
4543 			LM_SetFlowControl (pDevice, 0, 0);
4544 
4545 			CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4546 			REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
4547 				MAC_MODE_SEND_CONFIGS);
4548 		}
4549 	}
4550 	/* Set the link polarity bit. */
4551 	pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4552 	REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4553 
4554 	pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4555 	    (pDevice->pStatusBlkVirt->
4556 	     Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4557 
4558 	for (j = 0; j < 100; j++) {
4559 		REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4560 			MAC_STATUS_CFG_CHANGED);
4561 		MM_Wait (5);
4562 		if ((REG_RD (pDevice, MacCtrl.Status) &
4563 		     (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4564 			break;
4565 	}
4566 
4567 	Value32 = REG_RD (pDevice, MacCtrl.Status);
4568 	if ((Value32 & MAC_STATUS_PCS_SYNCED) == 0) {
4569 		CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4570 		if (pDevice->DisableAutoNeg == FALSE) {
4571 			REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
4572 				MAC_MODE_SEND_CONFIGS);
4573 			MM_Wait (1);
4574 			REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4575 		}
4576 	}
4577 
4578 	/* Initialize the current link status. */
4579 	if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4580 		pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
4581 		pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
4582 		REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4583 			LED_CTRL_1000MBPS_LED_ON);
4584 	} else {
4585 		pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
4586 		pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4587 		REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4588 			LED_CTRL_OVERRIDE_TRAFFIC_LED);
4589 	}
4590 
4591 	/* Indicate link status. */
4592 	if (pDevice->LinkStatus != CurrentLinkStatus) {
4593 		pDevice->LinkStatus = CurrentLinkStatus;
4594 		MM_IndicateStatus (pDevice, CurrentLinkStatus);
4595 	}
4596 
4597 	return LM_STATUS_SUCCESS;
4598 }
4599 #endif				/* INCLUDE_TBI_SUPPORT */
4600 
4601 /******************************************************************************/
4602 /* Description:                                                               */
4603 /*                                                                            */
4604 /* Return:                                                                    */
4605 /******************************************************************************/
LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice)4606 LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice)
4607 {
4608 	LM_STATUS CurrentLinkStatus;
4609 	LM_UINT32 Value32;
4610 
4611 	/* Assume there is not link first. */
4612 	CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4613 
4614 	/* Disable phy link change attention. */
4615 	REG_WR (pDevice, MacCtrl.MacEvent, 0);
4616 
4617 	/* Clear link change attention. */
4618 	REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4619 		MAC_STATUS_CFG_CHANGED);
4620 
4621 	/* Disable auto-polling for the moment. */
4622 	pDevice->MiMode = 0xc0000;
4623 	REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4624 	MM_Wait (40);
4625 
4626 	/* Determine the requested line speed and duplex. */
4627 	pDevice->OldLineSpeed = pDevice->LineSpeed;
4628 	LM_TranslateRequestedMediaType (pDevice->RequestedMediaType,
4629 					&pDevice->MediaType,
4630 					&pDevice->LineSpeed,
4631 					&pDevice->DuplexMode);
4632 
4633 	/* Initialize the phy chip. */
4634 	switch (pDevice->PhyId & PHY_ID_MASK) {
4635 	case PHY_BCM5400_PHY_ID:
4636 	case PHY_BCM5401_PHY_ID:
4637 	case PHY_BCM5411_PHY_ID:
4638 	case PHY_BCM5701_PHY_ID:
4639 	case PHY_BCM5703_PHY_ID:
4640 	case PHY_BCM5704_PHY_ID:
4641 		CurrentLinkStatus = LM_InitBcm540xPhy (pDevice);
4642 		break;
4643 
4644 	default:
4645 		break;
4646 	}
4647 
4648 	if (CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH) {
4649 		CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4650 	}
4651 
4652 	/* Setup flow control. */
4653 	pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
4654 	if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4655 		LM_FLOW_CONTROL FlowCap;	/* Flow control capability. */
4656 
4657 		FlowCap = LM_FLOW_CONTROL_NONE;
4658 
4659 		if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
4660 			if (pDevice->DisableAutoNeg == FALSE ||
4661 			    pDevice->RequestedMediaType ==
4662 			    LM_REQUESTED_MEDIA_TYPE_AUTO
4663 			    || pDevice->RequestedMediaType ==
4664 			    LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
4665 				LM_UINT32 ExpectedPhyAd;
4666 				LM_UINT32 LocalPhyAd;
4667 				LM_UINT32 RemotePhyAd;
4668 
4669 				LM_ReadPhy (pDevice, PHY_AN_AD_REG,
4670 					    &LocalPhyAd);
4671 				pDevice->advertising = LocalPhyAd;
4672 				LocalPhyAd &=
4673 				    (PHY_AN_AD_ASYM_PAUSE |
4674 				     PHY_AN_AD_PAUSE_CAPABLE);
4675 
4676 				ExpectedPhyAd =
4677 				    GetPhyAdFlowCntrlSettings (pDevice);
4678 
4679 				if (LocalPhyAd != ExpectedPhyAd) {
4680 					CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4681 				} else {
4682 					LM_ReadPhy (pDevice,
4683 						    PHY_LINK_PARTNER_ABILITY_REG,
4684 						    &RemotePhyAd);
4685 
4686 					LM_SetFlowControl (pDevice, LocalPhyAd,
4687 							   RemotePhyAd);
4688 				}
4689 			} else {
4690 				pDevice->FlowControlCap &=
4691 				    ~LM_FLOW_CONTROL_AUTO_PAUSE;
4692 				LM_SetFlowControl (pDevice, 0, 0);
4693 			}
4694 		}
4695 	}
4696 
4697 	if (CurrentLinkStatus == LM_STATUS_LINK_DOWN) {
4698 		LM_ForceAutoNeg (pDevice, pDevice->RequestedMediaType);
4699 
4700 		/* If we force line speed, we make get link right away. */
4701 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4702 		LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4703 		if (Value32 & PHY_STATUS_LINK_PASS) {
4704 			CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4705 		}
4706 	}
4707 
4708 	/* GMII interface. */
4709 	pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
4710 	if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4711 		if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
4712 		    pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
4713 			pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
4714 		} else {
4715 			pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
4716 		}
4717 	} else {
4718 		pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
4719 	}
4720 
4721 	/* Set the MAC to operate in the appropriate duplex mode. */
4722 	pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
4723 	if (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF) {
4724 		pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
4725 	}
4726 
4727 	/* Set the link polarity bit. */
4728 	pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4729 	if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
4730 		if ((pDevice->LedMode == LED_MODE_LINK10) ||
4731 		    (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
4732 		     pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)) {
4733 			pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
4734 		}
4735 	} else {
4736 		if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4737 			pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
4738 		}
4739 
4740 		/* Set LED mode. */
4741 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
4742 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
4743 			Value32 = LED_CTRL_PHY_MODE_1;
4744 		} else {
4745 			if (pDevice->LedMode == LED_MODE_OUTPUT) {
4746 				Value32 = LED_CTRL_PHY_MODE_2;
4747 			} else {
4748 				Value32 = LED_CTRL_PHY_MODE_1;
4749 			}
4750 		}
4751 		REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
4752 	}
4753 
4754 	REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4755 
4756 	/* Enable auto polling. */
4757 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4758 		pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
4759 		REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4760 	}
4761 
4762 	/* Enable phy link change attention. */
4763 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
4764 		REG_WR (pDevice, MacCtrl.MacEvent,
4765 			MAC_EVENT_ENABLE_MI_INTERRUPT);
4766 	} else {
4767 		REG_WR (pDevice, MacCtrl.MacEvent,
4768 			MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4769 	}
4770 	if ((T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
4771 	    (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
4772 	    (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
4773 	    (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
4774 	      (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
4775 	     !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))) {
4776 		MM_Wait (120);
4777 		REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4778 			MAC_STATUS_CFG_CHANGED);
4779 		MEM_WR_OFFSET (pDevice, T3_FIRMWARE_MAILBOX,
4780 			       T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
4781 	}
4782 
4783 	/* Indicate link status. */
4784 	if (pDevice->LinkStatus != CurrentLinkStatus) {
4785 		pDevice->LinkStatus = CurrentLinkStatus;
4786 		MM_IndicateStatus (pDevice, CurrentLinkStatus);
4787 	}
4788 
4789 	return LM_STATUS_SUCCESS;
4790 }				/* LM_SetupCopperPhy */
4791 
4792 /******************************************************************************/
4793 /* Description:                                                               */
4794 /*                                                                            */
4795 /* Return:                                                                    */
4796 /******************************************************************************/
LM_SetupPhy(PLM_DEVICE_BLOCK pDevice)4797 LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice)
4798 {
4799 	LM_STATUS LmStatus;
4800 	LM_UINT32 Value32;
4801 
4802 #if INCLUDE_TBI_SUPPORT
4803 	if (pDevice->EnableTbi) {
4804 		LmStatus = LM_SetupFiberPhy (pDevice);
4805 	} else
4806 #endif				/* INCLUDE_TBI_SUPPORT */
4807 	{
4808 		LmStatus = LM_SetupCopperPhy (pDevice);
4809 	}
4810 	if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
4811 		if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
4812 			Value32 = REG_RD (pDevice, PciCfg.PciState);
4813 			REG_WR (pDevice, PciCfg.PciState,
4814 				Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
4815 		}
4816 	}
4817 	if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
4818 	    (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)) {
4819 		REG_WR (pDevice, MacCtrl.TxLengths, 0x26ff);
4820 	} else {
4821 		REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
4822 	}
4823 
4824 	return LmStatus;
4825 }
4826 
4827 /******************************************************************************/
4828 /* Description:                                                               */
4829 /*                                                                            */
4830 /* Return:                                                                    */
4831 /******************************************************************************/
4832 LM_VOID
LM_ReadPhy(PLM_DEVICE_BLOCK pDevice,LM_UINT32 PhyReg,PLM_UINT32 pData32)4833 LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, PLM_UINT32 pData32)
4834 {
4835 	LM_UINT32 Value32;
4836 	LM_UINT32 j;
4837 
4838 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4839 		REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
4840 			~MI_MODE_AUTO_POLLING_ENABLE);
4841 		MM_Wait (40);
4842 	}
4843 
4844 	Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
4845 	    ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
4846 	     MI_COM_FIRST_PHY_REG_ADDR_BIT) | MI_COM_CMD_READ | MI_COM_START;
4847 
4848 	REG_WR (pDevice, MacCtrl.MiCom, Value32);
4849 
4850 	for (j = 0; j < 20; j++) {
4851 		MM_Wait (25);
4852 
4853 		Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4854 
4855 		if (!(Value32 & MI_COM_BUSY)) {
4856 			MM_Wait (5);
4857 			Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4858 			Value32 &= MI_COM_PHY_DATA_MASK;
4859 			break;
4860 		}
4861 	}
4862 
4863 	if (Value32 & MI_COM_BUSY) {
4864 		Value32 = 0;
4865 	}
4866 
4867 	*pData32 = Value32;
4868 
4869 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4870 		REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4871 		MM_Wait (40);
4872 	}
4873 }				/* LM_ReadPhy */
4874 
4875 /******************************************************************************/
4876 /* Description:                                                               */
4877 /*                                                                            */
4878 /* Return:                                                                    */
4879 /******************************************************************************/
4880 LM_VOID
LM_WritePhy(PLM_DEVICE_BLOCK pDevice,LM_UINT32 PhyReg,LM_UINT32 Data32)4881 LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, LM_UINT32 Data32)
4882 {
4883 	LM_UINT32 Value32;
4884 	LM_UINT32 j;
4885 
4886 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4887 		REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
4888 			~MI_MODE_AUTO_POLLING_ENABLE);
4889 		MM_Wait (40);
4890 	}
4891 
4892 	Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
4893 	    ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
4894 	     MI_COM_FIRST_PHY_REG_ADDR_BIT) | (Data32 & MI_COM_PHY_DATA_MASK) |
4895 	    MI_COM_CMD_WRITE | MI_COM_START;
4896 
4897 	REG_WR (pDevice, MacCtrl.MiCom, Value32);
4898 
4899 	for (j = 0; j < 20; j++) {
4900 		MM_Wait (25);
4901 
4902 		Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4903 
4904 		if (!(Value32 & MI_COM_BUSY)) {
4905 			MM_Wait (5);
4906 			break;
4907 		}
4908 	}
4909 
4910 	if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4911 		REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4912 		MM_Wait (40);
4913 	}
4914 }				/* LM_WritePhy */
4915 
4916 /******************************************************************************/
4917 /* Description:                                                               */
4918 /*                                                                            */
4919 /* Return:                                                                    */
4920 /******************************************************************************/
LM_SetPowerState(PLM_DEVICE_BLOCK pDevice,LM_POWER_STATE PowerLevel)4921 LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel)
4922 {
4923 	LM_UINT32 PmeSupport;
4924 	LM_UINT32 Value32;
4925 	LM_UINT32 PmCtrl;
4926 
4927 	/* make sureindirect accesses are enabled */
4928 	MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
4929 			  pDevice->MiscHostCtrl);
4930 
4931 	/* Clear the PME_ASSERT bit and the power state bits.  Also enable */
4932 	/* the PME bit. */
4933 	MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
4934 
4935 	PmCtrl |= T3_PM_PME_ASSERTED;
4936 	PmCtrl &= ~T3_PM_POWER_STATE_MASK;
4937 
4938 	/* Set the appropriate power state. */
4939 	if (PowerLevel == LM_POWER_STATE_D0) {
4940 
4941 		/* Bring the card out of low power mode. */
4942 		PmCtrl |= T3_PM_POWER_STATE_D0;
4943 		MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
4944 
4945 		REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
4946 		MM_Wait (40);
4947 #if 0				/* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
4948 		LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x02);
4949 #endif
4950 
4951 		return LM_STATUS_SUCCESS;
4952 	} else if (PowerLevel == LM_POWER_STATE_D1) {
4953 		PmCtrl |= T3_PM_POWER_STATE_D1;
4954 	} else if (PowerLevel == LM_POWER_STATE_D2) {
4955 		PmCtrl |= T3_PM_POWER_STATE_D2;
4956 	} else if (PowerLevel == LM_POWER_STATE_D3) {
4957 		PmCtrl |= T3_PM_POWER_STATE_D3;
4958 	} else {
4959 		return LM_STATUS_FAILURE;
4960 	}
4961 	PmCtrl |= T3_PM_PME_ENABLE;
4962 
4963 	/* Mask out all interrupts so LM_SetupPhy won't be called while we are */
4964 	/* setting new line speed. */
4965 	Value32 = REG_RD (pDevice, PciCfg.MiscHostCtrl);
4966 	REG_WR (pDevice, PciCfg.MiscHostCtrl,
4967 		Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
4968 
4969 	if (!pDevice->RestoreOnWakeUp) {
4970 		pDevice->RestoreOnWakeUp = TRUE;
4971 		pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
4972 		pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
4973 	}
4974 
4975 	/* Force auto-negotiation to 10 line speed. */
4976 	pDevice->DisableAutoNeg = FALSE;
4977 	pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
4978 	LM_SetupPhy (pDevice);
4979 
4980 	/* Put the driver in the initial state, and go through the power down */
4981 	/* sequence. */
4982 	LM_Halt (pDevice);
4983 
4984 	MM_ReadConfig32 (pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
4985 
4986 	if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) {
4987 
4988 		/* Enable WOL. */
4989 		LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x5a);
4990 		MM_Wait (40);
4991 
4992 		/* Set LED mode. */
4993 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
4994 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
4995 			Value32 = LED_CTRL_PHY_MODE_1;
4996 		} else {
4997 			if (pDevice->LedMode == LED_MODE_OUTPUT) {
4998 				Value32 = LED_CTRL_PHY_MODE_2;
4999 			} else {
5000 				Value32 = LED_CTRL_PHY_MODE_1;
5001 			}
5002 		}
5003 
5004 		Value32 = MAC_MODE_PORT_MODE_MII;
5005 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
5006 			if (pDevice->LedMode == LED_MODE_LINK10 ||
5007 			    pDevice->WolSpeed == WOL_SPEED_10MB) {
5008 				Value32 |= MAC_MODE_LINK_POLARITY;
5009 			}
5010 		} else {
5011 			Value32 |= MAC_MODE_LINK_POLARITY;
5012 		}
5013 		REG_WR (pDevice, MacCtrl.Mode, Value32);
5014 		MM_Wait (40);
5015 		MM_Wait (40);
5016 		MM_Wait (40);
5017 
5018 		/* Always enable magic packet wake-up if we have vaux. */
5019 		if ((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
5020 		    (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET)) {
5021 			Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
5022 		}
5023 
5024 		REG_WR (pDevice, MacCtrl.Mode, Value32);
5025 
5026 		/* Enable the receiver. */
5027 		REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
5028 	}
5029 
5030 	/* Disable tx/rx clocks, and seletect an alternate clock. */
5031 	if (pDevice->WolSpeed == WOL_SPEED_100MB) {
5032 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5033 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5034 			Value32 =
5035 			    T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5036 			    T3_PCI_SELECT_ALTERNATE_CLOCK;
5037 		} else {
5038 			Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
5039 		}
5040 		REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5041 
5042 		MM_Wait (40);
5043 
5044 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5045 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5046 			Value32 =
5047 			    T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5048 			    T3_PCI_SELECT_ALTERNATE_CLOCK |
5049 			    T3_PCI_44MHZ_CORE_CLOCK;
5050 		} else {
5051 			Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5052 			    T3_PCI_44MHZ_CORE_CLOCK;
5053 		}
5054 
5055 		REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5056 
5057 		MM_Wait (40);
5058 
5059 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5060 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5061 			Value32 =
5062 			    T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5063 			    T3_PCI_44MHZ_CORE_CLOCK;
5064 		} else {
5065 			Value32 = T3_PCI_44MHZ_CORE_CLOCK;
5066 		}
5067 
5068 		REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5069 	} else {
5070 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5071 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5072 			Value32 =
5073 			    T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5074 			    T3_PCI_SELECT_ALTERNATE_CLOCK |
5075 			    T3_PCI_POWER_DOWN_PCI_PLL133;
5076 		} else {
5077 			Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5078 			    T3_PCI_POWER_DOWN_PCI_PLL133;
5079 		}
5080 
5081 		REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5082 	}
5083 
5084 	MM_Wait (40);
5085 
5086 	if (!pDevice->EepromWp
5087 	    && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)) {
5088 		/* Switch adapter to auxilliary power. */
5089 		if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5090 		    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5091 			/* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5092 			REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5093 				GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5094 				GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5095 				GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5096 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5097 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5098 			MM_Wait (40);
5099 		} else {
5100 			/* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
5101 			REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5102 				GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5103 				GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5104 				GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5105 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5106 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5107 			MM_Wait (40);
5108 
5109 			/* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
5110 			REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5111 				GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5112 				GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5113 				GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5114 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5115 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5116 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5117 			MM_Wait (40);
5118 
5119 			/* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5120 			REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5121 				GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5122 				GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5123 				GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5124 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5125 				GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5126 			MM_Wait (40);
5127 		}
5128 	}
5129 
5130 	/* Set the phy to low power mode. */
5131 	/* Put the the hardware in low power mode. */
5132 	MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5133 
5134 	return LM_STATUS_SUCCESS;
5135 }				/* LM_SetPowerState */
5136 
5137 /******************************************************************************/
5138 /* Description:                                                               */
5139 /*                                                                            */
5140 /* Return:                                                                    */
5141 /******************************************************************************/
GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice)5142 static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice)
5143 {
5144 	LM_UINT32 Value32;
5145 
5146 	Value32 = 0;
5147 
5148 	/* Auto negotiation flow control only when autonegotiation is enabled. */
5149 	if (pDevice->DisableAutoNeg == FALSE ||
5150 	    pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5151 	    pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
5152 		/* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
5153 		if ((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
5154 		    ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
5155 		     && (pDevice->
5156 			 FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))) {
5157 			Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
5158 		} else if (pDevice->
5159 			   FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
5160 			Value32 |= PHY_AN_AD_ASYM_PAUSE;
5161 		} else if (pDevice->
5162 			   FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
5163 			Value32 |=
5164 			    PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
5165 		}
5166 	}
5167 
5168 	return Value32;
5169 }
5170 
5171 /******************************************************************************/
5172 /* Description:                                                               */
5173 /*                                                                            */
5174 /* Return:                                                                    */
5175 /*    LM_STATUS_FAILURE                                                       */
5176 /*    LM_STATUS_SUCCESS                                                       */
5177 /*                                                                            */
5178 /******************************************************************************/
5179 static LM_STATUS
LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,LM_REQUESTED_MEDIA_TYPE RequestedMediaType)5180 LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
5181 			   LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5182 {
5183 	LM_MEDIA_TYPE MediaType;
5184 	LM_LINE_SPEED LineSpeed;
5185 	LM_DUPLEX_MODE DuplexMode;
5186 	LM_UINT32 NewPhyCtrl;
5187 	LM_UINT32 Value32;
5188 	LM_UINT32 Cnt;
5189 
5190 	/* Get the interface type, line speed, and duplex mode. */
5191 	LM_TranslateRequestedMediaType (RequestedMediaType, &MediaType,
5192 					&LineSpeed, &DuplexMode);
5193 
5194 	if (pDevice->RestoreOnWakeUp) {
5195 		LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5196 		pDevice->advertising1000 = 0;
5197 		Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
5198 		if (pDevice->WolSpeed == WOL_SPEED_100MB) {
5199 			Value32 |=
5200 			    PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5201 		}
5202 		Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5203 		Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5204 		LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5205 		pDevice->advertising = Value32;
5206 	}
5207 	/* Setup the auto-negotiation advertisement register. */
5208 	else if (LineSpeed == LM_LINE_SPEED_UNKNOWN) {
5209 		/* Setup the 10/100 Mbps auto-negotiation advertisement register. */
5210 		Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
5211 		    PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
5212 		    PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5213 		Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5214 
5215 		LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5216 		pDevice->advertising = Value32;
5217 
5218 		/* Advertise 1000Mbps */
5219 		Value32 =
5220 		    BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
5221 
5222 #if INCLUDE_5701_AX_FIX
5223 		/* Bug: workaround for CRC error in gigabit mode when we are in */
5224 		/* slave mode.  This will force the PHY to operate in */
5225 		/* master mode. */
5226 		if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5227 		    pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
5228 			Value32 |= BCM540X_CONFIG_AS_MASTER |
5229 			    BCM540X_ENABLE_CONFIG_AS_MASTER;
5230 		}
5231 #endif
5232 
5233 		LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5234 		pDevice->advertising1000 = Value32;
5235 	} else {
5236 		if (LineSpeed == LM_LINE_SPEED_1000MBPS) {
5237 			Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5238 			Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5239 
5240 			LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5241 			pDevice->advertising = Value32;
5242 
5243 			if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5244 				Value32 = BCM540X_AN_AD_1000BASET_HALF;
5245 			} else {
5246 				Value32 = BCM540X_AN_AD_1000BASET_FULL;
5247 			}
5248 
5249 			LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG,
5250 				     Value32);
5251 			pDevice->advertising1000 = Value32;
5252 		} else if (LineSpeed == LM_LINE_SPEED_100MBPS) {
5253 			LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5254 			pDevice->advertising1000 = 0;
5255 
5256 			if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5257 				Value32 = PHY_AN_AD_100BASETX_HALF;
5258 			} else {
5259 				Value32 = PHY_AN_AD_100BASETX_FULL;
5260 			}
5261 
5262 			Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5263 			Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5264 
5265 			LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5266 			pDevice->advertising = Value32;
5267 		} else if (LineSpeed == LM_LINE_SPEED_10MBPS) {
5268 			LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5269 			pDevice->advertising1000 = 0;
5270 
5271 			if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5272 				Value32 = PHY_AN_AD_10BASET_HALF;
5273 			} else {
5274 				Value32 = PHY_AN_AD_10BASET_FULL;
5275 			}
5276 
5277 			Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5278 			Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5279 
5280 			LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5281 			pDevice->advertising = Value32;
5282 		}
5283 	}
5284 
5285 	/* Force line speed if auto-negotiation is disabled. */
5286 	if (pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN) {
5287 		/* This code path is executed only when there is link. */
5288 		pDevice->MediaType = MediaType;
5289 		pDevice->LineSpeed = LineSpeed;
5290 		pDevice->DuplexMode = DuplexMode;
5291 
5292 		/* Force line seepd. */
5293 		NewPhyCtrl = 0;
5294 		switch (LineSpeed) {
5295 		case LM_LINE_SPEED_10MBPS:
5296 			NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
5297 			break;
5298 		case LM_LINE_SPEED_100MBPS:
5299 			NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
5300 			break;
5301 		case LM_LINE_SPEED_1000MBPS:
5302 			NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5303 			break;
5304 		default:
5305 			NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5306 			break;
5307 		}
5308 
5309 		if (DuplexMode == LM_DUPLEX_MODE_FULL) {
5310 			NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
5311 		}
5312 
5313 		/* Don't do anything if the PHY_CTRL is already what we wanted. */
5314 		LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
5315 		if (Value32 != NewPhyCtrl) {
5316 			/* Temporary bring the link down before forcing line speed. */
5317 			LM_WritePhy (pDevice, PHY_CTRL_REG,
5318 				     PHY_CTRL_LOOPBACK_MODE);
5319 
5320 			/* Wait for link to go down. */
5321 			for (Cnt = 0; Cnt < 15000; Cnt++) {
5322 				MM_Wait (10);
5323 
5324 				LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
5325 				LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
5326 
5327 				if (!(Value32 & PHY_STATUS_LINK_PASS)) {
5328 					MM_Wait (40);
5329 					break;
5330 				}
5331 			}
5332 
5333 			LM_WritePhy (pDevice, PHY_CTRL_REG, NewPhyCtrl);
5334 			MM_Wait (40);
5335 		}
5336 	} else {
5337 		LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
5338 			     PHY_CTRL_RESTART_AUTO_NEG);
5339 	}
5340 
5341 	return LM_STATUS_SUCCESS;
5342 }				/* LM_ForceAutoNegBcm540xPhy */
5343 
5344 /******************************************************************************/
5345 /* Description:                                                               */
5346 /*                                                                            */
5347 /* Return:                                                                    */
5348 /******************************************************************************/
5349 static LM_STATUS
LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,LM_REQUESTED_MEDIA_TYPE RequestedMediaType)5350 LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
5351 		 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5352 {
5353 	LM_STATUS LmStatus;
5354 
5355 	/* Initialize the phy chip. */
5356 	switch (pDevice->PhyId & PHY_ID_MASK) {
5357 	case PHY_BCM5400_PHY_ID:
5358 	case PHY_BCM5401_PHY_ID:
5359 	case PHY_BCM5411_PHY_ID:
5360 	case PHY_BCM5701_PHY_ID:
5361 	case PHY_BCM5703_PHY_ID:
5362 	case PHY_BCM5704_PHY_ID:
5363 		LmStatus =
5364 		    LM_ForceAutoNegBcm540xPhy (pDevice, RequestedMediaType);
5365 		break;
5366 
5367 	default:
5368 		LmStatus = LM_STATUS_FAILURE;
5369 		break;
5370 	}
5371 
5372 	return LmStatus;
5373 }				/* LM_ForceAutoNeg */
5374 
5375 /******************************************************************************/
5376 /* Description:                                                               */
5377 /*                                                                            */
5378 /* Return:                                                                    */
5379 /******************************************************************************/
LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,PT3_FWIMG_INFO pFwImg,LM_UINT32 LoadCpu,LM_UINT32 StartCpu)5380 LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
5381 			   PT3_FWIMG_INFO pFwImg,
5382 			   LM_UINT32 LoadCpu, LM_UINT32 StartCpu)
5383 {
5384 	LM_UINT32 i;
5385 	LM_UINT32 address;
5386 
5387 	if (LoadCpu & T3_RX_CPU_ID) {
5388 		if (LM_HaltCpu (pDevice, T3_RX_CPU_ID) != LM_STATUS_SUCCESS) {
5389 			return LM_STATUS_FAILURE;
5390 		}
5391 
5392 		/* First of all clear scrach pad memory */
5393 		for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i += 4) {
5394 			LM_RegWrInd (pDevice, T3_RX_CPU_SPAD_ADDR + i, 0);
5395 		}
5396 
5397 		/* Copy code first */
5398 		address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5399 		for (i = 0; i <= pFwImg->Text.Length; i += 4) {
5400 			LM_RegWrInd (pDevice, address + i,
5401 				     ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
5402 									 4]);
5403 		}
5404 
5405 		address =
5406 		    T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5407 		for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
5408 			LM_RegWrInd (pDevice, address + i,
5409 				     ((LM_UINT32 *) pFwImg->ROnlyData.
5410 				      Buffer)[i / 4]);
5411 		}
5412 
5413 		address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5414 		for (i = 0; i <= pFwImg->Data.Length; i += 4) {
5415 			LM_RegWrInd (pDevice, address + i,
5416 				     ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
5417 									 4]);
5418 		}
5419 	}
5420 
5421 	if (LoadCpu & T3_TX_CPU_ID) {
5422 		if (LM_HaltCpu (pDevice, T3_TX_CPU_ID) != LM_STATUS_SUCCESS) {
5423 			return LM_STATUS_FAILURE;
5424 		}
5425 
5426 		/* First of all clear scrach pad memory */
5427 		for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i += 4) {
5428 			LM_RegWrInd (pDevice, T3_TX_CPU_SPAD_ADDR + i, 0);
5429 		}
5430 
5431 		/* Copy code first */
5432 		address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5433 		for (i = 0; i <= pFwImg->Text.Length; i += 4) {
5434 			LM_RegWrInd (pDevice, address + i,
5435 				     ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
5436 									 4]);
5437 		}
5438 
5439 		address =
5440 		    T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5441 		for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
5442 			LM_RegWrInd (pDevice, address + i,
5443 				     ((LM_UINT32 *) pFwImg->ROnlyData.
5444 				      Buffer)[i / 4]);
5445 		}
5446 
5447 		address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5448 		for (i = 0; i <= pFwImg->Data.Length; i += 4) {
5449 			LM_RegWrInd (pDevice, address + i,
5450 				     ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
5451 									 4]);
5452 		}
5453 	}
5454 
5455 	if (StartCpu & T3_RX_CPU_ID) {
5456 		/* Start Rx CPU */
5457 		REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5458 		REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
5459 		for (i = 0; i < 5; i++) {
5460 			if (pFwImg->StartAddress ==
5461 			    REG_RD (pDevice, rxCpu.reg.PC))
5462 				break;
5463 
5464 			REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5465 			REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5466 			REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
5467 			MM_Wait (1000);
5468 		}
5469 
5470 		REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5471 		REG_WR (pDevice, rxCpu.reg.mode, 0);
5472 	}
5473 
5474 	if (StartCpu & T3_TX_CPU_ID) {
5475 		/* Start Tx CPU */
5476 		REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5477 		REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
5478 		for (i = 0; i < 5; i++) {
5479 			if (pFwImg->StartAddress ==
5480 			    REG_RD (pDevice, txCpu.reg.PC))
5481 				break;
5482 
5483 			REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5484 			REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
5485 			REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
5486 			MM_Wait (1000);
5487 		}
5488 
5489 		REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5490 		REG_WR (pDevice, txCpu.reg.mode, 0);
5491 	}
5492 
5493 	return LM_STATUS_SUCCESS;
5494 }
5495 
LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)5496 STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number)
5497 {
5498 	LM_UINT32 i;
5499 
5500 	if (cpu_number == T3_RX_CPU_ID) {
5501 		for (i = 0; i < 10000; i++) {
5502 			REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5503 			REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5504 
5505 			if (REG_RD (pDevice, rxCpu.reg.mode) & CPU_MODE_HALT)
5506 				break;
5507 		}
5508 
5509 		REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5510 		REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5511 		MM_Wait (10);
5512 	} else {
5513 		for (i = 0; i < 10000; i++) {
5514 			REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5515 			REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
5516 
5517 			if (REG_RD (pDevice, txCpu.reg.mode) & CPU_MODE_HALT)
5518 				break;
5519 		}
5520 	}
5521 
5522 	return ((i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
5523 }
5524 
LM_BlinkLED(PLM_DEVICE_BLOCK pDevice,LM_UINT32 BlinkDurationSec)5525 int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
5526 {
5527 	LM_UINT32 Oldcfg;
5528 	int j;
5529 	int ret = 0;
5530 
5531 	if (BlinkDurationSec == 0) {
5532 		return 0;
5533 	}
5534 	if (BlinkDurationSec > 120) {
5535 		BlinkDurationSec = 120;
5536 	}
5537 
5538 	Oldcfg = REG_RD (pDevice, MacCtrl.LedCtrl);
5539 	for (j = 0; j < BlinkDurationSec * 2; j++) {
5540 		if (j % 2) {
5541 			/* Turn on the LEDs. */
5542 			REG_WR (pDevice, MacCtrl.LedCtrl,
5543 				LED_CTRL_OVERRIDE_LINK_LED |
5544 				LED_CTRL_1000MBPS_LED_ON |
5545 				LED_CTRL_100MBPS_LED_ON |
5546 				LED_CTRL_10MBPS_LED_ON |
5547 				LED_CTRL_OVERRIDE_TRAFFIC_LED |
5548 				LED_CTRL_BLINK_TRAFFIC_LED |
5549 				LED_CTRL_TRAFFIC_LED);
5550 		} else {
5551 			/* Turn off the LEDs. */
5552 			REG_WR (pDevice, MacCtrl.LedCtrl,
5553 				LED_CTRL_OVERRIDE_LINK_LED |
5554 				LED_CTRL_OVERRIDE_TRAFFIC_LED);
5555 		}
5556 
5557 #ifndef EMBEDDED
5558 		current->state = TASK_INTERRUPTIBLE;
5559 		if (schedule_timeout (HZ / 2) != 0) {
5560 			ret = -EINTR;
5561 			break;
5562 		}
5563 #else
5564 		udelay (100000);	/* 1s sleep */
5565 #endif
5566 	}
5567 	REG_WR (pDevice, MacCtrl.LedCtrl, Oldcfg);
5568 	return ret;
5569 }
5570 
t3_do_dma(PLM_DEVICE_BLOCK pDevice,LM_PHYSICAL_ADDRESS host_addr_phy,int length,int dma_read)5571 int t3_do_dma (PLM_DEVICE_BLOCK pDevice,
5572 	       LM_PHYSICAL_ADDRESS host_addr_phy, int length, int dma_read)
5573 {
5574 	T3_DMA_DESC dma_desc;
5575 	int i;
5576 	LM_UINT32 dma_desc_addr;
5577 	LM_UINT32 value32;
5578 
5579 	REG_WR (pDevice, BufMgr.Mode, 0);
5580 	REG_WR (pDevice, Ftq.Reset, 0);
5581 
5582 	dma_desc.host_addr.High = host_addr_phy.High;
5583 	dma_desc.host_addr.Low = host_addr_phy.Low;
5584 	dma_desc.nic_mbuf = 0x2100;
5585 	dma_desc.len = length;
5586 	dma_desc.flags = 0x00000004;	/* Generate Rx-CPU event */
5587 
5588 	if (dma_read) {
5589 		dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
5590 		    T3_QID_DMA_HIGH_PRI_READ;
5591 		REG_WR (pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
5592 	} else {
5593 		dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
5594 		    T3_QID_DMA_HIGH_PRI_WRITE;
5595 		REG_WR (pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
5596 	}
5597 
5598 	dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
5599 
5600 	/* Writing this DMA descriptor to DMA memory */
5601 	for (i = 0; i < sizeof (T3_DMA_DESC); i += 4) {
5602 		value32 = *((PLM_UINT32) (((PLM_UINT8) & dma_desc) + i));
5603 		MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG,
5604 				  dma_desc_addr + i);
5605 		MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG,
5606 				  cpu_to_le32 (value32));
5607 	}
5608 	MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
5609 
5610 	if (dma_read)
5611 		REG_WR (pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue,
5612 			dma_desc_addr);
5613 	else
5614 		REG_WR (pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue,
5615 			dma_desc_addr);
5616 
5617 	for (i = 0; i < 40; i++) {
5618 		if (dma_read)
5619 			value32 =
5620 			    REG_RD (pDevice,
5621 				    Ftq.RcvBdCompFtqFifoEnqueueDequeue);
5622 		else
5623 			value32 =
5624 			    REG_RD (pDevice,
5625 				    Ftq.RcvDataCompFtqFifoEnqueueDequeue);
5626 
5627 		if ((value32 & 0xffff) == dma_desc_addr)
5628 			break;
5629 
5630 		MM_Wait (10);
5631 	}
5632 
5633 	return LM_STATUS_SUCCESS;
5634 }
5635 
5636 STATIC LM_STATUS
LM_DmaTest(PLM_DEVICE_BLOCK pDevice,PLM_UINT8 pBufferVirt,LM_PHYSICAL_ADDRESS BufferPhy,LM_UINT32 BufferSize)5637 LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
5638 	    LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
5639 {
5640 	int j;
5641 	LM_UINT32 *ptr;
5642 	int dma_success = 0;
5643 
5644 	if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
5645 	    T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
5646 		return LM_STATUS_SUCCESS;
5647 	}
5648 	while (!dma_success) {
5649 		/* Fill data with incremental patterns */
5650 		ptr = (LM_UINT32 *) pBufferVirt;
5651 		for (j = 0; j < BufferSize / 4; j++)
5652 			*ptr++ = j;
5653 
5654 		if (t3_do_dma (pDevice, BufferPhy, BufferSize, 1) ==
5655 		    LM_STATUS_FAILURE) {
5656 			return LM_STATUS_FAILURE;
5657 		}
5658 
5659 		MM_Wait (40);
5660 		ptr = (LM_UINT32 *) pBufferVirt;
5661 		/* Fill data with zero */
5662 		for (j = 0; j < BufferSize / 4; j++)
5663 			*ptr++ = 0;
5664 
5665 		if (t3_do_dma (pDevice, BufferPhy, BufferSize, 0) ==
5666 		    LM_STATUS_FAILURE) {
5667 			return LM_STATUS_FAILURE;
5668 		}
5669 
5670 		MM_Wait (40);
5671 		/* Check for data */
5672 		ptr = (LM_UINT32 *) pBufferVirt;
5673 		for (j = 0; j < BufferSize / 4; j++) {
5674 			if (*ptr++ != j) {
5675 				if ((pDevice->
5676 				     DmaReadWriteCtrl &
5677 				     DMA_CTRL_WRITE_BOUNDARY_MASK)
5678 				    == DMA_CTRL_WRITE_BOUNDARY_DISABLE) {
5679 					pDevice->DmaReadWriteCtrl =
5680 					    (pDevice->
5681 					     DmaReadWriteCtrl &
5682 					     ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
5683 					    DMA_CTRL_WRITE_BOUNDARY_16;
5684 					REG_WR (pDevice,
5685 						PciCfg.DmaReadWriteCtrl,
5686 						pDevice->DmaReadWriteCtrl);
5687 					break;
5688 				} else {
5689 					return LM_STATUS_FAILURE;
5690 				}
5691 			}
5692 		}
5693 		if (j == (BufferSize / 4))
5694 			dma_success = 1;
5695 	}
5696 	return LM_STATUS_SUCCESS;
5697 }
5698