finally move buildroot-ng to trunk
[openwrt.git] / target / linux / ar7-2.4 / patches / 003-net_driver_cpmac.patch
1 diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c
2 --- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c      1970-01-01 01:00:00.000000000 +0100
3 +++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c      2005-07-12 02:48:41.996601000 +0200
4 @@ -0,0 +1,728 @@
5 +#ifndef _INC_CPCOMMON_C
6 +#define _INC_CPCOMMON_C
7 +
8 +#ifdef _CPHAL_CPMAC
9 +#include "cpremap_cpmac.c"
10 +#endif
11 +
12 +#ifdef _CPHAL_AAL5
13 +#include "cpremap_cpaal5.c"
14 +#endif
15 +
16 +#ifdef _CPHAL_CPSAR
17 +#include "cpremap_cpsar.c"
18 +#endif
19 +
20 +#ifdef _CPHAL_AAL2
21 +#include "cpremap_cpaal2.c"
22 +#endif
23 +
24 +/**
25 +@defgroup Common_Config_Params Common Configuration Parameters
26 +
27 +This section documents the configuration parameters that are valid across
28 +all CPHAL devices.
29 +@{
30 +*/
31 +/** This is the debug level.  The field is bit defined, such that the user
32 +should set to 1 all the bits corresponding to desired debug outputs.  The following 
33 +are the meanings for each debug bit:
34 +- bit0 (LSB): CPHAL Function Trace
35 +- b1 : OS Function call trace
36 +- b2 : Critical section entry/exit
37 +- b3 : Memory allocation/destruction
38 +- b4 : Detailed information in Rx path
39 +- b5 : Detailed information in Tx path
40 +- b6 : Extended error information
41 +- b7 : General info
42 +*/
43 +static const char pszDebug[]        = "debug";
44 +/** CPU Frequency. */
45 +/*static const char pszCpuFreq[]      = "CpuFreq";*/               /*MJH-030403*/
46 +/** Base address for the module. */
47 +static const char pszBase[]         = "base";
48 +/** Reset bit for the module. */
49 +static const char pszResetBit[]     = "reset_bit";
50 +/** Reset base address for the module. */
51 +static const char pszResetBase[]    = "ResetBase";
52 +/** Interrupt line for the module. */
53 +static const char pszIntLine[]      = "int_line";
54 +/** VLYNQ offset for the module.  Disregard if not using VLYNQ. */
55 +static const char pszOffset[]       = "offset";
56 +/** The OS may "Get" this parameter, which is a pointer
57 +    to a character string that indicates the version of CPHAL. */
58 +static const char pszVer[]          = "Version";
59 +/*@}*/
60 +
61 +/**
62 +@defgroup Common_Control_Params Common Keys for [os]Control()
63 +
64 +This section documents the keys used with the OS @c Control() interface that
65 +are required by CPHAL devices.
66 +
67 +@{
68 +*/
69 +/** Used to wait for an integer number of clock ticks, given as an integer
70 +    pointer in the @p Value parameter.  No actions are defined. */
71 +static const char pszSleep[]             = "Sleep";
72 +/** Requests the OS to flush it's IO buffers.  No actions are defined. */
73 +static const char pszSioFlush[]          = "SioFlush";
74 +/*@}*/
75 +
76 +static const char pszStateChange[]       = "StateChange";
77 +static const char pszStatus[]            = "Status";
78 +
79 +static const char pszGET[]               = "Get";
80 +static const char pszSET[]               = "Set";
81 +static const char pszCLEAR[]             = "Clear";
82 +static const char pszNULL[]              = "";
83 +static const char pszLocator[]           = "Locator";
84 +static const char pszOff[]               = "Off";
85 +static const char pszOn[]                = "On";
86 +static const char hcMaxFrags[]           = "MaxFrags";
87 +
88 +#ifdef _CPHAL_CPMAC
89 +
90 +/*  New method for string constants */
91 +const char hcClear[]  = "Clear";
92 +const char hcGet[]    = "Get";
93 +const char hcSet[]    = "Set";
94 +
95 +const char hcTick[]   = "Tick";
96 +
97 +static const CONTROL_KEY KeyCommon[] =
98 +   {
99 +     {""                   , enCommonStart},
100 +     {pszStatus            , enStatus},
101 +     {pszOff               , enOff},
102 +     {pszOn                , enOn},
103 +     {pszDebug             , enDebug},
104 +     {hcCpuFrequency       , enCpuFreq},                           /*MJH~030403*/
105 +     {""                   , enCommonEnd}
106 +   };
107 +#endif
108 +
109 +/**
110 +@defgroup Common_Statistics Statistics
111 +
112 +A broad array of module statistics is available.  Statistics values are accessed
113 +through the @c Control() interface of the CPHAL.  There are 5 different levels
114 +of statistics, each of which correspond to a unique set of data.  Furthermore,
115 +certain statistics data is indexed by using a channel number and Tx queue number.
116 +The following is a brief description of each statistics level, along with the
117 +indexes used for the level:
118 +
119 +- Level 0:  Hardware Statistics (index with channel)
120 +- Level 1:  CPHAL Software Statistics (channel, queue)
121 +- Level 2:  CPHAL Flags (channel, queue)
122 +- Level 3:  CPHAL Channel Configuration (channel)
123 +- Level 4:  CPHAL General Configuration (no index)
124 +
125 +The caller requests statistics information by providing a Key string to the
126 +@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]".
127 +The only valid Action parameter for statistics usage is "Get".
128 +
129 +Code Examples:
130 +@code
131 +unsigned int *StatsData;
132 +
133 +# Get Level 0 stats for Channel 1
134 +HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData);
135 +
136 +# Get Level 2 stats for Channel 0, Queue 0
137 +HalFunc->Control(OsDev->HalDev, "Stats;2;0;0", "Get", &StatsData);
138 +
139 +# Get Level 4 stats
140 +HalFunc->Control(OsDev->HalDev, "Stats;4", "Get", &StatsData);
141 +@endcode
142 +
143 +The information returned in the Value parameter of @c Control() is an
144 +array of pointers to strings.  The pointers are arranged in pairs.
145 +The first pointer is a pointer to a name string for a particular statistic.
146 +The next pointer is a pointer to a string containing the representation of
147 +the integer statistic value corresponding to the first pointer.  This is followed
148 +by another pair of pointers, and so on, until a NULL pointer is encountered.  The
149 +following is example code for processing the statistics data.  Note that the OS
150 +is responsible for freeing the memory passed back through the Value parameter of
151 +@c Control().
152 +
153 +@code
154 +unsigned int *StatsData;
155 +
156 +# Get Level 0 stats for Channel 1
157 +HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData);
158 +
159 +# output Statistics data
160 +PrintStats(StatsData);
161 +
162 +# the upper layer is responsible for freeing stats info
163 +free(&StatsPtr);
164 +
165 +...
166 +
167 +void PrintStats(unsigned int *StatsPtr)
168 +  {
169 +   while(*StatsPtr)
170 +     {
171 +      printf("%20s:",  (char *)*StatsPtr);
172 +      StatsPtr++;
173 +      printf("%11s\n", (char *)*StatsPtr);
174 +      StatsPtr++;
175 +     }
176 +   MySioFlush();
177 +  }
178 +@endcode
179 +
180 +Within each statistics level, there are several statistics defined.  The statistics that
181 +are common to every CPPI module are listed below.  In addition, each module may define
182 +extra statistics in each level, which will be documented within the module-specific
183 +documentation appendices.
184 +
185 +- Level 0 Statistics
186 +  - All level 0 statistics are module-specific.
187 +- Level 1 Statistics (CPHAL Software Statistics)
188 +  - DmaLenErrors: Incremented when the port DMA's more data than expected (per channel). (AAL5 Only)
189 +  - TxMisQCnt: Incremented when host queues a packet for transmission as the port finishes
190 +transmitting the previous last packet in the queue (per channel and queue).
191 +  - RxMisQCnt: Incremented when host queues adds buffers to a queue as the port finished the
192 +reception of the previous last packet in the queue (per channel).
193 +  - TxEOQCnt: Number of times the port has reached the end of the transmit queue (per channel and queue).
194 +  - RxEOQCnt: Number of times the port has reached the end of the receive queue (per channel).
195 +  - RxPacketsServiced: Number of received packets (per channel).
196 +  - TxPacketsServiced: Number of transmitted packets (per channel and queue).
197 +  - RxMaxServiced: Maximum number of packets that the CPHAL receive interrupt has serviced at a time (per channel).
198 +  - TxMaxServiced: Maximum number of packets that the CPHAL transmit interrupt has serviced at a time (per channel and queue).
199 +  - RxTotal: Total number of received packets, all channels.
200 +  - TxTotal: Total number of transmitted packets, all channels and queues.
201 +- Level 2 Statistics (CPHAL Flags)
202 +  - RcbPool: Pointer to receive descriptor pool (per channel).
203 +  - RxActQueueCount: Number of buffers currently available for receive (per channel).
204 +  - RxActQueueHead: Pointer to first buffer in receive queue (per channel).
205 +  - RxActQueueTail: Pointer to last buffer in receive queue (per channel).
206 +  - RxActive: 0 if inactive (no buffers available), or 1 if active (buffers available).
207 +  - RcbStart: Pointer to block of receive descriptors.
208 +  - RxTeardownPending: 1 if Rx teardown is pending but incomplete, 0 otherwise.
209 +  - TcbPool: Pointer to transmit descriptor pool (per channel and queue).
210 +  - TxActQueueCount: Number of buffers currently queued to be transmitted (per channel and queue).
211 +  - TxActQueueHead: Pointer to first buffer in transmit queue (per channel and queue).
212 +  - TxActQueueTail: Pointer to last buffer in transmit queue (per channel and queue).
213 +  - TxActive: 0 if inactive (no buffers to send), or 1 if active (buffers queued to send).
214 +  - TcbStart: Pointer to block of transmit descriptors.
215 +  - TxTeardownPending: 1 if Tx teardown is pending but incomplete, 0 otherwise.
216 +- Level 3 Statistics (CPHAL Channel Configuration)
217 +  - RxBufSize: Rx buffer size.
218 +  - RxBufferOffset: Rx buffer offset.
219 +  - RxNumBuffers: Number of Rx buffers.
220 +  - RxServiceMax: Maximum number of receive packets to service at a time.
221 +  - TxNumBuffers: Number of Tx buffer descriptors.
222 +  - TxNumQueues: Number of Tx queues to use.
223 +  - TxServiceMax: Maximum number of transmit packets to service at a time.
224 +- Level 4 Statistics (CPHAL General Configuration)
225 +  - Base Address: Base address of the module.
226 +  - Offset (VLYNQ): VLYNQ relative module offset.
227 +  - Interrupt Line: Interrupt number.
228 +  - Debug: Debug flag, 1 to enable debug.
229 +  - Inst: Instance number.
230 +*/
231 +
232 +/* 
233 +   Data Type 0 = int display
234 +   Data Type 1 = hex display
235 +   Data Type 2 = channel structure, int display
236 +   Data Type 3 = queue index and int display
237 +   Data Type 4 = queue index and hex display
238 +*/
239 +#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) /* +GSG 030307 */
240 +static STATS_TABLE StatsTable0[] =
241 +  {
242 +#ifdef _CPHAL_AAL5
243 +   /* Name ,        Data Ptr,   Data Type */
244 +   {"Crc Errors",          0,          0},
245 +   {"Len Errors",          0,          0},
246 +   {"Abort Errors",        0,          0},
247 +   {"Starv Errors",        0,          0}
248 +#endif
249 +#ifdef _CPHAL_CPMAC
250 +   {"Rx Good Frames",      0,          0}
251 +#endif
252 +  };
253 +
254 +static STATS_TABLE StatsTable1[] =
255 +  {
256 +   /* Name ,        Data Ptr,   Data Type */
257 +   {"DmaLenErrors",        0,          0},
258 +   {"TxMisQCnt",           0,          3},
259 +   {"RxMisQCnt",           0,          0},
260 +   {"TxEOQCnt",            0,          3},
261 +   {"RxEOQCnt",            0,          0},
262 +   {"RxPacketsServiced",   0,          0},
263 +   {"TxPacketsServiced",   0,          3},
264 +   {"RxMaxServiced",       0,          0},
265 +   {"TxMaxServiced",       0,          3},
266 +   {"RxTotal",             0,          0},
267 +   {"TxTotal",             0,          0},
268 +  };
269 +
270 +static STATS_TABLE StatsTable2[] =
271 +  {
272 +   /* Name ,        Data Ptr,   Data Type */
273 +   {"RcbPool",             0,          1},
274 +   {"RxActQueueCount",     0,          0},
275 +   {"RxActQueueHead",      0,          1},
276 +   {"RxActQueueTail",      0,          1},
277 +   {"RxActive",            0,          0},
278 +   {"RcbStart",            0,          1},
279 +   {"RxTeardownPending",   0,          0},
280 +   {"TcbPool",             0,          4},
281 +   {"TxActQueueCount",     0,          3},
282 +   {"TxActQueueHead",      0,          4},
283 +   {"TxActQueueTail",      0,          4},
284 +   {"TxActive",            0,          3},
285 +   {"TcbStart",            0,          4},
286 +   {"TxTeardownPending",   0,          0}
287 +  };
288 +
289 +static STATS_TABLE StatsTable3[] =
290 +  {
291 +   /* Name ,        Data Ptr,   Data Type */
292 +   {"RxBufSize",           0,          2},
293 +   {"RxBufferOffset",      0,          2},
294 +   {"RxNumBuffers",        0,          2},
295 +   {"RxServiceMax",        0,          2},
296 +   {"TxNumBuffers",        0,          2},
297 +   {"TxNumQueues",         0,          2},
298 +   {"TxServiceMax",        0,          2},
299 +#ifdef _CPHAL_AAL5
300 +   {"CpcsUU",              0,          2},
301 +   {"Gfc",                 0,          2},
302 +   {"Clp",                 0,          2},
303 +   {"Pti",                 0,          2},
304 +   {"DaMask",              0,          2},
305 +   {"Priority",            0,          2},
306 +   {"PktType",             0,          2},
307 +   {"Vci",                 0,          2},
308 +   {"Vpi",                 0,          2},
309 +   {"CellRate",            0,          2},
310 +   {"QosType",             0,          2},
311 +   {"Mbs",                 0,          2},
312 +   {"Pcr",                 0,          2}
313 +#endif
314 +  };
315 +
316 +static STATS_TABLE StatsTable4[] =
317 +  {
318 +   {"Base Address",        0,          1},
319 +   {"Offset (VLYNQ)",      0,          0},
320 +   {"Interrupt Line",      0,          0},
321 +   {"Debug",               0,          0},
322 +   {"Instance",            0,          0},
323 +#ifdef _CPHAL_AAL5
324 +   {"UniNni",              0,          0}
325 +#endif
326 +  };
327 +
328 +static STATS_DB StatsDb[] =
329 +  {
330 +    {(sizeof(StatsTable0)/sizeof(STATS_TABLE)), StatsTable0},
331 +    {(sizeof(StatsTable1)/sizeof(STATS_TABLE)), StatsTable1},
332 +    {(sizeof(StatsTable2)/sizeof(STATS_TABLE)), StatsTable2},
333 +    {(sizeof(StatsTable3)/sizeof(STATS_TABLE)), StatsTable3},
334 +    {(sizeof(StatsTable4)/sizeof(STATS_TABLE)), StatsTable4}
335 +  };
336 +#endif /* +GSG 030307 */
337 +
338 +#ifdef _CPHAL_CPMAC /* +RC 3.02 */
339 +static void resetWait(HAL_DEVICE *HalDev)
340 +  {                                                                  /*+RC3.02*/
341 +  const int TickReset=64;
342 +  osfuncSleep((int*)&TickReset);
343 +  }                                                                  /*+RC3.02*/
344 +#endif /* +RC 3.02 */
345 +
346 +/* I only define the reset base function for the modules
347 +   that can perform a reset.  The AAL5 and AAL2 modules
348 +   do not perform a reset, that is done by the shared module
349 +   CPSAR */
350 +#if defined(_CPHAL_CPSAR) || defined(_CPHAL_CPMAC) || defined(_CPHAL_VDMAVT)
351 +/*
352 + *  Determines the reset register address to be used for a particular device.
353 + *  It will search the current device entry for Locator information.  If the
354 + *  device is a root device, there will be no Locator information, and the
355 + *  function will find and return the root reset register.  If a Locator value
356 + *  is found, the function will search each VLYNQ device entry in the system
357 + *  looking for a matching Locator.  Once it finds a VLYNQ device entry with
358 + *  a matching Locator, it will extract the "ResetBase" parameter from that
359 + *  VLYNQ device entry (thus every VLYNQ entry must have the ResetBase parameter).
360 + *
361 + *  @param  HalDev   CPHAL module instance. (set by xxxInitModule())
362 + *  @param  ResetBase Pointer to integer address of reset register.
363 + *
364 + *  @return 0 OK, Non-zero not OK
365 + */
366 +static int ResetBaseGet(HAL_DEVICE *HalDev, bit32u *ResetBase)
367 +  {
368 +   char *DeviceInfo = HalDev->DeviceInfo;
369 +   char *MyLocator, *NextLocator;
370 +   int Inst=1;
371 +   bit32u error_code;
372 +
373 +#ifdef __CPHAL_DEBUG
374 +   if (DBG(0))
375 +     {
376 +      dbgPrintf("[cpcommon]ResetBaseGet(HalDev:%08x, ResetBase:%08x)\n", (bit32u)HalDev, ResetBase);
377 +      osfuncSioFlush();
378 +     }
379 +#endif
380 +
381 +   error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &MyLocator);
382 +   if (error_code)
383 +     {
384 +      /* if no Locator value, device is on the root, so get the "reset" device */
385 +      error_code = HalDev->OsFunc->DeviceFindInfo(0, "reset", &DeviceInfo);
386 +      if  (error_code)
387 +        {
388 +         return(EC_VAL_DEVICE_NOT_FOUND);
389 +        }
390 +
391 +      error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "base", ResetBase);
392 +      if (error_code)
393 +        {
394 +         return(EC_VAL_BASE_ADDR_NOT_FOUND);
395 +        }
396 +
397 +      *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase));
398 +
399 +      /* found base address for root device, so we're done */
400 +      return (EC_NO_ERRORS);
401 +     }
402 +    else
403 +     {
404 +      /* we have a Locator value, so the device is remote */
405 +
406 +      /* Find a vlynq device with a matching locator value */
407 +      while ((HalDev->OsFunc->DeviceFindInfo(Inst, "vlynq", &DeviceInfo)) == EC_NO_ERRORS)
408 +        {
409 +         error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &NextLocator);
410 +         if (error_code)
411 +           {
412 +            /* no Locator value for this VLYNQ, so move on */
413 +            continue;
414 +           }
415 +         if (HalDev->OsFunc->Strcmpi(MyLocator, NextLocator)==0)
416 +           {
417 +            /* we have found a VLYNQ with a matching Locator, so extract the ResetBase */
418 +            error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "ResetBase", ResetBase);
419 +            if (error_code)
420 +              {
421 +               return(EC_VAL_BASE_ADDR_NOT_FOUND);
422 +              }
423 +            *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase));
424 +
425 +            /* found base address for root device, so we're done */
426 +            return (EC_NO_ERRORS);
427 +           }
428 +         Inst++;
429 +        } /* while */
430 +     } /* else */
431 +
432 +   return (EC_NO_ERRORS);
433 +  }
434 +#endif
435 +
436 +#ifndef _CPHAL_AAL2 /* + RC 3.02 */
437 +static bit32u ConfigGetCommon(HAL_DEVICE *HalDev)
438 +  {
439 +   bit32u ParmValue;
440 +   bit32 error_code;
441 +   char *DeviceInfo = HalDev->DeviceInfo;
442 +
443 +#ifdef __CPHAL_DEBUG
444 +   if (DBG(0))
445 +     {
446 +      dbgPrintf("[cpcommon]ConfigGetCommon(HalDev:%08x)\n", (bit32u)HalDev);
447 +      osfuncSioFlush();
448 +     }
449 +#endif
450 +
451 +   error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszBase, &ParmValue);
452 +   if (error_code)
453 +     {
454 +      return(EC_FUNC_HAL_INIT|EC_VAL_BASE_ADDR_NOT_FOUND);
455 +     }
456 +   HalDev->dev_base = ((bit32u)PhysToVirtNoCache(ParmValue));
457 +
458 +#ifndef _CPHAL_AAL5
459 +#ifndef _CPHAL_AAL2
460 +   error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszResetBit, &ParmValue);
461 +   if(error_code)
462 +     {
463 +      return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BIT_NOT_FOUND);
464 +     }
465 +   HalDev->ResetBit = ParmValue;
466 +
467 +   /* Get reset base address */
468 +   error_code = ResetBaseGet(HalDev, &ParmValue);
469 +   if (error_code)
470 +     return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BASE_NOT_FOUND);
471 +   HalDev->ResetBase = ParmValue;
472 +#endif
473 +#endif
474 +
475 +#ifndef _CPHAL_CPSAR
476 +   error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszIntLine,&ParmValue);
477 +   if (error_code)
478 +     {
479 +      return(EC_FUNC_HAL_INIT|EC_VAL_INTERRUPT_NOT_FOUND);
480 +     }
481 +   HalDev->interrupt = ParmValue;
482 +#endif
483 +
484 +   /* only look for the offset if there is a Locator field, which indicates that
485 +      the module is a VLYNQ module */
486 +   error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszLocator,&ParmValue);
487 +   if (!error_code)
488 +     {
489 +      error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszOffset,&ParmValue);
490 +      if (error_code)
491 +        {
492 +         return(EC_FUNC_HAL_INIT|EC_VAL_OFFSET_NOT_FOUND);
493 +        }
494 +      HalDev->offset = ParmValue;
495 +     }
496 +    else
497 +      HalDev->offset = 0;
498 +
499 +   error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszDebug, &ParmValue);
500 +   if (!error_code) HalDev->debug = ParmValue;
501 +
502 +   return (EC_NO_ERRORS);
503 +  }
504 +#endif /* +RC 3.02 */
505 +
506 +#ifdef _CPHAL_CPMAC /* +RC 3.02 */
507 +static void StatsInit(HAL_DEVICE *HalDev)                             /* +() RC3.02 */
508 +  {
509 +   /* even though these statistics may be for multiple channels and
510 +      queues, i need only configure the pointer to the beginning
511 +      of the array, and I can index from there if necessary */
512 +
513 +#ifdef _CPHAL_AAL5
514 +   StatsTable0[0].StatPtr  = &HalDev->Stats.CrcErrors[0];
515 +   StatsTable0[1].StatPtr  = &HalDev->Stats.LenErrors[0];
516 +   StatsTable0[2].StatPtr  = &HalDev->Stats.AbortErrors[0];
517 +   StatsTable0[3].StatPtr  = &HalDev->Stats.StarvErrors[0];
518 +
519 +   StatsTable1[0].StatPtr  = &HalDev->Stats.DmaLenErrors[0];
520 +   StatsTable1[1].StatPtr  = &HalDev->Stats.TxMisQCnt[0][0];
521 +   StatsTable1[2].StatPtr  = &HalDev->Stats.RxMisQCnt[0];
522 +   StatsTable1[3].StatPtr  = &HalDev->Stats.TxEOQCnt[0][0];
523 +   StatsTable1[4].StatPtr  = &HalDev->Stats.RxEOQCnt[0];
524 +   StatsTable1[5].StatPtr  = &HalDev->Stats.RxPacketsServiced[0];
525 +   StatsTable1[6].StatPtr  = &HalDev->Stats.TxPacketsServiced[0][0];
526 +   StatsTable1[7].StatPtr  = &HalDev->Stats.RxMaxServiced;
527 +   StatsTable1[8].StatPtr  = &HalDev->Stats.TxMaxServiced[0][0];
528 +   StatsTable1[9].StatPtr  = &HalDev->Stats.RxTotal;
529 +   StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal;
530 +#endif
531 +
532 +#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC))
533 +   StatsTable2[0].StatPtr  = (bit32u *)&HalDev->RcbPool[0];
534 +   StatsTable2[1].StatPtr  = &HalDev->RxActQueueCount[0];
535 +   StatsTable2[2].StatPtr  = (bit32u *)&HalDev->RxActQueueHead[0];
536 +   StatsTable2[3].StatPtr  = (bit32u *)&HalDev->RxActQueueTail[0];
537 +   StatsTable2[4].StatPtr  = &HalDev->RxActive[0];
538 +   StatsTable2[5].StatPtr  = (bit32u *)&HalDev->RcbStart[0];
539 +   StatsTable2[6].StatPtr  = &HalDev->RxTeardownPending[0];
540 +   StatsTable2[7].StatPtr  = (bit32u *)&HalDev->TcbPool[0][0];
541 +   StatsTable2[8].StatPtr  = &HalDev->TxActQueueCount[0][0];
542 +   StatsTable2[9].StatPtr  = (bit32u *)&HalDev->TxActQueueHead[0][0];
543 +   StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0];
544 +   StatsTable2[11].StatPtr = &HalDev->TxActive[0][0];
545 +   StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0];
546 +   StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0];
547 +
548 +   StatsTable3[0].StatPtr  = &HalDev->ChData[0].RxBufSize;
549 +   StatsTable3[1].StatPtr  = &HalDev->ChData[0].RxBufferOffset;
550 +   StatsTable3[2].StatPtr  = &HalDev->ChData[0].RxNumBuffers;
551 +   StatsTable3[3].StatPtr  = &HalDev->ChData[0].RxServiceMax;
552 +   StatsTable3[4].StatPtr  = &HalDev->ChData[0].TxNumBuffers;
553 +   StatsTable3[5].StatPtr  = &HalDev->ChData[0].TxNumQueues;
554 +   StatsTable3[6].StatPtr  = &HalDev->ChData[0].TxServiceMax;
555 +#ifdef _CPHAL_AAL5
556 +   StatsTable3[7].StatPtr  = &HalDev->ChData[0].CpcsUU;
557 +   StatsTable3[8].StatPtr  = &HalDev->ChData[0].Gfc;
558 +   StatsTable3[9].StatPtr  = &HalDev->ChData[0].Clp;
559 +   StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti;
560 +   StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask;
561 +   StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority;
562 +   StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType;
563 +   StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci;
564 +   StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi;
565 +   StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate;
566 +   StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType;
567 +   StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs;
568 +   StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr;
569 +#endif
570 +#endif
571 +
572 +   StatsTable4[0].StatPtr  = &HalDev->dev_base;
573 +   StatsTable4[1].StatPtr  = &HalDev->offset;
574 +   StatsTable4[2].StatPtr  = &HalDev->interrupt;
575 +   StatsTable4[3].StatPtr  = &HalDev->debug;
576 +   StatsTable4[4].StatPtr  = &HalDev->Inst;
577 +  }
578 +#endif /* +RC 3.02 */
579 +
580 +#ifndef _CPHAL_CPSAR /* +RC 3.02 */
581 +#ifndef _CPHAL_AAL2 /* +RC 3.02 */
582 +/*
583 + *  Returns statistics information.
584 + *
585 + *  @param  HalDev   CPHAL module instance. (set by xxxInitModule())
586 + *
587 + *  @return 0
588 + */
589 +static int StatsGet(HAL_DEVICE *HalDev, void **StatPtr, int Index, int Ch, int Queue)
590 +  {
591 +   int Size;
592 +   bit32u *AddrPtr;
593 +   char *DataPtr;
594 +   STATS_TABLE *StatsTable;
595 +   int i, NumberOfStats;
596 +
597 +#ifdef __CPHAL_DEBUG
598 +   if (DBG(0))
599 +     {
600 +      dbgPrintf("[cpcommon]StatsGet(HalDev:%08x, StatPtr:%08x)\n",
601 +                (bit32u)HalDev, (bit32u)StatPtr);
602 +      osfuncSioFlush();
603 +     }
604 +#endif
605 +
606 +   StatsTable = StatsDb[Index].StatTable;
607 +   NumberOfStats = StatsDb[Index].NumberOfStats;
608 +
609 +   Size = sizeof(bit32u)*((NumberOfStats*2)+1);
610 +   Size += (NumberOfStats*11);
611 +   *StatPtr = (bit32u *)HalDev->OsFunc->Malloc(Size);
612 +
613 +   AddrPtr = (bit32u *) *StatPtr;
614 +   DataPtr = (char *)AddrPtr;
615 +   DataPtr += sizeof(bit32u)*((NumberOfStats*2)+1);
616 +
617 +   for (i=0; i<NumberOfStats; i++)
618 +     {
619 +      *AddrPtr++ = (bit32u)StatsTable[i].StatName;
620 +      *AddrPtr++ = (bit32u)DataPtr;
621 +      if (&StatsTable[i].StatPtr[Ch] != 0)
622 +        {
623 +         switch(StatsTable[i].DataType)
624 +           {
625 +            case 0:
626 +              HalDev->OsFunc->Sprintf(DataPtr, "%d", (bit32u *)StatsTable[i].StatPtr[Ch]);
627 +              break;
628 +            case 1:
629 +              HalDev->OsFunc->Sprintf(DataPtr, "0x%x", (bit32u *)StatsTable[i].StatPtr[Ch]);
630 +              break;
631 +            case 2:
632 +              HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch * (sizeof(CHANNEL_INFO)/4))));
633 +              break;
634 +            case 3:
635 +              HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue));
636 +              break;
637 +            case 4:
638 +              HalDev->OsFunc->Sprintf(DataPtr, "0x%x", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue));
639 +              break;
640 +            default:
641 +              /* invalid data type, due to CPHAL programming error */
642 +              break;
643 +           }
644 +        }
645 +       else
646 +        {
647 +         /* invalid statistics pointer, probably was not initialized */
648 +        }
649 +      DataPtr += HalDev->OsFunc->Strlen(DataPtr) + 1;
650 +     }
651 +
652 +   *AddrPtr = (bit32u) 0;
653 +
654 +   return (EC_NO_ERRORS);
655 +  }
656 +#endif /* +RC 3.02 */
657 +#endif /* +RC 3.02 */
658 +
659 +#ifdef _CPHAL_CPMAC
660 +static void gpioFunctional(int base, int bit)
661 +  {                                                                  /*+RC3.02*/
662 +  bit32u GpioEnr = base + 0xC;
663 +  /*  To make functional, set to zero  */
664 +  *(volatile bit32u *)(GpioEnr) &= ~(1 << bit);                      /*+RC3.02*/
665 +  }                                                                  /*+RC3.02*/
666 +
667 +
668 +/*+RC3.02*/
669 +/* Common function, Checks to see if GPIO should be in functional mode */
670 +static void gpioCheck(HAL_DEVICE *HalDev, void *moduleDeviceInfo)
671 +  {                                                                  /*+RC3.02*/
672 +  int rc;
673 +  void *DeviceInfo;
674 +  char *pszMuxBits;
675 +  char pszMuxBit[20];
676 +  char *pszTmp;
677 +  char szMuxBit[20];
678 +  char *ptr;
679 +  int base;
680 +  int reset_bit;
681 +  int bit;
682 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
683 +
684 +  rc = OsFunc->DeviceFindParmValue(moduleDeviceInfo, "gpio_mux",&pszTmp);
685 +  if(rc) return;
686 +  /*  gpio entry found, get GPIO register info and make functional  */
687 +
688 +  /* temp copy until FinParmValue fixed */
689 +  ptr = &szMuxBit[0];
690 +  while ((*ptr++ = *pszTmp++));
691 +
692 +  pszMuxBits = &szMuxBit[0];
693 +
694 +  rc = OsFunc->DeviceFindInfo(0,"gpio",&DeviceInfo);
695 +  if(rc) return;
696 +
697 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",&base);
698 +  if(rc) return;
699 +
700 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit);
701 +  if(rc) return;
702 +
703 +  /* If GPIO still in reset, then exit  */
704 +  if((VOLATILE32(HalDev->ResetBase) & (1 << reset_bit)) == 0)
705 +    return;
706 +  /*  format for gpio_mux is  gpio_mux = <int>;<int>;<int>...*/
707 +  while (*pszMuxBits)
708 +    {
709 +    pszTmp = &pszMuxBit[0];
710 +    if(*pszMuxBits == ';') pszMuxBits++;
711 +    while ((*pszMuxBits != ';') && (*pszMuxBits != '\0'))
712 +      {
713 +      osfuncSioFlush();
714 +      /*If value not a number, skip */
715 +      if((*pszMuxBits < '0') || (*pszMuxBits > '9'))
716 +        pszMuxBits++;
717 +      else
718 +        *pszTmp++ = *pszMuxBits++;
719 +      }
720 +    *pszTmp = '\0';
721 +    bit = OsFunc->Strtoul(pszMuxBit, &pszTmp, 10);
722 +    gpioFunctional(base, bit);
723 +    resetWait(HalDev);  /* not sure if this is needed */
724 +    }
725 +  }                                                                  /*+RC3.02*/
726 +#endif  /* CPMAC  */
727 +
728 +#ifdef _CPHAL_AAL5
729 +const char hcSarFrequency[] = "SarFreq";
730 +#endif
731 +
732 +#endif  /* _INC  */
733 diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h
734 --- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h      1970-01-01 01:00:00.000000000 +0100
735 +++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h      2005-07-12 02:48:41.996601000 +0200
736 @@ -0,0 +1,79 @@
737 +#ifndef _INC_CPCOMMON_H
738 +#define _INC_CPCOMMON_H
739 +
740 +#define VOLATILE32(addr)  (*(volatile bit32u *)(addr))
741 +#ifndef dbgPrintf
742 +#define dbgPrintf HalDev->OsFunc->Printf
743 +#endif
744 +
745 +#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field
746 +
747 +#define DBG(level)  (HalDev->debug & (1<<(level)))
748 +/*
749 +#define DBG0()      DBG(0)
750 +#define DBG1()      DBG(1)
751 +#define DBG2()      DBG(2)
752 +#define DBG3()      DBG(3)
753 +#define DBG4()      DBG(4)
754 +#define DBG5()      DBG(5)
755 +#define DBG6()      DBG(6)
756 +#define DBG7()      DBG(7)
757 +*/
758 +
759 +/*
760 + *  List of defined actions for use with Control().
761 + */
762 +typedef enum 
763 +  {
764 +   enGET=0,     /**< Get the value associated with a key */
765 +   enSET,       /**< Set the value associates with a key */
766 +   enCLEAR,     /**<Clear the value */ 
767 +   enNULL       /**< No data action, used to initiate a service or send a message */
768 +  }ACTION;
769 +
770 +/*
771 + *  Enumerated hardware states.
772 + */
773 +typedef enum
774 +  {
775 +   enConnected=1, enDevFound, enInitialized, enOpened
776 +  }DEVICE_STATE;
777 +
778 +typedef enum 
779 +  {
780 +   enCommonStart=0,
781 +   /* General  */
782 +   enOff, enOn, enDebug, 
783 +   /* Module General */
784 +   enCpuFreq, 
785 +   enStatus,
786 +   enCommonEnd
787 +   }COMMON_KEY;
788 +
789 +typedef struct
790 +  {
791 +   const char  *strKey;
792 +   int  enKey;
793 +  }CONTROL_KEY;
794 +
795 +typedef struct
796 +  {
797 +   char *StatName;
798 +   unsigned int *StatPtr;
799 +   int DataType; /* 0: int, 1: hex int, 2:channel data */
800 +  }STATS_TABLE;
801 +
802 +typedef struct
803 +  {
804 +   int NumberOfStats;
805 +   STATS_TABLE *StatTable;
806 +  }STATS_DB;
807 +
808 +#define osfuncSioFlush()    HalDev->OsFunc->Control(HalDev->OsDev,"SioFlush",pszNULL,0)
809 +#define osfuncSleep(Ticks)  HalDev->OsFunc->Control(HalDev->OsDev,pszSleep,pszNULL,Ticks)
810 +#define osfuncStateChange() HalDev->OsFunc->Control(HalDev->OsDev,pszStateChange,pszNULL,0)
811 +
812 +#define CHANNEL_NAMES {"Ch0","Ch1","Ch2","Ch3","Ch4","Ch5","Ch6","Ch7","Ch8","Ch9","Ch10","Ch11","Ch12","Ch13","Ch14","Ch15"}
813 +
814 +#endif
815 +
816 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpmac.c
817 --- linux.old/drivers/net/avalanche_cpmac/cpmac.c       1970-01-01 01:00:00.000000000 +0100
818 +++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c       2005-07-22 01:03:12.609318544 +0200
819 @@ -0,0 +1,2504 @@
820 +/******************************************************************************
821 + * FILE PURPOSE:    CPMAC Linux Network Device Driver Source
822 + ******************************************************************************
823 + * FILE NAME:       cpmac.c
824 + *
825 + * DESCRIPTION:     CPMAC Network Device Driver Source
826 + *
827 + * REVISION HISTORY:
828 + *
829 + * Date           Description                               Author
830 + *-----------------------------------------------------------------------------
831 + * 27 Nov 2002    Initial Creation                          Suraj S Iyer  
832 + * 09 Jun 2003    Updates for GA                            Suraj S Iyer
833 + * 30 Sep 2003    Updates for LED, Reset stats              Suraj S Iyer
834 + * 
835 + * (C) Copyright 2003, Texas Instruments, Inc
836 + *******************************************************************************/
837 +#include <linux/kernel.h> 
838 +#include <linux/module.h> 
839 +#include <linux/init.h>
840 +#include <linux/netdevice.h>
841 +#include <linux/etherdevice.h>
842 +#include <linux/delay.h>     
843 +#include <linux/spinlock.h>
844 +#include <linux/proc_fs.h>
845 +#include <linux/ioport.h>
846 +#include <asm/io.h>
847 +
848 +#include <linux/skbuff.h>
849 +
850 +#include <asm/mips-boards/prom.h>
851 +#include <linux/string.h>
852 +#include <asm/uaccess.h>
853 +#include <linux/config.h>
854 +#include <asm/ar7/if_port.h>
855 +
856 +extern void build_psp_config(void);
857 +extern void psp_config_cleanup(void);
858 +
859 +#include "cpmacHalLx.h"
860 +#include "cpmac.h"
861 +
862 +static struct net_device *last_cpmac_device = NULL;
863 +static int    cpmac_devices_installed = 0;
864 +
865 +void xdump( u_char*  cp, int  length, char*  prefix );
866 +
867 +unsigned int  cpmac_cpu_freq = 0;
868 +
869 +char cpmac_version[] = "1.5";
870 +
871 +char l3_align_array[]            = {0x02, 0x01, 0x00, 0x03};
872 +#define L3_ALIGN(i)                l3_align_array[i]
873 +
874 +char add_for_4byte_align[]       = {0x04, 0x03, 0x02, 0x05};
875 +#define ADD_FOR_4BYTE_ALIGN(i)     add_for_4byte_align[i]
876 +
877 +
878 +#define TPID                       0x8100
879 +#define IS_802_1Q_FRAME(byte_ptr)  (*(unsigned short*)byte_ptr == TPID)
880 +#define TPID_START_OFFSET          12
881 +#define TCI_START_OFFSET           14
882 +#define TCI_LENGTH                 2
883 +#define TPID_LENGTH                2
884 +#define TPID_END_OFFSET            (TPID_START_OFFSET + TPID_LENGTH)
885 +#define TCI_END_OFFSET             (TCI_START_OFFSET  + TCI_LENGTH)
886 +#define IS_VALID_VLAN_ID(byte_ptr) ((*(unsigned short*)byte_ptr) && 0xfff != 0)
887 +#define MAX_CLASSES                8
888 +#define MAX_USER_PRIORITY          8
889 +#define CONTROL_802_1Q_SIZE        (TCI_LENGTH + TPID_LENGTH)
890 +
891 +unsigned char user_priority_to_traffic_class_map[MAX_CLASSES][MAX_USER_PRIORITY] = 
892 +{ 
893 +  {0, 0, 0, 1, 1, 1, 1, 2}, 
894 +  {0, 0, 0, 0, 0, 0, 0, 0}, 
895 +  {0, 0, 0, 0, 0, 0, 0, 1}, 
896 +  {0, 0, 0, 1, 1, 2, 2, 3}, 
897 +  {0, 1, 1, 2, 2, 3, 3, 4}, 
898 +  {0, 1, 1, 2, 3, 4, 4, 5}, 
899 +  {0, 1, 2, 3, 4, 5, 5, 6}, 
900 +  {0, 1, 2, 3, 4, 5, 6, 7}
901 +};
902 +
903 +#define GET_802_1P_CHAN(x,y) user_priority_to_traffic_class_map[x][(y & 0xe0)]
904 +
905 +#if defined(CONFIG_MIPS_SEAD2)
906 +unsigned long temp_base_address[2] = {0xa8610000, 0xa8612800};
907 +unsigned long temp_reset_value[2] = { 1<< 17,1<<21};
908 +#define RESET_REG_PRCR   (*(volatile unsigned int *)((0xa8611600 + 0x0)))
909 +#define VERSION(base)   (*(volatile unsigned int *)(((base)|0xa0000000) + 0x0))
910 +#endif
911 +
912 +MODULE_AUTHOR("Maintainer: Suraj S Iyer <ssiyer@ti.com>");
913 +MODULE_DESCRIPTION("Driver for TI CPMAC");
914 +
915 +static int cfg_link_speed = 0;
916 +MODULE_PARM(cfg_link_speed, "i");
917 +MODULE_PARM_DESC(cfg_link_speed, "Fixed speed of the Link: <100/10>");
918 +
919 +static char *cfg_link_mode = NULL;
920 +MODULE_PARM(cfg_link_mode, "1-3s");
921 +MODULE_PARM_DESC(cfg_link_mode, "Fixed mode of the Link: <fd/hd>");
922 +
923 +int cpmac_debug_mode = 0;
924 +MODULE_PARM(debug_mode, "i");
925 +MODULE_PARM_DESC(debug_mode, "Turn on the debug info: <0/1>. Default is 0 (off)");
926 +
927 +#define dbgPrint if (cpmac_debug_mode) printk
928 +#define errPrint printk
929 +
930 +static int g_cfg_start_link_params = CFG_START_LINK_SPEED;
931 +static int g_init_enable_flag      = 0;
932 +static int cfg_start_link_speed;
933 +static int cpmac_max_frame_size;
934 +
935 +static struct net_device *g_dev_array[2];
936 +static struct proc_dir_entry *gp_stats_file = NULL;
937 +
938 +//-----------------------------------------------------------------------------
939 +// Statistics related private functions.
940 +//----------------------------------------------------------------------------- 
941 +static int  cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *len);
942 +static int  cpmac_p_read_rfc2665_stats(char *buf, char **start, off_t offset, int count, int *eof, void *data);
943 +static int  cpmac_p_read_link(char *buf, char **start, off_t offset, int count, int *eof, void *data);
944 +static int  cpmac_p_read_stats(char* buf, char **start, off_t offset, int count, int *eof, void *data);
945 +static int  cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data);
946 +static int  cpmac_p_reset_statistics (struct net_device *p_dev);
947 +static int  cpmac_p_get_version(char *buf, char **start, off_t offset, int count, int *eof, void *data);
948 +
949 +static int  cpmac_p_detect_manual_cfg(int, char*, int);
950 +static int  cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv);
951 +
952 +//-----------------------------------------------------------------------------
953 +// Timer related private functions.
954 +//-----------------------------------------------------------------------------
955 +static int  cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv);
956 +// static int  cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv);
957 +static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param);
958 +inline static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks);
959 +static int  cpmac_p_stop_timer(struct timer_list *p_timer);
960 +
961 +//------------------------------------------------------------------------------
962 +// Device configuration and setup related private functions.
963 +//------------------------------------------------------------------------------
964 +static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, unsigned long *p_dev_flags);
965 +static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv);
966 +inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan);
967 +
968 +//-----------------------------------------------------------------------------
969 +// Net device related private functions.
970 +//-----------------------------------------------------------------------------
971 +static int  cpmac_dev_init(struct net_device *p_dev);
972 +static int  cpmac_dev_open( struct net_device *dev );
973 +static int  cpmac_dev_close(struct net_device *p_dev);
974 +static void cpmac_dev_mcast_set(struct net_device *p_dev);
975 +static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr);
976 +static int  cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev);
977 +static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *dev);
978 +
979 +static int cpmac_p_dev_enable( struct net_device *p_dev);
980 +
981 +
982 +
983 +/* Max. Reserved headroom in front of each packet so that the headers can be added to
984 + * a packet. Worst case scenario would be PPPoE + 2684 LLC Encapsulation + Ethernet
985 + * header. */
986 +#define MAX_RESERVED_HEADROOM       20
987 +
988 +/* This is the MAX size of the static buffer for pure data. */
989 +#define MAX_SIZE_STATIC_BUFFER      1600
990 +
991 +typedef struct DRIVER_BUFFER
992 +{
993 +       /* Pointer to the allocated data buffer. This is the static data buffer 
994 +     * allocated for the TI-Cache. 60 bytes out of the below buffer are required
995 +     * by the SKB shared info. We always reserve at least MAX_RESERVED_HEADROOM bytes 
996 +     * so that the packets always have sufficient headroom. */
997 +       char                                    ptr_buffer[MAX_SIZE_STATIC_BUFFER + MAX_RESERVED_HEADROOM + 60];
998 +
999 +       /* List of the driver buffers. */
1000 +       struct DRIVER_BUFFER*   ptr_next;
1001 +}DRIVER_BUFFER;
1002 +
1003 +typedef struct DRIVER_BUFFER_MCB
1004 +{
1005 +       /* List of the driver buffers. */
1006 +       DRIVER_BUFFER*  ptr_available_driver_buffers;
1007 +
1008 +    /* The number of available buffers. */
1009 +    int                     num_available_buffers;
1010 +}DRIVER_BUFFER_MCB;
1011 +
1012 +DRIVER_BUFFER_MCB      driver_mcb;
1013 +int                 hybrid_mode = 0;
1014 +
1015 +static union {
1016 +       struct sk_buff_head     list;
1017 +       char                    pad[SMP_CACHE_BYTES];
1018 +} skb_head_pool[NR_CPUS];
1019 +
1020 +/**************************************************************************
1021 + * FUNCTION NAME : ti_release_skb
1022 + **************************************************************************
1023 + * DESCRIPTION   :
1024 + *  This function is called from the ti_alloc_skb when there were no more
1025 + *  data buffers available. The allocated SKB had to released back to the 
1026 + *  data pool. The reason why this function was moved from the fast path 
1027 + *  below was because '__skb_queue_head' is an inline function which adds
1028 + *  a large code chunk on the fast path.
1029 + *
1030 + * NOTES         :
1031 + *  This function is called with interrupts disabled. 
1032 + **************************************************************************/
1033 +static void ti_release_skb (struct sk_buff_head* list, struct sk_buff* skb)
1034 +{
1035 +    __skb_queue_head(list, skb);
1036 +    return;
1037 +}
1038 +
1039 +/**************************************************************************
1040 + * FUNCTION NAME : ti_alloc_skb
1041 + **************************************************************************
1042 + * DESCRIPTION   :
1043 + *  The function is called to allocate memory from the static allocated 
1044 + *  TI-Cached memory pool.
1045 + *
1046 + * RETURNS       :
1047 + *      Allocated static memory buffer - Success
1048 + *      NULL                           - Error.
1049 + **************************************************************************/
1050 +struct sk_buff *ti_alloc_skb(unsigned int size,int gfp_mask)
1051 +{
1052 +    register struct sk_buff*    skb;
1053 +    unsigned long               flags;
1054 +       struct sk_buff_head*        list;
1055 +       DRIVER_BUFFER*              ptr_node = NULL;
1056 +
1057 +    /* Critical Section Begin: Lock out interrupts. */
1058 +    local_irq_save(flags);
1059 +
1060 +    /* Get the SKB Pool list associated with the processor and dequeue the head. */
1061 +    list = &skb_head_pool[smp_processor_id()].list;
1062 +    skb = __skb_dequeue(list);
1063 +
1064 +    /* Align the data size. */
1065 +    size = SKB_DATA_ALIGN(size);
1066 +
1067 +    /* Did we get one. */
1068 +    if (skb != NULL)
1069 +    {
1070 +        /* YES. Now get a data block from the head of statically allocated block. */
1071 +        ptr_node = driver_mcb.ptr_available_driver_buffers;
1072 +           if (ptr_node != NULL)
1073 +        {
1074 +            /* YES. Got a data block. Advance the free list pointer to the next available buffer. */
1075 +               driver_mcb.ptr_available_driver_buffers = ptr_node->ptr_next;
1076 +            ptr_node->ptr_next = NULL;
1077 +
1078 +            /* Decrement the number of available data buffers. */
1079 +            driver_mcb.num_available_buffers = driver_mcb.num_available_buffers - 1;
1080 +        }
1081 +        else
1082 +        {
1083 +          /* NO. Was unable to get a data block. So put the SKB back on the free list. 
1084 +           * This is slow path. */
1085 +#ifdef DEBUG_SKB 
1086 +           printk ("DEBUG: No Buffer memory available: Number of free buffer:%d.\n",
1087 +                   driver_mcb.num_available_buffers);
1088 +#endif
1089 +           ti_release_skb (list, skb);
1090 +        }
1091 +    }
1092 +
1093 +    /* Critical Section End: Unlock interrupts. */
1094 +    local_irq_restore(flags);
1095 +
1096 +    /* Did we get an SKB and data buffer. Proceed only if we were succesful in getting both else drop */
1097 +    if (skb != NULL && ptr_node != NULL)
1098 +    {
1099 +               /* XXX: does not include slab overhead */ 
1100 +        skb->truesize = size + sizeof(struct sk_buff);
1101
1102 +        /* Load the data pointers. */
1103 +       skb->head = ptr_node->ptr_buffer;
1104 +        skb->data = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM;
1105 +           skb->tail = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM;
1106 +        skb->end  = ptr_node->ptr_buffer + size + MAX_RESERVED_HEADROOM;
1107 +
1108 +           /* Set up other state */
1109 +       skb->len    = 0;
1110 +       skb->cloned = 0;
1111 +        skb->data_len = 0;
1112 +    
1113 +        /* Mark the SKB indicating that the SKB is from the TI cache. */
1114 +        skb->cb[45] = 1;
1115 +
1116 +       atomic_set(&skb->users, 1); 
1117 +       atomic_set(&(skb_shinfo(skb)->dataref), 1);
1118 +        skb_shinfo(skb)->nr_frags = 0;
1119 +           skb_shinfo(skb)->frag_list = NULL;
1120 +        return skb;
1121 +    }
1122 +    else
1123 +    {
1124 +        /* Control comes here only when there is no statically allocated data buffers
1125 +         * available. This case is handled using the mode selected
1126 +         *
1127 +         * 1. Hybrid Mode.
1128 +         *  In that case lets jump to the old allocation code. This way we
1129 +         *  can allocate a small number of data buffers upfront and the rest will hit
1130 +         *  this portion of the code, which is slow path. Note the number of hits here
1131 +         *  should be kept as low as possible to satisfy performance requirements. 
1132 +         *
1133 +         * 2. Pure Static Mode.
1134 +         *  Return NULL the user should have tuned the number of static buffers for
1135 +         *  worst case scenario. So return NULL and let the drivers handle the error. */
1136 +        if (hybrid_mode == 1)
1137 +        {
1138 +            /* Hybrid Mode: Old allocation. */
1139 +            return dev_alloc_skb(size);
1140 +        }
1141 +        else
1142 +        {
1143 +            /* Pure Static Mode: No buffers available. */
1144 +            return NULL;
1145 +        }
1146 +    }
1147 +}
1148 +
1149 +/**************************************************************************
1150 + * FUNCTION NAME : ti_skb_release_fragment
1151 + **************************************************************************
1152 + * DESCRIPTION   :
1153 + *  This function is called to release fragmented packets. This is NOT in 
1154 + *  the fast path and this function requires some work. 
1155 + **************************************************************************/
1156 +static void ti_skb_release_fragment(struct sk_buff *skb)
1157 +{
1158 +    if (skb_shinfo(skb)->nr_frags)
1159 +    {
1160 +        /* PANKAJ TODO: This portion has not been tested. */
1161 +           int i;
1162 +#ifdef DEBUG_SKB 
1163 +        printk ("DEBUG: Releasing fragments in TI-Cached code.\n");
1164 +#endif
1165 +               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
1166 +                   printk ("DEBUG: Fragmented Page = 0x%p.\n", skb_shinfo(skb)->frags[i].page);
1167 +    }
1168 +
1169 +    /* Check if there were any fragments present and if so clean all the SKB's. 
1170 +     * This is required to recursivly clean the SKB's. */
1171 +       if (skb_shinfo(skb)->frag_list)
1172 +           skb_drop_fraglist(skb);
1173 +
1174 +    return;
1175 +}
1176 +
1177 +/**************************************************************************
1178 + * FUNCTION NAME : ti_skb_release_data
1179 + **************************************************************************
1180 + * DESCRIPTION   :
1181 + *  The function is called to release the SKB back into the TI-Cached static
1182 + *  memory pool. 
1183 + **************************************************************************/
1184 +static void ti_skb_release_data(struct sk_buff *skb)
1185 +{
1186 +    DRIVER_BUFFER*     ptr_node;
1187 +    unsigned long   flags;
1188 +
1189 +    /* The SKB data can be cleaned only if the packet has not been cloned and we
1190 +     * are the only one holding a reference to the data. */
1191 +       if (!skb->cloned || atomic_dec_and_test(&(skb_shinfo(skb)->dataref)))
1192 +    {
1193 +        /* Are there any fragments associated with the SKB ?*/
1194 +               if ((skb_shinfo(skb)->nr_frags != 0) || (skb_shinfo(skb)->frag_list != NULL))
1195 +        {
1196 +            /* Slow Path: Try and clean up the fragments. */
1197 +            ti_skb_release_fragment (skb);
1198 +        }
1199 +
1200 +        /* Cleanup the SKB data memory. This is fast path. */
1201 +        ptr_node = (DRIVER_BUFFER *)skb->head;
1202 +
1203 +        /* Critical Section: Lock out interrupts. */
1204 +        local_irq_save(flags);
1205 +
1206 +        /* Add the data buffer to the list of available buffers. */
1207 +        ptr_node->ptr_next = driver_mcb.ptr_available_driver_buffers;
1208 +           driver_mcb.ptr_available_driver_buffers = ptr_node;
1209 +
1210 +        /* Increment the number of available data buffers. */
1211 +        driver_mcb.num_available_buffers = driver_mcb.num_available_buffers + 1;
1212 +
1213 +        /* Criticial Section: Unlock interrupts. */
1214 +        local_irq_restore(flags);
1215 +       }
1216 +    return;
1217 +}
1218 +
1219 +
1220 +
1221 +
1222 +static unsigned char str2hexnum(unsigned char c)
1223 +{
1224 +        if(c >= '0' && c <= '9')
1225 +                return c - '0';
1226 +        if(c >= 'a' && c <= 'f')
1227 +                return c - 'a' + 10;
1228 +        if(c >= 'A' && c <= 'F')
1229 +                return c - 'A' + 10;
1230 +        return 0; 
1231 +}
1232 +
1233 +static void str2eaddr(unsigned char *ea, unsigned char *str)
1234 +{
1235 +    int i;
1236 +    unsigned char num;
1237 +    for(i = 0; i < 6; i++) {
1238 +        if((*str == '.') || (*str == ':'))
1239 +            str++;
1240 +        num = str2hexnum(*str++) << 4;
1241 +        num |= (str2hexnum(*str++));
1242 +        ea[i] = num;
1243 +    }
1244 +}
1245 +
1246 +//-----------------------------------------------------------------------------
1247 +// Statistics related private functions.
1248 +//-----------------------------------------------------------------------------
1249 +static int cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *p_len)
1250 +{
1251 +    int                 ret_val   = -1;
1252 +    unsigned long rx_hal_errors   = 0;
1253 +    unsigned long rx_hal_discards = 0;
1254 +    unsigned long tx_hal_errors   = 0;
1255 +    unsigned long ifOutDiscards   = 0;
1256 +    unsigned long ifInDiscards    = 0;
1257 +    unsigned long ifOutErrors     = 0;
1258 +    unsigned long ifInErrors      = 0;
1259 +
1260 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
1261 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cpmac_priv->drv_hal;
1262 +    CPMAC_DEVICE_MIB_T   *p_device_mib = p_cpmac_priv->device_mib;
1263 +    CPMAC_DRV_STATS_T    *p_stats      = p_cpmac_priv->stats;
1264 +    CPMAC_DEVICE_MIB_T   local_mib;
1265 +    CPMAC_DEVICE_MIB_T   *p_local_mib  = &local_mib;
1266 +
1267 +    struct net_device_stats *p_net_dev_stats = &p_cpmac_priv->net_dev_stats;
1268 +
1269 +    int                 len      = 0;
1270 +    int  dev_mib_elem_count      = 0;
1271 +
1272 +    /* do not access the hardware if it is in the reset state. */
1273 +    if(!test_bit(0, &p_cpmac_priv->set_to_close))
1274 +    {
1275 +        if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsDump", "Get",
1276 +                                        p_local_mib) != 0)
1277 +        {
1278 +            errPrint("The stats dump for %s is failing.\n", p_dev->name);
1279 +            return(ret_val);
1280 +        }
1281 +
1282 +        p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL);
1283 +
1284 +        dev_mib_elem_count = sizeof(CPMAC_DEVICE_MIB_T)/sizeof(unsigned long);
1285 +
1286 +        /* Update the history of the stats. This takes care of any reset of the 
1287 +         * device and stats that might have taken place during the life time of 
1288 +         * the driver. 
1289 +         */
1290 +        while(dev_mib_elem_count--)
1291 +        {
1292 +            *((unsigned long*) p_device_mib + dev_mib_elem_count) += 
1293 +            *((unsigned long*) p_local_mib  + dev_mib_elem_count); 
1294 +        }
1295 +    }
1296 +
1297 +    /* RFC2665, section 3.2.7, page 9 */
1298 +    rx_hal_errors          = p_device_mib->ifInFragments       +
1299 +                            p_device_mib->ifInCRCErrors       +
1300 +                            p_device_mib->ifInAlignCodeErrors +
1301 +                            p_device_mib->ifInJabberFrames;
1302 +
1303 +    /* RFC2233 */
1304 +    rx_hal_discards        = p_device_mib->ifRxDMAOverruns;
1305 +
1306 +    /* RFC2665, section 3.2.7, page 9 */
1307 +    tx_hal_errors          = p_device_mib->ifExcessiveCollisionFrames +
1308 +                             p_device_mib->ifLateCollisions           +
1309 +                             p_device_mib->ifCarrierSenseErrors       +
1310 +                             p_device_mib->ifOutUnderrun;
1311 +
1312 +    /* if not set, the short frames (< 64 bytes) are considered as errors */
1313 +    if(!p_cpmac_priv->flags & IFF_PRIV_SHORT_FRAMES)
1314 +        rx_hal_errors += p_device_mib->ifInUndersizedFrames;
1315 +
1316 +    /* if not set, the long frames ( > 1518) are considered as errors 
1317 +     * RFC2665, section 3.2.7, page 9. */
1318 +    if(!p_cpmac_priv->flags & IFF_PRIV_JUMBO_FRAMES)
1319 +        rx_hal_errors += p_device_mib->ifInOversizedFrames;
1320 +
1321 +    /* if not in promiscous, then non addr matching frames are discarded */
1322 +    /* CPMAC 2.0 Manual Section 2.8.1.14 */
1323 +    if(!p_dev->flags & IFF_PROMISC)
1324 +    {
1325 +        ifInDiscards  +=  p_device_mib->ifInFilteredFrames;
1326 +    }
1327 +
1328 +     /* total rx discards = hal discards + driver discards. */
1329 +    ifInDiscards  = rx_hal_discards + p_net_dev_stats->rx_dropped;
1330 +    ifInErrors    = rx_hal_errors;
1331 +
1332 +    ifOutErrors   = tx_hal_errors;
1333 +    ifOutDiscards = p_net_dev_stats->tx_dropped;
1334 +
1335 +    /* Let us update the net device stats struct. To be updated in the later releases.*/
1336 +    p_cpmac_priv->net_dev_stats.rx_errors  = ifInErrors;
1337 +    p_cpmac_priv->net_dev_stats.collisions = p_device_mib->ifCollisionFrames;
1338 +
1339 +    if(buf == NULL || limit == 0)
1340 +    {
1341 +        return(0);
1342 +    }
1343 +
1344 +    if(len <= limit)
1345 +        len+= sprintf(buf + len, "%-35s: %ld\n", "ifSpeed",                                 (long)p_cpmac_priv->link_speed);
1346 +    if(len <= limit)
1347 +        len+= sprintf(buf + len, "%-35s: %lu\n", "dot3StatsDuplexStatus",                   (long)p_cpmac_priv->link_mode);
1348 +    if(len <= limit)
1349 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifAdminStatus",                           (long)(p_dev->flags & IFF_UP ? 1:2));
1350 +    if(len <= limit)
1351 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOperStatus",                            (long)(((p_dev->flags & IFF_UP) && netif_carrier_ok(p_dev)) ? 1:2));
1352 +    if(len <= limit)
1353 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifLastChange",                            p_stats->start_tick);
1354 +    if(len <= limit)
1355 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInDiscards",                            ifInDiscards);
1356 +    if(len <= limit)
1357 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInErrors",                              ifInErrors);
1358 +    if(len <= limit)
1359 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutDiscards",                           ifOutDiscards);
1360 +    if(len <= limit)
1361 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutErrors",                             ifOutErrors);
1362 +    if(len <= limit)
1363 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInGoodFrames",                          p_device_mib->ifInGoodFrames);
1364 +    if(len <= limit)
1365 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInBroadcasts",                          p_device_mib->ifInBroadcasts);
1366 +    if(len <= limit)
1367 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInMulticasts",                          p_device_mib->ifInMulticasts);
1368 +    if(len <= limit)
1369 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInPauseFrames",                         p_device_mib->ifInPauseFrames);
1370 +    if(len <= limit)
1371 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInCRCErrors",                           p_device_mib->ifInCRCErrors);
1372 +    if(len <= limit)
1373 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInAlignCodeErrors",                     p_device_mib->ifInAlignCodeErrors);
1374 +    if(len <= limit)
1375 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOversizedFrames",                     p_device_mib->ifInOversizedFrames);
1376 +    if(len <= limit)
1377 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInJabberFrames",                        p_device_mib->ifInJabberFrames);
1378 +    if(len <= limit)
1379 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInUndersizedFrames",                    p_device_mib->ifInUndersizedFrames);
1380 +    if(len <= limit)
1381 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFragments",                           p_device_mib->ifInFragments);
1382 +    if(len <= limit)
1383 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFilteredFrames",                      p_device_mib->ifInFilteredFrames);
1384 +    if(len <= limit)
1385 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInQosFilteredFrames",                   p_device_mib->ifInQosFilteredFrames);
1386 +    if(len <= limit)
1387 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOctets",                              p_device_mib->ifInOctets);
1388 +    if(len <= limit)
1389 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutGoodFrames",                         p_device_mib->ifOutGoodFrames);
1390 +    if(len <= limit)
1391 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutBroadcasts",                         p_device_mib->ifOutBroadcasts);
1392 +    if(len <= limit)
1393 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutMulticasts",                         p_device_mib->ifOutMulticasts);
1394 +    if(len <= limit)
1395 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutPauseFrames",                        p_device_mib->ifOutPauseFrames);
1396 +    if(len <= limit)
1397 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifDeferredTransmissions",                 p_device_mib->ifDeferredTransmissions);
1398 +    if(len <= limit)
1399 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifCollisionFrames",                       p_device_mib->ifCollisionFrames);
1400 +    if(len <= limit)
1401 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifSingleCollisionFrames",                 p_device_mib->ifSingleCollisionFrames);
1402 +    if(len <= limit)
1403 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifMultipleCollisionFrames",               p_device_mib->ifMultipleCollisionFrames);
1404 +    if(len <= limit)
1405 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifExcessiveCollisionFrames",              p_device_mib->ifExcessiveCollisionFrames);
1406 +    if(len <= limit)
1407 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifLateCollisions",                        p_device_mib->ifLateCollisions);
1408 +    if(len <= limit)
1409 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutUnderrun",                           p_device_mib->ifOutUnderrun);
1410 +    if(len <= limit)
1411 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifCarrierSenseErrors",                    p_device_mib->ifCarrierSenseErrors);
1412 +    if(len <= limit)
1413 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutOctets",                             p_device_mib->ifOutOctets);
1414 +    if(len <= limit)
1415 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if64OctetFrames",                         p_device_mib->if64OctetFrames);
1416 +    if(len <= limit)
1417 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if65To127POctetFrames",                   p_device_mib->if65To127OctetFrames);
1418 +    if(len <= limit)
1419 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if128To255OctetFrames",                   p_device_mib->if128To255OctetFrames);
1420 +    if(len <= limit)
1421 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if256To511OctetFrames",                   p_device_mib->if256To511OctetFrames);
1422 +    if(len <= limit)
1423 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if512To1023OctetFrames",                  p_device_mib->if512To1023OctetFrames);
1424 +    if(len <= limit)
1425 +        len+= sprintf(buf + len, "%-35s: %lu\n", "if1024ToUpOctetFrames",                   p_device_mib->if1024ToUPOctetFrames);
1426 +    if(len <= limit)
1427 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifNetOctets",                             p_device_mib->ifNetOctets);
1428 +    if(len <= limit)
1429 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxSofOverruns",                         p_device_mib->ifRxSofOverruns);
1430 +    if(len <= limit)
1431 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxMofOverruns",                         p_device_mib->ifRxMofOverruns);
1432 +    if(len <= limit)
1433 +        len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxDMAOverruns",                         p_device_mib->ifRxDMAOverruns);
1434 +
1435 +    *p_len = len;
1436 +
1437 +    return(0);
1438 +}
1439 +
1440 +
1441 +static int cpmac_p_read_rfc2665_stats(char* buf, char **start, off_t offset, 
1442 +                              int count, int *eof, void *data)
1443 +{
1444 +    int limit = count - 80;
1445 +    int len   = 0;
1446 +    struct net_device *p_dev = (struct net_device*)data;
1447 +
1448 +    cpmac_p_update_statistics(p_dev, buf, limit, &len);
1449 +
1450 +    *eof = 1;
1451 +
1452 +    return len;
1453 +}
1454 +
1455 +static int cpmac_p_read_link(char *buf, char **start, off_t offset, int count, 
1456 +                             int *eof, void *data)
1457 +{
1458 +    int len = 0;
1459 +
1460 +    struct net_device    *p_dev;
1461 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv;
1462 +    struct net_device    *cpmac_dev_list[cpmac_devices_installed];
1463 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal;
1464 +
1465 +    int                  i;
1466 +    int                  phy;            /* what phy are we using? */
1467 +
1468 +    len += sprintf(buf+len, "CPMAC devices = %d\n",cpmac_devices_installed);
1469 +
1470 +    p_dev        = last_cpmac_device;
1471 +
1472 +    /* Reverse the the device link list to list eth0,eth1...in correct order */
1473 +    for(i=0; i< cpmac_devices_installed; i++)
1474 +    {
1475 +        cpmac_dev_list[cpmac_devices_installed -(i+1)] = p_dev;
1476 +        p_cpmac_priv = p_dev->priv;
1477 +        p_dev = p_cpmac_priv->next_device;
1478 +    }
1479 +
1480 +    for(i=0; i< cpmac_devices_installed; i++)
1481 +    {
1482 +        p_dev        = cpmac_dev_list[i];
1483 +        p_cpmac_priv = p_dev->priv;
1484 +        p_drv_hal    = p_cpmac_priv->drv_hal;
1485 +
1486 +        /*  This prints them out from high to low because of how the devices are linked */
1487 +        if(netif_carrier_ok(p_dev))
1488 +        {
1489 +            p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "PhyNum", "Get", &phy);
1490 +
1491 +
1492 +            len += sprintf(buf+len,"eth%d: Link State: %s    Phy:0x%x, Speed = %s, Duplex = %s\n",
1493 +                           p_cpmac_priv->instance_num, "UP", phy, 
1494 +                           (p_cpmac_priv->link_speed == 100000000) ? "100":"10",
1495 +                           (p_cpmac_priv->link_mode  == 2) ? "Half":"Full");
1496 +
1497 +        }
1498 +        else
1499 +            len += sprintf(buf+len,"eth%d: Link State: DOWN\n",p_cpmac_priv->instance_num);
1500 +
1501 +        p_dev = p_cpmac_priv->next_device;
1502 +    }
1503 +
1504 +    return len;
1505 +
1506 +}
1507 +
1508 +static int cpmac_p_read_stats(char* buf, char **start, off_t offset, int count,
1509 +                              int *eof, void *data)
1510 +{
1511 +    struct net_device *p_dev = last_cpmac_device;
1512 +    int                len   = 0;
1513 +    int                limit = count - 80;
1514 +    int i;
1515 +    struct net_device     *cpmac_dev_list[cpmac_devices_installed];
1516 +    CPMAC_PRIVATE_INFO_T  *p_cpmac_priv;
1517 +    CPMAC_DEVICE_MIB_T    *p_device_mib;
1518 +
1519 +    /* Reverse the the device link list to list eth0,eth1...in correct order */
1520 +    for(i=0; i< cpmac_devices_installed; i++)
1521 +    {
1522 +        cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev;
1523 +        p_cpmac_priv = p_dev->priv;
1524 +        p_dev = p_cpmac_priv->next_device;
1525 +    }
1526 +
1527 +    for(i=0; i< cpmac_devices_installed; i++)
1528 +    {
1529 +        p_dev = cpmac_dev_list[i];
1530 +
1531 +        if(!p_dev)
1532 +          goto proc_error;
1533 +
1534 +        /* Get Stats */
1535 +        cpmac_p_update_statistics(p_dev, NULL, 0, NULL);
1536 +
1537 +        p_cpmac_priv = p_dev->priv;
1538 +        p_device_mib = p_cpmac_priv->device_mib;
1539 +
1540 +        /* Transmit stats */
1541 +        if(len<=limit)
1542 +          len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1, p_dev->base_addr);
1543 +        if(len<=limit)
1544 +          len+= sprintf(buf+len, " Transmit Stats\n");
1545 +        if(len<=limit)
1546 +          len+= sprintf(buf+len, "   Tx Valid Bytes Sent        :%lu\n",p_device_mib->ifOutOctets);
1547 +        if(len<=limit)
1548 +          len+= sprintf(buf+len, "   Good Tx Frames (Hardware)  :%lu\n",p_device_mib->ifOutGoodFrames);
1549 +        if(len<=limit)
1550 +          len+= sprintf(buf+len, "   Good Tx Frames (Software)  :%lu\n",p_cpmac_priv->net_dev_stats.tx_packets);
1551 +        if(len<=limit)
1552 +          len+= sprintf(buf+len, "   Good Tx Broadcast Frames   :%lu\n",p_device_mib->ifOutBroadcasts);
1553 +        if(len<=limit)
1554 +          len+= sprintf(buf+len, "   Good Tx Multicast Frames   :%lu\n",p_device_mib->ifOutMulticasts);
1555 +        if(len<=limit)
1556 +          len+= sprintf(buf+len, "   Pause Frames Sent          :%lu\n",p_device_mib->ifOutPauseFrames);
1557 +        if(len<=limit)
1558 +          len+= sprintf(buf+len, "   Collisions                 :%lu\n",p_device_mib->ifCollisionFrames);
1559 +        if(len<=limit)
1560 +          len+= sprintf(buf+len, "   Tx Error Frames            :%lu\n",p_cpmac_priv->net_dev_stats.tx_errors);
1561 +        if(len<=limit)
1562 +          len+= sprintf(buf+len, "   Carrier Sense Errors       :%lu\n",p_device_mib->ifCarrierSenseErrors);
1563 +        if(len<=limit)
1564 +          len+= sprintf(buf+len, "\n");
1565 +
1566 +
1567 +        /* Receive Stats */
1568 +        if(len<=limit)
1569 +          len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1,p_dev->base_addr);
1570 +        if(len<=limit)
1571 +          len+= sprintf(buf+len, " Receive Stats\n");
1572 +        if(len<=limit)
1573 +          len+= sprintf(buf+len, "   Rx Valid Bytes Received    :%lu\n",p_device_mib->ifInOctets);
1574 +        if(len<=limit)
1575 +          len+= sprintf(buf+len, "   Good Rx Frames (Hardware)  :%lu\n",p_device_mib->ifInGoodFrames);
1576 +        if(len<=limit)
1577 +          len+= sprintf(buf+len, "   Good Rx Frames (Software)  :%lu\n",p_cpmac_priv->net_dev_stats.rx_packets);
1578 +        if(len<=limit)
1579 +          len+= sprintf(buf+len, "   Good Rx Broadcast Frames   :%lu\n",p_device_mib->ifInBroadcasts);
1580 +        if(len<=limit)
1581 +          len+= sprintf(buf+len, "   Good Rx Multicast Frames   :%lu\n",p_device_mib->ifInMulticasts);
1582 +        if(len<=limit)
1583 +          len+= sprintf(buf+len, "   Pause Frames Received      :%lu\n",p_device_mib->ifInPauseFrames);
1584 +        if(len<=limit)
1585 +          len+= sprintf(buf+len, "   Rx CRC Errors              :%lu\n",p_device_mib->ifInCRCErrors);
1586 +        if(len<=limit)
1587 +          len+= sprintf(buf+len, "   Rx Align/Code Errors       :%lu\n",p_device_mib->ifInAlignCodeErrors);
1588 +        if(len<=limit)
1589 +          len+= sprintf(buf+len, "   Rx Jabbers                 :%lu\n",p_device_mib->ifInOversizedFrames);
1590 +        if(len<=limit)
1591 +          len+= sprintf(buf+len, "   Rx Filtered Frames         :%lu\n",p_device_mib->ifInFilteredFrames);
1592 +        if(len<=limit)
1593 +          len+= sprintf(buf+len, "   Rx Fragments               :%lu\n",p_device_mib->ifInFragments);
1594 +        if(len<=limit)
1595 +          len+= sprintf(buf+len, "   Rx Undersized Frames       :%lu\n",p_device_mib->ifInUndersizedFrames);
1596 +        if(len<=limit)
1597 +          len+= sprintf(buf+len, "   Rx Overruns                :%lu\n",p_device_mib->ifRxDMAOverruns);
1598 +    }
1599 +
1600 +
1601 +    return len;
1602 +
1603 + proc_error:
1604 +    *eof=1;
1605 +    return len;
1606 +}
1607 +
1608 +static int cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data)
1609 +{
1610 +       char local_buf[31];
1611 +        int  ret_val = 0;
1612 +
1613 +       if(count > 30)
1614 +       {
1615 +               printk("Error : Buffer Overflow\n");
1616 +               printk("Use \"echo 0 > cpmac_stat\" to reset the statistics\n");
1617 +               return -EFAULT;
1618 +       }
1619 +
1620 +       copy_from_user(local_buf,buf,count);
1621 +       local_buf[count-1]='\0'; /* Ignoring last \n char */
1622 +        ret_val = count;
1623 +       
1624 +       if(strcmp("0",local_buf)==0)
1625 +       {
1626 +            struct net_device *p_dev = last_cpmac_device;
1627 +            int i;
1628 +            struct net_device     *cpmac_dev_list[cpmac_devices_installed];
1629 +            CPMAC_PRIVATE_INFO_T  *p_cpmac_priv;
1630 +
1631 +            /* Valid command */
1632 +           printk("Resetting statistics for CPMAC interface.\n");
1633 +
1634 +            /* Reverse the the device link list to list eth0,eth1...in correct order */
1635 +            for(i=0; i< cpmac_devices_installed; i++)
1636 +            {
1637 +                cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev;
1638 +                p_cpmac_priv = p_dev->priv;
1639 +                p_dev = p_cpmac_priv->next_device;
1640 +            }
1641 +
1642 +            for(i=0; i< cpmac_devices_installed; i++)
1643 +             {
1644 +                p_dev = cpmac_dev_list[i];
1645 +                if(!p_dev)
1646 +                {
1647 +                    ret_val = -EFAULT;
1648 +                    break;
1649 +                }
1650 +
1651 +                cpmac_p_reset_statistics(p_dev);
1652 +            }
1653 +       }
1654 +       else
1655 +       {
1656 +               printk("Error: Unknown operation on cpmac statistics\n");
1657 +               printk("Use \"echo 0 > cpmac_stats\" to reset the statistics\n");
1658 +               return -EFAULT;
1659 +       }
1660 +       
1661 +       return ret_val;
1662 +}
1663 +
1664 +static int cpmac_p_reset_statistics(struct net_device *p_dev)
1665 +{
1666 +    int                       ret_val  = 0;
1667 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
1668 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cpmac_priv->drv_hal;
1669 +
1670 +    memset(p_cpmac_priv->device_mib, 0, sizeof(CPMAC_DEVICE_MIB_T));
1671 +    memset(p_cpmac_priv->stats, 0, sizeof(CPMAC_DRV_STATS_T));
1672 +    memset(&p_cpmac_priv->net_dev_stats, 0, sizeof(struct net_device_stats));
1673 +
1674 +    p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL);
1675 +
1676 +    return(ret_val);
1677 +}
1678 +
1679 +static int cpmac_p_get_version(char* buf, char **start, off_t offset, int count,int *eof, void *data)
1680 +{
1681 +    int  len                           = 0;
1682 +    int  limit                         = count - 80;
1683 +    char *hal_version                  = NULL;
1684 +    struct net_device *p_dev           = last_cpmac_device;
1685 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
1686 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cpmac_priv->drv_hal;
1687 +
1688 +    p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Version", "Get", &hal_version);
1689 +
1690 +    len += sprintf(buf+len, "Texas Instruments CPMAC driver version: %s\n", cpmac_version);
1691 +
1692 +    if(len <= limit && hal_version)
1693 +        len += sprintf(buf+len, "Texas Instruments CPMAC HAL version: %s\n", hal_version);
1694 +
1695 +    return len;
1696 +}
1697 +
1698 +static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *p_dev)
1699 +{
1700 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv;
1701 +
1702 +    cpmac_p_update_statistics(p_dev, NULL, 0, NULL);
1703 +
1704 +    return &p_cpmac_priv->net_dev_stats;
1705 +}
1706 +
1707 +static int cpmac_p_detect_manual_cfg(int link_speed, char* link_mode, int debug)
1708 +{
1709 +    char *pSpeed = NULL;
1710 +
1711 +    if(debug == 1)
1712 +    {
1713 +        cpmac_debug_mode = 1;
1714 +        dbgPrint("Enabled the debug print.\n");
1715 +    }
1716 +
1717 +    if(!link_speed && !link_mode)
1718 +    {
1719 +        dbgPrint("No manual link params, defaulting to auto negotiation.\n");
1720 +        return (0);
1721 +    }
1722 +
1723 +    if(!link_speed || (link_speed != 10 && link_speed != 100))
1724 +    {
1725 +        dbgPrint("Invalid or No value of link speed specified, defaulting to auto speed.\n");
1726 +        pSpeed = "auto";
1727 +    }
1728 +    else if(link_speed == 10)
1729 +    {
1730 +        g_cfg_start_link_params &= ~(_CPMDIO_100);
1731 +        pSpeed = "10 Mbps";
1732 +    }
1733 +    else
1734 +    {
1735 +       g_cfg_start_link_params &= ~(_CPMDIO_10);
1736 +        pSpeed = "100 Mbps";
1737 +    }
1738 +
1739 +    if(!link_mode || (!strcmp(link_mode, "fd") && !strcmp(link_mode, "hd")))
1740 +    {
1741 +        dbgPrint("Invalid or No value of link mode specified, defaulting to auto mode.\n");
1742 +    }
1743 +    else if(!strcmp(link_mode, "hd"))
1744 +    {
1745 +        g_cfg_start_link_params &= ~(_CPMDIO_FD);
1746 +    }
1747 +    else
1748 +    {
1749 +        g_cfg_start_link_params &= ~(_CPMDIO_HD);
1750 +    }
1751 +
1752 +    dbgPrint("Link is manually set to the speed of %s speed and %s mode.\n", 
1753 +              pSpeed, link_mode ? link_mode : "auto");
1754 +
1755 +    return(0);
1756 +}
1757 +
1758 +//------------------------------------------------------------------------------
1759 +// Call back from the HAL.
1760 +//------------------------------------------------------------------------------
1761 +static int cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv)
1762 +{
1763 +    struct net_device    *p_dev        = p_cpmac_priv->owner;
1764 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cpmac_priv->drv_hal;
1765 +    int status;
1766 +
1767 +    p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Status", "Get", &status);
1768 +
1769 +    /* We do not reflect the real link status if in loopback.
1770 +     * After all, we want the packets to reach the hardware so
1771 +     * that Send() should work. */
1772 +    if(p_dev->flags & IFF_LOOPBACK)
1773 +    {
1774 +        dbgPrint("Maintaining the link up loopback for %s.\n", p_dev->name);
1775 +       netif_carrier_on(p_dev);
1776 +
1777 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
1778 +//        avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON);
1779 +//#endif
1780 +
1781 +        return(0);
1782 +    }
1783 +
1784 +    if(status & CPMAC_STATUS_ADAPTER_CHECK) /* ???? */
1785 +    {
1786 +        ; /* what to do ? */
1787 +    }    
1788 +    else if(status)
1789 +    {
1790 +        if(!netif_carrier_ok(p_dev))
1791 +       {
1792 +            netif_carrier_on(p_cpmac_priv->owner);
1793 +
1794 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
1795 +//            avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON);
1796 +//#endif
1797 +           dbgPrint("Found the Link for the CPMAC instance %s.\n", p_dev->name);
1798 +        }
1799 +
1800 +        if(netif_running(p_dev) & netif_queue_stopped(p_dev))
1801 +        {
1802 +            netif_wake_queue(p_dev);
1803 +        }
1804 +
1805 +       p_cpmac_priv->link_speed = status & CPMAC_STATUS_LINK_SPEED ? 100000000:10000000;
1806 +       p_cpmac_priv->link_mode  = status & CPMAC_STATUS_LINK_DUPLEX? 3:2;
1807 +
1808 +    }
1809 +    else
1810 +    {
1811 +        if(netif_carrier_ok(p_dev))
1812 +       {
1813 +           /* do we need to register synchronization issues with stats here. */
1814 +           p_cpmac_priv->link_speed        = 100000000;
1815 +           p_cpmac_priv->link_mode         = 1;
1816 +
1817 +           netif_carrier_off(p_dev);
1818 +
1819 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
1820 +//            avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF);
1821 +//#endif
1822 +
1823 +           dbgPrint("Lost the Link for the CPMAC for %s.\n", p_dev->name);
1824 +       }
1825 +
1826 +        if(!netif_queue_stopped(p_dev))
1827 +        {
1828 +            netif_stop_queue(p_dev);     /* So that kernel does not keep on xmiting pkts. */
1829 +        }
1830 +    }
1831 +
1832 +    return(0);
1833 +}
1834 +
1835 +//-----------------------------------------------------------------------------
1836 +// Timer related private functions.
1837 +//-----------------------------------------------------------------------------
1838 +static int cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv)
1839 +{
1840 +    struct timer_list *p_timer = p_cpmac_priv->timer;
1841 +
1842 +    init_timer(p_timer);
1843 +    
1844 +    p_timer                    = p_cpmac_priv->timer + TICK_TIMER;
1845 +    p_timer->expires           = 0;
1846 +    p_timer->data              = (unsigned long)p_cpmac_priv;
1847 +    p_timer->function          = cpmac_p_tick_timer_expiry;
1848 +
1849 +    return(0);
1850 +}
1851 +
1852 +#if 0
1853 +static int cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv)
1854 +{
1855 +    struct timer_list *p_timer;
1856 +
1857 +    p_timer = p_cpmac_priv->timer + TICK_TIMER;
1858 +   
1859 +    /* use spin lock to establish synchronization with the dispatch */
1860 +    if(p_timer->function) del_timer_sync(p_timer);
1861 +    p_timer->function = NULL;
1862 +
1863 +    return (0);
1864 +}
1865 +#endif
1866 +
1867 +static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks)
1868 +{
1869 +    p_timer->expires        = jiffies + delay_ticks;
1870 +
1871 +    if(p_timer->function)
1872 +    {
1873 +        add_timer(p_timer);
1874 +    }
1875 +
1876 +    return(0);
1877 +} 
1878 +
1879 +static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param)
1880 +{
1881 +    CPMAC_PRIVATE_INFO_T   *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T*) p_cb_param;
1882 +    CPMAC_DRV_HAL_INFO_T   *p_drv_hal    = p_cpmac_priv->drv_hal; 
1883 +    struct timer_list       *p_timer     = p_cpmac_priv->timer + TICK_TIMER;
1884 +
1885 +    if(test_bit(0, &p_cpmac_priv->set_to_close))
1886 +    {
1887 +        return;
1888 +    }
1889 +
1890 +    p_drv_hal->hal_funcs->Tick(p_drv_hal->hal_dev);
1891 +  
1892 +    cpmac_p_start_timer(p_timer, p_cpmac_priv->delay_ticks);
1893 +}
1894 +
1895 +static int cpmac_p_stop_timer(struct timer_list *p_timer)
1896 +{
1897 +    /* Ideally we need to a set flag indicating not to start the timer again
1898 +       before del_timer_sync() is called up. But here we assume that the 
1899 +       caller has set the p_cpmac_priv->set_to_close (ok for now). */
1900 +    del_timer_sync(p_timer);
1901 +    
1902 +    return(0);
1903 +}
1904 +
1905 +//------------------------------------------------------------------------------
1906 +// Device configuration and setup related private functions.
1907 +//------------------------------------------------------------------------------
1908 +static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, 
1909 +                                         unsigned long *p_dev_flags)
1910 +{
1911 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal   = p_cpmac_priv->drv_hal;
1912 +    HAL_FUNCTIONS        *p_hal_funcs = p_drv_hal->hal_funcs;
1913 +    HAL_DEVICE           *p_hal_dev   = p_drv_hal->hal_dev;
1914 +    CPMAC_ABILITY_INFO_T *p_capability= p_cpmac_priv->ability_info;
1915 +    unsigned int         val          = 0;
1916 +    int                  channel      = 0;
1917 +
1918 +    p_cpmac_priv->flags                  = 0;
1919 +
1920 +    p_capability->promiscous             = CFG_PROMISCOUS;
1921 +    p_capability->broadcast              = CFG_BROADCAST;
1922 +    p_capability->multicast              = CFG_MULTICAST;
1923 +    p_capability->all_multi              = CFG_ALL_MULTI;
1924 +    p_capability->jumbo_frames           = CFG_JUMBO_FRAMES;
1925 +    p_capability->short_frames           = CFG_SHORT_FRAMES;
1926 +    p_capability->auto_negotiation       = CFG_AUTO_NEGOTIATION;
1927 +    p_capability->link_speed             = cfg_start_link_speed;
1928 +    p_capability->loop_back              = CFG_LOOP_BACK;
1929 +    p_capability->tx_flow_control        = CFG_TX_FLOW_CNTL;
1930 +    p_capability->rx_flow_control        = CFG_RX_FLOW_CNTL;
1931 +    p_capability->tx_pacing              = CFG_TX_PACING;
1932 +    p_capability->rx_pass_crc            = CFG_RX_PASS_CRC;
1933 +    p_capability->qos_802_1q             = CFG_QOS_802_1Q;
1934 +    p_capability->tx_num_chan            = CFG_TX_NUM_CHAN;
1935 +
1936 +    /* Lets probe the device for the configured capabilities (netdev specific).*/ 
1937 +
1938 +    /* Following are set in the set_multi_list, when indicated by the kernel 
1939 +     * Promiscous and all multi.
1940 +     */
1941 +
1942 +    if(p_capability->broadcast)
1943 +    {
1944 +        channel = 0;
1945 +       val     = 1;
1946 +        if((p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_EN, pszSet, &val) == 0) && 
1947 +           (p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_CH, pszSet, &channel) == 0))
1948 +           *p_dev_flags |= IFF_BROADCAST;
1949 +       else
1950 +           p_capability->broadcast = 0; /* no broadcast capabilities */
1951 +    }
1952 +
1953 +    if(p_capability->multicast)
1954 +    {
1955 +        val     = 1;
1956 +       channel = 0;
1957 +       if((p_hal_funcs->Control(p_hal_dev, pszRX_MULT_EN, pszSet, &val) == 0) &&
1958 +          (p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel) == 0))
1959 +           *p_dev_flags |= IFF_MULTICAST;
1960 +       else
1961 +       {
1962 +           p_capability->multicast = 0; 
1963 +           p_capability->all_multi = 0; /* no multicast, no all-multi. */
1964 +       }
1965 +    }
1966 +
1967 +    if(p_capability->loop_back)
1968 +    {
1969 +        ;  /* We do not put the device in loopback, if required use ioctl */
1970 +    }
1971 +    
1972 +    /* Lets probe the device for the configured capabilities (Non net device specific).*/
1973 +
1974 +    if(p_capability->jumbo_frames)
1975 +    {
1976 +       val = 0;
1977 +        if(p_hal_funcs->Control(p_hal_dev, pszRX_NO_CHAIN, pszSet, &val) == 0)
1978 +            p_cpmac_priv->flags |= IFF_PRIV_JUMBO_FRAMES;
1979 +       else
1980 +           p_capability->jumbo_frames = 0;
1981 +    }
1982 +
1983 +    if(p_capability->short_frames)
1984 +    {
1985 +       val = 1;
1986 +        if(p_hal_funcs->Control(p_hal_dev, pszRX_CSF_EN, pszSet, &val) == 0)
1987 +            p_cpmac_priv->flags |= IFF_PRIV_SHORT_FRAMES;
1988 +       else
1989 +           p_capability->short_frames = 0;
1990 +    }            
1991 +
1992 +    val = g_cfg_start_link_params;
1993 +
1994 +#ifdef CONFIG_AR7_MDIX
1995 +    if( avalanche_is_mdix_on_chip() )
1996 +    {
1997 +        val |= _CPMDIO_AUTOMDIX;
1998 +    }
1999 +#endif 
2000 +
2001 +    if(p_hal_funcs->Control(p_hal_dev,pszMdioConnect,pszSet, &val) !=0)
2002 +    {
2003 +        p_capability->link_speed = 0;
2004 +    }
2005 +    else
2006 +    {
2007 +       if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD | _CPMDIO_10))
2008 +            p_cpmac_priv->flags |= IFF_PRIV_AUTOSPEED;
2009 +       else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD))
2010 +           p_cpmac_priv->flags |= IFF_PRIV_LINK100_HD;
2011 +       else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_FD))
2012 +           p_cpmac_priv->flags |= IFF_PRIV_LINK100_FD;
2013 +       else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_HD))
2014 +           p_cpmac_priv->flags |= IFF_PRIV_LINK10_HD;
2015 +       else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_FD))
2016 +           p_cpmac_priv->flags |= IFF_PRIV_LINK10_FD;
2017 +       else
2018 +           ;
2019 +    }
2020 +
2021 +    if(p_capability->tx_flow_control)
2022 +    {
2023 +       val = 1;
2024 +        if(p_hal_funcs->Control(p_hal_dev,pszTX_FLOW_EN, pszSet, &val) ==0)
2025 +            p_cpmac_priv->flags |= IFF_PRIV_TX_FLOW_CNTL;
2026 +       else
2027 +            p_capability->tx_flow_control = 0;
2028 +    }
2029 +
2030 +    if(p_capability->rx_flow_control)
2031 +    {
2032 +       val = 1;
2033 +        if(p_hal_funcs->Control(p_hal_dev, pszRX_FLOW_EN, pszSet, &val) ==0)
2034 +           p_cpmac_priv->flags |= IFF_PRIV_RX_FLOW_CNTL;
2035 +       else
2036 +            p_capability->rx_flow_control = 0;
2037 +    }
2038 +
2039 +    if(p_capability->tx_pacing)
2040 +    {
2041 +       val = 1;
2042 +        if(p_hal_funcs->Control(p_hal_dev, pszTX_PACE, pszSet, &val) ==0)
2043 +            p_cpmac_priv->flags |= IFF_PRIV_TX_PACING;
2044 +       else
2045 +           p_capability->tx_pacing = 0;
2046 +    }
2047 +
2048 +    if(p_capability->rx_pass_crc)
2049 +    {
2050 +       val = 1;
2051 +       if(p_hal_funcs->Control(p_hal_dev, pszRX_PASS_CRC, pszSet, &val) == 0)
2052 +           p_cpmac_priv->flags |= IFF_PRIV_RX_PASS_CRC;
2053 +       else                                  
2054 +            p_capability->rx_pass_crc = 0;
2055 +    }
2056 +
2057 +    if(p_capability->qos_802_1q)
2058 +    {
2059 +       val  = 1;
2060 +        if(p_hal_funcs->Control(p_hal_dev, pszRX_QOS_EN, pszSet, &val) == 0)
2061 +            p_cpmac_priv->flags |= IFF_PRIV_8021Q_EN;
2062 +       else
2063 +       {
2064 +           p_capability->qos_802_1q = 0;
2065 +           p_capability->tx_num_chan= 1;
2066 +        }
2067 +    }
2068 +
2069 +    if(p_capability->tx_num_chan > 1)
2070 +    {
2071 +       int cfg_tx_num_chan = p_capability->tx_num_chan;
2072 +        val = 0;
2073 +#ifdef TEST
2074 +       if(p_hal_funcs->Control(p_hal_dev, pszTX_NUM_CH, pszGet, &val) == 0)
2075 +           cfg_tx_num_chan = cfg_tx_num_chan > val ? val : cfg_tx_num_chan;
2076 +       else 
2077 +           cfg_tx_num_chan = 1;
2078 +#endif
2079 +       p_capability->tx_num_chan = cfg_tx_num_chan;
2080 +    }
2081 +
2082 +    return(0);
2083 +}
2084 +
2085 +static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv)
2086 +{
2087 +   int i=0;
2088 +   int threshold = CFG_TX_NUM_BUF_SERVICE;
2089 +
2090 +   char *tx_threshold_ptr = prom_getenv("threshold");
2091 +   
2092 +    CPMAC_TX_CHAN_INFO_T *p_tx_chan_info = p_cpmac_priv->tx_chan_info;
2093 +    CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info;
2094 +    CPMAC_ABILITY_INFO_T *p_capability   = p_cpmac_priv->ability_info;
2095 +
2096 +    /* Timer stuff */
2097 +    p_cpmac_priv->timer_count      = 1; /* should be < or = the MAX TIMER */
2098 +    p_cpmac_priv->timer_created    = 0;
2099 +    p_cpmac_priv->timer_access_hal = 1;
2100 +
2101 +    for(i=0; i < MAX_TIMER; i++)
2102 +        p_cpmac_priv->timer[i].function = NULL;
2103 +
2104 +    p_cpmac_priv->enable_802_1q  = p_capability->qos_802_1q;  
2105 +
2106 +    /* Tx channel related.*/
2107 +    p_tx_chan_info->cfg_chan     = p_capability->tx_num_chan;
2108 +    p_tx_chan_info->opened_chan  = 0;
2109 +    
2110 +    if(tx_threshold_ptr)
2111 +       threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10);
2112 +    
2113 +    if((threshold <= 0) && tx_threshold_ptr) /* If threshold set to 0 then Enable the TX interrupt */
2114 +    {
2115 +       threshold  = CFG_TX_NUM_BUF_SERVICE;
2116 +       p_tx_chan_info->tx_int_disable = 0;
2117 +       
2118 +    }
2119 +    else
2120 +    {
2121 +       p_tx_chan_info->tx_int_disable = CFG_TX_INT_DISABLE;
2122 +    }
2123 +
2124 +    for(i=0; i < MAX_TX_CHAN; i++)
2125 +    {
2126 +       
2127 +
2128 +
2129 +       p_tx_chan_info->chan[i].state         = CHAN_CLOSE; 
2130 +       p_tx_chan_info->chan[i].num_BD        = CFG_TX_NUM_BUF_DESC;  
2131 +       p_tx_chan_info->chan[i].buffer_size   = cpmac_max_frame_size;
2132 +       p_tx_chan_info->chan[i].buffer_offset = CFG_TX_BUF_OFFSET;
2133 +
2134 +
2135 +
2136 +       p_tx_chan_info->chan[i].service_max   = threshold;
2137 +    }
2138 +    
2139 +    if (p_tx_chan_info->tx_int_disable)
2140 +       printk("Cpmac driver Disable TX complete interrupt setting threshold to %d.\n",threshold);
2141 +    else
2142 +       printk("Cpmac driver Enable TX complete interrupt\n");
2143 +
2144 +    
2145 +    /* Assuming just one rx channel for now */
2146 +    p_rx_chan_info->cfg_chan            = 1;
2147 +    p_rx_chan_info->opened_chan         = 0;
2148 +    p_rx_chan_info->chan->state         = CHAN_CLOSE;
2149 +    p_rx_chan_info->chan->num_BD        = CFG_RX_NUM_BUF_DESC;
2150 +    p_rx_chan_info->chan->buffer_size   = cpmac_max_frame_size;
2151 +    p_rx_chan_info->chan->buffer_offset = CFG_RX_BUF_OFFSET;
2152 +    p_rx_chan_info->chan->service_max   = CFG_RX_NUM_BUF_SERVICE;
2153 +
2154 +    /* Set as per RFC 2665 */
2155 +    p_cpmac_priv->link_speed     = 100000000; 
2156 +    p_cpmac_priv->link_mode      = 1;
2157 +
2158 +    p_cpmac_priv->loop_back      = 0;
2159 +
2160 +    return(0);
2161 +}
2162 +
2163 +inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan)
2164 +{
2165 +    /* Number of ethernet packets & max pkt length */
2166 +    p_rx_chan->chan->tot_buf_size  = p_rx_chan->chan->buffer_size   + 
2167 +                                     2*(CONTROL_802_1Q_SIZE)        +
2168 +                                    p_rx_chan->chan->buffer_offset +
2169 +                                     ADD_FOR_4BYTE_ALIGN(p_rx_chan->chan->buffer_offset & 0x3);
2170 +
2171 +    p_rx_chan->chan->tot_reserve_bytes = CONTROL_802_1Q_SIZE + 
2172 +                                         p_rx_chan->chan->buffer_offset +
2173 +                                        L3_ALIGN(p_rx_chan->chan->buffer_offset & 0x3);
2174 +
2175 +    return(0);
2176 +}
2177 +
2178 +//-----------------------------------------------------------------------------
2179 +// Net device related private functions.
2180 +//-----------------------------------------------------------------------------
2181 +
2182 +/***************************************************************
2183 + *     cpmac_dev_init
2184 + *
2185 + *     Returns:
2186 + *             0 on success, error code otherwise.
2187 + *     Parms:
2188 + *             dev     The structure of the device to be
2189 + *                     init'ed.
2190 + *
2191 + *     This function completes the initialization of the
2192 + *     device structure and driver.  It reserves the IO
2193 + *     addresses and assignes the device's methods.
2194 + *
2195 + *     
2196 + **************************************************************/
2197 +
2198 +static int cpmac_dev_init(struct net_device *p_dev)
2199 +{
2200 +    int retVal = -1;
2201 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
2202 +    int instance_num                   = p_cpmac_priv->instance_num;
2203 +    unsigned long net_flags = 0;
2204 +    char *mac_name          = NULL;
2205 +    char *mac_string        = NULL;
2206 +
2207 +    CPMAC_TX_CHAN_INFO_T *p_tx_chan_info;
2208 +    CPMAC_RX_CHAN_INFO_T *p_rx_chan_info;
2209 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal;
2210 +    int i;
2211 +
2212 +    int mem_size =    sizeof(CPMAC_DRV_HAL_INFO_T)
2213 +                   + sizeof(CPMAC_TX_CHAN_INFO_T)
2214 +                   + sizeof(CPMAC_RX_CHAN_INFO_T)
2215 +                   + sizeof(CPMAC_ABILITY_INFO_T)
2216 +                    + sizeof(CPMAC_DEVICE_MIB_T)
2217 +                    + sizeof(CPMAC_DRV_STATS_T);
2218 +
2219 +
2220 +#if defined(CONFIG_MIPS_SEAD2)
2221 +    int prev_reset_val = RESET_REG_PRCR;
2222 +    /* Bring the module out of reset */
2223 +    RESET_REG_PRCR |= temp_reset_value[p_cpmac_priv->instance_num];     
2224 +
2225 +    /* Read the version id of the device to check if the device really exists */
2226 +    if( VERSION(temp_base_address[p_cpmac_priv->instance_num]) == 0)
2227 +    {
2228 +        printk(" CPMAC:Device not found\n");
2229 +       RESET_REG_PRCR = prev_reset_val;
2230 +        return -ENODEV;
2231 +    }
2232 +
2233 +    RESET_REG_PRCR = prev_reset_val;
2234 +#endif
2235 +
2236 +
2237 +    if((p_drv_hal = kmalloc(mem_size,  GFP_KERNEL)) == NULL)
2238 +    {
2239 +        errPrint("Failed to allocate memory; rewinding.\n");
2240 +        return(-1);
2241 +    }
2242 +
2243 +    memset(p_drv_hal, 0, mem_size);
2244 +
2245 +    /* build the cpmac private object */
2246 +    p_cpmac_priv->drv_hal       = p_drv_hal;
2247 +    p_cpmac_priv->tx_chan_info  = p_tx_chan_info
2248 +                                = (CPMAC_TX_CHAN_INFO_T*)((char*)p_drv_hal 
2249 +                                 + sizeof(CPMAC_DRV_HAL_INFO_T));
2250 +    p_cpmac_priv->rx_chan_info  = p_rx_chan_info 
2251 +                                = (CPMAC_RX_CHAN_INFO_T*)((char *)p_tx_chan_info 
2252 +                                 + sizeof(CPMAC_TX_CHAN_INFO_T));
2253 +    p_cpmac_priv->ability_info  = (CPMAC_ABILITY_INFO_T *)((char *)p_rx_chan_info 
2254 +                                 + sizeof(CPMAC_RX_CHAN_INFO_T));
2255 +    p_cpmac_priv->device_mib    = (CPMAC_DEVICE_MIB_T *)((char *)p_cpmac_priv->ability_info 
2256 +                                 + sizeof(CPMAC_ABILITY_INFO_T));
2257 +    p_cpmac_priv->stats         = (CPMAC_DRV_STATS_T *)((char *)p_cpmac_priv->device_mib   
2258 +                                 + sizeof(CPMAC_DEVICE_MIB_T));
2259 +
2260 +    p_drv_hal->owner            = p_cpmac_priv;
2261 +
2262 +
2263 +    switch(instance_num)
2264 +    {
2265 +
2266 +        case 0:
2267 +            mac_name="maca";
2268 +
2269 +            /* Also setting port information */
2270 +            p_dev->if_port =  AVALANCHE_CPMAC_LOW_PORT_ID;            
2271 +
2272 +            break;
2273 +
2274 +        case 1:
2275 +            mac_name="macb";
2276 +
2277 +            /* Also setting port information */
2278 +            p_dev->if_port =  AVALANCHE_CPMAC_HIGH_PORT_ID;            
2279 +
2280 +            break;
2281 +    }
2282 +
2283 +    if(mac_name)
2284 +        mac_string=prom_getenv(mac_name);
2285 +
2286 +    if(!mac_string)
2287 +    {
2288 +        mac_string="08.00.28.32.06.02";
2289 +        printk("Error getting mac from Boot enviroment for %s\n",p_dev->name);
2290 +        printk("Using default mac address: %s\n",mac_string);
2291 +        if(mac_name)
2292 +        {
2293 +            printk("Use Bootloader command:\n");
2294 +            printk("    setenv %s xx.xx.xx.xx.xx.xx\n","<env_name>");
2295 +            printk("to set mac address\n");
2296 +        }
2297 +    }
2298 +
2299 +    str2eaddr(p_cpmac_priv->mac_addr,mac_string);
2300 +
2301 +    for (i=0; i <= ETH_ALEN; i++)
2302 +    {
2303 +        /* This sets the hardware address */
2304 +       p_dev->dev_addr[i] = p_cpmac_priv->mac_addr[i]; 
2305 +    }
2306 +
2307 +    p_cpmac_priv->set_to_close          = 1;
2308 +    p_cpmac_priv->non_data_irq_expected = 0;
2309 +
2310 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
2311 +//    if((p_cpmac_priv->led_handle = avalanche_led_register("cpmac", instance_num)) == NULL)
2312 +//   {
2313 +//        errPrint("Could not allocate handle for CPMAC[%d] LED.\n", instance_num);
2314 +//       goto cpmac_init_mod_error;
2315 +//    }
2316 +//#endif
2317 +
2318 +    if(cpmac_drv_init_module(p_drv_hal, p_dev, instance_num) != 0)
2319 +    {
2320 +        errPrint("Could not initialize the HAL for %s.\n", p_dev->name);
2321 +        goto cpmac_init_mod_error;
2322 +    } 
2323 +
2324 +    /* initialize the CPMAC device */
2325 +    if (cpmac_drv_init(p_drv_hal) == -1)
2326 +    {
2327 +       errPrint("HAL init failed for %s.\n", p_dev->name);
2328 +       goto cpmac_init_device_error;
2329 +    }
2330 +
2331 +    if(cpmac_p_probe_and_setup_device(p_cpmac_priv, &net_flags) == -1)
2332 +    {
2333 +        errPrint("Failed to configure up %s.\n", p_dev->name);
2334 +        goto cpmac_init_device_error;
2335 +    }
2336 +
2337 +    if(cpmac_p_setup_driver_params(p_cpmac_priv) == -1)
2338 +    {
2339 +        errPrint("Failed to set driver parameters for %s.\n", p_dev->name);
2340 +        goto cpmac_init_device_error;
2341 +    }
2342 +
2343 +    cpmac_p_rx_buf_setup(p_rx_chan_info);
2344 +
2345 +    /* initialize the timers for the net device */
2346 +    if(cpmac_p_timer_init(p_cpmac_priv) == -1)
2347 +    {
2348 +        errPrint("Failed to set timer(s) for %s.\n", p_dev->name);
2349 +        goto cpmac_timer_init_error;
2350 +    }
2351 +
2352 +    p_dev->addr_len           = 6;
2353 +
2354 +    p_dev->open               = &cpmac_dev_open;    /*  i.e. Start Device  */
2355 +    p_dev->hard_start_xmit    = &cpmac_dev_tx;
2356 +    p_dev->stop               = &cpmac_dev_close;
2357 +    p_dev->get_stats          = &cpmac_dev_get_net_stats;
2358 +
2359 +    p_dev->set_multicast_list = &cpmac_dev_mcast_set;
2360 +    p_dev->set_mac_address    = cpmac_dev_set_mac_addr;
2361 +    /* Knocking off the default broadcast and multicast flags. Allowing the 
2362 +       device configuration to control the flags. */
2363 +    p_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
2364 +    p_dev->flags |= net_flags;
2365 +
2366 +    netif_carrier_off(p_dev);
2367 +
2368 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
2369 +//    avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF);
2370 +//#endif
2371 +
2372 +    /* Tasklet is initialized at the isr registeration time. */
2373 +    p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacBase", "Get", &p_dev->base_addr);
2374 +    p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacSize", "Get", &p_cpmac_priv->dev_size);
2375 +
2376 +    request_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size, p_dev->name);
2377 +
2378 +    retVal = 0;
2379 +
2380 +    if(g_init_enable_flag)
2381 +        cpmac_p_dev_enable(p_dev);
2382 +
2383 +    return(retVal);
2384 +
2385 +cpmac_timer_init_error:
2386 +cpmac_init_device_error  :
2387 +    cpmac_drv_cleanup(p_drv_hal);
2388 +
2389 +cpmac_init_mod_error:
2390 +    kfree(p_drv_hal);
2391 +
2392 +    return (retVal);
2393 +
2394 +} /* cpmac_dev_init */
2395 +
2396 +
2397 +/***************************************************************
2398 + *     cpmac_p_dev_enable
2399 + *
2400 + *     Returns:
2401 + *             0 on success, error code otherwise.
2402 + *     Parms:
2403 + *             dev     Structure of device to be opened.
2404 + *
2405 + *     This routine puts the driver and CPMAC adapter in a
2406 + *     state where it is ready to send and receive packets.
2407 + *     
2408 + *
2409 + **************************************************************/
2410 +int cpmac_p_dev_enable( struct net_device *p_dev)
2411 +{
2412 +    int ret_val = 0;
2413 +    int channel = 0;
2414
2415 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_dev->priv;
2416 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal      = p_cpmac_priv->drv_hal;
2417 +    CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info;
2418 +    int max_length                       = p_rx_chan_info->chan->tot_buf_size;
2419 +
2420 +    p_cpmac_priv->set_to_close = 0;
2421 +
2422 +    if((ret_val = cpmac_drv_start(p_drv_hal, p_cpmac_priv->tx_chan_info, 
2423 +                                 p_cpmac_priv->rx_chan_info, CHAN_SETUP))==-1)
2424 +    {
2425 +        errPrint("%s error: failed to start the device.\n", p_dev->name);
2426 +        ret_val = -1;
2427 +    }
2428 +    else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev,"RX_UNICAST_SET",  
2429 +                                         "Set", &channel)!=0)
2430 +    {
2431 +        errPrint("%s error: device chan 0 could not be enabled.\n", p_dev->name);      
2432 +       ret_val = -1;
2433 +    }
2434 +    else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, pszRX_MAXLEN, pszSet, &max_length) != 0)
2435 +    {
2436 +        errPrint(" CPMAC registers can't be written \n");
2437 +        ret_val = -1;
2438 +    }
2439 +    else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "TxIntDisable", "Set", 
2440 +            &p_cpmac_priv->tx_chan_info->tx_int_disable) != 0)
2441 +    {    
2442 +        errPrint(" CPMAC registers can't be written \n");
2443 +        ret_val = -1;
2444 +    }
2445 +    else
2446 +    {
2447 +        ; // Every thing went OK. 
2448 +    }
2449 +    
2450 +    return(ret_val);
2451 +} /* cpmac_dev_enable */
2452 +
2453 +
2454 +static int cpmac_dev_open(struct net_device *p_dev)
2455 +{
2456 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_dev->priv;
2457 +    CPMAC_ISR_INFO_T     *p_isr_cb_param = &p_cpmac_priv->cpmac_isr;
2458 +
2459 +    if(!g_init_enable_flag)
2460 +        cpmac_p_dev_enable(p_dev);
2461 +   
2462 +    if(request_irq(p_isr_cb_param->intr, cpmac_hal_isr, SA_INTERRUPT, 
2463 +                   "Cpmac Driver", p_isr_cb_param))
2464 +    {
2465 +        errPrint("Failed to register the irq %d for Cpmac %s.\n",
2466 +                  p_isr_cb_param->intr, p_dev->name); 
2467 +        return (-1);          
2468 +    }
2469 +    
2470 +    netif_start_queue(p_dev);
2471 +
2472 +    MOD_INC_USE_COUNT;
2473 +    p_cpmac_priv->stats->start_tick = jiffies;
2474 +    dbgPrint("Started the network queue for %s.\n", p_dev->name);    
2475 +    return(0);
2476 +}
2477 +
2478 +/***************************************************************
2479 + *     cpmac_p_dev_disable
2480 + *  
2481 + *     Returns:
2482 + *             An error code.
2483 + *     Parms:
2484 + *             dev     The device structure of the device to
2485 + *                     close.
2486 + *
2487 + *     This function shuts down the adapter.  
2488 + *
2489 + **************************************************************/
2490 +int cpmac_p_dev_disable(struct net_device *p_dev)
2491 +{
2492 +    int ret_val = 0;
2493 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
2494 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cpmac_priv->drv_hal;
2495 +
2496 +    set_bit(0, &p_cpmac_priv->set_to_close);
2497 +    set_bit(0, &p_cpmac_priv->non_data_irq_expected);
2498 +   
2499 +    /* The driver does not re-schedule the tasklet after kill is called. So, this 
2500 +       should take care of the bug in the kernel. */
2501 +    tasklet_kill(&p_cpmac_priv->cpmac_isr.tasklet);
2502
2503 +    if(cpmac_drv_stop(p_drv_hal, p_cpmac_priv->tx_chan_info,
2504 +                     p_cpmac_priv->rx_chan_info, 
2505 +                     CHAN_TEARDOWN | FREE_BUFFER | BLOCKING | COMPLETE) == -1)
2506 +    {
2507 +        ret_val = -1;
2508 +    }
2509 +    else
2510 +    {
2511 +        /* hope that the HAL closes down the tick timer.*/
2512 +
2513 +        dbgPrint("Device %s Closed.\n", p_dev->name);
2514 +        p_cpmac_priv->stats->start_tick = jiffies;
2515 +
2516 +        p_cpmac_priv->link_speed        = 100000000;
2517 +        p_cpmac_priv->link_mode         = 1;
2518 +        netif_carrier_off(p_dev);
2519 +
2520 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
2521 +//        avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF);
2522 +//#endif
2523 +
2524 +        clear_bit(0, &p_cpmac_priv->non_data_irq_expected);
2525 +
2526 +    }
2527 +    
2528 +    return (ret_val);
2529 +
2530 +} /* cpmac_dev_close */
2531 +
2532 +
2533 +/***************************************************************
2534 + *     cpmac_dev_close
2535 + *  
2536 + *     Returns:
2537 + *             An error code.
2538 + *     Parms:
2539 + *             dev     The device structure of the device to
2540 + *                     close.
2541 + *
2542 + *     This function shuts down the adapter.  
2543 + *
2544 + **************************************************************/
2545 +static int cpmac_dev_close(struct net_device *p_dev)
2546 +{
2547 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_dev->priv;
2548 +    CPMAC_ISR_INFO_T     *p_isr_cb_param = &p_cpmac_priv->cpmac_isr;
2549 +
2550 +    /* inform the upper layers. */
2551 +    netif_stop_queue(p_dev);
2552 +
2553 +    if(!g_init_enable_flag)
2554 +        cpmac_p_dev_disable(p_dev);
2555 +    else
2556 +        free_irq(p_isr_cb_param->intr, p_isr_cb_param);
2557 +
2558 +    MOD_DEC_USE_COUNT;
2559 +
2560 +    return(0);
2561 +}
2562 +
2563 +static void cpmac_dev_mcast_set(struct net_device *p_dev)
2564 +{
2565 +    CPMAC_PRIVATE_INFO_T    *p_cpmac_priv = p_dev->priv;
2566 +    CPMAC_DRV_HAL_INFO_T    *p_drv_hal    = p_cpmac_priv->drv_hal;
2567 +    CPMAC_ABILITY_INFO_T    *p_capability = p_cpmac_priv->ability_info;
2568 +    HAL_FUNCTIONS           *p_hal_funcs  = p_drv_hal->hal_funcs;
2569 +    HAL_DEVICE              *p_hal_dev    = p_drv_hal->hal_dev;
2570 +    int                     val           = 1;
2571 +    int                     channel       = 0;
2572 +
2573 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)    
2574 +//    if(netif_carrier_ok(p_dev))
2575 +//      avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON);
2576 +//#endif
2577 +
2578 +    if(p_dev->flags & IFF_PROMISC)
2579 +    {
2580 +        if(p_capability->promiscous)
2581 +        {       
2582 +            /* multi mode in the HAL, check this */
2583 +           val = 0;
2584 +           p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val);
2585 +
2586 +           val = 1;
2587 +            /* set the promiscous mode in the HAL */
2588 +            p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val);
2589 +            p_hal_funcs->Control(p_hal_dev, pszRX_PROM_CH, pszSet, &channel);
2590 +
2591 +                   dbgPrint("%s set in the Promisc mode.\n", p_dev->name);     
2592 +       }
2593 +        else
2594 +        {
2595 +           errPrint("%s not configured for Promisc mode.\n", p_dev->name);
2596 +        }
2597 +    }
2598 +    else if(p_dev->flags & IFF_ALLMULTI)
2599 +    {
2600 +        if(p_capability->all_multi)
2601 +        {      
2602 +           val = 0;
2603 +           /* disable the promiscous mode in the HAL */
2604 +           p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, "Clear", &val);
2605 +
2606 +           val = 1;
2607 +            /* set the all multi mode in the HAL */
2608 +           p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, pszSet, &val);
2609 +           p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel);
2610 +
2611 +            dbgPrint("%s has been set to the ALL_MULTI mode.\n", p_dev->name);
2612 +        }
2613 +        else
2614 +        {
2615 +           errPrint("%s not configured for ALL MULTI mode.\n", p_dev->name);
2616 +        }
2617 +    }
2618 +    else if(p_dev->mc_count)
2619 +    {
2620 +        if(p_capability->multicast)
2621 +        {
2622 +           struct dev_mc_list *p_dmi = p_dev->mc_list;
2623 +            int    count;
2624 +
2625 +            val = 0;
2626 +            /* clear all the previous data, we are going to populate new ones.*/
2627 +           p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val);
2628 +           /* disable the promiscous mode in the HAL */
2629 +           p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val);
2630 +
2631 +           for(count = 0; count < p_dev->mc_count; count++, p_dmi = p_dmi->next)
2632 +           {
2633 +               p_hal_funcs->Control(p_hal_dev, "RX_MULTI_SINGLE", "Set", p_dmi->dmi_addr); 
2634 +           }
2635 +
2636 +            dbgPrint("%s configured for %d multicast addresses.\n", p_dev->name, p_dev->mc_count);
2637 +        }
2638 +        else
2639 +        {
2640 +           errPrint("%s has not been configuted for multicast handling.\n", p_dev->name);
2641 +        }
2642 +    }
2643 +    else
2644 +    {
2645 +       val = 0;
2646 +       /* clear all the previous data, we are going to populate new ones.*/
2647 +       p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val);
2648 +       /* disable the promiscous mode in the HAL */
2649 +       p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val);
2650 +       dbgPrint("Dev set to  Unicast mode.\n");
2651 +    }
2652 +}
2653 +
2654 +static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr)
2655 +{
2656 +    CPMAC_PRIVATE_INFO_T    *p_cpmac_priv = p_dev->priv;
2657 +    CPMAC_DRV_HAL_INFO_T    *p_drv_hal    = p_cpmac_priv->drv_hal;
2658 +    HAL_FUNCTIONS           *p_hal_funcs  = p_drv_hal->hal_funcs;
2659 +    HAL_DEVICE              *p_hal_dev    = p_drv_hal->hal_dev;
2660 +    struct sockaddr *sa = addr;
2661 +
2662 +   memcpy(p_cpmac_priv->mac_addr,sa->sa_data,p_dev->addr_len);
2663 +   memcpy(p_dev->dev_addr,sa->sa_data,p_dev->addr_len);
2664 +   p_hal_funcs->Control(p_hal_dev, pszMacAddr, pszSet, p_cpmac_priv->mac_addr);   
2665 +
2666 +       return 0;
2667 +
2668 +}
2669 +
2670 +/* VLAN is handled by vlan/vconfig support. Here, we just check for the 
2671 + * 802.1q configuration of the device and en-queue the packet accordingly.
2672 + * We do not do any 802.1q processing here.
2673 + */
2674 +static int cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev)
2675 +{
2676 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv  = p_dev->priv;
2677 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal     = p_cpmac_priv->drv_hal;
2678 +    int channel                         = 0;
2679 +    int ret_val                         = 0;
2680 +    FRAGLIST             send_frag_list[1];
2681 +
2682 +#ifdef CPMAC_8021Q_SUPPORT
2683 +    if(skb->len < TCI_END_OFFSET)
2684 +    {
2685 +        /* Whee, frame shorter than 14 bytes !! We need to copy 
2686 +        * fragments to understand the frame. Too much work. 
2687 +        * Hmm, dump it. */
2688 +
2689 +        /* Free the buffer */
2690 +       goto cpmac_dev_tx_drop_pkt;
2691 +    }
2692 +
2693 +    /* 802.1p/q stuff */
2694 +    if(IS_802_1Q_FRAME(skb->data + TPID_START_OFFSET)) 
2695 +    {
2696 +        /* IEEE 802.1q, section 8.8 and section 8.11.9 */
2697 +        if(!p_cpmac_priv->enable_802_1q) 
2698 +        {
2699 +           /* free the buffer */
2700 +           goto cpmac_dev_tx_drop_pkt;
2701 +        }              
2702 +
2703 +        channel = GET_802_1P_CHAN(p_cpmac_priv->tx_chan_info->opened_chan,
2704 +                                 skb->data[TCI_START_OFFSET]);
2705 +
2706 +    }
2707 +    /* sending a non 802.1q frame, when configured for 802.1q: dump it.*/
2708 +    else if(p_cpmac_priv->enable_802_1q)
2709 +    {
2710 +         /* free the buffer */
2711 +        goto cpmac_dev_tx_drop_pkt;
2712 +    }
2713 +    else
2714 +    {
2715 +        ;/* it is the good old non 802.1q */
2716 +    }
2717 +#endif
2718 +
2719 +    send_frag_list->len  = skb->len;
2720 +    send_frag_list->data = skb->data;
2721 +
2722 +#ifdef CPMAC_TEST
2723 +    xdump(skb->data, skb->len, "send");
2724 +#endif
2725 +
2726 +    dma_cache_wback_inv((unsigned long)skb->data, skb->len);    
2727 +
2728 +    if(p_drv_hal->hal_funcs->Send(p_drv_hal->hal_dev, send_frag_list, 1, 
2729 +                                 skb->len, skb, channel) != 0)
2730 +    {
2731 +       /* code here to stop the queue, when allowing tx timeout, perhaps next release.*/
2732 +        p_cpmac_priv->net_dev_stats.tx_errors++;  
2733 +#ifndef TI_SLOW_PATH
2734 +       /* Free the skb in case of Send return error */
2735 +        dev_kfree_skb_any(skb);
2736 +        p_cpmac_priv->net_dev_stats.tx_dropped++;
2737 +        return 0;
2738 +#endif
2739 +        goto cpmac_dev_tx_drop_pkt; 
2740 +    }
2741 +
2742 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
2743 +//    avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_TX_ACTIVITY);
2744 +//#endif
2745 +
2746 +    return(ret_val);
2747 +
2748 +cpmac_dev_tx_drop_pkt:
2749 +
2750 +    p_cpmac_priv->net_dev_stats.tx_dropped++;
2751 +    ret_val = -1;
2752 +    return (ret_val);
2753 +
2754 +} /*cpmac_dev_tx */
2755 +
2756 +
2757 +//------------------------------------------------------------------------------
2758 +// Public functions : Called by outsiders to this file.
2759 +//------------------------------------------------------------------------------
2760 +
2761 +
2762 +void *cpmac_hal_malloc_buffer(unsigned int size, void* mem_base, unsigned int mem_range,
2763 +                             OS_SETUP *p_os_setup, HAL_RECEIVEINFO *HalReceiveInfo, 
2764 +                             OS_RECEIVEINFO **osReceiveInfo, OS_DEVICE *p_dev)
2765 +{
2766 +    CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = (CPMAC_RX_CHAN_INFO_T *)p_os_setup;
2767 +    int                  tot_buf_size    = p_rx_chan_info->chan->tot_buf_size;
2768 +    int             tot_reserve_bytes    = p_rx_chan_info->chan->tot_reserve_bytes;
2769 +    struct sk_buff  *p_skb;
2770 +    void             *ret_ptr;
2771 +
2772 +    /* use TI SKB private pool */
2773 +    p_skb = dev_alloc_skb(tot_buf_size);
2774 +
2775 +    if(p_skb == NULL)
2776 +    {
2777 +        errPrint("Failed to allocate skb for %s.\n", ((struct net_device*)p_dev)->name);
2778 +        return (NULL);
2779 +    }
2780 +
2781 +    p_skb->dev = p_dev;
2782 +    skb_reserve(p_skb, tot_reserve_bytes);
2783 +
2784 +    *osReceiveInfo = p_skb;
2785 +
2786 +    ret_ptr = skb_put(p_skb, p_rx_chan_info->chan->buffer_size);
2787 +
2788 +    return(ret_ptr);
2789 +}
2790 +
2791 +void cpmac_hal_isr(int irq, void *p_param, struct pt_regs *regs)
2792 +{
2793 +    CPMAC_ISR_INFO_T      *p_cb_param    = (CPMAC_ISR_INFO_T*) p_param;
2794 +    CPMAC_DRV_HAL_INFO_T  *p_drv_hal     = p_cb_param->owner;
2795 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_drv_hal->owner;
2796 +    int                   pkts_to_handle = 0;
2797 +
2798 +    if(p_cpmac_priv->non_data_irq_expected)
2799 +    {
2800 +        p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle);
2801 +        p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev);
2802 +    }
2803 +    else if(!p_cpmac_priv->set_to_close)
2804 +        tasklet_schedule(&((CPMAC_ISR_INFO_T*) p_param)->tasklet);
2805 +    else
2806 +        ; // back off from doing anything more. We are closing down.
2807 +}
2808 +
2809 +void cpmac_handle_tasklet(unsigned long data)
2810 +{
2811 +    CPMAC_ISR_INFO_T     *p_cb_param   = (CPMAC_ISR_INFO_T*) data;
2812 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal    = p_cb_param->owner;
2813 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_drv_hal->owner;
2814 +    int                  pkts_to_handle;
2815 +
2816 +    p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle);
2817 +
2818 +    if(test_bit(0, &p_cpmac_priv->non_data_irq_expected) || !pkts_to_handle)
2819 +        p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev);
2820 +    else if(!test_bit(0, &p_cpmac_priv->set_to_close))
2821 +        tasklet_schedule(&p_cb_param->tasklet);
2822 +    else
2823 +        ; // Back off from processing packets we are closing down.
2824 +}
2825 +
2826 +int cpmac_hal_control(OS_DEVICE *p_dev, const char *key, 
2827 +                     const char *action, void *value)
2828 +{
2829 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv;
2830 +    int ret_val = -1;
2831 +
2832 +    if(key == NULL)
2833 +    {
2834 +        dbgPrint("Encountered NULL key.\n");
2835 +       return (-1);
2836 +    }
2837 +
2838 +    if(cpmac_ci_strcmp(key, "Sleep") == 0 && value != NULL)
2839 +    {
2840 +        unsigned int clocks_per_tick  = cpmac_cpu_freq/HZ;
2841 +       unsigned int requested_clocks = *(unsigned int*)value;
2842 +       unsigned int requested_ticks  = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick;
2843 +        mdelay(requested_ticks); 
2844 +       ret_val = 0;
2845 +    }
2846 +    else if(cpmac_ci_strcmp(key, "StateChange") == 0)
2847 +    {
2848 +        ret_val = cpmac_p_process_status_ind(p_cpmac_priv);
2849 +    }
2850 +    else if(cpmac_ci_strcmp(key, "Tick") == 0 && action != NULL)
2851 +    {
2852 +       if(cpmac_ci_strcmp(action, "Set") == 0 && value != NULL)
2853 +       {
2854 +            if(*(unsigned int*)value == 0)
2855 +            {
2856 +                cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER);
2857 +                ret_val = 0;
2858 +            }
2859 +            else
2860 +            {
2861 +                unsigned int clocks_per_tick  = cpmac_cpu_freq/HZ;
2862 +               unsigned int requested_clocks = *(unsigned int*)value;
2863 +               unsigned int requested_ticks  = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick;
2864 +
2865 +                p_cpmac_priv->delay_ticks =  requested_ticks; /* save it for re-triggering */
2866 +               ret_val = cpmac_p_start_timer(p_cpmac_priv->timer + TICK_TIMER, 
2867 +                                             p_cpmac_priv->delay_ticks);
2868 +            }
2869 +       }
2870 +        else if(cpmac_ci_strcmp(action, "Clear") == 0)
2871 +        {
2872 +            ret_val = cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER);
2873 +        }
2874 +        else
2875 +            ;
2876 +    }
2877 +    else if(cpmac_ci_strcmp(key, "MacAddr") == 0 && action != NULL)
2878 +    {
2879 +        if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL)
2880 +       {
2881 +            *(char **)value = p_cpmac_priv->mac_addr; 
2882 +           ret_val = 0;
2883 +       }
2884 +    }
2885 +    else if(cpmac_ci_strcmp(key, "CpuFreq") == 0)
2886 +    {
2887 +       if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL)
2888 +       {
2889 +           *(unsigned int *)value = cpmac_cpu_freq;
2890 +           dbgPrint("Cpu frequency for cpmacs is %u\n",cpmac_cpu_freq);
2891 +           ret_val = 0;
2892 +       }
2893 +    }
2894 +    else if(cpmac_ci_strcmp(key, "SioFlush") == 0)
2895 +    {
2896 +       ret_val = 0;
2897 +       dbgPrint("\n"); 
2898 +    }
2899 +    else if(cpmac_ci_strcmp(key, "CpmacFrequency") == 0)
2900 +    {
2901 +        /* For Sangam cpmac clock is off the PBUS */
2902 +        /* OS Needs to supply CORRECT frequency */
2903 +        if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL)
2904 +        {
2905 +            *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000;
2906 +            ret_val = 0;
2907 +        }
2908 +    }
2909 +    /* For now, providing back the default values. */
2910 +    else if(cpmac_ci_strcmp(key, "MdioClockFrequency") == 0)
2911 +    {
2912 +        if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL)
2913 +        {
2914 +            *(unsigned int *)value = 2200000;  /*DEFAULT */
2915 +            ret_val = 0;
2916 +        }
2917 +    }
2918 +    /* For now, providing back the default values. */
2919 +    else if(cpmac_ci_strcmp(key, "MdioBusFrequency") == 0)
2920 +    {
2921 +        /* For Sangam MdioBusFreq is off the PBUS */
2922 +        if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL)
2923 +        {
2924 +            *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000;
2925 +            ret_val = 0;
2926 +        }
2927 +    }
2928 +  
2929 +#if 0 
2930 +#if defined(CONFIG_AVALANCHE_AUTO_MDIX) 
2931 +    /* supporting Mdio Mdix switching */
2932 +    else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0)
2933 +    {
2934 +        /* For Sangam Mdio-switching  action should be always "set"*/
2935 +        if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL )
2936 +        {
2937 +           unsigned  int mdix =  *((unsigned int *) value) ;
2938 +
2939 +           if(mdix)
2940 +              avalanche_set_phy_into_mdix_mode();
2941 +
2942 +           else
2943 +              avalanche_set_phy_into_mdi_mode();  
2944 +  
2945 +           ret_val = 0;
2946 +        } 
2947 +
2948 +    }
2949 +#endif
2950 +#endif
2951 +    else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0)
2952 +    {
2953 +        /* For Sangam Mdio-switching  action should be always "set"*/
2954 +        if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL )
2955 +        {
2956 +           unsigned  int mdix =  *((unsigned int *) value) ;
2957 +
2958 +#ifdef CONFIG_AR7_MDIX
2959 +          avalanche_set_mdix_on_chip(0xa8610000 , mdix ? 1: 0);
2960 +#endif
2961 +  
2962 +           ret_val = 0;
2963 +        } 
2964 +
2965 +    }
2966 +
2967 +    return(ret_val);
2968 +}
2969 +
2970 +
2971 +int cpmac_hal_receive(OS_DEVICE *p_dev, FRAGLIST *fragList, 
2972 +                             unsigned int fragCount,
2973 +                             unsigned int packet_size, 
2974 +                             HAL_RECEIVEINFO *hal_receive_info,
2975 +                             unsigned int mode)
2976 +{
2977 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv  = p_dev->priv;
2978 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal     = p_cpmac_priv->drv_hal;
2979 +    struct sk_buff       *p_skb         = fragList[0].OsInfo;
2980 +    p_skb->len                          = fragList[0].len;    
2981 +
2982 +    /* invalidate the cache. */
2983 +    dma_cache_inv((unsigned long)p_skb->data, fragList[0].len);    
2984 +#ifdef CPMAC_TEST
2985 +    xdump(p_skb->data, p_skb->len, "recv");
2986 +#endif
2987 +#ifdef CPMAC_8021Q_SUPPORT
2988 +    /* 802.1q stuff, just does the basic checking here. */
2989 +    if(!p_cpmac_priv->enable_802_1q      &&
2990 +       p_skb->len > TCI_END_OFFSET       &&
2991 +       IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET))
2992 +    {
2993 +         goto cpmac_hal_recv_frame_mismatch;
2994 +    }
2995 +#endif
2996 +    if(fragCount > 1)      
2997 +    {      
2998 +       int     len;
2999 +       struct sk_buff *p_temp_skb;
3000 +       CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info;
3001 +       int     count;
3002 +       
3003 +       dbgPrint("Recv: It is multifragment for %s.\n", p_dev->name);
3004 +       
3005 +       p_skb = dev_alloc_skb(packet_size + 
3006 +          p_rx_chan_info->chan->tot_reserve_bytes); 
3007 +       if(p_skb == NULL) 
3008 +       {
3009 +          p_cpmac_priv->net_dev_stats.rx_errors++;
3010 +          goto cpmac_hal_recv_alloc_failed;
3011 +       }
3012 +       
3013 +       p_skb->dev = p_dev;
3014 +       skb_reserve(p_skb, p_rx_chan_info->chan->tot_reserve_bytes);
3015 +       
3016 +       for(count = 0; count < fragCount; count++)
3017 +       {
3018 +          p_temp_skb = fragList[count].OsInfo;
3019 +          len        = fragList[count].len;
3020 +          
3021 +          dma_cache_inv((unsigned long)p_temp_skb->data, len);
3022 +          
3023 +          memcpy(skb_put(p_skb, len), p_temp_skb->data, len);
3024 +          dev_kfree_skb_any(p_temp_skb);
3025 +       }
3026 +    }
3027 +    
3028 +
3029 +#if defined(CONFIG_MIPS_AVALANCHE_MARVELL)                                                                                                   
3030 + /* Fetch the receiving port information from EGRESS TRAILOR Bytes*/         
3031 +     p_dev->if_port = (unsigned char)p_skb->data[packet_size -(EGRESS_TRAILOR_LEN-1)] + AVALANCHE_MARVELL_BASE_PORT_ID;
3032 +    skb_trim(p_skb, packet_size - EGRESS_TRAILOR_LEN);                                                                       
3033 +#else                                                                                                                        
3034 +    /* set length & tail */                                                                                                  
3035 +    skb_trim(p_skb, packet_size);                                                                                            
3036 +#endif 
3037
3038 +    p_skb->protocol = eth_type_trans(p_skb, p_dev);
3039 +
3040 +    netif_rx(p_skb);
3041 +
3042 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
3043 +//    avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_RX_ACTIVITY);       
3044 +//#endif
3045 +
3046 +    p_cpmac_priv->net_dev_stats.rx_packets++;
3047 +    p_cpmac_priv->net_dev_stats.rx_bytes += packet_size;
3048 +
3049 +    p_drv_hal->hal_funcs->RxReturn(hal_receive_info,1);
3050 +
3051 +    return(0);
3052 +
3053 +cpmac_hal_recv_alloc_failed:
3054 +
3055 +#ifdef CPMAC_8021Q_SUPPORT
3056 +cpmac_hal_recv_frame_mismatch:
3057 +#endif
3058
3059 +    fragCount--;
3060 +
3061 +    do
3062 +    {
3063 +        dev_kfree_skb_any(fragList[fragCount].OsInfo);
3064 +    }
3065 +    while(fragCount--);
3066 +
3067 +    p_cpmac_priv->net_dev_stats.rx_dropped++;
3068 +
3069 +    return(-1);
3070 +} /*cpmac_receive*/
3071 +
3072 +
3073 +void cpmac_hal_tear_down_complete(OS_DEVICE*a, int b, int ch)
3074 +{
3075 +    dbgPrint("what to do with this.\n");
3076 +}
3077 +
3078 +
3079 +int  cpmac_hal_send_complete(OS_SENDINFO *p_skb)
3080 +{
3081 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_skb->dev->priv;
3082 +
3083 +    p_cpmac_priv->net_dev_stats.tx_packets++;
3084 +    p_cpmac_priv->net_dev_stats.tx_bytes += p_skb->len;
3085 +    
3086 +    dev_kfree_skb_any(p_skb);
3087 +
3088 +    return(0);
3089 +}
3090 +
3091 +
3092 +int cpmac_reset(CPMAC_PRIVATE_INFO_T *p_cpmac_priv)
3093 +{
3094 +    // code here to reset the device/hal. Not now.
3095 +
3096 +   netif_wake_queue(p_cpmac_priv->owner);
3097 +   return(0);
3098 +}
3099 +
3100 +#ifdef CPMAC_TEST
3101 +
3102 +#define isprint(a) ((a >=' ')&&(a<= '~'))
3103 +void xdump( u_char*  cp, int  length, char*  prefix )
3104 +{
3105 +    int col, count;
3106 +    u_char prntBuf[120];
3107 +    u_char*  pBuf = prntBuf;
3108 +    count = 0;
3109 +    while(count < length){
3110 +        pBuf += sprintf( pBuf, "%s", prefix );
3111 +        for(col = 0;count + col < length && col < 16; col++){
3112 +            if (col != 0 && (col % 4) == 0)
3113 +                pBuf += sprintf( pBuf, " " );
3114 +            pBuf += sprintf( pBuf, "%02X ", cp[count + col] );
3115 +        }
3116 +        while(col++ < 16){      /* pad end of buffer with blanks */
3117 +            if ((col % 4) == 0)
3118 +                sprintf( pBuf, " " );
3119 +            pBuf += sprintf( pBuf, "   " );
3120 +        }
3121 +        pBuf += sprintf( pBuf, "  " );
3122 +        for(col = 0;count + col < length && col < 16; col++){
3123 +            if (isprint((int)cp[count + col]))
3124 +                pBuf += sprintf( pBuf, "%c", cp[count + col] );
3125 +            else
3126 +                pBuf += sprintf( pBuf, "." );
3127 +                }
3128 +        sprintf( pBuf, "\n" );
3129 +        // SPrint(prntBuf);
3130 +        printk(prntBuf);
3131 +        count += col;
3132 +        pBuf = prntBuf;
3133 +    }
3134 +
3135 +}  /* close xdump(... */
3136 +#endif
3137 +
3138 +
3139 +static int __init cpmac_dev_probe(void)
3140 +{
3141 +    int     retVal         = 0;
3142 +    int     unit;
3143 +    int     instance_count = CONFIG_MIPS_CPMAC_PORTS;
3144 +
3145 +    //cpmac_cpu_freq = avalanche_clkc_get_freq(CLKC_MIPS);
3146 +    cpmac_cpu_freq = CONFIG_AR7_CPU * 1000 * 1000;
3147 +
3148 +    build_psp_config();                       
3149 +
3150 +    for(unit = 0; unit < instance_count; unit++)
3151 +    {
3152 +        struct net_device              *p_dev;
3153 +        CPMAC_PRIVATE_INFO_T            *p_cpmac_priv;
3154 +        size_t                         dev_size;
3155 +       int                             failed;
3156 +
3157 +        dev_size =    sizeof(struct net_device) 
3158 +                   + sizeof(CPMAC_PRIVATE_INFO_T);
3159 +
3160 +
3161 +        if((p_dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL)) == NULL)
3162 +        {
3163 +            dbgPrint( "Could not allocate memory for device.\n" );
3164 +            retVal = -ENOMEM;
3165 +            break;
3166 +        }            
3167 +               
3168 +        memset(p_dev, 0, dev_size );
3169 +
3170 +        p_dev->priv                 = p_cpmac_priv
3171 +                                    = (CPMAC_PRIVATE_INFO_T*)(((char *) p_dev) + sizeof(struct net_device));
3172 +        p_cpmac_priv->owner         = p_dev;
3173 +       
3174 +        ether_setup(p_dev); 
3175 +
3176 +       p_cpmac_priv->instance_num  = unit;
3177 +        p_dev->init                 = cpmac_dev_init;
3178 +
3179 +        g_dev_array[p_cpmac_priv->instance_num] = p_dev;
3180 +        
3181 +#if defined CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC
3182 +        g_init_enable_flag = 1;
3183 +        printk("Cpmac driver is allocating buffer memory at init time.\n");
3184 +#endif
3185 +
3186 +       /* This section gives a default value by the number of PHY in order to
3187 +        * replace the default MACRO. */
3188 +       {
3189 +           char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */
3190 +           if(0 == strcmp(mac_port, "1")) {
3191 +               printk("Using the MAC with external PHY\n");
3192 +               cfg_start_link_speed = _CPMDIO_NOPHY;
3193 +               cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE + 4;
3194 +           }
3195 +           else {
3196 +               printk("Using the MAC with internal PHY\n");
3197 +               cfg_start_link_speed = CFG_START_LINK_SPEED;
3198 +               cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE;
3199 +           }
3200 +           g_cfg_start_link_params = cfg_start_link_speed;
3201 +       }
3202 +
3203 +        cpmac_p_detect_manual_cfg(cfg_link_speed, cfg_link_mode, cpmac_debug_mode);
3204 +
3205 +       failed = register_netdev(p_dev);
3206 +        if (failed)
3207 +        {
3208 +            dbgPrint("Could not register device for inst %d because of reason \
3209 +                      code %d.\n", unit, failed);
3210 +            retVal = -1;
3211 +            kfree(p_dev);
3212 +            break;
3213 +        }           
3214 +        else
3215 +        {
3216 +
3217 +            char proc_name[100];
3218 +            int  proc_category_name_len = 0;
3219 +
3220 +           p_cpmac_priv->next_device = last_cpmac_device;
3221 +            last_cpmac_device         = p_dev;
3222 +
3223 +           dbgPrint(" %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq,
3224 +                      (int) p_dev->base_addr);
3225 +
3226 +           strcpy(proc_name, "avalanche/");
3227 +            strcat(proc_name, p_dev->name);
3228 +            proc_category_name_len = strlen(proc_name);
3229 +
3230 +            strcpy(proc_name + proc_category_name_len, "_rfc2665_stats");
3231 +            create_proc_read_entry(proc_name,0,NULL,cpmac_p_read_rfc2665_stats, p_dev);
3232 +
3233 +       }
3234 +    }
3235 +
3236 +    if(retVal == 0)
3237 +    {
3238 +       /* To maintain backward compatibility with NSP. */
3239 +        gp_stats_file = create_proc_entry("avalanche/cpmac_stats", 0644, NULL);
3240 +        if(gp_stats_file)
3241 +        {
3242 +            gp_stats_file->read_proc  = cpmac_p_read_stats;
3243 +            gp_stats_file->write_proc = cpmac_p_write_stats;
3244 +        }
3245 +       create_proc_read_entry("avalanche/cpmac_link", 0, NULL, cpmac_p_read_link, NULL);
3246 +       create_proc_read_entry("avalanche/cpmac_ver", 0, NULL, cpmac_p_get_version, NULL);
3247 +
3248 +    }
3249 +   
3250 +    cpmac_devices_installed  = unit;
3251 +    dbgPrint("Installed %d cpmac instances.\n", unit);
3252 +    return ( (unit >= 0 ) ? 0 : -ENODEV );
3253 +
3254 +} /* init_module */
3255 +
3256 +
3257 +/***************************************************************
3258 + *     cleanup_module
3259 + *
3260 + *     Returns:
3261 + *             Nothing
3262 + *     Parms:
3263 + *             None
3264 + *
3265 + *     Goes through the CpmacDevices list and frees the device
3266 + *     structs and memory associated with each device (lists
3267 + *     and buffers).  It also ureserves the IO port regions
3268 + *     associated with this device.
3269 + *
3270 + **************************************************************/
3271 +
3272 +void cpmac_exit(void)
3273 +{
3274 +    struct net_device       *p_dev;
3275 +    CPMAC_PRIVATE_INFO_T    *p_cpmac_priv;
3276 +
3277 +    while (cpmac_devices_installed) 
3278 +    {
3279 +        char proc_name[100];
3280 +        int  proc_category_name_len = 0;
3281 +
3282 +        p_dev = last_cpmac_device;
3283 +        p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv;
3284 +
3285 +       dbgPrint("Unloading %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq, (int) p_dev->base_addr);
3286 +
3287 +        if(g_init_enable_flag)
3288 +            cpmac_p_dev_disable(p_dev);
3289 +      
3290 +        cpmac_drv_cleanup(p_cpmac_priv->drv_hal);
3291 +
3292 +//#if defined (CONFIG_MIPS_AVALANCHE_LED)
3293 +//        avalanche_led_unregister(p_cpmac_priv->led_handle);
3294 +//#endif
3295 +       strcpy(proc_name, "avalanche/");
3296 +        strcat(proc_name, p_dev->name);
3297 +        proc_category_name_len = strlen(proc_name);
3298 +
3299 +        strcpy(proc_name + proc_category_name_len, "_rfc2665_stats");
3300 +        remove_proc_entry(proc_name, NULL);
3301 +        
3302 +        release_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size);
3303 +        unregister_netdev(p_dev);
3304 +       last_cpmac_device = p_cpmac_priv->next_device;
3305 +
3306 +        kfree(p_cpmac_priv->drv_hal);
3307 +        kfree(p_dev);
3308 +     
3309 +       cpmac_devices_installed--;
3310 +    }
3311 +
3312 +    if(gp_stats_file)
3313 +        remove_proc_entry("avalanche/cpmac_stats", NULL);
3314 +
3315 +    remove_proc_entry("avalanche/cpmac_link",  NULL);
3316 +    remove_proc_entry("avalanche/cpmac_ver",   NULL);
3317 +
3318 +    psp_config_cleanup();
3319 +}
3320 +
3321 +     
3322 +module_init(cpmac_dev_probe);
3323 +module_exit(cpmac_exit);
3324 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpmac.h
3325 --- linux.old/drivers/net/avalanche_cpmac/cpmac.h       1970-01-01 01:00:00.000000000 +0100
3326 +++ linux.dev/drivers/net/avalanche_cpmac/cpmac.h       2005-07-12 02:48:42.043594000 +0200
3327 @@ -0,0 +1,379 @@
3328 +/******************************************************************************
3329 + * FILE PURPOSE:    CPMAC Linux Network Device Driver Header
3330 + ******************************************************************************
3331 + * FILE NAME:       cpmac.h
3332 + *
3333 + * DESCRIPTION:     CPMAC Network Device Driver Header
3334 + *
3335 + * REVISION HISTORY:
3336 + * Date            Name                   Details
3337 + *----------------------------------------------------------------------------- 
3338 + * 27 Nov 2002     Suraj S Iyer           Initial Create.
3339 + * 09 Jun 2003     Suraj S Iyer           Preparing for GA.
3340 + *
3341 + * (C) Copyright 2003, Texas Instruments, Inc
3342 + *******************************************************************************/
3343 +
3344 +#ifndef CPMAC_H
3345 +#define CPMAC_H
3346 +
3347 +#include <linux/timer.h>
3348 +#include <linux/netdevice.h>
3349 +#include <asm/semaphore.h>
3350 +#include <linux/ctype.h>
3351 +#include <linux/interrupt.h>
3352 +
3353 +#include "cpmacHalLx.h"
3354 +/*-----------------------------------------------------------------------------
3355 + * Config macros. Use these to config the driver.
3356 + *---------------------------------------------------------------------------*/
3357 +#define CPMAC_MAX_FRAME_SIZE         1518
3358 +
3359 +#if defined(CONFIG_AR7WRD) || defined(CONFIG_AR7WI) || defined(CONFIG_AR7VWI)|| defined(CONFIG_AR7VW) 
3360 +#define CFG_RX_NUM_BUF_DESC            64 
3361 +#define CFG_RX_NUM_BUF_SERVICE         32 
3362 +#else                                     
3363 +#define CFG_RX_NUM_BUF_DESC            16 
3364 +#define CFG_RX_NUM_BUF_SERVICE         8  
3365 +#endif                                    
3366 +
3367 +#define CFG_RX_BUF_OFFSET              0
3368 +
3369 +#define CFG_TX_NUM_BUF_DESC            128
3370 +#define CFG_TX_NUM_BUF_SERVICE         20 
3371 +#define CFG_TX_BUF_OFFSET              0  /* Lets not change this. */
3372 +#define CFG_TX_TIMEOUT                 2000 /* ticks*/
3373 +#define CFG_TX_INT_DISABLE             1  /* Disable the Tx Complete interrupt */
3374 +
3375 +#define CFG_JUMBO_FRAMES               1
3376 +#define CFG_SHORT_FRAMES               1
3377 +#define CFG_PROMISCOUS                 1
3378 +#define CFG_BROADCAST                  1
3379 +#define CFG_MULTICAST                  1
3380 +#define CFG_ALL_MULTI                  (1*(CFG_MULTICAST))
3381 +#define CFG_AUTO_NEGOTIATION           1
3382 +
3383 +#if defined (CONFIG_MIPS_AVALANCHE_MARVELL)
3384 +#define EGRESS_TRAILOR_LEN             4 
3385 +#define CFG_START_LINK_SPEED           (_CPMDIO_NOPHY)
3386 +#undef  CPMAC_MAX_FRAME_SIZE
3387 +#define CPMAC_MAX_FRAME_SIZE          (1518 + EGRESS_TRAILOR_LEN)
3388 +#else
3389 +#define CFG_START_LINK_SPEED          (_CPMDIO_10 | _CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD) /* auto nego */
3390 +#endif
3391 +
3392 +#define CFG_LOOP_BACK                  1
3393 +#define CFG_TX_FLOW_CNTL               0
3394 +#define CFG_RX_FLOW_CNTL               0
3395 +#define CFG_TX_PACING                  0
3396 +#define CFG_RX_PASS_CRC                0
3397 +#define CFG_QOS_802_1Q                 0
3398 +#define CFG_TX_NUM_CHAN                1
3399 +
3400 +
3401 +/*-----------------------------------------------------------------------------
3402 + * Private macros.
3403 + *---------------------------------------------------------------------------*/
3404 +#define MAX_TIMER               2
3405 +#define TX_TIMER                0
3406 +#define TICK_TIMER              0
3407 +#define MAX_TX_CHAN             8
3408 +
3409 +#define CPMAC_LINK_OFF          0
3410 +#define CPMAC_LINK_ON           1
3411 +/*#define CPMAC_SPEED_100         2
3412 +#define CPMAC_SPEED_10          3
3413 +#define CPMAC_FULL_DPLX         4
3414 +#define CPMAC_HALF_DPLX         5*/
3415 +#define CPMAC_RX_ACTIVITY       2
3416 +#define CPMAC_TX_ACTIVITY       3
3417 +
3418 +struct cpmac_timer_info;
3419 +
3420 +typedef int  (*CPMAC_HAL_ISR_FUNC_T)(HAL_DEVICE*, int*);
3421 +typedef int  (*CPMAC_TIMEOUT_CB_T)(struct cpmac_timer_info*);
3422 +
3423 +typedef struct cpmac_ability_info
3424 +{
3425 +    int promiscous;
3426 +    int broadcast;
3427 +    int multicast;
3428 +    int all_multi;
3429 +    int loop_back;
3430 +    int jumbo_frames;
3431 +    int short_frames;
3432 +    int auto_negotiation;
3433 +    int tx_flow_control;
3434 +    int rx_flow_control;
3435 +    int tx_pacing;
3436 +    int link_speed;
3437 +    int rx_pass_crc;
3438 +    int qos_802_1q;
3439 +    int tx_num_chan;
3440 +}
3441 +CPMAC_ABILITY_INFO_T;
3442 +
3443 +#ifdef DEBUG
3444 +typedef struct cpmac_timer_info
3445 +{
3446 +    void               *owner;
3447 +    UINT32             delay_ticks;
3448 +    WDOG_ID            timer_id;
3449 +    UINT32             is_running;
3450 +    UINT32             timer_set_at;
3451 +    CPMAC_TIMEOUT_CB_T timeout_CB;
3452 +} CPMAC_TIMER_INFO_T;
3453 +
3454 +typedef struct
3455 +{
3456 +    void               *owner;
3457 +    unsigned int       num_cl_desc;
3458 +    CL_DESC            *cl_desc_tbl;
3459 +    M_CL_CONFIG        *m_cl_blk_config;
3460 +    NET_POOL           *net_pool;
3461 +    CL_POOL_ID         clPoolId;
3462 +
3463 +} CPMAC_NET_MEM_INFO_T;
3464 +
3465 +#endif
3466 +
3467 +typedef struct
3468 +{
3469 +    void                  *owner;
3470 +    CPMAC_HAL_ISR_FUNC_T  hal_isr;
3471 +    struct tasklet_struct tasklet;
3472 +    int                   intr;
3473 +
3474 +} CPMAC_ISR_INFO_T;
3475 +
3476 +typedef struct cpmac_chan
3477 +{
3478 +   int num_BD;
3479 +   int buffer_size;
3480 +   int buffer_offset;
3481 +   int service_max;
3482 +   int state;
3483 +   int tot_buf_size;
3484 +   int tot_reserve_bytes;
3485 +
3486 +} CPMAC_CHAN_T;
3487 +
3488 +#define CHAN_CLOSE  0
3489 +#define CHAN_OPENED 1
3490 +
3491 +typedef struct 
3492 +{
3493 +    int          cfg_chan;
3494 +    int          dev_chan;
3495 +    int          opened_chan;
3496 +    CPMAC_CHAN_T chan[1];
3497 +    int          enable_802_1q;
3498 +
3499 +} CPMAC_RX_CHAN_INFO_T;
3500 +
3501 +typedef struct
3502 +{
3503 +    int          cfg_chan;
3504 +    int          dev_chan;
3505 +    int          opened_chan;
3506 +    int          tx_int_disable;
3507 +    CPMAC_CHAN_T chan[MAX_TX_CHAN];
3508 +   
3509 +} CPMAC_TX_CHAN_INFO_T;
3510 +
3511 +
3512 +
3513 +typedef struct
3514 +{
3515 +   void                        *owner;
3516 +   HAL_FUNCTIONS               *hal_funcs;
3517 +   HAL_DEVICE                  *hal_dev;
3518 +   OS_FUNCTIONS                *os_funcs; 
3519 +//   SEM_ID                      chan_teardown_sem;
3520 +   int                         non_data_irq_expected;
3521 +} CPMAC_DRV_HAL_INFO_T;
3522 +
3523 +
3524 +typedef struct
3525 +{
3526 +    unsigned long tx_discards;
3527 +    unsigned long rx_discards;
3528 +    unsigned long start_tick;
3529 +
3530 +} CPMAC_DRV_STATS_T;
3531 +
3532 +typedef struct 
3533 +{
3534 +    unsigned long   ifInGoodFrames;
3535 +    unsigned long   ifInBroadcasts;
3536 +    unsigned long   ifInMulticasts;
3537 +    unsigned long   ifInPauseFrames;
3538 +    unsigned long   ifInCRCErrors;
3539 +    unsigned long   ifInAlignCodeErrors;
3540 +    unsigned long   ifInOversizedFrames;
3541 +    unsigned long   ifInJabberFrames;
3542 +    unsigned long   ifInUndersizedFrames;
3543 +    unsigned long   ifInFragments;
3544 +    unsigned long   ifInFilteredFrames;
3545 +    unsigned long   ifInQosFilteredFrames;
3546 +    unsigned long   ifInOctets;
3547 +    unsigned long   ifOutGoodFrames;
3548 +    unsigned long   ifOutBroadcasts;
3549 +    unsigned long   ifOutMulticasts;
3550 +    unsigned long   ifOutPauseFrames;
3551 +    unsigned long   ifDeferredTransmissions;
3552 +    unsigned long   ifCollisionFrames;
3553 +    unsigned long   ifSingleCollisionFrames;
3554 +    unsigned long   ifMultipleCollisionFrames;
3555 +    unsigned long   ifExcessiveCollisionFrames;
3556 +    unsigned long   ifLateCollisions;
3557 +    unsigned long   ifOutUnderrun;
3558 +    unsigned long   ifCarrierSenseErrors;
3559 +    unsigned long   ifOutOctets;
3560 +    unsigned long   if64OctetFrames;
3561 +    unsigned long   if65To127OctetFrames;
3562 +    unsigned long   if128To255OctetFrames;
3563 +    unsigned long   if256To511OctetFrames;
3564 +    unsigned long   if512To1023OctetFrames;
3565 +    unsigned long   if1024ToUPOctetFrames;
3566 +    unsigned long   ifNetOctets;
3567 +    unsigned long   ifRxSofOverruns;
3568 +    unsigned long   ifRxMofOverruns;
3569 +    unsigned long   ifRxDMAOverruns;
3570 +
3571 +} CPMAC_DEVICE_MIB_T;
3572 +
3573 +
3574 +typedef struct
3575 +{
3576 +    void                         *owner;
3577 +    int                          timer_count;
3578 +    int                          timer_created;
3579 +    struct timer_list            timer[1];
3580 +    CPMAC_DRV_HAL_INFO_T         *drv_hal;
3581 +    unsigned int                 num_of_intr;
3582 +    CPMAC_ISR_INFO_T             cpmac_isr;
3583 +    unsigned int                 link_speed;
3584 +    unsigned int                 link_mode;
3585 +    unsigned int                 enable_802_1q;
3586 +    unsigned int                 timer_access_hal;
3587 +    unsigned int                 loop_back;
3588 +    CPMAC_RX_CHAN_INFO_T         *rx_chan_info;
3589 +    CPMAC_TX_CHAN_INFO_T         *tx_chan_info;
3590 +    CPMAC_ABILITY_INFO_T         *ability_info;
3591 +    CPMAC_DEVICE_MIB_T           *device_mib;
3592 +    CPMAC_DRV_STATS_T            *stats;
3593 +    unsigned int                 flags;
3594 +    unsigned int                 delay_ticks;
3595 +    char                         mac_addr[6];
3596 +    struct net_device_stats      net_dev_stats; 
3597 +//    rwlock_t                     rw_lock;
3598 +    int                          set_to_close;
3599 +    struct net_device            *next_device;
3600 +    unsigned int                 instance_num;
3601 +    unsigned int                 non_data_irq_expected;
3602 +    unsigned long                dev_size;
3603 +    void*                        led_handle;
3604 +} CPMAC_PRIVATE_INFO_T;
3605 +
3606 +
3607 +/* Private flags */
3608 +
3609 +/* bit 0 to 31, bit 32 is used to indicate set or reset */
3610 +
3611 +#define IFF_PRIV_SHORT_FRAMES   0x00010000
3612 +#define IFF_PRIV_JUMBO_FRAMES   0x00020000
3613 +#define IFF_PRIV_AUTOSPEED      0x00080000
3614 +#define IFF_PRIV_LINK10_HD      0x00100000
3615 +#define IFF_PRIV_LINK10_FD      0x00200000
3616 +#define IFF_PRIV_LINK100_HD     0x00400000
3617 +#define IFF_PRIV_LINK100_FD     0x00800000
3618 +#define IFF_PRIV_8021Q_EN       0x01000000
3619 +#define IFF_PRIV_NUM_TX_CHAN    0x02000000
3620 +#define IFF_PRIV_TX_FLOW_CNTL   0x04000000
3621 +#define IFF_PRIV_RX_FLOW_CNTL   0x08000000
3622 +#define IFF_PRIV_TX_PACING      0x10000000
3623 +#define IFF_PRIV_RX_PASS_CRC    0x20000000
3624 +
3625 +#define PRIVCSFLAGS             0x200
3626 +#define PRIVCGFLAGS             0x201
3627 +
3628 +
3629 +#define BLOCKING      1
3630 +#define CHAN_TEARDOWN 2
3631 +#define CHAN_SETUP    4
3632 +#define COMPLETE      8
3633 +#define FREE_BUFFER   16
3634 +
3635 +
3636 +static const char pszStats0[]            = "Stats0";
3637 +static const char pszStats1[]            = "Stats1";
3638 +static const char pszStats2[]            = "Stats2";
3639 +static const char pszStats3[]            = "Stats3";
3640 +static const char pszStats4[]            = "Stats4";
3641 +static const char pszStatsDump[]         = "StatsDump";
3642 +static const char pszStatsClear[]        = "StatsClear";
3643 +static const char pszRX_PASS_CRC[]       = "RX_PASS_CRC";
3644 +static const char pszRX_QOS_EN[]         = "RX_QOS_EN";
3645 +static const char pszRX_NO_CHAIN[]       = "RX_NO_CHAIN";
3646 +static const char pszRX_CMF_EN[]         = "RX_CMF_EN";
3647 +static const char pszRX_CSF_EN[]         = "RX_CSF_EN";
3648 +static const char pszRX_CEF_EN[]         = "RX_CEF_EN";
3649 +static const char pszRX_CAF_EN[]         = "RX_CAF_EN";
3650 +static const char pszRX_PROM_CH[]        = "RX_PROM_CH";
3651 +static const char pszRX_BROAD_EN[]       = "RX_BROAD_EN";
3652 +static const char pszRX_BROAD_CH[]       = "RX_BROAD_CH";
3653 +static const char pszRX_MULT_EN[]        = "RX_MULT_EN";
3654 +static const char pszRX_MULT_CH[]        = "RX_MULT_CH";
3655 +static const char pszTX_PTYPE[]          = "TX_PTYPE";
3656 +static const char pszTX_PACE[]           = "TX_PACE";
3657 +static const char pszMII_EN[]            = "MII_EN";
3658 +static const char pszTX_FLOW_EN[]        = "TX_FLOW_EN";
3659 +static const char pszRX_FLOW_EN[]        = "RX_FLOW_EN";
3660 +static const char pszRX_MAXLEN[]         = "RX_MAXLEN";
3661 +static const char pszRX_FILTERLOWTHRESH[]   = "RX_FILTERLOWTHRESH";
3662 +static const char pszRX0_FLOWTHRESH[]   = "RX0_FLOWTHRESH";
3663 +static const char pszRX_UNICAST_SET[]    = "RX_UNICAST_SET";
3664 +static const char pszRX_UNICAST_CLEAR[]  = "RX_UNICAST_CLEAR";
3665 +static const char pszMdioConnect[]       = "MdioConnect";
3666 +static const char pszMacAddr[]           = "MacAddr";
3667 +static const char pszTick[]              = "Tick";
3668 +static const char pszRX_MULTICAST[]      = "RX_MULTICAST";
3669 +static const char pszRX_MULTI_ALL[]      = "RX_MULTI_ALL";
3670 +static const char pszRX_MULTI_SINGLE[]   = "RX_MULTI_SINGLE";
3671 +
3672 +static const char pszSet[]               = "Set";
3673 +static const char pszGet[]               = "Get";
3674 +static const char pszClear[]             = "Clear";
3675 +
3676 +
3677 +void *cpmac_hal_malloc_buffer(unsigned int size, void *MemBase, unsigned int MemRange,
3678 +                              HAL_DEVICE *HalDev, HAL_RECEIVEINFO *HalReceiveInfo, 
3679 +                              OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev);
3680 +
3681 +void cpmac_hal_tear_down_complete(OS_DEVICE*, int, int);
3682 +int  cpmac_hal_control(OS_DEVICE *p_END_obj, const char *key, 
3683 +                   const char *action, void *value);
3684 +int  cpmac_hal_receive(OS_DEVICE *p_END_obj, FRAGLIST *fragList, 
3685 +               unsigned int FragCount, unsigned int pkt_len, 
3686 +               HAL_RECEIVEINFO *halReceiveInfo, 
3687 +               unsigned int mode);
3688 +int  cpmac_hal_send_complete(OS_SENDINFO*);
3689 +
3690 +void  cpmac_hal_isr(int irq, void *p_param, struct pt_regs *p_cb_param);
3691 +void  cpmac_handle_tasklet(unsigned long data);
3692 +
3693 +inline static int cpmac_ci_strcmp(const char *s1, const char *s2)
3694 +{
3695 +    while(*s1 && *s2)
3696 +    {
3697 +        if(tolower(*s1) != tolower(*s2))
3698 +            break;
3699 +        s1++;
3700 +        s2++;
3701 +    }
3702 +
3703 +    return(tolower(*s1) - tolower(*s2));
3704 +}
3705 +
3706 +#endif
3707 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c
3708 --- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c  1970-01-01 01:00:00.000000000 +0100
3709 +++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c  2005-07-12 02:48:42.044593000 +0200
3710 @@ -0,0 +1,492 @@
3711 +/******************************************************************************
3712 + * FILE PURPOSE:    CPMAC Net Driver HAL support Source
3713 + ******************************************************************************
3714 + * FILE NAME:       cpmacHalLx.c
3715 + *
3716 + * DESCRIPTION:     CPMAC Network Device Driver Source
3717 + *
3718 + * REVISION HISTORY:
3719 + *
3720 + * Date           Description                               Author
3721 + *-----------------------------------------------------------------------------
3722 + * 27 Nov 2002    Initial Creation                          Suraj S Iyer  
3723 + * 09 Jun 2003    Updates for GA                            Suraj S Iyer
3724 + * 18 Dec 2003    Updated for 5.7                           Suraj S Iyer
3725 + *
3726 + * (C) Copyright 2003, Texas Instruments, Inc
3727 + *******************************************************************************/
3728 +#include <linux/kernel.h> 
3729 +#include <linux/module.h> 
3730 +#include <linux/init.h>
3731 +#include <linux/netdevice.h>
3732 +#include <linux/etherdevice.h>
3733 +#include <linux/delay.h>     
3734 +#include <linux/spinlock.h>
3735 +#include <linux/proc_fs.h>
3736 +#include <asm/io.h>
3737 +#include <linux/string.h>
3738 +
3739 +#include <asm/ar7/avalanche_intc.h>
3740 +
3741 +#include "cpmacHalLx.h"
3742 +#include "cpmac.h"
3743 +
3744 +/* PSP config headers */
3745 +#include "psp_config_parse.h"
3746 +#include "psp_config_mgr.h"
3747 +
3748 +/* debug */                                 
3749 +extern int cpmac_debug_mode;
3750 +#define dbgPrint if (cpmac_debug_mode) printk
3751 +#define errPrint printk
3752 +
3753 +char CpmacSignature[] = "Cpmac driver";
3754 +static unsigned long irq_flags = 0;
3755 +OS_SETUP *p_os_setup = NULL;
3756 +
3757 +extern int avalanche_request_intr_pacing(int, unsigned int, unsigned int);
3758 +extern int avalanche_free_intr_pacing(unsigned int blk_num);
3759 +
3760 +/*----------------------------------------------------------------------------
3761 + * Parameter extracting functionalities.
3762 + *--------------------------------------------------------------------------*/
3763 +static int os_find_parm_u_int(void *info_ptr, const char *param, unsigned int *val)
3764 +{
3765 +    int ret_val = 0;
3766 +
3767 +    if((ret_val = psp_config_get_param_uint(info_ptr, param, val)) == -1)
3768 +    {
3769 +        dbgPrint("Error: could not locate the requested \"%s\" param.\n",param);
3770 +        ret_val = -1;
3771 +    }
3772 +
3773 +    return(ret_val);
3774 +}
3775 +
3776 +static int os_find_parm_val(void *info_ptr, const char *param, void *val)
3777 +{
3778 +    int ret_val = 0;
3779 +
3780 +    if(psp_config_get_param_string(info_ptr, param, val) == -1)
3781 +    {
3782 +        dbgPrint("Error: could not locate the requested \"%s\" param.\n",param);
3783 +        ret_val = -1;
3784 +    }
3785 +
3786 +    return(ret_val);
3787 +}
3788 +
3789 +static int os_find_device(int unit, const char *find_name, void *device_info)
3790 +{
3791 +    int ret_val = 0;
3792 +
3793 +    if(psp_config_get((char *)find_name, unit, device_info) == -1)
3794 +    {
3795 +        dbgPrint("Error: could not locate the requested \"%s\" param.\n", find_name);
3796 +        ret_val = -1;
3797 +    }
3798 +
3799 +    return(ret_val);
3800 +}
3801 +
3802 +/*---------------------------------------------------------------------------
3803 + * Memory related OS abstraction.
3804 + *--------------------------------------------------------------------------*/
3805 +void os_free(void *mem_ptr)
3806 +{
3807 +    kfree(mem_ptr);
3808 +}
3809 +
3810 +void  os_free_buffer(OS_RECEIVEINFO *osReceiveInfo, void *mem_ptr)
3811 +{
3812 +    dev_kfree_skb_any(osReceiveInfo);
3813 +}
3814 +
3815 +void  os_free_dev(void *mem_ptr)
3816 +{
3817 +    kfree(mem_ptr);
3818 +}
3819 +
3820 +void os_free_dma_xfer(void *mem_ptr)
3821 +{
3822 +    kfree(mem_ptr);
3823 +}
3824 +
3825 +static void *os_malloc(unsigned int size)
3826 +{
3827 +    return(kmalloc(size, GFP_KERNEL));
3828 +}
3829 +
3830 +static void *os_malloc_dma_xfer(unsigned int size, 
3831 +                                void         *mem_base, 
3832 +                                unsigned int mem_range)
3833 +{
3834 +    return(kmalloc(size, GFP_KERNEL));
3835 +}
3836 +
3837 +static void *os_malloc_dev(unsigned int size)
3838 +{
3839 +    return(kmalloc(size, GFP_KERNEL));
3840 +}
3841 +
3842 +
3843 +/*----------------------------------------------------------------------------
3844 + * CRITICAL SECTION ENABLING/DISABLING.
3845 + *--------------------------------------------------------------------------*/
3846 +static void os_critical_on(void)
3847 +{
3848 +    save_and_cli(irq_flags);
3849 +}
3850 +
3851 +static void os_critical_off(void)
3852 +{
3853 +    restore_flags(irq_flags);
3854 +}
3855 +
3856 +/*----------------------------------------------------------------------------
3857 + * Cache related abstraction
3858 + *--------------------------------------------------------------------------*/
3859 +static void os_cache_invalidate(void *mem_ptr, int size)
3860 +{
3861 +    dma_cache_inv((unsigned long)mem_ptr, size);
3862 +}
3863 +
3864 +static void os_cache_writeback(void *mem_ptr, int size)
3865 +{
3866 +    dma_cache_wback_inv((unsigned long)mem_ptr, size);
3867 +}
3868 +
3869 +/*-----------------------------------------------------------------------------
3870 + * Support functions.
3871 + *---------------------------------------------------------------------------*/
3872 +
3873 +static void  hal_drv_unregister_isr(OS_DEVICE *p_dev, int intr)
3874 +{
3875 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_dev->priv;
3876 +    CPMAC_ISR_INFO_T     *p_isr_cb_param = &p_cpmac_priv->cpmac_isr;
3877 +    intr                                 = LNXINTNUM(intr);
3878 +
3879 +    free_irq(p_isr_cb_param->intr, p_isr_cb_param);
3880 +
3881 +    dbgPrint("cpmac_hal_unregister called for the intr %d for unit %x and isr_cb_param %x.\n", 
3882 +             intr, p_cpmac_priv->instance_num, (unsigned int )&p_cpmac_priv->cpmac_isr);
3883 +}
3884 +
3885 +
3886 +static void hal_drv_register_isr(OS_DEVICE *p_dev, 
3887 +                                 CPMAC_HAL_ISR_FUNC_T hal_isr, int intr)
3888 +{
3889 +    CPMAC_PRIVATE_INFO_T *p_cpmac_priv   = p_dev->priv;
3890 +    CPMAC_DRV_HAL_INFO_T *p_drv_hal      = p_cpmac_priv->drv_hal;
3891 +    CPMAC_ISR_INFO_T     *p_isr_cb_param = &p_cpmac_priv->cpmac_isr;
3892 +    intr                                 = LNXINTNUM(intr);
3893 +       
3894 +    dbgPrint("osRegister called for the intr %d for device %x and p_isr_cb_param %x.\n", 
3895 +             intr, (bit32u)p_dev, (bit32u)p_isr_cb_param);
3896 +
3897 +    p_isr_cb_param->owner       = p_drv_hal;
3898 +    p_isr_cb_param->hal_isr     = hal_isr;
3899 +    p_isr_cb_param->intr        = intr;
3900 +
3901 +    tasklet_init(&p_isr_cb_param->tasklet, cpmac_handle_tasklet, (unsigned long)p_isr_cb_param);
3902 +    dbgPrint("Success in registering irq %d for Cpmac unit# %d.\n", intr, p_cpmac_priv->instance_num); 
3903 +}
3904 +
3905 +/*---------------------------------------------------------------------------
3906 + * FUNCTIONS called by the CPMAC Net Device.
3907 + *-------------------------------------------------------------------------*/
3908 +static int load_os_funcs(OS_FUNCTIONS *os_func)
3909 +{
3910 +    dbgPrint("os_init_module: Start\n"); 
3911 +    if( os_func == 0 )
3912 +    {
3913 +        return(sizeof(OS_FUNCTIONS));   
3914 +    }
3915 +
3916 +    os_func->Control                    = cpmac_hal_control;
3917 +    os_func->CriticalOn                 = os_critical_on;
3918 +    os_func->CriticalOff                = os_critical_off;
3919 +    os_func->DataCacheHitInvalidate     = os_cache_invalidate;
3920 +    os_func->DataCacheHitWriteback      = os_cache_writeback;       
3921 +    os_func->DeviceFindInfo     = os_find_device;
3922 +    os_func->DeviceFindParmUint = os_find_parm_u_int;
3923 +    os_func->DeviceFindParmValue= os_find_parm_val;
3924 +    os_func->Free               = os_free;
3925 +    os_func->FreeRxBuffer       = os_free_buffer;
3926 +    os_func->FreeDev            = os_free_dev;
3927 +    os_func->FreeDmaXfer        = os_free_dma_xfer;
3928 +    os_func->IsrRegister        = hal_drv_register_isr;
3929 +    os_func->IsrUnRegister      = hal_drv_unregister_isr;
3930 +    os_func->Malloc             = os_malloc;
3931 +    os_func->MallocDev          = os_malloc_dev;
3932 +    os_func->MallocDmaXfer      = os_malloc_dma_xfer;
3933 +    os_func->MallocRxBuffer     = cpmac_hal_malloc_buffer;
3934 +    os_func->Memset             = memset;
3935 +    os_func->Printf             = printk;
3936 +    os_func->Receive            = cpmac_hal_receive;
3937 +    os_func->SendComplete       = cpmac_hal_send_complete;
3938 +    os_func->Strcmpi            = cpmac_ci_strcmp;
3939 +    os_func->TeardownComplete   = cpmac_hal_tear_down_complete;
3940 +    os_func->Strstr             = strstr;
3941 +    os_func->Strtoul            = simple_strtol;
3942 +    os_func->Sprintf            = sprintf;
3943 +    os_func->Strlen             = strlen;
3944 +
3945 +    dbgPrint("os_init_module: Leave\n");             
3946 +  
3947 +    return(0);
3948 +}
3949 +
3950 +
3951 +int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T *p_drv_hal)
3952 +{
3953 +    HAL_DEVICE       *p_hal_dev    = p_drv_hal->hal_dev;
3954 +    HAL_FUNCTIONS    *p_hal_funcs  = p_drv_hal->hal_funcs;
3955 +
3956 +    return(p_hal_funcs->Init(p_hal_dev));
3957 +}
3958 +
3959 +int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *p_drv_hal)
3960 +{
3961 +    HAL_DEVICE       *p_hal_dev    = p_drv_hal->hal_dev;
3962 +    HAL_FUNCTIONS    *p_hal_funcs  = p_drv_hal->hal_funcs;
3963 +
3964 +    int              ret_val       = p_hal_funcs->Shutdown(p_hal_dev);
3965 +
3966 +#if 0
3967 +    if(ret_val == 0)
3968 +        kfree(p_hal_funcs);
3969 +    else
3970 +        ret_val = -1;
3971 +#endif
3972 +
3973 +    kfree(p_drv_hal->os_funcs); 
3974 +    
3975 +    return (ret_val); 
3976 +}
3977 +
3978 +int cpmac_drv_tx_setup(HAL_FUNCTIONS        *p_hal_funcs,
3979 +                       HAL_DEVICE           *p_hal_dev,
3980 +                       CPMAC_TX_CHAN_INFO_T *p_tx_chan_info)
3981 +{
3982 +    int ret_val = 0;
3983 +    int count   = 0;
3984 +    CHANNEL_INFO chan_info;
3985 +
3986 +    /* Let's setup the TX Channels. */
3987 +    for(count=0; count < p_tx_chan_info->cfg_chan; count++)
3988 +    {
3989 +        chan_info.Channel        = count;
3990 +        chan_info.Direction      = DIRECTION_TX;       
3991 +        chan_info.TxNumBuffers   = p_tx_chan_info->chan[count].num_BD;
3992 +        chan_info.TxServiceMax   = p_tx_chan_info->chan[count].service_max;
3993 +        chan_info.TxNumQueues    = 0;
3994 +        
3995 +        if((ret_val = p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info,
3996 +                                                NULL)) != 0)
3997 +        {
3998 +            errPrint("Error in opening channel %d for TX.\n", count);
3999 +            ret_val = -1;
4000 +            break;
4001 +        }
4002 +
4003 +        p_tx_chan_info->opened_chan++;
4004 +    }
4005 +
4006 +    return(ret_val);
4007 +}
4008 +
4009 +int cpmac_drv_rx_setup(HAL_FUNCTIONS         *p_hal_funcs,
4010 +                       HAL_DEVICE            *p_hal_dev,
4011 +                       CPMAC_RX_CHAN_INFO_T  *p_rx_chan_info)
4012 +{
4013 +    int ret_val = 0;
4014 +    CHANNEL_INFO chan_info;
4015 +
4016 +    chan_info.Channel       = 0;
4017 +    chan_info.Direction     = DIRECTION_RX;
4018 +    chan_info.RxBufSize     = p_rx_chan_info->chan[0].buffer_size;
4019 +    chan_info.RxBufferOffset= p_rx_chan_info->chan[0].buffer_offset;
4020 +    chan_info.RxNumBuffers  = p_rx_chan_info->chan[0].num_BD;
4021 +    chan_info.RxServiceMax  = p_rx_chan_info->chan[0].service_max;
4022 +
4023 +    if(p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info, p_rx_chan_info) != 0) 
4024 +    {
4025 +        errPrint("Error in opening channel %d for RX.\n", 0);
4026 +        ret_val = -1;
4027 +    }
4028 +
4029 +    return(ret_val);
4030 +}
4031 +
4032 +int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *p_drv_hal,
4033 +                    CPMAC_TX_CHAN_INFO_T *p_tx_chan_info,
4034 +                    CPMAC_RX_CHAN_INFO_T *p_rx_chan_info,
4035 +                    unsigned int         flags)
4036 +{
4037 +    int ret_val = 0;
4038 +    HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs;
4039 +    HAL_DEVICE    *p_hal_dev   = p_drv_hal->hal_dev;
4040 +
4041 +    dbgPrint("It is in cpmac_drv_start for %x.\n", (unsigned int)p_drv_hal);
4042 +
4043 +    if(flags & CHAN_SETUP)
4044 +    {
4045 +        if(cpmac_drv_tx_setup(p_hal_funcs, p_hal_dev, 
4046 +                  p_tx_chan_info)!=0)
4047 +        {
4048 +            errPrint("Failed to set up tx channel(s).\n");
4049 +            ret_val = -1;
4050 +        }
4051 +        else if(cpmac_drv_rx_setup(p_hal_funcs, p_hal_dev,
4052 +                                   p_rx_chan_info)!=0)
4053 +        {
4054 +            errPrint("Failed to set up rx channel.\n");
4055 +            ret_val = -1;
4056 +        }
4057 +        else
4058 +        {
4059 +            ret_val = 0;
4060 +        }
4061 +    }
4062 +
4063 +    /* Error in setting up the Channels, quit. */
4064 +    if((ret_val == 0) && (ret_val = p_hal_funcs->Open(p_hal_dev)) != 0)
4065 +    {
4066 +        errPrint("failed to open the HAL!!!.\n");
4067 +        ret_val = -1;
4068 +    }
4069 +
4070 +    return (ret_val);
4071 +} /* cpmac_drv_start */
4072 +
4073 +
4074 +
4075 +int cpmac_drv_tx_teardown(HAL_FUNCTIONS        *p_hal_funcs,
4076 +                          HAL_DEVICE           *p_hal_dev,
4077 +                          CPMAC_TX_CHAN_INFO_T *p_tx_chan_info,
4078 +                          unsigned int         flags)
4079 +{
4080 +    int ret_val = 0;
4081 +    int count   = 0;
4082 +
4083 +    /* Let's setup the TX Channels. */
4084 +    for(;  p_tx_chan_info->opened_chan > 0; 
4085 +        p_tx_chan_info->opened_chan--, count++)
4086 +    {
4087 +        if(p_hal_funcs->ChannelTeardown(p_hal_dev, count, flags) != 0)
4088 +        {
4089 +            errPrint("Error in tearing down channel %d for TX.\n", count);
4090 +            ret_val = -1;
4091 +            break;
4092 +        }
4093 +    }
4094 +
4095 +    return(ret_val);
4096 +}
4097 +
4098 +
4099 +int cpmac_drv_rx_teardown(HAL_FUNCTIONS *p_hal_funcs,
4100 +                  HAL_DEVICE    *p_hal_dev,
4101 +              unsigned int  flags)
4102 +{
4103 +    int ret_val = 0;
4104 +
4105 +    if(p_hal_funcs->ChannelTeardown(p_hal_dev, 0, flags) != 0) 
4106 +    {
4107 +        errPrint("Error in tearing down channel %d for RX.\n", 0);
4108 +        ret_val = -1;
4109 +    }
4110 +
4111 +    return(ret_val);
4112 +}
4113 +
4114 +int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T    *p_drv_hal,
4115 +                   CPMAC_TX_CHAN_INFO_T    *p_tx_chan_info,
4116 +                   CPMAC_RX_CHAN_INFO_T    *p_rx_chan_info,
4117 +                   unsigned int flags)
4118 +{
4119 +    HAL_DEVICE       *p_hal_dev    = p_drv_hal->hal_dev;
4120 +    HAL_FUNCTIONS    *p_hal_funcs  = p_drv_hal->hal_funcs;
4121 +    int ret_val                    = 0;
4122 +
4123 +    if(flags & CHAN_TEARDOWN)
4124 +    {
4125 +        unsigned int chan_flags = 0;
4126 +
4127 +        if(flags & FREE_BUFFER) chan_flags |= 0x4; /* full tear down */
4128 +        if(flags & BLOCKING)    chan_flags |= 0x8; /* blocking call  */
4129 +
4130 +        dbgPrint("The teardown flags are %d.\n", flags);
4131 +        dbgPrint("The teardown chan flags are %d.\n", chan_flags);
4132 +
4133 +        if(cpmac_drv_tx_teardown(p_hal_funcs, p_hal_dev, 
4134 +                                 p_tx_chan_info, chan_flags | 0x1) != 0)
4135 +        {
4136 +            ret_val = -1;
4137 +            errPrint("The tx channel teardown failed.\n");
4138 +        }
4139 +        else if(cpmac_drv_rx_teardown(p_hal_funcs, p_hal_dev, chan_flags | 0x2) != 0)
4140 +        {
4141 +            ret_val = -1;
4142 +            errPrint("The rx channel teardown failed.\n");
4143 +        }
4144 +        else
4145 +        {
4146 +            ;
4147 +        }
4148 +    }
4149 +
4150 +    if(ret_val == 0)
4151 +    {
4152 +        int close_flags = 1;
4153 +
4154 +        if(flags & FREE_BUFFER)  close_flags = 2;
4155 +//        if(flags & COMPLETE)     close_flags = 3;
4156 +
4157 +        if(p_hal_funcs->Close(p_hal_dev, close_flags) != 0)
4158 +        {
4159 +            ret_val = -1;
4160 +        }
4161 +    }
4162 +        
4163 +    return(ret_val);
4164 +}
4165 +
4166 +int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T *p_drv_hal, OS_DEVICE *p_os_dev, int inst)
4167 +{
4168 +    int ret_val = -1;
4169 +    int hal_func_size;
4170 +
4171 +    dbgPrint("Entering the CpmacInitModule for the inst %d \n", inst);
4172 +
4173 +    if((p_drv_hal->os_funcs = kmalloc(sizeof(OS_FUNCTIONS), GFP_KERNEL)) == NULL)
4174 +    {
4175 +        errPrint("Failed to allocate memory for OS_FUNCTIONS.\n");
4176 +    }
4177 +    else if(load_os_funcs(p_drv_hal->os_funcs) != 0)
4178 +    {
4179 +        errPrint("Failed to load OS funcs.\n");
4180 +        os_free(p_drv_hal->os_funcs);
4181 +    }
4182 +    else if(halCpmacInitModule(&p_drv_hal->hal_dev, p_os_dev,
4183 +                               &p_drv_hal->hal_funcs, p_drv_hal->os_funcs, 
4184 +                               sizeof(*p_drv_hal->os_funcs),
4185 +                               &hal_func_size, inst) != 0)
4186 +    {
4187 +        errPrint("halCpmacInitModule failed for inst %d \n", inst);
4188 +        os_free(p_drv_hal->os_funcs);
4189 +    }
4190 +    else if(p_drv_hal->hal_funcs->Probe(p_drv_hal->hal_dev) != 0)
4191 +    {
4192 +        errPrint("halCpmacProbe failed for inst %d \n", inst);       
4193 +        os_free(p_drv_hal->os_funcs);
4194 +    }
4195 +    else
4196 +    {
4197 +        /* every thing went well. */
4198 +        ret_val = 0;
4199 +    }  
4200 +
4201 +    return (ret_val);  
4202 +}
4203 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h
4204 --- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h  1970-01-01 01:00:00.000000000 +0100
4205 +++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h  2005-07-12 02:48:42.044593000 +0200
4206 @@ -0,0 +1,51 @@
4207 +/******************************************************************************
4208 + * FILE PURPOSE:    CPMAC Linux Device Driver HAL support Header
4209 + ******************************************************************************
4210 + * FILE NAME:       cpmacHalVx.h
4211 + *
4212 + * DESCRIPTION:     CPMAC Linux Device Driver Header
4213 + *
4214 + * REVISION HISTORY:
4215 + *
4216 + * Date           Description                               Author
4217 + *-----------------------------------------------------------------------------
4218 + * 27 Nov 2002    Initial Creation                          Suraj S Iyer  
4219 + * 09 Jun 2003    Updates for GA                            Suraj S Iyer
4220 + * 
4221 + * (C) Copyright 2002, Texas Instruments, Inc
4222 + *******************************************************************************/
4223 +
4224 +#ifndef __CPMAC_HAL_LX_H
4225 +#define __CPMAC_HAL_LX_H
4226 +
4227 +
4228 +typedef struct net_device         OS_DEVICE;
4229 +typedef struct sk_buff            OS_RECEIVEINFO;
4230 +typedef struct sk_buff            OS_SENDINFO;
4231 +
4232 +#ifdef DEBUG
4233 +typedef void                      HAL_RECEIVEINFO;
4234 +typedef void                      HAL_DEVICE;
4235 +typedef void                      OS_SETUP;
4236 +#endif
4237 +
4238 +#define OS_SETUP   void
4239 +#define HAL_DEVICE void
4240 +#define HAL_RECEIVEINFO void
4241 +
4242 +#define _CPHAL_CPMAC
4243
4244 +#include "cpswhal_cpmac.h"
4245 +#include "cpmac.h"
4246 +
4247 +int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *, CPMAC_TX_CHAN_INFO_T*,
4248 +                    CPMAC_RX_CHAN_INFO_T *, unsigned int);
4249 +int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *);
4250 +int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T*);
4251 +int cpmac_drv_close(CPMAC_DRV_HAL_INFO_T*);
4252 +int cpmac_drv_open(CPMAC_DRV_HAL_INFO_T*);
4253 +int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T*, OS_DEVICE*, int);
4254 +int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T *p_drv_hal,CPMAC_TX_CHAN_INFO_T *p_tx_chan_info,
4255 +                   CPMAC_RX_CHAN_INFO_T *p_rx_chan_info,unsigned int flags);
4256 +
4257 +#endif
4258 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h
4259 --- linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h   1970-01-01 01:00:00.000000000 +0100
4260 +++ linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h   2005-07-12 02:48:42.045593000 +0200
4261 @@ -0,0 +1,406 @@
4262 +/****************************************************************************
4263 +        TNETD73xx Software Support
4264 +        Copyright(c) 2000, Texas Instruments Incorporated. All Rights Reserved.
4265 +
4266 +        FILE: cpmac_reg.h   Register definitions for the CPMAC module
4267 +
4268 +         DESCRIPTION:
4269 +                This include file contains register definitions for the
4270 +                CPMAC module.
4271 +
4272 +         HISTORY:
4273 +              15Nov00 BEGR Original version written
4274 +              30May02 MICK Added bits for Int Vector
4275 +              19Sep02 MICK Added INT_ACK per Channel
4276 +              08Nov02 GDUN Updated to use base
4277 +              12Nov02 MICK Incorporated into CPHAL 
4278 +*****************************************************************************/
4279 +#ifndef _INC_CPMAC_REG
4280 +#define _INC_CPMAC_REG
4281 +
4282 +#ifndef MEM_PTR
4283 +#define MEM_PTR volatile bit32u *
4284 +#endif
4285 +
4286 +/***************************************************************************
4287 + *                                                                         
4288 + *         C P M A C  M E M O R Y  M A P 
4289 + *                                                                         
4290 + **************************************************************************/
4291 +
4292 +#define pCPMAC_TX_IDVER(base)                 ((MEM_PTR)(base+0x000))
4293 +#define  CPMAC_TX_IDVER(base)                 (*pCPMAC_TX_IDVER(base))
4294 +#define pCPMAC_TX_CONTROL(base)               ((MEM_PTR)(base+0x004))
4295 +#define  CPMAC_TX_CONTROL(base)               (*pCPMAC_TX_CONTROL(base))
4296 +#define pCPMAC_TX_TEARDOWN(base)              ((MEM_PTR)(base+0x008))
4297 +#define  CPMAC_TX_TEARDOWN(base)              (*pCPMAC_TX_TEARDOWN(base))
4298 +#define pCPMAC_RX_IDVER(base)                 ((MEM_PTR)(base+0x010))
4299 +#define  CPMAC_RX_IDVER(base)                 (*pCPMAC_RX_IDVER(base))
4300 +#define pCPMAC_RX_CONTROL(base)               ((MEM_PTR)(base+0x014))
4301 +#define  CPMAC_RX_CONTROL(base)               (*pCPMAC_RX_CONTROL(base))
4302 +#define pCPMAC_RX_TEARDOWN(base)              ((MEM_PTR)(base+0x018))
4303 +#define  CPMAC_RX_TEARDOWN(base)              (*pCPMAC_RX_TEARDOWN(base))
4304 +#define pCPMAC_RX_MBP_ENABLE(base)            ((MEM_PTR)(base+0x100))
4305 +#define  CPMAC_RX_MBP_ENABLE(base)            (*pCPMAC_RX_MBP_ENABLE(base))
4306 +#define pCPMAC_RX_UNICAST_SET(base)           ((MEM_PTR)(base+0x104))
4307 +#define  CPMAC_RX_UNICAST_SET(base)           (*pCPMAC_RX_UNICAST_SET(base))
4308 +#define pCPMAC_RX_UNICAST_CLEAR(base)         ((MEM_PTR)(base+0x108))
4309 +#define  CPMAC_RX_UNICAST_CLEAR(base)         (*pCPMAC_RX_UNICAST_CLEAR(base))
4310 +#define pCPMAC_RX_MAXLEN(base)                ((MEM_PTR)(base+0x10C))
4311 +#define  CPMAC_RX_MAXLEN(base)                (*pCPMAC_RX_MAXLEN(base))
4312 +#define pCPMAC_RX_BUFFER_OFFSET(base)         ((MEM_PTR)(base+0x110))
4313 +#define  CPMAC_RX_BUFFER_OFFSET(base)         (*pCPMAC_RX_BUFFER_OFFSET(base))
4314 +#define pCPMAC_RX_FILTERLOWTHRESH(base)       ((MEM_PTR)(base+0x114))
4315 +#define  CPMAC_RX_FILTERLOWTHRESH(base)       (*pCPMAC_RX_FILTERLOWTHRESH(base))
4316 +#define pCPMAC_RX0_FLOWTHRESH(base)           ((MEM_PTR)(base+0x120))
4317 +#define  CPMAC_RX0_FLOWTHRESH(base)           (*pCPMAC_RX0_FLOWTHRESH(base))
4318 +#define pCPMAC_RX1_FLOWTHRESH(base)           ((MEM_PTR)(base+0x124))
4319 +#define  CPMAC_RX1_FLOWTHRESH(base)           (*pCPMAC_RX1_FLOWTHRESH(base))
4320 +#define pCPMAC_RX2_FLOWTHRESH(base)           ((MEM_PTR)(base+0x128))
4321 +#define  CPMAC_RX2_FLOWTHRESH(base)           (*pCPMAC_RX2_FLOWTHRESH(base))
4322 +#define pCPMAC_RX3_FLOWTHRESH(base)           ((MEM_PTR)(base+0x12C))
4323 +#define  CPMAC_RX3_FLOWTHRESH(base)           (*pCPMAC_RX3_FLOWTHRESH(base))
4324 +#define pCPMAC_RX4_FLOWTHRESH(base)           ((MEM_PTR)(base+0x130))
4325 +#define  CPMAC_RX4_FLOWTHRESH(base)           (*pCPMAC_RX4_FLOWTHRESH(base))
4326 +#define pCPMAC_RX5_FLOWTHRESH(base)           ((MEM_PTR)(base+0x134))
4327 +#define  CPMAC_RX5_FLOWTHRESH(base)           (*pCPMAC_RX5_FLOWTHRESH(base))
4328 +#define pCPMAC_RX6_FLOWTHRESH(base)           ((MEM_PTR)(base+0x138))
4329 +#define  CPMAC_RX6_FLOWTHRESH(base)           (*pCPMAC_RX6_FLOWTHRESH(base))
4330 +#define pCPMAC_RX7_FLOWTHRESH(base)           ((MEM_PTR)(base+0x13C))
4331 +#define  CPMAC_RX7_FLOWTHRESH(base)           (*pCPMAC_RX7_FLOWTHRESH(base))
4332 +#define pCPMAC_RX0_FREEBUFFER(base)           ((MEM_PTR)(base+0x140))
4333 +#define  CPMAC_RX0_FREEBUFFER(base)           (*pCPMAC_RX0_FREEBUFFER(base))
4334 +#define pCPMAC_RX1_FREEBUFFER(base)           ((MEM_PTR)(base+0x144))
4335 +#define  CPMAC_RX1_FREEBUFFER(base)           (*pCPMAC_RX1_FREEBUFFER(base))
4336 +#define pCPMAC_RX2_FREEBUFFER(base)           ((MEM_PTR)(base+0x148))
4337 +#define  CPMAC_RX2_FREEBUFFER(base)           (*pCPMAC_RX2_FREEBUFFER(base))
4338 +#define pCPMAC_RX3_FREEBUFFER(base)           ((MEM_PTR)(base+0x14C))
4339 +#define  CPMAC_RX3_FREEBUFFER(base)           (*pCPMAC_RX3_FREEBUFFER(base))
4340 +#define pCPMAC_RX4_FREEBUFFER(base)           ((MEM_PTR)(base+0x150))
4341 +#define  CPMAC_RX4_FREEBUFFER(base)           (*pCPMAC_RX4_FREEBUFFER(base))
4342 +#define pCPMAC_RX5_FREEBUFFER(base)           ((MEM_PTR)(base+0x154))
4343 +#define  CPMAC_RX5_FREEBUFFER(base)           (*pCPMAC_RX5_FREEBUFFER(base))
4344 +#define pCPMAC_RX6_FREEBUFFER(base)           ((MEM_PTR)(base+0x158))
4345 +#define  CPMAC_RX6_FREEBUFFER(base)           (*pCPMAC_RX6_FREEBUFFER(base))
4346 +#define pCPMAC_RX7_FREEBUFFER(base)           ((MEM_PTR)(base+0x15C))
4347 +#define  CPMAC_RX7_FREEBUFFER(base)           (*pCPMAC_RX7_FREEBUFFER(base))
4348 +#define pCPMAC_MACCONTROL(base)               ((MEM_PTR)(base+0x160))
4349 +#define  CPMAC_MACCONTROL(base)               (*pCPMAC_MACCONTROL(base))
4350 +#define pCPMAC_MACSTATUS(base)                ((MEM_PTR)(base+0x164))
4351 +#define  CPMAC_MACSTATUS(base)                (*pCPMAC_MACSTATUS(base))
4352 +#define pCPMAC_EMCONTROL(base)                ((MEM_PTR)(base+0x168))
4353 +#define  CPMAC_EMCONTROL(base)                (*pCPMAC_EMCONTROL(base))
4354 +#define pCPMAC_TX_INTSTAT_RAW(base)           ((MEM_PTR)(base+0x170))
4355 +#define  CPMAC_TX_INTSTAT_RAW(base)           (*pCPMAC_TX_INTSTAT_RAW(base))
4356 +#define pCPMAC_TX_INTSTAT_MASKED(base)        ((MEM_PTR)(base+0x174))
4357 +#define  CPMAC_TX_INTSTAT_MASKED(base)        (*pCPMAC_TX_INTSTAT_MASKED(base))
4358 +#define pCPMAC_TX_INTMASK_SET(base)           ((MEM_PTR)(base+0x178))
4359 +#define  CPMAC_TX_INTMASK_SET(base)           (*pCPMAC_TX_INTMASK_SET(base))
4360 +#define pCPMAC_TX_INTMASK_CLEAR(base)         ((MEM_PTR)(base+0x17C))
4361 +#define  CPMAC_TX_INTMASK_CLEAR(base)         (*pCPMAC_TX_INTMASK_CLEAR(base))
4362 +#define pCPMAC_MAC_IN_VECTOR(base)            ((MEM_PTR)(base+0x180))
4363 +#define  CPMAC_MAC_IN_VECTOR(base)            (*pCPMAC_MAC_IN_VECTOR(base))
4364 +#define pCPMAC_MAC_EOI_VECTOR(base)           ((MEM_PTR)(base+0x184))
4365 +#define  CPMAC_MAC_EOI_VECTOR(base)           (*pCPMAC_MAC_EOI_VECTOR(base))
4366 +#define pCPMAC_RX_INTSTAT_RAW(base)           ((MEM_PTR)(base+0x190))
4367 +#define  CPMAC_RX_INTSTAT_RAW(base)           (*pCPMAC_RX_INTSTAT_RAW(base))
4368 +#define pCPMAC_RX_INTSTAT_MASKED(base)        ((MEM_PTR)(base+0x194))
4369 +#define  CPMAC_RX_INTSTAT_MASKED(base)        (*pCPMAC_RX_INTSTAT_MASKED(base))
4370 +#define pCPMAC_RX_INTMASK_SET(base)           ((MEM_PTR)(base+0x198))
4371 +#define  CPMAC_RX_INTMASK_SET(base)           (*pCPMAC_RX_INTMASK_SET(base))
4372 +#define pCPMAC_RX_INTMASK_CLEAR(base)         ((MEM_PTR)(base+0x19C))
4373 +#define  CPMAC_RX_INTMASK_CLEAR(base)         (*pCPMAC_RX_INTMASK_CLEAR(base))
4374 +#define pCPMAC_MAC_INTSTAT_RAW(base)          ((MEM_PTR)(base+0x1A0))
4375 +#define  CPMAC_MAC_INTSTAT_RAW(base)          (*pCPMAC_MAC_INTSTAT_RAW(base))
4376 +#define pCPMAC_MAC_INTSTAT_MASKED(base)       ((MEM_PTR)(base+0x1A4))
4377 +#define  CPMAC_MAC_INTSTAT_MASKED(base)       (*pCPMAC_MAC_INTSTAT_MASKED(base))
4378 +#define pCPMAC_MAC_INTMASK_SET(base)          ((MEM_PTR)(base+0x1A8))
4379 +#define  CPMAC_MAC_INTMASK_SET(base)          (*pCPMAC_MAC_INTMASK_SET(base))
4380 +#define pCPMAC_MAC_INTMASK_CLEAR(base)        ((MEM_PTR)(base+0x1AC))
4381 +#define  CPMAC_MAC_INTMASK_CLEAR(base)        (*pCPMAC_MAC_INTMASK_CLEAR(base))
4382 +#define pCPMAC_MACADDRLO_0(base)              ((MEM_PTR)(base+0x1B0))
4383 +#define  CPMAC_MACADDRLO_0(base)              (*pCPMAC_MACADDRLO_0(base))
4384 +#define pCPMAC_MACADDRLO_1(base)              ((MEM_PTR)(base+0x1B4))
4385 +#define  CPMAC_MACADDRLO_1(base)              (*pCPMAC_MACADDRLO_1(base))
4386 +#define pCPMAC_MACADDRLO_2(base)              ((MEM_PTR)(base+0x1B8))
4387 +#define  CPMAC_MACADDRLO_2(base)              (*pCPMAC_MACADDRLO_2(base))
4388 +#define pCPMAC_MACADDRLO_3(base)              ((MEM_PTR)(base+0x1BC))
4389 +#define  CPMAC_MACADDRLO_3(base)              (*pCPMAC_MACADDRLO_3(base))
4390 +#define pCPMAC_MACADDRLO_4(base)              ((MEM_PTR)(base+0x1C0))
4391 +#define  CPMAC_MACADDRLO_4(base)              (*pCPMAC_MACADDRLO_4(base))
4392 +#define pCPMAC_MACADDRLO_5(base)              ((MEM_PTR)(base+0x1C4))
4393 +#define  CPMAC_MACADDRLO_5(base)              (*pCPMAC_MACADDRLO_5(base))
4394 +#define pCPMAC_MACADDRLO_6(base)              ((MEM_PTR)(base+0x1C8))
4395 +#define  CPMAC_MACADDRLO_6(base)              (*pCPMAC_MACADDRLO_6(base))
4396 +#define pCPMAC_MACADDRLO_7(base)              ((MEM_PTR)(base+0x1CC))
4397 +#define  CPMAC_MACADDRLO_7(base)              (*pCPMAC_MACADDRLO_7(base))
4398 +#define pCPMAC_MACADDRMID(base)               ((MEM_PTR)(base+0x1D0))
4399 +#define  CPMAC_MACADDRMID(base)               (*pCPMAC_MACADDRMID(base))
4400 +#define pCPMAC_MACADDRHI(base)                ((MEM_PTR)(base+0x1D4))
4401 +#define  CPMAC_MACADDRHI(base)                (*pCPMAC_MACADDRHI(base))
4402 +#define pCPMAC_MACHASH1(base)                 ((MEM_PTR)(base+0x1D8))
4403 +#define  CPMAC_MACHASH1(base)                 (*pCPMAC_MACHASH1(base))
4404 +#define pCPMAC_MACHASH2(base)                 ((MEM_PTR)(base+0x1DC))
4405 +#define  CPMAC_MACHASH2(base)                 (*pCPMAC_MACHASH2(base))
4406 +#define pCPMAC_BOFFTEST(base)                 ((MEM_PTR)(base+0x1E0))
4407 +#define  CPMAC_BOFFTEST(base)                 (*pCPMAC_BOFFTEST(base))
4408 +#define pCPMAC_PACTEST(base)                  ((MEM_PTR)(base+0x1E4))
4409 +#define  CPMAC_PACTEST(base)                  (*pCPMAC_PACTEST(base))
4410 +#define pCPMAC_RXPAUSE(base)                  ((MEM_PTR)(base+0x1E8))
4411 +#define  CPMAC_RXPAUSE(base)                  (*pCPMAC_RXPAUSE(base))
4412 +#define pCPMAC_TXPAUSE(base)                  ((MEM_PTR)(base+0x1EC))
4413 +#define  CPMAC_TXPAUSE(base)                  (*pCPMAC_TXPAUSE(base))
4414 +/* STATISTICS */
4415 +#define pCPMAC_RXGOODFRAMES(base)             ((MEM_PTR)(base+0x200))
4416 +#define  CPMAC_RXGOODFRAMES(base)             (*pCPMAC_RXGOODFRAMES(base))
4417 +#define pCPMAC_RXBROADCASTFRAMES(base)        ((MEM_PTR)(base+0x204))
4418 +#define  CPMAC_RXBROADCASTFRAMES(base)        (*pCPMAC_RXBROADCASTFRAMES(base))
4419 +#define pCPMAC_RXMULTICASTFRAMES(base)        ((MEM_PTR)(base+0x208))
4420 +#define  CPMAC_RXMULTICASTFRAMES(base)        (*pCPMAC_RXMULTICASTFRAMES(base))
4421 +#define pCPMAC_RXPAUSEFRAMES(base)            ((MEM_PTR)(base+0x20C))
4422 +#define   CPMAC_RXPAUSEFRAMES(base)           (*pCPMAC_RXPAUSEFRAMES(base))
4423 +#define pCPMAC_RXCRCERRORS(base)              ((MEM_PTR)(base+0x210))
4424 +#define   CPMAC_RXCRCERRORS(base)             (*pCPMAC_RXCRCERRORS(base))
4425 +#define pCPMAC_RXALIGNCODEERRORS(base)        ((MEM_PTR)(base+0x214))
4426 +#define   CPMAC_RXALIGNCODEERRORS(base)       (*pCPMAC_RXALIGNCODEERRORS(base))
4427 +#define pCPMAC_RXOVERSIZEDFRAMES(base)        ((MEM_PTR)(base+0x218))
4428 +#define   CPMAC_RXOVERSIZEDFRAMES(base)       (*pCPMAC_RXOVERSIZEDFRAMES(base))
4429 +#define pCPMAC_RXJABBERFRAMES(base)           ((MEM_PTR)(base+0x21C))
4430 +#define  CPMAC_RXJABBERFRAMES(base)           (*pCPMAC_RXJABBERFRAMES(base))
4431 +#define pCPMAC_RXUNDERSIZEDFRAMES(base)       ((MEM_PTR)(base+0x220))
4432 +#define  CPMAC_RXUNDERSIZEDFRAMES(base)       (*pCPMAC_RXUNDERSIZEDFRAMES(base))
4433 +#define pCPMAC_RXFRAGMENTS(base)              ((MEM_PTR)(base+0x224))
4434 +#define  CPMAC_RXFRAGMENTS(base)              (*pCPMAC_RXFRAGMENTS(base))
4435 +#define pCPMAC_RXFILTEREDFRAMES(base)         ((MEM_PTR)(base+0x228))
4436 +#define  CPMAC_RXFILTEREDFRAMES(base)         (*pCPMAC_RXFILTEREDFRAMES(base))
4437 +#define pCPMAC_RXQOSFILTEREDFRAMES(base)      ((MEM_PTR)(base+0x22C))
4438 +#define  CPMAC_RXQOSFILTEREDFRAMES(base)      (*pCPMAC_RXQOSFILTEREDFRAMES(base))
4439 +#define pCPMAC_RXOCTETS(base)                 ((MEM_PTR)(base+0x230))
4440 +#define  CPMAC_RXOCTETS(base)                 (*pCPMAC_RXOCTETS(base))
4441 +#define pCPMAC_TXGOODFRAMES(base)             ((MEM_PTR)(base+0x234))
4442 +#define  CPMAC_TXGOODFRAMES(base)             (*pCPMAC_TXGOODFRAMES(base))
4443 +#define pCPMAC_TXBROADCASTFRAMES(base)        ((MEM_PTR)(base+0x238))
4444 +#define  CPMAC_TXBROADCASTFRAMES(base)        (*pCPMAC_TXBROADCASTFRAMES(base))
4445 +#define pCPMAC_TXMULTICASTFRAMES(base)        ((MEM_PTR)(base+0x23C))
4446 +#define  CPMAC_TXMULTICASTFRAMES(base)        (*pCPMAC_TXMULTICASTFRAMES(base))
4447 +#define pCPMAC_TXPAUSEFRAMES(base)            ((MEM_PTR)(base+0x240))
4448 +#define  CPMAC_TXPAUSEFRAMES(base)            (*pCPMAC_TXPAUSEFRAMES(base))
4449 +#define pCPMAC_TXDEFERREDFRAMES(base)         ((MEM_PTR)(base+0x244))
4450 +#define  CPMAC_TXDEFERREDFRAMES(base)         (*pCPMAC_TXDEFERREDFRAMES(base))
4451 +#define pCPMAC_TXCOLLISIONFRAMES(base)        ((MEM_PTR)(base+0x248))
4452 +#define  CPMAC_TXCOLLISIONFRAMES(base)        (*pCPMAC_TXCOLLISIONFRAMES(base))
4453 +#define pCPMAC_TXSINGLECOLLFRAMES(base)       ((MEM_PTR)(base+0x24C))
4454 +#define  CPMAC_TXSINGLECOLLFRAMES(base)       (*pCPMAC_TXSINGLECOLLFRAMES(base))
4455 +#define pCPMAC_TXMULTCOLLFRAMES(base)         ((MEM_PTR)(base+0x250))
4456 +#define  CPMAC_TXMULTCOLLFRAMES(base)         (*pCPMAC_TXMULTCOLLFRAMES(base))
4457 +#define pCPMAC_TXEXCESSIVECOLLISIONS(base)    ((MEM_PTR)(base+0x254))
4458 +#define  CPMAC_TXEXCESSIVECOLLISIONS(base)    (*pCPMAC_TXEXCESSIVECOLLISIONS(base))
4459 +#define pCPMAC_TXLATECOLLISIONS(base)         ((MEM_PTR)(base+0x258))
4460 +#define  CPMAC_TXLATECOLLISIONS(base)         (*pCPMAC_TXLATECOLLISIONS(base))
4461 +#define pCPMAC_TXUNDERRUN(base)               ((MEM_PTR)(base+0x25C))
4462 +#define  CPMAC_TXUNDERRUN(base)               (*pCPMAC_TXUNDERRUN(base))
4463 +#define pCPMAC_TXCARRIERSENSEERRORS(base)     ((MEM_PTR)(base+0x260))
4464 +#define  CPMAC_TXCARRIERSENSEERRORS(base)     (*pCPMAC_TXCARRIERSENSEERRORS(base))
4465 +#define pCPMAC_TXOCTETS(base)                 ((MEM_PTR)(base+0x264))
4466 +#define  CPMAC_TXOCTETS(base)                 (*pCPMAC_TXOCTETS(base))
4467 +#define pCPMAC_64OCTETFRAMES(base)            ((MEM_PTR)(base+0x268))
4468 +#define  CPMAC_64OCTETFRAMES(base)            (*pCPMAC_64OCTETFRAMES(base))
4469 +#define pCPMAC_65T127OCTETFRAMES(base)        ((MEM_PTR)(base+0x26C))
4470 +#define  CPMAC_65T127OCTETFRAMES(base)        (*pCPMAC_65T127OCTETFRAMES(base))
4471 +#define pCPMAC_128T255OCTETFRAMES(base)       ((MEM_PTR)(base+0x270))
4472 +#define  CPMAC_128T255OCTETFRAMES(base)       (*pCPMAC_128T255OCTETFRAMES(base))
4473 +#define pCPMAC_256T511OCTETFRAMES(base)       ((MEM_PTR)(base+0x274))
4474 +#define  CPMAC_256T511OCTETFRAMES(base)       (*pCPMAC_256T511OCTETFRAMES(base))
4475 +#define pCPMAC_512T1023OCTETFRAMES(base)      ((MEM_PTR)(base+0x278))
4476 +#define  CPMAC_512T1023OCTETFRAMES(base)      (*pCPMAC_512T1023OCTETFRAMES(base))
4477 +#define pCPMAC_1024TUPOCTETFRAMES(base)       ((MEM_PTR)(base+0x27C))
4478 +#define  CPMAC_1024TUPOCTETFRAMES(base)       (*pCPMAC_1024TUPOCTETFRAMES(base))
4479 +#define pCPMAC_NETOCTETS(base)                ((MEM_PTR)(base+0x280))
4480 +#define  CPMAC_NETOCTETS(base)                (*pCPMAC_NETOCTETS(base))
4481 +#define pCPMAC_RXSOFOVERRUNS(base)            ((MEM_PTR)(base+0x284))
4482 +#define  CPMAC_RXSOFOVERRUNS(base)            (*pCPMAC_RXSOFOVERRUNS(base))
4483 +#define pCPMAC_RXMOFOVERRUNS(base)            ((MEM_PTR)(base+0x288))
4484 +#define  CPMAC_RXMOFOVERRUNS(base)            (*pCPMAC_RXMOFOVERRUNS(base))
4485 +#define pCPMAC_RXDMAOVERRUNS(base)            ((MEM_PTR)(base+0x28C))
4486 +#define  CPMAC_RXDMAOVERRUNS(base)            (*pCPMAC_RXDMAOVERRUNS(base))
4487 +
4488 +#define  CPMAC_TX_HDP(base,ch)                (*(MEM_PTR)(base+0x600+(4*ch)))
4489 +#define pCPMAC_TX0_HDP(base)                  ((MEM_PTR)(base+0x600))
4490 +#define  CPMAC_TX0_HDP(base)                  (*pCPMAC_TX0_HDP(base))
4491 +#define pCPMAC_TX1_HDP(base)                  ((MEM_PTR)(base+0x604))
4492 +#define  CPMAC_TX1_HDP(base)                  (*pCPMAC_TX1_HDP(base))
4493 +#define pCPMAC_TX2_HDP(base)                  ((MEM_PTR)(base+0x608))
4494 +#define  CPMAC_TX2_HDP(base)                  (*pCPMAC_TX2_HDP(base))
4495 +#define pCPMAC_TX3_HDP(base)                  ((MEM_PTR)(base+0x60C))
4496 +#define  CPMAC_TX3_HDP(base)                  (*pCPMAC_TX3_HDP(base))
4497 +#define pCPMAC_TX4_HDP(base)                  ((MEM_PTR)(base+0x610))
4498 +#define  CPMAC_TX4_HDP(base)                  (*pCPMAC_TX4_HDP(base))
4499 +#define pCPMAC_TX5_HDP(base)                  ((MEM_PTR)(base+0x614))
4500 +#define  CPMAC_TX5_HDP(base)                  (*pCPMAC_TX5_HDP(base))
4501 +#define pCPMAC_TX6_HDP(base)                  ((MEM_PTR)(base+0x618))
4502 +#define  CPMAC_TX6_HDP(base)                  (*pCPMAC_TX6_HDP(base))
4503 +#define pCPMAC_TX7_HDP(base)                  ((MEM_PTR)(base+0x61C))
4504 +#define  CPMAC_TX7_HDP(base)                  (*pCPMAC_TX7_HDP(base))
4505 +#define  CPMAC_RX_HDP(base,ch)                (*(MEM_PTR)(base+0x620+(4*ch)))
4506 +#define pCPMAC_RX0_HDP(base)                  ((MEM_PTR)(base+0x620))
4507 +#define  CPMAC_RX0_HDP(base)                  (*pCPMAC_RX0_HDP(base))
4508 +#define pCPMAC_RX1_HDP(base)                  ((MEM_PTR)(base+0x624))
4509 +#define  CPMAC_RX1_HDP(base)                  (*pCPMAC_RX1_HDP(base))
4510 +#define pCPMAC_RX2_HDP(base)                  ((MEM_PTR)(base+0x628))
4511 +#define  CPMAC_RX2_HDP(base)                  (*pCPMAC_RX2_HDP(base))
4512 +#define pCPMAC_RX3_HDP(base)                  ((MEM_PTR)(base+0x62C))
4513 +#define  CPMAC_RX3_HDP(base)                  (*pCPMAC_RX3_HDP(base))
4514 +#define pCPMAC_RX4_HDP(base)                  ((MEM_PTR)(base+0x630))
4515 +#define  CPMAC_RX4_HDP(base)                  (*pCPMAC_RX4_HDP(base))
4516 +#define pCPMAC_RX5_HDP(base)                  ((MEM_PTR)(base+0x634))
4517 +#define  CPMAC_RX5_HDP(base)                  (*pCPMAC_RX5_HDP(base))
4518 +#define pCPMAC_RX6_HDP(base)                  ((MEM_PTR)(base+0x638))
4519 +#define  CPMAC_RX6_HDP(base)                  (*pCPMAC_RX6_HDP(base))
4520 +#define pCPMAC_RX7_HDP(base)                  ((MEM_PTR)(base+0x63C))
4521 +#define  CPMAC_RX7_HDP(base)                  (*pCPMAC_RX7_HDP(base))
4522 +
4523 +
4524 +#define CPMAC_TX_INT_ACK(base,ch)             (*(MEM_PTR)(base+0x640+(4*ch)))
4525 +
4526 +#define pCPMAC_TX0_INT_ACK(base)              ((MEM_PTR)(base+0x640))
4527 +#define  CPMAC_TX0_INT_ACK(base)              (*pCPMAC_TX0_INT_ACK(base))
4528 +#define pCPMAC_TX1_INT_ACK(base)              ((MEM_PTR)(base+0x644))
4529 +#define  CPMAC_TX1_INT_ACK(base)              (*pCPMAC_TX1_INT_ACK(base))
4530 +#define pCPMAC_TX2_INT_ACK(base)              ((MEM_PTR)(base+0x648))
4531 +#define  CPMAC_TX2_INT_ACK(base)              (*pCPMAC_TX2_INT_ACK(base))
4532 +#define pCPMAC_TX3_INT_ACK(base)              ((MEM_PTR)(base+0x64C))
4533 +#define  CPMAC_TX3_INT_ACK(base)              (*pCPMAC_TX3_INT_ACK(base))
4534 +#define pCPMAC_TX4_INT_ACK(base)              ((MEM_PTR)(base+0x650))
4535 +#define  CPMAC_TX4_INT_ACK(base)              (*pCPMAC_TX4_INT_ACK(base))
4536 +#define pCPMAC_TX5_INT_ACK(base)              ((MEM_PTR)(base+0x654))
4537 +#define  CPMAC_TX5_INT_ACK(base)              (*pCPMAC_TX5_INT_ACK(base))
4538 +#define pCPMAC_TX6_INT_ACK(base)              ((MEM_PTR)(base+0x658))
4539 +#define  CPMAC_TX6_INT_ACK(base)              (*pCPMAC_TX6_INT_ACK(base))
4540 +#define pCPMAC_TX7_INT_ACK(base)              ((MEM_PTR)(base+0x65C))
4541 +#define  CPMAC_TX7_INT_ACK(base)              (*pCPMAC_TX7_INT_ACK(base))
4542 +#define CPMAC_RX_INT_ACK(base,ch)             (*(MEM_PTR)(base+0x660+(4*ch)))
4543 +         
4544 +#define pCPMAC_RX0_INT_ACK(base)              ((MEM_PTR)(base+0x660))
4545 +#define  CPMAC_RX0_INT_ACK(base)              (*pCPMAC_RX0_INT_ACK(base))
4546 +#define pCPMAC_RX1_INT_ACK(base)              ((MEM_PTR)(base+0x664))
4547 +#define  CPMAC_RX1_INT_ACK(base)              (*pCPMAC_RX1_INT_ACK(base))
4548 +#define pCPMAC_RX2_INT_ACK(base)              ((MEM_PTR)(base+0x668))
4549 +#define  CPMAC_RX2_INT_ACK(base)              (*pCPMAC_RX2_INT_ACK(base))
4550 +#define pCPMAC_RX3_INT_ACK(base)              ((MEM_PTR)(base+0x66C))
4551 +#define  CPMAC_RX3_INT_ACK(base)              (*pCPMAC_RX3_INT_ACK(base))
4552 +#define pCPMAC_RX4_INT_ACK(base)              ((MEM_PTR)(base+0x670))
4553 +#define  CPMAC_RX4_INT_ACK(base)              (*pCPMAC_RX4_INT_ACK(base))
4554 +#define pCPMAC_RX5_INT_ACK(base)              ((MEM_PTR)(base+0x674))
4555 +#define  CPMAC_RX5_INT_ACK(base)              (*pCPMAC_RX5_INT_ACK(base))
4556 +#define pCPMAC_RX6_INT_ACK(base)              ((MEM_PTR)(base+0x678))
4557 +#define  CPMAC_RX6_INT_ACK(base)              (*pCPMAC_RX6_INT_ACK(base))
4558 +#define pCPMAC_RX7_INT_ACK(base)              ((MEM_PTR)(base+0x67C))
4559 +#define  CPMAC_RX7_INT_ACK(base)              (*pCPMAC_RX7_INT_ACK(base))
4560 +
4561 +/****************************************************************************/
4562 +/*                                                                          */
4563 +/*         R E G I S T E R  B I T  D E F I N I T I O N S                    */
4564 +/*                                                                          */
4565 +/****************************************************************************/
4566 +
4567 +/* TX_CONTROL */
4568 +
4569 +#define TX_EN               (1 << 0)
4570 +
4571 +/* RX_CONTROL */
4572 +
4573 +#define RX_EN               (1 << 0)
4574 +
4575 +/* RX_MBP_ENABLE */
4576 +
4577 +#define RX_PASS_CRC         (1 << 30)
4578 +#define RX_QOS_EN           (1 << 29)
4579 +#define RX_NO_CHAIN         (1 << 28)
4580 +
4581 +#define RX_CMF_EN           (1 << 24)
4582 +#define RX_CSF_EN           (1 << 23)
4583 +#define RX_CEF_EN           (1 << 22)
4584 +#define RX_CAF_EN           (1 << 21)
4585 +
4586 +#define RX_PROM_CH(n)       (n << 16)
4587 +#define RX_PROM_CH_MASK     RX_PROM_CH(7)
4588 +#define RX_PROM_CH_7        RX_PROM_CH(7)
4589 +#define RX_PROM_CH_6        RX_PROM_CH(6)
4590 +#define RX_PROM_CH_5        RX_PROM_CH(5)
4591 +#define RX_PROM_CH_4        RX_PROM_CH(4)
4592 +#define RX_PROM_CH_3        RX_PROM_CH(3)
4593 +#define RX_PROM_CH_2        RX_PROM_CH(2)
4594 +#define RX_PROM_CH_1        RX_PROM_CH(1)
4595 +#define RX_PROM_CH_0        RX_PROM_CH(0)
4596 +
4597 +#define RX_BROAD_EN         (1 << 13)
4598 +
4599 +#define RX_BROAD_CH(n)       (n <<  8)
4600 +#define RX_BROAD_CH_MASK     RX_BROAD_CH(7)
4601 +#define RX_BROAD_CH_7        RX_BROAD_CH(7)
4602 +#define RX_BROAD_CH_6        RX_BROAD_CH(6)
4603 +#define RX_BROAD_CH_5        RX_BROAD_CH(5)
4604 +#define RX_BROAD_CH_4        RX_BROAD_CH(4)
4605 +#define RX_BROAD_CH_3        RX_BROAD_CH(3)
4606 +#define RX_BROAD_CH_2        RX_BROAD_CH(2)
4607 +#define RX_BROAD_CH_1        RX_BROAD_CH(1)
4608 +#define RX_BROAD_CH_0        RX_BROAD_CH(0)
4609 +
4610 +#define RX_MULT_EN          (1 <<  5)
4611 +
4612 +#define RX_MULT_CH(n)       (n << 0)
4613 +#define RX_MULT_CH_MASK     RX_MULT_CH(7)
4614 +#define RX_MULT_CH_7        RX_MULT_CH(7)
4615 +#define RX_MULT_CH_6        RX_MULT_CH(6)
4616 +#define RX_MULT_CH_5        RX_MULT_CH(5)
4617 +#define RX_MULT_CH_4        RX_MULT_CH(4)
4618 +#define RX_MULT_CH_3        RX_MULT_CH(3)
4619 +#define RX_MULT_CH_2        RX_MULT_CH(2)
4620 +#define RX_MULT_CH_1        RX_MULT_CH(1)
4621 +#define RX_MULT_CH_0        RX_MULT_CH(0)
4622 +
4623 +
4624 +
4625 +/* RX_UNICAST_SET */
4626 +
4627 +#define RX_CH7_EN        (1 <<  7)
4628 +#define RX_CH6_EN        (1 <<  6)
4629 +#define RX_CH5_EN        (1 <<  5)
4630 +#define RX_CH4_EN        (1 <<  4)
4631 +#define RX_CH3_EN        (1 <<  3)
4632 +#define RX_CH2_EN        (1 <<  2)
4633 +#define RX_CH1_EN        (1 <<  1)
4634 +#define RX_CH0_EN        (1 <<  0)
4635 +
4636 +
4637 +
4638 +/*  MAC control */
4639 +#define TX_PTYPE         (1 << 9)
4640 +#define TX_PACE          (1 << 6)
4641 +#define MII_EN           (1 << 5)
4642 +#define TX_FLOW_EN       (1 << 4)
4643 +#define RX_FLOW_EN       (1 << 3)
4644 +#define MTEST            (1 << 2)
4645 +#define CTRL_LOOPBACK    (1 << 1)
4646 +#define FULLDUPLEX       (1 << 0)
4647 +
4648 +
4649 +/* IntVec definitions  */
4650 +#define MAC_IN_VECTOR_STATUS_INT   (1 << 19)
4651 +#define MAC_IN_VECTOR_HOST_INT     (1 << 18)
4652 +#define MAC_IN_VECTOR_RX_INT_OR    (1 << 17)
4653 +#define MAC_IN_VECTOR_TX_INT_OR    (1 << 16)
4654 +#define MAC_IN_VECTOR_RX_INT_VEC   (7 << 8)
4655 +#define MAC_IN_VECTOR_TX_INT_VEC   (7)  
4656 +
4657 +
4658 +/*  MacStatus */
4659 +
4660 +#define TX_HOST_ERR_CODE         (0xF << 20)
4661 +#define TX_ERR_CH                (0x7 << 16)
4662 +#define RX_HOST_ERR_CODE         (0xF << 12)
4663 +#define RX_ERR_CH                (0x7 <<  8)
4664 +#define RX_QOS_ACT               (1 << 2)
4665 +#define RX_FLOW_ACT              (1 << 1)
4666 +#define TX_FLOW_ACT              (1 << 0)
4667 +#endif _INC_CPMAC_REG
4668 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmdio.c linux.dev/drivers/net/avalanche_cpmac/cpmdio.c
4669 --- linux.old/drivers/net/avalanche_cpmac/cpmdio.c      1970-01-01 01:00:00.000000000 +0100
4670 +++ linux.dev/drivers/net/avalanche_cpmac/cpmdio.c      2005-07-12 02:48:42.046593000 +0200
4671 @@ -0,0 +1,960 @@
4672 +/***************************************************************************
4673 +**  TNETD53xx Software Support
4674 +**  Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved.
4675 +**
4676 +**  FILE: cpmdio.c
4677 +**
4678 +**  DESCRIPTION:
4679 +**   MDIO Polling State Machine API. Functions will enable mii-Phy
4680 +**   negotiation.
4681 +**
4682 +**  HISTORY:
4683 +**    01Jan01 Denis, Bill      Original
4684 +**      27Mar02 Michael Hanrahan (modified from emacmdio.c)
4685 +**      07May02 Michael Hanrahan replaced clockwait for code delay
4686 +**      10Jul02 Michael Hanrahan more debug, if fallback link is selected
4687 +*****************************************************************************/
4688 +#define __CPHAL_CPMDIO
4689 +
4690 +#include "mdio_reg.h"
4691 +
4692 +#ifdef _CPHAL_CPMAC
4693 +#define mdioPrintf PhyDev->HalDev->OsFunc->Printf
4694 +#else
4695 +#define mdioPrintf printf
4696 +#endif
4697 +
4698 +typedef struct _phy_device
4699 +{
4700 +   bit32u miibase;
4701 +   bit32u inst;
4702 +   bit32u PhyState;
4703 +   bit32u MdixMask;
4704 +   bit32u PhyMask;
4705 +   bit32u MLinkMask;
4706 +   bit32u PhyMode;
4707 +#ifdef _CPHAL_CPMAC
4708 +   HAL_DEVICE *HalDev;
4709 +#endif
4710 +} _PHY_DEVICE;
4711 +
4712 +static void   _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait);
4713 +static void   _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev);
4714 +static void   _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data);
4715 +static bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr);
4716 +static void   _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data);
4717 +
4718 +static void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum);
4719 +static void _mdioPhyTimeOut(PHY_DEVICE *PhyDev);
4720 +static void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum);
4721 +
4722 +static void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p);
4723 +static void _mdioDumpState(PHY_DEVICE *PhyDev);
4724 +
4725 +/* Auto Mdix */
4726 +static void _mdioMdixDelay(PHY_DEVICE *PhyDev);
4727 +static int  _mdioMdixSupported(PHY_DEVICE *PhyDev);
4728 +
4729 +static void _MdioDefaultState  (PHY_DEVICE *PhyDev);
4730 +static void _MdioFindingState  (PHY_DEVICE *PhyDev);
4731 +static void _MdioFoundState    (PHY_DEVICE *PhyDev);
4732 +static void _MdioInitState     (PHY_DEVICE *PhyDev);
4733 +static void _MdioLinkedState   (PHY_DEVICE *PhyDev);
4734 +static void _MdioLinkWaitState (PHY_DEVICE *PhyDev);
4735 +static void _MdioLoopbackState (PHY_DEVICE *PhyDev);
4736 +static void _MdioNwayStartState(PHY_DEVICE *PhyDev);
4737 +static void _MdioNwayWaitState (PHY_DEVICE *PhyDev);
4738 +
4739 +
4740 +
4741 +#ifndef TRUE
4742 +#define TRUE (1==1)
4743 +#endif
4744 +
4745 +#ifndef FALSE
4746 +#define FALSE (1==2)
4747 +#endif
4748 +
4749 +#define PHY_NOT_FOUND  0xFFFF    /*  Used in Phy Detection */
4750 +
4751 +/*PhyState breakout                                                          */
4752 +
4753 +#define PHY_DEV_OFFSET      (0)
4754 +#define PHY_DEV_SIZE        (5)        /*  5 Bits used */
4755 +#define PHY_DEV_MASK        (0x1f<<PHY_DEV_OFFSET)
4756 +
4757 +#define PHY_STATE_OFFSET    (PHY_DEV_SIZE+PHY_DEV_OFFSET)
4758 +#define PHY_STATE_SIZE      (5)        /* 10 Bits used */
4759 +#define PHY_STATE_MASK      (0x1f<<PHY_STATE_OFFSET)
4760 +  #define INIT       (1<<PHY_STATE_OFFSET)
4761 +  #define FINDING    (2<<PHY_STATE_OFFSET)
4762 +  #define FOUND      (3<<PHY_STATE_OFFSET)
4763 +  #define NWAY_START (4<<PHY_STATE_OFFSET)
4764 +  #define NWAY_WAIT  (5<<PHY_STATE_OFFSET)
4765 +  #define LINK_WAIT  (6<<PHY_STATE_OFFSET)
4766 +  #define LINKED     (7<<PHY_STATE_OFFSET)
4767 +  #define LOOPBACK   (8<<PHY_STATE_OFFSET)
4768 +
4769 +#define PHY_SPEED_OFFSET    (PHY_STATE_OFFSET+PHY_STATE_SIZE)
4770 +#define PHY_SPEED_SIZE      (1)     /* 11 Bits used */
4771 +#define PHY_SPEED_MASK      (1<<PHY_SPEED_OFFSET)
4772 +
4773 +#define PHY_DUPLEX_OFFSET   (PHY_SPEED_OFFSET+PHY_SPEED_SIZE)
4774 +#define PHY_DUPLEX_SIZE     (1)     /* 12 Bits used */
4775 +#define PHY_DUPLEX_MASK     (1<<PHY_DUPLEX_OFFSET)
4776 +
4777 +#define PHY_TIM_OFFSET      (PHY_DUPLEX_OFFSET+PHY_DUPLEX_SIZE)
4778 +#define PHY_TIM_SIZE        (10)    /* 22 Bits used */
4779 +#define PHY_TIM_MASK        (0x3ff<<PHY_TIM_OFFSET)
4780 +  #define PHY_FIND_TO (  2<<PHY_TIM_OFFSET)
4781 +  #define PHY_RECK_TO (200<<PHY_TIM_OFFSET)
4782 +  #define PHY_LINK_TO (500<<PHY_TIM_OFFSET)
4783 +  #define PHY_NWST_TO (500<<PHY_TIM_OFFSET)
4784 +  #define PHY_NWDN_TO (800<<PHY_TIM_OFFSET)
4785 +  #define PHY_MDIX_TO (274<<PHY_TIM_OFFSET) /* 2.74 Seconds <--Spec and empirical */
4786 +
4787 +#define PHY_SMODE_OFFSET    (PHY_TIM_OFFSET+PHY_TIM_SIZE)
4788 +#define PHY_SMODE_SIZE      (5)     /* 27 Bits used */
4789 +#define PHY_SMODE_MASK      (0x1f<<PHY_SMODE_OFFSET)
4790 +  #define SMODE_AUTO   (0x10<<PHY_SMODE_OFFSET)
4791 +  #define SMODE_FD100  (0x08<<PHY_SMODE_OFFSET)
4792 +  #define SMODE_HD100  (0x04<<PHY_SMODE_OFFSET)
4793 +  #define SMODE_FD10   (0x02<<PHY_SMODE_OFFSET)
4794 +  #define SMODE_HD10   (0x01<<PHY_SMODE_OFFSET)
4795 +  #define SMODE_ALL    (0x1f<<PHY_SMODE_OFFSET)
4796 +
4797 +#define PHY_CHNG_OFFSET    (PHY_SMODE_OFFSET+PHY_SMODE_SIZE)
4798 +#define PHY_CHNG_SIZE      (1)     /* 28 Bits used */
4799 +#define PHY_CHNG_MASK      (1<<PHY_CHNG_OFFSET)
4800 +  #define PHY_CHANGE (1<<PHY_CHNG_OFFSET)
4801 +
4802 +#define PHY_TIMEDOUT_OFFSET    (PHY_CHNG_OFFSET+PHY_CHNG_SIZE)
4803 +#define PHY_TIMEDOUT_SIZE      (1)     /*  29 Bits used */
4804 +#define PHY_TIMEDOUT_MASK      (1<<PHY_TIMEDOUT_OFFSET)
4805 +  #define PHY_MDIX_SWITCH  (1<<PHY_TIMEDOUT_OFFSET)
4806 +
4807 +#define PHY_MDIX_OFFSET    (PHY_TIMEDOUT_OFFSET+PHY_TIMEDOUT_SIZE)
4808 +#define PHY_MDIX_SIZE      (1)     /*  30 Bits used */
4809 +#define PHY_MDIX_MASK      (1<<PHY_MDIX_OFFSET)
4810 +  #define PHY_MDIX     (1<<PHY_MDIX_OFFSET)
4811 +
4812 +static char *lstate[]={"NULL","INIT","FINDING","FOUND","NWAY_START","NWAY_WAIT","LINK_WAIT","LINKED", "LOOPBACK"};
4813 +static int cpMacDebug;
4814 +
4815 +/*  Local MDIO Register Macros    */
4816 +
4817 +#define myMDIO_ALIVE           MDIO_ALIVE     (PhyDev->miibase)
4818 +#define myMDIO_CONTROL         MDIO_CONTROL   (PhyDev->miibase)
4819 +#define myMDIO_LINK            MDIO_LINK      (PhyDev->miibase)
4820 +#define myMDIO_LINKINT         MDIO_LINKINT   (PhyDev->miibase)
4821 +#define myMDIO_USERACCESS      MDIO_USERACCESS(PhyDev->miibase, PhyDev->inst)
4822 +#define myMDIO_USERPHYSEL      MDIO_USERPHYSEL(PhyDev->miibase, PhyDev->inst)
4823 +#define myMDIO_VER             MDIO_VER       (PhyDev->miibase)
4824 +
4825 +#ifndef VOLATILE32
4826 +#define VOLATILE32(addr) (*((volatile bit32u *)(addr)))
4827 +#endif
4828 +
4829 +/************************************
4830 +***
4831 +*** Delays at least ClockWait cylces
4832 +*** before returning
4833 +***
4834 +**************************************/
4835 +void _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait)
4836 +  {
4837 +#ifdef _CPHAL_CPMAC                                                  /*+RC3.02*/
4838 +  HAL_DEVICE *HalDev = PhyDev->HalDev;                               /*+RC3.02*/
4839 +  osfuncSleep((int*)&ClockWait);                                     /*+RC3.02*/
4840 +#else                                                                /*+RC3.02*/
4841 +  volatile bit32u i=0;
4842 +  while(ClockWait--)
4843 +    {
4844 +    i |= myMDIO_LINK; /*  MDIO register access to burn cycles */
4845 +    }
4846 +#endif
4847 +  }
4848 +
4849 +void _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev)
4850 +  {
4851 +  while((myMDIO_USERACCESS & MDIO_USERACCESS_GO)!=0)
4852 +    {
4853 +    }
4854 +  }
4855 +
4856 +void _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data)
4857 +  {
4858 +  bit32u  control;
4859 +
4860 +  control =  MDIO_USERACCESS_GO |
4861 +             (method) |
4862 +             (((regadr) << 21) & MDIO_USERACCESS_REGADR) |
4863 +             (((phyadr) << 16) & MDIO_USERACCESS_PHYADR) |
4864 +             ((data) & MDIO_USERACCESS_DATA);
4865 +
4866 +  myMDIO_USERACCESS = control;
4867 +  }
4868 +
4869 +
4870 +
4871 +/************************************
4872 +***
4873 +*** Waits for MDIO_USERACCESS to be ready and reads data
4874 +*** If 'WaitForData' set, waits for read to complete and returns Data,
4875 +*** otherwise returns 0
4876 +*** Note: 'data' is 16 bits but we use 32 bits
4877 +***        to be consistent with rest of the code.
4878 +***
4879 +**************************************/
4880 +bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr)
4881 +  {
4882 +
4883 +  _mdioWaitForAccessComplete(PhyDev);  /* Wait until UserAccess ready */
4884 +  _mdioUserAccess(PhyDev, MDIO_USERACCESS_READ, regadr, phyadr, 0);
4885 +  _mdioWaitForAccessComplete(PhyDev);  /* Wait for Read to complete */
4886 +
4887 +  return(myMDIO_USERACCESS & MDIO_USERACCESS_DATA);
4888 +  }
4889 +
4890 +
4891 +/************************************
4892 +***
4893 +*** Waits for MDIO_USERACCESS to be ready and writes data
4894 +***
4895 +**************************************/
4896 +void _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data)
4897 +  {
4898 +  _mdioWaitForAccessComplete(PhyDev);  /* Wait until UserAccess ready */
4899 +  _mdioUserAccess(PhyDev, MDIO_USERACCESS_WRITE, regadr, phyadr, data);
4900 +  }
4901 +
4902 +void _mdioDumpPhyDetailed(PHY_DEVICE *PhyDev)
4903 +{
4904 +  bit32u *PhyState = &PhyDev->PhyState;
4905 +  bit32u  PhyNum;
4906 +  int     RegData;
4907 +
4908 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
4909 +
4910 +  RegData = _mdioUserAccessRead(PhyDev, 0, PhyNum);
4911 +  mdioPrintf("PhyControl: %04X, Lookback=%s, Speed=%s, Duplex=%s\n",
4912 +    RegData,
4913 +    RegData&PHY_LOOP?"On":"Off",
4914 +    RegData&PHY_100?"100":"10",
4915 +    RegData&PHY_FD?"Full":"Half");
4916 +  RegData = _mdioUserAccessRead(PhyDev, 1, PhyNum);
4917 +  mdioPrintf("PhyStatus: %04X, AutoNeg=%s, Link=%s\n",
4918 +    RegData,
4919 +    RegData&NWAY_COMPLETE?"Complete":"NotComplete",
4920 +    RegData&PHY_LINKED?"Up":"Down");
4921 +  RegData = _mdioUserAccessRead(PhyDev, 4, PhyNum);
4922 +  mdioPrintf("PhyMyCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n",
4923 +    RegData,
4924 +    RegData&NWAY_FD100?"Yes":"No",
4925 +    RegData&NWAY_HD100?"Yes":"No",
4926 +    RegData&NWAY_FD10?"Yes":"No",
4927 +    RegData&NWAY_HD10?"Yes":"No");
4928 +
4929 +  RegData = _mdioUserAccessRead(PhyDev, 5, PhyNum);
4930 +  mdioPrintf("PhyPartnerCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n",
4931 +    RegData,
4932 +    RegData&NWAY_FD100?"Yes":"No",
4933 +    RegData&NWAY_HD100?"Yes":"No",
4934 +    RegData&NWAY_FD10?"Yes":"No",
4935 +    RegData&NWAY_HD10?"Yes":"No");
4936 +}
4937 +void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p)
4938 +  {
4939 +  bit32u j,n,PhyAcks;
4940 +  bit32u PhyRegAddr;
4941 +  bit32u phy_num;
4942 +  bit32u PhyMask  = PhyDev->PhyMask;
4943 +
4944 +  PhyAcks=myMDIO_ALIVE;
4945 +  PhyAcks&=PhyMask;   /* Only interested in 'our' Phys */
4946 +
4947 +  for(phy_num=0,j=1;phy_num<32;phy_num++,j<<=1)
4948 +    {
4949 +    if (PhyAcks&j)
4950 +      {
4951 +      mdioPrintf("%2d%s:",phy_num,(phy_num==p)?">":" ");
4952 +      for(PhyRegAddr=0;PhyRegAddr<6;PhyRegAddr++)
4953 +        {
4954 +        n = _mdioUserAccessRead(PhyDev, PhyRegAddr, phy_num);
4955 +        mdioPrintf(" %04x",n&0x0ffff);
4956 +        }
4957 +      mdioPrintf("\n");
4958 +      }
4959 +    }
4960 +  _mdioDumpPhyDetailed(PhyDev);
4961 +  }
4962 +
4963 +void _mdioDumpState(PHY_DEVICE *PhyDev)
4964 +  {
4965 +  bit32u state    = PhyDev->PhyState;
4966 +
4967 +  if (!cpMacDebug) return;
4968 +
4969 +  mdioPrintf("Phy: %d, ",(state&PHY_DEV_MASK)>>PHY_DEV_OFFSET);
4970 +  mdioPrintf("State: %d/%s, ",(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET,lstate[(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET]);
4971 +  mdioPrintf("Speed: %d, ",(state&PHY_SPEED_MASK)>>PHY_SPEED_OFFSET);
4972 +  mdioPrintf("Dup: %d, ",(state&PHY_DUPLEX_MASK)>>PHY_DUPLEX_OFFSET);
4973 +  mdioPrintf("Tim: %d, ",(state&PHY_TIM_MASK)>>PHY_TIM_OFFSET);
4974 +  mdioPrintf("SMode: %d, ",(state&PHY_SMODE_MASK)>>PHY_SMODE_OFFSET);
4975 +  mdioPrintf("Chng: %d",(state&PHY_CHNG_MASK)>>PHY_CHNG_OFFSET);
4976 +  mdioPrintf("\n");
4977 +
4978 +  if (((state&PHY_STATE_MASK)!=FINDING)&&((state&PHY_STATE_MASK)!=INIT))
4979 +    _mdioDumpPhy(PhyDev, (state&PHY_DEV_MASK)>>PHY_DEV_OFFSET);
4980 +  }
4981 +
4982 +
4983 +void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum)
4984 +  {
4985 +  bit16u PhyControlReg;
4986 +
4987 +  _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_RESET);
4988 +  if (cpMacDebug)
4989 +    mdioPrintf("cpMacMdioPhYReset(%d)\n",PhyNum);
4990 +
4991 +  /* Read control register until Phy Reset is complete */
4992 +  do
4993 +   {
4994 +    PhyControlReg = _mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum);
4995 +   }
4996 +   while (PhyControlReg & PHY_RESET); /* Wait for Reset to clear */
4997 +  }
4998 +
4999 +void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum)
5000 +  {
5001 +  _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_ISOLATE|PHY_PDOWN);
5002 +
5003 +  if (cpMacDebug)
5004 +    mdioPrintf("cpMacMdioDisablePhy(%d)\n",PhyNum);
5005 +
5006 +  }
5007 +
5008 +void _MdioInitState(PHY_DEVICE *PhyDev)
5009 +  {
5010 +  bit32u *PhyState = &PhyDev->PhyState;
5011 +  bit32u CurrentState;
5012 +
5013 +  CurrentState=*PhyState;
5014 +  CurrentState=(CurrentState&~PHY_TIM_MASK)|(PHY_FIND_TO);
5015 +  CurrentState=(CurrentState&~PHY_STATE_MASK)|(FINDING);
5016 +  CurrentState=(CurrentState&~PHY_SPEED_MASK);
5017 +  CurrentState=(CurrentState&~PHY_DUPLEX_MASK);
5018 +  CurrentState|=PHY_CHANGE;
5019 +
5020 +  *PhyState=CurrentState;
5021 +
5022 +  }
5023 +
5024 +void _MdioFindingState(PHY_DEVICE *PhyDev)
5025 +  {
5026 +  bit32u *PhyState = &PhyDev->PhyState;
5027 +  bit32u  PhyMask  = PhyDev->PhyMask;
5028 +  bit32u  PhyNum,i,j,PhyAcks;
5029 +
5030 +
5031 +  PhyNum=PHY_NOT_FOUND;
5032 +
5033 +  if (*PhyState&PHY_TIM_MASK)
5034 +    {
5035 +    *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
5036 +    }
5037 +   else
5038 +    {
5039 +    PhyAcks=myMDIO_ALIVE;
5040 +    PhyAcks&=PhyMask;   /* Only interested in 'our' Phys */
5041 +
5042 +    for(i=0,j=1;(i<32)&&((j&PhyAcks)==0);i++,j<<=1);
5043 +
5044 +    if ((PhyAcks)&&(i<32)) PhyNum=i;
5045 +    if (PhyNum!=PHY_NOT_FOUND)
5046 +      {
5047 +      /*  Phy Found! */
5048 +      *PhyState=(*PhyState&~PHY_DEV_MASK)|((PhyNum&PHY_DEV_MASK)<<PHY_DEV_OFFSET);
5049 +      *PhyState=(*PhyState&~PHY_STATE_MASK)|(FOUND);
5050 +      *PhyState|=PHY_CHANGE;
5051 +      if (cpMacDebug)
5052 +        mdioPrintf("cpMacMdioFindingState: PhyNum: %d\n",PhyNum);
5053 +      }
5054 +     else
5055 +      {
5056 +      if (cpMacDebug)
5057 +        mdioPrintf("cpMacMdioFindingState: Timed Out looking for a Phy!\n");
5058 +      *PhyState|=PHY_RECK_TO;  /* This state currently has no support?*/
5059 +      }
5060 +    }
5061 +  }
5062 +
5063 +void _MdioFoundState(PHY_DEVICE *PhyDev)
5064 +  {
5065 +  bit32u *PhyState  = &PhyDev->PhyState;
5066 +  bit32u  PhyMask   = PhyDev->PhyMask;
5067 +  bit32u  MLinkMask = PhyDev->MLinkMask;
5068 +  bit32u  PhyNum,PhyStatus,NWAYadvertise,m,phynum,i,j,PhyAcks;
5069 +  bit32u  PhySel;
5070 +
5071 +  if ((*PhyState&PHY_SMODE_MASK)==0) return;
5072 +
5073 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5074 +
5075 +  PhyAcks=myMDIO_ALIVE;
5076 +  PhyAcks&=PhyMask;   /* Only interested in 'our' Phys */
5077 +
5078 +  /* Will now isolate all our Phys, except the one we have decided to use */
5079 +  for(phynum=0,j=1;phynum<32;phynum++,j<<=1)
5080 +    {
5081 +    if (PhyAcks&j)
5082 +      {
5083 +        if (phynum!=PhyNum)  /* Do not disabled Found Phy */
5084 +          _mdioDisablePhy(PhyDev,phynum);
5085 +      }
5086 +    }
5087 +
5088 +  /*  Reset the Phy and proceed with auto-negotiation */
5089 +  _mdioResetPhy(PhyDev,PhyNum);
5090 +
5091 +  /* Now setup the MDIOUserPhySel register */
5092 +
5093 +  PhySel=PhyNum;  /* Set the phy address */
5094 +
5095 +  /*  Set the way Link will be Monitored */
5096 +  /* Check the Link Selection Method */
5097 +  if ((1 << PhyNum) & MLinkMask)
5098 +    PhySel |= MDIO_USERPHYSEL_LINKSEL;
5099 +
5100 +  myMDIO_USERPHYSEL = PhySel;  /* update PHYSEL */
5101 +
5102 +  /* Get the Phy Status */
5103 +  PhyStatus = _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum);
5104 +
5105 +
5106 +#ifdef _CPHAL_CPMAC
5107 +  /*  For Phy Internal loopback test, need to wait until Phy
5108 +      found, then set Loopback */
5109 +  if (PhyDev->HalDev->MdioConnect & _CPMDIO_LOOPBK)
5110 +    {
5111 +    /* Set Phy in Loopback */
5112 +    _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_LOOP|PHY_FD);
5113 +    /* Do a read to ensure PHY_LOOP has completed */
5114 +    _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum);
5115 +    *PhyState=(*PhyState&~PHY_STATE_MASK)|(LOOPBACK);
5116 +    *PhyState|=PHY_CHANGE;
5117 +    return;
5118 +    }
5119 +#endif
5120 +
5121 +
5122 +  if (cpMacDebug)
5123 +    mdioPrintf("Enable Phy to negotiate external connection\n");
5124 +
5125 +  NWAYadvertise=NWAY_SEL;
5126 +  if (*PhyState&SMODE_FD100) NWAYadvertise|=NWAY_FD100;
5127 +  if (*PhyState&SMODE_HD100) NWAYadvertise|=NWAY_HD100;
5128 +  if (*PhyState&SMODE_FD10)  NWAYadvertise|=NWAY_FD10;
5129 +  if (*PhyState&SMODE_HD10)  NWAYadvertise|=NWAY_HD10;
5130 +
5131 +  *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK);
5132 +  if ((PhyStatus&NWAY_CAPABLE)&&(*PhyState&SMODE_AUTO))   /*NWAY Phy Detected*/
5133 +    {
5134 +    /*For NWAY compliant Phys                                                */
5135 +
5136 +    _mdioUserAccessWrite(PhyDev, NWAY_ADVERTIZE_REG, PhyNum, NWAYadvertise);
5137 +
5138 +    if (cpMacDebug)
5139 +      {
5140 +      mdioPrintf("NWAY Advertising: ");
5141 +      if (NWAYadvertise&NWAY_FD100) mdioPrintf("FullDuplex-100 ");
5142 +      if (NWAYadvertise&NWAY_HD100) mdioPrintf("HalfDuplex-100 ");
5143 +      if (NWAYadvertise&NWAY_FD10)  mdioPrintf("FullDuplex-10 ");
5144 +      if (NWAYadvertise&NWAY_HD10)  mdioPrintf("HalfDuplex-10 ");
5145 +      mdioPrintf("\n");
5146 +      }
5147 +
5148 +    _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN);
5149 +
5150 +    _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE);
5151 +
5152 +    *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START;
5153 +    }
5154 +   else
5155 +    {
5156 +    *PhyState&=~SMODE_AUTO;   /*The Phy is not capable of auto negotiation!  */
5157 +    m=NWAYadvertise;
5158 +    for(j=0x8000,i=0;(i<16)&&((j&m)==0);i++,j>>=1);
5159 +    m=j;
5160 +    j=0;
5161 +    if (m&(NWAY_FD100|NWAY_HD100))
5162 +      {
5163 +      j=PHY_100;
5164 +      m&=(NWAY_FD100|NWAY_HD100);
5165 +      }
5166 +    if (m&(NWAY_FD100|NWAY_FD10))
5167 +      j |= PHY_FD;
5168 +    if (cpMacDebug)
5169 +      mdioPrintf("Requested PHY mode %s Duplex %s Mbps\n",(j&PHY_FD)?"Full":"Half",(j&PHY_100)?"100":"10");
5170 +    _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, j);
5171 +    *PhyState&=~PHY_SPEED_MASK;
5172 +    if (j&PHY_100)
5173 +      *PhyState|=(1<<PHY_SPEED_OFFSET);
5174 +    *PhyState&=~PHY_DUPLEX_MASK;
5175 +    if (j&PHY_FD)
5176 +      *PhyState|=(1<<PHY_DUPLEX_OFFSET);
5177 +    *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT;
5178 +    }
5179 +     _mdioMdixDelay(PhyDev);  /* If AutoMdix add delay */
5180 +  }
5181 +
5182 +void _MdioNwayStartState(PHY_DEVICE *PhyDev)
5183 +  {
5184 +  bit32u *PhyState = &PhyDev->PhyState;
5185 +  bit32u PhyNum,PhyMode;
5186 +
5187 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5188 +
5189 +  /*Wait for Negotiation to start                                            */
5190 +
5191 +  PhyMode=_mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum);
5192 +
5193 +  if((PhyMode&RENEGOTIATE)==0)
5194 +    {
5195 +    _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); /*Flush pending latch bits*/
5196 +    *PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK);
5197 +    *PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO;
5198 +    _mdioMdixDelay(PhyDev);  /* If AutoMdix add delay */
5199 +    }
5200 +   else
5201 +    {
5202 +    if (*PhyState&PHY_TIM_MASK)
5203 +      *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
5204 +     else
5205 +      _mdioPhyTimeOut(PhyDev);
5206 +    }
5207 +  }
5208 +
5209 +void _MdioNwayWaitState(PHY_DEVICE *PhyDev)
5210 +  {
5211 +  bit32u *PhyState = &PhyDev->PhyState;
5212 +  bit32u  PhyNum,PhyStatus,NWAYadvertise,NWAYREadvertise,NegMode,i,j;
5213 +
5214 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5215 +
5216 +  PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum);
5217 +
5218 +  if (PhyStatus&NWAY_COMPLETE)
5219 +    {
5220 +    *PhyState|=PHY_CHANGE;
5221 +    *PhyState&=~PHY_SPEED_MASK;
5222 +    *PhyState&=~PHY_DUPLEX_MASK;
5223 +
5224 +    NWAYadvertise   =_mdioUserAccessRead(PhyDev, NWAY_ADVERTIZE_REG, PhyNum);
5225 +    NWAYREadvertise =_mdioUserAccessRead(PhyDev, NWAY_REMADVERTISE_REG, PhyNum);
5226 +
5227 +    /* Negotiated mode is we and the remote have in common */
5228 +    NegMode = NWAYadvertise & NWAYREadvertise;
5229 +
5230 +    if (cpMacDebug)
5231 +      {
5232 +       mdioPrintf("Phy: %d, ",(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET);
5233 +       mdioPrintf("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n",
5234 +         NegMode,  NWAYadvertise, NWAYREadvertise);
5235 +      }
5236 +
5237 +    /* Limit negotiation to fields below */
5238 +    NegMode &= (NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10);
5239 +
5240 +    if (NegMode==0)
5241 +      {
5242 +      NegMode=(NWAY_HD100|NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/
5243 +      if(cpMacDebug)
5244 +        {
5245 +         mdioPrintf("Mdio:WARNING: Negotiation complete but NO agreement, default is HD\n");
5246 +         _mdioDumpPhyDetailed(PhyDev);
5247 +        } 
5248 +      }
5249 +    for(j=0x8000,i=0;(i<16)&&((j&NegMode)==0);i++,j>>=1);
5250 +
5251 +
5252 +    NegMode=j;
5253 +    if (cpMacDebug)
5254 +      {
5255 +      mdioPrintf("Negotiated connection: ");
5256 +      if (NegMode&NWAY_FD100) mdioPrintf("FullDuplex 100 Mbs\n");
5257 +      if (NegMode&NWAY_HD100) mdioPrintf("HalfDuplex 100 Mbs\n");
5258 +      if (NegMode&NWAY_FD10) mdioPrintf("FullDuplex 10 Mbs\n");
5259 +      if (NegMode&NWAY_HD10) mdioPrintf("HalfDuplex 10 Mbs\n");
5260 +      }
5261 +    if (NegMode!=0)
5262 +      {
5263 +      if (PhyStatus&PHY_LINKED)
5264 +        *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED;
5265 +       else
5266 +        *PhyState=(*PhyState&~PHY_STATE_MASK)|LINK_WAIT;
5267 +      if (NegMode&(NWAY_FD100|NWAY_HD100))
5268 +        *PhyState=(*PhyState&~PHY_SPEED_MASK)|(1<<PHY_SPEED_OFFSET);
5269 +      if (NegMode&(NWAY_FD100|NWAY_FD10))
5270 +        *PhyState=(*PhyState&~PHY_DUPLEX_MASK)|(1<<PHY_DUPLEX_OFFSET);
5271 +      }
5272 +    }
5273 +   else
5274 +    {
5275 +    if (*PhyState&PHY_TIM_MASK)
5276 +      *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
5277 +     else
5278 +      _mdioPhyTimeOut(PhyDev);
5279 +    }
5280 +  }
5281 +
5282 +void _MdioLinkWaitState(PHY_DEVICE *PhyDev)
5283 +  {
5284 +  bit32u *PhyState = &PhyDev->PhyState;
5285 +  bit32u  PhyStatus;
5286 +  bit32u  PhyNum;
5287 +
5288 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5289 +
5290 +  PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum);
5291 +
5292 +  if (PhyStatus&PHY_LINKED)
5293 +    {
5294 +    *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED;
5295 +    *PhyState|=PHY_CHANGE;
5296 +    }
5297 +   else
5298 +    {
5299 +    if (*PhyState&PHY_TIM_MASK)
5300 +      *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET));
5301 +     else
5302 +      _mdioPhyTimeOut(PhyDev);
5303 +    }
5304 +  }
5305 +
5306 +void _mdioPhyTimeOut(PHY_DEVICE *PhyDev)
5307 +  {
5308 +  bit32u *PhyState;
5309 +
5310 +  if(_mdioMdixSupported(PhyDev) == 0)
5311 +    return;  /* AutoMdix not supported */
5312 +
5313 +  PhyState = &PhyDev->PhyState;
5314 +
5315 +  /*  Indicate MDI/MDIX mode switch is needed */
5316 +  *PhyState|=PHY_MDIX_SWITCH;
5317 +
5318 +  /* Toggle the MDIX mode indicatir */
5319 +  if(*PhyState & PHY_MDIX)
5320 +    *PhyState &= ~PHY_MDIX_MASK;       /* Current State is MDIX, set to MDI */
5321 +  else
5322 +    *PhyState |=  PHY_MDIX_MASK;      /* Current State is MDI, set to MDIX */
5323 +
5324 +  /* Reset state machine to FOUND */
5325 +  *PhyState=(*PhyState&~PHY_STATE_MASK)|(FOUND);
5326 +  }
5327 +
5328 +void _MdioLoopbackState(PHY_DEVICE *PhyDev)
5329 +  {
5330 +  return;
5331 +  }
5332 +
5333 +void _MdioLinkedState(PHY_DEVICE *PhyDev)
5334 +  {
5335 +  bit32u *PhyState = &PhyDev->PhyState;
5336 +  bit32u  PhyNum   = (*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5337 +
5338 +  if (myMDIO_LINK&(1<<PhyNum)) return;  /* if still Linked, exit*/
5339 +
5340 +  /* Not Linked */
5341 +  *PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK);
5342 +  if (*PhyState&SMODE_AUTO)
5343 +    *PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO;
5344 +   else
5345 +    *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT;
5346 +    
5347 +  _mdioMdixDelay(PhyDev);  /* If AutoMdix add delay */
5348 +  }
5349 +
5350 +void _MdioDefaultState(PHY_DEVICE *PhyDev)
5351 +  {
5352 +  bit32u *PhyState = &PhyDev->PhyState;
5353 +  /*Awaiting a cpMacMdioInit call                                             */
5354 +  *PhyState|=PHY_CHANGE;
5355 +  }
5356 +
5357 +
5358 +/*User Calls*********************************************************       */
5359 +
5360 +void cpMacMdioClose(PHY_DEVICE *PhyDev, int Full)
5361 +  {
5362 +  }
5363 +
5364 +
5365 +int cpMacMdioInit(PHY_DEVICE *PhyDev, bit32u miibase, bit32u inst, bit32u PhyMask, bit32u MLinkMask, bit32u MdixMask, bit32u ResetReg, bit32u ResetBit, bit32u MdioBusFreq, bit32u MdioClockFreq, int verbose, void *Info)
5366 +  {
5367 +  bit32u HighestChannel;
5368 +  bit32u ControlState;
5369 +  bit32u *PhyState = &PhyDev->PhyState;
5370 +  bit32u clkdiv;                                                  /*MJH+030328*/
5371 +
5372 +  cpMacDebug=verbose;  
5373
5374 +  PhyDev->miibase   = miibase;
5375 +  PhyDev->inst      = inst;
5376 +  PhyDev->PhyMask   = PhyMask;
5377 +  PhyDev->MLinkMask = MLinkMask;
5378 +  PhyDev->MdixMask  = MdixMask;
5379 +#ifdef _CPHAL_CPMAC
5380 +  PhyDev->HalDev    = (HAL_DEVICE*) Info;
5381 +#endif
5382 +
5383 +  *PhyState &= ~PHY_MDIX_MASK;   /* Set initial State to MDI */
5384 +   
5385 +  /* Check that the channel supplied is within range */
5386 +  HighestChannel = (myMDIO_CONTROL & MDIO_CONTROL_HIGHEST_USER_CHANNEL) > 8;
5387 +  if(inst > HighestChannel)
5388 +    return(HighestChannel);
5389 +
5390 +  /*Setup MII MDIO access regs                                              */
5391 +
5392 +  /* Calculate the correct value for the mclkdiv */
5393 +  /* See PITS #14 */
5394 +  if (MdioClockFreq)                                              /*MJH+030402*/
5395 +     clkdiv = (MdioBusFreq / MdioClockFreq) - 1;                  /*MJH+030402*/
5396 +  else                                                            /*MJH+030402*/
5397 +     clkdiv = 0xFF;                                               /*MJH+030402*/
5398 +
5399 +  ControlState  = MDIO_CONTROL_ENABLE;
5400 +  ControlState |= (clkdiv & MDIO_CONTROL_CLKDIV);                 /*MJH+030328*/
5401 +
5402 +  /*
5403 +      If mii is not out of reset or if the Control Register is not set correctly
5404 +      then initalize
5405 +  */
5406 +  if( !(VOLATILE32(ResetReg) & (1 << ResetBit)) ||
5407 +     ((myMDIO_CONTROL & (MDIO_CONTROL_CLKDIV | MDIO_CONTROL_ENABLE)) != ControlState) )/*GSG~030404*/
5408 +    {
5409 +    /*  MII not setup, Setup initial condition  */
5410 +    VOLATILE32(ResetReg) &= ~(1 << ResetBit);
5411 +    _mdioDelayEmulate(PhyDev, 64);
5412 +    VOLATILE32(ResetReg) |= (1 << ResetBit);  /* take mii out of reset  */
5413 +    _mdioDelayEmulate(PhyDev, 64);
5414 +    myMDIO_CONTROL = ControlState;  /* Enable MDIO   */
5415 +    }
5416 +
5417 +  *PhyState=INIT;
5418 +
5419 +  if (cpMacDebug)
5420 +    mdioPrintf("cpMacMdioInit\n");
5421 +  _mdioDumpState(PhyDev);
5422 +  return(0);
5423 +  }
5424 +
5425 +void cpMacMdioSetPhyMode(PHY_DEVICE *PhyDev,bit32u PhyMode)
5426 +  {
5427 +  bit32u *PhyState = &PhyDev->PhyState;
5428 +  bit32u CurrentState;
5429 +
5430 +  PhyDev->PhyMode = PhyMode;   /* used for AUTOMIDX, planned to replace PhyState fields */
5431 +
5432 +  *PhyState&=~PHY_SMODE_MASK;
5433 +
5434 +  if (PhyMode&NWAY_AUTO)  *PhyState|=SMODE_AUTO;
5435 +  if (PhyMode&NWAY_FD100) *PhyState|=SMODE_FD100;
5436 +  if (PhyMode&NWAY_HD100) *PhyState|=SMODE_HD100;
5437 +  if (PhyMode&NWAY_FD10)  *PhyState|=SMODE_FD10;
5438 +  if (PhyMode&NWAY_HD10)  *PhyState|=SMODE_HD10;
5439 +
5440 +  CurrentState=*PhyState&PHY_STATE_MASK;
5441 +  if ((CurrentState==NWAY_START)||
5442 +      (CurrentState==NWAY_WAIT) ||
5443 +      (CurrentState==LINK_WAIT) ||
5444 +      (CurrentState==LINKED)      )
5445 +    *PhyState=(*PhyState&~PHY_STATE_MASK)|FOUND|PHY_CHANGE;
5446 +  if (cpMacDebug)
5447 +    mdioPrintf("cpMacMdioSetPhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode,
5448 +     PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100,
5449 +     PhyMode&NWAY_HD100);
5450 +  _mdioDumpState(PhyDev);
5451 +  }
5452 +
5453 +/* cpMacMdioTic is called every 10 mili seconds to process Phy states         */
5454 +
5455 +int cpMacMdioTic(PHY_DEVICE *PhyDev)
5456 +  {
5457 +  bit32u *PhyState = &PhyDev->PhyState;
5458 +  bit32u  CurrentState;
5459 +
5460 +  /*Act on current state of the Phy                                          */
5461 +
5462 +  CurrentState=*PhyState;
5463 +  switch(CurrentState&PHY_STATE_MASK)
5464 +    {
5465 +    case INIT:       _MdioInitState(PhyDev);      break;
5466 +    case FINDING:    _MdioFindingState(PhyDev);   break;
5467 +    case FOUND:      _MdioFoundState(PhyDev);     break;
5468 +    case NWAY_START: _MdioNwayStartState(PhyDev); break;
5469 +    case NWAY_WAIT:  _MdioNwayWaitState(PhyDev);  break;
5470 +    case LINK_WAIT:  _MdioLinkWaitState(PhyDev);  break;
5471 +    case LINKED:     _MdioLinkedState(PhyDev);    break;
5472 +    case LOOPBACK:   _MdioLoopbackState(PhyDev);  break;
5473 +    default:         _MdioDefaultState(PhyDev);   break;
5474 +    }
5475 +
5476 +  /*Dump state info if a change has been detected                            */
5477 +
5478 +  if ((CurrentState&~PHY_TIM_MASK)!=(*PhyState&~PHY_TIM_MASK))
5479 +    _mdioDumpState(PhyDev);
5480 +
5481 +  /*  Check is MDI/MDIX mode switch is needed */
5482 +  if(*PhyState & PHY_MDIX_SWITCH)
5483 +    {
5484 +    bit32u Mdix;
5485 +
5486 +    *PhyState &= ~PHY_MDIX_SWITCH;  /* Clear Mdix Flip indicator */
5487 +
5488 +    if(*PhyState & PHY_MDIX)
5489 +      Mdix = 1;
5490 +    else
5491 +      Mdix = 0;
5492 +    return(_MIIMDIO_MDIXFLIP|Mdix);
5493 +    }
5494 +
5495 +  /*Return state change to user                                              */
5496 +
5497 +  if (*PhyState&PHY_CHNG_MASK)
5498 +    {
5499 +    *PhyState&=~PHY_CHNG_MASK;
5500 +    return(1);
5501 +    }
5502 +   else
5503 +    return(0);
5504 +  }
5505 +
5506 +/* cpMacMdioGetDuplex is called to retrieve the Duplex info                   */
5507 +
5508 +int cpMacMdioGetDuplex(PHY_DEVICE *PhyDev)
5509 +  {
5510 +  bit32u *PhyState = &PhyDev->PhyState;
5511 +  return((*PhyState&PHY_DUPLEX_MASK)?1:0);  /* return 0 or a 1  */
5512 +  }
5513 +
5514 +/* cpMacMdioGetSpeed is called to retreive the Speed info                     */
5515 +
5516 +int cpMacMdioGetSpeed(PHY_DEVICE *PhyDev)
5517 +  {
5518 +  bit32u *PhyState = &PhyDev->PhyState;
5519 +  return(*PhyState&PHY_SPEED_MASK);
5520 +  }
5521 +
5522 +/* cpMacMdioGetPhyNum is called to retreive the Phy Device Adr info           */
5523 +
5524 +int cpMacMdioGetPhyNum(PHY_DEVICE *PhyDev)
5525 +  {
5526 +  bit32u *PhyState = &PhyDev->PhyState;
5527 +  return((*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET);
5528 +  }
5529 +
5530 +/* cpMacMdioGetLoopback is called to Determine if the LOOPBACK state has been reached*/
5531 +
5532 +int cpMacMdioGetLoopback(PHY_DEVICE *PhyDev)
5533 +  {
5534 +  bit32u *PhyState = &PhyDev->PhyState;
5535 +  return((*PhyState&PHY_STATE_MASK)==LOOPBACK);
5536 +  }
5537 +/* cpMacMdioGetLinked is called to Determine if the LINKED state has been reached*/
5538 +
5539 +int cpMacMdioGetLinked(PHY_DEVICE *PhyDev)
5540 +  {
5541 +  bit32u *PhyState = &PhyDev->PhyState;
5542 +  return((*PhyState&PHY_STATE_MASK)==LINKED);
5543 +  }
5544 +
5545 +void cpMacMdioLinkChange(PHY_DEVICE *PhyDev)
5546 +  {
5547 +  bit32u *PhyState = &PhyDev->PhyState;
5548 +  bit32u  PhyNum,PhyStatus;
5549 +
5550 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5551 +
5552 +  if (cpMacMdioGetLinked(PhyDev))
5553 +    {
5554 +    PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum);
5555 +
5556 +    if ((PhyStatus&PHY_LINKED)==0)
5557 +      {
5558 +      *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK);
5559 +      if (*PhyState&SMODE_AUTO)
5560 +        {
5561 +        _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE);
5562 +        *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START;
5563 +        }
5564 +       else
5565 +        {
5566 +        *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT;
5567 +        }
5568 +      }
5569 +    }
5570 +  }
5571 +
5572 +void cpMacMdioGetVer(bit32u miibase, bit32u *ModID,  bit32u *RevMaj,  bit32u *RevMin)
5573 +  {
5574 +  bit32u  Ver;
5575 +
5576 +  Ver = MDIO_VER(miibase);
5577 +
5578 +  *ModID  = (Ver & MDIO_VER_MODID) >> 16;
5579 +  *RevMaj = (Ver & MDIO_VER_REVMAJ) >> 8;
5580 +  *RevMin = (Ver & MDIO_VER_REVMIN);
5581 +  }
5582 +
5583 +int cpMacMdioGetPhyDevSize(void)
5584 +  {
5585 +  return(sizeof(PHY_DEVICE));
5586 +  }
5587 +
5588 +  /* returns 0 if current Phy has AutoMdix support, otherwise 0 */
5589 +int _mdioMdixSupported(PHY_DEVICE *PhyDev)
5590 +  {
5591 +  bit32u *PhyState = &PhyDev->PhyState;
5592 +  bit32u PhyNum;
5593 +
5594 +  if((PhyDev->PhyMode & NWAY_AUTOMDIX) == 0)
5595 +    return(0);  /* AutoMdix not turned on */
5596 +
5597 +  PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET;
5598 +  if( ((1<<PhyNum) & PhyDev->MdixMask) == 0)
5599 +    return(0);  /*  Phy does not support AutoMdix*/
5600 +
5601 +  return(1);
5602 +  }
5603 +
5604 +/* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */
5605 +void _mdioMdixDelay(PHY_DEVICE *PhyDev)
5606 +  {
5607 +  int Delay;
5608 +  bit32u *PhyState = &PhyDev->PhyState;  
5609 +#ifdef _CPHAL_CPMAC
5610 +  HAL_DEVICE *HalDev = PhyDev->HalDev;
5611 +#endif
5612 +
5613 +  if(_mdioMdixSupported(PhyDev) == 0)
5614 +    return;  /* AutoMdix not supported */
5615 +/* Currently only supported when used with the CPMAC */
5616 +#ifdef _CPHAL_CPMAC
5617 +  /* Get the Delay value in milli-seconds and convert to ten-milli second value */
5618 +  Delay = cpmacRandomRange(HalDev, _AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX);
5619 +  Delay /= 10;
5620 +
5621 +  /*  Add AutoMidx Random Switch Delay to AutoMdix Link Delay */
5622 +
5623 +  Delay += (PHY_MDIX_TO>>PHY_TIM_OFFSET);
5624 +
5625 +  /* Change Timeout value to AutoMdix standard */
5626 +  *PhyState &= ~(PHY_TIM_MASK);  /* Clear current Time out value */
5627 +  *PhyState |=  (Delay<<PHY_TIM_OFFSET);     /* Set new value */
5628 +#endif
5629 +  }
5630 +
5631 +
5632 diff -urN linux.old/drivers/net/avalanche_cpmac/cpmdio.h linux.dev/drivers/net/avalanche_cpmac/cpmdio.h
5633 --- linux.old/drivers/net/avalanche_cpmac/cpmdio.h      1970-01-01 01:00:00.000000000 +0100
5634 +++ linux.dev/drivers/net/avalanche_cpmac/cpmdio.h      2005-07-12 02:48:42.047593000 +0200
5635 @@ -0,0 +1,73 @@
5636 +/*****************************************************************************
5637 +**      TNETD53xx Software Support
5638 +**      Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved.
5639 +**
5640 +**      FILE: cpmdio.h   User Include for MDIO API Access
5641 +**
5642 +**      DESCRIPTION:
5643 +**              This include file contains definitions for the the MDIO API
5644 +**
5645 +**      HISTORY:
5646 +**              27Mar02 Michael Hanrahan Original (modified from emacmdio.h)
5647 +**              04Apr02 Michael Hanrahan Added Interrupt Support
5648 +*****************************************************************************/
5649 +#ifndef _INC_CPMDIO
5650 +#define _INC_CPMDIO
5651 +
5652 +
5653 +#ifndef __CPHAL_CPMDIO
5654 +typedef void PHY_DEVICE;
5655 +#endif
5656 +
5657 +
5658 +/*Version Information */
5659 +
5660 +void cpMacMdioGetVer(bit32u miiBase, bit32u *ModID,  bit32u *RevMaj,  bit32u *RevMin);
5661 +
5662 +/*Called once at the begining of time                                        */
5663 +
5664 +int  cpMacMdioInit(PHY_DEVICE *PhyDev, bit32u miibase, bit32u inst, bit32u PhyMask, bit32u MLinkMask, bit32u MdixMask, bit32u ResetBase, bit32u ResetBit, bit32u MdioBusFreq, bit32u MdioClockFreq, int verbose, void *Info);
5665 +int  cpMacMdioGetPhyDevSize(void);
5666 +
5667 +
5668 +/*Called every 10 mili Seconds, returns TRUE if there has been a mode change */
5669 +
5670 +int cpMacMdioTic(PHY_DEVICE *PhyDev);
5671 +
5672 +/*Called to set Phy mode                                                     */
5673 +
5674 +void cpMacMdioSetPhyMode(PHY_DEVICE *PhyDev,bit32u PhyMode);
5675 +
5676 +/*Calls to retreive info after a mode change!                                */
5677 +
5678 +int  cpMacMdioGetDuplex(PHY_DEVICE *PhyDev);
5679 +int  cpMacMdioGetSpeed(PHY_DEVICE *PhyDev);
5680 +int  cpMacMdioGetPhyNum(PHY_DEVICE *PhyDev);
5681 +int  cpMacMdioGetLinked(PHY_DEVICE *PhyDev);
5682 +void cpMacMdioLinkChange(PHY_DEVICE *PhyDev);
5683 +
5684 +/*  Shot Down  */
5685 +
5686 +void cpMacMdioClose(PHY_DEVICE *PhyDev, int Full);
5687 +
5688 +
5689 +/* Phy Mode Values  */
5690 +#define NWAY_AUTOMDIX       (1<<16)
5691 +#define NWAY_FD100          (1<<8)
5692 +#define NWAY_HD100          (1<<7)
5693 +#define NWAY_FD10           (1<<6)
5694 +#define NWAY_HD10           (1<<5)
5695 +#define NWAY_AUTO           (1<<0)
5696 +
5697 +/*
5698 + *
5699 + *    Tic() return values
5700 + *
5701 + */
5702 +
5703 +#define _MIIMDIO_MDIXFLIP (1<<28)
5704 +
5705 +#define _AUTOMDIX_DELAY_MIN  80  /* milli-seconds*/
5706 +#define _AUTOMDIX_DELAY_MAX 200  /* milli-seconds*/
5707 +
5708 +#endif  /*  _INC_CPMDIO */
5709 diff -urN linux.old/drivers/net/avalanche_cpmac/cppi_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cppi_cpmac.c
5710 --- linux.old/drivers/net/avalanche_cpmac/cppi_cpmac.c  1970-01-01 01:00:00.000000000 +0100
5711 +++ linux.dev/drivers/net/avalanche_cpmac/cppi_cpmac.c  2005-07-12 02:48:42.048593000 +0200
5712 @@ -0,0 +1,1345 @@
5713 +/*************************************************************************
5714 + *  TNETDxxxx Software Support
5715 + *  Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved.
5716 + *
5717 + *  FILE: cppi.c
5718 + *
5719 + *  DESCRIPTION:
5720 + *      This file contains shared code for all CPPI modules.
5721 + *
5722 + *  HISTORY:
5723 + *   7Aug02 Greg RC1.00  Original Version created.
5724 + *  27Sep02 Mick RC1.01  Merged for use by CPMAC/CPSAR
5725 + *  16Oct02 Mick RC1.02  Performance Tweaks (see cppihist.txt)
5726 + *  12Nov02 Mick RC1.02  Updated to use cpmac_reg.h
5727 + *  09Jan03 Mick RC3.01  Removed modification to RxBuffer ptr
5728 + *  28Mar03 Mick 1.03    RxReturn now returns error if Malloc Fails
5729 + *  10Apr03 Mick 1.03.02 Added Needs Buffer Support
5730 + *  11Jun03 Mick 1.06.02 halSend() errors corrected
5731 + *  23Aug04 Mick 1.07.08 cpmac only - Send: bypass threshold check if TxInts re-enabled
5732 + *
5733 + *  @author  Greg Guyotte
5734 + *  @version 1.00
5735 + *  @date    7-Aug-2002
5736 + *****************************************************************************/
5737 +/* each CPPI module must modify this file, the rest of the
5738 +                     code in cppi.c should be totally shared *//* Each CPPI module MUST properly define all constants shown below */
5739 +
5740 +/* CPPI registers */
5741 +
5742 +/* the following defines are not CPPI specific */
5743 +
5744 +static int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork);                     
5745 +
5746 +static void FreeRx(HAL_DEVICE *HalDev, int Ch)
5747 +  {
5748 +   HAL_RCB *rcb_ptr;                                                /*+GSG 030303*/
5749 +   int rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf;                        /*+GSG 030303*/
5750 +   int Num = HalDev->ChData[Ch].RxNumBuffers, i;                    /*+GSG 030303*/
5751 +
5752 +   /* Free Rx data buffers attached to descriptors, if necessary */
5753 +   if (HalDev->RcbStart[Ch] != 0)                                   /*+GSG 030303*/
5754 +     {                                                              /*+GSG 030303*/
5755 +      for(i=0;i<Num;i++)                                            /*+GSG 030303*/
5756 +        {                                                           /*+GSG 030303*/
5757 +         rcb_ptr = (HAL_RCB *)(HalDev->RcbStart[Ch] + (i*rcbSize)); /*+GSG 030303*/
5758 +
5759 +         /* free the data buffer */
5760 +         if (rcb_ptr->DatPtr != 0)
5761 +       {
5762 +
5763 +        HalDev->OsFunc->FreeRxBuffer((void *)rcb_ptr->OsInfo, (void *)rcb_ptr->DatPtr);
5764 +        rcb_ptr->OsInfo=0;                                        /*MJH+030522*/
5765 +        rcb_ptr->DatPtr=0;                                        /*MJH+030522*/
5766 +       }
5767 +    }                                                           /*+GSG 030303*/
5768 +     }                                                              /*+GSG 030303*/
5769 +
5770 +   /* free up all desciptors at once */
5771 +   HalDev->OsFunc->FreeDmaXfer(HalDev->RcbStart[Ch]);
5772 +
5773 +   /* mark buffers as freed */
5774 +   HalDev->RcbStart[Ch] = 0;
5775 +  }
5776 +
5777 +static void FreeTx(HAL_DEVICE *HalDev, int Ch, int Queue)
5778 +  {
5779 +
5780 +/*+GSG 030303*/
5781 +
5782 +   /* free all descriptors at once */
5783 +   HalDev->OsFunc->FreeDmaXfer(HalDev->TcbStart[Ch][Queue]);
5784 +
5785 +   HalDev->TcbStart[Ch][Queue] = 0;
5786 +  }
5787 +
5788 +/* return of 0 means that this code executed, -1 means the interrupt was not
5789 +   a teardown interrupt */
5790 +static int RxTeardownInt(HAL_DEVICE *HalDev, int Ch)
5791 +  {
5792 +   bit32u base = HalDev->dev_base;
5793 +
5794 +   /* check to see if the interrupt is a teardown interrupt */
5795 +   if (((CPMAC_RX_INT_ACK( base , Ch ))  & TEARDOWN_VAL) == TEARDOWN_VAL)
5796 +     {
5797 +      /* finish channel teardown */
5798 +
5799 +      /* Free channel resources on a FULL teardown */
5800 +      if (HalDev->RxTeardownPending[Ch] & FULL_TEARDOWN)
5801 +        {
5802 +         FreeRx(HalDev, Ch);
5803 +        }
5804 +
5805 +      /* bug fix - clear Rx channel pointers on teardown */
5806 +      HalDev->RcbPool[Ch] = 0;
5807 +      HalDev->RxActQueueHead[Ch]  = 0;
5808 +      HalDev->RxActQueueCount[Ch] = 0;
5809 +      HalDev->RxActive[Ch] = FALSE;
5810 +
5811 +      /* write completion pointer */
5812 +      (CPMAC_RX_INT_ACK( base , Ch ))  = TEARDOWN_VAL;
5813 +
5814 +      /* use direction bit as a teardown pending bit! May be able to
5815 +         use only one teardown pending integer in HalDev */
5816 +
5817 +      HalDev->RxTeardownPending[Ch] &= ~RX_TEARDOWN;
5818 +
5819 +      HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0;
5820 +
5821 +      HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0;
5822 +      CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Ch);
5823 +      if ((HalDev->RxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0)
5824 +    {
5825 +
5826 +     HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_RX);
5827 +    }
5828 +      HalDev->RxTeardownPending[Ch] = 0;
5829 +
5830 +      return (EC_NO_ERRORS);
5831 +     }
5832 +   return (-1);
5833 +  }
5834 +
5835 +/* return of 0 means that this code executed, -1 means the interrupt was not
5836 +   a teardown interrupt.  Note: this code is always called with Queue == 0 (hi priority). */
5837 +static int TxTeardownInt(HAL_DEVICE *HalDev, int Ch, int Queue)
5838 +  {
5839 +   bit32u base = HalDev->dev_base;
5840 +   HAL_TCB *Last, *Curr, *First;                                    /*+GSG 030303*/
5841 +   int i;
5842 +
5843 +   if (((CPMAC_TX_INT_ACK( base , Ch ))  & TEARDOWN_VAL) == TEARDOWN_VAL)
5844 +     {
5845 +      /* perform all actions for both queues (+GSG 040212) */
5846 +      for (i=0; i<HalDev->ChData[Ch].TxNumQueues; i++)
5847 +        {
5848 +         /* return outstanding buffers to OS                             +RC3.02*/
5849 +         Curr = HalDev->TxActQueueHead[Ch][i];                     /*+GSG 030303*/
5850 +         First = Curr;                                                 /*+GSG 030303*/
5851 +         while (Curr)                                                  /*+GSG 030303*/
5852 +           {                                                           /*+GSG 030303*/
5853 +            /* Pop TCB(s) for packet from the stack */                 /*+GSG 030303*/
5854 +            Last = Curr->Eop;                                          /*+GSG 030303*/
5855 +            HalDev->TxActQueueHead[Ch][i] = Last->Next;            /*+GSG 030303*/
5856 +                                                                    /*+GSG 030303*/
5857 +            /* return to OS */                                         /*+GSG 030303*/
5858 +            HalDev->OsFunc->SendComplete(Curr->OsInfo);                /*+GSG 030303*/
5859 +                                                                    /*+GSG 030303*/
5860 +            /* Push Tcb(s) back onto the stack */                      /*+GSG 030303*/
5861 +            Curr = Last->Next;                                         /*+GSG 030303*/
5862 +            Last->Next = HalDev->TcbPool[Ch][i];                   /*+GSG 030303*/
5863 +            HalDev->TcbPool[Ch][i] = First;                        /*+GSG 030303*/
5864 +                                                                    /*+GSG 030303*/
5865 +            /* set the first(SOP) pointer for the next packet */       /*+GSG 030303*/
5866 +            First = Curr;                                              /*+GSG 030303*/
5867 +           }                                                           /*+GSG 030303*/
5868 +        }
5869 +
5870 +      /* finish channel teardown */
5871 +
5872 +      if (HalDev->TxTeardownPending[Ch] & FULL_TEARDOWN)
5873 +        {
5874 +         FreeTx(HalDev, Ch, 0);
5875 +
5876 +         if (HalDev->ChData[Ch].TxNumQueues == 2)
5877 +           FreeTx(HalDev, Ch, 1);
5878 +        } /* if FULL teardown */
5879 +
5880 +      /* perform all actions for both queues (+GSG 040212) */
5881 +      for (i=0; i<HalDev->ChData[Ch].TxNumQueues; i++)
5882 +        {
5883 +         /* bug fix - clear Tx channel pointers on teardown */
5884 +         HalDev->TcbPool[Ch][i] = 0;
5885 +         HalDev->TxActQueueHead[Ch][i]  = 0;
5886 +         HalDev->TxActQueueCount[Ch][i] = 0;
5887 +         HalDev->TxActive[Ch][i]        = FALSE;
5888 +        }
5889 +
5890 +      /* write completion pointer, only needed for the high priority queue */
5891 +      (CPMAC_TX_INT_ACK( base , Ch ))  = TEARDOWN_VAL;
5892 +
5893 +      /* no longer pending teardown */
5894 +      HalDev->TxTeardownPending[Ch] &= ~TX_TEARDOWN;
5895 +
5896 +      HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0;
5897 +
5898 +      HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0;
5899 +      CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Ch);
5900 +      if ((HalDev->TxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0)
5901 +        {
5902 +
5903 +         HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_TX);
5904 +        }
5905 +      HalDev->TxTeardownPending[Ch] = 0;
5906 +
5907 +      return (EC_NO_ERRORS);
5908 +     }
5909 +   return (-1);
5910 +  }
5911 +
5912 +/* +GSG 030421 */
5913 +static void AddToRxQueue(HAL_DEVICE *HalDev, HAL_RCB *FirstRcb, HAL_RCB *LastRcb, int FragCount, int Ch)
5914 +  {
5915 +   if (HalDev->RxActQueueHead[Ch]==0)
5916 +     {
5917 +
5918 +      HalDev->RxActQueueHead[Ch]=FirstRcb;
5919 +      HalDev->RxActQueueTail[Ch]=LastRcb;
5920 +      if (!HalDev->RxActive[Ch])
5921 +        {
5922 +         /* write Rx Queue Head Descriptor Pointer */
5923 +         ((CPMAC_RX_HDP(  HalDev->dev_base  ,  Ch  )) )  = VirtToPhys(FirstRcb) - HalDev->offset;
5924 +         HalDev->RxActive[Ch]=TRUE;
5925 +        }
5926 +     }
5927 +    else
5928 +     {
5929 +      register HAL_RCB *OldTailRcb;
5930 +      register bit32u rmode;
5931 +      
5932 +      HalDev->OsFunc->CriticalOn();
5933 +      OldTailRcb=HalDev->RxActQueueTail[Ch];
5934 +      OldTailRcb->Next=(void *)FirstRcb;
5935 +      OldTailRcb=VirtToVirtNoCache(OldTailRcb);
5936 +      OldTailRcb->HNext=VirtToPhys(FirstRcb) - HalDev->offset;
5937 +      HalDev->RxActQueueTail[Ch]=LastRcb;
5938 +      rmode=OldTailRcb->mode;
5939 +      if (rmode&CB_EOQ_BIT)
5940 +        {
5941 +        rmode&=~CB_EOQ_BIT;
5942 +        ((CPMAC_RX_HDP(  HalDev->dev_base  ,  Ch  )) )  = VirtToPhys(FirstRcb) - HalDev->offset;
5943 +        OldTailRcb->mode=rmode;
5944 +        }   
5945 +      HalDev->OsFunc->CriticalOff();
5946 +     }
5947 +  }
5948 +
5949 +/**
5950 + *  @ingroup CPHAL_Functions
5951 + *  This function is called to indicate to the CPHAL that the upper layer
5952 + *  software has finished processing the receive data (given to it by
5953 + *  osReceive()).  The CPHAL will then return the appropriate receive buffers
5954 + *  and buffer descriptors to the available pool.
5955 + *
5956 + *  @param   HalReceiveInfo   Start of receive buffer descriptor chain returned to
5957 + *                      CPHAL.
5958 + *  @param   StripFlag  Flag indicating whether the upper layer software has
5959 + *                      retained ownership of the receive data buffers.
5960 + *<BR>
5961 + * 'FALSE' means  that the CPHAL can reuse the receive data buffers.
5962 + *<BR>
5963 + * 'TRUE' : indicates the data buffers were retained by the OS
5964 + *<BR>
5965 + * NOTE:  If StripFlag is TRUE, it is the responsibility of the upper layer software to free the buffers when they are no longer needed.
5966 + *
5967 + *  @return EC_NO_ERRORS (ok). <BR>
5968 + *          Possible Error Codes:<BR>
5969 + *          @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR>
5970 + *          @ref EC_VAL_RCB_NEEDS_BUFFER "EC_VAL_RCB_NEEDS_BUFFER"<BR>
5971 + *          @ref EC_VAL_RCB_DROPPED "EC_VAL_RCB_DROPPED"<BR>
5972 + */
5973 +static int halRxReturn(HAL_RECEIVEINFO *HalReceiveInfo,
5974 +            int StripFlag)
5975 +  {
5976 +   int Ch, i;
5977 +   HAL_RCB *LastRcb;
5978 +   HAL_DEVICE *HalDev;
5979 +   int RcbSize;
5980 +   int FragCount;
5981 +
5982 +   Ch = HalReceiveInfo->mode&0x0ff;
5983 +   HalDev = (HAL_DEVICE *)HalReceiveInfo->Off_BLen;
5984 +   FragCount = HalReceiveInfo->mode>>8;
5985 +      
5986 +   if (HalDev->State != enOpened)
5987 +     return(EC_CPMAC |EC_FUNC_RXRETURN|EC_VAL_INVALID_STATE);
5988 +
5989 +   LastRcb=(HAL_RCB *)HalReceiveInfo->Eop;
5990 +   LastRcb->HNext=0;
5991 +   LastRcb->Next=0;
5992 +   RcbSize = HalDev->ChData[Ch].RxBufSize;
5993 +
5994 +   if (FragCount>1)
5995 +     {
5996 +      LastRcb->Off_BLen=RcbSize;
5997 +      LastRcb->mode=CB_OWNERSHIP_BIT;
5998 +     }
5999 +
6000 +   HalReceiveInfo->Off_BLen=RcbSize;
6001 +   HalReceiveInfo->mode=CB_OWNERSHIP_BIT;
6002 +
6003 +   /* If OS has kept the buffers for this packet, attempt to alloc new buffers */
6004 +   if (StripFlag)
6005 +     {
6006 +      int rc=0;                                                      /*MJH+030417*/
6007 +      int GoodCount=0;                                               /*GSG+030421*/       
6008 +      HAL_RCB *TempRcb;
6009 +      char *pBuf;
6010 +      HAL_RCB *CurrHeadRcb = HalReceiveInfo, *LastGoodRcb=0;         /* +GSG 030421 */
6011 +
6012 +      TempRcb = HalReceiveInfo;
6013 +      for (i=0; i<FragCount; i++)
6014 +        {
6015 +         if (TempRcb == 0)
6016 +           {
6017 +            dbgPrintf("Rx Return error while allocating new buffers\n");
6018 +            dbgPrintf("Rcb = %08x, Rcb->Eop = %08x, FragCount = %d:%d\n",
6019 +              (bit32u)HalReceiveInfo, (bit32u)HalReceiveInfo->Eop, FragCount,i);
6020 +            osfuncSioFlush();
6021 +
6022 +            return(EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_CORRUPT_RCB_CHAIN);
6023 +           }
6024 +
6025 +         pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(RcbSize,0,
6026 +                             0xF,HalDev->ChData[Ch].OsSetup,
6027 +                             (void *)TempRcb,
6028 +                             (void *)&TempRcb->OsInfo,
6029 +                             (void *) HalDev->OsDev);
6030 +         if (!pBuf)
6031 +           {
6032 +            /* malloc failed, add this RCB to Needs Buffer List */
6033 +            (HAL_RCB *)TempRcb->Eop = TempRcb;                                  /* GSG +030430 */
6034 +            TempRcb->mode=1<<8|Ch;
6035 +            TempRcb->Off_BLen=(bit32u)HalDev;
6036 +            
6037 +            if(HalDev->NeedsCount < MAX_NEEDS)                                  /* +MJH 030410 */
6038 +              {                                                                 /* +MJH 030410 */
6039 +               HalDev->Needs[HalDev->NeedsCount] = (HAL_RECEIVEINFO *) TempRcb; /* +MJH 030410 */
6040 +               HalDev->NeedsCount++;                                            /* +MJH 030410 */
6041 +               rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_NEEDS_BUFFER);         /* ~MJH 030417 */
6042 +              }                                                                 /* +MJH 030410 */
6043 +             else                                                               /* +MJH 030410 */
6044 +               rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_DROPPED);              /* ~MJH 030417 */
6045 +
6046 +            /* requeue any previous RCB's that were ready to go before this one */
6047 +            if (GoodCount > 0)                                                  /* +GSG 030421 */
6048 +              {                                                                 /* +GSG 030421 */
6049 +               LastGoodRcb->HNext=0;                                            /* +GSG 030430 */
6050 +               LastGoodRcb->Next=0;                                             /* +GSG 030430 */
6051 +               osfuncDataCacheHitWritebackAndInvalidate((void *)LastGoodRcb, 16);            /* +GSG 030430 */
6052 +
6053 +               AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch);   /* +GSG 030421 */
6054 +               GoodCount = 0;                                                   /* +GSG 030421 */
6055 +              }                                                                 /* +GSG 030421 */
6056 +
6057 +            CurrHeadRcb = TempRcb->Next;                                        /* +GSG 030421 */
6058 +           }
6059 +          else                                                                  /* +GSG 030421 */
6060 +           {                                                                    /* +GSG 030421 */
6061 +            /* malloc succeeded, requeue the RCB to the hardware */
6062 +            TempRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset;
6063 +            TempRcb->DatPtr=pBuf;
6064 +            /* Emerald fix 10/29 */
6065 +            osfuncDataCacheHitWritebackAndInvalidate((void *)TempRcb, 16);
6066 +
6067 +            /* i store the last good RCB in case the malloc fails for the
6068 +               next fragment.  This ensures that I can go ahead and return
6069 +               a partial chain of RCB's to the hardware */
6070 +            LastGoodRcb = TempRcb;                                              /* +GSG 030421 */
6071 +            GoodCount++;                                                        /* +GSG 030421 */
6072 +           }                                                                    /* +GSG 030421 */
6073 +         TempRcb = TempRcb->Next;
6074 +        } /*  end of Frag loop */
6075 +      /* if there any good RCB's to requeue, do so here */
6076 +      if (GoodCount > 0)                                                        /* +GSG 030421 */
6077 +        {
6078 +         AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch);          /* +GSG 030421 */
6079 +        }
6080 +      return(rc);                                                               /* ~GSG 030421 */
6081 +     }
6082 +   else
6083 +     {
6084 +      /*  Not Stripping */
6085 +      /* Emerald */
6086 +      /* Write Back SOP and last RCB */
6087 +      osfuncDataCacheHitWritebackAndInvalidate((void *)HalReceiveInfo, 16);
6088 +
6089 +      if (FragCount > 1)
6090 +        {
6091 +         osfuncDataCacheHitWritebackAndInvalidate((void *)LastRcb, 16);
6092 +        }
6093 +      /* if not stripping buffers, always add to queue */
6094 +      AddToRxQueue(HalDev, HalReceiveInfo, LastRcb, FragCount, Ch); /*MJH~030520*/
6095 +     }
6096 +
6097 +   return(EC_NO_ERRORS);
6098 +  }
6099 +
6100 +/* +MJH 030410
6101 +   Trys to liberate an RCB until liberation fails.
6102 +   Note: If liberation fails then RxReturn will re-add the RCB to the
6103 +         Needs list.
6104 +*/
6105 +static void NeedsCheck(HAL_DEVICE *HalDev)
6106 +{
6107 +    HAL_RECEIVEINFO* HalRcb;
6108 +    int rc;
6109 +    HalDev->OsFunc->CriticalOn();
6110 +    while(HalDev->NeedsCount)
6111 +      {
6112 +      HalDev->NeedsCount--;
6113 +      HalRcb = HalDev->Needs[HalDev->NeedsCount];
6114 +      rc =  halRxReturn(HalRcb, 1);
6115 +      /* short circuit if RxReturn starts to fail */
6116 +      if (rc != 0)
6117 +        break;
6118 +      }
6119 +    HalDev->OsFunc->CriticalOff();
6120 +}
6121 +
6122 +/*
6123 + *  This function allocates transmit buffer descriptors (internal CPHAL function).
6124 + *  It creates a high priority transmit queue by default for a single Tx
6125 + *  channel.  If QoS is enabled for the given CPHAL device, this function
6126 + *  will also allocate a low priority transmit queue.
6127 + *
6128 + *  @param   HalDev   CPHAL module instance. (set by cphalInitModule())
6129 + *  @param   Ch       Channel number.
6130 + *
6131 + *  @return  0 OK, Non-Zero Not OK
6132 + */
6133 +static int InitTcb(HAL_DEVICE *HalDev, int Ch)
6134 +  {
6135 +   int i, Num = HalDev->ChData[Ch].TxNumBuffers;
6136 +   HAL_TCB *pTcb=0;
6137 +   char *AllTcb;
6138 +   int  tcbSize, Queue;
6139 +   int SizeMalloc;
6140 +
6141 +   tcbSize = (sizeof(HAL_TCB)+0xf)&~0xf;
6142 +   SizeMalloc = (tcbSize*Num)+0xf;
6143 +
6144 +   for (Queue=0; Queue < HalDev->ChData[Ch].TxNumQueues; Queue++)
6145 +     {
6146 +      if (HalDev->TcbStart[Ch][Queue] == 0)
6147 +        {
6148 +
6149 +         /* malloc all TCBs at once */
6150 +         AllTcb = (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff);
6151 +         if (!AllTcb)
6152 +           {
6153 +            return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_TCB_MALLOC_FAILED);
6154 +           }
6155 +
6156 +         HalDev->OsFunc->Memset(AllTcb, 0, SizeMalloc);
6157 +
6158 +         /* keep this address for freeing later */
6159 +         HalDev->TcbStart[Ch][Queue] = AllTcb;
6160 +        }
6161 +       else
6162 +        {
6163 +         /* if the memory has already been allocated, simply reuse it! */
6164 +         AllTcb = HalDev->TcbStart[Ch][Queue];
6165 +        }
6166 +
6167 +      /* align to cache line */
6168 +      AllTcb = (char *)(((bit32u)AllTcb + 0xf) &~ 0xf); /*PITS #143  MJH~030522*/
6169 +
6170 +      /* default High priority transmit queue */
6171 +      HalDev->TcbPool[Ch][Queue]=0;
6172 +      for(i=0;i<Num;i++)
6173 +        {
6174 +         /*pTcb=(HAL_TCB *) OsFunc->MallocDmaXfer(sizeof(HAL_TCB),0,0xffffffff); */
6175 +         pTcb= (HAL_TCB *)(AllTcb + (i*tcbSize));
6176 +         pTcb->mode=0;
6177 +         pTcb->BufPtr=0;
6178 +         pTcb->Next=HalDev->TcbPool[Ch][Queue];
6179 +         pTcb->Off_BLen=0;
6180 +         HalDev->TcbPool[Ch][Queue]=pTcb;
6181 +        }
6182 +      /*HalDev->TcbEnd = pTcb;*/
6183 +     }
6184 +
6185 +   return(EC_NO_ERRORS);
6186 +  }
6187 +
6188 +/*
6189 + *  This function allocates receive buffer descriptors (internal CPHAL function).
6190 + *  After allocation, the function 'queues' (gives to the hardware) the newly
6191 + *  created receive buffers to enable packet reception.
6192 + *
6193 + *  @param   HalDev   CPHAL module instance. (set by cphalInitModule())
6194 + *  @param   Ch    Channel number.
6195 + *
6196 + *  @return  0 OK, Non-Zero Not OK
6197 + */
6198 +static int InitRcb(HAL_DEVICE *HalDev, int Ch)
6199 +  {
6200 +   int i, Num = HalDev->ChData[Ch].RxNumBuffers;
6201 +   int Size = HalDev->ChData[Ch].RxBufSize;
6202 +   HAL_RCB *pRcb;
6203 +   char *pBuf;
6204 +   char *AllRcb;
6205 +   int  rcbSize;
6206 +   int  DoMalloc = 0;
6207 +   int SizeMalloc;
6208 +   int MallocSize;
6209 +
6210 +   rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf;
6211 +   SizeMalloc = (rcbSize*Num)+0xf;
6212 +
6213 +   if (HalDev->RcbStart[Ch] == 0)
6214 +     {
6215 +      DoMalloc = 1;
6216 +
6217 +      /* malloc all RCBs at once */
6218 +      AllRcb= (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff);
6219 +      if (!AllRcb)
6220 +        {
6221 +         return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RCB_MALLOC_FAILED);
6222 +        }
6223 +
6224 +      HalDev->OsFunc->Memset(AllRcb, 0, SizeMalloc);
6225 +
6226 +      /* keep this address for freeing later */
6227 +      HalDev->RcbStart[Ch] = AllRcb;
6228 +     }
6229 +    else
6230 +     {
6231 +      /* if the memory has already been allocated, simply reuse it! */
6232 +      AllRcb = HalDev->RcbStart[Ch];
6233 +     }
6234 +
6235 +   /* align to cache line */
6236 +   AllRcb = (char *)(((bit32u)AllRcb + 0xf)&~0xf);  /*PITS #143  MJH~030522*/
6237 +
6238 +   HalDev->RcbPool[Ch]=0;
6239 +   for(i=0;i<Num;i++)
6240 +     {
6241 +      pRcb = (HAL_RCB *)(AllRcb + (i*rcbSize));
6242 +
6243 +      if (DoMalloc == 1)
6244 +        {
6245 +
6246 +         MallocSize = Size;                                       /*~3.01 */
6247 +         pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(MallocSize,0,0xF,HalDev->ChData[Ch].OsSetup, (void *)pRcb, (void *)&pRcb->OsInfo, (void *) HalDev->OsDev);
6248 +         if(!pBuf)
6249 +             {
6250 +            return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RX_BUFFER_MALLOC_FAILED);
6251 +             }
6252 +           /* -RC3.01 pBuf = (char *)(((bit32u)pBuf+0xF) & ~0xF); */
6253 +         pRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset;
6254 +         pRcb->DatPtr=pBuf;
6255 +        }
6256 +      pRcb->mode=(1<<8)|Ch; /* One Frag for Ch */
6257 +      pRcb->Next=(void *)HalDev->RcbPool[Ch];
6258 +      pRcb->Off_BLen=(bit32u)HalDev;
6259 +      HalDev->RcbPool[Ch]=pRcb;
6260 +     }
6261 +
6262 +   /* Give all of the Rx buffers to hardware */
6263 +
6264 +   while(HalDev->RcbPool[Ch])
6265 +     {
6266 +      pRcb=HalDev->RcbPool[Ch];
6267 +      HalDev->RcbPool[Ch]=pRcb->Next;
6268 +      pRcb->Eop=(void*)pRcb;
6269 +      pRcb->mode=(1<<8)|Ch;
6270 +      halRxReturn((HAL_RECEIVEINFO *)pRcb, 0);
6271 +     }
6272 +
6273 +   return(EC_NO_ERRORS);
6274 +  }
6275 +
6276 +/**
6277 + *  @ingroup CPHAL_Functions
6278 + *  This function transmits the data in FragList using available transmit
6279 + *  buffer descriptors.  More information on the use of the Mode parameter
6280 + *  is available in the module-specific appendices.  Note:  The OS should
6281 + *  not call Send() for a channel that has been requested to be torndown.
6282 + *
6283 + *  @param   HalDev      CPHAL module instance. (set by cphalInitModule())
6284 + *  @param   FragList    Fragment List structure.
6285 + *  @param   FragCount   Number of fragments in FragList.
6286 + *  @param   PacketSize  Number of bytes to transmit.
6287 + *  @param   OsSendInfo  OS Send Information structure. <BR>
6288 + *  @param   Mode        32-bit value with the following bit fields: <BR>
6289 + *                       31-16: Mode  (used for module specific data). <BR>
6290 + *                       15-08: Queue (transmit queue to send on). <BR>
6291 + *                       07-00: Channel (channel number to send on).
6292 + *
6293 + *  @return  EC_NO_ERRORS (ok). <BR>
6294 + *           Possible Error Codes:<BR>
6295 + *           @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR>
6296 + *           @ref EC_VAL_NOT_LINKED "EC_VAL_NOT_LINKED"<BR>
6297 + *           @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"<BR>
6298 + *           @ref EC_VAL_OUT_OF_TCBS "EC_VAL_OUT_OF_TCBS"<BR>
6299 + *           @ref EC_VAL_NO_TCBS "EC_VAL_NO_TCBS"<BR>
6300 + */
6301 +static int halSend(HAL_DEVICE *HalDev,FRAGLIST *FragList,
6302 +                      int FragCount,int PacketSize, OS_SENDINFO *OsSendInfo,
6303 +                      bit32u Mode)
6304 +  {
6305 +  HAL_TCB *tcb_ptr, *head;
6306 +  int i;
6307 +  int rc = EC_NO_ERRORS;
6308 +  int Ch = Mode & 0xFF;
6309 +  int Queue = (Mode>>8)&0xFF;
6310 +  /*int DoThresholdCheck=1;  */ /* Used when TxIntDisable is set and TxInts are re-enabled */
6311 +  
6312 +  if (HalDev->State != enOpened)
6313 +     return(EC_CPPI|EC_FUNC_SEND|EC_VAL_INVALID_STATE);
6314 +
6315 +  if (!HalDev->Linked)
6316 +    {
6317 +     rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NOT_LINKED;
6318 +     return(rc);
6319 +    }
6320 +
6321 +  if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0)                    /*MJH~030611*/ /*PITS 148*/
6322 +    return(EC_CPMAC |EC_FUNC_SEND|EC_VAL_INVALID_CH);              /*+GSG 030303*/
6323 +
6324 +  HalDev->OsFunc->CriticalOn();
6325 +
6326 +  /* Setup Tx mode and size */
6327 +  if (PacketSize<60)
6328 +    {
6329 +     FragList[FragCount-1].len += (60 - PacketSize);              /*MJH~030506*//*PITS 132*/
6330 +     PacketSize = 60;                                             /*MJH~030506*/
6331 +    }
6332 +  Mode &= CB_PASSCRC_BIT;
6333 +
6334 +  tcb_ptr = head = HalDev->TcbPool[Ch][Queue];
6335 +
6336 +  if (tcb_ptr)
6337 +    {
6338 +
6339 +     Mode|=PacketSize|CB_SOF_BIT|CB_OWNERSHIP_BIT;
6340 +
6341 +     for (i=0; i<FragCount; i++)
6342 +
6343 +       {
6344 +        /* Setup Tx mode and size */
6345 +        tcb_ptr->Off_BLen = FragList[i].len;
6346 +        
6347 +        tcb_ptr->mode     = Mode;
6348 +        tcb_ptr->BufPtr   = VirtToPhys((bit32 *)FragList[i].data) - HalDev->offset;
6349 +        tcb_ptr->OsInfo = OsSendInfo;
6350 +
6351 +        if (i == (FragCount - 1))
6352 +          {
6353 +           /* last fragment */
6354 +           tcb_ptr->mode |= CB_EOF_BIT;
6355 +
6356 +           /* since this is the last fragment, set the TcbPool pointer before
6357 +              nulling out the Next pointers */
6358 +
6359 +           HalDev->TcbPool[Ch][Queue] = tcb_ptr->Next;
6360 +
6361 +           tcb_ptr->Next = 0;
6362 +           tcb_ptr->HNext = 0;
6363 +
6364 +           /* In the Tx Interrupt handler, we will need to know which TCB is EOP,
6365 +              so we can save that information in the SOP */
6366 +           head->Eop = tcb_ptr;
6367 +
6368 +           /* Emerald fix 10/29 */
6369 +       osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16);
6370 +
6371 +          }
6372 +         else
6373 +          {
6374 +           Mode=CB_OWNERSHIP_BIT;
6375 +           tcb_ptr->HNext    = VirtToPhys((bit32 *)tcb_ptr->Next) - HalDev->offset;
6376 +        
6377 +           /* Emerald fix 10/29 */
6378 +           osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16);
6379 +
6380 +           tcb_ptr = tcb_ptr->Next;  /* what about the end of TCB list?? */
6381 +
6382 +           if (tcb_ptr == 0)
6383 +             {
6384 +              rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_OUT_OF_TCBS;
6385 +              goto ExitSend;
6386 +             }
6387 +          }
6388 +       } /* for */
6389 +
6390 +     /* put it on the high priority queue */
6391 +     if (HalDev->TxActQueueHead[Ch][Queue] == 0)
6392 +       {
6393 +        HalDev->TxActQueueHead[Ch][Queue]=head;
6394 +        HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr;
6395 +/*+GSG 030303*//*+GSG 030303*/
6396 +        if (!HalDev->TxActive[Ch][Queue])
6397 +          {
6398 +
6399 +              bit32u base = HalDev->dev_base;
6400 +              
6401 +              /* write CPPI TX HDP */
6402 +              (CPMAC_TX_HDP( base , Ch ))  = VirtToPhys(head)  - HalDev->offset;
6403 +              HalDev->TxActive[Ch][Queue]=TRUE;
6404 +
6405 +          }
6406 +       }
6407 +      else
6408 +       {
6409 +           register volatile HAL_TCB *pTailTcb;   
6410 +        register bit32u tmode;
6411 +        register bit32u pCurrentTcb;
6412 +        
6413 +        HalDev->TxActQueueTail[Ch][Queue]->Next=head;
6414 +        /* Emerald fix 10/29 */
6415 +        
6416 +        pTailTcb=(HAL_TCB *)VirtToVirtNoCache(&HalDev->TxActQueueTail[Ch][Queue]->HNext);
6417 +        pCurrentTcb=VirtToPhys(head)  - HalDev->offset;
6418 +        pTailTcb->HNext=pCurrentTcb;
6419 +        HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr;
6420 +/*+GSG 030303*/
6421 +        tmode=pTailTcb->mode;  
6422 +        if (tmode&CB_EOQ_BIT)
6423 +          {
6424 +           bit32u base = HalDev->dev_base;
6425 +
6426 +           tmode&=~CB_EOQ_BIT;
6427 +           pTailTcb->mode=tmode;
6428 +           ((CPMAC_TX_HDP( base , Ch )) )  = pCurrentTcb;
6429 +          }
6430 +
6431 +        else
6432 +          {
6433 +           if(HalDev->TxIntDisable)
6434 +             {
6435 +              /*  Enable Interrupts, to ensure packet goes out on wire */
6436 +              CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<<Ch); 
6437 +              halPacketProcessEnd(HalDev); /* Allow Interrupt to be seen at the OS */
6438 +              /*DoThresholdCheck = 0; */       /* Disable Threshold Check */
6439 +
6440 +             }       
6441 +          }
6442 +
6443 +       }
6444 +     rc = EC_NO_ERRORS;
6445 +     goto ExitSend;
6446 +    } /* if (tcb_ptr) */
6447 +   else
6448 +    {
6449 +     rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NO_TCBS;
6450 +     goto ExitSend;
6451 +    }
6452 +ExitSend:
6453 +
6454 +/* 15 June 2004 - NSP Performance Update : If Tx Ints are disabled then process them here */
6455 +/* 29 June 2004 - NSP Performance Update : Moved to end at request of BCIL */
6456 +/* 23 Aug  2004 - NSP Performance Update : If Tx Ints are re-enabled do not do Threshold check */
6457 +
6458 +   if(HalDev->TxIntDisable /*&& DoThresholdCheck*/)
6459 +   {
6460 +      if(--HalDev->TxIntThreshold[Ch] <= 0)
6461 +      {
6462 +          int MoreWork;
6463 +          TxInt(HalDev, Ch, 0, &MoreWork);
6464 +          HalDev->TxIntThreshold[Ch] = HalDev->TxIntThresholdMaster[Ch];
6465 +      }
6466 +   }
6467 +    HalDev->OsFunc->CriticalOff();
6468 +
6469 +   return(rc);
6470 +  }
6471 +
6472 +/*
6473 + *  This function processes receive interrupts.  It traverses the receive
6474 + *  buffer queue, extracting the data and passing it to the upper layer software via
6475 + *  osReceive().  It handles all error conditions and fragments without valid data by
6476 + *  immediately returning the RCB's to the RCB pool.
6477 + *
6478 + *  @param   HalDev   CPHAL module instance. (set by cphalInitModule())
6479 + *  @param   Ch       Channel Number.
6480 + *  @param   MoreWork Flag that indicates that there is more work to do when set to 1.
6481 + *
6482 + *  @return  0 if OK, non-zero otherwise.
6483 + */
6484 +static int RxInt(HAL_DEVICE *HalDev, int Ch, int *MoreWork)
6485 +  {
6486 +  HAL_RCB *CurrentRcb, *SopRcb, *EofRcb, *EopRcb;
6487 +  bit32u RxBufStatus,PacketsServiced, RxPktLen = 0, RxSopStatus,
6488 +    FrmFrags, TotalFrags, FrmLen;
6489 +  int base = HalDev->dev_base, Ret;
6490 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
6491 +  int RxServiceMax = HalDev->ChData[Ch].RxServiceMax;
6492 +  int FragIndex; /* +GSG 030508 */
6493 +  
6494 +  if(HalDev->NeedsCount) /* +MJH 030410 */
6495 +    NeedsCheck(HalDev);  /* +MJH 030410 */
6496 +
6497 +  /* Handle case of teardown interrupt */
6498 +  if (HalDev->RxTeardownPending[Ch] != 0)
6499 +    {
6500 +     Ret = RxTeardownInt(HalDev, Ch);
6501 +     if (Ret == 0)
6502 +       {                                                              /*+GSG 030303*/
6503 +        *MoreWork = 0;
6504 +        return (EC_NO_ERRORS);
6505 +       }                                                              /*+GSG 030303*/
6506 +    }
6507 +
6508 +  /* Examine first RCB on the software active queue */
6509 +  CurrentRcb=HalDev->RxActQueueHead[Ch];
6510 +  osfuncDataCacheHitInvalidate((void*)CurrentRcb, 16);
6511 +  RxBufStatus=CurrentRcb->mode;
6512 +  PacketsServiced=0;
6513 +  
6514 +  /* Process received packets until we find hardware owned descriptors
6515 +     or until we hit RxServiceMax */
6516 +  while((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)&&
6517 +    (PacketsServiced<RxServiceMax)) /* ~GSG 030307 */
6518 +    {
6519 +
6520 +     PacketsServiced++; /* ~GSG 030307 */
6521 +     SopRcb=CurrentRcb;
6522 +     RxSopStatus=RxBufStatus;
6523 +     RxPktLen = RxSopStatus&CB_SIZE_MASK;
6524 +    
6525 +     FrmFrags=0;
6526 +     TotalFrags=0;
6527 +     FragIndex=0;
6528 +     FrmLen=0;
6529 +     EofRcb=0;
6530 +
6531 +/* +GSG 030508 *//* +GSG 030508 */
6532 +
6533 +     /* Loop through all fragments that comprise current packet.  Build
6534 +        fraglist and exit when the end of the packet is reached, or the
6535 +        end of the descriptor list is reached. */
6536 +     do
6537 +       {
6538 +           bit32u DmaLen;
6539 +          
6540 +
6541 +        DmaLen=CurrentRcb->Off_BLen;
6542 +
6543 +        FrmLen+=DmaLen;
6544 +        TotalFrags++;
6545 +        if (!EofRcb)
6546 +          {
6547 +           HalDev->fraglist[FragIndex].data=((char *)CurrentRcb->DatPtr);       /* ~GSG 030508 */
6548 +
6549 +           HalDev->fraglist[FragIndex].len=DmaLen;                              /* ~GSG 030508 */
6550 +
6551 +           /* GSG 12/9 */
6552 +           HalDev->fraglist[FragIndex].OsInfo = CurrentRcb->OsInfo;             /* ~GSG 030508 */
6553 +
6554 +           /* Upper layer must do the data invalidate */ 
6555 +
6556 +           FrmFrags++;
6557 +           FragIndex++;                                                         /* ~GSG 030508 */
6558 +           if (FrmLen>=RxPktLen)
6559 +             EofRcb=CurrentRcb;
6560 +          }
6561 +        EopRcb=CurrentRcb;
6562 +        CurrentRcb=EopRcb->Next;
6563 +        if (CurrentRcb)
6564 +          {
6565 +           osfuncDataCacheHitInvalidate((void*)CurrentRcb,16);
6566 +          }
6567 +       }while(((EopRcb->mode&CB_EOF_BIT)==0)&&(CurrentRcb));
6568 +     
6569 +     /* Write the completion pointer for interrupt acknowledgement*/
6570 +     (CPMAC_RX_INT_ACK( base , Ch ))  = VirtToPhys(EopRcb) - HalDev->offset;
6571 +
6572 +     EopRcb->Next=0;
6573 +
6574 +     if (CurrentRcb == 0)
6575 +       { 
6576 +           /* If we are out of RCB's we must not send this packet
6577 +              to the OS. */
6578 +        int RcbSize = HalDev->ChData[Ch].RxBufSize;
6579 +
6580 +        if (TotalFrags>1)
6581 +          {
6582 +           EopRcb->Off_BLen=RcbSize;
6583 +           EopRcb->mode=CB_OWNERSHIP_BIT;
6584 +           osfuncDataCacheHitWritebackAndInvalidate((void *)EopRcb, 16);
6585 +          }
6586 +
6587 +        SopRcb->Off_BLen=RcbSize;
6588 +        SopRcb->mode=CB_OWNERSHIP_BIT;   
6589 +        osfuncDataCacheHitWritebackAndInvalidate((void *)SopRcb, 16);
6590 +      
6591 +        ((CPMAC_RX_HDP( base , Ch )) )  = VirtToPhys(SopRcb);
6592 +       }
6593 +      else
6594 +       { 
6595 +           /* Dequeue packet and send to OS */
6596 +        int mode;
6597 +
6598 +        /* setup SopRcb for the packet */
6599 +        SopRcb->Eop=(void*)EopRcb;
6600 +
6601 +        /* dequeue packet */
6602 +        HalDev->RxActQueueHead[Ch]=CurrentRcb;
6603 +        
6604 +        if (EopRcb->mode&CB_EOQ_BIT)
6605 +          {
6606 +              /* Next pointer is non-null and EOQ bit is set, which
6607 +                 indicates misqueue packet in CPPI protocol. */
6608 +
6609 +           ((CPMAC_RX_HDP( base , Ch )) )  = EopRcb->HNext;
6610 +          }
6611 +        
6612 +        mode = (SopRcb->mode & 0xFFFF0000) | Ch;
6613 +
6614 +        SopRcb->mode=(FrmFrags<<8)|Ch;
6615 +        SopRcb->Off_BLen=(bit32u)HalDev;
6616 +        
6617 +        /* send packet up the higher layer driver */
6618 +        OsFunc->Receive(HalDev->OsDev,HalDev->fraglist,FragIndex,RxPktLen,             /* ~GSG 030508 */
6619 +                       (HAL_RECEIVEINFO *)SopRcb,mode);
6620 +    
6621 +        RxBufStatus=CurrentRcb->mode;          
6622 +       }
6623 +    } /* while loop */
6624 +      
6625 +  if ((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)) /*~GSG 030307*/
6626 +    {
6627 +     *MoreWork = 1;
6628 +    }
6629 +   else
6630 +    {
6631 +     *MoreWork = 0;
6632 +    }
6633 +
6634 +  return (EC_NO_ERRORS);
6635 +}
6636 +
6637 +/*
6638 + *  This function processes transmit interrupts.  It traverses the
6639 + *  transmit buffer queue, detecting sent data buffers and notifying the upper
6640 + *  layer software via osSendComplete().  (for SAR, i originally had this split
6641 + *  into two functions, one for each queue, but joined them on 8/8/02)
6642 + *
6643 + *  @param   HalDev   CPHAL module instance. (set by cphalInitModule())
6644 + *  @param   Queue    Queue number to service (always 0 for MAC, Choose 1 for SAR to service low priority queue)
6645 + *  @param   MoreWork Flag that indicates that there is more work to do when set to 1.
6646 + *
6647 + *  @return  0 if OK, non-zero otherwise.
6648 + */
6649 +int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork)
6650 +  {
6651 +  HAL_TCB *CurrentTcb,*LastTcbProcessed,*FirstTcbProcessed;
6652 +  int PacketsServiced;
6653 +  bit32u TxFrameStatus;
6654 +  int base;
6655 +  int TxServiceMax = HalDev->ChData[Ch].TxServiceMax;
6656 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
6657 +
6658 +/*+GSG 030303*//*+GSG 030303*/
6659 +
6660 +  /* load the module base address */
6661 +  base = HalDev->dev_base;
6662 +  
6663 +  /* Handle case of teardown interrupt.  This must be checked at
6664 +     the top of the function rather than the bottom, because
6665 +     the normal data processing can wipe out the completion
6666 +     pointer which is used to determine teardown complete. */
6667 +  if (HalDev->TxTeardownPending[Ch] != 0)
6668 +    {
6669 +        int Ret;
6670 +        
6671 +     Ret = TxTeardownInt(HalDev, Ch, Queue);
6672 +     if (Ret == 0)
6673 +       {                                                              /*+GSG 030303*/
6674 +        *MoreWork = 0; /* bug fix 1/6 */                              /*+GSG 030303*/
6675 +        return (EC_NO_ERRORS);
6676 +       }                                                              /*+GSG 030303*/
6677 +    }
6678 +
6679 +  OsFunc->CriticalOn(); /*  240904 */
6680 +
6681 +  CurrentTcb = HalDev->TxActQueueHead[Ch][Queue];
6682 +  FirstTcbProcessed=CurrentTcb;
6683 +
6684 +  if (CurrentTcb==0)
6685 +    {
6686 +     /* I saw this error a couple of times when multi-channels were added */
6687 +     dbgPrintf("[cppi TxInt()]TxH int with no TCB in queue!\n");
6688 +     dbgPrintf("              Ch=%d, CurrentTcb = 0x%08x\n", Ch, (bit32u)CurrentTcb);
6689 +     dbgPrintf("              HalDev = 0x%08x\n", (bit32u)HalDev);
6690 +     osfuncSioFlush();
6691 +     OsFunc->CriticalOff(); 
6692 +     return(EC_CPPI|EC_FUNC_TXINT|EC_VAL_NULL_TCB);
6693 +    }
6694 +
6695 +  osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16);
6696 +  TxFrameStatus=CurrentTcb->mode;
6697 +  PacketsServiced=0;
6698 +
6699 +  /* should the ownership bit check be inside of the loop?? could make it a
6700 +     while-do loop and take this check away */
6701 +  if ((TxFrameStatus&CB_OWNERSHIP_BIT)==0)
6702 +    {
6703 +    do
6704 +      {
6705 +      /* Pop TCB(s) for packet from the stack */
6706 +      LastTcbProcessed=CurrentTcb->Eop;
6707 +
6708 +      /* new location for acknowledge */
6709 +      /* Write the completion pointer */
6710 +      (CPMAC_TX_INT_ACK( base , Ch ))  = VirtToPhys(LastTcbProcessed) - HalDev->offset;
6711 +
6712 +      HalDev->TxActQueueHead[Ch][Queue] = LastTcbProcessed->Next;
6713 +
6714 +/*+GSG 030303*//*+GSG 030303*/
6715 +
6716 +      osfuncDataCacheHitInvalidate((void *)LastTcbProcessed, 16);
6717 +
6718 +      if (LastTcbProcessed->mode&CB_EOQ_BIT)
6719 +        {
6720 +         if (LastTcbProcessed->Next)
6721 +           {
6722 +            /* Misqueued packet */
6723 +
6724 +               (CPMAC_TX_HDP( base , Ch ))  = LastTcbProcessed->HNext;
6725 +
6726 +           }
6727 +          else
6728 +           {
6729 +       /* Tx End of Queue */
6730 +
6731 +            HalDev->TxActive[Ch][Queue]=FALSE;
6732 +           }
6733 +        }
6734 +
6735 +      OsFunc->SendComplete(CurrentTcb->OsInfo);
6736 +
6737 +      /* Push Tcb(s) back onto the stack */
6738 +      CurrentTcb = LastTcbProcessed->Next;
6739 +
6740 +      LastTcbProcessed->Next=HalDev->TcbPool[Ch][Queue];
6741 +
6742 +      HalDev->TcbPool[Ch][Queue]=FirstTcbProcessed;
6743 +
6744 +      PacketsServiced++;
6745 +
6746 +      TxFrameStatus=CB_OWNERSHIP_BIT;
6747 +      /* set the first(SOP) pointer for the next packet */
6748 +      FirstTcbProcessed = CurrentTcb;
6749 +      if (CurrentTcb)
6750 +        {
6751 +         osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16);
6752 +         TxFrameStatus=CurrentTcb->mode;
6753 +        }
6754 +
6755 +      }while(((TxFrameStatus&CB_OWNERSHIP_BIT)==0)
6756 +             &&(PacketsServiced<TxServiceMax));
6757 +
6758 +    if (((TxFrameStatus&CB_OWNERSHIP_BIT)==0)
6759 +             &&(PacketsServiced==TxServiceMax))
6760 +      {
6761 +       *MoreWork = 1;
6762 +      }
6763 +     else
6764 +      {
6765 +       *MoreWork = 0;
6766 +      }
6767 +    }
6768 +    OsFunc->CriticalOff(); 
6769 +
6770 +  return(EC_NO_ERRORS);
6771 +  }
6772 +
6773 +/**
6774 + *  @ingroup CPHAL_Functions
6775 + *  This function performs a teardown for the given channel.  The value of the
6776 + *  Mode parameter controls the operation of the function, as documented below.
6777 + *
6778 + *  Note: If bit 3 of Mode is set, this call is blocking, and will not return
6779 + *  until the teardown interrupt has occurred and been processed. While waiting
6780 + *  for a blocking teardown to complete, ChannelTeardown() will signal the OS
6781 + *  (via Control(.."Sleep"..)) to allow the OS to perform other tasks if
6782 + *  necessary.  If and only if bit 3 of Mode is clear, the CPHAL will call the
6783 + *  OS TeardownComplete() function to indicate that the teardown has completed.
6784 + *
6785 + *  @param   HalDev  CPHAL module instance. (set by xxxInitModule())
6786 + *  @param   Ch      Channel number.
6787 + *  @param   Mode    Bit 0 (LSB): Perform Tx teardown (if set).<BR>
6788 + *                   Bit 1: Perform Rx teardown (if set). <BR>
6789 + *                   Bit 2: If set, perform full teardown (free buffers/descriptors).
6790 + *                          If clear, perform partial teardown (keep buffers). <BR>
6791 + *                   Bit 3 (MSB): If set, call is blocking.
6792 + *                            If clear, call is non-blocking.
6793 + *
6794 + *  @return  EC_NO_ERRORS (ok). <BR>
6795 + *           Possible Error Codes:<BR>
6796 + *           @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR>
6797 + *           @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"<BR>
6798 + *           @ref EC_VAL_TX_TEARDOWN_ALREADY_PEND "EC_VAL_TX_TEARDOWN_ALREADY_PEND"<BR>
6799 + *           @ref EC_VAL_RX_TEARDOWN_ALREADY_PEND "EC_VAL_RX_TEARDOWN_ALREADY_PEND"<BR>
6800 + *           @ref EC_VAL_TX_CH_ALREADY_TORNDOWN "EC_VAL_TX_CH_ALREADY_TORNDOWN"<BR>
6801 + *           @ref EC_VAL_RX_CH_ALREADY_TORNDOWN "EC_VAL_RX_CH_ALREADY_TORNDOWN"<BR>
6802 + *           @ref EC_VAL_TX_TEARDOWN_TIMEOUT "EC_VAL_TX_TEARDOWN_TIMEOUT"<BR>
6803 + *           @ref EC_VAL_RX_TEARDOWN_TIMEOUT "EC_VAL_RX_TEARDOWN_TIMEOUT"<BR>
6804 + *           @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"<BR>
6805 + */
6806 +static int halChannelTeardown(HAL_DEVICE *HalDev, int Ch, bit32 Mode)
6807 +  {
6808 +   int DoTx, DoRx, Sleep=2048, timeout=0;                         /*MJH~030306*/
6809 +   bit32u base = HalDev->dev_base;
6810 +
6811 +/* Set the module, used for error returns */
6812 +
6813 +   DoTx = (Mode & TX_TEARDOWN);
6814 +   DoRx = (Mode & RX_TEARDOWN);
6815 +
6816 +   if (HalDev->State < enInitialized)
6817 +     return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_STATE);
6818 +
6819 +   if ((Ch < 0) || (Ch > (MAX_CHAN-1) ))
6820 +     {
6821 +     return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_CH);
6822 +     }
6823 +
6824 +   /* set teardown pending bits before performing the teardown, because they
6825 +      will be used in the int handler (this is done for AAL5) */
6826 +   if (DoTx)
6827 +     {
6828 +      if (HalDev->TxTeardownPending[Ch] != 0)
6829 +        return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_ALREADY_PEND);
6830 +
6831 +      /* If a full teardown, this also means that the user must
6832 +      setup all channels again to use them */
6833 +      if (Mode & FULL_TEARDOWN)
6834 +        HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0;
6835 +
6836 +      if (HalDev->State < enOpened)
6837 +        {
6838 +         /* if the hardware has never been opened, the channel has never actually
6839 +         been setup in the hardware, so I just need to reset the software flag
6840 +         and leave */
6841 +         HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0;
6842 +         return (EC_NO_ERRORS);
6843 +    }
6844 +       else
6845 +    {
6846 +         if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0)
6847 +       {
6848 +            return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_CH_ALREADY_TORNDOWN);
6849 +       }
6850 +
6851 +         /* set teardown flag */
6852 +         HalDev->TxTeardownPending[Ch] = Mode;
6853 +    }
6854 +     }
6855 +
6856 +   if (DoRx)
6857 +     {
6858 +      if (HalDev->RxTeardownPending[Ch] != 0)
6859 +        return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_ALREADY_PEND);
6860 +
6861 +      if (Mode & FULL_TEARDOWN)
6862 +        HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0;
6863 +
6864 +      if (HalDev->State < enOpened)
6865 +        {
6866 +         HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0;
6867 +         return (EC_NO_ERRORS);
6868 +    }
6869 +       else
6870 +    {
6871 +         if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == 0)
6872 +           return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_CH_ALREADY_TORNDOWN);
6873 +
6874 +         HalDev->RxTeardownPending[Ch] = Mode;
6875 +    }
6876 +     }
6877 +
6878 +   /* Perform Tx Teardown Duties */
6879 +   if ((DoTx) && (HalDev->State == enOpened))
6880 +     {
6881 +      /* Request TX channel teardown */
6882 +      (CPMAC_TX_TEARDOWN( base ))  = Ch;
6883 +
6884 +      /* wait until teardown has completed */
6885 +      if (Mode & BLOCKING_TEARDOWN)
6886 +        {
6887 +     timeout = 0;
6888 +         while (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE)
6889 +       {
6890 +            osfuncSleep(&Sleep);
6891 +
6892 +            timeout++;
6893 +        if (timeout > 100000)
6894 +          {
6895 +               return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_TIMEOUT);
6896 +          }
6897 +       }
6898 +    }
6899 +     } /* if DoTx */
6900 +
6901 +   /* Perform Rx Teardown Duties */
6902 +   if ((DoRx) && (HalDev->State == enOpened))
6903 +     {
6904 +
6905 +      /* perform CPMAC specific RX channel teardown */
6906 +      CPMAC_RX_TEARDOWN(base) = Ch;
6907 +
6908 +      if (Mode & BLOCKING_TEARDOWN)
6909 +        {
6910 +     timeout = 0;
6911 +         while (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE)
6912 +       {
6913 +            osfuncSleep(&Sleep);
6914 +
6915 +            timeout++;
6916 +        if (timeout > 100000)
6917 +          {
6918 +               return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_TIMEOUT);
6919 +          }
6920 +       }
6921 +        }
6922 +     } /* if DoRx */
6923 +
6924 +   return (EC_NO_ERRORS);
6925 +  }
6926 +
6927 +/**
6928 + *  @ingroup CPHAL_Functions
6929 + *  This function closes the CPHAL module.  The module will be reset.
6930 + *  The Mode parameter should be used to determine the actions taken by
6931 + *  Close().
6932 + *
6933 + *  @param   HalDev   CPHAL module instance. (set by xxxInitModule())
6934 + *  @param   Mode     Indicates actions to take on close.  The following integer
6935 + *                    values are valid: <BR>
6936 + *                    1:  Does not free buffer resources, init parameters remain
6937 + *                        intact.  User can then call Open() without calling Init()
6938 + *                        to attempt to reset the device and bring it back to the
6939 + *                        last known state.<BR>
6940 + *                    2:  Frees the buffer resources, but keeps init parameters.  This
6941 + *                        option is a more aggressive means of attempting a device reset.
6942 + *                    3:  Frees the buffer resources, and clears all init parameters. <BR>
6943 + *                        At this point, the caller would have to call to completely
6944 + *                        reinitialize the device (Init()) before being able to call
6945 + *                        Open().  Use this mode if you are shutting down the module
6946 + *                        and do not plan to restart.
6947 + *
6948 + *  @return  EC_NO_ERRORS (ok).<BR>
6949 + *           Possible Error Codes:<BR>
6950 + *           @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR>
6951 + *           Any error code from halChannelTeardown().<BR>
6952 + */
6953 +static int halClose(HAL_DEVICE *HalDev, bit32 Mode)
6954 +  {
6955 +   int Ch, Inst, Ret;
6956 +   OS_DEVICE *TmpOsDev;
6957 +   OS_FUNCTIONS *TmpOsFunc;
6958 +   HAL_FUNCTIONS *TmpHalFunc;
6959 +   char *TmpDeviceInfo;
6960 +
6961 +   int Ticks;                                                     /*MJH~030306*/
6962 +
6963 +   /* Verify proper device state */
6964 +   if (HalDev->State != enOpened)
6965 +     return (EC_CPMAC  | EC_FUNC_CLOSE|EC_VAL_INVALID_STATE);
6966 +
6967 +   /* Teardown all open channels */
6968 +   for (Ch = 0; Ch <= (MAX_CHAN-1) ; Ch++)
6969 +     {
6970 +      if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE)
6971 +        {
6972 +         if (Mode == 1)
6973 +           {
6974 +            Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN);
6975 +            if (Ret) return (Ret);
6976 +           }
6977 +          else
6978 +           {
6979 +            Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN);
6980 +            if (Ret) return (Ret);
6981 +           }
6982 +        }
6983 +
6984 +      if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE)
6985 +        {
6986 +         if (Mode == 1)
6987 +           {
6988 +            Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN);
6989 +            if (Ret) return (Ret);
6990 +           }
6991 +          else
6992 +           {
6993 +            Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN);
6994 +            if (Ret) return (Ret);
6995 +           }
6996 +        }
6997 +     }
6998 +
6999 +   /* free fraglist in HalDev */
7000 +   HalDev->OsFunc->Free(HalDev->fraglist);
7001 +   HalDev->fraglist = 0;
7002 +
7003 +   /* unregister the interrupt */
7004 +   HalDev->OsFunc->IsrUnRegister(HalDev->OsDev, HalDev->interrupt);
7005 +
7006 +   Ticks = 0;    /* Disable Tick Timer */                           /*MJH+030306*/
7007 +   HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcClear, &Ticks); /*MJH+030306*/
7008 +
7009 +   /* Free the Phy Information Structure */
7010 +   if(HalDev->PhyDev)
7011 +   {
7012 +      HalDev->OsFunc->Free(HalDev->PhyDev);                               /*MJH+030513*/
7013 +      HalDev->PhyDev = 0;                                         /*MJH+030522*/
7014 +   }
7015 +
7016 +   /* Perform CPMAC specific closing functions */
7017 +   CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN;
7018 +   CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN;
7019 +   CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN;
7020 +
7021 +   /* put device back into reset */
7022 +   (*(volatile bit32u *)(HalDev->ResetBase)) &=~ (1<<HalDev->ResetBit);
7023 +   Ticks = 64;                                                    /*MJH~030306*/
7024 +   osfuncSleep(&Ticks);
7025 +
7026 +   /* If mode is 3, than clear the HalDev and set next state to DevFound*/
7027 +   if (Mode == 3)
7028 +     {
7029 +      /* I need to keep the HalDev parameters that were setup in InitModule */
7030 +      TmpOsDev = HalDev->OsDev;
7031 +      TmpOsFunc = HalDev->OsFunc;
7032 +      TmpDeviceInfo = HalDev->DeviceInfo;
7033 +
7034 +      TmpHalFunc = HalDev->HalFuncPtr;
7035 +      Inst = HalDev->Inst;
7036 +
7037 +      /* Clear HalDev */
7038 +
7039 +      HalDev->OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE));
7040 +
7041 +      /* Restore key parameters */
7042 +      HalDev->OsDev = TmpOsDev;
7043 +      HalDev->OsFunc = TmpOsFunc;
7044 +      HalDev->DeviceInfo = TmpDeviceInfo;
7045 +
7046 +      HalDev->HalFuncPtr = TmpHalFunc;
7047 +      HalDev->Inst = Inst;
7048 +
7049 +      HalDev->State = enDevFound;
7050 +     }
7051 +    else
7052 +     {
7053 +      HalDev->State = enInitialized;
7054 +     }
7055 +
7056 +   return(EC_NO_ERRORS);
7057 +  }
7058 diff -urN linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c
7059 --- linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c       1970-01-01 01:00:00.000000000 +0100
7060 +++ linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c       2005-07-12 02:48:42.049593000 +0200
7061 @@ -0,0 +1,28 @@
7062 +#ifndef _INC_CPREMAP_C
7063 +#define _INC_CPREMAP_C
7064 +
7065 +#ifdef __ADAM2
7066 +static inline void osfuncDataCacheHitInvalidate(void *ptr, int Size)
7067 +  {
7068 +  asm(" cache  17, (%0)" : : "r" (ptr));
7069 +  }
7070 +
7071 +static inline void osfuncDataCacheHitWriteback(void *ptr, int Size)
7072 +  { 
7073 +  asm(" cache  25, (%0)" : : "r" (ptr));
7074 +  }
7075 +  
7076 +static inline void osfuncDataCacheHitWritebackAndInvalidate(void *ptr, int Size)
7077 +  { 
7078 +  asm(" cache  21, (%0)" : : "r" (ptr));
7079 +  }
7080 +
7081 +#else
7082 +
7083 +#define osfuncDataCacheHitInvalidate(MemPtr, Size)               __asm__(" .set mips3; cache  17, (%0); .set mips0" : : "r" (MemPtr))
7084 +#define osfuncDataCacheHitWritebackAndInvalidate(MemPtr, Size)   __asm__(" .set mips3; cache  21, (%0); .set mips0" : : "r" (MemPtr))
7085 +#define osfuncDataCacheHitWriteback(MemPtr, Size)                __asm__(" .set mips3; cache  25, (%0); .set mips0" : : "r" (MemPtr))      
7086 +            
7087 +#endif
7088 +
7089 +#endif
7090 diff -urN linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h
7091 --- linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h       1970-01-01 01:00:00.000000000 +0100
7092 +++ linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h       2005-07-12 02:48:42.050593000 +0200
7093 @@ -0,0 +1,632 @@
7094 +/************************************************************************
7095 + *  TNETDxxxx Software Support
7096 + *  Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved.
7097 + *
7098 + *  FILE: cphal.h
7099 + *
7100 + *  DESCRIPTION:
7101 + *      User include file, contains data definitions shared between the CPHAL
7102 + *      and the upper-layer software.
7103 + *
7104 + *  HISTORY:
7105 + *      Date      Modifier  Ver    Notes
7106 + *      28Feb02   Greg      1.00   Original
7107 + *      06Mar02   Greg      1.01   Documentation enhanced
7108 + *      18Jul02   Greg      1.02   Many updates (OAM additions, general reorg)
7109 + *      22Nov02   Mick      RC2    Additions from Denis' input on Control
7110 + *
7111 + *  author  Greg Guyotte
7112 + *  version 1.02
7113 + *  date    18-Jul-2002
7114 + *****************************************************************************/
7115 +#ifndef _INC_CPHAL_H
7116 +#define _INC_CPHAL_H
7117 +
7118 +#ifdef _CPHAL_CPMAC
7119 +#include "ec_errors_cpmac.h"
7120 +#endif
7121 +
7122 +#ifdef _CPHAL_AAL5
7123 +#include "ec_errors_cpaal5.h"
7124 +#endif
7125 +
7126 +#ifdef _CPHAL_CPSAR
7127 +#include "ec_errors_cpsar.h"
7128 +#endif
7129 +
7130 +#ifdef _CPHAL_AAL2
7131 +#include "ec_errors_cpaal2.h"
7132 +#endif
7133 +
7134 +#ifndef __ADAM2
7135 +typedef char           bit8;
7136 +typedef short          bit16;
7137 +typedef int            bit32;
7138 +
7139 +typedef unsigned char  bit8u;
7140 +typedef unsigned short bit16u;
7141 +typedef unsigned int   bit32u;
7142 +
7143 +/*
7144 +typedef char           INT8;
7145 +typedef short          INT16;
7146 +typedef int            INT32;
7147 +typedef unsigned char  UINT8;
7148 +typedef unsigned short UINT16;
7149 +typedef unsigned int   UINT32;
7150 +*/
7151 +/*typedef unsigned int   size_t;*/
7152 +#endif
7153 +
7154 +#ifdef _CPHAL
7155 +
7156 +#ifndef TRUE
7157 +#define TRUE (1==1)
7158 +#endif
7159 +
7160 +#ifndef FALSE
7161 +#define FALSE (1==2)
7162 +#endif
7163 +
7164 +#ifndef NULL
7165 +#define NULL 0
7166 +#endif
7167 +
7168 +#endif
7169 +
7170 +#define        VirtToPhys(a)                 (((int)a)&~0xe0000000)
7171 +#define        VirtToVirtNoCache(a)          ((void*)((VirtToPhys(a))|0xa0000000))
7172 +#define        VirtToVirtCache(a)            ((void*)((VirtToPhys(a))|0x80000000))
7173 +#define        PhysToVirtNoCache(a)          ((void*)(((int)a)|0xa0000000))
7174 +#define        PhysToVirtCache(a)            ((void*)(((int)a)|0x80000000))
7175 +/*
7176 +#define        DataCacheHitInvalidate(a)     {__asm__(" cache  17, (%0)" :   : "r" (a));}
7177 +#define        DataCacheHitWriteback(a)      {__asm__(" cache  25, (%0)" :   : "r" (a));}
7178 +*/
7179 +
7180 +#define PARTIAL 1     /**< Used in @c Close() and @c ChannelTeardown() */
7181 +#define FULL 2        /**< Used in @c Close() and @c ChannelTeardown() */
7182 +
7183 +/* Channel Teardown Defines */
7184 +#define RX_TEARDOWN 2
7185 +#define TX_TEARDOWN 1
7186 +#define BLOCKING_TEARDOWN 8
7187 +#define FULL_TEARDOWN 4
7188 +#define PARTIAL_TEARDOWN 0
7189 +
7190 +#define MAX_DIR 2
7191 +#define DIRECTION_TX 0
7192 +#define DIRECTION_RX 1
7193 +#define TX_CH 0
7194 +#define RX_CH 1
7195 +#define HAL_ERROR_DEVICE_NOT_FOUND    1
7196 +#define HAL_ERROR_FAILED_MALLOC       2
7197 +#define HAL_ERROR_OSFUNC_SIZE         3
7198 +#define HAL_DEFAULT  0xFFFFFFFF
7199 +#define VALID(val)    (val!=HAL_DEFAULT)
7200 +
7201 +/*
7202 +ERROR REPORTING
7203 +
7204 +HAL Module Codes.  Each HAL module reporting an error code
7205 +should OR the error code with the respective Module error code
7206 +from the list below.
7207 +*/
7208 +#define EC_AAL5                                EC_HAL|EC_DEV_AAL5
7209 +#define EC_AAL2                                EC_HAL|EC_DEV_AAL2
7210 +#define EC_CPSAR                               EC_HAL|EC_DEV_CPSAR
7211 +#define EC_CPMAC                               EC_HAL|EC_DEV_CPMAC
7212 +#define EC_VDMA                                EC_HAL|EC_DEV_VDMA
7213 +#define EC_VLYNQ                               EC_HAL|EC_DEV_VLYNQ
7214 +#define EC_CPPI                                EC_HAL|EC_DEV_CPPI
7215 +
7216 +/*
7217 +HAL Function Codes.  Each HAL module reporting an error code
7218 +should OR the error code with one of the function codes from
7219 +the list below.
7220 +*/
7221 +#define EC_FUNC_HAL_INIT                       EC_FUNC(1)
7222 +#define EC_FUNC_CHSETUP                        EC_FUNC(2)
7223 +#define EC_FUNC_CHTEARDOWN                     EC_FUNC(3)
7224 +#define EC_FUNC_RXRETURN                       EC_FUNC(4)
7225 +#define EC_FUNC_SEND                           EC_FUNC(5)
7226 +#define EC_FUNC_RXINT                          EC_FUNC(6)
7227 +#define EC_FUNC_TXINT                          EC_FUNC(7)
7228 +#define EC_FUNC_AAL2_VDMA                      EC_FUNC(8)
7229 +#define EC_FUNC_OPTIONS                        EC_FUNC(9)
7230 +#define EC_FUNC_PROBE                          EC_FUNC(10)
7231 +#define EC_FUNC_OPEN                           EC_FUNC(11)
7232 +#define EC_FUNC_CONTROL                        EC_FUNC(12)
7233 +#define EC_FUNC_DEVICE_INT                     EC_FUNC(13)
7234 +#define EC_FUNC_STATUS                         EC_FUNC(14)
7235 +#define EC_FUNC_TICK                           EC_FUNC(15)
7236 +#define EC_FUNC_CLOSE                          EC_FUNC(16)
7237 +#define EC_FUNC_SHUTDOWN                       EC_FUNC(17)
7238 +#define EC_FUNC_DEVICE_INT_ALT                 EC_FUNC(18) /* +GSG 030306 */
7239 +
7240 +/*
7241 +HAL Error Codes.  The list below defines every type of error
7242 +used in all HAL modules. DO NOT CHANGE THESE VALUES!  Add new
7243 +values in integer order to the bottom of the list.
7244 +*/
7245 +#define EC_VAL_PDSP_LOAD_FAIL                 EC_ERR(0x01)|EC_CRITICAL
7246 +#define EC_VAL_FIRMWARE_TOO_LARGE             EC_ERR(0x02)|EC_CRITICAL
7247 +#define EC_VAL_DEVICE_NOT_FOUND               EC_ERR(0x03)|EC_CRITICAL
7248 +#define EC_VAL_BASE_ADDR_NOT_FOUND            EC_ERR(0x04)|EC_CRITICAL
7249 +#define EC_VAL_RESET_BIT_NOT_FOUND            EC_ERR(0x05)|EC_CRITICAL
7250 +#define EC_VAL_CH_INFO_NOT_FOUND              EC_ERR(0x06)
7251 +#define EC_VAL_RX_STATE_RAM_NOT_CLEARED       EC_ERR(0x07)|EC_CRITICAL
7252 +#define EC_VAL_TX_STATE_RAM_NOT_CLEARED       EC_ERR(0x08)|EC_CRITICAL
7253 +#define EC_VAL_MALLOC_DEV_FAILED              EC_ERR(0x09)
7254 +#define EC_VAL_OS_VERSION_NOT_SUPPORTED       EC_ERR(0x0A)|EC_CRITICAL
7255 +#define EC_VAL_CPSAR_VERSION_NOT_SUPPORTED    EC_ERR(0x0B)|EC_CRITICAL
7256 +#define EC_VAL_NULL_CPSAR_DEV                 EC_ERR(0x0C)|EC_CRITICAL
7257 +
7258 +#define EC_VAL_LUT_NOT_READY                  EC_ERR(0x0D)
7259 +#define EC_VAL_INVALID_CH                     EC_ERR(0x0E)
7260 +#define EC_VAL_NULL_CH_STRUCT                 EC_ERR(0x0F)
7261 +#define EC_VAL_RX_TEARDOWN_ALREADY_PEND       EC_ERR(0x10)
7262 +#define EC_VAL_TX_TEARDOWN_ALREADY_PEND       EC_ERR(0x11)
7263 +#define EC_VAL_RX_CH_ALREADY_TORNDOWN         EC_ERR(0x12)
7264 +#define EC_VAL_TX_CH_ALREADY_TORNDOWN         EC_ERR(0x13)
7265 +#define EC_VAL_TX_TEARDOWN_TIMEOUT            EC_ERR(0x14)
7266 +#define EC_VAL_RX_TEARDOWN_TIMEOUT            EC_ERR(0x15)
7267 +#define EC_VAL_CH_ALREADY_TORNDOWN            EC_ERR(0x16)
7268 +#define EC_VAL_VC_SETUP_NOT_READY             EC_ERR(0x17)
7269 +#define EC_VAL_VC_TEARDOWN_NOT_READY          EC_ERR(0x18)
7270 +#define EC_VAL_INVALID_VC                     EC_ERR(0x19)
7271 +#define EC_VAL_INVALID_LC                     EC_ERR(0x20)
7272 +#define EC_VAL_INVALID_VDMA_CH                EC_ERR(0x21)
7273 +#define EC_VAL_INVALID_CID                    EC_ERR(0x22)
7274 +#define EC_VAL_INVALID_UUI                    EC_ERR(0x23)
7275 +#define EC_VAL_INVALID_UUI_DISCARD            EC_ERR(0x24)
7276 +#define EC_VAL_CH_ALREADY_OPEN                EC_ERR(0x25)
7277 +
7278 +#define EC_VAL_RCB_MALLOC_FAILED              EC_ERR(0x26)
7279 +#define EC_VAL_RX_BUFFER_MALLOC_FAILED        EC_ERR(0x27)
7280 +#define EC_VAL_OUT_OF_TCBS                    EC_ERR(0x28)
7281 +#define EC_VAL_NO_TCBS                        EC_ERR(0x29)
7282 +#define EC_VAL_NULL_RCB                       EC_ERR(0x30)|EC_CRITICAL
7283 +#define EC_VAL_SOP_ERROR                      EC_ERR(0x31)|EC_CRITICAL
7284 +#define EC_VAL_EOP_ERROR                      EC_ERR(0x32)|EC_CRITICAL
7285 +#define EC_VAL_NULL_TCB                       EC_ERR(0x33)|EC_CRITICAL
7286 +#define EC_VAL_CORRUPT_RCB_CHAIN              EC_ERR(0x34)|EC_CRITICAL
7287 +#define EC_VAL_TCB_MALLOC_FAILED              EC_ERR(0x35)
7288 +
7289 +#define EC_VAL_DISABLE_POLLING_FAILED         EC_ERR(0x36)
7290 +#define EC_VAL_KEY_NOT_FOUND                  EC_ERR(0x37)
7291 +#define EC_VAL_MALLOC_FAILED                  EC_ERR(0x38)
7292 +#define EC_VAL_RESET_BASE_NOT_FOUND           EC_ERR(0x39)|EC_CRITICAL
7293 +#define EC_VAL_INVALID_STATE                  EC_ERR(0x40)
7294 +#define EC_VAL_NO_TXH_WORK_TO_DO              EC_ERR(0x41)
7295 +#define EC_VAL_NO_TXL_WORK_TO_DO              EC_ERR(0x42)
7296 +#define EC_VAL_NO_RX_WORK_TO_DO               EC_ERR(0x43)
7297 +#define EC_VAL_NOT_LINKED                     EC_ERR(0x44)
7298 +#define EC_VAL_INTERRUPT_NOT_FOUND            EC_ERR(0x45)
7299 +#define EC_VAL_OFFSET_NOT_FOUND               EC_ERR(0x46)
7300 +#define EC_VAL_MODULE_ALREADY_CLOSED          EC_ERR(0x47)
7301 +#define EC_VAL_MODULE_ALREADY_SHUTDOWN        EC_ERR(0x48)
7302 +#define EC_VAL_ACTION_NOT_FOUND               EC_ERR(0x49)
7303 +#define EC_VAL_RX_CH_ALREADY_SETUP            EC_ERR(0x50)
7304 +#define EC_VAL_TX_CH_ALREADY_SETUP            EC_ERR(0x51)
7305 +#define EC_VAL_RX_CH_ALREADY_OPEN             EC_ERR(0x52)
7306 +#define EC_VAL_TX_CH_ALREADY_OPEN             EC_ERR(0x53)
7307 +#define EC_VAL_CH_ALREADY_SETUP               EC_ERR(0x54)
7308 +#define EC_VAL_RCB_NEEDS_BUFFER               EC_ERR(0x55) /* +GSG 030410 */
7309 +#define EC_VAL_RCB_DROPPED                    EC_ERR(0x56) /* +GSG 030410 */
7310 +#define EC_VAL_INVALID_VALUE                  EC_ERR(0x57)
7311 +
7312 +/**
7313 +@defgroup shared_data Shared Data Structures
7314 +
7315 +The data structures documented here are shared by all modules.
7316 +*/
7317 +
7318 +/**
7319 + *  @ingroup shared_data
7320 + *  This is the fragment list structure.  Each fragment list entry contains a
7321 + *  length and a data buffer.
7322 + */
7323 +typedef struct
7324 +  {
7325 +   bit32u   len;    /**< Length of the fragment in bytes (lower 16 bits are valid).  For SOP, upper 16 bits is the buffer offset. */
7326 +   void     *data;  /**< Pointer to fragment data. */
7327 +   void     *OsInfo; /**< Pointer to OS defined data. */
7328 +  }FRAGLIST;
7329 +
7330 +#if defined (_CPHAL_CPMAC)
7331 +#define CB_PASSCRC_BIT     (1<<26)
7332 +
7333 +/* CPMAC CPHAL STATUS */
7334 +#define CPMAC_STATUS_LINK               (1 << 0)
7335 +#define CPMAC_STATUS_LINK_DUPLEX        (1 << 1)  /* 0 - HD, 1 - FD */
7336 +#define CPMAC_STATUS_LINK_SPEED         (1 << 2)  /* 0 - 10, 1 - 100 */
7337 +
7338 +/*   ADAPTER CHECK Codes */
7339 +
7340 +#define CPMAC_STATUS_ADAPTER_CHECK             (1 << 7)
7341 +#define CPMAC_STATUS_HOST_ERR_DIRECTION        (1 << 8)
7342 +#define CPMAC_STATUS_HOST_ERR_CODE             (0xF << 9)
7343 +#define CPMAC_STATUS_HOST_ERR_CH               (0x7 << 13)
7344 +
7345 +#define _CPMDIO_DISABLE                 (1 << 0)
7346 +#define _CPMDIO_HD                      (1 << 1)
7347 +#define _CPMDIO_FD                      (1 << 2)
7348 +#define _CPMDIO_10                      (1 << 3)
7349 +#define _CPMDIO_100                     (1 << 4)
7350 +#define _CPMDIO_NEG_OFF                 (1 << 5)
7351 +#define _CPMDIO_LOOPBK                  (1 << 16)
7352 +#define _CPMDIO_AUTOMDIX                (1 << 17)   /* Bit 16 and above not used by MII register */
7353 +#define _CPMDIO_NOPHY                   (1 << 20)
7354 +#endif
7355 +
7356 +/**
7357 + *  @ingroup shared_data
7358 + *  Channel specific configuration information.  This structure should be
7359 + *  populated by upper-layer software prior to calling @c ChannelSetup().  Any
7360 + *  configuration item that can be changed on a per channel basis should
7361 + *  be represented here.  Each module may define this structure with additional
7362 + *  module-specific members.
7363 + */
7364 +typedef struct
7365 +  {
7366 +   int Channel;        /**< Channel number. */
7367 +   int Direction;      /**< DIRECTION_RX(1) or DIRECTION_TX(0). */
7368 +   OS_SETUP *OsSetup;  /**< OS defined information associated with this channel. */
7369 +
7370 +#if defined(_CPHAL_AAL5) || defined (_CPHAL_CPSAR) || defined (_CPHAL_CPMAC)
7371 +   int RxBufSize;      /**< Size (in bytes) for each Rx buffer.*/
7372 +   int RxBufferOffset; /**< Number of bytes to offset rx data from start of buffer (must be less than buffer size). */
7373 +   int RxNumBuffers;   /**< The number of Rx buffer descriptors to allocate for Ch. */
7374 +   int RxServiceMax;   /**< Maximum number of packets to service at one time. */
7375 +
7376 +   int TxNumBuffers;   /**< The number of Tx buffer descriptors to allocate for Ch. */
7377 +   int TxNumQueues;    /**< Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. */
7378 +   int TxServiceMax;   /**< Maximum number of packets to service at one time. */
7379 +#endif
7380 +
7381 +#if defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR)
7382 +   int CpcsUU;      /**< The 2-byte CPCS UU and CPI information. */
7383 +   int Gfc;         /**< Generic Flow Control. */
7384 +   int Clp;         /**< Cell Loss Priority. */
7385 +   int Pti;         /**< Payload Type Indication. */
7386 +#endif
7387 +
7388 +#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR)
7389 +   int DaMask;      /**< Specifies whether credit issuance is paused when Tx data not available. */
7390 +   int Priority;    /**< Priority bin this channel will be scheduled within. */
7391 +   int PktType;     /**< 0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. */
7392 +   int Vci;         /**< Virtual Channel Identifier. */
7393 +   int Vpi;         /**< Virtual Path Identifier. */
7394 +   int FwdUnkVc;    /**< Enables forwarding of unknown VCI/VPI cells to host. 1=enable, 0=disable. */
7395 +
7396 +   /* Tx VC State */
7397 +   int TxVc_CellRate;  /**< Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). */
7398 +   int TxVc_QosType;   /**< 0=CBR,1=VBR,2=UBR,3=UBRmcr. */
7399 +   int TxVc_Mbs;       /**< Min Burst Size in cells.*/
7400 +   int TxVc_Pcr;       /**< Peak Cell Rate for VBR in clock ticks between transmissions. */
7401 +
7402 +   bit32 TxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Tx Ch (must be big endian with 0 PTI). */
7403 +   int TxVc_OamTc;     /**< TC Path to transmit OAM cells for TX connection (0,1). */
7404 +   int TxVc_VpOffset;  /**< Offset to the OAM VP state table. */
7405 +   /* Rx VC State */
7406 +   int RxVc_OamCh;     /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */
7407 +   int RxVc_OamToHost; /**< 0=do not pass, 1=pass. */
7408 +   bit32 RxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx conn (must be big endian with 0 PTI). */
7409 +   int RxVc_OamTc;     /**< TC Path to transmit OAM cells for RX connection (0,1). */
7410 +   int RxVc_VpOffset;  /**< Offset to the OAM VP state table. */
7411 +   /* Tx VP State */
7412 +   int TxVp_OamTc;     /**< TC Path to transmit OAM cells for TX VP connection (0,1). */
7413 +   bit32 TxVp_AtmHeader; /**< ATM Header placed on firmware gen'd VP OAM cells for this Tx VP conn (must be big endian with 0 VCI). */
7414 +   /* Rx VP State  */
7415 +   int RxVp_OamCh;     /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */
7416 +   int RxVp_OamToHost; /**< 0=do not pass, 1=pass. */
7417 +   bit32 RxVp_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx VP conn (must be big endian with 0 VCI). */
7418 +   int RxVp_OamTc;     /**< TC Path to transmit OAM cells for RX VP connection (0,1). */
7419 +   int RxVp_OamVcList; /**< Indicates all VC channels associated with this VP channel (one-hot encoded). */
7420 +#endif
7421 +
7422 +
7423 +#ifdef _CPHAL_VDMAVT
7424 +   bit32u RemFifoAddr; /* Mirror mode only. */
7425 +   bit32u FifoAddr;
7426 +   bit32  PollInt;
7427 +   bit32  FifoSize;
7428 +   int    Ready;
7429 +#endif
7430 +
7431 +  }CHANNEL_INFO;
7432 +
7433 +/*
7434 + *  This structure contains each statistic value gathered by the CPHAL.
7435 + *  Applications may access statistics data by using the @c StatsGet() routine.
7436 + */
7437 +/* STATS */
7438 +#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR)
7439 +typedef struct
7440 +  {
7441 +   bit32u CrcErrors[16];
7442 +   bit32u LenErrors[16];
7443 +   bit32u DmaLenErrors[16];
7444 +   bit32u AbortErrors[16];
7445 +   bit32u StarvErrors[16];
7446 +   bit32u TxMisQCnt[16][2];
7447 +   bit32u RxMisQCnt[16];
7448 +   bit32u RxEOQCnt[16];
7449 +   bit32u TxEOQCnt[16][2];
7450 +   bit32u RxPacketsServiced[16];
7451 +   bit32u TxPacketsServiced[16][2];
7452 +   bit32u RxMaxServiced;
7453 +   bit32u TxMaxServiced[16][2];
7454 +   bit32u RxTotal;
7455 +   bit32u TxTotal;
7456 +  } STAT_INFO;
7457 +#endif
7458 +
7459 +/*
7460 + *  VDMA Channel specific configuration information
7461 + */
7462 +#ifdef _CPHAL_AAL2
7463 +typedef struct
7464 +  {
7465 +   int Ch;           /**< Channel Number */
7466 +   int RemoteEndian; /**< Endianness of remote VDMA-VT device */
7467 +   int CpsSwap;      /**< When 0, octet 0 in CPS pkt located in LS byte of 16-bit word sent to rem VDMA device.  When 1, in MS byte. */
7468 +  }VdmaChInfo;
7469 +#endif
7470 +
7471 +#ifndef _CPHAL
7472 +  typedef void HAL_DEVICE;
7473 +  typedef void HAL_PRIVATE;
7474 +  typedef void HAL_RCB;
7475 +  typedef void HAL_RECEIVEINFO;
7476 +#endif
7477 +
7478 +/**
7479 + *  @ingroup shared_data
7480 + *  The HAL_FUNCTIONS struct defines the function pointers used by upper layer
7481 + *  software.  The upper layer software receives these pointers through the
7482 + *  call to xxxInitModule().
7483 + */
7484 +typedef struct
7485 +  {
7486 +  int  (*ChannelSetup)    (HAL_DEVICE *HalDev, CHANNEL_INFO *Channel, OS_SETUP *OsSetup);
7487 +  int  (*ChannelTeardown) (HAL_DEVICE *HalDev, int Channel, int Mode);
7488 +  int  (*Close)           (HAL_DEVICE *HalDev, int Mode);
7489 +  int  (*Control)         (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value);
7490 +  int  (*Init)            (HAL_DEVICE *HalDev);
7491 +  int  (*Open)            (HAL_DEVICE *HalDev);
7492 +  int  (*PacketProcessEnd) (HAL_DEVICE *HalDev);
7493 +  int  (*Probe)           (HAL_DEVICE *HalDev);
7494 +  int  (*RxReturn)        (HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag);
7495 +  int  (*Send)            (HAL_DEVICE *HalDev, FRAGLIST *FragList, int FragCount, int PacketSize, OS_SENDINFO *OsSendInfo, bit32u Mode);
7496 +  int  (*Shutdown)        (HAL_DEVICE *HalDev);
7497 +  int  (*Tick)            (HAL_DEVICE *HalDev);
7498 +
7499 +#ifdef _CPHAL_AAL5
7500 +  int  (*Kick) (HAL_DEVICE *HalDev, int Queue);
7501 +  void (*OamFuncConfig)   (HAL_DEVICE *HalDev, unsigned int OamConfig);
7502 +  void (*OamLoopbackConfig)   (HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag);
7503 +  volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset);
7504 +  STAT_INFO*  (*StatsGetOld)(HAL_DEVICE *HalDev);
7505 +#endif
7506 +  } HAL_FUNCTIONS;
7507 +
7508 +/**
7509 + *  @ingroup shared_data
7510 + *  The OS_FUNCTIONS struct defines the function pointers for all upper layer
7511 + *  functions accessible to the CPHAL.  The upper layer software is responsible
7512 + *  for providing the correct OS-specific implementations for the following
7513 + *  functions. It is populated by calling InitModule() (done by the CPHAL in
7514 + *  xxxInitModule().
7515 + */
7516 +typedef struct
7517 +  {
7518 +  int   (*Control)(OS_DEVICE *OsDev, const char *Key, const char *Action, void *Value);
7519 +  void  (*CriticalOn)(void);
7520 +  void  (*CriticalOff)(void);
7521 +  void  (*DataCacheHitInvalidate)(void *MemPtr, int Size);
7522 +  void  (*DataCacheHitWriteback)(void *MemPtr, int Size);
7523 +  int   (*DeviceFindInfo)(int Inst, const char *DeviceName, void *DeviceInfo);
7524 +  int   (*DeviceFindParmUint)(void *DeviceInfo, const char *Parm, bit32u *Value);
7525 +  int   (*DeviceFindParmValue)(void *DeviceInfo, const char *Parm, void *Value);
7526 +  void  (*Free)(void *MemPtr);
7527 +  void  (*FreeRxBuffer)(OS_RECEIVEINFO *OsReceiveInfo, void *MemPtr);
7528 +  void  (*FreeDev)(void *MemPtr);
7529 +  void  (*FreeDmaXfer)(void *MemPtr);
7530 +  void  (*IsrRegister)(OS_DEVICE *OsDev, int (*halISR)(HAL_DEVICE*, int*), int InterruptBit);
7531 +  void  (*IsrUnRegister)(OS_DEVICE *OsDev, int InterruptBit);
7532 +  void* (*Malloc)(bit32u size);
7533 +  void* (*MallocDev)(bit32u Size);
7534 +  void* (*MallocDmaXfer)(bit32u size, void *MemBase, bit32u MemRange);
7535 +  void* (*MallocRxBuffer)(bit32u size, void *MemBase, bit32u MemRange,
7536 +                       OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo,
7537 +                       OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev);
7538 +  void* (*Memset)(void *Dest, int C, bit32u N);
7539 +  int   (*Printf)(const char *Format, ...);
7540 +  int   (*Receive)(OS_DEVICE *OsDev,FRAGLIST *FragList,bit32u FragCount,
7541 +                 bit32u PacketSize,HAL_RECEIVEINFO *HalReceiveInfo, bit32u Mode);
7542 +  int   (*SendComplete)(OS_SENDINFO *OsSendInfo);
7543 +  int   (*Sprintf)(char *S, const char *Format, ...);
7544 +  int   (*Strcmpi)(const char *Str1, const char *Str2);
7545 +  unsigned int (*Strlen)(const char *S);
7546 +  char* (*Strstr)(const char *S1, const char *S2);
7547 +  unsigned long  (*Strtoul)(const char *Str, char **Endptr, int Base);
7548 +  void  (*TeardownComplete)(OS_DEVICE *OsDev, int Ch, int Direction);
7549 +  } OS_FUNCTIONS;
7550 +
7551 +/************** MODULE SPECIFIC STUFF BELOW **************/
7552 +
7553 +#ifdef _CPHAL_CPMAC
7554 +
7555 +/*
7556 +int halCpmacInitModule(HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, int (*osBridgeInitModule)(OS_FUNCTIONS *), void* (*osMallocDev) (bit32u), int *Size, int inst);
7557 +*/
7558 +
7559 +int halCpmacInitModule(HAL_DEVICE **HalDev,
7560 +                 OS_DEVICE *OsDev,
7561 +                 HAL_FUNCTIONS **HalFunc,
7562 +                 OS_FUNCTIONS *OsFunc,
7563 +                 int OsFuncSize,
7564 +                 int *HalFuncSize,
7565 +                 int Inst);
7566 +#endif
7567 +
7568 +#ifdef _CPHAL_AAL5
7569 +/*
7570 + *  @ingroup shared_data
7571 + *  The AAL5_FUNCTIONS struct defines the AAL5 function pointers used by upper layer
7572 + *  software.  The upper layer software receives these pointers through the
7573 + *  call to cphalInitModule().
7574 + */
7575 +/*
7576 +typedef struct
7577 +  {
7578 +  int  (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup);
7579 +  int  (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode);
7580 +  int  (*Close)(HAL_DEVICE *HalDev, int Mode);
7581 +  int  (*Init)(HAL_DEVICE *HalDev);
7582 +  int  (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms);
7583 +  int  (*Open)(HAL_DEVICE *HalDev);
7584 +  int  (*InfoGet)(HAL_DEVICE *HalDev, int Key, void *Value);
7585 +  int  (*Probe)(HAL_DEVICE *HalDev);
7586 +  int  (*RxReturn)(HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag);
7587 +  int  (*Send)(HAL_DEVICE *HalDev,FRAGLIST *FragList,int FragCount,
7588 +                 int PacketSize,OS_SENDINFO *OsSendInfo,int Ch, int Queue,
7589 +                 bit32u Mode);
7590 +  int  (*StatsClear)(HAL_DEVICE *HalDev);
7591 +  STAT_INFO*  (*StatsGet)(HAL_DEVICE *HalDev);
7592 +  int  (*Status)(HAL_DEVICE *HalDev);
7593 +  void (*Tick)(HAL_DEVICE *HalDev);
7594 +  int  (*Kick)(HAL_DEVICE *HalDev, int Queue);
7595 +  volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset);
7596 +  } AAL5_FUNCTIONS;
7597 +*/
7598 +
7599 +int cpaal5InitModule(HAL_DEVICE **HalDev,
7600 +                 OS_DEVICE *OsDev,
7601 +                 HAL_FUNCTIONS **HalFunc,
7602 +                 OS_FUNCTIONS *OsFunc,
7603 +                 int OsFuncSize,
7604 +                 int *HalFuncSize,
7605 +                 int Inst);
7606 +#endif
7607 +
7608 +#ifdef _CPHAL_AAL2
7609 +/**
7610 + *  @ingroup shared_data
7611 + *  The AAL2_FUNCTIONS struct defines the AAL2 function pointers used by upper layer
7612 + *  software.  The upper layer software receives these pointers through the
7613 + *  call to cphalInitModule().
7614 + */
7615 +typedef struct
7616 +  {
7617 +  int  (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup);
7618 +  int  (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode);
7619 +  int  (*Close)(HAL_DEVICE *HalDev, int Mode);
7620 +  int  (*Init)(HAL_DEVICE *HalDev);
7621 +  int  (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms);
7622 +  int  (*Open)(HAL_DEVICE *HalDev);
7623 +  int  (*OptionsGet)(HAL_DEVICE *HalDev, char *Key, bit32u *Value);
7624 +  int  (*Probe)(HAL_DEVICE *HalDev);
7625 +
7626 +  int  (*StatsClear)(HAL_DEVICE *HalDev);
7627 +  STAT_INFO*  (*StatsGet)(HAL_DEVICE *HalDev);
7628 +  int  (*Status)(HAL_DEVICE *HalDev);
7629 +  void (*Tick)(HAL_DEVICE *HalDev);
7630 +  int  (*Aal2UuiMappingSetup)(HAL_DEVICE *HalDev, int VC, int UUI,
7631 +                                    int VdmaCh, int UUIDiscard);
7632 +  int  (*Aal2RxMappingSetup)(HAL_DEVICE *HalDev, int VC, int CID,
7633 +                                   int LC);
7634 +  int  (*Aal2TxMappingSetup)(HAL_DEVICE *HalDev, int VC, int LC, int VdmaCh);
7635 +  int  (*Aal2VdmaChSetup)(HAL_DEVICE *HalDev, bit32u RemVdmaVtAddr,
7636 +                               VdmaChInfo *VdmaCh);
7637 +  volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset);
7638 +  int  (*Aal2ModeChange)(HAL_DEVICE *HalDev, int Vc, int RxCrossMode,
7639 +                           int RxMultiMode, int TxMultiMode, int SchedMode,
7640 +                           int TcCh);
7641 +  void (*Aal2VdmaEnable)(HAL_DEVICE *HalDev, int Ch);
7642 +  int  (*Aal2VdmaDisable)(HAL_DEVICE *HalDev, int Ch);
7643 +  } AAL2_FUNCTIONS;
7644 +
7645 +int cpaal2InitModule(HAL_DEVICE **HalDev,
7646 +                 OS_DEVICE *OsDev,
7647 +                 AAL2_FUNCTIONS **HalFunc,
7648 +                 OS_FUNCTIONS *OsFunc,
7649 +                 int OsFuncSize,
7650 +                 int *HalFuncSize,
7651 +                 int Inst);
7652 +#endif
7653 +
7654 +#ifdef _CPHAL_VDMAVT
7655 +/**
7656 + *  @ingroup shared_data
7657 + *  The VDMA_FUNCTIONS struct defines the HAL function pointers used by upper layer
7658 + *  software.  The upper layer software receives these pointers through the
7659 + *  call to InitModule().
7660 + *
7661 + *  Note that this list is still under definition.
7662 + */
7663 +typedef struct
7664 +  {
7665 +  bit32  (*Init)( HAL_DEVICE *VdmaVtDev);
7666 +    /*  bit32  (*SetupTxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem,
7667 +                  bit32u Addr, bit32u Size, bit32u PollInt);
7668 +    bit32  (*SetupRxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem,
7669 +                  bit32u Addr, bit32u Size, bit32u PollInt); */
7670 +  bit32  (*Tx)(HAL_DEVICE *VdmaVtDev);
7671 +  bit32  (*Rx)(HAL_DEVICE *VdmaVtDev);
7672 +  bit32  (*SetRemoteChannel)(HAL_DEVICE *VdmaVtDev, bit32u RemAddr,
7673 +                         bit32u RemDevID);
7674 +  bit32  (*ClearRxInt)(HAL_DEVICE *VdmaVtDev);
7675 +  bit32  (*ClearTxInt)(HAL_DEVICE *VdmaVtDev);
7676 +  bit32  (*Open)(HAL_DEVICE *VdmaVtDev);
7677 +  bit32  (*Close)(HAL_DEVICE *VdmaVtDev);
7678 +  int    (*Control)         (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value);
7679 +  int    (*ChannelSetup)(HAL_DEVICE *VdmaVtDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup);
7680 +  int    (*ChannelTeardown)(HAL_DEVICE *VdmaVtDev, int Ch, int Mode);
7681 +  int    (*Send)(HAL_DEVICE *VdmaVtDev,FRAGLIST *FragList,int FragCount,
7682 +                 int PacketSize,OS_SENDINFO *OsSendInfo,bit32u Mode);
7683 +  } VDMA_FUNCTIONS;
7684 +
7685 +int VdmaInitModule(HAL_DEVICE **VdmaVt,
7686 +                 OS_DEVICE *OsDev,
7687 +                 VDMA_FUNCTIONS **VdmaVtFunc,
7688 +                 OS_FUNCTIONS *OsFunc,
7689 +                 int OsFuncSize,
7690 +                 int *HalFuncSize,
7691 +                 int Inst);
7692 +#endif
7693 +
7694 +/*
7695 +extern int cphalInitModule(MODULE_TYPE ModuleType, HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc,
7696 +                      int (*osInitModule)(OS_FUNCTIONS *), void* (*osMallocDev)(bit32u),
7697 +                      int *Size, int Inst);
7698 +*/
7699 +
7700 +
7701 +#ifdef _CPHAL_AAL5
7702 +extern const char hcSarFrequency[];
7703 +#endif
7704 +
7705 +#ifdef _CPHAL_CPMAC
7706 +/* following will be common, once 'utl' added */
7707 +extern const char hcClear[];
7708 +extern const char hcGet[];
7709 +extern const char hcSet[];
7710 +extern const char hcTick[];
7711 +
7712 +extern const char hcCpuFrequency[];
7713 +extern const char hcCpmacFrequency[];
7714 +extern const char hcMdioBusFrequency[];
7715 +extern const char hcMdioClockFrequency[];
7716 +extern const char hcCpmacBase[];
7717 +extern const char hcPhyNum[];
7718 +extern const char hcSize[];
7719 +extern const char hcCpmacSize[];
7720 +extern const char hcPhyAccess[];
7721 +extern const char hcMdixMask[];
7722 +extern const char hcMdioMdixSwitch[];
7723 +#endif
7724 +
7725 +#endif  /*  end of _INC_    */
7726 diff -urN linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h
7727 --- linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h   1970-01-01 01:00:00.000000000 +0100
7728 +++ linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h   2005-07-12 02:48:42.050593000 +0200
7729 @@ -0,0 +1,842 @@
7730 +/*****************************************************************************
7731 + *  TNETDxxxx Software Support
7732 + *  Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved.
7733 + *
7734 + *  FILE:
7735 + *
7736 + *  DESCRIPTION:
7737 + *      This file contains documentation for the CPMAC
7738 + *
7739 + *  HISTORY:
7740 + *  @author Michael Hanrahan/Greg Guyotte
7741 + *  @version 1.00
7742 + *  @date    03-Dec-2002
7743 + *****************************************************************************/
7744 +#ifndef _DOX_CPMAC_H
7745 +#define _DOX_CPMAC_H
7746 +/**
7747 +@page CPMAC_Implementation_Details Version
7748 +
7749 +@copydoc CPMAC_Version
7750 +*/
7751 +
7752 +/**
7753 +@page cpmac_intro Introduction
7754 +
7755 +The CPMAC implementation will support 8 channels for transmit and 8 channel for
7756 +receive.  Each of the 8 transmit channels has 1 queue associated with it.  It is
7757 +recommended that only 1 channel is used for @c Receive() per processor.
7758 +*/
7759 +
7760 +/**
7761 +@page cpmac_details API Implementation Details
7762 +@par osReceive
7763 +@p Mode parameter
7764 +- The Upper 16 bits of Mode match Word 3 of the Rx Buffer Descriptor
7765 +
7766 +@par halSend
7767 +@p Mode parameter
7768 +-  Bits 0-7 contain the Channel Number
7769 +-  Bits 8-25 are reserved
7770 +-  Bit  26 - if 0, the CRC will be calculated, if 1 the CRC will be Passed
7771 +-  Bits 27-31 : reserved
7772 +@section cpmac_keys Control Keys
7773 +
7774 +@par StateChange
7775 +CPHAL calls the OS when a state change is detected.
7776 +OS should check the CPMAC Status. See the Control Key 'Status' for more details.
7777 +
7778 +@par Status
7779 +OS calls the CPHAL to obtain Status information. The Returned status is as follows
7780 +
7781 +@par MaxFrags
7782 +The OS may "Set" or "Get" this value.  This defines the maximum
7783 +number of fragments that can be received by the CPMAC Rx port.  The default
7784 +value for CPMAC is 2.  This provides enough space to receive a maximum
7785 +length packet (1,518 bytes) with the default buffer size of 1518 and any
7786 +amount of RxBufferOffset.  If the buffer size is configured to be smaller,
7787 +the OS *MUST* modify this parameter according to the following formula:
7788 +((System Max packet length)/(RxBufSize)) + 1.  (The extra 1 fragment is to
7789 +allow for RxBufferOffset)
7790 +
7791 +@code
7792 +// Following defined in "cpswhal_cpmac.h"
7793 +// CPMAC CPHAL STATUS
7794 +#define CPMAC_STATUS_LINK               (1 << 0)
7795 +#define CPMAC_STATUS_LINK_DUPLEX        (1 << 1)  // 0 - HD, 1 - FD
7796 +#define CPMAC_STATUS_LINK_SPEED         (1 << 2)  // 0 - 10, 1 - 100
7797 +
7798 +// ADAPTER CHECK Codes
7799 +#define CPMAC_STATUS_ADAPTER_CHECK             (1 << 7)
7800 +#define CPMAC_STATUS_HOST_ERR_DIRECTION        (1 << 8)    // 0 - Tx, 1 - Rx
7801 +#define CPMAC_STATUS_HOST_ERR_CODE             (0xF << 9)  See CPMAC Guide
7802 +#define CPMAC_STATUS_HOST_ERR_CH               (0x7 << 13) See CPMAC Guide
7803 +@endcode
7804 +
7805 +@code
7806 +void osStateChange(OS_DEVICE *OsDev)
7807 +  {
7808 +  int status;
7809 +  OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status);
7810 +  if(status & CPMAC_STATUS_ADAPTER_CHECK)
7811 +    {
7812 +    printf("[osStateChange[%d]]  HAL notified OS of AdapterCheck (Link Status 0x%08X)\n", OsDev->port, status);
7813 +    adaptercheck(OsDev->port);
7814 +    }
7815 +  else
7816 +    {
7817 +    printf("[osStateChange[%d]]  HAL notified OS of State Change (Link Status %s)\n", OsDev->port, (status & CPMAC_STATUS_LINK) ? "Up" : "Down");
7818 +    if(status & CPMAC_STATUS_LINK)
7819 +      {
7820 +      printf("Speed %s, Duplex %s\n",
7821 +      status & CPMAC_STATUS_LINK_SPEED ? "100" : "10",
7822 +      status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD");
7823 +      }
7824 +    }
7825 +@endcode
7826 +
7827 +@par Tick
7828 +     The CPHAL calls the OS to set the interval for calling halTick()<BR>
7829 +     Note: Predefined value hcTick now recommended for use.
7830 +@code
7831 +***  Example Code ***
7832 +
7833 +*** CPHAL code ***
7834 +int Ticks;
7835 +HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcSet, &Ticks);
7836 +
7837 +*** OS code ***
7838 +  ..
7839 +  if(osStrcmpi(pszKey, hcTick) == 0)
7840 +  {
7841 +    if(osStrcmpi(pszAction, hcSet) == 0)
7842 +    {
7843 +      // Enable the Tick Interval
7844 +      if(*(unsigned int *) ParmValue)
7845 +        printf("osTickSet: Interval = %d ticks\n", Interval);
7846 +    }
7847 +    else
7848 +    if(osStrcmpi(pszAction, hcClear) == 0)
7849 +    {
7850 +        // Request disabling of the Tick Timer, ParmValue is ignored
7851 +    }
7852 +  }
7853 +@endcode
7854 +
7855 +@par The following information can be obtained by the OS via 'Get'
7856 +
7857 +- StatsDump : OS supplies pointer to an 36 element unsigned int array
7858 +CPHAL will populate the array with the current Statistics values.<BR>
7859 +Note: all hcXXXX values are predefined and should be used by the OS.
7860 +
7861 +- hcPhyNum : Returns the PHY number.
7862 +- hcCpmacBase : Returns the base-address of the CPMAC device
7863 +- hcCpmacSize : Returns size of the CPMAC memory map
7864 +
7865 +
7866 +@par Phy Register Communication
7867 +
7868 +halControl() is used to read and write the Phy Registers via the key hcPhyAccess
7869 +
7870 +Both reading and writing the Phy registers involve setting the Value parameter of halControl()
7871 +<BR>
7872 +Value is a 32-bit value with bits partioned as follows
7873 +<BR>
7874 +
7875 +   0 -  4  Phy Number   <BR>
7876 +   5 -  9  Phy Register <BR>
7877 +  10 - 15  reserved     <BR>
7878 +  16 - 31  Data  (write only)
7879 +<BR>
7880 +
7881 +
7882 +<B>Reading the Phy register</B>
7883 +
7884 +@code
7885 +    bit32u Value;
7886 +    bit32u RegAddr;
7887 +    bit32u PhyNum;
7888 +    bit32u PhyRegisterData;
7889 +
7890 +    //  Read Phy 31, register 20
7891 +
7892 +    PhyNum  = 31;
7893 +    RegAddr = 20;
7894 +
7895 +    Value = (RegAddr << 5);
7896 +    Value |= (PhyNum & 0x1F);
7897 +
7898 +    rc  = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value)
7899 +    If(rc == 0)
7900 +    {
7901 +        // Value is overwriten with the value in Register 20 of Phy number 31.
7902 +        PhyRegisterData = Value;
7903 +    }
7904 +@endcode
7905 +
7906 +<B>Writing the Phy register</B>
7907 +@code
7908 +    bit32u Value;
7909 +    bit32u RegAddr;
7910 +    bit32u PhyNum;
7911 +    bit32u PhyRegisterData;
7912 +
7913 +    //  Reset Phy 23
7914 +
7915 +    PhyNum  = 23;
7916 +    RegAddr = 0;
7917 +    PhyRegisterData = 0x8000;  // Reset bit set
7918 +
7919 +    Value = (RegAddr << 5);
7920 +    Value |= (PhyNum & 0x1F);
7921 +    Value |= (PhyRegisterData << 16);
7922 +
7923 +    rc  = HalFunc->Control(HalDev, hcPhyAccess, hcSet, (bit32u *) &Value)
7924 +
7925 +    // Check is reset if done
7926 +
7927 +    PhyNum  = 23;
7928 +    RegAddr = 0;
7929 +
7930 +    Value = (RegAddr << 5);
7931 +    Value |= (PhyNum & 0x1F);
7932 +
7933 +    rc  = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value)
7934 +
7935 +    If(rc == 0)
7936 +    {
7937 +        // Value is overwriten with the value in Register 0 of Phy number 23.
7938 +        PhyRegisterData = Value;
7939 +        if((PhyRegisterData & 0x8000) == 0)
7940 +           ResetIsComplete;
7941 +    }
7942 +
7943 +@endcode
7944 +<B>
7945 +*** Example Showing turning values off/on ***
7946 +<BR>
7947 +</B>
7948 +
7949 +@code
7950 +
7951 +int On=1;
7952 +int Off=0;
7953 +   # Turn On loopback
7954 +   OsDev->HalFunc->Control(OsDev->HalDev, "CTRL_LOOPBACK", hcSet, (int*) &On);
7955 +
7956 +   #  Turn off RX Flow
7957 +   OsDev->HalFunc->Control(OsDev->HalDev, "RX_FLOW_EN", hcSet, (int*) &Off);
7958 +@endcode
7959 +
7960 +@par CPMAC Configurable Parameters
7961 +
7962 +- RX_PASS_CRC        : See MBP_Enable description
7963 +- RX_QOS_EN          : See MBP_Enable description
7964 +- RX_NO_CHAIN        : See MBP_Enable description
7965 +- RX_CMF_EN          : See MBP_Enable description
7966 +- RX_CSF_EN          : See MBP_Enable description
7967 +- RX_CEF_EN          : See MBP_Enable description
7968 +- RX_CAF_EN          : See MBP_Enable description
7969 +- RX_PROM_CH         : See MBP_Enable description
7970 +- RX_BROAD_EN        : See MBP_Enable description
7971 +- RX_BROAD_CH        : See MBP_Enable description
7972 +- RX_MULT_EN         : See MBP_Enable description
7973 +- RX_MULT_CH         : See MBP_Enable description
7974 +
7975 +- TX_PTYPE           : See MacControl description
7976 +- TX_PACE            : See MacControl description
7977 +- TX_FLOW_EN         : See MacControl description
7978 +- RX_FLOW_EN         : See MacControl description
7979 +- CTRL_LOOPBACK      : See MacControl description
7980 +
7981 +- RX_MAXLEN          : See CPMAC Guide
7982 +- RX_FILTERLOWTHRESH : See CPMAC Guide
7983 +- RX0_FLOWTHRESH     : See CPMAC Guide
7984 +- RX_UNICAST_SET     : See CPMAC Guide
7985 +- RX_UNICAST_CLEAR   : See CPMAC Guide
7986 +
7987 +@par Multicast Support
7988 +- RX_MULTI_ALL       : When used with hcSet, sets all the Hash Bits. When used
7989 +with hcClear clears all the Hash Bits.
7990 +- RX_MULTI_SINGLE    : When used with hcSet, adds the Hashed Mac Address. When used
7991 +with hcClear deletes the Hashed Mac Address.
7992 +Note: Support will be added to keep track of Single additions and deletions.
7993 +
7994 +@code
7995 +*** Example Code ***
7996 +
7997 +*** OS code ***
7998 +  bit8u  MacAddress[6];
7999 +  MacAddress[0] = 0x80;
8000 +  MacAddress[1] = 0x12;
8001 +  MacAddress[2] = 0x34;
8002 +  MacAddress[3] = 0x56;
8003 +  MacAddress[4] = 0x78;
8004 +  MacAddress[5] = 0x78;
8005 +  OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcSet, (bit8u*) &MacAddress);
8006 +  OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcClear, (bit8u*) &MacAddress);
8007 +  OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcSet, NULL);
8008 +  OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcClear, NULL);
8009 +@endcode
8010 +@par MdioConnect Fields
8011 +<BR>
8012 +- "MdioConnect"     : The OS can set the Phy connection using this key. The default connection is Auto-Negotiation ON, All modes possible.
8013 +
8014 +
8015 +- _CPMDIO_HD       <----- Allow Half Duplex, default is 1 (On)
8016 +- _CPMDIO_FD       <----- Allow Full Duplex, default is 1 (On)
8017 +- _CPMDIO_10       <----- Allow 10  Mbs, default is 1 (On)
8018 +- _CPMDIO_100      <----- Allow 100 Mbs, default is 1 (On)
8019 +- _CPMDIO_NEG_OFF  <----- Turn off Auto Negotiation, default is 0 (Auto Neg is on)
8020 +- _CPMDIO_NOPHY    <----- Set for use with Marvel-type switch, default is 0 (Phy present)
8021 +- _CPMDIO_AUTOMDIX  <---- Enables Auto Mdix (in conjunction with MdixMask), default is 1 (On)
8022 +
8023 +Note: When _CPMDIO_NOPHY is set, CPMAC will report being linked at 100/FD. Reported PhyNum will be 0xFFFFFFFF
8024 +
8025 +@par Setting CPMAC for use with a Marvel-type Switch
8026 +@code
8027 +     bit32u MdioConnect;
8028 +
8029 +     MdioConnect = _CPMDIO_NOPHY;
8030 +     OsDev->HalFunc->Control(OsDev->HalDev, "MdioConnect", hcSet, (bit32u*) &MdioConnect);
8031 +@endcode
8032 +
8033 +@par OS Support for MDIO
8034 +@p The OS will need to supply the following values which the CPHAL will request via halControl()
8035 +<BR>
8036 +- MdioBusFrequency : The frequency of the BUS that MDIO is on (requested via hcMdioBusFrequency)
8037 +<BR>
8038 +- MdioClockFrequency : The desired Clock Frequency that MDIO qill operate at (requested via hcMdioClockFrequency)
8039 +*/
8040 +
8041 +/**
8042 +@page cpmac_conf DeviceFindxxx() Parameters
8043 +
8044 +These are some of the parameters that the CPMAC will request via the DeviceFindxxx() functions -
8045 +<BR>
8046 +- "Mlink"    : bit mask indicating what link status method Phy is using. Default is MDIO state machine (0x0)
8047 +- "PhyMask"  : bit mask indicating PhyNums used by this CPMAC (e.g 0x8000000, PhyNum is 31)
8048 +- "MdixMask" : bit mask indicating which Phys support AutoMdix. Default is 0x0 (None)
8049 +<BR>
8050 +@par Example cpmac definition from the options.conf for the Sangam VDB
8051 +<BR>
8052 +- cpmac( id=eth0, base=0xA8610000, size=0x800, reset_bit=17, int_line=19, PhyMask=0x80000000, MLink=0, MdixMask=0 )
8053 +*/
8054 +
8055 +/**
8056 +@page auto_mdix Auto Mdix Support
8057 +
8058 +Auto Mdix selection is controlled by two elements in the CPMAC. First the OS can turn Auto Midx On or Off by the use of the
8059 +MdioConnect field, _CPMDIO_AUTOMDIX. This is defaulted ON.  For actual Auto Mdix operation the Phy must also be Auto Mdix capable.
8060 +This is specified by the DeviceFindxxx() field, "MdixMask" (supplied as the variable hcMdixMask).
8061 +If both these fields are set then the CPMDIO state machine will be enabled for Auto Mdix checking.
8062 +If a switch to MDI or MDIX mode is needed, the CPMAC will signal this to the OS via Control() using
8063 +the hcMdioMdixSwitch key.
8064 +
8065 +@par OS example for responding to a Mdix Switch Request
8066 +<BR>
8067 +@code
8068 +if(osStrcmpi(pszKey, hcMdioMdixSwitch) == 0)  // See if key is Mdix Switch Request
8069 +  {
8070 +      if(osStrcmpi(pszAction, hcSet) == 0)   // Only respond to Set requests
8071 +      {
8072 +
8073 +          bit32u Mdix;
8074 +
8075 +          Mdix = *(bit32u *) ParmValue;     // Extract requested Mode
8076 +                                            // 0 : MDI
8077 +                                            // 1 : MDIX
8078 +          if(Mdix)
8079 +            osSetPhyIntoMdixMode();         // Device specific logic
8080 +          else
8081 +            osSetPhyIntoMdiMode();          // Device specific logic
8082 +          rc = 0;                           // Set return code as Successfull
8083 +      }
8084 +@endcode
8085 +*/
8086 +
8087 +/**
8088 +@page cpmac_stats CPMAC Specific Statistics
8089 +
8090 +Statistics level '0' contains all CPMAC specific statistics.
8091 +
8092 +
8093 +*/
8094 +
8095 +/**
8096 +@page Example_Driver_Code
8097 +
8098 +@section  example_intro Introduction
8099 +This section provides an in-depth code example for driver implementations.  The code
8100 +below illustrates the use of the CPMAC HAL, but is equally applicable to any CPHAL
8101 +implementation. Note: the CPHAl constants hcGet, hcSet etc., are currently available for use with teh CPMAC module.
8102 +Other modules should continue to use pszGET, etc. until these are made generally available.
8103 +
8104 +@par Pull Model Example
8105 +
8106 +@code
8107 +
8108 +#define _CPHAL_CPMAC
8109 +
8110 +typedef struct _os_device_s  OS_DEVICE;
8111 +typedef struct _os_receive_s OS_RECEIVEINFO;
8112 +typedef struct _os_send_s    OS_SENDINFO;
8113 +typedef struct _os_setup_s   OS_SETUP;
8114 +
8115 +#include "cpswhal_cpmac.h"
8116 +
8117 +#define dbgPrintf printf
8118 +
8119 +typedef struct  _os_device_s
8120 +{
8121 +   HAL_DEVICE    *HalDev;
8122 +   HAL_FUNCTIONS *HalFunc;
8123 +   OS_FUNCTIONS  *OsFunc;
8124 +   OS_SETUP      *OsSetup;
8125 +   bit32u        Interrupt;
8126 +   int           (*halIsr)(HAL_DEVICE  *HalDev, int*);
8127 +   int           ModulePort;
8128 +   int           Protocol;
8129 +   int           LinkStatus;  // 0-> down, otherwise up
8130 +}os_device_s;
8131 +
8132 +typedef struct  _os_receive_s
8133 +{
8134 +   HAL_RECEIVEINFO *HalReceiveInfo;
8135 +   char   *ReceiveBuffer;
8136 +   OS_DEVICE  *OsDev;
8137 +}os_receive_s;
8138 +
8139 +typedef struct  _os_send_s
8140 +{
8141 +   OS_DEVICE  *OsDev;
8142 +}os_send_s;
8143 +
8144 +typedef struct  _os_setup_s
8145 +{
8146 +   OS_DEVICE  *OsDev;
8147 +}os_setup_s;
8148 +
8149 +
8150 +
8151 +void FlowForCphal(OS_DEVICE *OsDev)
8152 +{
8153 +  CHANNEL_INFO ChannelInfo;
8154 +  int nChannels = 200;
8155 +  int halFuncSize;
8156 +  int rc;
8157 +
8158 +  //  Populate OsFunc structure
8159 +  rc =  osInitModule(OsDev);
8160 +
8161 +  if(rc)
8162 +  {
8163 +    sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc);
8164 +    errorout(bufTmp);
8165 +  }
8166 +
8167 +
8168 +  //  OS-Cphal handshake
8169 +  rc = halCpmacInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc,
8170 +                              sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort);
8171 +
8172 +  if(rc)
8173 +  {
8174 +    sprintf(bufTmp, "%s: return code from halCpmacInitModule:'0x%08X'", __FUNCTION__, rc);
8175 +    errorout(bufTmp);
8176 +  }
8177 +
8178 +  // See if hardware module exists
8179 +  rc = OsDev->HalFunc->Probe(OsDev->HalDev);
8180 +
8181 +  if(rc)
8182 +  {
8183 +    sprintf(bufTmp, "%s: return code from Probe:'0x%08X'", __FUNCTION__, rc);
8184 +    errorout(bufTmp);
8185 +  }
8186 +
8187 +  // Initialize hardware module
8188 +  rc = OsDev->HalFunc->Init(OsDev->HalDev);
8189 +
8190 +  if(rc)
8191 +  {
8192 +    sprintf(bufTmp, "%s: return code from Init:'0x%08X'", __FUNCTION__, rc);
8193 +    errorout(bufTmp);
8194 +  }
8195 +
8196 +  // Setup Channel Information (Tranmsit, channel 0)
8197 +  ChannelInfo.Channel      = 0;
8198 +  ChannelInfo.Direction    = DIRECTION_TX;
8199 +  ChannelInfo.TxNumBuffers = nChannels;
8200 +  ChannelInfo.TxNumQueues  = 1;
8201 +  ChannelInfo.TxServiceMax = nChannels/3;
8202 +
8203 +  rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup);
8204 +
8205 +  // Setup Channel Information (Receive, channel 0)
8206 +  ChannelInfo.Channel        = 0;
8207 +  ChannelInfo.Direction      = DIRECTION_RX;
8208 +  ChannelInfo.RxBufSize      = 1518;
8209 +  ChannelInfo.RxBufferOffset = 0;
8210 +  ChannelInfo.RxNumBuffers   = 2*nChannels;
8211 +  ChannelInfo.RxServiceMax   = nChannels/3;
8212 +
8213 +  rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup);
8214 +
8215 +  // Open the hardware module
8216 +  rc = OsDev->HalFunc->Open(OsDev->HalDev);
8217 +
8218 +  // Module now ready to Send/Receive data
8219 +}
8220 +
8221 +
8222 +int osInitModule(OS_FUNCTIONS **pOsFunc)
8223 +  {
8224 +   OS_FUNCTIONS *OsFunc;
8225 +
8226 +   OsFunc = (OS_FUNCTIONS *) malloc(sizeof(OS_FUNCTIONS));
8227 +   if (!OsFunc)
8228 +     return (-1);
8229 +
8230 +   *pOsFunc = OsFunc;
8231 +
8232 +   OsFunc->CriticalOff               = osCriticalOff;
8233 +   OsFunc->CriticalOn                = osCriticalOn;
8234 +   OsFunc->DataCacheHitInvalidate    = osDataCacheHitInvalidate;
8235 +   OsFunc->DataCacheHitWriteback     = osDataCacheHitWriteback;
8236 +   OsFunc->DeviceFindInfo            = osDeviceFindInfo;
8237 +   OsFunc->DeviceFindParmUint        = osDeviceFindParmUint;
8238 +   OsFunc->DeviceFindParmValue       = osDeviceFindParmValue;
8239 +   OsFunc->Free                      = osFree;
8240 +   OsFunc->FreeDev                   = osFreeDev;
8241 +   OsFunc->FreeDmaXfer               = osFreeDmaXfer;
8242 +   OsFunc->FreeRxBuffer              = osFreeRxBuffer;
8243 +   OsFunc->IsrRegister               = osIsrRegister;
8244 +   OsFunc->IsrUnRegister             = osIsrUnRegister;
8245 +   OsFunc->Malloc                    = osMalloc;
8246 +   OsFunc->MallocDev                 = osMallocDev;
8247 +   OsFunc->MallocDmaXfer             = osMallocDmaXfer;
8248 +   OsFunc->MallocRxBuffer            = osMallocRxBuffer;
8249 +
8250 +
8251 +   OsFunc->Memset                    = memset;
8252 +   OsFunc->Printf                    = printf;
8253 +   OsFunc->Sprintf                   = sprintf;
8254 +   OsFunc->Strcmpi                   = osStrcmpi;
8255 +   OsFunc->Strlen                    = strlen;
8256 +   OsFunc->Strstr                    = strstr;
8257 +   OsFunc->Strtoul                   = strtoul;
8258 +
8259 +   OsFunc->Control                   = osControl;
8260 +   OsFunc->Receive                   = osReceive;
8261 +   OsFunc->SendComplete              = osSendComplete;
8262 +   OsFunc->TeardownComplete          = osTearDownComplete;
8263 +
8264 +   return(0);
8265 +  }
8266 +
8267 +
8268 +int osReceive(OS_DEVICE *OsDev,FRAGLIST *Fraglist,bit32u FragCount,bit32u PacketSize,HAL_RECEIVEINFO *halInfo, bit32u mode)
8269 +  {
8270 +  OS_RECEIVEINFO *skb = (OS_RECEIVEINFO *)Fraglist[0].OsInfo;
8271 +  dcache_i((char *)Fraglist->data, Fraglist->len);
8272 +  OsDev->HalFunc->RxReturn(halInfo,0);
8273 +  return(0);
8274 +  }
8275 +
8276 +int osSendComplete(OS_SENDINFO *skb)
8277 +  {
8278 +  return(0);
8279 +  }
8280 +
8281 +
8282 +static void *osMallocRxBuffer(bit32u Size,void *MemBase, bit32u MemRange,
8283 +                              OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo,
8284 +                              OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev )
8285 +  {
8286 +   void *HalBuffer;
8287 +   OS_RECEIVEINFO *OsPriv;
8288 +
8289 +   HalBuffer=malloc(Size);
8290 +   if (!HalBuffer)
8291 +     {
8292 +      return(0);
8293 +     }
8294 +
8295 +   // Malloc the OS block
8296 +   *OsReceiveInfo = malloc(sizeof(OS_RECEIVEINFO));
8297 +   if (!*OsReceiveInfo)
8298 +     {
8299 +      free(HalBuffer);
8300 +      return(0);
8301 +     }
8302 +
8303 +   // Initialize the new buffer descriptor
8304 +   OsPriv                 = *OsReceiveInfo;
8305 +   OsPriv->OsDev          =  OsDev;
8306 +   OsPriv->ReceiveBuffer  =  HalBuffer;
8307 +   OsPriv->HalReceiveInfo =  HalReceiveInfo;
8308 +
8309 +   return(HalBuffer);
8310 +  }
8311 +
8312 +
8313 +void SendBuffer(OS_DEVICE *OsDev, char *Buffer, int Size)
8314 +{
8315 +  FRAGLIST Fraglist;
8316 +  bit32u FragCount;
8317 +
8318 +  tcb_pending++;
8319 +  Fraglist.len  = Size;
8320 +  Fraglist.data = (unsigned *) Buffer;
8321 +  FragCount     = 1;
8322 +  mode          = 0;   //  Channel 0
8323 +
8324 +  dcache_wb(Fraglist.data, Fraglist.len);
8325 +  OsDev->HalFunc->Send(OsDev->HalDev, &Fraglist, FragCount, Size, (OS_SENDINFO *) Buffer, mode);
8326 +}
8327 +
8328 +
8329 +void osStateChange(OS_DEVICE *OsDev)
8330 +  {
8331 +  int status;
8332 +  int LinkStatus;
8333 +  OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status);
8334 +  if(status & CPMAC_STATUS_ADAPTER_CHECK)
8335 +    {
8336 +    //  Adapter Check, take appropiate action
8337 +    }
8338 +  else
8339 +    {
8340 +    LinkStatus = status & CPMAC_STATUS_LINK;
8341 +    if(LinkStatus != OsDev->LinkStatus)
8342 +      {
8343 +      dbgPrintf("\n%s:Link %s for inst %d Speed %s, Duplex %s\n",
8344 +                 __FUNCTION__,
8345 +                 LinkStatus ? "up" : "down",
8346 +                 OsDev->ModulePort,
8347 +                 status & CPMAC_STATUS_LINK_SPEED ? "100" : "10",
8348 +                 status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD");
8349 +      OsDev->LinkStatus = LinkStatus;
8350 +      }
8351 +    }
8352 +  }
8353 +
8354 +
8355 +int osControl(OS_DEVICE *OsDev, const char *pszKey, const char* pszAction, void *ParmValue)
8356 +  {
8357 +  int rc=-1;
8358 +
8359 +  if (osStrcmpi(pszKey, hcCpuFrequency) == 0)
8360 +   {
8361 +   if(osStrcmpi(pszAction, hcGet) == 0)
8362 +     {
8363 +     *(bit32u*) ParmValue = cpufreq;
8364 +     rc = 0;
8365 +     }
8366 +   }
8367 +  if (osStrcmpi(pszKey, hcMdioBusFrequency) == 0)
8368 +   {
8369 +   if(osStrcmpi(pszAction, hcGet) == 0)
8370 +     {
8371 +     *(bit32u *)ParmValue = MdioBusFrequency;
8372 +     rc = 0;
8373 +     }
8374 +   }
8375 +if (osStrcmpi(pszKey, hcMdioClockFrequency) == 0)
8376 +   {
8377 +   if(osStrcmpi(pszAction, hcGet) == 0)
8378 +     {
8379 +     *(bit32u *)ParmValue = MdioClockFrequency;
8380 +     rc = 0;
8381 +     }
8382 +   }
8383 +
8384 +  if (osStrcmpi(pszKey, hcTick) == 0)
8385 +   {
8386 +   if(osStrcmpi(pszAction, hcSet) == 0)
8387 +     {
8388 +       osTickSetInterval(OsDev, *(unsigned int *) ParmValue);
8389 +       rc = 0;
8390 +     }
8391 +   else
8392 +   if(osStrcmpi(pszAction, hcClear) == 0)
8393 +     {
8394 +       osTickDisable(OsDev);
8395 +       rc = 0;
8396 +     }
8397 +   }
8398 +
8399 +  if (osStrcmpi(pszKey, "SioFlush") == 0)
8400 +    {
8401 +       MySioFlush();
8402 +       rc = 0;
8403 +    }
8404 +
8405 +  if (osStrcmpi(pszKey, "StateChange") == 0)
8406 +    {
8407 +       osStateChange(OsDev);
8408 +       rc = 0;
8409 +    }
8410 +
8411 +  if (osStrcmpi(pszKey, "Sleep") == 0)
8412 +    {
8413 +       osSleep(*(int *)ParmValue);
8414 +       rc = 0;
8415 +    }
8416 +  return(rc);
8417 +  }
8418 +
8419 +@endcode
8420 +
8421 +
8422 +@par Push Model Example (Currently Eswitch ONLY)
8423 +
8424 +@code
8425 +
8426 +typedef struct _os_device_s  OS_DEVICE;
8427 +typedef struct _os_receive_s OS_RECEIVEINFO;
8428 +typedef struct _os_send_s    OS_SENDINFO;
8429 +typedef struct _os_setup_s   OS_SETUP;
8430 +
8431 +#include "cpswhal.h"          //Get glogal HAL stuff
8432 +#include "cpswhaleswitch.h"   //Get device specific hal stuff
8433 +
8434 +
8435 +typedef struct  _os_device_s
8436 +{
8437 +   HAL_DEVICE    *HalDev;
8438 +   HAL_FUNCTIONS *HalFunc;
8439 +   OS_FUNCTIONS  *OsFunc;
8440 +   OS_SETUP      *OsSetup;
8441 +   bit32u        Interrupt;
8442 +   int           (*halIsr)(HAL_DEVICE  *HalDev, int*);
8443 +   int           ModulePort;
8444 +   int           Protocol;
8445 +   int           LinkStatus;  // 0-> down, otherwise up
8446 +}os_device_s;
8447 +
8448 +typedef struct  _os_receive_s
8449 +{
8450 +   HAL_RECEIVEINFO *HalReceiveInfo;
8451 +   char   *ReceiveBuffer;
8452 +   OS_DEVICE  *OsDev;
8453 +}os_receive_s;
8454 +
8455 +typedef struct  _os_send_s
8456 +{
8457 +   OS_DEVICE  *OsDev;
8458 +}os_send_s;
8459 +
8460 +typedef struct  _os_setup_s
8461 +{
8462 +   OS_DEVICE  *OsDev;
8463 +}os_setup_s;
8464 +
8465 +
8466 +
8467 +void FlowForCphal(OS_DEVICE *OsDev)
8468 +{
8469 +CHANNEL_INFO ChannelInfo;
8470 +  int nChannels = 200;
8471 +  int halFuncSize;
8472 +  int rc;
8473 +
8474 +  //  Populate OsFunc structure
8475 +  rc =  osInitModule(OsDev);
8476 +
8477 +  if(rc)
8478 +  {
8479 +    sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc);
8480 +    errorout(bufTmp);
8481 +  }
8482 +
8483 +
8484 +  //  OS-Cphal handshake
8485 +  rc = cpswHalEswitchInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc,
8486 +                              sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort);
8487 +
8488 +  if(rc)
8489 +  {
8490 +    sprintf(bufTmp, "%s: return code from cpswHalEswitchInitModule:'0x%08X'", __FUNCTION__, rc);
8491 +    errorout(bufTmp);
8492 +  }
8493 +
8494 +
8495 +  ChannelInfo.Channel      = 7;
8496 +  ChannelInfo.Direction    = DIRECTION_RX;
8497 +  ChanInfo.Receive = osReceiveSS;         //  Specify function to receive data for this channel
8498 +
8499 +  rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup);
8500 +
8501 +  MyConfig.debug=0;
8502 +  MyConfig.CpuFrequency = CpuFreq;
8503 +  MyConfig.EswitchFrequency = EswitchFreq;
8504 +  MyConfig.ResetBase  = 0xa8611600;
8505 +  MyConfig.MacAddress = MacAddr;
8506 +
8507 +  MyConfig.EswitchResetBit= 27;
8508 +  MyConfig.Cpmac0ResetBit = 17;
8509 +  MyConfig.Cpmac1ResetBit = 21;
8510 +  MyConfig.MdioResetBit   = 22;
8511 +  MyConfig.Phy0ResetBit   = 26;
8512 +  MyConfig.Phy1ResetBit   = 28;
8513 +  MyConfig.HdmaResetBit   = 13;
8514 +  MyConfig.Cpmac0IntBit   = 19;
8515 +  MyConfig.Cpmac1IntBit   = 33;
8516 +  MyConfig.EswitchIntBit  = 27;
8517 +  MyConfig.EswitchBase    = 0xa8640000;
8518 +  MyConfig.EswitchBufferSize     = 64;
8519 +  MyConfig.EswitchHostBufCount   = 0;
8520 +  MyConfig.EswitchDefaultCamSize = 64;
8521 +  MyConfig.EswitchOverFlowCount  = 200;
8522 +  MyConfig.EswitchOverFlowSize   = 256;
8523 +
8524 +
8525 +
8526 +
8527 +  rc=EswitchConfig(HalDev,HalFunc,&MyConfig);
8528 +
8529 +
8530 +  // Open the hardware module
8531 +  rc = OsDev->HalFunc->Open(OsDev->HalDev);
8532 +
8533 +  // Module now ready to Send/Receive data
8534 +}
8535 +
8536 +
8537 +int EswitchConfig(HAL_DEVICE *HalDev, HAL_FUNCTIONS *HalFunc, ESWITCH_CONFIG *Config)
8538 +{
8539 +  bit32u sts;
8540 +  sts = 0;
8541 +
8542 +  sts |= cpswhalPushBin(hcdebug, Config->debug);
8543 +  sts |= cpswhalPushBin(hcCpuFrequency     , Config->CpuFrequency );
8544 +  sts |= cpswhalPushBin(hcEswitchFrequency , Config->EswitchFrequency );
8545 +  sts |= cpswhalPushBin(hcResetBase        , Config->ResetBase  );
8546 +  sts |= cpswhalPushBin(hcMacAddress       , Config->MacAddress );
8547 +  sts |= cpswhalPushBin(hcEswitchResetBit, Config->EswitchResetBit);
8548 +  sts |= cpswhalPushBin(hcCpmac0ResetBit , Config->Cpmac0ResetBit );
8549 +  sts |= cpswhalPushBin(hcCpmac1ResetBit , Config->Cpmac1ResetBit );
8550 +  sts |= cpswhalPushBin(hcMdioResetBit   , Config->MdioResetBit   );
8551 +  sts |= cpswhalPushBin(hcPhy0ResetBit   , Config->Phy0ResetBit   );
8552 +  sts |= cpswhalPushBin(hcPhy1ResetBit   , Config->Phy1ResetBit   );
8553 +  sts |= cpswhalPushBin(hcHdmaResetBit   , Config->HdmaResetBit   );
8554 +  sts |= cpswhalPushBin(hcCpmac0IntBit   , Config->Cpmac0IntBit   );
8555 +  sts |= cpswhalPushBin(hcCpmac1IntBit   , Config->Cpmac1IntBit   );
8556 +  sts |= cpswhalPushBin(hcEswitchIntBit  , Config->EswitchIntBit  );
8557 +  sts |= cpswhalPushBin(hcEswitchBase           , Config->EswitchBase    );
8558 +  sts |= cpswhalPushBin(hcEswitchBufferSize     , Config->EswitchBufferSize     );
8559 +  sts |= cpswhalPushBin(hcEswitchHostBufCount   , Config->EswitchHostBufCount   );
8560 +  sts |= cpswhalPushBin(hcEswitchDefaultCamSize , Config->EswitchDefaultCamSize );
8561 +  sts |= cpswhalPushBin(hcEswitchOverFlowCount  , Config->EswitchOverFlowCount  );
8562 +  sts |= cpswhalPushBin(hcEswitchOverFlowSize   , Config->EswitchOverFlowSize   );
8563 +  return(sts);
8564 +}
8565 +
8566 +
8567 +
8568 +@endcode
8569 +*/
8570 +
8571 +#endif
8572 diff -urN linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h
8573 --- linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h     1970-01-01 01:00:00.000000000 +0100
8574 +++ linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h     2005-07-12 02:48:42.051592000 +0200
8575 @@ -0,0 +1,118 @@
8576 +/***************************************************************************
8577 + Copyright(c) 2001, Texas Instruments Incorporated. All Rights Reserved.
8578 +
8579 + FILE:  ec_errors.h
8580 +
8581 + DESCRIPTION:
8582 +   This file contains definitions and function declarations for
8583 +   error code support.
8584 +
8585 + HISTORY:
8586 +   14Dec00 MJH             Added masking to EC_CLASS etc macros
8587 +   17Sep02 GSG             Added HAL support (new class&devices)
8588 +   03Oct02 GSG             Removed C++ style comments
8589 +***************************************************************************/
8590 +#ifndef _INC_EC_ERRORS
8591 +#define _INC_EC_ERRORS
8592 +
8593 +/*
8594 +  31    - CRITICAL
8595 +  30-28 - CLASS         (ie. DIAG, KERNEL, FLASH, etc)
8596 +  27-24 - INSTANCE      (ie. 1, 2, 3, etc )
8597 +  23-16 - DEVICE        (ie. EMAC, IIC, etc)
8598 +  15-08 - FUNCTION      (ie. RX, TX, INIT, etc)
8599 +  07-00 - ERROR CODE    (ie. NO_BASE, FILE_NOT_FOUND, etc )
8600 +*/
8601 +
8602 +/*---------------------------------------------------------------------------
8603 +  Useful defines for accessing fields within error code
8604 +---------------------------------------------------------------------------*/
8605 +#define CRITICAL_SHIFT    31
8606 +#define CLASS_SHIFT       28
8607 +#define INST_SHIFT        24
8608 +#define DEVICE_SHIFT      16
8609 +#define FUNCTION_SHIFT     8
8610 +#define ERROR_CODE_SHIFT   0
8611 +
8612 +#define CRITICAL_MASK     1
8613 +#define CLASS_MASK        0x07
8614 +#define DEVICE_MASK       0xFF
8615 +#define INST_MASK         0x0F
8616 +#define FUNCTION_MASK     0xFF
8617 +#define ERROR_CODE_MASK   0xFF
8618 +
8619 +#define EC_CLASS(val)     ((val&CLASS_MASK)      << CLASS_SHIFT)
8620 +#define EC_DEVICE(val)    ((val&DEVICE_MASK)     << DEVICE_SHIFT)
8621 +#define EC_INST(val)      ((val&INST_MASK)       << INST_SHIFT)
8622 +#define EC_FUNC(val)      ((val&FUNCTION_MASK)   << FUNCTION_SHIFT)
8623 +#define EC_ERR(val)       ((val&ERROR_CODE_MASK) << ERROR_CODE_SHIFT)
8624 +
8625 +/*---------------------------------------------------------------------------
8626 +   Operation classes
8627 +---------------------------------------------------------------------------*/
8628 +#define EC_HAL              EC_CLASS(0)
8629 +#define EC_DIAG             EC_CLASS(8)
8630 +
8631 +/*---------------------------------------------------------------------------
8632 +   Device types
8633 +---------------------------------------------------------------------------*/
8634 +#define EC_DEV_EMAC         EC_DEVICE(1)
8635 +#define EC_DEV_IIC          EC_DEVICE(2)
8636 +#define EC_DEV_RESET        EC_DEVICE(3)
8637 +#define EC_DEV_ATMSAR       EC_DEVICE(4)
8638 +#define EC_DEV_MEM          EC_DEVICE(5)
8639 +#define EC_DEV_DES          EC_DEVICE(6)
8640 +#define EC_DEV_DMA          EC_DEVICE(7)
8641 +#define EC_DEV_DSP          EC_DEVICE(8)
8642 +#define EC_DEV_TMR          EC_DEVICE(9)
8643 +#define EC_DEV_WDT          EC_DEVICE(10)
8644 +#define EC_DEV_DCL          EC_DEVICE(11)
8645 +#define EC_DEV_BBIF         EC_DEVICE(12)
8646 +#define EC_DEV_PCI              EC_DEVICE(13)
8647 +#define EC_DEV_XBUS         EC_DEVICE(14)
8648 +#define EC_DEV_DSLIF            EC_DEVICE(15)
8649 +#define EC_DEV_USB                      EC_DEVICE(16)
8650 +#define EC_DEV_CLKC                     EC_DEVICE(17)
8651 +#define EC_DEV_RAPTOR       EC_DEVICE(18)
8652 +#define EC_DEV_DSPC                     EC_DEVICE(19)
8653 +#define EC_DEV_INTC                     EC_DEVICE(20)
8654 +#define EC_DEV_GPIO                     EC_DEVICE(21)
8655 +#define EC_DEV_BIST                     EC_DEVICE(22)
8656 +#define EC_DEV_HDLC                     EC_DEVICE(23)
8657 +#define EC_DEV_UART                     EC_DEVICE(24)
8658 +#define EC_DEV_VOIC                     EC_DEVICE(25)
8659 +/* 9.17.02 (new HAL modules) */
8660 +#define EC_DEV_CPSAR        EC_DEVICE(0x1A)
8661 +#define EC_DEV_AAL5         EC_DEVICE(0x1B)
8662 +#define EC_DEV_AAL2         EC_DEVICE(0x1C)
8663 +#define EC_DEV_CPMAC        EC_DEVICE(0x1D)
8664 +#define EC_DEV_VDMA         EC_DEVICE(0x1E)
8665 +#define EC_DEV_VLYNQ        EC_DEVICE(0x1F)
8666 +#define EC_DEV_CPPI         EC_DEVICE(0x20)
8667 +#define EC_DEV_CPMDIO       EC_DEVICE(0x21)
8668 +
8669 +/*---------------------------------------------------------------------------
8670 +   Function types
8671 +---------------------------------------------------------------------------*/
8672 +#define EC_FUNC_READ_CONF   EC_FUNC(1)
8673 +#define EC_FUNC_INIT        EC_FUNC(2)
8674 +
8675 +/*---------------------------------------------------------------------------
8676 +   Error codes
8677 +---------------------------------------------------------------------------*/
8678 +#define EC_CRITICAL         (1<<CRITICAL_SHIFT)
8679 +#define EC_NO_ERRORS        0
8680 +#define EC_VAL_NO_BASE      EC_ERR(1)
8681 +#define EC_VAL_NO_RESET_BIT EC_ERR(2)
8682 +#define EC_VAL_NO_RESET     EC_ERR(3)
8683 +#define EC_VAL_BAD_BASE     EC_ERR(4)
8684 +#define EC_VAL_MALLOCFAILED EC_ERR(5)
8685 +#define EC_VAL_NO_RESETBASE EC_ERR(6)
8686 +#define EC_DEVICE_NOT_FOUND EC_ERR(7)
8687 +
8688 +/*---------------------------------------------------------------------------
8689 +   Function declarations
8690 +---------------------------------------------------------------------------*/
8691 +extern void ec_log_error( unsigned int );
8692 +
8693 +#endif /* _INC_EC_ERRORS */
8694 diff -urN linux.old/drivers/net/avalanche_cpmac/hcpmac.c linux.dev/drivers/net/avalanche_cpmac/hcpmac.c
8695 --- linux.old/drivers/net/avalanche_cpmac/hcpmac.c      1970-01-01 01:00:00.000000000 +0100
8696 +++ linux.dev/drivers/net/avalanche_cpmac/hcpmac.c      2005-07-12 02:48:42.174574000 +0200
8697 @@ -0,0 +1,1878 @@
8698 +/******************************************************************************
8699 + *  TNETDxxxx Software Support
8700 + *  Copyright (c) 2002-2004 Texas Instruments Incorporated. All Rights Reserved.
8701 + *
8702 + *  FILE:
8703 + *
8704 + *  DESCRIPTION:
8705 + *      This file contains the code for the HAL EMAC Bridge Test
8706 + *
8707 + *  HISTORY:
8708 + *  xxXxx01 Denis            RC1.00  Original Version created.
8709 + *  22Jan02 Denis/Mick       RC1.01  Modified for HAL EMAC API
8710 + *  24Jan02 Denis/Mick       RC1.02  Speed Improvements
8711 + *  28Jan02 Denis/Mick       RC1.16  Made function calls pointers
8712 + *  28Jan02 Mick             RC1.18  Split into separate modules
8713 + *  29Jan02 Mick             RC1.19  Hal include file cleaned up
8714 + *  15Jul02 Michael Hanrahan RC1.20  Synch'd with Linux Version
8715 + *  23Sep02 Michael Hanrahan RC1.21  Added CPPI.C
8716 + *  16Oct02 Michael Hanrahan RC1.22  Added CAF etc to Options.Conf
8717 + *  09Jan03 Michael Hanrahan RC3.01  Fixed incorrect MDIO check
8718 + *  01Feb03 Michael Hanrahan RC3.02  Updated for GPIO/PBUSFREQ
8719 + *  29Mar03 Michael Hanrahan 1.03 Corrected  ChannelConfigGet
8720 + *  29Mar03 Michael Hanrahan 1.03 Removed user setting of TxNumQueues
8721 + *  23Aug04 Michael Hanrahan 1.7.8 Support for Setting Mac Address
8722 + *  @author Michael Hanrahan
8723 + *  @version 1.02
8724 + *  @date    24-Jan-2002
8725 + *****************************************************************************/
8726 +#define _HAL_CPMAC
8727 +#define _CPHAL_CPMAC
8728 +#define _CPHAL
8729 +#define __CPHAL_CPMDIO
8730 +
8731 +#include "dox_cpmac.h"  /*  Documentation information */
8732 +
8733 +/*  OS Data Structure definitions  */
8734 +
8735 +typedef void OS_PRIVATE;
8736 +typedef void OS_DEVICE;
8737 +typedef void OS_SENDINFO;
8738 +typedef void OS_RECEIVEINFO;
8739 +typedef void OS_SETUP;
8740 +
8741 +/*  HAL Data Structure definitions  */
8742 +
8743 +typedef struct _phy_device PHY_DEVICE;
8744 +typedef struct hal_device  HAL_DEVICE;
8745 +typedef struct hal_private HAL_PRIVATE;
8746 +typedef struct hal_private HAL_RECEIVEINFO;
8747 +
8748 +#include "cpcommon_cpmac.h"
8749 +#include "cpswhal_cpmac.h"
8750 +#include "cpmdio.h"
8751 +#include "hcpmac.h"
8752 +#include "cpmac_reg.h"
8753 +
8754 +
8755 +#define EC_MODULE
8756 +
8757 +/* MDIO Clock Frequency Default Value */
8758 +
8759 +/* Rcb/Tcb Constants */
8760 +
8761 +#define CB_SOF_BIT         (1<<31)
8762 +#define CB_EOF_BIT         (1<<30)
8763 +#define CB_SOF_AND_EOF_BIT (CB_SOF_BIT|CB_EOF_BIT)
8764 +#define CB_OWNERSHIP_BIT   (1<<29)
8765 +#define CB_EOQ_BIT         (1<<28)
8766 +#define CB_SIZE_MASK       0x0000ffff
8767 +#define RCB_ERRORS_MASK    0x03fe0000
8768 +
8769 +static char *channel_names[]   = CHANNEL_NAMES; /* GSG 11/22 (may change this implementation) */
8770 +
8771 +#define scFound(Module) if (HalDev->State != enDevFound)    return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE)
8772 +#define scInit(Module)  if (HalDev->State <  enInitialized) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE)
8773 +#define scOpen(Module)  if (HalDev->State <  enOpened)      return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE)
8774 +
8775 +
8776 +
8777 +/********************************************************************
8778 +**
8779 +**  L O C A L  F U N C T I O N S
8780 +**
8781 +********************************************************************/
8782 +static int halIsr(HAL_DEVICE *HalDev, int *MorePackets);
8783 +static int cpmacRandom(HAL_DEVICE *HalDev);
8784 +static int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max);
8785 +static int halPacketProcessEnd(HAL_DEVICE *HalDev);
8786 +
8787 +#include "cpcommon_cpmac.c"                                                /*~RC3.02*/
8788 +#include "cppi_cpmac.c"
8789 +#include "cpmdio.c"                                                  /*~RC3.02*/
8790 +
8791 +static int MacAddressSave(HAL_DEVICE *HalDev, unsigned char *MacAddr)
8792 +  {
8793 +  int i;
8794 +  int inst             = HalDev->inst;
8795 +
8796 +  HalDev->MacAddr = MacAddr;
8797 +
8798 +  if(HalDev->debug)
8799 +    {
8800 +    dbgPrintf("MacAddrSave[%d]: ", inst);
8801 +    for (i=0;i<6;i++)
8802 +       dbgPrintf("%X", HalDev->MacAddr[i]);
8803 +    dbgPrintf("\n");
8804 +    osfuncSioFlush();
8805 +    }
8806 +  return(EC_NO_ERRORS);
8807 +  }
8808 +static int MacAddressSet(HAL_DEVICE *HalDev)
8809 +  {
8810 +  unsigned char *macadr = &HalDev->MacAddr[0];
8811 +  int base             = HalDev->dev_base;
8812 +
8813 +  scOpen(EC_CPMAC);
8814 +  CPMAC_MACADDRLO_0(base) = macadr[5];
8815 +  CPMAC_MACADDRMID(base)  = macadr[4];
8816 +  CPMAC_MACADDRHI(base)   = (macadr[0])|(macadr[1]<<8)|(macadr[2]<<16)|(macadr[3]<<24);
8817 +  if(HalDev->debug)
8818 +    {
8819 +     dbgPrintf("MacAddrSet: MacAddr(%d) %X %X %X\n", HalDev->inst, CPMAC_MACADDRLO_0(base),
8820 +                                                     CPMAC_MACADDRMID(base),
8821 +                                                     CPMAC_MACADDRHI(base));
8822 +
8823 +     dbgPrintf("Start MAC: %d\n",HalDev->dev_base);
8824 +     osfuncSioFlush();
8825 +    }
8826 +  return(EC_NO_ERRORS);
8827 +  }
8828 +
8829 +
8830 +/*
8831 +  Updates the MacHash registers
8832 +*/
8833 +static void MacHashSet(HAL_DEVICE *HalDev)
8834 +  {
8835 +  if(HalDev->State <  enOpened)
8836 +    return;
8837 +
8838 +  CPMAC_MACHASH1(HalDev->dev_base) = HalDev->MacHash1;
8839 +  CPMAC_MACHASH2(HalDev->dev_base) = HalDev->MacHash2;
8840 +  if (DBG(11))
8841 +    dbgPrintf("CPMAC[%X]: MacHash1 0x%08X, MacHash2 0x%08X\n", HalDev->dev_base, CPMAC_MACHASH1(HalDev->dev_base), CPMAC_MACHASH2(HalDev->dev_base));
8842 +  }
8843 +
8844 +/*
8845 +  Reads the MacControl register and updates
8846 +  the changable bits. (See MACCONTROL_MASK)
8847 +*/
8848 +static void RxMBP_EnableSet(HAL_DEVICE *HalDev)
8849 +  {
8850 +   bit32u RxMbpEnable;
8851 +   if(HalDev->State <  enOpened)
8852 +     return;
8853 +   RxMbpEnable  = CPMAC_RX_MBP_ENABLE(HalDev->dev_base);
8854 +   RxMbpEnable &= ~RX_MBP_ENABLE_MASK; /* Clear out updatable bits */
8855 +   RxMbpEnable |= HalDev->RxMbpEnable;
8856 +   CPMAC_RX_MBP_ENABLE(HalDev->dev_base) = RxMbpEnable;
8857 +  }
8858 +/*
8859 +  Reads the MacControl register and updates
8860 +  the changable bits. (See MACCONTROL_MASK)
8861 +*/
8862 +static void MacControlSet(HAL_DEVICE *HalDev)
8863 +  {
8864 +   bit32u MacControl;
8865 +   if(HalDev->State <  enOpened)
8866 +     return;
8867 +   MacControl  = CPMAC_MACCONTROL(HalDev->dev_base);
8868 +   MacControl &= ~MACCONTROL_MASK; /* Clear out updatable bits */
8869 +   MacControl |= HalDev->MacControl;
8870 +   if(!(MacControl & MII_EN)) /* If Enable is not set just update register  */
8871 +      CPMAC_MACCONTROL(HalDev->dev_base) = MacControl;
8872 +   else
8873 +     {
8874 +     if(MacControl & CTRL_LOOPBACK)    /*  Loopback Set  */
8875 +       {
8876 +       /* mii_en is set and loopback is needed,
8877 +          clear mii_en, set loopback, then set mii_en
8878 +       */
8879 +       MacControl &= ~MII_EN;  /* Clear MII_EN  */
8880 +       CPMAC_MACCONTROL(HalDev->dev_base) = MacControl;
8881 +       CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN; /* Set MII_EN  */
8882 +       HalDev->Linked = 1; /* if in loopback the logically linked */
8883 +       }
8884 +     else  /* If Loopback not set just update */
8885 +       {
8886 +       CPMAC_MACCONTROL(HalDev->dev_base) = MacControl;
8887 +       }
8888 +     }
8889 +    if(DBG(0))
8890 +      dbgPrintf("[halMacControlSet]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base));
8891 +  }
8892 +static int UnicastSet(HAL_DEVICE *HalDev)
8893 +  {
8894 +  CPMAC_RX_UNICAST_SET(HalDev->dev_base)    = HalDev->RxUnicastSet;
8895 +  CPMAC_RX_UNICAST_CLEAR(HalDev->dev_base)  = HalDev->RxUnicastClear;
8896 +  return(EC_NO_ERRORS);
8897 +  }
8898 +
8899 +  
8900 +static bit32u HashGet(bit8u *Address)
8901 +  {
8902 +  bit32u hash;
8903 +    bit8u  tmpval;
8904 +    int    i;
8905 +
8906 +    hash = 0;
8907 +    for( i=0; i<2; i++ )
8908 +    {
8909 +        tmpval = *Address++;
8910 +        hash  ^= (tmpval>>2)^(tmpval<<4);
8911 +        tmpval = *Address++;
8912 +        hash  ^= (tmpval>>4)^(tmpval<<2);
8913 +        tmpval = *Address++;
8914 +        hash  ^= (tmpval>>6)^(tmpval);
8915 +    }
8916 +
8917 +    return( hash & 0x3F );
8918 +  }
8919 +
8920 +static void HashAdd(HAL_DEVICE *HalDev, bit8u *MacAddress)
8921 +{
8922 +  bit32u HashValue;
8923 +  bit32u HashBit;
8924 +
8925 +  HashValue = HashGet(MacAddress);
8926 +
8927 +  if(HashValue < 32)
8928 +    {
8929 +    HashBit = (1 << HashValue);
8930 +    HalDev->MacHash1 |= HashBit;
8931 +    }
8932 +    else
8933 +    {
8934 +    HashBit = (1 << (HashValue-32));
8935 +    HalDev->MacHash2 |= HashBit;
8936 +    }
8937 +}
8938 +
8939 +static void HashDel(HAL_DEVICE *HalDev, bit8u *MacAddress)
8940 +{
8941 +  bit32u HashValue;
8942 +  bit32u HashBit;
8943 +
8944 +  HashValue = HashGet(MacAddress);
8945 +
8946 +  if(HashValue < 32)
8947 +    {
8948 +    HashBit = (1 << HashValue);
8949 +    HalDev->MacHash1 &= ~HashBit;
8950 +    }
8951 +    else
8952 +    {
8953 +    HashBit = (1 << (HashValue-32));
8954 +    HalDev->MacHash2 &= ~HashBit;
8955 +    }
8956 +}
8957 +
8958 +/*  Replace with an array based on key, with a ptr to the code to do */
8959 +/* e.g.  [enRX_PASS_CRC] = {Set, MBP_UPDATE() } */
8960 +static void DuplexUpdate(HAL_DEVICE *HalDev)
8961 +{
8962 +  int base           = HalDev->dev_base;
8963 +  PHY_DEVICE *PhyDev = HalDev->PhyDev;
8964 +
8965 +  if(HalDev->State <  enOpened)
8966 +    return;
8967 +
8968 +   /* No Phy Condition */
8969 +   if(HalDev->MdioConnect & _CPMDIO_NOPHY)                        /*MJH+030805*/
8970 +   {
8971 +       /*  No Phy condition, always linked */
8972 +       HalDev->Linked     = 1;
8973 +       HalDev->EmacSpeed  = 1;
8974 +       HalDev->EmacDuplex = 1;
8975 +       HalDev->PhyNum     = 0xFFFFFFFF;  /* No Phy Num */
8976 +       CPMAC_MACCONTROL(base) |= FULLDUPLEX;                      /*MJH+030909*/
8977 +       osfuncStateChange();
8978 +       return;
8979 +   }
8980 +
8981 +  if(HalDev->MacControl & CTRL_LOOPBACK)    /*  Loopback Set  */
8982 +    {
8983 +    HalDev->Linked = 1;
8984 +    return;
8985 +    }
8986 +
8987 +  if (HalDev->MdioConnect & _CPMDIO_LOOPBK)
8988 +    {
8989 +    HalDev->Linked = cpMacMdioGetLoopback(HalDev->PhyDev);
8990 +    }
8991 +  else
8992 +    {
8993 +    HalDev->Linked = cpMacMdioGetLinked(HalDev->PhyDev);
8994 +    }
8995 +  if (HalDev->Linked)
8996 +    {
8997 +     /*  Retreive Duplex and Speed and the Phy Number  */
8998 +     if(HalDev->MdioConnect & _CPMDIO_LOOPBK)
8999 +       HalDev->EmacDuplex = 1;
9000 +     else
9001 +       HalDev->EmacDuplex = cpMacMdioGetDuplex(PhyDev);
9002 +     HalDev->EmacSpeed  = cpMacMdioGetSpeed(PhyDev);
9003 +     HalDev->PhyNum     = cpMacMdioGetPhyNum(PhyDev);
9004 +
9005 +     if(HalDev->EmacDuplex)
9006 +       CPMAC_MACCONTROL(base) |= FULLDUPLEX;
9007 +     else
9008 +       CPMAC_MACCONTROL(base) &= ~FULLDUPLEX;
9009 +     if(HalDev->debug)
9010 +        dbgPrintf("%d: Phy= %d, Speed=%s, Duplex=%s\n",HalDev->inst,HalDev->PhyNum,(HalDev->EmacSpeed)?"100":"10",(HalDev->EmacDuplex)?"Full":"Half");
9011 +    }
9012 +  if(HalDev->debug)
9013 +     dbgPrintf("DuplexUpdate[%d]: MACCONTROL 0x%08X, %s\n", HalDev->inst, CPMAC_MACCONTROL(base),(HalDev->Linked)?"Linked":"Not Linked");
9014 +}
9015 +static void MdioSetPhyMode(HAL_DEVICE *HalDev)
9016 +  {
9017 +  unsigned int PhyMode;
9018 +  /* Verify proper device state */
9019 +  if (HalDev->State < enOpened)
9020 +    return;
9021 +
9022 +  PhyMode = NWAY_AUTO|NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10;
9023 +  if(DBG(0))
9024 +    {
9025 +    dbgPrintf("halSetPhyMode1: MdioConnect:%08X ,", HalDev->MdioConnect);
9026 +    dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode,
9027 +           PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100,
9028 +           PhyMode&NWAY_HD100);
9029 +    }
9030 +
9031 +
9032 +  if (  HalDev->MdioConnect & _CPMDIO_NEG_OFF)  /* ~RC3.01                */
9033 +    PhyMode &= ~(NWAY_AUTO);                    /* Disable Auto Neg       */
9034 +  if (!(HalDev->MdioConnect & _CPMDIO_HD))
9035 +    PhyMode &= ~(NWAY_HD100|NWAY_HD10);         /* Cannot support HD      */
9036 +  if (!(HalDev->MdioConnect & _CPMDIO_FD))
9037 +    PhyMode &= ~(NWAY_FD100|NWAY_FD10);         /* Cannot support FD      */
9038 +  if (!(HalDev->MdioConnect & _CPMDIO_10))
9039 +    PhyMode &= ~(NWAY_HD10|NWAY_FD10);          /* Cannot support 10 Mbs  */
9040 +  if (!(HalDev->MdioConnect & _CPMDIO_100))
9041 +    PhyMode &= ~(NWAY_HD100|NWAY_FD100);        /* Cannot support 100 Mbs */
9042 +
9043 +  if(HalDev->MdioConnect & _CPMDIO_AUTOMDIX)   PhyMode |= NWAY_AUTOMDIX; /* Set AutoMdix */
9044 +
9045 +  if (HalDev->CpmacFrequency <= 50000000)
9046 +    PhyMode &= ~(NWAY_FD100|NWAY_HD100); /* Cannot support 100 MBS */
9047 +  if(DBG(7))
9048 +    dbgPrintf("halNeg: PhyMode[0x%08X] %d\n", HalDev->dev_base, PhyMode);
9049 +
9050 +  if(DBG(0))
9051 +    {
9052 +    dbgPrintf("halSetPhyMode2: MdioConnect:%08X ,", HalDev->MdioConnect);
9053 +    dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode,
9054 +               PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100,
9055 +               PhyMode&NWAY_HD100);
9056 +    }
9057 +
9058 +
9059 +  cpMacMdioSetPhyMode(HalDev->PhyDev,PhyMode);
9060 +  DuplexUpdate(HalDev);
9061 +  }
9062 +static int StatsClear(HAL_DEVICE *HalDev)
9063 +{
9064 +  int i;
9065 +  MEM_PTR pStats;
9066 +
9067 +  scOpen(EC_CPMAC);
9068 +
9069 +  pStats = pCPMAC_RXGOODFRAMES(HalDev->dev_base);
9070 +  for (i=0;i<STATS_MAX;i++)
9071 +    {
9072 +    *(MEM_PTR)(pStats) =  0xFFFFFFFF;
9073 +    pStats++;
9074 +    }
9075 +
9076 +  return(EC_NO_ERRORS);
9077 +}
9078 +static void StatsDump(HAL_DEVICE *HalDev, void *Value)
9079 + {
9080 + MEM_PTR ptrStats;
9081 + MEM_PTR ptrValue;
9082 + int i;
9083 + ptrStats = pCPMAC_RXGOODFRAMES(HalDev->dev_base);
9084 + ptrValue = (bit32u*) Value;
9085 + for (i=0; i<STATS_MAX; i++)
9086 +  {
9087 +     *ptrValue = *ptrStats;
9088 +     if(DBG(4))
9089 +      {
9090 +      dbgPrintf("halStatsDump: Stat[%d:0x%08X] %d 0x%08X %d\n", i, ptrStats, *ptrStats, ptrValue, *ptrValue);
9091 +      osfuncSioFlush();
9092 +      }
9093 +     ptrStats++;
9094 +     ptrValue++;
9095 +  }
9096 + }
9097 +static void ConfigApply(HAL_DEVICE *HalDev)
9098 +  {
9099 +  CPMAC_RX_MAXLEN(HalDev->dev_base)          = HalDev->RxMaxLen;
9100 +  CPMAC_RX_FILTERLOWTHRESH(HalDev->dev_base) = HalDev->RxFilterLowThresh;
9101 +  CPMAC_RX0_FLOWTHRESH(HalDev->dev_base)     = HalDev->Rx0FlowThresh;
9102 +  UnicastSet(HalDev);
9103 +  MacAddressSet(HalDev);
9104 +  RxMBP_EnableSet(HalDev);
9105 +  MacHashSet(HalDev);
9106 +  MacControlSet(HalDev);
9107 +  if(DBG(0))
9108 +     dbgPrintf("ValuesUpdate[%d]: MBP_ENABLE 0x%08X\n", HalDev->inst, CPMAC_RX_MBP_ENABLE(HalDev->dev_base));
9109 +  }
9110 +static int halStatus(HAL_DEVICE *HalDev)
9111 +{
9112 +   int status;
9113 +
9114 +    if(HalDev->State <  enOpened)
9115 +      return (EC_CPMAC|EC_FUNC_STATUS|EC_VAL_INVALID_STATE);      /*MJH+030805*/
9116 +
9117 +   /* No Phy Condition */
9118 +   if(HalDev->MdioConnect & _CPMDIO_NOPHY)                        /*MJH+030805*/
9119 +   {
9120 +       /*  No Phy condition, always linked */
9121 +       status = HalDev->Linked;
9122 +       status |= CPMAC_STATUS_LINK_DUPLEX;
9123 +       status |= CPMAC_STATUS_LINK_SPEED;
9124 +       return(status);
9125 +   }
9126 +
9127 +
9128 +   if (HalDev->HostErr)  /* Adapter Check  */
9129 +    {
9130 +    bit32u tmp;
9131 +    status = CPMAC_STATUS_ADAPTER_CHECK;
9132 +    if(HalDev->MacStatus & RX_HOST_ERR_CODE)
9133 +      {
9134 +      status |= CPMAC_STATUS_HOST_ERR_DIRECTION;
9135 +      tmp     = (HalDev->MacStatus & RX_HOST_ERR_CODE) >> 12; /* Code */
9136 +      status |= (tmp << 9); /* Code */
9137 +      tmp     = (HalDev->MacStatus & RX_ERR_CH) >> 8; /* Channel */
9138 +      status |= (tmp << 13);
9139 +      }
9140 +    else
9141 +    if(HalDev->MacStatus & TX_HOST_ERR_CODE)
9142 +      {
9143 +      status |= CPMAC_STATUS_HOST_ERR_DIRECTION;
9144 +      tmp     = (HalDev->MacStatus & TX_HOST_ERR_CODE) >> 20; /* Code */
9145 +      status |= (tmp << 9); /* Code */
9146 +      tmp     = (HalDev->MacStatus & TX_ERR_CH) >> 16; /* Channel */
9147 +      status |= (tmp << 13);
9148 +      }
9149 +    }
9150 +   else
9151 +    {
9152 +    status = HalDev->Linked;
9153 +    if(status)
9154 +      {
9155 +      status = CPMAC_STATUS_LINK;
9156 +      if(cpMacMdioGetDuplex(HalDev->PhyDev))
9157 +        status |= CPMAC_STATUS_LINK_DUPLEX;
9158 +      if(cpMacMdioGetSpeed(HalDev->PhyDev))
9159 +        status |= CPMAC_STATUS_LINK_SPEED;
9160 +      }
9161 +    }
9162 +   if(HalDev->debug)
9163 +      dbgPrintf("[halStatus] Link Status is %d for 0x%X\n", status, HalDev->dev_base);
9164 +   return(status);
9165 +}
9166 +static int InfoAccess(HAL_DEVICE *HalDev, int Key, int Action, void *ParmValue)
9167 +  {
9168 +  int rc = 0;
9169 +  int Update=0;
9170 +
9171 +  switch (Key)
9172 +  {
9173 +    /********************************************************************/
9174 +    /*                                                                  */
9175 +    /*                      GENERAL                                     */
9176 +    /*                                                                  */
9177 +    /********************************************************************/
9178 +
9179 +    case enVersion :
9180 +         if(Action==enGET)
9181 +           {
9182 +           *(const char **)ParmValue = pszVersion_CPMAC;
9183 +           }
9184 +    break;
9185 +    case enDebug  :
9186 +         if(Action==enSET)
9187 +           {
9188 +           HalDev->debug = *(unsigned int *)ParmValue;
9189 +           }
9190 +    break;
9191 +
9192 +    case enStatus      :
9193 +         if(Action==enGET)
9194 +           {
9195 +           int status;
9196 +           status = halStatus(HalDev);
9197 +           *(int *)ParmValue = status;
9198 +           }
9199 +    break;
9200 +    /********************************************************************/
9201 +    /*                                                                  */
9202 +    /*                      RX_MBP_ENABLE                               */
9203 +    /*                                                                  */
9204 +    /********************************************************************/
9205 +
9206 +    case enRX_PASS_CRC  :
9207 +         if(Action==enSET)
9208 +           {
9209 +           UPDATE_RX_PASS_CRC(*(unsigned int *)ParmValue);
9210 +           Update=1;
9211 +           }
9212 +    break;
9213 +    case enRX_QOS_EN  :
9214 +         if(Action==enSET)
9215 +           {
9216 +           UPDATE_RX_QOS_EN(*(unsigned int *)ParmValue);
9217 +           Update=1;
9218 +           }
9219 +    break;
9220 +    case enRX_NO_CHAIN :
9221 +         if(Action==enSET)
9222 +           {
9223 +           UPDATE_RX_NO_CHAIN(*(unsigned int *)ParmValue);
9224 +           Update=1;
9225 +           }
9226 +    break;
9227 +    case enRX_CMF_EN :
9228 +         if(Action==enSET)
9229 +           {
9230 +           UPDATE_RX_CMF_EN(*(unsigned int *)ParmValue);
9231 +           Update=1;
9232 +           }
9233 +    break;
9234 +    case enRX_CSF_EN :
9235 +         if(Action==enSET)
9236 +           {
9237 +           UPDATE_RX_CSF_EN(*(unsigned int *)ParmValue);
9238 +           Update=1;
9239 +           }
9240 +    break;
9241 +    case enRX_CEF_EN :
9242 +         if(Action==enSET)
9243 +           {
9244 +           UPDATE_RX_CEF_EN(*(unsigned int *)ParmValue);
9245 +           Update=1;
9246 +           }
9247 +    break;
9248 +    case enRX_CAF_EN :
9249 +         if(Action==enSET)
9250 +           {
9251 +           UPDATE_RX_CAF_EN(*(unsigned int *)ParmValue);
9252 +           Update=1;
9253 +           }
9254 +    break;
9255 +    case enRX_PROM_CH :
9256 +         if(Action==enSET)
9257 +           {
9258 +           UPDATE_RX_PROM_CH(*(unsigned int *)ParmValue);
9259 +           Update=1;
9260 +           }
9261 +    break;
9262 +    case enRX_BROAD_EN :
9263 +         if(Action==enSET)
9264 +           {
9265 +           UPDATE_RX_BROAD_EN(*(unsigned int *)ParmValue);
9266 +           Update=1;
9267 +           }
9268 +    break;
9269 +    case enRX_BROAD_CH :
9270 +         if(Action==enSET)
9271 +           {
9272 +           UPDATE_RX_BROAD_CH(*(unsigned int *)ParmValue);
9273 +           Update=1;
9274 +           }
9275 +    break;
9276 +    case enRX_MULT_EN :
9277 +         if(Action==enSET)
9278 +           {
9279 +           UPDATE_RX_MULT_EN(*(unsigned int *)ParmValue);
9280 +           Update=1;
9281 +           }
9282 +    break;
9283 +    case enRX_MULT_CH :
9284 +         if(Action==enSET)
9285 +           {
9286 +           UPDATE_RX_MULT_CH(*(unsigned int *)ParmValue);
9287 +           Update=1;
9288 +           }
9289 +    break;
9290 +
9291 +    /********************************************************************/
9292 +    /*                                                                  */
9293 +    /*                      MAC_CONTROL                                 */
9294 +    /*                                                                  */
9295 +    /********************************************************************/
9296 +
9297 +    case enTX_PTYPE :
9298 +         if(Action==enSET)
9299 +           {
9300 +           UPDATE_TX_PTYPE(*(unsigned int *)ParmValue);
9301 +           Update=1;
9302 +           }
9303 +    break;
9304 +    case enTX_PACE :
9305 +         if(Action==enSET)
9306 +           {
9307 +           UPDATE_TX_PACE(*(unsigned int *)ParmValue);
9308 +           Update=1;
9309 +           }
9310 +    break;
9311 +    case enTX_FLOW_EN :
9312 +         if(Action==enSET)
9313 +           {
9314 +           UPDATE_TX_FLOW_EN(*(unsigned int *)ParmValue);
9315 +           Update=1;
9316 +           }
9317 +    break;
9318 +    case enRX_FLOW_EN :
9319 +         if(Action==enSET)
9320 +           {
9321 +           UPDATE_RX_FLOW_EN(*(unsigned int *)ParmValue);
9322 +           Update=1;
9323 +           }
9324 +    break;
9325 +
9326 +    case enCTRL_LOOPBACK :
9327 +         if(Action==enSET)
9328 +           {
9329 +           UPDATE_CTRL_LOOPBACK(*(unsigned int *)ParmValue);
9330 +           Update=1;
9331 +           }
9332 +    break;
9333 +    /********************************************************************/
9334 +    /*                                                                  */
9335 +    /*                      RX_UNICAST_SET                              */
9336 +    /*                                                                  */
9337 +    /********************************************************************/
9338 +
9339 +    case enRX_UNICAST_SET :
9340 +         if(Action==enSET)
9341 +          {
9342 +           HalDev->RxUnicastSet   |=  (1 << *(unsigned int *)ParmValue);
9343 +           HalDev->RxUnicastClear &= ~(1 << *(unsigned int *)ParmValue);
9344 +           Update=1;
9345 +          }
9346 +    break;
9347 +    case enRX_UNICAST_CLEAR :
9348 +         if(Action==enSET)
9349 +          {
9350 +          HalDev->RxUnicastClear |=  (1 << *(unsigned int *)ParmValue);
9351 +          HalDev->RxUnicastSet   &= ~(1 << *(unsigned int *)ParmValue);
9352 +          Update=1;
9353 +          }
9354 +    break;
9355 +
9356 +    case enRX_MAXLEN :
9357 +         if(Action==enSET)
9358 +           {
9359 +           HalDev->RxMaxLen    =   *(unsigned int *)ParmValue;
9360 +           Update=1;
9361 +           }
9362 +    break;
9363 +
9364 +    case enRX_FILTERLOWTHRESH :
9365 +         if(Action==enSET)
9366 +           {
9367 +           HalDev->RxFilterLowThresh  =   *(unsigned int *)ParmValue;
9368 +           Update=1;
9369 +           }
9370 +    break;
9371 +    case enRX0_FLOWTHRESH :
9372 +         if(Action==enSET)
9373 +           {
9374 +           HalDev->Rx0FlowThresh =   *(unsigned int *)ParmValue;
9375 +           Update=1;
9376 +           }
9377 +    break;
9378 +    /********************************************************************/
9379 +    /*                                                                  */
9380 +    /*                      RX_MULTICAST                                */
9381 +    /*                                                                  */
9382 +    /********************************************************************/
9383 +
9384 +    case enRX_MULTICAST :
9385 +    break;
9386 +    case enRX_MULTI_SINGLE :
9387 +         if(DBG(11))
9388 +          {
9389 +           int tmpi;
9390 +           bit8u *MacAddress;
9391 +           MacAddress = (bit8u *) ParmValue;
9392 +           dbgPrintf("CPMAC[%X]:  MacAddress '", HalDev->dev_base);
9393 +           for (tmpi=0; tmpi<6; tmpi++)
9394 +             dbgPrintf("%02X:", MacAddress[tmpi]);
9395 +             dbgPrintf("\n");
9396 +          }
9397 +         if(Action==enCLEAR)
9398 +           {
9399 +           HashDel(HalDev, ParmValue);
9400 +           Update=1;
9401 +           }
9402 +         else
9403 +         if(Action==enSET)
9404 +           {
9405 +           HashAdd(HalDev, ParmValue);
9406 +           Update=1;
9407 +           }
9408 +    break;
9409 +    case enRX_MULTI_ALL :
9410 +         if(Action==enCLEAR)
9411 +           {
9412 +           HalDev->MacHash1 = 0;
9413 +           HalDev->MacHash2 = 0;
9414 +           Update=1;
9415 +           }
9416 +         else
9417 +         if(Action==enSET)
9418 +           {
9419 +           HalDev->MacHash1 = 0xFFFFFFFF;
9420 +           HalDev->MacHash2 = 0xFFFFFFFF;
9421 +           Update=1;
9422 +           }
9423 +    break;
9424 +
9425 +    /********************************************************************/
9426 +    /*                                                                  */
9427 +    /*                      MDIO                                        */
9428 +    /*                                                                  */
9429 +    /********************************************************************/
9430 +
9431 +    case enMdioConnect :
9432 +         if(Action==enSET)
9433 +           {
9434 +           HalDev->MdioConnect = *(unsigned int *)ParmValue;
9435 +           MdioSetPhyMode(HalDev);
9436 +           }
9437 +           if(Action==enGET)
9438 +           {
9439 +           *(unsigned int *)ParmValue = HalDev->MdioConnect;
9440 +           }
9441 +    break;
9442 +
9443 +
9444 +    /********************************************************************/
9445 +    /*                                                                  */
9446 +    /*                      STATISTICS                                  */
9447 +    /*                                                                  */
9448 +    /********************************************************************/
9449 +    case enStatsClear :
9450 +           StatsClear(HalDev);
9451 +    break;
9452 +    case enStatsDump :
9453 +         if(Action==enGET)
9454 +           {
9455 +           StatsDump(HalDev, ParmValue);
9456 +           }
9457 +    break;
9458 +
9459 +/*  Not implemented
9460 +    case enStats1 :
9461 +         if(Action==enGET)
9462 +           {
9463 +           StatsGet(HalDev, ParmValue, 1);
9464 +           }
9465 +    break;
9466 +
9467 +    case enStats2 :
9468 +         if(Action==enGET)
9469 +           {
9470 +           StatsGet(HalDev, ParmValue, 2);
9471 +           }
9472 +    break;
9473 +    case enStats3 :
9474 +         if(Action==enGET)
9475 +           {
9476 +           StatsGet(HalDev, ParmValue, 3);
9477 +           }
9478 +    break;
9479 +    case enStats4 :
9480 +         if(Action==enGET)
9481 +           {
9482 +           StatsGet(HalDev, ParmValue, 4);
9483 +           }
9484 +    break;
9485 +
9486 +*/
9487 +
9488 +    default:
9489 +    rc = EC_CPMAC|EC_FUNC_OPTIONS|EC_VAL_KEY_NOT_FOUND;
9490 +    break;
9491 +  }
9492 +
9493 +  /* Verify proper device state */
9494 +  if (HalDev->State == enOpened)
9495 +    switch (Update)
9496 +      {
9497 +      case 1 :
9498 +           ConfigApply(HalDev);
9499 +      break;
9500 +      default:
9501 +      break;
9502 +      }
9503 +
9504 +  return (rc);
9505 +  }
9506 +static const char pszStats[]       = "Stats;";
9507 +
9508 +static int halControl(HAL_DEVICE *HalDev, const char *pszKey, const char *pszAction, void *Value)
9509 +  {
9510 +  int i;
9511 +  int rc=0;
9512 +  int Action;
9513 +  int ActionFound;
9514 +  int KeyFound;
9515 +
9516 +#ifdef __CPHAL_DEBUG
9517 +  if (DBG(1))
9518 +    {
9519 +    dbgPrintf("\nhalControl-HalDev:%08X,Action:%s,Key:%s\n", (bit32u)HalDev, pszAction, pszKey);
9520 +    }
9521 +#endif
9522 +
9523 +  /* 23Aug04 - BCIL needs to set Mac Address  */
9524 +  if(HalDev->OsFunc->Strcmpi(pszKey, pszMacAddr) == 0)
9525 +    {
9526 +    KeyFound=1;
9527 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9528 +      {
9529 +        unsigned char *MacAddr;  
9530 +        MacAddr = (unsigned char *) Value;  
9531 +        MacAddressSave(HalDev, MacAddr); 
9532 +        MacAddressSet(HalDev);       
9533 +        return(0);
9534 +      }
9535 +    else
9536 +      {
9537 +       return(-1);
9538 +      }
9539 +    }
9540 +     
9541 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcLinked) == 0)
9542 +    {
9543 +    KeyFound=1;
9544 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9545 +      {
9546 +        HalDev->Linked = *(int *)Value;
9547 +        return(0);
9548 +      }
9549 +    else
9550 +      {
9551 +       return(-1);
9552 +      }
9553 +    }
9554 +  
9555 +  if(HalDev->OsFunc->Strcmpi(pszKey, "TxIntDisable") == 0)
9556 +    {
9557 +    KeyFound=1;
9558 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9559 +      {
9560 +        HalDev->TxIntDisable = *(int *)Value;
9561 +        if(HalDev->TxIntDisable && (HalDev->State == enOpened))
9562 +          {
9563 +              /* if Opened and need TxIntDisabled, clear Ints for Channel 0 */
9564 +              CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 1;             
9565 +          }        
9566 +        return(0);
9567 +      }
9568 +    else
9569 +      {
9570 +       return(-1);
9571 +      }
9572 +    }
9573 +
9574 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyAccess) == 0)
9575 +    {
9576 +    bit32u RegAddr;
9577 +    bit32u PhyNum;
9578 +    bit32u Data;
9579 +    bit32u ValueIn;
9580 +
9581 +    ValueIn = *(bit32u*) Value;
9582 +
9583 +    KeyFound=1;
9584 +    /* Cannot access MII if not opended */
9585 +
9586 +    if(HalDev->State < enOpened)
9587 +      return(-1);
9588 +
9589 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9590 +      {
9591 +
9592 +      PhyNum  = (ValueIn & 0x1F);        /* Phynum 0-32 */
9593 +      RegAddr = (ValueIn >> 5) & 0xFF;   /* RegAddr in upper 11 bits */
9594 +
9595 +      *(bit32u*)Value = _mdioUserAccessRead(HalDev->PhyDev, RegAddr, PhyNum);
9596 +
9597 +      return(0);
9598 +      } /* end of hcGet */
9599 +
9600 +
9601 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9602 +      {
9603 +      PhyNum  = (ValueIn & 0x1F);        /* Phynum 0-32 */
9604 +      RegAddr = (ValueIn >> 5) & 0xFF;   /* RegAddr in upper 11 bits of lower 16 */
9605 +
9606 +      Data    = ValueIn >> 16;           /* Data store in upper 16 bits */
9607 +
9608 +      _mdioUserAccessWrite(HalDev->PhyDev, RegAddr, PhyNum, Data);
9609 +      return(0);
9610 +      }
9611 +    } /*  End of hcPhyAccess */
9612 +
9613 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyNum) == 0)
9614 +    {
9615 +    KeyFound=1;
9616 +    if(!HalDev->Linked)
9617 +      return(-1);  /* if not linked the no Phy Connected */
9618 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9619 +      {
9620 +        *(int *)Value = HalDev->PhyNum;
9621 +      return(0);
9622 +      }
9623 +    }
9624 +
9625 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacSize) == 0)
9626 +    {
9627 +    KeyFound=1;
9628 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9629 +      {
9630 +        *(bit32u *)Value = HalDev->CpmacSize;
9631 +      return(0);
9632 +      }
9633 +    }
9634 +
9635 +   if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacBase) == 0)
9636 +    {
9637 +    KeyFound=1;
9638 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9639 +      {
9640 +        *(int *)Value = HalDev->dev_base;
9641 +      return(0);
9642 +      }
9643 +    }
9644 +
9645 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcFullDuplex) == 0)
9646 +    {
9647 +    KeyFound=1;
9648 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9649 +      {
9650 +        UPDATE_FULLDUPLEX(*(unsigned int *)Value);
9651 +        if(HalDev->State == enOpened)
9652 +           ConfigApply(HalDev);
9653 +      return(0);
9654 +      }
9655 +    else
9656 +      return(-1);
9657 +    }
9658 +
9659 +  if(HalDev->OsFunc->Strcmpi(pszKey, pszDebug) == 0)
9660 +    {
9661 +    KeyFound=1;
9662 +    if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9663 +      {
9664 +        ActionFound=1;
9665 +        HalDev->debug = *(int *)Value;
9666 +      }
9667 +    }
9668 +
9669 +  if(HalDev->OsFunc->Strcmpi(pszKey, hcMaxFrags) == 0)
9670 +    {
9671 +     KeyFound=1;
9672 +     if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9673 +       {
9674 +        ActionFound=1;
9675 +
9676 +        if ((*(int *)Value) > 0)
9677 +          HalDev->MaxFrags = *(int *)Value;
9678 +         else
9679 +          rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_INVALID_VALUE);
9680 +      }
9681 +
9682 +     if (HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9683 +       {
9684 +        ActionFound=1;
9685 +
9686 +        *(int *)Value = HalDev->MaxFrags;
9687 +       }
9688 +    }
9689 +
9690 +  if(HalDev->OsFunc->Strstr(pszKey, pszStats) != 0)
9691 +    {
9692 +     KeyFound=1;
9693 +     if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9694 +         {
9695 +       int Level;
9696 +       int Ch;
9697 +       char *TmpKey = (char *)pszKey;
9698 +       ActionFound=1;
9699 +       TmpKey += HalDev->OsFunc->Strlen(pszStats);
9700 +       Level   = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10);
9701 +       TmpKey++;
9702 +       Ch      = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10);
9703 +       TmpKey++;
9704 +       osfuncSioFlush();
9705 +#ifdef __CPHAL_DEBUG
9706 +  if (DBG(1))
9707 +    {
9708 +    dbgPrintf("\nhalControl-HalDev:%08X, Level:%d, Ch:%d\n", (bit32u)HalDev, Level, Ch);
9709 +    }
9710 +#endif
9711 +         StatsGet(HalDev, (void **)Value, Level, Ch, 0);
9712 +       osfuncSioFlush();
9713 +         }
9714 +    }
9715 +
9716 +
9717 +  if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0)
9718 +    Action = enSET;
9719 +  else
9720 +  if(HalDev->OsFunc->Strcmpi(pszAction, hcClear) == 0)
9721 +    Action = enCLEAR;
9722 +  else
9723 +  if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0)
9724 +    Action = enGET;
9725 +  else
9726 +    Action = enNULL;
9727 +
9728 +
9729 +
9730 +  for(i=enCommonStart+1;i<enCommonEnd;i++)
9731 +    {
9732 +    if(HalDev->OsFunc->Strcmpi(KeyCommon[i].strKey, pszKey)==0)
9733 +      {
9734 +      rc = InfoAccess(HalDev, KeyCommon[i].enKey, Action, Value);
9735 +      }
9736 +    }
9737 +  for(i=enCpmacStart+1;i<enCpmacEnd;i++)
9738 +    {
9739 +    if(HalDev->OsFunc->Strcmpi(KeyCpmac[i].strKey, pszKey)==0)
9740 +      {
9741 +      rc = InfoAccess(HalDev, KeyCpmac[i].enKey, Action, Value);
9742 +      }
9743 +    }
9744 +/*
9745 +  if (KeyFound == 0)
9746 +    rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_KEY_NOT_FOUND);
9747 +
9748 +  if (ActionFound == 0)
9749 +    rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_ACTION_NOT_FOUND);
9750 +*/
9751 +
9752 +  return(rc);
9753 +  }
9754 +static bit32u ConfigGet(HAL_DEVICE *HalDev)
9755 +  {
9756 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
9757 +  char *DeviceInfo     = HalDev->DeviceInfo;
9758 +  int i                = HalDev->inst;
9759 +  bit32u Value;
9760 +  int Error;
9761 +
9762 +  /* get the configuration parameters common to all modules */
9763 +  Error = ConfigGetCommon(HalDev);
9764 +  if (Error) return (EC_CPMAC|Error);
9765 +
9766 +  if (HalDev->debug)
9767 +    {
9768 +      dbgPrintf("ConfigGet: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit);
9769 +      osfuncSioFlush();
9770 +    }
9771 +
9772 +  Error = OsFunc->DeviceFindParmUint(DeviceInfo, pszMdioConnect,&Value); /*MJH+030805*/
9773 +  if(!Error) HalDev->MdioConnect = Value;
9774 +
9775 +  Error = OsFunc->DeviceFindParmUint(DeviceInfo, "PhyMask",&Value);
9776 +  if(!Error) HalDev->PhyMask = Value;
9777 +
9778 +  Error = OsFunc->DeviceFindParmUint(DeviceInfo, "MLink",&Value);
9779 +  if(!Error) HalDev->MLinkMask = Value;
9780 +
9781 +  Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcMdixMask, &Value);
9782 +  if(!Error)
9783 +    HalDev->MdixMask = Value;
9784 +  else
9785 +    HalDev->MdixMask = 0;
9786 +
9787 +  Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcSize, &Value); /*MJH+030425*/
9788 +  if(!Error) HalDev->CpmacSize = Value;
9789 +
9790 +  for(i=enCommonStart+1;i<enCommonEnd;i++)
9791 +    {
9792 +    Error = OsFunc->DeviceFindParmUint(DeviceInfo, KeyCommon[i].strKey, (bit32u*)&Value);
9793 +    if(!Error)
9794 +      {
9795 +      InfoAccess(HalDev, KeyCommon[i].enKey, enSET, (bit32u*)&Value);
9796 +      }
9797 +    }
9798 +  for(i=enCpmacStart+1;i<enCpmacEnd;i++)
9799 +    {
9800 +    Error = OsFunc->DeviceFindParmUint(DeviceInfo, KeyCpmac[i].strKey, (bit32u*)&Value);
9801 +    if(!Error)
9802 +      {
9803 +      InfoAccess(HalDev, KeyCpmac[i].enKey, enSET, (bit32u*)&Value);
9804 +      }
9805 +    }
9806 +   return (EC_NO_ERRORS);
9807 +  }
9808 +
9809 +
9810 +static void ConfigInit(HAL_DEVICE *HalDev)
9811 +  {
9812 +  if(HalDev->inst == 0)
9813 +    {
9814 +     HalDev->dev_base  = 0xA8610000;
9815 +     HalDev->ResetBit  = 17;
9816 +     HalDev->interrupt = 19;
9817 +     HalDev->MLinkMask = 0;
9818 +     HalDev->PhyMask   = 0xAAAAAAAA;
9819 +    }
9820 +  else
9821 +    {
9822 +     HalDev->dev_base  = 0xA8612800;
9823 +     HalDev->ResetBit  = 21;
9824 +     HalDev->interrupt = 33;                                         /*~RC3.02*/
9825 +     HalDev->MLinkMask = 0;
9826 +     HalDev->PhyMask   = 0x55555555;
9827 +    }
9828 +  HalDev->RxMaxLen    = 1518;
9829 +  HalDev->MaxFrags    = 2;
9830 +  HalDev->MdioConnect = _CPMDIO_HD|_CPMDIO_FD|_CPMDIO_10|_CPMDIO_100|_CPMDIO_AUTOMDIX;
9831 +  HalDev->debug=0xFFFFFFFF;
9832 +  HalDev->debug=0;
9833 +  }
9834 +/* Shuts down the EMAC device
9835 + *
9836 + *@param HalDev EMAC instance. This was returned by halOpen()
9837 + *@param mode Indicates actions to tak on close.
9838 + <br>
9839 + *PARTIAL - Disable EMAC
9840 + <br>
9841 + *FULL    - Disable EMAC and call OS to free all allocated memory
9842 + *
9843 + *@retval
9844 + *        0 OK
9845 + <br>
9846 + *        Non-Zero Not OK
9847 + *
9848 + */
9849 +static int halInit( HAL_DEVICE *HalDev)
9850 +  {
9851 +   int rc;
9852 +
9853 +  /* Verify proper device state */
9854 +  if (HalDev->State != enDevFound)
9855 +    return(EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_INVALID_STATE);
9856 +
9857 +  /* Configure HAL defaults */
9858 +  ConfigInit(HalDev);
9859 +
9860 +  /* Retrieve HAL configuration parameters from data store */
9861 +  rc = ConfigGet(HalDev);
9862 +  if (rc) return (rc);
9863 +
9864 +  /* Updated 030403*/
9865 +  rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpuFrequency, hcGet, &HalDev->CpuFrequency); /*MJH+030403*/
9866 +  if(rc)
9867 +    HalDev->CpuFrequency = 20000000;  /*20 Mhz default */         /*MJH+030403*/
9868 +
9869 +  rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpmacFrequency, hcGet, &HalDev->CpmacFrequency); /*MJH+030331*/
9870 +  if(rc)
9871 +    HalDev->CpmacFrequency = HalDev->CpuFrequency/2;               /*MJH~030404*/
9872 +
9873 +  rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioBusFrequency,  hcGet, &HalDev->MdioBusFrequency);  /*MJH+030402*/
9874 +  if(rc)
9875 +    HalDev->MdioBusFrequency = HalDev->CpmacFrequency;
9876 +
9877 +  rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioClockFrequency,  hcGet, &HalDev->MdioClockFrequency);  /*MJH+030402*/
9878 +  if(rc)
9879 +    HalDev->MdioClockFrequency = 2200000; /* 2.2 Mhz PITS #14 */
9880 +
9881 +
9882 +  /* update device state */
9883 +  HalDev->State = enInitialized;
9884 +
9885 +  /* initialize statistics */
9886 +  StatsInit(HalDev);                                                  /* +RC3.02 */
9887 +
9888 +  /*                                                                  -RC3.02
9889 +  StatsTable3[0].StatPtr  = &HalDev->ChData[0].RxBufSize;
9890 +  StatsTable3[1].StatPtr  = &HalDev->ChData[0].RxBufferOffset;
9891 +  StatsTable3[2].StatPtr  = &HalDev->ChData[0].RxNumBuffers;
9892 +  StatsTable3[3].StatPtr  = &HalDev->ChData[0].RxServiceMax;
9893 +  StatsTable3[4].StatPtr  = &HalDev->ChData[0].TxNumBuffers;
9894 +  StatsTable3[5].StatPtr  = &HalDev->ChData[0].TxNumQueues;
9895 +  StatsTable3[6].StatPtr  = &HalDev->ChData[0].TxServiceMax;
9896 +  */
9897 +
9898 +  return(EC_NO_ERRORS);
9899 +  }
9900 +static int halProbe(HAL_DEVICE *HalDev)
9901 +  {
9902 +  int inst             = HalDev->inst;
9903 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
9904 +  int error_code;
9905 +
9906 +  if (HalDev->State != enConnected)
9907 +     return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_INVALID_STATE);
9908 +
9909 +  if(HalDev->debug) dbgPrintf("halProbe: %d ",inst);
9910 +
9911 +  error_code = OsFunc->DeviceFindInfo(inst,"cpmac",&HalDev->DeviceInfo);
9912 +
9913 +  if(error_code)
9914 +     return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_DEVICE_NOT_FOUND );
9915 +
9916 +  /* Set device state to DevFound */
9917 +  HalDev->State = enDevFound;
9918 +  return(EC_NO_ERRORS);
9919 +  }
9920 +static void ChannelConfigInit(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn)
9921 +  {
9922 +  int Ch        = HalChn->Channel;
9923 +  int Direction = HalChn->Direction;
9924 +  int nTxBuffers = 256;
9925 +
9926 +  if (Direction == DIRECTION_TX)
9927 +    {
9928 +    HalDev->ChData[Ch].TxNumBuffers   = nTxBuffers;
9929 +    HalDev->ChData[Ch].TxNumQueues    = 1;
9930 +    HalDev->ChData[Ch].TxServiceMax   = nTxBuffers/3;
9931 +    HalDev->TxIntThreshold[Ch]        = HalDev->ChData[Ch].TxServiceMax;
9932 +    HalDev->TxIntThresholdMaster[Ch]  = HalDev->TxIntThreshold[Ch];
9933 +    }
9934 +
9935 +  if (Direction == DIRECTION_RX)
9936 +    {
9937 +    HalDev->ChData[Ch].RxNumBuffers   = nTxBuffers*2;
9938 +    HalDev->ChData[Ch].RxBufferOffset = 0;
9939 +    HalDev->ChData[Ch].RxBufSize      = 1518;
9940 +    HalDev->ChData[Ch].RxServiceMax   = nTxBuffers/3; /*Not a typo*/
9941 +    }
9942 +  }
9943 +static int ChannelConfigApply(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn)
9944 +  {
9945 +   int Ch        = HalChn->Channel;
9946 +   int Direction = HalChn->Direction;
9947 +
9948 +   if (DBG(11))
9949 +     {
9950 +      dbgPrintf("halChannelConfigApply[%d:%d] haldev:0x%08X inst:%d base:0x%08X reset:%d\n", Ch, Direction, (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit);
9951 +      osfuncSioFlush();
9952 +     }
9953 +
9954 +   if (Direction == DIRECTION_TX)
9955 +   {
9956 +     if (HalDev->ChIsOpen[Ch][Direction] == TRUE)
9957 +     {
9958 +      return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_TX_CH_ALREADY_OPEN);
9959 +     }
9960 +
9961 +     /* Initialize Queue Data */
9962 +     HalDev->TxActQueueHead[Ch][0]  = 0;
9963 +     HalDev->TxActQueueCount[Ch][0] = 0;
9964 +     HalDev->TxActive[Ch][0]        = FALSE;
9965 +
9966 +     /* Need to use a macro that takes channel as input */
9967 +     CPMAC_TX0_HDP(HalDev->dev_base)=0;
9968 +
9969 +     /* Initialize buffer memory for the channel */
9970 +     InitTcb(HalDev, Ch);
9971 +
9972 +     if(!HalDev->TxIntDisable)
9973 +       CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<<Ch); /* GSG 11/22 */
9974 +   }
9975 +   else
9976 +   {
9977 +     if (HalDev->ChIsOpen[Ch][Direction] == TRUE)
9978 +     {
9979 +      return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_RX_CH_ALREADY_OPEN);
9980 +     }
9981 +
9982 +     /* Initialize Queue Data */
9983 +     HalDev->RxActQueueHead[Ch]     = 0;
9984 +     HalDev->RxActQueueCount[Ch]    = 0;
9985 +
9986 +     HalDev->RxActive[Ch]           = FALSE;
9987 +
9988 +     /* Need to use a macro that takes channel as input */
9989 +     CPMAC_RX0_HDP(HalDev->dev_base)=0;
9990 +
9991 +     /* Initialize buffer memory for the channel */
9992 +     InitRcb(HalDev, Ch);
9993 +
9994 +     CPMAC_RX_INTMASK_SET(HalDev->dev_base)  = (1<<Ch); /* GSG 11/22 */
9995 +   }
9996 +
9997 +   HalDev->ChIsOpen[Ch][Direction] = TRUE; /* channel is open */
9998 +
9999 +   return (EC_NO_ERRORS);
10000 +  }
10001 +
10002 +/* GSG 11/22
10003 + * Retrieves channel parameters from configuration file.  Any parameters
10004 + * which are not found are ignored, and the HAL default value will apply,
10005 + * unless a new value is given through the channel structure in the call
10006 + * to ChannelSetup.
10007 + */
10008 +static int ChannelConfigGet(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn)
10009 +  {
10010 +  int Ch        = HalChn->Channel;
10011 +  int Direction = HalChn->Direction;
10012 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
10013 +  unsigned int rc, Value;
10014 +  void *ChInfo;
10015 +
10016 +   rc=OsFunc->DeviceFindParmValue(HalDev->DeviceInfo, channel_names[Ch], &ChInfo);
10017 +   /*  Do not fail if Channel Info not available for RC2 */
10018 +   if (rc) return(0);
10019 +/*   if (rc) return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_INFO_NOT_FOUND);*/
10020 +
10021 +   /* i don't care if a value is not found because they are optional */
10022 +   if(Direction == DIRECTION_TX)
10023 +     {
10024 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumBuffers", &Value);
10025 +     if (!rc) HalDev->ChData[Ch].TxNumBuffers = Value;
10026 +
10027 +     /*rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumQueues", &Value);*/ /*MJH-030329*/
10028 +     /*if (!rc) HalDev->ChData[Ch].TxNumQueues = Value;*/              /*MJH-030329*/
10029 +
10030 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "TxServiceMax", &Value);
10031 +     if (!rc) 
10032 +       {
10033 +         HalDev->ChData[Ch].TxServiceMax = Value;
10034 +         HalDev->TxIntThreshold[Ch]      = HalDev->ChData[Ch].TxServiceMax;
10035 +         HalDev->TxIntThresholdMaster[Ch]  = HalDev->TxIntThreshold[Ch];
10036 +       }
10037 +     }
10038 +   if(Direction == DIRECTION_RX)
10039 +     {
10040 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "RxNumBuffers", &Value);
10041 +     if (!rc) HalDev->ChData[Ch].RxNumBuffers = Value;
10042 +
10043 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufferOffset", &Value);
10044 +     if (!rc) HalDev->ChData[Ch].RxBufferOffset = Value;
10045 +
10046 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufSize", &Value);
10047 +     if (!rc) HalDev->ChData[Ch].RxBufSize = Value;
10048 +
10049 +     rc=OsFunc->DeviceFindParmUint(ChInfo, "RxServiceMax", &Value);
10050 +     if (!rc) HalDev->ChData[Ch].RxServiceMax = Value;
10051 +     }
10052 +   return (EC_NO_ERRORS);
10053 +  }
10054 +#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field
10055 +
10056 +static void ChannelConfigUpdate(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn)
10057 +  {
10058 +  int Ch        = HalChn->Channel;
10059 +  int Direction = HalChn->Direction;
10060 +#ifdef __CPHAL_DEBUG
10061 +  if (DBG(1))
10062 +    {
10063 +    dbgPrintf("\nChnUpd-HalDev:%08X,Chn:%d:%d\n", (bit32u)HalDev, Ch, Direction); osfuncSioFlush();
10064 +    }
10065 +#endif
10066 +  if (Direction == DIRECTION_TX)
10067 +    {
10068 +    ChannelUpdate(TxNumBuffers);
10069 +    /*ChannelUpdate(TxNumQueues);*/                               /*MJH~030329*/
10070 +    ChannelUpdate(TxServiceMax);
10071 +    HalDev->TxIntThreshold[Ch]        = HalDev->ChData[Ch].TxServiceMax;
10072 +    HalDev->TxIntThresholdMaster[Ch]  = HalDev->TxIntThreshold[Ch];
10073 +    }
10074 +  else
10075 +  if (Direction == DIRECTION_RX)
10076 +    {
10077 +    ChannelUpdate(RxBufferOffset);
10078 +    ChannelUpdate(RxBufSize);
10079 +    ChannelUpdate(RxNumBuffers);
10080 +    ChannelUpdate(RxServiceMax);
10081 +#ifdef __CPHAL_DEBUG
10082 +  if (DBG(1))
10083 +    {
10084 +    dbgPrintf("\nRxNumBuffers %d\n",HalChn->RxNumBuffers); osfuncSioFlush();
10085 +    }
10086 +#endif
10087 +    }
10088 +  }
10089 +static int halChannelSetup(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn, OS_SETUP *OsSetup)
10090 +  {
10091 +  int Direction;
10092 +  int Ch;
10093 +  int rc;
10094 +
10095 +  /* Verify proper device state */
10096 +  if (HalDev->State < enInitialized)
10097 +    return (EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE);
10098 +
10099 +  /* We require the channel structure to be passed, even if it only contains
10100 +     the channel number */
10101 +  if (HalChn == NULL)
10102 +    {
10103 +     return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_NULL_CH_STRUCT);
10104 +    }
10105 +
10106 +  Ch        = HalChn->Channel;
10107 +  Direction = HalChn->Direction;
10108 +
10109 +  /* This should check on Maximum Channels for RX or TX,
10110 +     they might be different Mick 021124 */
10111 +  if ((Ch < 0) || (Ch > (MAX_CHAN-1)))
10112 +    {
10113 +     return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_CH);
10114 +    }
10115 +
10116 +  /* if channel is already open, this call is invalid */
10117 +  if (HalDev->ChIsOpen[Ch][Direction] == TRUE)
10118 +    {
10119 +     return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_ALREADY_OPEN);
10120 +    }
10121 +
10122 +  /* channel is closed, but might be setup.  If so, reopen the hardware channel. */
10123 +  if (HalDev->ChIsSetup[Ch][Direction] == FALSE)
10124 +    {
10125 +     /* Setup channel configuration */
10126 +     HalDev->ChData[Ch].Channel = Ch;
10127 +
10128 +     /* Store OS_SETUP */
10129 +     HalDev->ChData[Ch].OsSetup = OsSetup;
10130 +
10131 +     /*  Framework :
10132 +         Set Default Values
10133 +         Update with options.conf
10134 +     Apply driver updates
10135 +     */
10136 +     ChannelConfigInit(HalDev, HalChn);
10137 +     ChannelConfigGet(HalDev, HalChn);
10138 +     ChannelConfigUpdate(HalDev, HalChn);
10139 +
10140 +     /* cppi.c needs to use Rx/TxServiceMax */
10141 +     HalDev->BuffersServicedMax  = 169;  /* TEMP */
10142 +
10143 +     HalDev->ChIsSetup[Ch][Direction] = TRUE;
10144 +    }
10145 +
10146 +  rc = EC_NO_ERRORS;
10147 +
10148 +  /* If the hardware has been opened (is out of reset), then configure the channel
10149 +     in the hardware. NOTE: ChannelConfigApply calls the CPSAR ChannelSetup()! */
10150 +  if (HalDev->State == enOpened)
10151 +    {
10152 +     rc = ChannelConfigApply(HalDev, HalChn);
10153 +    }
10154 +
10155 +  return (rc);
10156 +  }
10157 +
10158 +
10159 +static int miiInfoGet(HAL_DEVICE *HalDev, bit32u *miiBaseAddress, bit32u *miiResetBit)
10160 +  {
10161 +  int rc;
10162 +  void *DeviceInfo;
10163 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
10164 +
10165 +  /*  Only one instance of cpmdio   */
10166 +  rc = OsFunc->DeviceFindInfo(0,"cpmdio",&DeviceInfo);               /*~RC3.02*/
10167 +
10168 +  if(rc)
10169 +     return (EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_DEVICE_NOT_FOUND );
10170 +
10171 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",miiBaseAddress);
10172 +  if(rc)
10173 +      rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE;
10174 +
10175 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",miiResetBit);
10176 +  if(rc)
10177 +      rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE;
10178 +
10179 +
10180 +  /* See if need to make mdio functional in GPIO */
10181 +  gpioCheck(HalDev, DeviceInfo);
10182 +
10183 +  if(DBG(0))
10184 +    dbgPrintf("miiBase: 0x%08X %u\n", *miiBaseAddress, *miiResetBit);
10185 +  return(rc);
10186 +  }
10187 +static void ephyCheck(HAL_DEVICE *HalDev)
10188 +  {                                                                  /*+RC3.02*/
10189 +  int rc;
10190 +  void *DeviceInfo;
10191 +  int mii_phy;
10192 +  int reset_bit;
10193 +  OS_FUNCTIONS *OsFunc = HalDev->OsFunc;
10194 +
10195 +  rc = OsFunc->DeviceFindInfo(0,"ephy",&DeviceInfo);
10196 +  if(rc) return;
10197 +
10198 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "mii_phy",&mii_phy);
10199 +  if(rc) return;
10200 +
10201 +  rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit);
10202 +  if(rc) return;
10203 +
10204 +  if (HalDev->PhyMask & (1 << mii_phy))
10205 +    {
10206 +    *(volatile bit32u *)(HalDev->ResetBase) |=  (1 << reset_bit);                      /*+RC3.02*/
10207 +    resetWait(HalDev);
10208 +    }
10209 +  }                                                                  /*+RC3.02*/
10210 +static void AutoNegotiate(HAL_DEVICE *HalDev)
10211 +  {
10212 +  int size;
10213 +  bit32u ModID,  RevMaj,  RevMin;
10214 +  PHY_DEVICE *PhyDev;
10215 +  bit32u miiBaseAddress;
10216 +  bit32u miiResetBit;
10217 +
10218 +  /* Verify proper device state */
10219 +  if (HalDev->State < enOpened)
10220 +    return;
10221 +
10222 +  miiInfoGet(HalDev, &miiBaseAddress, &miiResetBit);
10223 +
10224 +  cpMacMdioGetVer(miiBaseAddress, &ModID,  &RevMaj,  &RevMin);
10225 +  if(HalDev->debug)
10226 +     dbgPrintf("Mdio Module Id %d, Version %d.%d\n", ModID,  RevMaj,  RevMin);
10227 +
10228 +  size = cpMacMdioGetPhyDevSize();
10229 +  PhyDev = (PHY_DEVICE *) HalDev->OsFunc->Malloc( size );
10230 +
10231 +  HalDev->PhyDev = PhyDev;
10232 +
10233 +  ephyCheck(HalDev);
10234 +
10235 +  cpMacMdioInit( PhyDev, miiBaseAddress, HalDev->inst, HalDev->PhyMask, HalDev->MLinkMask, HalDev->MdixMask, HalDev->ResetBase, miiResetBit, HalDev->MdioBusFrequency, HalDev->MdioClockFrequency, HalDev->debug, HalDev); /*MJH~030402*/
10236 +  MdioSetPhyMode(HalDev);
10237 +
10238 +  return;
10239 +  }
10240 +static int halOpen(HAL_DEVICE *HalDev)
10241 +  {
10242 +  unsigned char *MacAddr;
10243 +  int i;
10244 +  int j;
10245 +  int rc, Ticks;
10246 +
10247 +  if (HalDev->debug)
10248 +    {
10249 +      dbgPrintf("halOpen: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit);
10250 +      osfuncSioFlush();
10251 +    }
10252 +
10253 +   /* Verify proper device state */
10254 +   if (HalDev->State < enInitialized)
10255 +     return (EC_CPMAC|EC_FUNC_OPEN|EC_VAL_INVALID_STATE);
10256 +
10257 +
10258 +  /* take CPMAC out of reset - GSG 11/20*/
10259 +  if ((VOLATILE32(HalDev->ResetBase) & (1 << HalDev->ResetBit)) != 0)
10260 +    {
10261 +     /* perform normal close duties */
10262 +     CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN;
10263 +     CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN;
10264 +     CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN;
10265 +
10266 +     /* disable interrupt masks */
10267 +     CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF;
10268 +     CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF;
10269 +    }
10270 +
10271 +   /* take CPMAC out of reset */
10272 +   *(volatile bit32u *)(HalDev->ResetBase) &= ~(1 << HalDev->ResetBit);
10273 +   resetWait(HalDev);
10274 +   *(volatile bit32u *)(HalDev->ResetBase) |=  (1 << HalDev->ResetBit);
10275 +   resetWait(HalDev);
10276 +
10277 +  /* After Reset clear the Transmit and Receive DMA Head Descriptor Pointers */
10278 +
10279 +  CPMAC_TX0_HDP(HalDev->dev_base)=0;
10280 +  CPMAC_TX1_HDP(HalDev->dev_base)=0;
10281 +  CPMAC_TX2_HDP(HalDev->dev_base)=0;
10282 +  CPMAC_TX3_HDP(HalDev->dev_base)=0;
10283 +  CPMAC_TX4_HDP(HalDev->dev_base)=0;
10284 +  CPMAC_TX5_HDP(HalDev->dev_base)=0;
10285 +  CPMAC_TX6_HDP(HalDev->dev_base)=0;
10286 +  CPMAC_TX7_HDP(HalDev->dev_base)=0;
10287 +
10288 +  /* Rx Init  */
10289 +
10290 +  CPMAC_RX0_HDP(HalDev->dev_base) = 0;
10291 +  CPMAC_RX1_HDP(HalDev->dev_base) = 0;
10292 +  CPMAC_RX2_HDP(HalDev->dev_base) = 0;
10293 +  CPMAC_RX3_HDP(HalDev->dev_base) = 0;
10294 +  CPMAC_RX4_HDP(HalDev->dev_base) = 0;
10295 +  CPMAC_RX5_HDP(HalDev->dev_base) = 0;
10296 +  CPMAC_RX6_HDP(HalDev->dev_base) = 0;
10297 +  CPMAC_RX7_HDP(HalDev->dev_base) = 0;
10298 +
10299 +  CPMAC_RX_BUFFER_OFFSET(HalDev->dev_base) = 0;
10300 +
10301 +  /* Init Tx and Rx DMA */
10302 +
10303 +  CPMAC_TX_CONTROL(HalDev->dev_base) |= TX_EN;
10304 +  CPMAC_RX_CONTROL(HalDev->dev_base) |= RX_EN;
10305 +
10306 +  CPMAC_MAC_INTMASK_SET(HalDev->dev_base) |=2; /* Enable Adaptercheck Ints */
10307 +  HalDev->OsFunc->Control(HalDev->OsDev, pszMacAddr, hcGet, &MacAddr); /* GSG 11/22 */
10308 +  MacAddressSave(HalDev, MacAddr);
10309 +
10310 +  HalDev->HostErr = 0;      /* Clear Adapter Check indicator */
10311 +  HalDev->State = enOpened; /* Change device state */
10312 +
10313 +  /* Start MDIO Negotiation */
10314 +  AutoNegotiate(HalDev);
10315 +
10316 +  /*  Enable the Os Timer  */
10317 +  Ticks = HalDev->CpuFrequency / 100;  /*  10 milli-secs */       /*MJH~030402*/
10318 +  HalDev->OsFunc->Control(HalDev->OsDev, pszTick, hcSet, &Ticks); /* GSG 11/22 */
10319 +  HalDev->OsFunc->IsrRegister(HalDev->OsDev, halIsr, HalDev->interrupt);
10320 +
10321 +  /* GSG +030523 Malloc space for the Rx fraglist */
10322 +  HalDev->fraglist = HalDev->OsFunc->Malloc(HalDev->MaxFrags * sizeof(FRAGLIST));
10323 +
10324 +  /* Any pre-open configuration */
10325 +
10326 +  /* For any channels that have been pre-initialized, set them up now */
10327 +  /* Note : This loop should not use MAX_CHN, it should only
10328 +            loop through Channels Setup, memory should not be reserved
10329 +            until Channel is Setup
10330 +  */
10331 +  for(i=0; i<MAX_CHAN; i++) /* i loops through Channels */
10332 +  for(j=0; j<2; j++)        /* j loops through DIRECTION values, 0 and 1  */
10333 +    {
10334 +     if(HalDev->ChIsSetup[i][j]==TRUE)   /* If the Channel and Direction have been Setup */
10335 +       if(HalDev->ChIsOpen[i][j]==FALSE) /* but not opened, then Apply Values now */
10336 +         {
10337 +          CHANNEL_INFO HalChn;
10338 +          HalChn.Channel   = i;
10339 +          HalChn.Direction = j;
10340 +          rc = ChannelConfigApply(HalDev, &HalChn);
10341 +          if(rc != EC_NO_ERRORS)
10342 +            return(rc);
10343 +         }
10344 +    }  /* End of looping through Channel/Direction */
10345 +
10346 +  ConfigApply(HalDev);  /* Apply Configuration Values to Device */
10347 +  CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN;  /* MAC_EN */
10348 +  if(DBG(0))
10349 +     dbgPrintf("[halOpen]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base));
10350 +  return(EC_NO_ERRORS);
10351 +  }
10352 +
10353 +#define INT_PENDING (MAC_IN_VECTOR_TX_INT_OR | MAC_IN_VECTOR_RX_INT_OR | MAC_IN_VECTOR_HOST_INT)
10354 +static int halShutdown(HAL_DEVICE *HalDev)
10355 +  {
10356 +   int Ch, Queue;                                                  /*GSG+030514*/
10357 +
10358 +   /* Verify proper device state */
10359 +   if (HalDev->State == enOpened)
10360 +     halClose(HalDev, 3); /* GSG ~030429 */
10361 +
10362 +   /* Buffer/descriptor resources may still need to be freed if a Close
10363 +      Mode 1 was performed prior to Shutdown - clean up here */    /*GSG+030514*/
10364 +   for (Ch=0; Ch<MAX_CHAN; Ch++)
10365 +     {
10366 +      if (HalDev->RcbStart[Ch] != 0)
10367 +        FreeRx(HalDev,Ch);
10368 +
10369 +      for(Queue=0; Queue<MAX_QUEUE; Queue++)
10370 +        {
10371 +         if (HalDev->TcbStart[Ch][Queue] != 0)
10372 +           FreeTx(HalDev,Ch,Queue);
10373 +        }
10374 +     }
10375 +
10376 +   /* free the HalFunc */
10377 +   HalDev->OsFunc->Free(HalDev->HalFuncPtr);
10378 +
10379 +   /* free the HAL device */
10380 +   HalDev->OsFunc->Free(HalDev);
10381 +
10382 +   return(EC_NO_ERRORS);
10383 +  }
10384 +int halIsr(HAL_DEVICE *HalDev, int *MorePackets)
10385 +{
10386 +  bit32u IntVec;
10387 +  int Serviced;
10388 +  int PacketsServiced=0;
10389 +  int Channel;
10390 +  int TxMorePackets=0;
10391 +  int RxMorePackets=0;
10392 +
10393 +  /* Verify proper device state - important because a call prior to Open would
10394 +      result in a lockup */
10395 +  if (HalDev->State != enOpened)
10396 +     return(EC_CPMAC|EC_FUNC_DEVICE_INT|EC_VAL_INVALID_STATE);
10397 +
10398 +  IntVec = CPMAC_MAC_IN_VECTOR(HalDev->dev_base);
10399 +
10400 +#ifdef __CPHAL_DEBUG
10401 +  if (DBG(0))
10402 +    {
10403 +    dbgPrintf("\nhalIsr: inst %d, IntVec 0x%X\n", HalDev->inst, IntVec); osfuncSioFlush();/* GSG 11/22 */
10404 +    }
10405 +#endif
10406 +
10407 +  HalDev->IntVec = IntVec;
10408 +  if (IntVec & MAC_IN_VECTOR_TX_INT_OR)
10409 +   {
10410 +     int TxServiceMax=0;  /* Compiler complains if not initialized */
10411 +      
10412 +     Channel = (IntVec & 0x7);
10413 +     
10414 +     if(HalDev->TxIntDisable)
10415 +       {
10416 +         CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Channel);  /* Disable Interrupt for Channel */           
10417 +         TxServiceMax = HalDev->ChData[Channel].TxServiceMax;  
10418 +         HalDev->ChData[Channel].TxServiceMax = 10000;             /* Need to service all packets in the Queue */
10419 +       }      
10420 +     
10421 +     PacketsServiced |= TxInt(HalDev, Channel, 0, &TxMorePackets);
10422 +     
10423 +     if(HalDev->TxIntDisable)        
10424 +          HalDev->ChData[Channel].TxServiceMax  = TxServiceMax;         
10425 +    }
10426 +  
10427 +  if (IntVec & MAC_IN_VECTOR_RX_INT_OR)
10428 +    {
10429 +     Channel = (IntVec >> 8) & 0x7;
10430 +     Serviced = RxInt(HalDev, Channel, &RxMorePackets);
10431 +     PacketsServiced |= (Serviced<<16);
10432 +    }
10433 +
10434 +  if (IntVec & MAC_IN_VECTOR_HOST_INT)
10435 +    {
10436 +    /* Adaptercheck */
10437 +    HalDev->HostErr = 1;
10438 +    HalDev->MacStatus = CPMAC_MACSTATUS(HalDev->dev_base);
10439 +    osfuncStateChange();                                          /*MJH+030328*/
10440 +    if(DBG(0))
10441 +      {
10442 +      dbgPrintf("Adaptercheck: %08x for base:%X\n",HalDev->MacStatus, (bit32u)HalDev->dev_base);
10443 +      osfuncSioFlush();
10444 +      }
10445 +    }
10446 +  *MorePackets = (TxMorePackets | RxMorePackets);
10447 +  return (PacketsServiced);
10448 +}
10449 +
10450 +int halPacketProcessEnd(HAL_DEVICE *HalDev)
10451 +{
10452 +  int base             = HalDev->dev_base;
10453 +  CPMAC_MAC_EOI_VECTOR(base) = 0;
10454 +  return(0);
10455 +}
10456 +
10457 +
10458 +
10459 +static int PhyCheck(HAL_DEVICE *HalDev)
10460 +  {
10461 +      return(cpMacMdioTic(HalDev->PhyDev));
10462 +  }
10463 +static int halTick(HAL_DEVICE *HalDev)
10464 +{
10465 +    int TickChange;
10466 +
10467 +    if(HalDev->State <  enOpened)
10468 +      return (EC_CPMAC|EC_FUNC_TICK|EC_VAL_INVALID_STATE);
10469 +
10470 +    /* if NO Phy no need to check Link */
10471 +    if(HalDev->MdioConnect & _CPMDIO_NOPHY)
10472 +      return(EC_NO_ERRORS);  /* No change in Phy State detected */
10473 +
10474 +    TickChange = PhyCheck(HalDev);
10475 +    /* Phy State Change Detected */
10476 +    if(TickChange == 1)
10477 +    {
10478 +        /*  MDIO indicated a change  */
10479 +        DuplexUpdate(HalDev);
10480 +        osfuncStateChange();
10481 +        return(EC_NO_ERRORS);
10482 +    }
10483 +
10484 +    /* if in AutoMdix mode, and Flip request received, inform OS */
10485 +    if( (HalDev->MdioConnect & _CPMDIO_AUTOMDIX)  &&
10486 +        (TickChange & _MIIMDIO_MDIXFLIP))
10487 +    {
10488 +       bit32u Mdix;
10489 +       Mdix = TickChange & 0x1;   /*  Mdix mode stored in bit 0 */
10490 +       HalDev->OsFunc->Control(HalDev->OsDev, hcMdioMdixSwitch, hcSet, &Mdix);
10491 +       return(EC_NO_ERRORS);
10492 +    }
10493 +
10494 +    return(EC_NO_ERRORS);
10495 +}
10496 +
10497 +int halCpmacInitModule(HAL_DEVICE **pHalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS **pHalFunc,
10498 +                       OS_FUNCTIONS *OsFunc, int OsFuncSize,     int *HalFuncSize, int Inst)
10499 +  {
10500 +    HAL_DEVICE *HalDev;
10501 +    HAL_FUNCTIONS *HalFunc;
10502 +
10503 +    if (OsFuncSize < sizeof(OS_FUNCTIONS))
10504 +      return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_OS_VERSION_NOT_SUPPORTED);
10505 +
10506 +    HalDev = (HAL_DEVICE *) OsFunc->MallocDev(sizeof(HAL_DEVICE));
10507 +    if (!HalDev)
10508 +      return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_DEV_FAILED);
10509 +
10510 +    /* clear the HalDev area */
10511 +    OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE));
10512 +
10513 +    /* Initialize the size of hal functions */
10514 +    *HalFuncSize = sizeof (HAL_FUNCTIONS);
10515 +
10516 +    HalFunc = (HAL_FUNCTIONS *) OsFunc->Malloc(sizeof(HAL_FUNCTIONS));
10517 +    if (!HalFunc)
10518 +      return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_FAILED);
10519 +
10520 +    /* clear the function pointers */
10521 +    OsFunc->Memset(HalFunc, 0, sizeof(HAL_FUNCTIONS));
10522 +
10523 +    HalDev->OsDev   = OsDev;
10524 +    HalDev->OsOpen  = OsDev;
10525 +    HalDev->inst    = Inst;
10526 +    HalDev->OsFunc  = OsFunc;
10527 +    HalDev->HalFunc = HalFunc;
10528 +    /* Remove the following from cppi, replace with HalFunc */
10529 +    HalDev->HalFuncPtr = HalFunc; /* GSG 11/20 changed name to match cppi */
10530 +
10531 +    /****************************************************************/
10532 +    /*                 POPULATE HALFUNC                             */
10533 +    /****************************************************************/
10534 +    HalFunc->ChannelSetup     = halChannelSetup;
10535 +    HalFunc->ChannelTeardown  = halChannelTeardown; /* GSG 11/20 */
10536 +    HalFunc->Close            = halClose; /* GSG 11/20 */
10537 +    HalFunc->Control          = halControl; /* GSG 11/22 */
10538 +    HalFunc->Init             = halInit;
10539 +    HalFunc->Open             = halOpen;
10540 +    HalFunc->PacketProcessEnd = halPacketProcessEnd;
10541 +    HalFunc->Probe            = halProbe;
10542 +    HalFunc->RxReturn         = halRxReturn;
10543 +    HalFunc->Send             = halSend;
10544 +    HalFunc->Shutdown         = halShutdown;
10545 +    HalFunc->Tick             = halTick;
10546 +
10547 +    /* HalFunc->Status        = halStatus;*/ /* GSG 11/22 */
10548 +    /* pass the HalDev and HalFunc back to the caller */
10549 +
10550 +    *pHalDev  = HalDev;
10551 +    *pHalFunc = HalFunc;
10552 +
10553 +    HalDev->State = enConnected;   /* Initialize the hardware state */
10554 +
10555 +    if (HalDev->debug) HalDev->OsFunc->Printf("halCpmacInitModule: Leave\n");
10556 +    return(0);
10557 +  }
10558 +
10559 +int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max)
10560 +{
10561 +    int iTmp;
10562 +    iTmp  = cpmacRandom(HalDev);
10563 +    iTmp %= ((max-min)+1);
10564 +    iTmp += min;
10565 +    return(iTmp);
10566 +}
10567 +
10568 +int cpmacRandom(HAL_DEVICE *HalDev)
10569 +{
10570 +    int iTmp;
10571 +    iTmp = CPMAC_BOFFTEST(HalDev->dev_base);
10572 +    iTmp >>= 16;      /*  get rndnum field */
10573 +    iTmp &= (0x3FF); /* field is 10 bits wide */
10574 +    return(iTmp);
10575 +}
10576 diff -urN linux.old/drivers/net/avalanche_cpmac/hcpmac.h linux.dev/drivers/net/avalanche_cpmac/hcpmac.h
10577 --- linux.old/drivers/net/avalanche_cpmac/hcpmac.h      1970-01-01 01:00:00.000000000 +0100
10578 +++ linux.dev/drivers/net/avalanche_cpmac/hcpmac.h      2005-07-12 02:48:42.175574000 +0200
10579 @@ -0,0 +1,383 @@
10580 +/** @file***********************************************************************
10581 + *  TNETDxxxx Software Support
10582 + *  Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved.
10583 + *
10584 + *  FILE:
10585 + *
10586 + *  DESCRIPTION:
10587 + *      This file contains definitions for the HAL EMAC API
10588 + *
10589 + *  HISTORY:
10590 + *  xxXxx01 Denis      1.00  Original Version created.
10591 + *  22Jan02 Denis/Mick 1.01  Modified for HAL EMAC API
10592 + *  24Jan02 Denis/Mick 1.02  Speed Improvements
10593 + *  28Jan02 Denis/Mick 1.16  Made function calls pointers
10594 + *  28Jan02 Mick       1.18  Split into separate modules
10595 + *  @author Michael Hanrahan
10596 + *  @version 1.02
10597 + *  @date    24-Jan-2002
10598 + *****************************************************************************/
10599 +#ifndef _INC_HCPMAC
10600 +#define _INC_HCPMAC
10601 +
10602 +/** \namespace CPMAC_Version
10603 +This documents version 01.07.04 of the CPMAC CPHAL.
10604 +*/
10605 +const char *pszVersion_CPMAC="CPMAC 01.07.08 "__DATE__" "__TIME__;
10606 +
10607 +/* CHECK THESE LOCATIONS */
10608 +#define TEARDOWN_VAL       0xfffffffc
10609 +#define CB_OFFSET_MASK     0xFFFF0000
10610 +
10611 +
10612 +#define MAX_CHAN 8
10613 +#define MAX_QUEUE 1
10614 +
10615 +typedef struct
10616 +  {
10617 +  bit32 HNext;      /*< Hardware's pointer to next buffer descriptor  */
10618 +  bit32 BufPtr;     /*< Pointer to the data buffer                    */
10619 +  bit32 Off_BLen;   /*< Contains buffer offset and buffer length      */
10620 +  bit32 mode;       /*< SOP, EOP, Ownership, EOQ, Teardown, Q Starv, Length */
10621 +  void *Next;
10622 +  void *OsInfo;
10623 +  void *Eop;
10624 +#ifdef __CPHAL_DEBUG
10625 +  bit32 DbgSop;
10626 +  bit32 DbgData;
10627 +  bit32 DbgFraglist;
10628 +#endif
10629 +  }HAL_TCB;
10630 +
10631 +typedef volatile struct hal_private
10632 +  {
10633 +  bit32 HNext;      /*< Hardware's pointer to next buffer descriptor     */
10634 +  bit32 BufPtr;     /*< Pointer to the data buffer                       */
10635 +  bit32 Off_BLen;   /*< Contains buffer offset and buffer length         */
10636 +  bit32 mode;       /*< SOP, EOP, Ownership, EOQ, Teardown Complete bits */
10637 +  void *DatPtr;
10638 +  void *Next;
10639 +  void *OsInfo;
10640 +  void *Eop;
10641 +  }HAL_RCB;
10642 +
10643 +#define MAX_NEEDS 512                                             /*MJH+030409*/
10644 +/*  HAL  */
10645 +
10646 +typedef struct hal_device
10647 +  {
10648 +  OS_DEVICE *OsDev;
10649 +  OS_FUNCTIONS *OsFunc;
10650 +    /*OS_SETUP *OsSetup;*/                                     /* -GSG 030508 */
10651 +  int inst;
10652 +  bit32u rxbufseq;
10653 +
10654 +
10655 +  bit32 dev_base;
10656 +  bit32  offset;
10657 +
10658 +  bit32u ResetBase; /* GSG 10/20 */
10659 +  int ResetBit;
10660 +  void *OsOpen;
10661 +  bit32u IntVec;
10662 +  PHY_DEVICE *PhyDev;
10663 +  bit32u EmacDuplex;
10664 +  bit32u EmacSpeed;
10665 +  bit32u PhyNum;
10666 +  bit32u MLinkMask;
10667 +  bit32u PhyMask;
10668 +  bit32u MdixMask;
10669 +
10670 +  bit32u Linked;
10671 +  DEVICE_STATE State;
10672 +  unsigned char *MacAddr;
10673 +  HAL_FUNCTIONS *HalFuncPtr; /* GSG 11/20 changed name to match cppi */
10674 +  HAL_FUNCTIONS *HalFunc;
10675 +/*  unsigned int CpuFreq;*/                                       /*MJH-030402*/
10676 +  unsigned int MdioConnect;
10677 +  unsigned int HostErr;
10678 +
10679 +/************************************************************************/
10680 +/*                                                                      */
10681 +/*      R E G I S T E R S                                               */
10682 +/*                                                                      */
10683 +/************************************************************************/
10684 +
10685 +  bit32u RxMbpEnable;
10686 +  bit32u RxUnicastSet;
10687 +  bit32u RxUnicastClear;
10688 +  bit32u RxMaxLen;
10689 +  bit32u RxFilterLowThresh;
10690 +  bit32u Rx0FlowThresh;
10691 +  bit32u MacControl;
10692 +  bit32u MacStatus;
10693 +  bit32u MacHash1;
10694 +  bit32u MacHash2;
10695 +
10696 +/************************************************************************/
10697 +/*                                                                      */
10698 +/*      O P T I O N S                                                   */
10699 +/*                                                                      */
10700 +/************************************************************************/
10701 +
10702 +  char *DeviceInfo;
10703 +  bit32u interrupt;
10704 +
10705 +
10706 +  bit32u RxPassCrc;
10707 +  bit32u RxCaf;
10708 +  bit32u RxCef;
10709 +  bit32u RxBcast;
10710 +  bit32u RxBcastCh;
10711 +  HAL_RCB *RcbPool[MAX_CHAN];
10712 +  bit32 RxActQueueCount[MAX_CHAN];
10713 +  HAL_RCB *RxActQueueHead[MAX_CHAN];
10714 +  HAL_RCB *RxActQueueTail[MAX_CHAN];
10715 +  bit32 RxActive[MAX_CHAN];
10716 +  HAL_TCB *TcbPool[MAX_CHAN][MAX_QUEUE];
10717 +  bit32 TxActQueueCount[MAX_CHAN][MAX_QUEUE];
10718 +  HAL_TCB *TxActQueueHead[MAX_CHAN][MAX_QUEUE];
10719 +  HAL_TCB *TxActQueueTail[MAX_CHAN][MAX_QUEUE];
10720 +  bit32 TxActive[MAX_CHAN][MAX_QUEUE];
10721 +  bit32 TxTeardownPending[MAX_CHAN];
10722 +  bit32 RxTeardownPending[MAX_CHAN];
10723 +  bit32 ChIsOpen[MAX_CHAN][2];
10724 +  bit32 ChIsSetup[MAX_CHAN][2];
10725 +  FRAGLIST *fraglist;
10726 +  char *TcbStart[MAX_CHAN][MAX_QUEUE];
10727 +  char *RcbStart[MAX_CHAN];
10728 +  bit32 RcbSize[MAX_CHAN];
10729 +/*  STAT_INFO Stats;  */
10730 +  bit32  Inst;
10731 +  bit32u BuffersServicedMax;
10732 +  CHANNEL_INFO ChData[MAX_CHAN];
10733 +  bit32u MdioClockFrequency;                                      /*MJH+030402*/
10734 +  bit32u MdioBusFrequency;                                        /*MJH+030402*/
10735 +  bit32u CpuFrequency;                                            /*MJH+030402*/
10736 +  bit32u CpmacFrequency;                                          /*MJH+030403*/
10737 +  bit32u CpmacSize;                                               /*MJH+030425*/
10738 +  int debug;
10739 +  bit32u NeedsCount;                                              /*MJH+030409*/
10740 +  HAL_RECEIVEINFO *Needs[MAX_NEEDS];                              /*MJH+030409*/
10741 +  int MaxFrags;
10742 +  int TxIntThreshold[MAX_CHAN];                   /* MJH 040621  NSP Performance Update */
10743 +  int TxIntThresholdMaster[MAX_CHAN];             /* MJH 040827  NSP Performance Update */
10744 +  int TxIntDisable;                     /* MJH 040621  NSP Performance Update */  
10745 +  }HALDEVICE;
10746 +
10747 +#define STATS_MAX 36
10748 +
10749 +#define MACCONTROL_MASK    (TX_PTYPE|TX_PACE|TX_FLOW_EN|RX_FLOW_EN|CTRL_LOOPBACK)
10750 +#define RX_MBP_ENABLE_MASK                                       \
10751 +        (RX_PASS_CRC|RX_QOS_EN|RX_NO_CHAIN|                      \
10752 +         RX_CMF_EN|RX_CSF_EN|RX_CEF_EN|RX_CAF_EN|RX_PROM_CH_MASK|     \
10753 +         RX_BROAD_EN|RX_BROAD_CH_MASK|RX_MULT_EN|RX_MULT_CH_MASK)
10754 +
10755 +
10756 +#define MBP_UPDATE(Mask, On)                      \
10757 +         if(On)   HalDev->RxMbpEnable |=  Mask;   \
10758 +         else     HalDev->RxMbpEnable &= ~Mask
10759 +
10760 +#define CONTROL_UPDATE(Mask, On)                  \
10761 +         if(On)   HalDev->MacControl |=  Mask;    \
10762 +         else     HalDev->MacControl &= ~Mask
10763 +
10764 +
10765 +#define UPDATE_TX_PTYPE(Value)       CONTROL_UPDATE(TX_PTYPE,Value)
10766 +#define UPDATE_TX_PACE(Value)        CONTROL_UPDATE(TX_PACE,Value)
10767 +#define UPDATE_MII_EN(Value)         CONTROL_UPDATE(MII_EN,Value)
10768 +#define UPDATE_TX_FLOW_EN(Value)     CONTROL_UPDATE(TX_FLOW_EN,Value)
10769 +#define UPDATE_RX_FLOW_EN(Value)     CONTROL_UPDATE(RX_FLOW_EN,Value)
10770 +#define UPDATE_CTRL_LOOPBACK(Value)  CONTROL_UPDATE(CTRL_LOOPBACK,Value)
10771 +#define UPDATE_FULLDUPLEX(Value)     CONTROL_UPDATE(FULLDUPLEX,(Value))
10772 +
10773 +#define UPDATE_RX_PASS_CRC(Value)    MBP_UPDATE(RX_PASS_CRC,  Value)
10774 +#define UPDATE_RX_QOS_EN(Value)      MBP_UPDATE(RX_QOS_EN,    Value)
10775 +#define UPDATE_RX_NO_CHAIN(Value)    MBP_UPDATE(RX_NO_CHAIN,  Value)
10776 +#define UPDATE_RX_CMF_EN(Value)      MBP_UPDATE(RX_CMF_EN,    Value)
10777 +#define UPDATE_RX_CSF_EN(Value)      MBP_UPDATE(RX_CSF_EN,    Value)
10778 +#define UPDATE_RX_CEF_EN(Value)      MBP_UPDATE(RX_CEF_EN,    Value)
10779 +#define UPDATE_RX_CAF_EN(Value)      MBP_UPDATE(RX_CAF_EN,    Value)
10780 +#define UPDATE_RX_BROAD_EN(Value)    MBP_UPDATE(RX_BROAD_EN,  Value)
10781 +#define UPDATE_RX_MULT_EN(Value)     MBP_UPDATE(RX_MULT_EN,   Value)
10782 +
10783 +#define UPDATE_RX_PROM_CH(Value)                         \
10784 +        HalDev->RxMbpEnable &=  ~RX_PROM_CH_MASK;        \
10785 +        HalDev->RxMbpEnable |=   RX_PROM_CH(Value)
10786 +
10787 +#define UPDATE_RX_BROAD_CH(Value)                        \
10788 +           HalDev->RxMbpEnable &=  ~RX_BROAD_CH_MASK;    \
10789 +           HalDev->RxMbpEnable |=   RX_BROAD_CH(Value)
10790 +
10791 +#define UPDATE_RX_MULT_CH(Value)                         \
10792 +           HalDev->RxMbpEnable &=  ~RX_MULT_CH_MASK;     \
10793 +           HalDev->RxMbpEnable |=   RX_MULT_CH(Value)
10794 +
10795 +
10796 +
10797 +typedef enum
10798 +  {
10799 +   /*  CPMAC */
10800 +    enCpmacStart=0,
10801 +    enStats0,
10802 +    enStats1,
10803 +    enStats2,
10804 +    enStats3,
10805 +    enStats4,
10806 +    enStatsDump,
10807 +    enStatsClear,
10808 +    enRX_PASS_CRC,
10809 +    enRX_QOS_EN,
10810 +    enRX_NO_CHAIN,
10811 +    enRX_CMF_EN,
10812 +    enRX_CSF_EN,
10813 +    enRX_CEF_EN,
10814 +    enRX_CAF_EN,
10815 +    enRX_PROM_CH,
10816 +    enRX_BROAD_EN,
10817 +    enRX_BROAD_CH,
10818 +    enRX_MULT_EN,
10819 +    enRX_MULT_CH,
10820 +
10821 +    enTX_PTYPE,
10822 +    enTX_PACE,
10823 +    enMII_EN,
10824 +    enTX_FLOW_EN,
10825 +    enRX_FLOW_EN,
10826 +    enCTRL_LOOPBACK,
10827 +
10828 +    enRX_MAXLEN,
10829 +    enRX_FILTERLOWTHRESH,
10830 +    enRX0_FLOWTHRESH,
10831 +    enRX_UNICAST_SET,
10832 +    enRX_UNICAST_CLEAR,
10833 +    enMdioConnect,
10834 +    enMAC_ADDR_GET,
10835 +    enTick,
10836 +    enRX_MULTICAST,
10837 +    enRX_MULTI_ALL,
10838 +    enRX_MULTI_SINGLE,
10839 +    enVersion,
10840 +    enCpmacEnd                                   /* Last entry */
10841 +  }INFO_KEY_CPMAC;
10842 +
10843 +static const char pszVersion[]                 = "Version";
10844 +static const char pszStats0[]                  = "Stats0";
10845 +static const char pszStats1[]                  = "Stats1";
10846 +static const char pszStats2[]                  = "Stats2";
10847 +static const char pszStats3[]                  = "Stats3";
10848 +static const char pszStats4[]                  = "Stats4";
10849 +static const char pszStatsDump[]               = "StatsDump";
10850 +static const char pszStatsClear[]              = "StatsClear";
10851 +
10852 +/********************************************************************
10853 +**
10854 +**  RX MBP ENABLE
10855 +**
10856 +********************************************************************/
10857 +static const char pszRX_PASS_CRC[]             = "RX_PASS_CRC";
10858 +static const char pszRX_QOS_EN[]               = "RX_QOS_EN";
10859 +static const char pszRX_NO_CHAIN[]             = "RX_NO_CHAIN";
10860 +static const char pszRX_CMF_EN[]               = "RX_CMF_EN";
10861 +static const char pszRX_CSF_EN[]               = "RX_CSF_EN";
10862 +static const char pszRX_CEF_EN[]               = "RX_CEF_EN";
10863 +static const char pszRX_CAF_EN[]               = "RX_CAF_EN";
10864 +static const char pszRX_PROM_CH[]              = "RX_PROM_CH";
10865 +static const char pszRX_BROAD_EN[]             = "RX_BROAD_EN";
10866 +static const char pszRX_BROAD_CH[]             = "RX_BROAD_CH";
10867 +static const char pszRX_MULT_EN[]              = "RX_MULT_EN";
10868 +static const char pszRX_MULT_CH[]              = "RX_MULT_CH";
10869 +
10870 +
10871 +/********************************************************************
10872 +**
10873 +**  MAC CONTROL
10874 +**
10875 +********************************************************************/
10876 +static const char pszTX_PTYPE[]                = "TX_PTYPE";
10877 +static const char pszTX_PACE[]                 = "TX_PACE";
10878 +static const char pszMII_EN[]                  = "MII_EN";
10879 +static const char pszTX_FLOW_EN[]              = "TX_FLOW_EN";
10880 +static const char pszRX_FLOW_EN[]              = "RX_FLOW_EN";
10881 +static const char pszCTRL_LOOPBACK[]           = "CTRL_LOOPBACK";
10882 +
10883 +static const char pszRX_MAXLEN[]               = "RX_MAXLEN";
10884 +static const char pszRX_FILTERLOWTHRESH[]      = "RX_FILTERLOWTHRESH";
10885 +static const char pszRX0_FLOWTHRESH[]          = "RX0_FLOWTHRESH";
10886 +static const char pszRX_UNICAST_SET[]          = "RX_UNICAST_SET";
10887 +static const char pszRX_UNICAST_CLEAR[]        = "RX_UNICAST_CLEAR";
10888 +static const char pszMdioConnect[]             = "MdioConnect";
10889 +static const char pszMacAddr[]                 = "MacAddr";
10890 +static const char pszTick[]                    = "Tick";
10891 +
10892 +/********************************************************************
10893 +**
10894 +**  MULTICAST
10895 +**
10896 +********************************************************************/
10897 +
10898 +static const char pszRX_MULTICAST[]            = "RX_MULTICAST";
10899 +static const char pszRX_MULTI_ALL[]            = "RX_MULTI_ALL";
10900 +static const char pszRX_MULTI_SINGLE[]         = "RX_MULTI_SINGLE";
10901 +
10902 +/*
10903 +static const char* pszGFHN = "GFHN";
10904 +*/
10905 +
10906 +static const CONTROL_KEY KeyCpmac[] =
10907 +   {
10908 +     {""                           , enCpmacStart},
10909 +     {pszStats0                    , enStats0},
10910 +     {pszStats1                    , enStats1},
10911 +     {pszStats2                    , enStats2},
10912 +     {pszStats3                    , enStats3},
10913 +     {pszStats4                    , enStats4},
10914 +     {pszStatsClear                , enStatsClear},
10915 +     {pszStatsDump                 , enStatsDump},
10916 +     {pszRX_PASS_CRC               , enRX_PASS_CRC},
10917 +     {pszRX_QOS_EN                 , enRX_QOS_EN},
10918 +     {pszRX_NO_CHAIN               , enRX_NO_CHAIN},
10919 +     {pszRX_CMF_EN                 , enRX_CMF_EN},
10920 +     {pszRX_CSF_EN                 , enRX_CSF_EN},
10921 +     {pszRX_CEF_EN                 , enRX_CEF_EN},
10922 +     {pszRX_CAF_EN                 , enRX_CAF_EN},
10923 +     {pszRX_PROM_CH                , enRX_PROM_CH},
10924 +     {pszRX_BROAD_EN               , enRX_BROAD_EN},
10925 +     {pszRX_BROAD_CH               , enRX_BROAD_CH},
10926 +     {pszRX_MULT_EN                , enRX_MULT_EN},
10927 +     {pszRX_MULT_CH                , enRX_MULT_CH},
10928 +
10929 +     {pszTX_PTYPE                  , enTX_PTYPE},
10930 +     {pszTX_PACE                   , enTX_PACE},
10931 +     {pszMII_EN                    , enMII_EN},
10932 +     {pszTX_FLOW_EN                , enTX_FLOW_EN},
10933 +     {pszRX_FLOW_EN                , enRX_FLOW_EN},
10934 +     {pszCTRL_LOOPBACK             , enCTRL_LOOPBACK},
10935 +     {pszRX_MAXLEN                 , enRX_MAXLEN},
10936 +     {pszRX_FILTERLOWTHRESH        , enRX_FILTERLOWTHRESH},
10937 +     {pszRX0_FLOWTHRESH            , enRX0_FLOWTHRESH},
10938 +     {pszRX_UNICAST_SET            , enRX_UNICAST_SET},
10939 +     {pszRX_UNICAST_CLEAR          , enRX_UNICAST_CLEAR},
10940 +     {pszMdioConnect               , enMdioConnect},
10941 +     {pszRX_MULTICAST              , enRX_MULTICAST},
10942 +     {pszRX_MULTI_ALL              , enRX_MULTI_ALL},
10943 +     {pszRX_MULTI_SINGLE           , enRX_MULTI_SINGLE},
10944 +     {pszTick                      , enTick},
10945 +     {pszVersion                   , enVersion},
10946 +     {""                           , enCpmacEnd}
10947 +   };
10948 +
10949 +const char hcCpuFrequency[]       = "CpuFreq";
10950 +const char hcCpmacFrequency[]     = "CpmacFrequency";
10951 +const char hcMdioBusFrequency[]   = "MdioBusFrequency";
10952 +const char hcMdioClockFrequency[] = "MdioClockFrequency";
10953 +const char hcCpmacBase[]          = "CpmacBase";
10954 +const char hcPhyNum[]             = "PhyNum";
10955 +const char hcSize[]               = "size";
10956 +const char hcCpmacSize[]          = "CpmacSize";
10957 +const char hcPhyAccess[]          = "PhyAccess";
10958 +const char hcLinked[]             = "Linked";
10959 +const char hcFullDuplex[]         = "FullDuplex";
10960 +const char hcMdixMask[]           = "MdixMask";
10961 +const char hcMdioMdixSwitch[]     = "MdixSet";
10962 +#endif
10963 diff -urN linux.old/drivers/net/avalanche_cpmac/Makefile linux.dev/drivers/net/avalanche_cpmac/Makefile
10964 --- linux.old/drivers/net/avalanche_cpmac/Makefile      1970-01-01 01:00:00.000000000 +0100
10965 +++ linux.dev/drivers/net/avalanche_cpmac/Makefile      2005-07-12 02:48:42.175574000 +0200
10966 @@ -0,0 +1,26 @@
10967 +# File: drivers/net/avalanche_cpmac/Makefile
10968 +#
10969 +# Makefile for the Linux network (CPMAC) device drivers.
10970 +#
10971 +
10972 +O_TARGET := avalanche_cpmac.o
10973 +
10974 +
10975 +list-multi := avalanche_cpmac.o
10976 +obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) := avalanche_cpmac.o
10977 +
10978 +avalanche_cpmac-objs += cpmac.o            cpmacHalLx.o       hcpmac.o \
10979 +                                     psp_config_build.o psp_config_mgr.o            \
10980 +                                     psp_config_parse.o psp_config_util.o
10981 +
10982 +
10983 +include $(TOPDIR)/Rules.make
10984 +
10985 +
10986 +avalanche_cpmac.o:        $(avalanche_cpmac-objs)
10987 +       $(LD) -r -o $@ $(avalanche_cpmac-objs)
10988 +
10989 +
10990 +
10991 +clean:
10992 +       rm -f core *.o *.a *.s
10993 diff -urN linux.old/drivers/net/avalanche_cpmac/mdio_reg.h linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h
10994 --- linux.old/drivers/net/avalanche_cpmac/mdio_reg.h    1970-01-01 01:00:00.000000000 +0100
10995 +++ linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h    2005-07-12 02:48:42.176573000 +0200
10996 @@ -0,0 +1,121 @@
10997 +/****************************************************************************
10998 +**      TNETD53xx Software Support
10999 +**      Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved.
11000 +**
11001 +**      FILE: mdio_reg.h   Register definitions for the VBUS MII module
11002 +**
11003 +**      DESCRIPTION:
11004 +**              This include file contains register definitions for the
11005 +**              VBUS MII module.
11006 +**
11007 +**      HISTORY:
11008 +**              27Mar02 Michael Hanrahan Original (modified from emacmdio.h)
11009 +**              01Apr02 Michael Hanrahan Modified to include all regs. in spec
11010 +**              03Apr02 Michael Hanrahan Updated to Version 0.6 of spec
11011 +**              05Apr02 Michael Hanrahan Moved Phy Mode values into here
11012 +**              30Apr02 Michael Hanrahan Updated to Version 0.8 of spec
11013 +**              30Apr02 Michael Hanrahan Updated to recommended format
11014 +**              10May02 Michael Hanrahan Updated to Version 0.9 of spec
11015 +*****************************************************************************/
11016 +#ifndef _INC_MDIO_REG
11017 +#define _INC_MDIO_REG
11018 +
11019 +/***************************************************************************
11020 +**                                                                         
11021 +**         M D I O  M E M O R Y  M A P 
11022 +**                                                                         
11023 +***************************************************************************/
11024 +
11025 +
11026 +#define pMDIO_VER(base)                 ((volatile bit32u *)(base+0x00))
11027 +#define pMDIO_CONTROL(base)             ((volatile bit32u *)(base+0x04))
11028 +#define pMDIO_ALIVE(base)               ((volatile bit32u *)(base+0x08))
11029 +#define pMDIO_LINK(base)                ((volatile bit32u *)(base+0x0C))
11030 +#define pMDIO_LINKINTRAW(base)          ((volatile bit32u *)(base+0x10))
11031 +#define pMDIO_LINKINTMASKED(base)       ((volatile bit32u *)(base+0x14))
11032 +#define pMDIO_USERINTRAW(base)          ((volatile bit32u *)(base+0x20))
11033 +#define pMDIO_USERINTMASKED(base)       ((volatile bit32u *)(base+0x24))
11034 +#define pMDIO_USERINTMASKED_SET(base)   ((volatile bit32u *)(base+0x28))
11035 +#define pMDIO_USERINTMASKED_CLR(base)   ((volatile bit32u *)(base+0x2C))
11036 +#define pMDIO_USERACCESS(base, channel) ((volatile bit32u *)(base+(0x80+(channel*8))))
11037 +#define pMDIO_USERPHYSEL(base, channel) ((volatile bit32u *)(base+(0x84+(channel*8))))
11038 +
11039 +
11040 +/***************************************************************************
11041 +**                                                                         
11042 +**         M D I O  R E G I S T E R  A C C E S S  M A C R O S 
11043 +**                                                                         
11044 +***************************************************************************/
11045 +
11046 +
11047 +#define MDIO_ALIVE(base)                    (*(pMDIO_ALIVE(base)))
11048 +#define MDIO_CONTROL(base)                  (*(pMDIO_CONTROL(base)))
11049 +#define         MDIO_CONTROL_IDLE                 (1 << 31)
11050 +#define         MDIO_CONTROL_ENABLE               (1 << 30)
11051 +#define         MDIO_CONTROL_PREAMBLE             (1 << 20)  
11052 +#define         MDIO_CONTROL_FAULT                (1 << 19)
11053 +#define         MDIO_CONTROL_FAULT_DETECT_ENABLE  (1 << 18)
11054 +#define         MDIO_CONTROL_INT_TEST_ENABLE      (1 << 17)
11055 +#define         MDIO_CONTROL_HIGHEST_USER_CHANNEL (0x1F << 8)
11056 +#define         MDIO_CONTROL_CLKDIV               (0xFF)
11057 +#define MDIO_LINK(base)                     (*(pMDIO_LINK(base)))
11058 +#define MDIO_LINKINTRAW(base)               (*(pMDIO_LINKINTRAW(base)))
11059 +#define MDIO_LINKINTMASKED(base)            (*(pMDIO_LINKINTMASKED(base)))
11060 +#define MDIO_USERINTRAW(base)               (*(pMDIO_USERINTRAW(base)))
11061 +#define MDIO_USERINTMASKED(base)            (*(pMDIO_USERINTMASKED(base)))
11062 +#define MDIO_USERINTMASKED_CLR(base)        (*(pMDIO_USERINTMASKED_CLR(base)))
11063 +#define MDIO_USERINTMASKED_SET(base)        (*(pMDIO_USERINTMASKED_SET(base)))
11064 +#define MDIO_USERINTRAW(base)               (*(pMDIO_USERINTRAW(base)))
11065 +#define MDIO_USERACCESS(base, channel)      (*(pMDIO_USERACCESS(base, channel)))
11066 +#define         MDIO_USERACCESS_GO     (1 << 31)
11067 +#define         MDIO_USERACCESS_WRITE  (1 << 30)
11068 +#define         MDIO_USERACCESS_READ   (0 << 30)
11069 +#define         MDIO_USERACCESS_ACK    (1 << 29)
11070 +#define         MDIO_USERACCESS_REGADR (0x1F << 21)
11071 +#define         MDIO_USERACCESS_PHYADR (0x1F << 16)
11072 +#define         MDIO_USERACCESS_DATA   (0xFFFF)
11073 +#define MDIO_USERPHYSEL(base, channel)      (*(pMDIO_USERPHYSEL(base, channel)))
11074 +#define         MDIO_USERPHYSEL_LINKSEL         (1 << 7)
11075 +#define         MDIO_USERPHYSEL_LINKINT_ENABLE  (1 << 6)
11076 +#define         MDIO_USERPHYSEL_PHYADR_MON      (0x1F)
11077 +#define MDIO_VER(base)                      (*(pMDIO_VER(base)))
11078 +#define         MDIO_VER_MODID         (0xFFFF << 16)
11079 +#define         MDIO_VER_REVMAJ        (0xFF   << 8)
11080 +#define         MDIO_VER_REVMIN        (0xFF)
11081 +
11082 +
11083 +
11084 +
11085 +/****************************************************************************/
11086 +/*                                                                          */
11087 +/*         P H Y   R E G I S T E R  D E F I N I T I O N S                   */
11088 +/*                                                                          */
11089 +/****************************************************************************/
11090 +
11091 +
11092 +#define PHY_CONTROL_REG       0
11093 +  #define PHY_RESET           (1<<15)
11094 +  #define PHY_LOOP            (1<<14)
11095 +  #define PHY_100             (1<<13)
11096 +  #define AUTO_NEGOTIATE_EN   (1<<12)
11097 +  #define PHY_PDOWN           (1<<11)
11098 +  #define PHY_ISOLATE         (1<<10)
11099 +  #define RENEGOTIATE         (1<<9)
11100 +  #define PHY_FD              (1<<8)
11101 +
11102 +#define PHY_STATUS_REG        1
11103 +  #define NWAY_COMPLETE       (1<<5)
11104 +  #define NWAY_CAPABLE        (1<<3)
11105 +  #define PHY_LINKED          (1<<2)
11106 +
11107 +#define NWAY_ADVERTIZE_REG    4
11108 +#define NWAY_REMADVERTISE_REG 5
11109 +  #define NWAY_FD100          (1<<8)
11110 +  #define NWAY_HD100          (1<<7)
11111 +  #define NWAY_FD10           (1<<6)
11112 +  #define NWAY_HD10           (1<<5)
11113 +  #define NWAY_SEL            (1<<0)
11114 +  #define NWAY_AUTO           (1<<0)
11115 +
11116 +
11117 +#endif _INC_MDIO_REG
11118 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.c linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c
11119 --- linux.old/drivers/net/avalanche_cpmac/psp_config_build.c    1970-01-01 01:00:00.000000000 +0100
11120 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c    2005-07-12 02:48:42.176573000 +0200
11121 @@ -0,0 +1,335 @@
11122 +/******************************************************************************
11123 + * FILE PURPOSE:    PSP Config Manager - Configuration Build Source
11124 + ******************************************************************************
11125 + * FILE NAME:       psp_config_build.c
11126 + *
11127 + * DESCRIPTION:     Configuration Build API Implementation
11128 + *
11129 + * REVISION HISTORY:
11130 + * 27 Nov 02 - PSP TII  
11131 + *
11132 + * (C) Copyright 2002, Texas Instruments, Inc
11133 + *******************************************************************************/
11134 +
11135 +#ifdef INCLUDE_FFS
11136 +#include "ffs.h"
11137 +#endif /* INCLUDE_FFS */
11138 +
11139 +#include "psp_config_mgr.h"
11140 +#include "psp_config_build.h"
11141 +#include "psp_config_util.h"
11142 +
11143 +#define MAX_DEVICE_NAME_LEN     16
11144 +#define MAX_DEVICE_STR_LEN      512
11145 +
11146 +#ifndef NULL
11147 +#define NULL (char *)0
11148 +#endif
11149 +
11150 +#include <asm/ar7/sangam.h>
11151 +#include <linux/slab.h>
11152 +#include <linux/config.h>
11153 +
11154 +
11155 +#define os_malloc(size) kmalloc(size, GFP_KERNEL)
11156 +
11157 +int psp_run_enumerator(void)
11158 +{
11159 +    return(0);
11160 +}
11161 +
11162 +#if defined (CONFIG_AVALANCHE_CPMAC_AUTO)
11163 +
11164 +static int auto_detect_cpmac_phy(void)
11165 +{
11166 +
11167 +#define SELECT_INT_PHY_MAC 0
11168 +#define SELECT_EXT_PHY_MAC 1
11169 +
11170 +    volatile unsigned long *reset_cntl = AVALANCHE_RESET_CONTROL_BASE, *mdio_cntl  = ((int)AVALANCHE_MDIO_BASE + 0x4);
11171 +    unsigned int j= 0, detected_phy_map = 0, auto_select = SELECT_INT_PHY_MAC;
11172 +                                                                                                                   
11173 +    *reset_cntl |= (1 << AVALANCHE_MDIO_RESET_BIT) | (1 << AVALANCHE_LOW_CPMAC_RESET_BIT) | (1 << AVALANCHE_HIGH_CPMAC_RESET_BIT) | (1 << AVALANCHE_LOW_EPHY_RESET_BIT);                                 
11174 +    *mdio_cntl   = (1 << 30) | ((CONFIG_AR7_SYS * 1000)/2200);                                              
11175 +                                                                                                                   
11176 +    for(j=0;j < 300000; j++) 
11177 +    { 
11178 +        if(j%100000) continue;
11179 +
11180 +        detected_phy_map = *(mdio_cntl + 1);
11181 +        if(detected_phy_map) 
11182 +        {
11183 +            detected_phy_map &= ~AVALANCHE_LOW_CPMAC_PHY_MASK;
11184 +                
11185 +            if(detected_phy_map && !(detected_phy_map & (detected_phy_map - 1)))
11186 +            {
11187 +                auto_select = SELECT_EXT_PHY_MAC;
11188 +                break;
11189 +            }
11190 +        } 
11191 +    }
11192 +
11193 +    return(auto_select);
11194 +
11195 +}
11196 +
11197 +#endif
11198 +
11199 +
11200 +#ifndef AVALANCHE_LOW_CPMAC_MDIX_MASK
11201 +#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0
11202 +#endif
11203 +
11204 +void psp_load_default_static_cfg(void)
11205 +{
11206 +    char s2[100],  s3[100];
11207 +    char s4[2000], s6[2000];
11208 +    int threshold = 20;
11209 +    char *tx_threshold_ptr = prom_getenv("threshold");
11210 +    
11211 +    if(tx_threshold_ptr)
11212 +      threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10);
11213 +
11214 +    /* Static configuration if options.conf not present */
11215 +    sprintf(s3,"cpmdio(id=mii, base=%u, reset_bit=%d)", AVALANCHE_MDIO_BASE, 22);
11216 +    sprintf(s2, "reset( id=[ResetRegister], base=%u)", AVALANCHE_RESET_CONTROL_BASE);
11217 +
11218 +    sprintf(s4, "cpmac(id=[cpmac], unit=0, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MdixMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_LOW_CPMAC_BASE, AVALANCHE_LOW_CPMAC_RESET_BIT, AVALANCHE_LOW_CPMAC_PHY_MASK, AVALANCHE_LOW_CPMAC_MDIX_MASK, AVALANCHE_LOW_CPMAC_INT,threshold,threshold,threshold);
11219 +
11220 +    sprintf(s6, "cpmac(id=[cpmac], unit=1, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_HIGH_CPMAC_BASE, AVALANCHE_HIGH_CPMAC_RESET_BIT, AVALANCHE_HIGH_CPMAC_PHY_MASK, AVALANCHE_HIGH_CPMAC_INT,threshold,threshold,threshold);
11221 +
11222 +    psp_config_add("reset", s2, psp_config_strlen(s2), en_compile);
11223 +
11224 +
11225 +#if defined (CONFIG_AVALANCHE_LOW_CPMAC)
11226 +
11227 +    psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile);
11228 +    psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile);
11229 +
11230 +#endif
11231 +
11232 +
11233 +#if defined (CONFIG_AVALANCHE_HIGH_CPMAC)
11234 +
11235 +    psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile);
11236 +    psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile);
11237 +
11238 +#endif
11239 +
11240 +#if defined (CONFIG_AVALANCHE_CPMAC_AUTO)
11241 +    { 
11242 +        char *phy_sel_ptr = prom_getenv("mac_phy_sel"); 
11243 +        int   phy_sel = SELECT_EXT_PHY_MAC;
11244 +        char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */
11245 +
11246 +        if(phy_sel_ptr && (0 == strcmp(phy_sel_ptr, "int")))
11247 +        {
11248 +            phy_sel = SELECT_INT_PHY_MAC;
11249 +        }
11250 +
11251 +        //if(phy_sel == auto_detect_cpmac_phy())
11252 +        if(0 == strcmp(mac_port, "1"))
11253 +        {
11254 +            printk("Using the MAC with external PHY\n");
11255 +            psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile);
11256 +            psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile);
11257 +        }
11258 +        else
11259 +        {
11260 +            printk("Using the MAC with internal PHY\n");
11261 +            psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile);
11262 +            psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile);
11263 +        }
11264 +    }
11265 +                      
11266 +#endif    
11267 +
11268 +}
11269 +
11270 +char* psp_conf_read_file(char *p_file_name)
11271 +{
11272 +#ifdef INCLUDE_FFS
11273 +    
11274 +    char        *p_file_data = NULL;
11275 +    unsigned int file_size;
11276 +    FFS_FILE    *p_file = NULL;
11277 +
11278 +    if(p_file_name == NULL)
11279 +    {
11280 +        return (NULL);
11281 +    }
11282 +
11283 +    if(!(p_file = ffs_fopen(p_file_name, "r"))) 
11284 +    {
11285 +        return(NULL);
11286 +    }
11287 +
11288 +    file_size = p_file->_AvailableBytes;
11289 +
11290 +    p_file_data = os_malloc(file_size + 1);
11291 +    
11292 +    if(ffs_fread(p_file_data, file_size, 1, p_file) == 0)
11293 +    {
11294 +        kfree(p_file_data);
11295 +        return(NULL);
11296 +    }
11297 +
11298 +    ffs_fclose(p_file);
11299 +   
11300 +    p_file_data[file_size] = '\0';
11301 +
11302 +    return(p_file_data);
11303 +    
11304 +#else /* NO FFS */
11305 +    return(NULL);
11306 +#endif /* INCLUDE_FFS */
11307 +}
11308 +
11309 +int psp_conf_get_line(char *p_in_data, char **next_line)
11310 +{
11311 +    char *p       = p_in_data;
11312 +
11313 +    while(*p && *p++ != '\n')
11314 +    {
11315 +
11316 +    } 
11317 +   
11318 +    *next_line = p;
11319 +
11320 +    return(p - 1 - p_in_data);
11321 +}
11322 +
11323 +
11324 +int psp_conf_is_data_line(char *line)
11325 +{
11326 +    int ret_val = 1;
11327 +
11328 +    if(*line == '\0' || *line == '\n' || *line == '#')
11329 +        ret_val = 0;
11330 +
11331 +    return(ret_val);
11332 +}
11333 +
11334 +int psp_conf_get_key_size(char *data)
11335 +{
11336 +    char *p = data;
11337 +
11338 +    while(*p && *p != '\n' && *p != '(' && *p != ' ')
11339 +        p++;
11340 +
11341 +    return(p - data);
11342 +}
11343 +
11344 +char* psp_conf_eat_white_spaces(char *p)
11345 +{
11346 +    while(*p && *p != '\n' && *p == ' ')
11347 +        p++;
11348 +
11349 +    return (p);
11350 +}
11351 +
11352 +int psp_build_from_opt_conf(void)
11353 +{
11354 +    char *data       = NULL;
11355 +    char *data_hold  = NULL;
11356 +    char *next_line  = NULL; 
11357 +    int  line_size   = 0;
11358 +
11359 +    if((data = psp_conf_read_file("/etc/options.conf")) == NULL)
11360 +        return(-1);
11361 +
11362 +    data_hold = data;
11363 +
11364 +    while((line_size=psp_conf_get_line(data, &next_line)) != -1)
11365 +    {
11366 +
11367 +        char *name = NULL;
11368 +        int  name_size; 
11369
11370 +    data = psp_conf_eat_white_spaces(data);
11371 +
11372 +        if(psp_conf_is_data_line(data))
11373 +        {
11374 +            data[line_size] = '\0';
11375
11376 +            name_size = psp_conf_get_key_size(data);
11377 +           
11378 +            if(name_size > 0) 
11379 +            {
11380 +                name = (char *) os_malloc(name_size + 1);
11381 +                if(name == NULL) break;
11382 +
11383 +                psp_config_memcpy(name, data, name_size);
11384 +                name[name_size] = '\0';
11385 +
11386 +                psp_config_add(name, data, line_size, en_opt_conf);
11387 +            
11388 +                kfree(name);
11389 +            }
11390 +
11391 +            data[line_size] = '\n';
11392 +        }
11393 +
11394 +        data = next_line;
11395 +    }
11396 +
11397 +    kfree(data_hold);
11398 +    return (0);
11399 +}
11400 +
11401 +
11402 +int psp_write_conf_file(char *p_write_file, char * dev_cfg_string)
11403 +{
11404 +#ifdef INCLUDE_FFS
11405 +    int bytes_written=0;
11406 +        FFS_FILE *file_ptr=NULL;    
11407
11408 +    /*
11409 +     * NOTE: In current implementation of FFS in ADAM2 if the file exists beforehand, it
11410 +     * can't be opened for write.
11411 +     */
11412 +        if(!(file_ptr=ffs_fopen(p_write_file, "w"))) {
11413 +        return(-1);
11414 +        }
11415 +    
11416 +    /* Write into the file "output.con" the character string */
11417 +    /* write a \n before a writing a line */
11418 +    if(!(bytes_written = ffs_fwrite("\n", 1, sizeof(char), file_ptr))) {
11419 +        return (-1);
11420 +    }
11421 +    
11422 +    if(!(bytes_written = ffs_fwrite(dev_cfg_string, psp_config_strlen(dev_cfg_string), sizeof(char), file_ptr))) {
11423 +        return (-1);        
11424 +    }
11425 +    ffs_fclose(file_ptr);
11426 +    return (bytes_written+1);
11427 +#else /* NO FFS */
11428 +    return(-1);
11429 +#endif /* INCLUDE_FFS */
11430 +}
11431 +
11432 +void build_psp_config(void)
11433 +{
11434 +
11435 +    /* initialize the repository. */
11436 +    psp_config_init();
11437 +    
11438 +#ifdef INCLUDE_FFS
11439 +    ffs_init();
11440 +#endif /* INCLUDE_FFS */
11441 +
11442 +    /* read the configuration from the options.conf to override default ones */
11443 +    psp_build_from_opt_conf();
11444 +
11445 +    /* read the configuration which were not over ridden in options.conf */
11446 +    psp_load_default_static_cfg();
11447 +
11448 +    /* let the vlynq be enumerated. Enumerator will add cfg info
11449 +       of the discovered device instances to the repository.*/
11450 +    psp_run_enumerator();
11451 +
11452 +    /* dump the repository*/
11453 +    dump_device_cfg_pool();
11454 +
11455 +}
11456 +
11457 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.h linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h
11458 --- linux.old/drivers/net/avalanche_cpmac/psp_config_build.h    1970-01-01 01:00:00.000000000 +0100
11459 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h    2005-07-12 02:48:42.176573000 +0200
11460 @@ -0,0 +1,138 @@
11461 +/******************************************************************************
11462 + * FILE PURPOSE:    PSP Config Manager - Configuration Build Header
11463 + ******************************************************************************
11464 + * FILE NAME:       psp_config_build.h
11465 + *
11466 + * DESCRIPTION:     Configuration Build API's.
11467 + *
11468 + * REVISION HISTORY:
11469 + * 27 Nov 02 - PSP TII  
11470 + *
11471 + * (C) Copyright 2002, Texas Instruments, Inc
11472 + *******************************************************************************/
11473 +
11474 +#ifndef __PSP_CONF_BUILD_H__
11475 +#define __PSP_CONF_BUILD_H__
11476 +
11477 +/*------------------------------------------------------------------------------
11478 + * Name: psp_conf_read_file
11479 + *
11480 + * Parameters: 
11481 + *         in: p_file_name - the name of the file to read from.
11482 + *
11483 + * Description:
11484 + *     Reads the entire file in one shot. This function opens  the 
11485 + *     file, determines the size of the data to be read, allocates 
11486 + *     the required memory, NULL terminates the data and closes the
11487 + *     file.
11488 + *
11489 + *     It is responsibily of the callee to free the memory after it is
11490 + *     done with that data.
11491 + *    
11492 + *
11493 + * Returns:
11494 + *     A NULL pointer, if failed to read the data otherwise, a valid
11495 + *     pointer referring to the data read from the file.
11496 + *
11497 + * Example: 
11498 + *   
11499 + *     psp_conf_read_file("/etc/options.conf");
11500 + *---------------------------------------------------------------------------*/
11501 + char *psp_conf_read_file(char *p_file_name);
11502 +
11503 + /*----------------------------------------------------------------------------
11504 +  * Function : psp_conf_write_file
11505 +  *
11506 +  * Parameters:
11507 +  *         in: p_file_name - the file to which data is to be written.
11508 +  *         in: data        - the NULL terminated data string.
11509 +  *
11510 +  * Description:
11511 +  *     Write the indicated data into the file. This function opens the file,
11512 +  *     appends the data to end of the file, closes the file. 
11513 +  *
11514 +  * Returns:
11515 +  *
11516 +  *     The number of bytes on success. 
11517 +  *     0 on failure.
11518 +  *
11519 +  * Example:
11520 +  *
11521 +  *     psp_conf_write_file("/etc/outcon.conf", data);
11522 +  *--------------------------------------------------------------------------*/
11523 + int   psp_conf_write_file(char *p_file_name, char *data);
11524 +
11525 + /*----------------------------------------------------------------------------
11526 +  * Function: psp_conf_get_line
11527 +  *
11528 +  * Parameters:
11529 +  *         in: data      - the data from which the line is to identified.
11530 +  *        out: next_line - the pointer to start of the next line. 
11531 +  *
11532 +  * Description:
11533 +  *     Expects the data to be '\n' separated segments and data is NULL 
11534 +  *     terminated. Parses the given data for '\n' or '\0'. Provides a pointer
11535 +  *     to the start of next line in the next_line. 
11536 +  *
11537 +  * Returns:
11538 +  *     -1 on error.
11539 +  *      0 or more to indicate the number of bytes in the line starting at 
11540 +  *      data.
11541 +  *--------------------------------------------------------------------------*/
11542 + int psp_get_conf_line(char *p_in_data, char **next_line);
11543 +
11544 + /*----------------------------------------------------------------------------
11545 +  * Function: psp_conf_is_data_line
11546 +  *
11547 +  * Parameters:
11548 +  *         in: line - the array of bytes.
11549 +  *
11550 +  * Description:
11551 +  *     Tests the first byte in the array for '\0' or '\n' or '#'. Lines 
11552 +  *     starting with these characters are not considered data.
11553 +  *
11554 +  * Returns:
11555 +  *     1 if the line has data.
11556 +  *     0 otherwise.
11557 +  *
11558 +  *--------------------------------------------------------------------------*/
11559 + int psp_conf_is_data_line(char *line);
11560 +
11561 + /*----------------------------------------------------------------------------
11562 +  * Function: psp_conf_eat_white_spaces
11563 +  *
11564 +  * Parameters:
11565 +  *         in: line - the array of bytes.
11566 +  *
11567 +  * Description:
11568 +  *     Eats white spaces at the begining of the line while looking out for 
11569 +  *     '\0' or '\n' or ' '.
11570 +  * 
11571 +  * Returns:
11572 +  *     Pointer to the begining of the non white space character. 
11573 +  *     NULL if '\0' or '\n' is found.
11574 +  *
11575 +  *--------------------------------------------------------------------------*/
11576 +  char *psp_conf_eat_white_spaces(char *line);
11577 +
11578 +  /*---------------------------------------------------------------------------
11579 +   * Function: psp_conf_get_key_size
11580 +   *
11581 +   * Parameters:
11582 +   *         in: line - the array of bytes.
11583 +   *
11584 +   * Description:
11585 +   *     Identifies the size of the 'key' in array formatted as 
11586 +   *     key(id=[key1]....). This function also checks out for '\0' and '\n'.
11587 +   *
11588 +   * Returns:
11589 +   *     On success, The number of bytes that forms the key. 
11590 +   *     0 otherwise. 
11591 +   *     
11592 +   *-------------------------------------------------------------------------*/
11593 +  int psp_conf_get_key_size(char *line);
11594 +
11595 +
11596 +
11597 +#endif /* __PSP_CONF_BUILD_H__ */
11598 +
11599 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c
11600 --- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c      1970-01-01 01:00:00.000000000 +0100
11601 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c      2005-07-12 02:48:42.177573000 +0200
11602 @@ -0,0 +1,464 @@
11603 +/******************************************************************************
11604 + * FILE PURPOSE:    PSP Config Manager Source
11605 + ******************************************************************************
11606 + * FILE NAME:       psp_config_mgr.c
11607 + *
11608 + * DESCRIPTION:
11609 + *
11610 + * Manages configuration information. The repository is managed on the basis of 
11611 + * <key, info> pair. It is possible to have multiple occurrence of the same key. 
11612 + * Multiple occurences of the same keys are referred to as 'instances'. 
11613 + * 'instances' are assigned in the order of configuration arrival. The first 
11614 + * config for a 'key' added to the repository would be treated as instance 0 and
11615 + * next config to arrive for the same key would be treated as instance '1' and 
11616 + * so on.
11617 + * 
11618 + * Info is retrieved from the repository based on the 'key' and 'instance' value.
11619 + *
11620 + * No assumption is made about the format of the information that is put in the 
11621 + * repository. The only requirement is that 'key' should be NULL terminated 
11622 + * string.
11623 + *
11624 + * REVISION HISTORY:
11625 + * 27 Nov 02 - PSP TII  
11626 + *
11627 + * (C) Copyright 2002, Texas Instruments, Inc
11628 + *******************************************************************************/
11629 +
11630 +//#include <stdio.h>
11631 +//#include <stdlib.h>
11632 +#include "psp_config_mgr.h"
11633 +#include "psp_config_util.h"
11634 +
11635 +#include <linux/slab.h>
11636 +
11637 +/*-----------------------------------------------------------
11638 +  Implemented elsewhere
11639 + -----------------------------------------------------------*/
11640 +extern int sys_read_options_conf(void);
11641 +extern int sys_write_options_conf(char *cfg_info);
11642 +extern int sys_load_default_static_cfg(void);
11643 +extern int sys_run_enumerator(void);
11644 +
11645 +#define os_malloc(size) kmalloc(size, GFP_KERNEL)
11646 +
11647 +/*---------------------------------------------------------
11648 + * Data structures.
11649 + *--------------------------------------------------------*/
11650 +struct device_cfg_data;
11651 +
11652 +typedef struct device_instance_cfg_data
11653 +{
11654 +    struct device_instance_cfg_data       *next;
11655 +    char                                  locale[100];
11656 +    unsigned int                          data_size;
11657 +    char                                  *data;
11658 +
11659 +} DEV_INSTANCE_CFG_DATA_T;
11660 +
11661 +struct device_cfg_collection;
11662 +
11663 +typedef struct device_cfg_collection
11664 +{
11665 +    struct device_cfg_collection *next;
11666 +    char                         *device_name;
11667 +    CFG_TYPE_T                   cfg_type;
11668 +    int                          count;
11669 +    DEV_INSTANCE_CFG_DATA_T      *dev_inst_list_begin;
11670 +    DEV_INSTANCE_CFG_DATA_T      *dev_inst_list_end;
11671 +} DEVICE_CFG_T;
11672 +
11673 +
11674 +typedef struct device_cfg_list
11675 +{
11676 +    DEVICE_CFG_T   *device_cfg_begin;
11677 +    int            count;
11678 +} DEVICE_CFG_LIST_T;
11679 +
11680 +/*-----------------------------------------------------------------------------
11681 + * Functions used locally with in the file.
11682 + *---------------------------------------------------------------------------*/
11683 +static void p_init_device_cfg_list(void);
11684 +static int  p_add_instance_cfg_data(DEVICE_CFG_T            *p_dev_cfg,
11685 +                                    DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data);
11686 +static DEVICE_CFG_T* p_create_dev_cfg(char *device_name);
11687 +static DEVICE_CFG_T* p_get_dev_cfg(char *device_name);
11688 +static int p_set_device_cfg_type(DEVICE_CFG_T     *p_dev_cfg,
11689 +                                 CFG_TYPE_T       cfg_type);
11690 +
11691 +/* PSP Config manager debug */                                 
11692 +#define PSP_CFG_MGR_DEBUG 0
11693 +
11694 +#define dbgPrint if (PSP_CFG_MGR_DEBUG) printk
11695 +
11696 +/*-----------------------------------------------------------------------------
11697 + * The repository.
11698 + *---------------------------------------------------------------------------*/
11699 +static DEVICE_CFG_LIST_T g_device_cfg_list;
11700 +
11701 +/*---------------------------------------------
11702 + * Initialize the device collection pool.
11703 + *--------------------------------------------*/ 
11704 +void p_init_device_cfg_list(void)
11705 +{
11706 +    g_device_cfg_list.count = 0;
11707 +    g_device_cfg_list.device_cfg_begin = NULL;
11708 +}
11709 +
11710 +/*----------------------------------------------------------------------
11711 + * Add the device cfg into the device linked list.
11712 + *---------------------------------------------------------------------*/
11713 +int p_add_dev_cfg_to_list(DEVICE_CFG_LIST_T *p_dev_list,
11714 +                          DEVICE_CFG_T      *p_dev_cfg)
11715 +{
11716 +    if(p_dev_list->count != 0)
11717 +        p_dev_cfg->next            = p_dev_list->device_cfg_begin;
11718 +
11719 +    p_dev_list->device_cfg_begin   = p_dev_cfg;
11720 +
11721 +    p_dev_list->count++;
11722 +
11723 +    return (0);
11724 +}
11725 +
11726 +/*------------------------------------------------------------------
11727 + * Add the cfg data into the cfg data linked list of the collection.
11728 + *------------------------------------------------------------------*/
11729 +int p_add_instance_cfg_data(DEVICE_CFG_T                 *p_dev_cfg,
11730 +                            DEV_INSTANCE_CFG_DATA_T      *p_dev_inst_data)
11731 +{
11732 +    if(p_dev_cfg->count == 0)
11733 +        p_dev_cfg->dev_inst_list_begin     = p_dev_inst_data;
11734 +    else
11735 +        p_dev_cfg->dev_inst_list_end->next = p_dev_inst_data;
11736 +        
11737 +    p_dev_cfg->dev_inst_list_end           = p_dev_inst_data;
11738 +
11739 +    p_dev_cfg->count++;
11740 +    
11741 +    return (0);
11742 +}
11743 +
11744 +/*-----------------------------------------------------------------------------
11745 + * Create the device cfg.
11746 + *---------------------------------------------------------------------------*/
11747 +DEVICE_CFG_T *p_create_dev_cfg(char *device_name)
11748 +{
11749 +    DEVICE_CFG_T *p_dev_cfg = NULL;
11750 +
11751 +    if((p_dev_cfg = os_malloc(sizeof(DEVICE_CFG_T))) == NULL)
11752 +    {
11753 +        dbgPrint("Failed to allocate memory for DEVICE_CFG_T.\n");
11754 +    }
11755 +    else if((p_dev_cfg->device_name = os_malloc(psp_config_strlen(device_name) + 1))==NULL)
11756 +    {
11757 +        dbgPrint("Failed to allocate memory for device name.\n");
11758 +    }
11759 +    else
11760 +    {
11761 +        psp_config_strcpy(p_dev_cfg->device_name, device_name);
11762 +        p_dev_cfg->cfg_type = en_raw;
11763 +        p_dev_cfg->count = 0;
11764 +        p_dev_cfg->dev_inst_list_begin = NULL;
11765 +        p_dev_cfg->dev_inst_list_end   = NULL;
11766 +        p_dev_cfg->next                = NULL;
11767 +    }
11768 +
11769 +    return(p_dev_cfg);
11770 +}
11771 +
11772 +/*------------------------------------------------------------------------------
11773 + * Get the device cfg collection.
11774 + *-----------------------------------------------------------------------------*/
11775 +DEVICE_CFG_T *p_get_dev_cfg(char *device_name)
11776 +{
11777 +    int count               = 0;
11778 +    DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin;
11779 +
11780 +    for(count=0; count < g_device_cfg_list.count; count++)
11781 +    {
11782 +        if(psp_config_strcmp(device_name, p_dev_cfg->device_name) == 0)
11783 +        {
11784 +            break;
11785 +        }
11786 +
11787 +        p_dev_cfg = p_dev_cfg->next;
11788 +    }
11789 +    
11790 +    return(p_dev_cfg); 
11791 +}
11792 +
11793 +/*-------------------------------------------------------------------------
11794 + * Gets the name for the static cfg type. Utility function. Debug purposes.
11795 + *-------------------------------------------------------------------------*/
11796 +char *p_get_cfg_type_name_for_en(CFG_TYPE_T  cfg_type)
11797 +{
11798 +    static char raw_str      [] = "still raw";
11799 +    static char compile_str  [] = "configured at compile time";
11800 +    static char optconf_str  [] = "configured by options.conf";
11801 +    static char vlynq_str    [] = "configured by VLYNQ";
11802 +    static char no_static_str[] = "no static configuration";
11803 +
11804 +    if(cfg_type == en_raw)
11805 +        return (raw_str);
11806 +    else if(cfg_type == en_compile)
11807 +        return (compile_str);
11808 +    else if(cfg_type == en_opt_conf)
11809 +        return (optconf_str);
11810 +    else if(cfg_type == en_vlynq)
11811 +        return (vlynq_str);
11812 +    else
11813 +        return (no_static_str);
11814 +
11815 +}
11816 +
11817 +/*-----------------------------------------------------------------------------
11818 + * Sets the static cfg status of the device collection.
11819 + *
11820 + * If the collection is en_virgin then, the collection is assigned to cfg_type.
11821 + * If the cfg_type is en_vlynq then, the old cfg_type is retained. 
11822 + * en_compile and en_opt_conf are mutually exclusive. One of these can be 
11823 + * accomodated.
11824 + *
11825 + *---------------------------------------------------------------------------*/
11826 +int p_set_device_cfg_type(DEVICE_CFG_T    *p_dev_cfg,
11827 +                          CFG_TYPE_T      cfg_type)
11828 +{
11829 +    int ret_val = 0;
11830 +
11831 +    if(p_dev_cfg->cfg_type == en_raw)
11832 +        p_dev_cfg->cfg_type = cfg_type;
11833 +    else if((cfg_type == en_vlynq) || (p_dev_cfg->cfg_type == cfg_type))
11834 +        ;
11835 +    else
11836 +    {
11837 +        dbgPrint("Device %s has been %s which overrides %s.\n",
11838 +                  p_dev_cfg->device_name,
11839 +                  p_get_cfg_type_name_for_en(p_dev_cfg->cfg_type),
11840 +                  p_get_cfg_type_name_for_en(cfg_type));
11841 +        ret_val = -1;
11842 +    }
11843 +
11844 +    return(ret_val);
11845 +}
11846 +
11847 +/*------------------------------------------------------------------------
11848 + * Add the config str into the repository. The cfg type indicates
11849 + * whether the device has been configured statically, from options.conf or
11850 + * by vlynq enumeration.
11851 + *------------------------------------------------------------------------*/
11852 +int psp_config_add(char *key, void *p_cfg_str, unsigned int cfg_len, 
11853 +                   CFG_TYPE_T cfg_type)
11854 +{
11855 +    int                     ret_val           = -1;
11856 +    DEVICE_CFG_T            *p_dev_cfg        = NULL;
11857 +    DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data  = NULL;  
11858 +
11859 +    if(p_cfg_str == NULL || key == NULL)
11860 +    {
11861 +        dbgPrint("Null input pointer(s).\n");
11862 +    }
11863 +    /* check if there exist a dev_cfg for the given key, if not,
11864 +       then create one and add it to the device list. */
11865 +    else if(((p_dev_cfg = p_get_dev_cfg(key)) == NULL) &&
11866 +            (((p_dev_cfg = p_create_dev_cfg(key)) == NULL) ||
11867 +               p_add_dev_cfg_to_list(&g_device_cfg_list, p_dev_cfg) != 0))
11868 +    {
11869 +        dbgPrint("Failed to allocate mem or add dev cfg for %s.\n", key);
11870 +    }
11871 +    /* make sure that we can add this cfg type to the repository */
11872 +    else if(p_set_device_cfg_type(p_dev_cfg, cfg_type) == -1)
11873 +    {
11874 +        dbgPrint("Ignoring \"%s\" for device \"%s\".\n",
11875 +                  p_get_cfg_type_name_for_en(cfg_type),  
11876 +                  p_dev_cfg->device_name); 
11877 +    }
11878 +    else if((p_dev_inst_data = os_malloc(sizeof(DEV_INSTANCE_CFG_DATA_T)))== NULL)
11879 +    {
11880 +        dbgPrint("Failed to allocate memory for DEV_INSTANCE_CFG_DATA_T.\n");
11881 +    }
11882 +    else if((p_dev_inst_data->data = os_malloc(cfg_len) + 1) == NULL)
11883 +    {
11884 +        dbgPrint("Failed to allocate memory for the config data.\n");
11885 +    }
11886 +    else
11887 +    {
11888 +        p_dev_inst_data->next = NULL;
11889 +
11890 +        if(cfg_type == en_opt_conf || cfg_type == en_compile)
11891 +            psp_config_strcpy(p_dev_inst_data->locale, "dev on chip ");
11892 +        else if(cfg_type == en_vlynq)
11893 +            psp_config_strcpy(p_dev_inst_data->locale, "dev on vlynq");
11894 +        else 
11895 +            psp_config_strcpy(p_dev_inst_data->locale, "dev locale ?");
11896 +
11897 +        psp_config_memcpy(p_dev_inst_data->data, p_cfg_str, cfg_len);
11898 +        p_dev_inst_data->data_size = cfg_len;
11899 +        *(p_dev_inst_data->data + cfg_len) = '\0';
11900 +
11901 +        ret_val = p_add_instance_cfg_data(p_dev_cfg, p_dev_inst_data);
11902 +    } 
11903 +
11904 +    return(ret_val);
11905 +}
11906 +
11907 +/*-------------------------------------------------------------
11908 + * Get the total number of device instances in the repository
11909 + *------------------------------------------------------------*/
11910 +int psp_config_get_num_keys(void)
11911 +{
11912 +    return(g_device_cfg_list.count);
11913 +}
11914 +
11915 +
11916 +/*--------------------------------------------------------------------
11917 + * Get the device configuration info from the repository.
11918 + *-------------------------------------------------------------------*/
11919 +int psp_config_get(char *key, int instance, char **cfg_data_out)
11920 +{
11921 +    int ret_val             = -1;
11922 +    DEVICE_CFG_T *p_dev_cfg = NULL;
11923 +    *cfg_data_out           = NULL;
11924 +
11925 +    if(key == NULL && cfg_data_out == NULL)
11926 +    {
11927 +        dbgPrint("Key has a NULL value.\n");
11928 +    }
11929 +    else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL)
11930 +    {
11931 +        dbgPrint("cfg information for %s could not be found.\n", key);
11932 +    }
11933 +    else if(p_dev_cfg->count)
11934 +    {
11935 +         DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data = 
11936 +                                  p_dev_cfg->dev_inst_list_begin;
11937 +         int index = 0;
11938 +         for(index = 0; 
11939 +             index != instance && index < p_dev_cfg->count; 
11940 +             index++)
11941 +         {
11942 +             p_dev_inst_data = p_dev_inst_data->next;
11943 +         }
11944 +
11945 +         if(p_dev_inst_data != NULL && p_dev_inst_data->data != NULL)
11946 +         {
11947 +             *cfg_data_out = p_dev_inst_data->data;
11948 +             ret_val = p_dev_inst_data->data_size;
11949 +         }
11950 +    }
11951 +
11952 +    return (ret_val);
11953 +}
11954 +
11955 +/*----------------------------------------------------------------
11956 + * Returns the number of instances found in the repository for the
11957 + * specified key.
11958 + *---------------------------------------------------------------*/
11959 +int psp_config_get_num_instances(char *key)
11960 +{
11961 +    int ret_val             = 0;
11962 +    DEVICE_CFG_T *p_dev_cfg = NULL;
11963 +
11964 +    if(key == NULL)
11965 +    {
11966 +        dbgPrint("Key has a NULL value.\n");
11967 +    }
11968 +    else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL)
11969 +    {
11970 +        dbgPrint("cfg information for %s could not be found.\n", key);
11971 +    }
11972 +    else
11973 +    {
11974 +        ret_val = p_dev_cfg->count;
11975 +    }
11976 +    
11977 +    return (ret_val);
11978 +}
11979 +
11980 +/*------------------------------------------------------------------
11981 + * Dump the configuration repository. 
11982 + * Caution: DO NOT USE THIS FOR ANY NON NBU specified config format.
11983 + *-----------------------------------------------------------------*/
11984 +void psp_config_print(char *key)
11985 +{
11986 +    DEVICE_CFG_T *p_dev_cfg = NULL;
11987 +
11988 +    if(key == NULL)
11989 +    {
11990 +        dbgPrint("Key has a NULL value.\n");
11991 +    }
11992 +    else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL)
11993 +    {
11994 +        dbgPrint("cfg information for %s could not be found.\n", key);
11995 +    }
11996 +    else if(p_dev_cfg && p_dev_cfg->count)
11997 +    {
11998 +        DEV_INSTANCE_CFG_DATA_T   *p_dev_inst_data;
11999 +
12000 +        p_dev_inst_data = p_dev_cfg->dev_inst_list_begin;
12001 +
12002 +        do
12003 +        {
12004 +            dbgPrint("%s : %s\n", p_dev_inst_data->locale, 
12005 +                      p_dev_inst_data->data);
12006 +            p_dev_inst_data = p_dev_inst_data->next;
12007 +
12008 +        } while(p_dev_inst_data);
12009 +    }
12010 +    else
12011 +    {
12012 +        dbgPrint("Nothing was found for %s.\n", key);
12013 +    }
12014 +}
12015 +
12016 +void dump_device_cfg_pool(void)
12017 +{
12018 +    DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin;
12019 +    
12020 +    if(p_dev_cfg != NULL && g_device_cfg_list.count)
12021 +    {
12022 +        int index=0;
12023 +
12024 +        for(index=0; index < g_device_cfg_list.count; index++)
12025 +        {
12026 +            psp_config_print(p_dev_cfg->device_name);
12027 +            p_dev_cfg = p_dev_cfg->next;
12028 +        }
12029 +    }
12030 +    else
12031 +    {
12032 +        dbgPrint("repository is empty.\n");
12033 +    }
12034 +}
12035 +
12036 +void psp_config_init(void)
12037 +{
12038 +    p_init_device_cfg_list();
12039 +}
12040 +
12041 +void psp_config_cleanup()                                                       
12042 +{                                                                               
12043 +    int dev_count              = 0;                                             
12044 +    int inst_count             = 0;                                             
12045 +    DEVICE_CFG_T            *p = g_device_cfg_list.device_cfg_begin;            
12046 +    DEV_INSTANCE_CFG_DATA_T *q = NULL;                                          
12047 +                                                                                
12048 +    for(dev_count = 0; dev_count < g_device_cfg_list.count; dev_count++)        
12049 +    {                                                                           
12050 +        DEVICE_CFG_T            *p_temp = NULL;                                 
12051 +        if(p) q = p->dev_inst_list_begin;                                       
12052 +                                                                                
12053 +        for(inst_count = 0; inst_count < p->count && q != NULL; inst_count++)   
12054 +        {                                                                       
12055 +            DEV_INSTANCE_CFG_DATA_T *q_temp = q;                                
12056 +            q_temp = q->next;                                                   
12057 +            kfree(q->data);                                                     
12058 +            kfree(q);                                                           
12059 +            q = q_temp;                                                         
12060 +        }                                                                       
12061 +                                                                                
12062 +        p_temp = p->next;                                                       
12063 +        kfree(p);                                                               
12064 +        p = p_temp;                                                             
12065 +    }                                                                           
12066 +}                                                                               
12067 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h
12068 --- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h      1970-01-01 01:00:00.000000000 +0100
12069 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h      2005-07-12 02:48:42.177573000 +0200
12070 @@ -0,0 +1,110 @@
12071 +/******************************************************************************
12072 + * FILE PURPOSE:    PSP Config Manager Header
12073 + ******************************************************************************
12074 + * FILE NAME:       psp_config_mgr.h
12075 + *
12076 + * DESCRIPTION:     Storing and retrieving the configuration based on key
12077 + * A set of APIs to be used by one and sundry (including drivers and enumerator) to build
12078 + * and read cfg information of the devices for an avalanche SOC.
12079 + *
12080 + * This set of APIs isolates the configuration management from the world and provides simple
12081 + * access convinience.
12082 + *
12083 + * Device in this set refers to the peripherals that can be found on the SOC or on VLYNQ.
12084 + * The configuration is stored in the form of string and drivers can use these APIs to get
12085 + * a particular parameter value.
12086 + *
12087 + * The memory allocation for the pass back parameters is done by the caller.
12088 + *
12089 + * 0 is returned for SUCCESS or TRUE.
12090 + *  -1 is returned for FAILURE or FALSE.
12091 + *
12092 + * REVISION HISTORY:
12093 + * 27 Nov 02 - PSP TII  
12094 + *
12095 + * (C) Copyright 2002, Texas Instruments, Inc
12096 + *******************************************************************************/
12097
12098 +#ifndef __PSP_CONFIG_MGR_H__
12099 +#define __PSP_CONFIG_MGR_H__
12100 +
12101 +typedef enum cfg_type
12102 +{
12103 +    en_raw     = 0,
12104 +    en_compile,
12105 +    en_opt_conf,
12106 +    en_vlynq
12107 +} CFG_TYPE_T;
12108 +
12109 +/* Build psp configuration */
12110 +void build_psp_config(void);
12111
12112 +/********************************************************
12113 + * Access Operations.
12114 + ********************************************************/
12115 +
12116 +/*------------------------------------------------------------------------- 
12117 +   initializes the configuration repository. 
12118 + -------------------------------------------------------------------------*/
12119 +void  psp_config_init(void);
12120 +
12121 +/*-------------------------------------------------------------------------- 
12122 +   Adds the configuration information into the repository. 'key' is required 
12123 +   to be NULL terminated string. 'cfg_ptr' points to the configuration data.
12124 +   'cfg_len' is the length of the data pointed to by 'cfg_ptr' in bytes. 
12125 +   'cfg_type' indicates the type of config information.
12126 +
12127 +   psp_config_mgr copies the 'cfg_len' bytes of data pointed to by 'cfg_ptr' 
12128 +   into its internal repository. 
12129 +
12130 +   Returns: 0 on success, -1 on failure.
12131 +  -------------------------------------------------------------------------*/
12132 +int   psp_config_add(char *key, void *cfg_ptr, 
12133 +                     unsigned int cfg_len, CFG_TYPE_T cfg_type);
12134 +
12135 +
12136 +/* --------------------------------------------------------------------------
12137 +   Passes back, in "*cfg_out_val" a pointer to the config data in the repository
12138 +   for the specified 'key' and 'instance'. It returns the size of the config
12139 +   info
12140 +
12141 +   psp_config_mgr passes back a pointer in '*cfg_out_val' which refers to 
12142 +   some location in its internal repository. It is strongly recommended that 
12143 +   if the user intends to modify the contents of the config info for reasons 
12144 +   whatsoever, then, user should allocate memory of size returned by this 
12145 +   routine and copy the contents from '*cfg_out_val'.
12146 +  
12147 +   Any, modification carried out on the repository would lead to un-expected
12148 +   results.
12149 +
12150 +   Returns: 0 or more for the size of config info, -1 on error.
12151 +  --------------------------------------------------------------------------*/ 
12152 +int   psp_config_get(char *key, int instance, char **cfg_out_val);
12153 +
12154 +
12155 +/*--------------------------------------------------------------------------
12156 +   Get the number of keys that have been added in the repository so far.
12157 +
12158 +   Returns: 0 or more for the num of keys, -1 on error.
12159 +  -------------------------------------------------------------------------*/
12160 +int   psp_config_get_num_keys(void);
12161 +
12162 +
12163 +/*--------------------------------------------------------------------------
12164 +   Get the number of instances that are present in the repository for the 
12165 +   given 'key'.
12166 +
12167 +   Returns: 0 or more for the num of instances, -1 on error.
12168 +  -------------------------------------------------------------------------*/  
12169 +int   psp_config_get_num_instances(char *key);
12170 +
12171 +
12172 +/*--------------------------------------------------------------------------
12173 +   Prints the config data for all instances associated with the specified 
12174 +   'key'.
12175 +  -------------------------------------------------------------------------*/
12176 +void  psp_config_print(char *key);
12177 +
12178 +void  dump_device_cfg_pool(void);
12179 +
12180 +#endif /* __PSP_CONFIG_MGR_H__ */
12181 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c
12182 --- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c    1970-01-01 01:00:00.000000000 +0100
12183 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c    2005-07-12 02:48:42.178573000 +0200
12184 @@ -0,0 +1,362 @@
12185 +/******************************************************************************
12186 + * FILE PURPOSE:    PSP Config Manager - Parse API Source
12187 + ******************************************************************************
12188 + * FILE NAME:       psp_config_parse.c
12189 + *
12190 + * DESCRIPTION:     These APIs should be used only for scanvenging parameters which 
12191 + *                  are stored in the following format.
12192 + *
12193 + *                  str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)"
12194 + *
12195 + * REVISION HISTORY:
12196 + * 27 Nov 02 - PSP TII  
12197 + *
12198 + * (C) Copyright 2002, Texas Instruments, Inc
12199 + *******************************************************************************/
12200 +
12201 +//#include <stdio.h>
12202 +#include <linux/stddef.h>
12203 +
12204 +/*--------------------------------------------------
12205 + * MACROS.
12206 + *-------------------------------------------------*/
12207 +#define my_isdigit(c) (c >= '0' && c <= '9')
12208 +#define my_isoct(c)   (c >= '0' && c <= '7')  
12209 +#define my_xtod(c)    ((c) <= '9' ? (c) - '0' : (c) - 'a' +  10)
12210 +#define my_ifupper(c)    (c >= 'A' && c <= 'F')
12211 +#define XTOD(c)       ((c) - 'A' + 10)
12212 +#define my_ishex(c)   ((c >= 'a' && c <='f') || (c >= 'A' && c<='F') || my_isdigit(c) ) 
12213 +
12214 +/*---------------------------------------------------
12215 + * Local Functions.
12216 + *--------------------------------------------------*/
12217 +static int p_get_substr_from_str(char *p_in_str, char begin_delimiter,
12218 +                                 char end_delimiter, int pair_flag,
12219 +                                 char **p_out_str);
12220 +static int p_get_u_int_from_str(char *p_in_str, char begin_delimiter,
12221 +                                char end_delimiter, unsigned long *out_val);
12222 +
12223 +/*---------------------------------------------------
12224 + * Return pointer to first instance of the char.
12225 + *--------------------------------------------------*/
12226 +static char* psp_config_strchr(char *str, char chr)
12227 +{
12228 +    while(*str)
12229 +    {
12230 +        if(*str == chr)
12231 +            break;
12232 +        str++;    
12233 +    }
12234 +    
12235 +    return((*str) ? str : NULL);
12236 +}
12237 +
12238 +/*------------------------------------------------------------------------
12239 + * Convert the string upto delimiter to unsigned long.
12240 + *-----------------------------------------------------------------------*/
12241 +unsigned long my_atoul(char *p, char end_delimiter, unsigned long *out_val)
12242 +{
12243 +    unsigned long n;
12244 +    int c;
12245
12246 +    /* check the for null input */    
12247 +    if (!p)
12248 +        return -1;
12249 +     
12250 +    c = *p;    
12251 +    
12252 +    /* pass through the leading spaces */
12253 +    if (!my_isdigit(c)) 
12254 +    {
12255 +        while ( c == ' ')
12256 +            c = *++p;
12257 +            
12258 +    }
12259 +    
12260 +    if (c == '0')
12261 +    {
12262 +        if(*(p + 1) == 'x' || *(p+1) == 'X' ) 
12263 +        {
12264 +            /* string is in hex format */
12265 +
12266 +            p += 2; 
12267 +            c = *p;
12268 +            
12269 +            if(my_ishex(c))
12270 +            {
12271 +               if(my_ifupper(c))
12272 +                   n = XTOD(c);
12273 +               else         
12274 +                       n = my_xtod(c);
12275 +            }
12276 +            else
12277 +                return -1; /* invalid hex string format */
12278 +                
12279 +            while ((c = *++p) && my_ishex(c)) 
12280 +            {
12281 +                n *= 16; 
12282 +                if(my_ifupper(c))
12283 +                   n += XTOD(c);
12284 +                else         
12285 +                       n += my_xtod(c);
12286 +            }
12287 +         }
12288 +        else
12289 +        {
12290 +            /* string is in octal format */
12291 +
12292 +            if( my_isoct(c) )
12293 +            n = c - '0';
12294 +            else
12295 +                return -1; /* invalid octal string format */
12296
12297 +            while ((c = *++p) && my_isoct(c)) 
12298 +            {
12299 +                n *= 8; 
12300 +                n += c - '0'; 
12301 +            }
12302 +        } 
12303 +         
12304 +    }      
12305 +    else 
12306 +    {
12307 +        /* string is in decimal format */
12308
12309 +        if( my_isdigit(c) )
12310 +            n = c - '0';
12311 +        else
12312 +            return -1; /* invalid decimal string format */
12313 +
12314 +        while ((c = *++p) && my_isdigit(c)) 
12315 +        {
12316 +            n *= 10; 
12317 +            n += c - '0'; 
12318 +        }
12319 +    }
12320 +   
12321 +    /* move through the trailing spaces */ 
12322 +    while(*p == ' ')
12323 +        p++;
12324 +        
12325 +    if(*p == end_delimiter)
12326 +       {
12327 +           *out_val = n;
12328 +           return 0;
12329 +       }   
12330 +        
12331 +    else
12332 +        return -1; /* invalid string format */
12333 +}
12334 +
12335 +/*---------------------------------------------------------------------------------
12336 + * Gets the substring de-limited by the 'begin_delimiter' and 'end_delimiter'.
12337 + * and returns the size of the substring. 
12338 + *
12339 + * Parses the NULL terminated p_in_str for a character array delimited by 
12340 + * begin_delimiter and end_delimiter, passes back the pointer to the character 
12341 + * array in ' *p_out_str '. The passed pointer ' *p_out_str ' should point to 
12342 + * the location next (byte) to the begin_delimiter. The function routine returns 
12343 + * the number of characters excluding the begin_delimiter and end_delimiter, 
12344 + * found in the array delimited by the said delimiters.
12345 + *
12346 + * If the pair_flag is set to 1, then, number of begin_delimiter and end_delimiter
12347 + * found in the parsing should match (equal) and this routine passes back the 
12348 + * pointer to the character array, starting at a location next (byte) to the 
12349 + * first begin_delimiter,  inclusive of all intermediate matching delimiter 
12350 + * characters found between outer delimiters. If the pair flag is set and if 
12351 + * begin_delimiter and end_delimiter happens to be same, then error (-1) is 
12352 + * returned.
12353 + * 
12354 + * Return: 0 or more to indicate the size of the substring, -1 on error.
12355 + *-------------------------------------------------------------------------------*/
12356 +int p_get_substr_from_str(char *p_in_str, char begin_delimiter, 
12357 +                          char end_delimiter, int pair_flag, 
12358 +                          char **p_out_str) 
12359 +{
12360 +    int cnt,pos;
12361 +
12362 +    if(pair_flag  && begin_delimiter == end_delimiter)
12363 +        return -1;
12364 +    
12365 +    if((p_in_str = psp_config_strchr(p_in_str, begin_delimiter)) == 0)
12366 +        return -1; /* no start delimiter found */
12367 +    
12368 +    p_in_str++;      
12369 +    *p_out_str = p_in_str;
12370 +     
12371 +    for(pos = 0,cnt =1; cnt && p_in_str[pos] ; pos++)
12372 +    {
12373 +        if(p_in_str[pos] == end_delimiter)
12374 +        {
12375 +            if(pair_flag == 0)
12376 +                return pos;
12377 +               
12378 +            cnt--;                  
12379 +        }             
12380 +        else if(p_in_str[pos] == begin_delimiter)
12381 +            cnt++;
12382 +        else 
12383 +            ; /* We do nothing */
12384 +      
12385 +    }
12386 +    
12387 +    if( cnt == 0)   
12388 +        return pos - 1;
12389 +    else
12390 +        return -1; /* no corresponding end delimiter found */
12391 +}
12392 +
12393 +/*--------------------------------------------------------------------------    
12394 + * Parses the NULL terminated p_in_str for unsigned long value delimited by 
12395 + * begin_delimiter and end_delimiter, passes back the found in ' *out_val '.  
12396 + * The function routine returns 0 on success and returns -1 on failure. 
12397 + * The first instance of the de-limiter should be accounted for the parsing.
12398 + *
12399 + * The base for unsigned value would 10, octal and hex. The value passed back 
12400 + * would be of the base 10. Spaces at the begining of the byte array are valid  
12401 + * and should be ingnored in the calculation of the value. Space character in 
12402 + * the middle of the byte array or any character other than the valid ones 
12403 + * (based on base type) should return error. The octal value begins with '0', 
12404 + * the hex value begins with "0x" or "0X", the base value can begin with 
12405 + * '1' to '9'.
12406 + * 
12407 + * Returns: 0 on success, -1 on failure.
12408 + *-------------------------------------------------------------------------*/
12409 +int p_get_u_int_from_str(char *p_in_str, char begin_delimiter, 
12410 +                         char end_delimiter, unsigned long *out_val) 
12411 +{
12412 +    char *start;
12413 +    unsigned long num;
12414 +    
12415 +    num = p_get_substr_from_str(p_in_str, begin_delimiter, end_delimiter,
12416 +                                0, &start);
12417 +
12418 +    if(num == (unsigned long)-1)
12419 +        return -1;
12420 +    
12421 +    return my_atoul(start,end_delimiter,out_val);
12422 +}
12423 +
12424 +/*--------------------------------------------------------------------------
12425 + * Finds the first occurrence of the substring p_find_str in the string
12426 + * p_in_str. 
12427 + *-------------------------------------------------------------------------*/
12428 +char *my_strstr(char *p_in_str, const char *p_find_str)
12429 +{
12430 +    char *p = (char *)p_find_str;
12431 +    char *ret = NULL;
12432 +
12433 +    while(*p_in_str)
12434 +    {
12435 +        if(!(*p))
12436 +            return (ret);
12437 +        else if(*p_in_str == *p)
12438 +        {
12439 +            if(!ret) ret = p_in_str;
12440 +            p++;
12441 +            p_in_str++;
12442 +        }
12443 +        else if(ret)
12444 +        {
12445 +            p = (char *)p_find_str;
12446 +            p_in_str = ret + 1;
12447 +            ret = NULL;
12448 +        }
12449 +        else
12450 +            p_in_str++;
12451 +    }
12452 +
12453 +    if(*p_in_str != *p) ret = NULL;
12454 +
12455 +    return (ret);
12456 +
12457 +}
12458 +
12459 +/*------------------------------------------------------------------------------
12460 + * Gets the value of the config param in the unsigned int format. The value is 
12461 + * stored in the following format in the string.
12462 + * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)"
12463 + *-----------------------------------------------------------------------------*/
12464 +int psp_config_get_param_uint(char *p_in_str, const char *param, unsigned int *out_val)
12465 +{
12466 +    int   ret_val = -1;
12467 +    char *p_strstr;
12468 +
12469 +    if(!p_in_str || !param || !out_val) 
12470 +    {
12471 +        ;
12472 +    } 
12473 +    else if((p_strstr = my_strstr(p_in_str, param)) == NULL)
12474 +    {
12475 +        ;
12476 +    }
12477 +    else if(p_get_u_int_from_str(p_strstr, '=', ',', (unsigned long *)out_val) == 0)
12478 +    {
12479 +        ret_val = 0;
12480 +    }
12481 +    else if(p_get_u_int_from_str(p_strstr, '=', ']', (unsigned long*)out_val) == 0)
12482 +    {
12483 +        ret_val = 0;
12484 +    }
12485 +    else if(p_get_u_int_from_str(p_strstr, '=', ')', (unsigned long*)out_val) == 0)
12486 +    {
12487 +        ret_val = 0;
12488 +    }
12489 +    else
12490 +    {
12491 +        /* we failed */
12492 +    }
12493 +
12494 +    return (ret_val);
12495 +}
12496
12497 +/*------------------------------------------------------------------------------
12498 + * Gets the value of the config param in the Non NULL terminated format. The value 
12499 + * is stored in the following format in the string. 
12500 + * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)"
12501 + *-----------------------------------------------------------------------------*/
12502 +int psp_config_get_param_string(char *p_in_str, const char *param, char **out_val)
12503 +{
12504 +    int ret_val = -1;
12505 +    char *p_strstr;
12506 +
12507 +    if(!p_in_str || !param || !(out_val))
12508 +        ;
12509 +    else if((p_strstr = my_strstr(p_in_str, param)) == NULL)
12510 +    {
12511 +        ;
12512 +    }
12513 +    else if((ret_val = p_get_substr_from_str(p_strstr, '[', ']', 1, out_val)) == -1)
12514 +    {
12515 +        ;
12516 +    }
12517 +    else
12518 +    {
12519 +        ; /* we got the value */
12520 +    }   
12521
12522 +    return (ret_val); 
12523 +} 
12524 +
12525 +#ifdef PSP_CONFIG_MGR_DEBUG_TEST
12526 +main()
12527 +{
12528 +    unsigned long num =999;
12529 +    int ret = 0;
12530 +    char *val1 = NULL;
12531 +    char val[30];
12532 +    char str1[] = "cpmac(id=[cpmac], k0=[a1=[a2=[test], a3=2], k1=100, k2=[k3=300, k4=200], k7=722)";
12533 +
12534 +    psp_config_get_param_uint(str1, "k7", &num);
12535 +    printf("%u.\n", num);    
12536 +    ret = psp_config_get_param_string(str1, "a1", &val1); 
12537 +    if(ret >= 0) { printf("%d.\n", ret); strncpy(val, val1, ret); val[ret] = '\0';}
12538 +    
12539 +    printf("val = \"%s\", and size = %d \n", val, ret);
12540 +
12541 +    if(val[ret]) ; else printf("jeee.\n");
12542 +}
12543 +#endif /* PSP_CONFIG_MGR_DEBUG_TEST */
12544 +
12545 +
12546 +
12547 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h
12548 --- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h    1970-01-01 01:00:00.000000000 +0100
12549 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h    2005-07-12 02:48:42.178573000 +0200
12550 @@ -0,0 +1,32 @@
12551 +/******************************************************************************
12552 + * FILE PURPOSE:    PSP Config Manager - Parse API Header
12553 + ******************************************************************************
12554 + * FILE NAME:       psp_config_parse.h
12555 + *
12556 + * DESCRIPTION:     Parsing for params from string available in the NBU format.
12557 + *                  These APIs should be used only for scanvenging parameters which 
12558 + *                  are stored in the following format.
12559 + *                  
12560 + *                  str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)"
12561 + *
12562 + * REVISION HISTORY:
12563 + * 27 Nov 02 - PSP TII  
12564 + *
12565 + * (C) Copyright 2002, Texas Instruments, Inc
12566 + *******************************************************************************/
12567 +
12568 +#ifndef __PSP_CONFIG_PARSER_H__
12569 +#define __PSP_CONFIG_PARSER_H__
12570 +
12571 +/*------------------------------------------------------------------
12572 + * These APIs should be used only for scanvenging parameters which 
12573 + * are stored in the following format.
12574 + *
12575 + * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)"
12576 + *-----------------------------------------------------------------*/
12577 +int psp_config_get_param_uint(char *p_in_str, const char *param, 
12578 +                              unsigned int *out_val);
12579 +int psp_config_get_param_string(char *p_in_str, const char *param, 
12580 +                                char **out_val);
12581 +
12582 +#endif /* __PSP_CONFIG_PARSER_H__ */
12583 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.c linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c
12584 --- linux.old/drivers/net/avalanche_cpmac/psp_config_util.c     1970-01-01 01:00:00.000000000 +0100
12585 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c     2005-07-12 02:48:42.178573000 +0200
12586 @@ -0,0 +1,106 @@
12587 +/******************************************************************************
12588 + * FILE PURPOSE:    PSP Config Manager - Utilities API Source
12589 + ******************************************************************************
12590 + * FILE NAME:       psp_config_util.c
12591 + *
12592 + * DESCRIPTION:     These APIs provide the standard "C" string interfaces. 
12593 + *                  Provided here to reduce dependencies on the standard libraries 
12594 + *                  and for cases where psp_config would required to run before 
12595 + *                  the whole system is loaded or outside the scope of the OS.
12596 + *
12597 + * REVISION HISTORY:
12598 + * 27 Nov 02 - PSP TII  
12599 + *
12600 + * (C) Copyright 2002, Texas Instruments, Inc
12601 + *******************************************************************************/
12602 +
12603 +//#include <stdio.h>
12604 +#include "psp_config_util.h"
12605 +#include <linux/stddef.h>
12606 +
12607 +/*---------------------------------------------
12608 + * strlen.
12609 + *-------------------------------------------*/
12610 +int psp_config_strlen(char *p)
12611 +{
12612 +    char *p_orig = p;
12613 +    while(*p)
12614 +        p++;
12615 +    return(p - p_orig);
12616 +}
12617 +
12618 +/*--------------------------------------------
12619 + * strcmp.
12620 + *-------------------------------------------*/
12621 +int psp_config_strcmp(char *s1, char *s2)
12622 +{
12623 +    while(*s1 && *s2)
12624 +    {
12625 +        if(*s1 != *s2)
12626 +            break;
12627 +        s1++;
12628 +        s2++;
12629 +    }
12630 +
12631 +    return(*s1 - *s2);
12632 +}
12633 +
12634 +/*--------------------------------------------
12635 + * strcpy.
12636 + *------------------------------------------*/
12637 +char* psp_config_strcpy(char *dest, char *src)
12638 +{
12639 +    char *dest_orig = dest;
12640 +
12641 +    while(*src)
12642 +    {
12643 +        *dest++ = *src++;
12644 +    }
12645 +
12646 +    *dest = '\0';
12647 +
12648 +    return(dest_orig);
12649 +}
12650 +
12651 +/*----------------------------------------------
12652 + * psp_config_memcpy.
12653 + *--------------------------------------------*/
12654 +void* psp_config_memcpy(void* dest, void* src, unsigned int n)
12655 +{
12656 +    void *dest_orig = dest;
12657 +
12658 +    while(n)
12659 +    {
12660 +        *(char *)dest++ = *(char *)src++;
12661 +        n--;
12662 +    }
12663 +
12664 +    return (dest_orig);
12665 +}
12666 +
12667 +/*---------------------------------------------------
12668 + * Return pointer to first instance of the char.
12669 + *--------------------------------------------------*/
12670 +char* psp_config_strchr(char *str, char chr)
12671 +{
12672 +    while(*str)
12673 +    {
12674 +        if(*str == chr)
12675 +            break;
12676 +        str++;    
12677 +    }
12678 +    
12679 +    return((*str) ? str : NULL);
12680 +}
12681 +
12682 +#ifdef PSP_CONFIG_MGR_DEBUG_TEST
12683 +
12684 +int main( )
12685 +{
12686 +    char s[] = "hello             ";
12687 +    printf("%d.\n", psp_config_strlen("hello\n"));
12688 +    printf("%d.\n", psp_config_strcmp("hells", "hellq"));
12689 +    printf("%s %s.\n", psp_config_strcpy(s + 6, "test1"), s);
12690 +}
12691 +
12692 +#endif /* PSP_CONFIG_MGR_DEBUG_TEST */
12693 diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.h linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h
12694 --- linux.old/drivers/net/avalanche_cpmac/psp_config_util.h     1970-01-01 01:00:00.000000000 +0100
12695 +++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h     2005-07-12 02:48:42.179573000 +0200
12696 @@ -0,0 +1,26 @@
12697 +/******************************************************************************
12698 + * FILE PURPOSE:    PSP Config Manager - Utilities API Header
12699 + ******************************************************************************
12700 + * FILE NAME:       psp_config_util.h
12701 + *
12702 + * DESCRIPTION:     These APIs provide the standard "C" string interfaces. 
12703 + *                  Provided here to reduce dependencies on the standard libraries 
12704 + *                  and for cases where psp_config would required to run before 
12705 + *                  the whole system is loaded or outside the scope of the OS.
12706 + *
12707 + * REVISION HISTORY:
12708 + * 27 Nov 02 - PSP TII  
12709 + *
12710 + * (C) Copyright 2002, Texas Instruments, Inc
12711 + *******************************************************************************/
12712
12713 +#ifndef __PSP_CONFIG_UTIL_H__
12714 +#define __PSP_CONFIG_UTIL_H__
12715 +
12716 +extern int   psp_config_strlen(char*);
12717 +extern int   psp_config_strcmp(char*, char*);
12718 +extern char* psp_config_strcpy(char*, char*);
12719 +extern void* psp_config_memcpy(void*, void*, unsigned int n);
12720 +extern char* psp_config_strchr(char*, char);
12721 +
12722 +#endif /* __PSP_CONFIG_UTIL_H__ */
12723 diff -urN linux.old/drivers/net/avalanche_cpmac/readme.txt linux.dev/drivers/net/avalanche_cpmac/readme.txt
12724 --- linux.old/drivers/net/avalanche_cpmac/readme.txt    1970-01-01 01:00:00.000000000 +0100
12725 +++ linux.dev/drivers/net/avalanche_cpmac/readme.txt    2005-07-12 02:48:42.179573000 +0200
12726 @@ -0,0 +1,545 @@
12727 +23 August 2004      CPMAC 1.7.8 (NSP Performance Team Release)
12728 +
12729 +CC Labels: REL_20040823_HALdallas_cpmac_01.07.08
12730 +
12731 +New features:  Key "MacAddr" can now be used to set the Mac Address after Open. 
12732 +
12733 + unsigned char MacAddr[6];
12734 +
12735 +  // Set Mac Address to "00.B0.D0.10.80.C1"     
12736 +  MacAddr[0] = 0x00;
12737 +  MacAddr[1] = 0xB0;
12738 +  MacAddr[2] = 0xD0;
12739 +  MacAddr[3] = 0x10;
12740 +  MacAddr[4] = 0x80;
12741 +  MacAddr[5] = 0xC1;
12742 +      
12743 +  HalFunc->Control(HalDev, "MacAddr", hcSet, &MacAddr);      
12744 +
12745 +Bug fixes: in Send(), Threshold is not checked if Tx Ints are re-enabled.
12746 +
12747 +Modules affected:  hcpmac.c, hcpmac.h, cppi_cpmac.c
12748 +
12749 +22 June 2004          CPMAC 1.7.6 (NSP Performance Team Release)
12750 +
12751 +CC Labels: REL_20040622_HALdallas_cpmac_01.07.06
12752 +
12753 +New features:  Key "TxIntDisable" used to disable Tx Interrupts. If it is set, then Tx Interrupts will be processed on Send() controlled by Tx ServiceMax Setting. 
12754 +
12755 + int On = 1;
12756 + HalFunc->Control(HalDev, "TxIntDisable", "Set", &On);
12757 +
12758 +Bug fixes: NTR
12759 +
12760 +10 June 2004          CPMAC 1.7.5 (external release)
12761 +
12762 +CC Labels: REL_20040610_HALdallas_cpmac_01.07.05
12763 +
12764 +New features:  NTR
12765 +
12766 +Bug fixes: Fixed an issue with calculation for the multicast hash.
12767 +
12768 +27 May 2004          CPSAR 1.7.4, CPMAC 1.7.4 (external release)
12769 +
12770 +CC Labels: REL_20040527_HALdallas_cpsar_01.07.04
12771 +           REL_20040527_HALdallas_cpmac_01.07.04
12772 +
12773 +New features:  NTR
12774 +
12775 +Bug fixes: A flaw was fixed in the critical sectioning of the CPPI file, affecting both
12776 +           the MAC and the SAR releases.  This flaw was detected on Titan PSP 4.7 BFT2.
12777 +
12778 +05 May 2004          CPSAR 1.7.3, CPMAC 1.7.3 (external release)
12779 +
12780 +CC Labels: REL_20040505_HALdallas_cpsar_01.07.03
12781 +                REL_20040505_HALdallas_cpmac_01.07.03
12782 +
12783 +New features:  NTR
12784 +
12785 +Bug fixes: 1) Firmware has been updated to fix a problem with Host OAM mode operation.  
12786 +               2) Cache macros have been fixed.
12787 +
12788 +Notes:  This release contains all performance enhancements currently available for CPHAL 1.x.  
12789 +
12790 +19 April 2004          CPSAR 1.7.2, CPMAC 1.7.2 (external release)
12791 +
12792 +CC Labels: REL_20040419_HALdallas_cpsar_01.07.02
12793 +                REL_20040419_HALdallas_cpmac_01.07.02
12794 +
12795 +New features:  NTR
12796 +
12797 +Bug fixes: Fixes merge problem in 1.7.1.
12798 +
12799 +Notes:  This is a branch release which contains only a subset of the performance improvements.
12800 +            The remaining performance improvements are stiill being qualified at this time.
12801 +
12802 +1 April 2004          CPSAR 1.7.1, CPMAC 1.7.1 (external release)
12803 +
12804 +NOTICE: DO NOT USE 1.7.1.  It has a known problem (see 1.7.2 notes)
12805 +
12806 +CC Labels: REL_20040401_HALdallas_cpsar_01.07.01
12807 +                REL_20040401_HALdallas_cpmac_01.07.01
12808 +
12809 +New features:  Performance improvement in CPPI layer, affecting both CPSAR and CPMAC.  
12810 +
12811 +Bug fixes: NTR
12812 +
12813 +17 Februrary 2004    CPSAR 1.7.0 (external release)
12814 +
12815 +CC Labels: REL_20040217_HALdallas_cpsar_01.07.00
12816 +
12817 +New features:  Added support for "TxFlush" feature.  This allows the upper
12818 +               layer to flush all or part of a given Tx queue for a given
12819 +               channel.  This is to be used during call setup for a voice
12820 +               connection.
12821 +
12822 +30 January 2004      CPMAC 1.7.0 (external release)
12823 +
12824 +CC Labels: REL_20040130_HALdallas_cpmac_01.07.00
12825 +
12826 +Bug fixes:    CPMDIO - When in manual negotiate mode and linked, dropping link would move into NWAY state rather than manual state.
12827 +              CPMDIO - Extraneous debug message corrected
12828 +New features: CPMDIO - Support for AutoMdix usage added. 
12829 +
12830 +25 September 2003      CPSAR 1.6.6 (external release)
12831 +
12832 +CC Labels: REL_20030925_HALdallas_cpsar_01.06.06
12833 +
12834 +Bug fixes:   PDSP firmware has been updated to fix the OAM padding problem.  It previously
12835 +             wrote pad bytes into a reserved field of the OAM cell.  There is a small
12836 +             change to the CPSAR configuration code which corresponds to the PDSP spec
12837 +             change.
12838 +
12839 +New features: NTR
12840 +
12841 +09 September 2003      CPMAC 1.6.6 (external release)
12842 +
12843 +CC Labels: REL_20030909_HALdallas_cpmac_01.06.06
12844 +
12845 +Bug fixes:   CPMAC : When _CPMDIO_NOPHY is set, Cpmac COntrol is set to Full Duplex
12846 +             Bridge loopback test does not show a problem using 1.6.5 if packet rate is
12847 +             below 50,000 pbs. Now testing with a 100% send from Ixia.
12848 +
12849 +New features: NTR
12850 +
12851 +05 August 2003         CPHAL 1.6.5 (external release)
12852 +
12853 +CC Labels: REL_20030805_HALdallas_cpmac_01.06.05
12854 +
12855 +Bug fixes: NTR
12856 +
12857 +New features:  CPMAC : Added support for CPMAC modules that do not have a Phy connected.
12858 +               The CPMAC is informed of this by the MdioConnect option
12859 +               _CPMDIO_NOPHY. This is the only driver change needed to
12860 +               receive and transmit packets through the Marvel switch.
12861 +               Note  In this mode Link status will reported linked at 100/FD to
12862 +               PhyNum 0xFFFFFFFF.
12863 +
12864 +               ALL:  Cleaned up some Vlynq support logic.
12865 +
12866 +16 July 2003         CPSAR 1.6.3 (external release), no CPMAC release
12867 +
12868 +CC Labels: REL_20030716_HALdallas_cpsar_01.06.03
12869 +
12870 +Bug fixes: 1) Changed default value of CPCS_UU from 0x5aa5 to 0.  The old default value caused
12871 +              problems with Cisco routers.
12872 +
12873 +New features:  NTR
12874 +
12875 +Known issues not addressed in this release: NTR.
12876 +
12877 +01 July 2003         CPHAL 1.6.2 (external release)
12878 +
12879 +CC Labels: REL_20030701_HALdallas_cpmac_01.06.02
12880 +           REL_20030701_HALdallas_cpsar_01.06.02
12881 +
12882 +Bug fixes: 1) A previous firmware upgrade caused firmware OAM loopback cells to only work on every other
12883 +              command.  This has been fixed in the new firmware version (0.47).
12884 +           2) Problem with PTI values changing on transparent mode packets has been resolved.
12885 +           3) Previously, successful firmware OAM loopback cells waited 5 seconds before notifying the
12886 +              OS of success, rather that notifying immediately.  This has been resolved in firmware.
12887 +           4) PITS #148 (MAC and SAR), #149 (MAC) have been fixed.
12888 +
12889 +New features: 1) AAL5 HAL now capable of receiving unknown VCI/VPI cells on a single transparent channel.
12890 +                 See updated HAL document (AAL5 appendix) for implementation details.
12891 +              2) AAL5 HAL now allows OS to modify the OAM loopback timeout window.  Previously, failed
12892 +                 OAM loopback attempts timed out after a nominal 5 seconds (based on the SAR frequency
12893 +                 provided by the OS).  Now, the default is 5 seconds, but the OS may change the
12894 +                 value via halControl() to any integer number of milliseconds.  See updated HAL document
12895 +                 (AAL5 appendix) for implementation details.
12896 +              3) MAC (cpmdio): added loopback to Istate.  Used for debug.
12897 +
12898 +Known issues not addressed in this release: NTR.
12899 +
12900 +09 June 2003         CPSAR 1.6.1 (external release), CPMAC 1.6.1 (internal release - no functional change)
12901 +
12902 +Note: This is the same set of fixes being applied to 1.6.0 that were applied to 1.5.3.  The only difference
12903 +      between 1.6.1 and 1.5.4 is that 1.6.1 has the TurboDSL fix.
12904 +
12905 +CC Labels: REL_20030609_HALdallas_cpmac_01.06.01
12906 +           REL_20030609_HALdallas_cpsar_01.06.01
12907 +
12908 +Bug fixes: 1) Bug in OamLoopbackConfig fixed.
12909 +           2) New firmware version (.43) to fix Westell issue of dropped downstream packets in
12910 +              presence of OAM traffic when operating at or near line rate.
12911 +
12912 +New features: NTR.
12913 +
12914 +09 June 2003         CPSAR 1.5.4 (external release), CPMAC 1.5.4 (internal release - no functional change)
12915 +
12916 +Note:  This is a branch release from 1.5.3.  This does not contain anything from 1.6.0.  The CPMAC is
12917 +only being labeled to keep the release flow consistent.
12918 +
12919 +CC Labels: REL_20030609_HALdallas_cpmac_01.05.04
12920 +           REL_20030609_HALdallas_cpsar_01.05.04
12921 +
12922 +Bug fixes: 1) Bug in OamLoopbackConfig fixed.
12923 +           2) New firmware version (.43) to fix Westell issue of dropped downstream packets in
12924 +              presence of OAM traffic when operating at or near line rate.
12925 +
12926 +New features: NTR.
12927 +
12928 +30 May 2003         CPSAR 1.6.0 (external release), CPMAC 1.6.0 (internal release - no functional change)
12929 +
12930 +CC Labels: REL_20030530_HALdallas_cpmac_01.06.00
12931 +           REL_20030530_HALdallas_cpsar_01.06.00
12932 +
12933 +Bug fixes: 1) TurboDSL issue has been fixed with a software workaround in TxInt.  This workaround
12934 +              has been verified under Adam2 ONLY at this point.  Testing remains to be done on
12935 +              Linux and VxWorks.
12936 +
12937 +New features: NTR.
12938 +
12939 +Known issues not addressed in this release: NTR.
12940 +
12941 +30 May 2003         CPSAR 1.5.3 (external release), CPMAC 1.5.3 (internal release - no functional change)
12942 +
12943 +CC Labels: REL_20030530_HALdallas_cpmac_01.05.03
12944 +           REL_20030530_HALdallas_cpsar_01.05.03
12945 +
12946 +Bug fixes: NTR.
12947 +
12948 +New features: 1) AAL5 Send() has been modified to accept an ATM Header either in the first
12949 +                 fragment by itself, or in the first fragment directly in front of payload data.
12950 +                 The API() does not change.
12951 +              2) Documentation updates throughout, reflected in latest version of CPHAL user's
12952 +                 guide.
12953 +              3) AAL5 MaxFrags default value is now 46.  This is based upon the default AAL5
12954 +                 RxBufSize of 1518 (MaxFrags = (65568/1518) + 2).  IF THE OS CHOOSES A SMALLER
12955 +                 RxBufSize, IT MUST INCREASE THE VALUE OF MaxFrags ACCORDINGLY.  This is done
12956 +                 via halControl(), prior to Open().
12957 +
12958 +Known issues not addressed in this release:
12959 +              1) The Linux SAR driver is seeing an issue in which it cannot
12960 +                 reliably send traffic simultaneously on both the high and
12961 +                 low priority queues of a single AAL5 channel. (TurboDSL)
12962 +
12963 +23 May 2003         CPHAL 1.5.2 (external release)
12964 +
12965 +CC Labels: REL_20030523_HALdallas_cpmac_01.05.02
12966 +           REL_20030523_HALdallas_cpsar_01.05.02
12967 +
12968 +Bug fixes: 1) PITS #138: CPMAC flooding issue resolved.
12969 +           2) PITS #142: OS may now set "MaxFrags" via Control().  This controls the
12970 +              maximum number of fragments expected by the CPHAL.  The default value is 2 for
12971 +              CPMAC and 1028 for AAL5.  If the OS chooses a RxBufSize that will cause more
12972 +              fragments than the defaults, the OS must set "MaxFrags" to a correct value
12973 +              ((maximum packet length / RxBufSize) + 2).
12974 +           3) PITS #143: Fixed.
12975 +           4) Firmware OAM bug fixed. (new firmware release in this version)
12976 +
12977 +New features: NTR.
12978 +
12979 +Known issues not addressed in this release:
12980 +              1) The Linux SAR driver is seeing an issue in which it cannot
12981 +                 reliably send traffic simultaneously on both the high and
12982 +                 low priority queues of a single AAL5 channel. (TurboDSL)
12983 +
12984 +14 May 2003         CPHAL 1.5.1 (external release)
12985 +
12986 +CC Labels: REL_20030514_HALdallas_cpmac_01.05.01
12987 +           REL_20030514_HALdallas_cpsar_01.05.01
12988 +
12989 +Bug fixes:    1) PITS 132 - (CPMAC) Frames < 60 bytes and split into
12990 +                             multi-fragments.
12991 +              2) BCIL MR PSP00000353 - (CPMAC) PhyDev not free'd on halClose()
12992 +              3) PITS 113 - OsSetup bug in ChannelSetup fixed.
12993 +              4) Fixed AAL5 to check return values of InitTcb/InitRcb.
12994 +              5) Fixed Shutdown to properly free resources in the case of a Close
12995 +                 mode 1 followed by Shutdown.  Previously, buffer and descriptor
12996 +                 resources were left unfreed in this case.
12997 +
12998 +New features: 1) AAL5 Send() modified to be capable of accepting ATM header as first four
12999 +                 bytes of first fragment.  This allows the OS to "override" the
13000 +                 default ATM header which is constructed from preconfigured channel
13001 +                 parameters.
13002 +              2) AAL5 Receive() modified to be capable of passing the received ATM header (4 bytes, no HEC)
13003 +                 in the first fragment (by itself).  It also passes up the OS an indication
13004 +                 of what the received packet type was.  For Host OAM and transparent mode
13005 +                 packets, the ATM header is passed in this manner, and for other types of packets
13006 +                 (AAL5, NULL AAL) no ATM header is passed currently.
13007 +
13008 +Known issues not addressed in this release:
13009 +              1) The Linux SAR driver is seeing an issue in which it cannot
13010 +                 reliably send traffic simultaneously on both the high and
13011 +                 low priority queues of a single AAL5 channel.
13012 +
13013 +30 April 2003         CPHAL 1.5.0 (external release)
13014 +
13015 +CC Labels: REL_20030430_HALdallas_cpmac_01.05.00
13016 +           REL_20030430_HALdallas_cpsar_01.05.00
13017 +
13018 +Bug fixes:   1) Fixed AAL5 bug that rendered the low priority queue
13019 +                unusable.
13020 +             2) Fixed a bug in AAL5's Oam Rate calculations.
13021 +             3) Fixed use of "DeviceCPID" key in AAL5's halControl().
13022 +             4) Fixed RxReturn logic in HAL.  The HAL now can handle
13023 +                failing MallocRxBuffer calls when multiple fragments
13024 +                are being used.
13025 +
13026 +New features: 1) AAL5 Stats now available on a per queue basis.
13027 +              2) AAL5 adds two new keys to halControl() for "Set" actions:
13028 +                 RxVc_OamCh and RxVp_OamCh.
13029 +              3) Shutdown() has been modified for both AAL5 and CPMAC to
13030 +                 call Close() if the module is still in the Open state.
13031 +              4) CPMAC adds the following access keys to halControl():
13032 +                 hcPhyAccess,hcPhyNum,hcCpmacBase,hcSize,and hcCpmacSize.
13033 +              5) CPHAL no longer requests an extra 15 bytes on data buffer
13034 +                 mallocs.
13035 +
13036 +Known issues not addressed in this release:
13037 +              1) The Linux SAR driver is seeing an issue in which it cannot
13038 +                 reliably send traffic simultaneously on both the high and
13039 +                 low priority queues of a single AAL5 channel.
13040 +
13041 +21 April 2003         CPHAL 1.4.1 (external release)
13042 +
13043 +CC Labels: REL_20030421_HALdallas_cpmac_01.04.01
13044 +           REL_20030421_HALdallas_cpsar_01.04.01
13045 +
13046 +Bug fixes:   1) Fixed OAM logic in SAR portion of CPHAL.
13047 +
13048 +New features: 1) OAM loopback counters exposed through halControl.
13049 +              2) Host OAM Send() can now use a single channel to send
13050 +                 OAM cells on unlimited number of VP's/VC's.
13051 +              3) CPHAL now requests "SarFreq" through osControl.
13052 +              4) CPHAL now calculates all OAM function rates based on
13053 +                 "SarFreq"; function OamRateConfig removed for API.
13054 +              5) New OAM function OamLoopbackConfig, used for configuring
13055 +                 loopback functions in firmware OAM mode.
13056 +
13057 +Known issues not addressed in this release:  Bug fix 1) in release 1.4
13058 +             (see below) does not work properly for multiple fragments.
13059 +
13060 +10 April 2003         CPHAL 1.4 (external release)
13061 +
13062 +CC Labels: REL_20030410_HALdallas_cpmac_01.04.00
13063 +           REL_20030410_HALdallas_cpsar_01.04.00
13064 +
13065 +This release is for SAR and MAC.
13066 +
13067 +  Bug fixes: 1) Implemented logic in HAL to re-request buffer mallocs
13068 +                in the case of MallocRxBuffer failing.  The HAL now maintains
13069 +                a NeedsBuffer queue of all RCB's that are without buffers.
13070 +                On interrupts, or on Send(), the HAL checks to see if any
13071 +                RCB's are on the queue, and if so, calls MallocRxBuffer
13072 +                to attempt to get a new buffer and return the RCB to
13073 +                circulation.
13074 +             2) SAR now properly returns all error codes from halOpen and
13075 +                halChannelSetup.
13076 +
13077 +  New features: NTR
13078 +
13079 +  Known issues not addressed in this release: NTR
13080 +
13081 +08 April 2003         CPHAL 1.3.1 (internal release - SAR only)
13082 +
13083 +  CC Labels: REL_20030408_HALdallas_cpsar_01.03.01
13084 +
13085 +  This is a SAR only release.  The current CPMAC release is still 1.3.
13086 +
13087 +  Bug fixes: 1) PDSP State RAM / Scratchpad RAM is now completely cleared after reset.
13088 +                This resolves a stability issue.
13089 +
13090 +  New features: 1) OamMode is now a parameter in halControl().  Both "Set" and "Get"
13091 +                   actions are available.  The value may be "0" (Host OAM), or "1"
13092 +                   (Firmware OAM).
13093 +
13094 +  Known issues not addressed in this release:
13095 +             1) Appropriate action for HAL in the case of MallocRxBuffer failing.  We
13096 +                are investigating whether the HAL should implement a needs buffer
13097 +                queue.
13098 +
13099 +04 April 2003         CPHAL 1.3 (external release)
13100 +
13101 +  CC Labels: REL_20030404_HALdallas_cpmac_01.03.00
13102 +             REL_20030404_HALdallas_cpsar_01.03.00
13103 +             REL_20030404_HALdallas_cpaal5_01.03.00
13104 +             REL_20030404_HALdallas_cpaal2_01.03.00
13105 +
13106 +  This release requires no changes for the ethernet end driver.  The changes necessary
13107 +  for the sar driver (firmware file name changes) have already been implemented.
13108 +
13109 +  Bug fixes: 1) RxReturn now returns an error if MallocRxBuffer fails.  On RxReturn error, the driver should
13110 +                call RxReturn again at a later time (when the malloc may succeed) in order for the CPHAL
13111 +                to maintain a full complement of Rx buffers.  We recommend holding off making this driver
13112 +                change until we verify that this condition occurs.
13113 +
13114 +  New features: 1) Removed benign compiler warnings.
13115 +                2) PITS 122: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=122
13116 +                3) Cpsar label (above) now is applied to everything
13117 +                   beneath /cpsar.
13118 +                4) PITS 14: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=14
13119 +                   Transferred to MR PSP 00000089.
13120 +                5) PITS 120: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=120
13121 +
13122 +  Known issues not addressed in this release:
13123 +             1) PITS 102 (as relating to OamMode configuration):
13124 +                http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=102
13125 +                Future release will make OamMode configurable
13126 +                through halControl(), not on per channel basis.
13127 +
13128 +20 March 2003         CPHAL 1.2.1 (internal release)
13129 +
13130 +  CC Labels: REL_20030320_HALdallas_cpmac_01.02.01
13131 +             REL_20030320_HALdallas_cpsar_01.02.01
13132 +             REL_20030320_HALdallas_cpaal5_01.02.01
13133 +             REL_20030320_HALdallas_cpaal2_01.02.01
13134 +
13135 +  Bug fixes: 1. Fixed modification of buffer pointer following
13136 +                MallocRxBuffer in cppi.c.
13137 +             2. Removed extra firmware files from /cpsar.
13138 +
13139 +  New features: NTR.
13140 +
13141 +  Known issues not addressed in this release: NTR.
13142 +
13143 +07 March 2003         CPHAL 1.2 (external release)
13144 +
13145 +  CPMAC/CPSAR feature complete release.  SAR added
13146 +  several features including full OAM support and various
13147 +  other features and bug fixes to address PITS 99-106, and
13148 +  114.  CPMAC cleaned up details raised by India PSP
13149 +  team.
13150 +
13151 +29 January 2003       CPHAL RC 3.01a (external release)
13152 +
13153 +  Corrects non-static functions to be static in cppi.c.
13154 +
13155 +09 Janurary 2003      CPHAL RC 3.01 (external release)
13156 +
13157 +  PITS 88: Fixed MDIO re-connection problem (hcpmac.c)
13158 +  PITS 90: Corrected Rx Buffer Pointer modification (cppi.c)
13159 +
13160 +  Corrected error in cpremap.c
13161 +
13162 +20 December 2002      CPHAL RC 3 (external release)
13163 +
13164 +  Statistics support via halControl().  See Appendix A of guide.
13165 +  Fixed errors in ChannelTeardown/ChannelSetup CPHAL logic.
13166 +  Added multicast support as requested.
13167 +  Several new OS string functions added to OS_FUNCTIONS.
13168 +  "DebugLevel" configuration parameter changed to "Debug".
13169 +  "Stats0" changed to "StatsDump" for CPMAC.
13170 +
13171 +13 December 2002      CPHAL RC 2.03 (internal release)
13172 +
13173 +  Performance improvements.
13174 +  More debug statements implemented (esp AAL5).
13175 +  Updated makefile with "make debug" option.
13176 +  Hbridge performance: [debug library] 15774 tps (53% line rate)
13177 +                   [non-debug library] 13700 tps (46%)
13178 +
13179 +10 December 2002      CPHAL Release Candidate 2.02 (internal release)
13180 +
13181 + Much of the configuration code internal to CPMAC and AAL5 has been made common.
13182 + [os]Receive API had been modified to remove OsReceiveInfo.  This information is now
13183 +   available as third member of the FRAGLIST structure, on a per buffer basis.
13184 + Successfully tested multi-fragment support on CPMAC, using 32 byte buffers.
13185 + Code is now Emerald compliant - all buffer descriptors now aligned to cache-line
13186 +   boundaries.
13187 +
13188 +2 December 2002      CPHAL Release Candidate 2.01
13189 +
13190 + Updates to comments in hcpmac.c, cpmdio.c, hcpmac.h
13191 + Nested comment in hcpmac.c in RC2 can cause compile errors.
13192 +
13193 +25 November 2002      CPHAL Release Candidate 2
13194 +
13195 +Project Items not completed for RC2
13196 +#6  Ship as Library -  Once under CC. Moved to RC3
13197 +#8  Under Clearcase -  Moved to RC3
13198 +#25 Emerald compliant - Moved to RC3
13199 +#26 Statistics support - Moved to RC3 (some support in RC2)
13200 +#36 Debug scheme implemented - Moved to RC3 (some support in RC2)
13201 +
13202 +8 November 2002       CPHAL Release Candidate 1
13203 +
13204 +Notes:
13205 +
13206 +Project Items not completed for RC1
13207 +
13208 +#8  Under Clearcase -  Clearcase server failure this week. Moved to RC2
13209 +#6  Ship as Library -  Once under CC. Moved to RC2
13210 +#13 Verify Datatypes. Moved to RC2
13211 +#14 Review APIs.  Moved to RC2
13212 +
13213 +APIs under review for RC2
13214 +
13215 +halIsr()
13216 +hslRxReturn()
13217 +halSend()
13218 +osSendComplete()
13219 +osReceive()
13220 +
13221 +
13222 +CPMAC Build Instructions
13223 +
13224 +Compile the file 'hcpmac.c'.
13225 +
13226 +
13227 +AAL5 Build Instructions
13228 +
13229 +The AAL5 build is composed of the source files aal5sar.c and cpsar.c.
13230 +Refer to the provided makefile for an example of compiling these files
13231 +into a library.
13232 +
13233 +Example CPHAL Code
13234 +
13235 +CPMAC:
13236 +
13237 +Example CPMAC code is provided in the file hbridge.c.
13238 +This program is provided simply as an example of using the CPHAL API.
13239 +It is not intended to be compiled and executed in your environment.
13240 +
13241 +AAL5:
13242 +
13243 +Example AAL5 code is provided in the file loopback.c.  This program
13244 +is provided simply as an example of using the CPHAL API.  It is not
13245 +intended to be compiled and executed in your environment.
13246 +
13247 +
13248 +Performance Baseline
13249 +
13250 +
13251 +Cpmac
13252 +
13253 +RC1: hbridge.bin, running with IXIA cpahl_1.cfg.
13254 +     This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port.
13255 +     MIPS core 4Kc.
13256 +
13257 +RC2: hbridge.bin, running with IXIA cpahl_1.cfg.
13258 +     This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port.
13259 +     MIPS core 4Ke.
13260 +     CPHAL now includes Emerald support, but this has been disabled by using 'cache -wt' to emulate 4Kc.
13261 +
13262 +RC3: hbridge.bin, running with IXIA cpahl_1.cfg.
13263 +     This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port.
13264 +     MIPS core 4Ke.
13265 +     Running as Emerald processor.
13266 +
13267 +Release  Total Receive Rate    Throughput Setting
13268 +
13269 +RC1             11300                 38%
13270 +RC2              9524                 32%
13271 +RC3             15190                 51%
13272 diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in
13273 --- linux.old/drivers/net/Config.in     2005-07-12 03:20:45.726149872 +0200
13274 +++ linux.dev/drivers/net/Config.in     2005-07-12 02:48:42.180573000 +0200
13275 @@ -25,6 +25,24 @@
13276  comment 'Ethernet (10 or 100Mbit)'
13277  bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
13278  if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
13279 +   if [ "$CONFIG_MIPS_TITAN" = "y" -o "$CONFIG_AR7" = "y" ]; then
13280 +        tristate '  Texas Instruments Avalanche CPMAC support' CONFIG_MIPS_AVALANCHE_CPMAC     
13281 +   fi
13282 +   if [ "$CONFIG_MIPS_AVALANCHE_CPMAC" != "n" ]; then
13283 +     if [ "$CONFIG_AR7WRD" = "y" -o "$CONFIG_AR7VWI" = "y" -o "$CONFIG_AR7VW" = "y" ]; then
13284 +        define_bool  CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC y
13285 +         define_int CONFIG_MIPS_CPMAC_PORTS 1
13286 +        if [ "$CONFIG_MIPS_AVALANCHE_MARVELL" = "y" ]; then
13287 +             define_bool CONFIG_AVALANCHE_LOW_CPMAC  n
13288 +             define_bool CONFIG_AVALANCHE_HIGH_CPMAC y
13289 +        else
13290 +             define_bool CONFIG_AVALANCHE_CPMAC_AUTO y
13291 +             define_bool CONFIG_AVALANCHE_LOW_CPMAC n
13292 +             define_bool CONFIG_AVALANCHE_HIGH_CPMAC n
13293 +       fi
13294 +     fi
13295 +   fi
13296 +
13297     if [ "$CONFIG_ARM" = "y" ]; then  
13298        dep_bool '  ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110
13299        tristate '  Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS
13300 diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile
13301 --- linux.old/drivers/net/Makefile      2005-07-12 03:20:45.726149872 +0200
13302 +++ linux.dev/drivers/net/Makefile      2005-07-12 02:48:42.181573000 +0200
13303 @@ -56,6 +56,16 @@
13304  subdir-$(CONFIG_BONDING) += bonding
13305  
13306  #
13307 +# Texas Instruments AVALANCHE CPMAC  driver
13308 +#
13309 +
13310 +subdir-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac
13311 +#obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac/avalanche_cpmac.o
13312 +ifeq ($(CONFIG_MIPS_AVALANCHE_CPMAC),y)
13313 +  obj-y += avalanche_cpmac/avalanche_cpmac.o
13314 +endif
13315 +
13316 +#
13317  # link order important here
13318  #
13319  obj-$(CONFIG_PLIP) += plip.o
13320 --- linux.old/drivers/net/avalanche_cpmac/cpmac.c       2005-08-25 10:56:33.702931008 +0200
13321 +++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c       2005-08-25 11:08:45.027451520 +0200
13322 @@ -2158,17 +2158,16 @@
13323      CPMAC_PRIVATE_INFO_T *p_cpmac_priv  = p_dev->priv;
13324      CPMAC_DRV_HAL_INFO_T *p_drv_hal     = p_cpmac_priv->drv_hal;
13325      struct sk_buff       *p_skb         = fragList[0].OsInfo;
13326 -    p_skb->len                          = fragList[0].len;    
13327  
13328      /* invalidate the cache. */
13329      dma_cache_inv((unsigned long)p_skb->data, fragList[0].len);    
13330  #ifdef CPMAC_TEST
13331 -    xdump(p_skb->data, p_skb->len, "recv");
13332 +    xdump(p_skb->data, fragList[0].len, "recv");
13333  #endif
13334  #ifdef CPMAC_8021Q_SUPPORT
13335      /* 802.1q stuff, just does the basic checking here. */
13336      if(!p_cpmac_priv->enable_802_1q      &&
13337 -       p_skb->len > TCI_END_OFFSET       &&
13338 +       fragList[0].len > TCI_END_OFFSET       &&
13339         IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET))
13340      {
13341           goto cpmac_hal_recv_frame_mismatch;