]>
Commit | Line | Data |
---|---|---|
7152b1d0 WD |
1 | /****************************************************************************** |
2 | * | |
3 | * Name: skgeinit.c | |
4 | * Project: GEnesis, PCI Gigabit Ethernet Adapter | |
5 | * Version: $Revision: 1.85 $ | |
6 | * Date: $Date: 2003/02/05 15:30:33 $ | |
7 | * Purpose: Contains functions to initialize the GE HW | |
8 | * | |
9 | ******************************************************************************/ | |
10 | ||
11 | /****************************************************************************** | |
12 | * | |
13 | * (C)Copyright 1998-2003 SysKonnect GmbH. | |
14 | * | |
15 | * This program is free software; you can redistribute it and/or modify | |
16 | * it under the terms of the GNU General Public License as published by | |
17 | * the Free Software Foundation; either version 2 of the License, or | |
18 | * (at your option) any later version. | |
19 | * | |
20 | * The information in this file is provided "AS IS" without warranty. | |
21 | * | |
22 | ******************************************************************************/ | |
23 | ||
24 | /****************************************************************************** | |
25 | * | |
26 | * History: | |
27 | * | |
28 | * $Log: skgeinit.c,v $ | |
29 | * Revision 1.85 2003/02/05 15:30:33 rschmidt | |
30 | * Corrected setting of GIHstClkFact (Host Clock Factor) and | |
31 | * GIPollTimerVal (Descr. Poll Timer Init Value) for YUKON. | |
32 | * Editorial changes. | |
42d1f039 | 33 | * |
7152b1d0 WD |
34 | * Revision 1.84 2003/01/28 09:57:25 rschmidt |
35 | * Added detection of YUKON-Lite Rev. A0 (stored in GIYukonLite). | |
36 | * Disabled Rx GMAC FIFO Flush for YUKON-Lite Rev. A0. | |
37 | * Added support for CLK_RUN (YUKON-Lite). | |
38 | * Added additional check of PME from D3cold for setting GIVauxAvail. | |
39 | * Editorial changes. | |
42d1f039 | 40 | * |
7152b1d0 WD |
41 | * Revision 1.83 2002/12/17 16:15:41 rschmidt |
42 | * Added default setting of PhyType (Copper) for YUKON. | |
43 | * Added define around check for HW self test results. | |
44 | * Editorial changes. | |
42d1f039 | 45 | * |
7152b1d0 WD |
46 | * Revision 1.82 2002/12/05 13:40:21 rschmidt |
47 | * Added setting of Rx GMAC FIFO Flush Mask register. | |
48 | * Corrected PhyType with new define SK_PHY_MARV_FIBER when | |
49 | * YUKON Fiber board was found. | |
50 | * Editorial changes. | |
42d1f039 | 51 | * |
7152b1d0 WD |
52 | * Revision 1.81 2002/11/15 12:48:35 rschmidt |
53 | * Replaced message SKERR_HWI_E018 with SKERR_HWI_E024 for Rx queue error | |
54 | * in SkGeStopPort(). | |
55 | * Added init for pAC->GIni.GIGenesis with SK_FALSE in YUKON-branch. | |
56 | * Editorial changes. | |
42d1f039 | 57 | * |
7152b1d0 WD |
58 | * Revision 1.80 2002/11/12 17:28:30 rschmidt |
59 | * Initialized GIPciSlot64 and GIPciClock66 in SkGeInit1(). | |
60 | * Reduced PCI FIFO watermarks for 32bit/33MHz bus in SkGeInitBmu(). | |
61 | * Editorial changes. | |
42d1f039 | 62 | * |
7152b1d0 WD |
63 | * Revision 1.79 2002/10/21 09:31:02 mkarl |
64 | * Changed SkGeInitAssignRamToQueues(), removed call to | |
65 | * SkGeInitAssignRamToQueues in SkGeInit1 and fixed compiler warning in | |
66 | * SkGeInit1. | |
42d1f039 | 67 | * |
7152b1d0 WD |
68 | * Revision 1.78 2002/10/16 15:55:07 mkarl |
69 | * Fixed a bug in SkGeInitAssignRamToQueues. | |
42d1f039 | 70 | * |
7152b1d0 WD |
71 | * Revision 1.77 2002/10/14 15:07:22 rschmidt |
72 | * Corrected timeout handling for Rx queue in SkGeStopPort() (#10748) | |
73 | * Editorial changes. | |
42d1f039 | 74 | * |
7152b1d0 WD |
75 | * Revision 1.76 2002/10/11 09:24:38 mkarl |
76 | * Added check for HW self test results. | |
42d1f039 | 77 | * |
7152b1d0 WD |
78 | * Revision 1.75 2002/10/09 16:56:44 mkarl |
79 | * Now call SkGeInitAssignRamToQueues() in Init Level 1 in order to assign | |
80 | * the adapter memory to the queues. This default assignment is not suitable | |
81 | * for dual net mode. | |
42d1f039 | 82 | * |
7152b1d0 WD |
83 | * Revision 1.74 2002/09/12 08:45:06 rwahl |
84 | * Set defaults for PMSCap, PLinkSpeed & PLinkSpeedCap dependent on PHY. | |
42d1f039 | 85 | * |
7152b1d0 WD |
86 | * Revision 1.73 2002/08/16 15:19:45 rschmidt |
87 | * Corrected check for Tx queues in SkGeCheckQSize(). | |
88 | * Added init for new entry GIGenesis and GICopperType | |
89 | * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis. | |
90 | * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros. | |
42d1f039 | 91 | * |
7152b1d0 WD |
92 | * Revision 1.72 2002/08/12 13:38:55 rschmidt |
93 | * Added check if VAUX is available (stored in GIVauxAvail) | |
94 | * Initialized PLinkSpeedCap in Port struct with SK_LSPEED_CAP_1000MBPS | |
95 | * Editorial changes. | |
42d1f039 | 96 | * |
7152b1d0 WD |
97 | * Revision 1.71 2002/08/08 16:32:58 rschmidt |
98 | * Added check for Tx queues in SkGeCheckQSize(). | |
99 | * Added start of Time Stamp Timer (YUKON) in SkGeInit2(). | |
100 | * Editorial changes. | |
42d1f039 | 101 | * |
7152b1d0 WD |
102 | * Revision 1.70 2002/07/23 16:04:26 rschmidt |
103 | * Added init for GIWolOffs (HW-Bug in YUKON 1st rev.) | |
104 | * Minor changes | |
42d1f039 | 105 | * |
7152b1d0 WD |
106 | * Revision 1.69 2002/07/17 17:07:08 rwahl |
107 | * - SkGeInit1(): fixed PHY type debug output; corrected init of GIFunc | |
108 | * table & GIMacType. | |
109 | * - Editorial changes. | |
42d1f039 | 110 | * |
7152b1d0 WD |
111 | * Revision 1.68 2002/07/15 18:38:31 rwahl |
112 | * Added initialization for MAC type dependent function table. | |
42d1f039 | 113 | * |
7152b1d0 WD |
114 | * Revision 1.67 2002/07/15 15:45:39 rschmidt |
115 | * Added Tx Store & Forward for YUKON (GMAC Tx FIFO is only 1 kB) | |
116 | * Replaced SK_PHY_MARV by SK_PHY_MARV_COPPER | |
117 | * Editorial changes | |
42d1f039 | 118 | * |
7152b1d0 WD |
119 | * Revision 1.66 2002/06/10 09:35:08 rschmidt |
120 | * Replaced C++ comments (//) | |
121 | * Editorial changes | |
42d1f039 | 122 | * |
7152b1d0 WD |
123 | * Revision 1.65 2002/06/05 08:33:37 rschmidt |
124 | * Changed GIRamSize and Reset sequence for YUKON. | |
125 | * SkMacInit() replaced by SkXmInitMac() resp. SkGmInitMac() | |
42d1f039 | 126 | * |
7152b1d0 WD |
127 | * Revision 1.64 2002/04/25 13:03:20 rschmidt |
128 | * Changes for handling YUKON. | |
129 | * Removed reference to xmac_ii.h (not necessary). | |
130 | * Moved all defines into header file. | |
131 | * Replaced all SkXm...() functions with SkMac...() to handle also | |
132 | * YUKON's GMAC. | |
133 | * Added handling for GMAC FIFO in SkGeInitMacFifo(), SkGeStopPort(). | |
134 | * Removed 'goto'-directive from SkGeCfgSync(), SkGeCheckQSize(). | |
135 | * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(), | |
136 | * SkMacFlushTxFifo(). | |
137 | * Optimized timeout handling in SkGeStopPort(). | |
138 | * Initialized PLinkSpeed in Port struct with SK_LSPEED_AUTO. | |
139 | * Release of GMAC Link Control reset in SkGeInit1(). | |
140 | * Initialized GIChipId and GIChipRev in GE Init structure. | |
141 | * Added GIRamSize and PhyType values for YUKON. | |
142 | * Removed use of PRxCmd to setup XMAC. | |
143 | * Moved setting of XM_RX_DIS_CEXT to SkXmInitMac(). | |
144 | * Use of SkGeXmitLED() only for GENESIS. | |
145 | * Changes for V-CPU support. | |
146 | * Editorial changes. | |
42d1f039 | 147 | * |
7152b1d0 WD |
148 | * Revision 1.63 2001/04/05 11:02:09 rassmann |
149 | * Stop Port check of the STOP bit did not take 2/18 sec as wanted. | |
42d1f039 | 150 | * |
7152b1d0 WD |
151 | * Revision 1.62 2001/02/07 07:54:21 rassmann |
152 | * Corrected copyright. | |
42d1f039 | 153 | * |
7152b1d0 WD |
154 | * Revision 1.61 2001/01/31 15:31:40 gklug |
155 | * fix: problem with autosensing an SR8800 switch | |
42d1f039 | 156 | * |
7152b1d0 WD |
157 | * Revision 1.60 2000/10/18 12:22:21 cgoos |
158 | * Added workaround for half duplex hangup. | |
42d1f039 | 159 | * |
7152b1d0 WD |
160 | * Revision 1.59 2000/10/10 11:22:06 gklug |
161 | * add: in manual half duplex mode ignore carrier extension errors | |
42d1f039 | 162 | * |
7152b1d0 WD |
163 | * Revision 1.58 2000/10/02 14:10:27 rassmann |
164 | * Reading BCOM PHY after releasing reset until it returns a valid value. | |
42d1f039 | 165 | * |
7152b1d0 WD |
166 | * Revision 1.57 2000/08/03 14:55:28 rassmann |
167 | * Waiting for I2C to be ready before de-initializing adapter | |
168 | * (prevents sensors from hanging up). | |
42d1f039 | 169 | * |
7152b1d0 WD |
170 | * Revision 1.56 2000/07/27 12:16:48 gklug |
171 | * fix: Stop Port check of the STOP bit does now take 2/18 sec as wanted | |
42d1f039 | 172 | * |
7152b1d0 WD |
173 | * Revision 1.55 1999/11/22 13:32:26 cgoos |
174 | * Changed license header to GPL. | |
42d1f039 | 175 | * |
7152b1d0 WD |
176 | * Revision 1.54 1999/10/26 07:32:54 malthoff |
177 | * Initialize PHWLinkUp with SK_FALSE. Required for Diagnostics. | |
42d1f039 | 178 | * |
7152b1d0 WD |
179 | * Revision 1.53 1999/08/12 19:13:50 malthoff |
180 | * Fix for 1000BT. Do not owerwrite XM_MMU_CMD when | |
181 | * disabling receiver and transmitter. Other bits | |
182 | * may be lost. | |
42d1f039 | 183 | * |
7152b1d0 WD |
184 | * Revision 1.52 1999/07/01 09:29:54 gklug |
185 | * fix: DoInitRamQueue needs pAC | |
42d1f039 | 186 | * |
7152b1d0 WD |
187 | * Revision 1.51 1999/07/01 08:42:21 gklug |
188 | * chg: use Store & forward for RAM buffer when Jumbos are used | |
42d1f039 | 189 | * |
7152b1d0 WD |
190 | * Revision 1.50 1999/05/27 13:19:38 cgoos |
191 | * Added Tx PCI watermark initialization. | |
192 | * Removed Tx RAM queue Store & Forward setting. | |
42d1f039 | 193 | * |
7152b1d0 WD |
194 | * Revision 1.49 1999/05/20 14:32:45 malthoff |
195 | * SkGeLinkLED() is completly removed now. | |
42d1f039 | 196 | * |
7152b1d0 WD |
197 | * Revision 1.48 1999/05/19 07:28:24 cgoos |
198 | * SkGeLinkLED no more available for drivers. | |
199 | * Changes for 1000Base-T. | |
42d1f039 | 200 | * |
7152b1d0 WD |
201 | * Revision 1.47 1999/04/08 13:57:45 gklug |
202 | * add: Init of new port struct fiels PLinkResCt | |
203 | * chg: StopPort Timer check | |
42d1f039 | 204 | * |
7152b1d0 WD |
205 | * Revision 1.46 1999/03/25 07:42:15 malthoff |
206 | * SkGeStopPort(): Add workaround for cache incoherency. | |
207 | * Create error log entry, disable port, and | |
208 | * exit loop if it does not terminate. | |
209 | * Add XM_RX_LENERR_OK to the default value for the | |
210 | * XMAC receive command register. | |
42d1f039 | 211 | * |
7152b1d0 WD |
212 | * Revision 1.45 1999/03/12 16:24:47 malthoff |
213 | * Remove PPollRxD and PPollTxD. | |
214 | * Add check for GIPollTimerVal. | |
215 | * | |
216 | * Revision 1.44 1999/03/12 13:40:23 malthoff | |
217 | * Fix: SkGeXmitLED(), SK_LED_TST mode does not work. | |
218 | * Add: Jumbo frame support. | |
219 | * Chg: Resolution of parameter IntTime in SkGeCfgSync(). | |
220 | * | |
221 | * Revision 1.43 1999/02/09 10:29:46 malthoff | |
222 | * Bugfix: The previous modification again also for the second location. | |
223 | * | |
224 | * Revision 1.42 1999/02/09 09:35:16 malthoff | |
225 | * Bugfix: The bits '66 MHz Capable' and 'NEWCAP are reset while | |
226 | * clearing the error bits in the PCI status register. | |
227 | * | |
228 | * Revision 1.41 1999/01/18 13:07:02 malthoff | |
229 | * Bugfix: Do not use CFG cycles after during Init- or Runtime, because | |
230 | * they may not be available after Boottime. | |
231 | * | |
232 | * Revision 1.40 1999/01/11 12:40:49 malthoff | |
233 | * Bug fix: PCI_STATUS: clearing error bits sets the UDF bit. | |
234 | * | |
235 | * Revision 1.39 1998/12/11 15:17:33 gklug | |
236 | * chg: Init LipaAutoNeg with Unknown | |
237 | * | |
238 | * Revision 1.38 1998/12/10 11:02:57 malthoff | |
239 | * Disable Error Log Message when calling SkGeInit(level 2) | |
240 | * more than once. | |
241 | * | |
242 | * Revision 1.37 1998/12/07 12:18:25 gklug | |
243 | * add: refinement of autosense mode: take into account the autoneg cap of LiPa | |
244 | * | |
245 | * Revision 1.36 1998/12/07 07:10:39 gklug | |
246 | * fix: init values of LinkBroken/ Capabilities for management | |
247 | * | |
248 | * Revision 1.35 1998/12/02 10:56:20 gklug | |
249 | * fix: do NOT init LoinkSync Counter. | |
250 | * | |
251 | * Revision 1.34 1998/12/01 10:53:21 gklug | |
252 | * add: init of additional Counters for workaround | |
253 | * | |
254 | * Revision 1.33 1998/12/01 10:00:49 gklug | |
255 | * add: init PIsave var in Port struct | |
256 | * | |
257 | * Revision 1.32 1998/11/26 14:50:40 gklug | |
258 | * chg: Default is autosensing with AUTOFULL mode | |
259 | * | |
260 | * Revision 1.31 1998/11/25 15:36:16 gklug | |
261 | * fix: do NOT stop LED Timer when port should be stopped | |
262 | * | |
263 | * Revision 1.30 1998/11/24 13:15:28 gklug | |
264 | * add: Init PCkeckPar struct member | |
265 | * | |
266 | * Revision 1.29 1998/11/18 13:19:27 malthoff | |
267 | * Disable packet arbiter timeouts on receive side. | |
268 | * Use maximum timeout value for packet arbiter | |
269 | * transmit timeouts. | |
270 | * Add TestStopBit() function to handle stop RX/TX | |
271 | * problem with active descriptor poll timers. | |
272 | * Bug Fix: Descriptor Poll Timer not started, because | |
273 | * GIPollTimerVal was initialized with 0. | |
274 | * | |
275 | * Revision 1.28 1998/11/13 14:24:26 malthoff | |
276 | * Bug Fix: SkGeStopPort() may hang if a Packet Arbiter Timout | |
277 | * is pending or occurs while waiting for TX_STOP and RX_STOP. | |
278 | * The PA timeout is cleared now while waiting for TX- or RX_STOP. | |
279 | * | |
280 | * Revision 1.27 1998/11/02 11:04:36 malthoff | |
281 | * fix the last fix | |
282 | * | |
283 | * Revision 1.26 1998/11/02 10:37:03 malthoff | |
284 | * Fix: SkGePollTxD() enables always the synchronounous poll timer. | |
285 | * | |
286 | * Revision 1.25 1998/10/28 07:12:43 cgoos | |
287 | * Fixed "LED_STOP" in SkGeLnkSyncCnt, "== SK_INIT_IO" in SkGeInit. | |
288 | * Removed: Reset of RAM Interface in SkGeStopPort. | |
289 | * | |
290 | * Revision 1.24 1998/10/27 08:13:12 malthoff | |
291 | * Remove temporary code. | |
292 | * | |
293 | * Revision 1.23 1998/10/26 07:45:03 malthoff | |
294 | * Add Address Calculation Workaround: If the EPROM byte | |
295 | * Id is 3, the address offset is 512 kB. | |
296 | * Initialize default values for PLinkMode and PFlowCtrlMode. | |
297 | * | |
298 | * Revision 1.22 1998/10/22 09:46:47 gklug | |
299 | * fix SysKonnectFileId typo | |
300 | * | |
301 | * Revision 1.21 1998/10/20 12:11:56 malthoff | |
302 | * Don't dendy the Queue config if the size of the unused | |
303 | * Rx qeueu is zero. | |
304 | * | |
305 | * Revision 1.20 1998/10/19 07:27:58 malthoff | |
306 | * SkGeInitRamIface() is public to be called by diagnostics. | |
307 | * | |
308 | * Revision 1.19 1998/10/16 13:33:45 malthoff | |
309 | * Fix: enabling descriptor polling is not allowed until | |
310 | * the descriptor addresses are set. Descriptor polling | |
311 | * must be handled by the driver. | |
312 | * | |
313 | * Revision 1.18 1998/10/16 10:58:27 malthoff | |
314 | * Remove temp. code for Diag prototype. | |
315 | * Remove lint warning for dummy reads. | |
316 | * Call SkGeLoadLnkSyncCnt() during SkGeInitPort(). | |
317 | * | |
318 | * Revision 1.17 1998/10/14 09:16:06 malthoff | |
319 | * Change parameter LimCount and programming of | |
320 | * the limit counter in SkGeCfgSync(). | |
321 | * | |
322 | * Revision 1.16 1998/10/13 09:21:16 malthoff | |
323 | * Don't set XM_RX_SELF_RX in RxCmd Reg, because it's | |
324 | * like a Loopback Mode in half duplex. | |
325 | * | |
326 | * Revision 1.15 1998/10/09 06:47:40 malthoff | |
327 | * SkGeInitMacArb(): set recovery counters init value | |
328 | * to zero although this counters are not uesd. | |
329 | * Bug fix in Rx Upper/Lower Pause Threshold calculation. | |
330 | * Add XM_RX_SELF_RX to RxCmd. | |
331 | * | |
332 | * Revision 1.14 1998/10/06 15:15:53 malthoff | |
333 | * Make sure no pending IRQ is cleared in SkGeLoadLnkSyncCnt(). | |
334 | * | |
335 | * Revision 1.13 1998/10/06 14:09:36 malthoff | |
336 | * Add SkGeLoadLnkSyncCnt(). Modify | |
337 | * the 'port stopped' condition according | |
338 | * to the current problem report. | |
339 | * | |
340 | * Revision 1.12 1998/10/05 08:17:21 malthoff | |
341 | * Add functions: SkGePollRxD(), SkGePollTxD(), | |
342 | * DoCalcAddr(), SkGeCheckQSize(), | |
343 | * DoInitRamQueue(), and SkGeCfgSync(). | |
344 | * Add coding for SkGeInitMacArb(), SkGeInitPktArb(), | |
345 | * SkGeInitMacFifo(), SkGeInitRamBufs(), | |
346 | * SkGeInitRamIface(), and SkGeInitBmu(). | |
347 | * | |
348 | * Revision 1.11 1998/09/29 08:26:29 malthoff | |
349 | * bug fix: SkGeInit0() 'i' should be increment. | |
350 | * | |
351 | * Revision 1.10 1998/09/28 13:19:01 malthoff | |
352 | * Coding time: Save the done work. | |
353 | * Modify SkGeLinkLED(), add SkGeXmitLED(), | |
354 | * define SkGeCheckQSize(), SkGeInitMacArb(), | |
355 | * SkGeInitPktArb(), SkGeInitMacFifo(), | |
356 | * SkGeInitRamBufs(), SkGeInitRamIface(), | |
357 | * and SkGeInitBmu(). Do coding for SkGeStopPort(), | |
358 | * SkGeInit1(), SkGeInit2(), and SkGeInit3(). | |
359 | * Do coding for SkGeDinit() and SkGeInitPort(). | |
360 | * | |
361 | * Revision 1.9 1998/09/16 14:29:05 malthoff | |
362 | * Some minor changes. | |
363 | * | |
364 | * Revision 1.8 1998/09/11 05:29:14 gklug | |
365 | * add: init state of a port | |
366 | * | |
367 | * Revision 1.7 1998/09/04 09:26:25 malthoff | |
368 | * Short temporary modification. | |
369 | * | |
370 | * Revision 1.6 1998/09/04 08:27:59 malthoff | |
371 | * Remark the do-while in StopPort() because it never ends | |
372 | * without a GE adapter. | |
373 | * | |
374 | * Revision 1.5 1998/09/03 14:05:45 malthoff | |
375 | * Change comment for SkGeInitPort(). Do not | |
376 | * repair the queue sizes if invalid. | |
377 | * | |
378 | * Revision 1.4 1998/09/03 10:03:19 malthoff | |
379 | * Implement the new interface according to the | |
380 | * reviewed interface specification. | |
381 | * | |
382 | * Revision 1.3 1998/08/19 09:11:25 gklug | |
383 | * fix: struct are removed from c-source (see CCC) | |
384 | * | |
385 | * Revision 1.2 1998/07/28 12:33:58 malthoff | |
386 | * Add 'IoC' parameter in function declaration and SK IO macros. | |
387 | * | |
388 | * Revision 1.1 1998/07/23 09:48:57 malthoff | |
389 | * Creation. First dummy 'C' file. | |
390 | * SkGeInit(Level 0) is card_start for GE. | |
391 | * SkGeDeInit() is card_stop for GE. | |
392 | * | |
393 | * | |
394 | ******************************************************************************/ | |
395 | ||
149dded2 WD |
396 | #include <config.h> |
397 | ||
7152b1d0 WD |
398 | #include "h/skdrv1st.h" |
399 | #include "h/skdrv2nd.h" | |
400 | ||
401 | /* global variables ***********************************************************/ | |
402 | ||
403 | /* local variables ************************************************************/ | |
404 | ||
405 | static const char SysKonnectFileId[] = | |
406 | "@(#)$Id: skgeinit.c,v 1.85 2003/02/05 15:30:33 rschmidt Exp $ (C) SK "; | |
407 | ||
408 | struct s_QOffTab { | |
409 | int RxQOff; /* Receive Queue Address Offset */ | |
410 | int XsQOff; /* Sync Tx Queue Address Offset */ | |
411 | int XaQOff; /* Async Tx Queue Address Offset */ | |
412 | }; | |
413 | static struct s_QOffTab QOffTab[] = { | |
414 | {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} | |
415 | }; | |
416 | ||
417 | ||
418 | /****************************************************************************** | |
419 | * | |
420 | * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring | |
421 | * | |
422 | * Description: | |
423 | * Enable or disable the descriptor polling of the receive descriptor | |
424 | * ring (RxD) for port 'Port'. | |
425 | * The new configuration is *not* saved over any SkGeStopPort() and | |
426 | * SkGeInitPort() calls. | |
427 | * | |
428 | * Returns: | |
429 | * nothing | |
430 | */ | |
431 | void SkGePollRxD( | |
432 | SK_AC *pAC, /* adapter context */ | |
433 | SK_IOC IoC, /* IO context */ | |
434 | int Port, /* Port Index (MAC_1 + n) */ | |
435 | SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ | |
436 | { | |
437 | SK_GEPORT *pPrt; | |
438 | ||
439 | pPrt = &pAC->GIni.GP[Port]; | |
440 | ||
441 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? | |
442 | CSR_ENA_POL : CSR_DIS_POL); | |
443 | } /* SkGePollRxD */ | |
444 | ||
445 | ||
446 | /****************************************************************************** | |
447 | * | |
448 | * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings | |
449 | * | |
450 | * Description: | |
451 | * Enable or disable the descriptor polling of the transmit descriptor | |
452 | * ring(s) (TxD) for port 'Port'. | |
453 | * The new configuration is *not* saved over any SkGeStopPort() and | |
454 | * SkGeInitPort() calls. | |
455 | * | |
456 | * Returns: | |
457 | * nothing | |
458 | */ | |
459 | void SkGePollTxD( | |
460 | SK_AC *pAC, /* adapter context */ | |
461 | SK_IOC IoC, /* IO context */ | |
462 | int Port, /* Port Index (MAC_1 + n) */ | |
463 | SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ | |
464 | { | |
465 | SK_GEPORT *pPrt; | |
466 | SK_U32 DWord; | |
467 | ||
468 | pPrt = &pAC->GIni.GP[Port]; | |
469 | ||
470 | DWord = (PollTxD) ? CSR_ENA_POL : CSR_DIS_POL; | |
471 | ||
472 | if (pPrt->PXSQSize != 0) { | |
473 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); | |
474 | } | |
42d1f039 | 475 | |
7152b1d0 WD |
476 | if (pPrt->PXAQSize != 0) { |
477 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); | |
478 | } | |
479 | } /* SkGePollTxD */ | |
480 | ||
481 | ||
482 | /****************************************************************************** | |
483 | * | |
484 | * SkGeYellowLED() - Switch the yellow LED on or off. | |
485 | * | |
486 | * Description: | |
487 | * Switch the yellow LED on or off. | |
488 | * | |
489 | * Note: | |
490 | * This function may be called any time after SkGeInit(Level 1). | |
491 | * | |
492 | * Returns: | |
493 | * nothing | |
494 | */ | |
495 | void SkGeYellowLED( | |
496 | SK_AC *pAC, /* adapter context */ | |
497 | SK_IOC IoC, /* IO context */ | |
498 | int State) /* yellow LED state, 0 = OFF, 0 != ON */ | |
499 | { | |
500 | if (State == 0) { | |
501 | /* Switch yellow LED OFF */ | |
502 | SK_OUT8(IoC, B0_LED, LED_STAT_OFF); | |
503 | } | |
504 | else { | |
505 | /* Switch yellow LED ON */ | |
506 | SK_OUT8(IoC, B0_LED, LED_STAT_ON); | |
507 | } | |
508 | } /* SkGeYellowLED */ | |
509 | ||
510 | ||
511 | /****************************************************************************** | |
512 | * | |
513 | * SkGeXmitLED() - Modify the Operational Mode of a transmission LED. | |
514 | * | |
515 | * Description: | |
516 | * The Rx or Tx LED which is specified by 'Led' will be | |
517 | * enabled, disabled or switched on in test mode. | |
518 | * | |
519 | * Note: | |
520 | * 'Led' must contain the address offset of the LEDs INI register. | |
521 | * | |
522 | * Usage: | |
523 | * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); | |
524 | * | |
525 | * Returns: | |
526 | * nothing | |
527 | */ | |
528 | void SkGeXmitLED( | |
529 | SK_AC *pAC, /* adapter context */ | |
530 | SK_IOC IoC, /* IO context */ | |
531 | int Led, /* offset to the LED Init Value register */ | |
532 | int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */ | |
533 | { | |
534 | SK_U32 LedIni; | |
535 | ||
536 | switch (Mode) { | |
537 | case SK_LED_ENA: | |
538 | LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; | |
539 | SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni); | |
540 | SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); | |
541 | break; | |
542 | case SK_LED_TST: | |
543 | SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON); | |
544 | SK_OUT32(IoC, Led + XMIT_LED_CNT, 100); | |
545 | SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); | |
546 | break; | |
547 | case SK_LED_DIS: | |
548 | default: | |
549 | /* | |
550 | * Do NOT stop the LED Timer here. The LED might be | |
551 | * in on state. But it needs to go off. | |
552 | */ | |
553 | SK_OUT32(IoC, Led + XMIT_LED_CNT, 0); | |
554 | SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF); | |
555 | break; | |
556 | } | |
42d1f039 | 557 | |
7152b1d0 WD |
558 | /* |
559 | * 1000BT: The Transmit LED is driven by the PHY. | |
560 | * But the default LED configuration is used for | |
561 | * Level One and Broadcom PHYs. | |
562 | * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.) | |
563 | * (In this case it has to be added here. But we will see. XXX) | |
564 | */ | |
565 | } /* SkGeXmitLED */ | |
566 | ||
567 | ||
568 | /****************************************************************************** | |
569 | * | |
570 | * DoCalcAddr() - Calculates the start and the end address of a queue. | |
571 | * | |
572 | * Description: | |
573 | * This function calculates the start and the end address of a queue. | |
574 | * Afterwards the 'StartVal' is incremented to the next start position. | |
575 | * If the port is already initialized the calculated values | |
576 | * will be checked against the configured values and an | |
577 | * error will be returned, if they are not equal. | |
578 | * If the port is not initialized the values will be written to | |
579 | * *StartAdr and *EndAddr. | |
580 | * | |
581 | * Returns: | |
582 | * 0: success | |
583 | * 1: configuration error | |
584 | */ | |
585 | static int DoCalcAddr( | |
53677ef1 | 586 | SK_AC *pAC, /* adapter context */ |
7152b1d0 WD |
587 | SK_GEPORT *pPrt, /* port index */ |
588 | int QuSize, /* size of the queue to configure in kB */ | |
589 | SK_U32 *StartVal, /* start value for address calculation */ | |
590 | SK_U32 *QuStartAddr, /* start addr to calculate */ | |
591 | SK_U32 *QuEndAddr) /* end address to calculate */ | |
592 | { | |
593 | SK_U32 EndVal; | |
594 | SK_U32 NextStart; | |
595 | int Rtv; | |
596 | ||
597 | Rtv = 0; | |
598 | if (QuSize == 0) { | |
599 | EndVal = *StartVal; | |
600 | NextStart = EndVal; | |
601 | } | |
602 | else { | |
603 | EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1; | |
604 | NextStart = EndVal + 1; | |
605 | } | |
606 | ||
607 | if (pPrt->PState >= SK_PRT_INIT) { | |
608 | if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) { | |
609 | Rtv = 1; | |
610 | } | |
611 | } | |
612 | else { | |
613 | *QuStartAddr = *StartVal; | |
614 | *QuEndAddr = EndVal; | |
615 | } | |
616 | ||
617 | *StartVal = NextStart; | |
618 | return(Rtv); | |
619 | } /* DoCalcAddr */ | |
620 | ||
621 | /****************************************************************************** | |
622 | * | |
623 | * SkGeInitAssignRamToQueues() - allocate default queue sizes | |
624 | * | |
625 | * Description: | |
626 | * This function assigns the memory to the different queues and ports. | |
627 | * When DualNet is set to SK_TRUE all ports get the same amount of memory. | |
628 | * Otherwise the first port gets most of the memory and all the | |
629 | * other ports just the required minimum. | |
630 | * This function can only be called when pAC->GIni.GIRamSize and | |
631 | * pAC->GIni.GIMacsFound have been initialized, usually this happens | |
632 | * at init level 1 | |
633 | * | |
634 | * Returns: | |
635 | * 0 - ok | |
636 | * 1 - invalid input values | |
637 | * 2 - not enough memory | |
638 | */ | |
639 | ||
640 | int SkGeInitAssignRamToQueues( | |
641 | SK_AC *pAC, /* Adapter context */ | |
642 | int ActivePort, /* Active Port in RLMT mode */ | |
643 | SK_BOOL DualNet) /* adapter context */ | |
644 | { | |
645 | int i; | |
646 | int UsedKilobytes; /* memory already assigned */ | |
647 | int ActivePortKilobytes; /* memory available for active port */ | |
648 | SK_GEPORT *pGePort; | |
649 | ||
650 | UsedKilobytes = 0; | |
651 | ||
652 | if (ActivePort >= pAC->GIni.GIMacsFound) { | |
653 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | |
654 | ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", | |
655 | ActivePort)); | |
656 | return(1); | |
657 | } | |
658 | if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + | |
659 | ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { | |
660 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | |
661 | ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", | |
662 | pAC->GIni.GIRamSize)); | |
663 | return(2); | |
664 | } | |
665 | ||
666 | ||
667 | if (DualNet) { | |
668 | /* every port gets the same amount of memory */ | |
669 | ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; | |
670 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
671 | ||
672 | pGePort = &pAC->GIni.GP[i]; | |
42d1f039 | 673 | |
7152b1d0 WD |
674 | /* take away the minimum memory for active queues */ |
675 | ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); | |
676 | ||
677 | /* receive queue gets the minimum + 80% of the rest */ | |
678 | pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( | |
679 | ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) | |
680 | + SK_MIN_RXQ_SIZE; | |
681 | ||
682 | ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); | |
683 | ||
684 | /* synchronous transmit queue */ | |
685 | pGePort->PXSQSize = 0; | |
686 | ||
687 | /* asynchronous transmit queue */ | |
688 | pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + | |
689 | SK_MIN_TXQ_SIZE); | |
690 | } | |
691 | } | |
42d1f039 | 692 | else { |
7152b1d0 WD |
693 | /* Rlmt Mode or single link adapter */ |
694 | ||
695 | /* Set standby queue size defaults for all standby ports */ | |
696 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
697 | ||
698 | if (i != ActivePort) { | |
699 | pGePort = &pAC->GIni.GP[i]; | |
700 | ||
701 | pGePort->PRxQSize = SK_MIN_RXQ_SIZE; | |
702 | pGePort->PXAQSize = SK_MIN_TXQ_SIZE; | |
703 | pGePort->PXSQSize = 0; | |
704 | ||
705 | /* Count used RAM */ | |
706 | UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; | |
707 | } | |
708 | } | |
709 | /* what's left? */ | |
710 | ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; | |
711 | ||
712 | /* assign it to the active port */ | |
713 | /* first take away the minimum memory */ | |
714 | ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); | |
715 | pGePort = &pAC->GIni.GP[ActivePort]; | |
716 | ||
717 | /* receive queue get's the minimum + 80% of the rest */ | |
718 | pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * | |
719 | (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; | |
720 | ||
721 | ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); | |
722 | ||
723 | /* synchronous transmit queue */ | |
724 | pGePort->PXSQSize = 0; | |
725 | ||
726 | /* asynchronous transmit queue */ | |
727 | pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + | |
728 | SK_MIN_TXQ_SIZE; | |
729 | } | |
730 | #ifdef VCPU | |
731 | VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", | |
732 | pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); | |
733 | #endif /* VCPU */ | |
734 | ||
735 | return(0); | |
736 | } /* SkGeInitAssignRamToQueues */ | |
737 | ||
738 | /****************************************************************************** | |
739 | * | |
740 | * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration | |
741 | * | |
742 | * Description: | |
743 | * This function verifies the Queue Size Configuration specified | |
744 | * in the variables PRxQSize, PXSQSize, and PXAQSize of all | |
745 | * used ports. | |
746 | * This requirements must be fullfilled to have a valid configuration: | |
747 | * - The size of all queues must not exceed GIRamSize. | |
748 | * - The queue sizes must be specified in units of 8 kB. | |
749 | * - The size of Rx queues of available ports must not be | |
750 | * smaller than 16 kB. | |
751 | * - The size of at least one Tx queue (synch. or asynch.) | |
752 | * of available ports must not be smaller than 16 kB | |
753 | * when Jumbo Frames are used. | |
754 | * - The RAM start and end addresses must not be changed | |
755 | * for ports which are already initialized. | |
756 | * Furthermore SkGeCheckQSize() defines the Start and End Addresses | |
757 | * of all ports and stores them into the HWAC port structure. | |
758 | * | |
759 | * Returns: | |
760 | * 0: Queue Size Configuration valid | |
761 | * 1: Queue Size Configuration invalid | |
762 | */ | |
763 | static int SkGeCheckQSize( | |
764 | SK_AC *pAC, /* adapter context */ | |
765 | int Port) /* port index */ | |
766 | { | |
767 | SK_GEPORT *pPrt; | |
768 | int UsedMem; /* total memory used (max. found ports) */ | |
769 | int i; | |
770 | int Rtv; | |
771 | int Rtv2; | |
772 | SK_U32 StartAddr; | |
773 | ||
774 | UsedMem = 0; | |
775 | Rtv = 0; | |
776 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
777 | pPrt = &pAC->GIni.GP[i]; | |
778 | ||
779 | if ((pPrt->PRxQSize & QZ_UNITS) != 0 || | |
780 | (pPrt->PXSQSize & QZ_UNITS) != 0 || | |
781 | (pPrt->PXAQSize & QZ_UNITS) != 0) { | |
782 | ||
783 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); | |
784 | return(1); | |
785 | } | |
786 | ||
787 | if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { | |
788 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); | |
789 | return(1); | |
790 | } | |
42d1f039 | 791 | |
7152b1d0 WD |
792 | /* |
793 | * the size of at least one Tx queue (synch. or asynch.) has to be > 0. | |
794 | * if Jumbo Frames are used, this size has to be >= 16 kB. | |
795 | */ | |
796 | if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || | |
797 | (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && | |
42d1f039 | 798 | ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || |
7152b1d0 WD |
799 | (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { |
800 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); | |
801 | return(1); | |
802 | } | |
42d1f039 | 803 | |
7152b1d0 WD |
804 | UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; |
805 | } | |
42d1f039 | 806 | |
7152b1d0 WD |
807 | if (UsedMem > pAC->GIni.GIRamSize) { |
808 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); | |
809 | return(1); | |
810 | } | |
811 | ||
812 | /* Now start address calculation */ | |
813 | StartAddr = pAC->GIni.GIRamOffs; | |
814 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
815 | pPrt = &pAC->GIni.GP[i]; | |
816 | ||
817 | /* Calculate/Check values for the receive queue */ | |
818 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, | |
819 | &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); | |
820 | Rtv |= Rtv2; | |
821 | ||
822 | /* Calculate/Check values for the synchronous Tx queue */ | |
823 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr, | |
824 | &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd); | |
825 | Rtv |= Rtv2; | |
826 | ||
827 | /* Calculate/Check values for the asynchronous Tx queue */ | |
828 | Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr, | |
829 | &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd); | |
830 | Rtv |= Rtv2; | |
831 | ||
832 | if (Rtv) { | |
833 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG); | |
834 | return(1); | |
835 | } | |
836 | } | |
837 | ||
838 | return(0); | |
839 | } /* SkGeCheckQSize */ | |
840 | ||
841 | ||
842 | /****************************************************************************** | |
843 | * | |
844 | * SkGeInitMacArb() - Initialize the MAC Arbiter | |
845 | * | |
846 | * Description: | |
847 | * This function initializes the MAC Arbiter. | |
848 | * It must not be called if there is still an | |
849 | * initialized or active port. | |
850 | * | |
851 | * Returns: | |
852 | * nothing | |
853 | */ | |
854 | static void SkGeInitMacArb( | |
855 | SK_AC *pAC, /* adapter context */ | |
856 | SK_IOC IoC) /* IO context */ | |
857 | { | |
858 | /* release local reset */ | |
859 | SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); | |
860 | ||
861 | /* configure timeout values */ | |
862 | SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53); | |
863 | SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53); | |
864 | SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53); | |
865 | SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53); | |
866 | ||
867 | SK_OUT8(IoC, B3_MA_RCINI_RX1, 0); | |
868 | SK_OUT8(IoC, B3_MA_RCINI_RX2, 0); | |
869 | SK_OUT8(IoC, B3_MA_RCINI_TX1, 0); | |
870 | SK_OUT8(IoC, B3_MA_RCINI_TX2, 0); | |
871 | ||
872 | /* recovery values are needed for XMAC II Rev. B2 only */ | |
873 | /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ | |
874 | ||
875 | /* | |
876 | * There is no start or enable button to push, therefore | |
877 | * the MAC arbiter is configured and enabled now. | |
878 | */ | |
879 | } /* SkGeInitMacArb */ | |
880 | ||
881 | ||
882 | /****************************************************************************** | |
883 | * | |
884 | * SkGeInitPktArb() - Initialize the Packet Arbiter | |
885 | * | |
886 | * Description: | |
887 | * This function initializes the Packet Arbiter. | |
888 | * It must not be called if there is still an | |
889 | * initialized or active port. | |
890 | * | |
891 | * Returns: | |
892 | * nothing | |
893 | */ | |
894 | static void SkGeInitPktArb( | |
895 | SK_AC *pAC, /* adapter context */ | |
896 | SK_IOC IoC) /* IO context */ | |
897 | { | |
898 | /* release local reset */ | |
899 | SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); | |
900 | ||
901 | /* configure timeout values */ | |
902 | SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX); | |
903 | SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX); | |
904 | SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX); | |
905 | SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX); | |
906 | ||
907 | /* | |
908 | * enable timeout timers if jumbo frames not used | |
909 | * NOTE: the packet arbiter timeout interrupt is needed for | |
910 | * half duplex hangup workaround | |
911 | */ | |
912 | if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { | |
913 | if (pAC->GIni.GIMacsFound == 1) { | |
914 | SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); | |
915 | } | |
916 | else { | |
917 | SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2); | |
918 | } | |
919 | } | |
920 | } /* SkGeInitPktArb */ | |
921 | ||
922 | ||
923 | /****************************************************************************** | |
924 | * | |
925 | * SkGeInitMacFifo() - Initialize the MAC FIFOs | |
926 | * | |
927 | * Description: | |
928 | * Initialize all MAC FIFOs of the specified port | |
929 | * | |
930 | * Returns: | |
931 | * nothing | |
932 | */ | |
933 | static void SkGeInitMacFifo( | |
934 | SK_AC *pAC, /* adapter context */ | |
935 | SK_IOC IoC, /* IO context */ | |
936 | int Port) /* Port Index (MAC_1 + n) */ | |
937 | { | |
938 | SK_U16 Word; | |
939 | #ifdef VCPU | |
940 | SK_U32 DWord; | |
941 | #endif /* VCPU */ | |
942 | /* | |
943 | * For each FIFO: | |
944 | * - release local reset | |
945 | * - use default value for MAC FIFO size | |
946 | * - setup defaults for the control register | |
947 | * - enable the FIFO | |
948 | */ | |
42d1f039 | 949 | |
7152b1d0 | 950 | Word = GMF_RX_CTRL_DEF; |
42d1f039 | 951 | |
7152b1d0 WD |
952 | if (pAC->GIni.GIGenesis) { |
953 | /* Configure Rx MAC FIFO */ | |
954 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); | |
955 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); | |
956 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); | |
42d1f039 | 957 | |
7152b1d0 WD |
958 | /* Configure Tx MAC FIFO */ |
959 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); | |
960 | SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); | |
961 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); | |
42d1f039 | 962 | |
7152b1d0 WD |
963 | /* Enable frame flushing if jumbo frames used */ |
964 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { | |
965 | SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); | |
966 | } | |
967 | } | |
968 | else { | |
969 | /* set Rx GMAC FIFO Flush Mask */ | |
970 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); | |
42d1f039 | 971 | |
7152b1d0 WD |
972 | if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { |
973 | ||
974 | Word &= ~GMF_RX_F_FL_ON; | |
975 | } | |
42d1f039 | 976 | |
7152b1d0 WD |
977 | /* Configure Rx MAC FIFO */ |
978 | SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); | |
979 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); | |
42d1f039 | 980 | |
7152b1d0 WD |
981 | /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ |
982 | SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); | |
42d1f039 | 983 | |
7152b1d0 WD |
984 | /* Configure Tx MAC FIFO */ |
985 | SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); | |
986 | SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); | |
42d1f039 | 987 | |
7152b1d0 WD |
988 | #ifdef VCPU |
989 | SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); | |
990 | SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); | |
991 | #endif /* VCPU */ | |
42d1f039 | 992 | |
7152b1d0 WD |
993 | /* set Tx GMAC FIFO Almost Empty Threshold */ |
994 | /* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ | |
995 | } | |
996 | } /* SkGeInitMacFifo */ | |
997 | ||
998 | ||
999 | /****************************************************************************** | |
1000 | * | |
1001 | * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting | |
1002 | * | |
1003 | * Description: | |
1004 | * This function starts the Link Sync Counter of the specified | |
1005 | * port and enables the generation of an Link Sync IRQ. | |
1006 | * The Link Sync Counter may be used to detect an active link, | |
1007 | * if autonegotiation is not used. | |
1008 | * | |
1009 | * Note: | |
1010 | * o To ensure receiving the Link Sync Event the LinkSyncCounter | |
1011 | * should be initialized BEFORE clearing the XMAC's reset! | |
1012 | * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this | |
1013 | * function. | |
1014 | * | |
1015 | * Returns: | |
1016 | * nothing | |
1017 | */ | |
1018 | void SkGeLoadLnkSyncCnt( | |
1019 | SK_AC *pAC, /* adapter context */ | |
1020 | SK_IOC IoC, /* IO context */ | |
1021 | int Port, /* Port Index (MAC_1 + n) */ | |
1022 | SK_U32 CntVal) /* Counter value */ | |
1023 | { | |
1024 | SK_U32 OrgIMsk; | |
1025 | SK_U32 NewIMsk; | |
1026 | SK_U32 ISrc; | |
1027 | SK_BOOL IrqPend; | |
1028 | ||
1029 | /* stop counter */ | |
1030 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); | |
1031 | ||
1032 | /* | |
1033 | * ASIC problem: | |
1034 | * Each time starting the Link Sync Counter an IRQ is generated | |
1035 | * by the adapter. See problem report entry from 21.07.98 | |
1036 | * | |
1037 | * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ | |
1038 | * if no IRQ is already pending. | |
1039 | */ | |
1040 | IrqPend = SK_FALSE; | |
1041 | SK_IN32(IoC, B0_ISRC, &ISrc); | |
1042 | SK_IN32(IoC, B0_IMSK, &OrgIMsk); | |
1043 | if (Port == MAC_1) { | |
1044 | NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; | |
1045 | if ((ISrc & IS_LNK_SYNC_M1) != 0) { | |
1046 | IrqPend = SK_TRUE; | |
1047 | } | |
1048 | } | |
1049 | else { | |
1050 | NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; | |
1051 | if ((ISrc & IS_LNK_SYNC_M2) != 0) { | |
1052 | IrqPend = SK_TRUE; | |
1053 | } | |
1054 | } | |
1055 | if (!IrqPend) { | |
1056 | SK_OUT32(IoC, B0_IMSK, NewIMsk); | |
1057 | } | |
1058 | ||
1059 | /* load counter */ | |
1060 | SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); | |
1061 | ||
1062 | /* start counter */ | |
1063 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); | |
1064 | ||
1065 | if (!IrqPend) { | |
1066 | /* clear the unexpected IRQ, and restore the interrupt mask */ | |
1067 | SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); | |
1068 | SK_OUT32(IoC, B0_IMSK, OrgIMsk); | |
1069 | } | |
1070 | } /* SkGeLoadLnkSyncCnt*/ | |
1071 | ||
1072 | ||
1073 | /****************************************************************************** | |
1074 | * | |
1075 | * SkGeCfgSync() - Configure synchronous bandwidth for this port. | |
1076 | * | |
1077 | * Description: | |
1078 | * This function may be used to configure synchronous bandwidth | |
1079 | * to the specified port. This may be done any time after | |
1080 | * initializing the port. The configuration values are NOT saved | |
1081 | * in the HWAC port structure and will be overwritten any | |
1082 | * time when stopping and starting the port. | |
1083 | * Any values for the synchronous configuration will be ignored | |
1084 | * if the size of the synchronous queue is zero! | |
1085 | * | |
1086 | * The default configuration for the synchronous service is | |
1087 | * TXA_ENA_FSYNC. This means if the size of | |
1088 | * the synchronous queue is unequal zero but no specific | |
1089 | * synchronous bandwidth is configured, the synchronous queue | |
1090 | * will always have the 'unlimited' transmit priority! | |
1091 | * | |
1092 | * This mode will be restored if the synchronous bandwidth is | |
1093 | * deallocated ('IntTime' = 0 and 'LimCount' = 0). | |
1094 | * | |
1095 | * Returns: | |
1096 | * 0: success | |
1097 | * 1: parameter configuration error | |
1098 | * 2: try to configure quality of service although no | |
1099 | * synchronous queue is configured | |
1100 | */ | |
1101 | int SkGeCfgSync( | |
1102 | SK_AC *pAC, /* adapter context */ | |
1103 | SK_IOC IoC, /* IO context */ | |
1104 | int Port, /* Port Index (MAC_1 + n) */ | |
1105 | SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ | |
1106 | SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ | |
1107 | int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */ | |
1108 | { | |
1109 | int Rtv; | |
1110 | ||
1111 | Rtv = 0; | |
1112 | ||
1113 | /* check the parameters */ | |
1114 | if (LimCount > IntTime || | |
1115 | (LimCount == 0 && IntTime != 0) || | |
1116 | (LimCount != 0 && IntTime == 0)) { | |
1117 | ||
1118 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); | |
1119 | return(1); | |
1120 | } | |
42d1f039 | 1121 | |
7152b1d0 WD |
1122 | if (pAC->GIni.GP[Port].PXSQSize == 0) { |
1123 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); | |
1124 | return(2); | |
1125 | } | |
42d1f039 | 1126 | |
7152b1d0 WD |
1127 | /* calculate register values */ |
1128 | IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; | |
1129 | LimCount = LimCount / 8; | |
42d1f039 | 1130 | |
7152b1d0 WD |
1131 | if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { |
1132 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); | |
1133 | return(1); | |
1134 | } | |
1135 | ||
1136 | /* | |
1137 | * - Enable 'Force Sync' to ensure the synchronous queue | |
1138 | * has the priority while configuring the new values. | |
1139 | * - Also 'disable alloc' to ensure the settings complies | |
1140 | * to the SyncMode parameter. | |
1141 | * - Disable 'Rate Control' to configure the new values. | |
1142 | * - write IntTime and LimCount | |
1143 | * - start 'Rate Control' and disable 'Force Sync' | |
1144 | * if Interval Timer or Limit Counter not zero. | |
1145 | */ | |
1146 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), | |
1147 | TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); | |
42d1f039 | 1148 | |
7152b1d0 WD |
1149 | SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); |
1150 | SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); | |
42d1f039 | 1151 | |
7152b1d0 WD |
1152 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), |
1153 | (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); | |
42d1f039 | 1154 | |
7152b1d0 WD |
1155 | if (IntTime != 0 || LimCount != 0) { |
1156 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); | |
1157 | } | |
1158 | ||
1159 | return(0); | |
1160 | } /* SkGeCfgSync */ | |
1161 | ||
1162 | ||
1163 | /****************************************************************************** | |
1164 | * | |
1165 | * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue | |
1166 | * | |
1167 | * Desccription: | |
1168 | * If the queue is used, enable and initialize it. | |
1169 | * Make sure the queue is still reset, if it is not used. | |
1170 | * | |
1171 | * Returns: | |
1172 | * nothing | |
1173 | */ | |
1174 | static void DoInitRamQueue( | |
1175 | SK_AC *pAC, /* adapter context */ | |
1176 | SK_IOC IoC, /* IO context */ | |
1177 | int QuIoOffs, /* Queue IO Address Offset */ | |
1178 | SK_U32 QuStartAddr, /* Queue Start Address */ | |
1179 | SK_U32 QuEndAddr, /* Queue End Address */ | |
1180 | int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */ | |
1181 | { | |
1182 | SK_U32 RxUpThresVal; | |
1183 | SK_U32 RxLoThresVal; | |
1184 | ||
1185 | if (QuStartAddr != QuEndAddr) { | |
1186 | /* calculate thresholds, assume we have a big Rx queue */ | |
1187 | RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8; | |
1188 | RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8; | |
1189 | ||
1190 | /* build HW address format */ | |
1191 | QuStartAddr = QuStartAddr / 8; | |
1192 | QuEndAddr = QuEndAddr / 8; | |
1193 | ||
1194 | /* release local reset */ | |
1195 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR); | |
1196 | ||
1197 | /* configure addresses */ | |
1198 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr); | |
1199 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr); | |
1200 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr); | |
1201 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr); | |
1202 | ||
1203 | switch (QuType) { | |
1204 | case SK_RX_SRAM_Q: | |
1205 | /* configure threshold for small Rx Queue */ | |
1206 | RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8; | |
1207 | ||
1208 | /* continue with SK_RX_BRAM_Q */ | |
1209 | case SK_RX_BRAM_Q: | |
1210 | /* write threshold for Rx Queue */ | |
1211 | ||
1212 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); | |
1213 | SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); | |
1214 | ||
1215 | /* the high priority threshold not used */ | |
1216 | break; | |
1217 | case SK_TX_RAM_Q: | |
1218 | /* | |
1219 | * Do NOT use Store & Forward under normal operation due to | |
1220 | * performance optimization (GENESIS only). | |
1221 | * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB) | |
1222 | * or YUKON is used ((GMAC Tx FIFO is only 1 kB) | |
1223 | * we NEED Store & Forward of the RAM buffer. | |
1224 | */ | |
1225 | if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || | |
1226 | !pAC->GIni.GIGenesis) { | |
1227 | /* enable Store & Forward Mode for the Tx Side */ | |
1228 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); | |
1229 | } | |
1230 | break; | |
1231 | } | |
1232 | ||
1233 | /* set queue operational */ | |
1234 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD); | |
1235 | } | |
1236 | else { | |
1237 | /* ensure the queue is still disabled */ | |
1238 | SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET); | |
1239 | } | |
1240 | } /* DoInitRamQueue */ | |
1241 | ||
1242 | ||
1243 | /****************************************************************************** | |
1244 | * | |
1245 | * SkGeInitRamBufs() - Initialize the RAM Buffer Queues | |
1246 | * | |
1247 | * Description: | |
1248 | * Initialize all RAM Buffer Queues of the specified port | |
1249 | * | |
1250 | * Returns: | |
1251 | * nothing | |
1252 | */ | |
1253 | static void SkGeInitRamBufs( | |
1254 | SK_AC *pAC, /* adapter context */ | |
1255 | SK_IOC IoC, /* IO context */ | |
1256 | int Port) /* Port Index (MAC_1 + n) */ | |
1257 | { | |
1258 | SK_GEPORT *pPrt; | |
1259 | int RxQType; | |
1260 | ||
1261 | pPrt = &pAC->GIni.GP[Port]; | |
1262 | ||
1263 | if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { | |
53677ef1 WD |
1264 | RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ |
1265 | } else { | |
7152b1d0 WD |
1266 | RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ |
1267 | } | |
1268 | ||
1269 | DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, | |
1270 | pPrt->PRxQRamEnd, RxQType); | |
42d1f039 | 1271 | |
7152b1d0 WD |
1272 | DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, |
1273 | pPrt->PXsQRamEnd, SK_TX_RAM_Q); | |
42d1f039 | 1274 | |
7152b1d0 WD |
1275 | DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, |
1276 | pPrt->PXaQRamEnd, SK_TX_RAM_Q); | |
1277 | ||
1278 | } /* SkGeInitRamBufs */ | |
1279 | ||
1280 | ||
1281 | /****************************************************************************** | |
1282 | * | |
1283 | * SkGeInitRamIface() - Initialize the RAM Interface | |
1284 | * | |
1285 | * Description: | |
1286 | * This function initializes the Adapters RAM Interface. | |
1287 | * | |
1288 | * Note: | |
1289 | * This function is used in the diagnostics. | |
1290 | * | |
1291 | * Returns: | |
1292 | * nothing | |
1293 | */ | |
1294 | void SkGeInitRamIface( | |
1295 | SK_AC *pAC, /* adapter context */ | |
1296 | SK_IOC IoC) /* IO context */ | |
1297 | { | |
1298 | /* release local reset */ | |
1299 | SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR); | |
1300 | ||
1301 | /* configure timeout values */ | |
1302 | SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53); | |
1303 | SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53); | |
1304 | SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53); | |
1305 | SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53); | |
1306 | SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53); | |
1307 | SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53); | |
1308 | SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53); | |
1309 | SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53); | |
1310 | SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53); | |
1311 | SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); | |
1312 | SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); | |
1313 | SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); | |
1314 | ||
1315 | } /* SkGeInitRamIface */ | |
1316 | ||
1317 | ||
1318 | /****************************************************************************** | |
1319 | * | |
1320 | * SkGeInitBmu() - Initialize the BMU state machines | |
1321 | * | |
1322 | * Description: | |
1323 | * Initialize all BMU state machines of the specified port | |
1324 | * | |
1325 | * Returns: | |
1326 | * nothing | |
1327 | */ | |
1328 | static void SkGeInitBmu( | |
1329 | SK_AC *pAC, /* adapter context */ | |
1330 | SK_IOC IoC, /* IO context */ | |
1331 | int Port) /* Port Index (MAC_1 + n) */ | |
1332 | { | |
1333 | SK_GEPORT *pPrt; | |
1334 | SK_U32 RxWm; | |
1335 | SK_U32 TxWm; | |
1336 | ||
1337 | pPrt = &pAC->GIni.GP[Port]; | |
1338 | ||
1339 | RxWm = SK_BMU_RX_WM; | |
1340 | TxWm = SK_BMU_TX_WM; | |
42d1f039 | 1341 | |
7152b1d0 WD |
1342 | if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { |
1343 | /* for better performance */ | |
1344 | RxWm /= 2; | |
1345 | TxWm /= 2; | |
1346 | } | |
1347 | ||
1348 | /* Rx Queue: Release all local resets and set the watermark */ | |
1349 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); | |
1350 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); | |
1351 | ||
1352 | /* | |
1353 | * Tx Queue: Release all local resets if the queue is used ! | |
53677ef1 | 1354 | * set watermark |
7152b1d0 WD |
1355 | */ |
1356 | if (pPrt->PXSQSize != 0) { | |
1357 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); | |
1358 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); | |
1359 | } | |
42d1f039 | 1360 | |
7152b1d0 WD |
1361 | if (pPrt->PXAQSize != 0) { |
1362 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); | |
1363 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); | |
1364 | } | |
1365 | /* | |
1366 | * Do NOT enable the descriptor poll timers here, because | |
1367 | * the descriptor addresses are not specified yet. | |
1368 | */ | |
1369 | } /* SkGeInitBmu */ | |
1370 | ||
1371 | ||
1372 | /****************************************************************************** | |
1373 | * | |
1374 | * TestStopBit() - Test the stop bit of the queue | |
1375 | * | |
1376 | * Description: | |
1377 | * Stopping a queue is not as simple as it seems to be. | |
1378 | * If descriptor polling is enabled, it may happen | |
1379 | * that RX/TX stop is done and SV idle is NOT set. | |
1380 | * In this case we have to issue another stop command. | |
1381 | * | |
1382 | * Returns: | |
1383 | * The queues control status register | |
1384 | */ | |
1385 | static SK_U32 TestStopBit( | |
1386 | SK_AC *pAC, /* Adapter Context */ | |
1387 | SK_IOC IoC, /* IO Context */ | |
1388 | int QuIoOffs) /* Queue IO Address Offset */ | |
1389 | { | |
1390 | SK_U32 QuCsr; /* CSR contents */ | |
1391 | ||
1392 | SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); | |
42d1f039 | 1393 | |
7152b1d0 WD |
1394 | if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { |
1395 | /* Stop Descriptor overridden by start command */ | |
1396 | SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); | |
1397 | ||
1398 | SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); | |
1399 | } | |
42d1f039 | 1400 | |
7152b1d0 WD |
1401 | return(QuCsr); |
1402 | } /* TestStopBit */ | |
1403 | ||
1404 | ||
1405 | /****************************************************************************** | |
1406 | * | |
1407 | * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'. | |
1408 | * | |
1409 | * Description: | |
1410 | * After calling this function the descriptor rings and Rx and Tx | |
1411 | * queues of this port may be reconfigured. | |
1412 | * | |
1413 | * It is possible to stop the receive and transmit path separate or | |
1414 | * both together. | |
1415 | * | |
53677ef1 | 1416 | * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC. |
7152b1d0 WD |
1417 | * The receive queue is still active and |
1418 | * the pending Rx frames may be still transferred | |
1419 | * into the RxD. | |
1420 | * SK_STOP_RX Stop the receive path. The tansmit path | |
1421 | * has to be stopped once before. | |
1422 | * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX | |
1423 | * | |
1424 | * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. | |
1425 | * SK_HARD_RST Resets the MAC and the PHY. | |
1426 | * | |
1427 | * Example: | |
1428 | * 1) A Link Down event was signaled for a port. Therefore the activity | |
1429 | * of this port should be stopped and a hardware reset should be issued | |
1430 | * to enable the workaround of XMAC errata #2. But the received frames | |
1431 | * should not be discarded. | |
1432 | * ... | |
1433 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); | |
1434 | * (transfer all pending Rx frames) | |
1435 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); | |
1436 | * ... | |
1437 | * | |
1438 | * 2) An event was issued which request the driver to switch | |
1439 | * the 'virtual active' link to an other already active port | |
1440 | * as soon as possible. The frames in the receive queue of this | |
1441 | * port may be lost. But the PHY must not be reset during this | |
1442 | * event. | |
1443 | * ... | |
1444 | * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST); | |
1445 | * ... | |
1446 | * | |
1447 | * Extended Description: | |
1448 | * If SK_STOP_TX is set, | |
1449 | * o disable the MAC's receive and transmitter to prevent | |
1450 | * from sending incomplete frames | |
1451 | * o stop the port's transmit queues before terminating the | |
1452 | * BMUs to prevent from performing incomplete PCI cycles | |
1453 | * on the PCI bus | |
1454 | * - The network Rx and Tx activity and PCI Tx transfer is | |
1455 | * disabled now. | |
1456 | * o reset the MAC depending on the RstMode | |
1457 | * o Stop Interval Timer and Limit Counter of Tx Arbiter, | |
1458 | * also disable Force Sync bit and Enable Alloc bit. | |
1459 | * o perform a local reset of the port's Tx path | |
1460 | * - reset the PCI FIFO of the async Tx queue | |
1461 | * - reset the PCI FIFO of the sync Tx queue | |
1462 | * - reset the RAM Buffer async Tx queue | |
1463 | * - reset the RAM Buffer sync Tx queue | |
1464 | * - reset the MAC Tx FIFO | |
1465 | * o switch Link and Tx LED off, stop the LED counters | |
1466 | * | |
1467 | * If SK_STOP_RX is set, | |
1468 | * o stop the port's receive queue | |
1469 | * - The path data transfer activity is fully stopped now. | |
1470 | * o perform a local reset of the port's Rx path | |
1471 | * - reset the PCI FIFO of the Rx queue | |
1472 | * - reset the RAM Buffer receive queue | |
1473 | * - reset the MAC Rx FIFO | |
1474 | * o switch Rx LED off, stop the LED counter | |
1475 | * | |
1476 | * If all ports are stopped, | |
1477 | * o reset the RAM Interface. | |
1478 | * | |
1479 | * Notes: | |
1480 | * o This function may be called during the driver states RESET_PORT and | |
1481 | * SWITCH_PORT. | |
1482 | */ | |
1483 | void SkGeStopPort( | |
1484 | SK_AC *pAC, /* adapter context */ | |
1485 | SK_IOC IoC, /* I/O context */ | |
1486 | int Port, /* port to stop (MAC_1 + n) */ | |
1487 | int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ | |
1488 | int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ | |
1489 | { | |
1490 | #ifndef SK_DIAG | |
1491 | SK_EVPARA Para; | |
1492 | #endif /* !SK_DIAG */ | |
1493 | SK_GEPORT *pPrt; | |
1494 | SK_U32 DWord; | |
1495 | SK_U32 XsCsr; | |
1496 | SK_U32 XaCsr; | |
1497 | SK_U64 ToutStart; | |
1498 | int i; | |
1499 | int ToutCnt; | |
1500 | ||
1501 | pPrt = &pAC->GIni.GP[Port]; | |
1502 | ||
1503 | if ((Dir & SK_STOP_TX) != 0) { | |
1504 | /* disable receiver and transmitter */ | |
1505 | SkMacRxTxDisable(pAC, IoC, Port); | |
42d1f039 | 1506 | |
7152b1d0 WD |
1507 | /* stop both transmit queues */ |
1508 | /* | |
1509 | * If the BMU is in the reset state CSR_STOP will terminate | |
1510 | * immediately. | |
1511 | */ | |
1512 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP); | |
1513 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP); | |
1514 | ||
1515 | ToutStart = SkOsGetTime(pAC); | |
1516 | ToutCnt = 0; | |
1517 | do { | |
1518 | /* | |
1519 | * Clear packet arbiter timeout to make sure | |
1520 | * this loop will terminate. | |
1521 | */ | |
1522 | SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_TX1 : | |
1523 | PA_CLR_TO_TX2); | |
1524 | ||
1525 | /* | |
1526 | * If the transfer stucks at the MAC the STOP command will not | |
1527 | * terminate if we don't flush the XMAC's transmit FIFO ! | |
1528 | */ | |
1529 | SkMacFlushTxFifo(pAC, IoC, Port); | |
1530 | ||
1531 | XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); | |
1532 | XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); | |
1533 | ||
1534 | if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) { | |
1535 | /* | |
1536 | * Timeout of 1/18 second reached. | |
1537 | * This needs to be checked at 1/18 sec only. | |
1538 | */ | |
1539 | ToutCnt++; | |
1540 | if (ToutCnt > 1) { | |
1541 | /* Might be a problem when the driver event handler | |
1542 | * calls StopPort again. XXX. | |
1543 | */ | |
1544 | ||
1545 | /* Fatal Error, Loop aborted */ | |
1546 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, | |
1547 | SKERR_HWI_E018MSG); | |
1548 | #ifndef SK_DIAG | |
1549 | Para.Para64 = Port; | |
1550 | SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); | |
1551 | #endif /* !SK_DIAG */ | |
1552 | return; | |
1553 | } | |
1554 | /* | |
1555 | * Cache incoherency workaround: Assume a start command | |
1556 | * has been lost while sending the frame. | |
1557 | */ | |
1558 | ToutStart = SkOsGetTime(pAC); | |
1559 | ||
1560 | if ((XsCsr & CSR_STOP) != 0) { | |
1561 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); | |
1562 | } | |
1563 | if ((XaCsr & CSR_STOP) != 0) { | |
1564 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); | |
1565 | } | |
1566 | } | |
1567 | ||
1568 | /* | |
1569 | * Because of the ASIC problem report entry from 21.08.1998 it is | |
1570 | * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. | |
1571 | */ | |
1572 | } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || | |
1573 | (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); | |
1574 | ||
1575 | /* Reset the MAC depending on the RstMode */ | |
1576 | if (RstMode == SK_SOFT_RST) { | |
1577 | SkMacSoftRst(pAC, IoC, Port); | |
1578 | } | |
1579 | else { | |
1580 | SkMacHardRst(pAC, IoC, Port); | |
1581 | } | |
42d1f039 | 1582 | |
7152b1d0 WD |
1583 | /* Disable Force Sync bit and Enable Alloc bit */ |
1584 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), | |
1585 | TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); | |
42d1f039 | 1586 | |
7152b1d0 WD |
1587 | /* Stop Interval Timer and Limit Counter of Tx Arbiter */ |
1588 | SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); | |
1589 | SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); | |
1590 | ||
1591 | /* Perform a local reset of the port's Tx path */ | |
1592 | ||
1593 | /* Reset the PCI FIFO of the async Tx queue */ | |
1594 | SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); | |
1595 | /* Reset the PCI FIFO of the sync Tx queue */ | |
1596 | SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); | |
1597 | /* Reset the RAM Buffer async Tx queue */ | |
1598 | SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); | |
1599 | /* Reset the RAM Buffer sync Tx queue */ | |
1600 | SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); | |
42d1f039 | 1601 | |
7152b1d0 WD |
1602 | /* Reset Tx MAC FIFO */ |
1603 | if (pAC->GIni.GIGenesis) { | |
1604 | /* Note: MFF_RST_SET does NOT reset the XMAC ! */ | |
1605 | SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); | |
1606 | ||
1607 | /* switch Link and Tx LED off, stop the LED counters */ | |
1608 | /* Link LED is switched off by the RLMT and the Diag itself */ | |
1609 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); | |
1610 | } | |
1611 | else { | |
1612 | /* Reset TX MAC FIFO */ | |
1613 | SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); | |
1614 | } | |
1615 | } | |
1616 | ||
1617 | if ((Dir & SK_STOP_RX) != 0) { | |
1618 | /* | |
1619 | * The RX Stop Command will not terminate if no buffers | |
1620 | * are queued in the RxD ring. But it will always reach | |
1621 | * the Idle state. Therefore we can use this feature to | |
1622 | * stop the transfer of received packets. | |
1623 | */ | |
1624 | /* stop the port's receive queue */ | |
1625 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); | |
42d1f039 | 1626 | |
7152b1d0 WD |
1627 | i = 100; |
1628 | do { | |
1629 | /* | |
1630 | * Clear packet arbiter timeout to make sure | |
1631 | * this loop will terminate | |
1632 | */ | |
1633 | SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_RX1 : | |
1634 | PA_CLR_TO_RX2); | |
42d1f039 | 1635 | |
7152b1d0 WD |
1636 | DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); |
1637 | ||
1638 | /* timeout if i==0 (bug fix for #10748) */ | |
1639 | if (--i == 0) { | |
1640 | SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, | |
1641 | SKERR_HWI_E024MSG); | |
1642 | break; | |
1643 | } | |
1644 | /* | |
1645 | * because of the ASIC problem report entry from 21.08.98 | |
1646 | * it is required to wait until CSR_STOP is reset and | |
1647 | * CSR_SV_IDLE is set. | |
1648 | */ | |
1649 | } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); | |
1650 | ||
1651 | /* The path data transfer activity is fully stopped now */ | |
1652 | ||
1653 | /* Perform a local reset of the port's Rx path */ | |
1654 | ||
1655 | /* Reset the PCI FIFO of the Rx queue */ | |
1656 | SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); | |
1657 | /* Reset the RAM Buffer receive queue */ | |
1658 | SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); | |
1659 | ||
1660 | /* Reset Rx MAC FIFO */ | |
1661 | if (pAC->GIni.GIGenesis) { | |
42d1f039 | 1662 | |
7152b1d0 WD |
1663 | SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); |
1664 | ||
1665 | /* switch Rx LED off, stop the LED counter */ | |
1666 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); | |
1667 | } | |
1668 | else { | |
1669 | /* Reset Rx MAC FIFO */ | |
1670 | SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); | |
1671 | } | |
1672 | } | |
1673 | } /* SkGeStopPort */ | |
1674 | ||
1675 | ||
1676 | /****************************************************************************** | |
1677 | * | |
1678 | * SkGeInit0() - Level 0 Initialization | |
1679 | * | |
1680 | * Description: | |
1681 | * - Initialize the BMU address offsets | |
1682 | * | |
1683 | * Returns: | |
1684 | * nothing | |
1685 | */ | |
1686 | static void SkGeInit0( | |
1687 | SK_AC *pAC, /* adapter context */ | |
1688 | SK_IOC IoC) /* IO context */ | |
1689 | { | |
1690 | int i; | |
1691 | SK_GEPORT *pPrt; | |
1692 | ||
1693 | for (i = 0; i < SK_MAX_MACS; i++) { | |
1694 | pPrt = &pAC->GIni.GP[i]; | |
1695 | ||
1696 | pPrt->PState = SK_PRT_RESET; | |
1697 | pPrt->PRxQOff = QOffTab[i].RxQOff; | |
1698 | pPrt->PXsQOff = QOffTab[i].XsQOff; | |
1699 | pPrt->PXaQOff = QOffTab[i].XaQOff; | |
1700 | pPrt->PCheckPar = SK_FALSE; | |
1701 | pPrt->PIsave = 0; | |
1702 | pPrt->PPrevShorts = 0; | |
1703 | pPrt->PLinkResCt = 0; | |
1704 | pPrt->PAutoNegTOCt = 0; | |
1705 | pPrt->PPrevRx = 0; | |
1706 | pPrt->PPrevFcs = 0; | |
1707 | pPrt->PRxLim = SK_DEF_RX_WA_LIM; | |
1708 | pPrt->PLinkMode = SK_LMODE_AUTOFULL; | |
1709 | pPrt->PLinkSpeedCap = SK_LSPEED_CAP_1000MBPS; | |
1710 | pPrt->PLinkSpeed = SK_LSPEED_1000MBPS; | |
1711 | pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_UNKNOWN; | |
1712 | pPrt->PLinkModeConf = SK_LMODE_AUTOSENSE; | |
1713 | pPrt->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; | |
1714 | pPrt->PLinkBroken = SK_TRUE; /* See WA code */ | |
1715 | pPrt->PLinkCap = (SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL | | |
1716 | SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL); | |
1717 | pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; | |
1718 | pPrt->PFlowCtrlCap = SK_FLOW_MODE_SYM_OR_REM; | |
1719 | pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; | |
1720 | pPrt->PMSCap = 0; | |
1721 | pPrt->PMSMode = SK_MS_MODE_AUTO; | |
1722 | pPrt->PMSStatus = SK_MS_STAT_UNSET; | |
1723 | pPrt->PAutoNegFail = SK_FALSE; | |
1724 | pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; | |
1725 | pPrt->PHWLinkUp = SK_FALSE; | |
1726 | } | |
1727 | ||
1728 | pAC->GIni.GIPortUsage = SK_RED_LINK; | |
1729 | ||
1730 | } /* SkGeInit0*/ | |
1731 | ||
1732 | #ifdef SK_PCI_RESET | |
1733 | ||
1734 | /****************************************************************************** | |
1735 | * | |
1736 | * SkGePciReset() - Reset PCI interface | |
1737 | * | |
1738 | * Description: | |
1739 | * o Read PCI configuration. | |
1740 | * o Change power state to 3. | |
1741 | * o Change power state to 0. | |
1742 | * o Restore PCI configuration. | |
1743 | * | |
1744 | * Returns: | |
1745 | * 0: Success. | |
1746 | * 1: Power state could not be changed to 3. | |
1747 | */ | |
1748 | static int SkGePciReset( | |
1749 | SK_AC *pAC, /* adapter context */ | |
1750 | SK_IOC IoC) /* IO context */ | |
1751 | { | |
1752 | int i; | |
1753 | SK_U16 PmCtlSts; | |
1754 | SK_U32 Bp1; | |
1755 | SK_U32 Bp2; | |
1756 | SK_U16 PciCmd; | |
1757 | SK_U8 Cls; | |
1758 | SK_U8 Lat; | |
1759 | SK_U8 ConfigSpace[PCI_CFG_SIZE]; | |
1760 | ||
1761 | /* | |
1762 | * Note: Switching to D3 state is like a software reset. | |
1763 | * Switching from D3 to D0 is a hardware reset. | |
1764 | * We have to save and restore the configuration space. | |
1765 | */ | |
1766 | for (i = 0; i < PCI_CFG_SIZE; i++) { | |
1767 | SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]); | |
1768 | } | |
1769 | ||
1770 | /* We know the RAM Interface Arbiter is enabled. */ | |
1771 | SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); | |
1772 | SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); | |
42d1f039 | 1773 | |
7152b1d0 WD |
1774 | if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { |
1775 | return(1); | |
1776 | } | |
1777 | ||
1778 | /* Return to D0 state. */ | |
1779 | SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); | |
1780 | ||
1781 | /* Check for D0 state. */ | |
1782 | SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); | |
42d1f039 | 1783 | |
7152b1d0 WD |
1784 | if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { |
1785 | return(1); | |
1786 | } | |
1787 | ||
1788 | /* Check PCI Config Registers. */ | |
1789 | SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); | |
1790 | SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); | |
1791 | SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); | |
1792 | SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); | |
1793 | SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); | |
42d1f039 | 1794 | |
7152b1d0 WD |
1795 | if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 || |
1796 | Lat != 0) { | |
1797 | return(1); | |
1798 | } | |
1799 | ||
1800 | /* Restore PCI Config Space. */ | |
1801 | for (i = 0; i < PCI_CFG_SIZE; i++) { | |
1802 | SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); | |
1803 | } | |
1804 | ||
1805 | return(0); | |
1806 | } /* SkGePciReset */ | |
1807 | ||
1808 | #endif /* SK_PCI_RESET */ | |
1809 | ||
1810 | /****************************************************************************** | |
1811 | * | |
1812 | * SkGeInit1() - Level 1 Initialization | |
1813 | * | |
1814 | * Description: | |
1815 | * o Do a software reset. | |
1816 | * o Clear all reset bits. | |
1817 | * o Verify that the detected hardware is present. | |
1818 | * Return an error if not. | |
1819 | * o Get the hardware configuration | |
1820 | * + Read the number of MACs/Ports. | |
1821 | * + Read the RAM size. | |
1822 | * + Read the PCI Revision Id. | |
1823 | * + Find out the adapters host clock speed | |
1824 | * + Read and check the PHY type | |
1825 | * | |
1826 | * Returns: | |
1827 | * 0: success | |
1828 | * 5: Unexpected PHY type detected | |
1829 | * 6: HW self test failed | |
1830 | */ | |
1831 | static int SkGeInit1( | |
1832 | SK_AC *pAC, /* adapter context */ | |
1833 | SK_IOC IoC) /* IO context */ | |
1834 | { | |
1835 | SK_U8 Byte; | |
1836 | SK_U16 Word; | |
1837 | SK_U16 CtrlStat; | |
1838 | SK_U32 FlashAddr; | |
1839 | int RetVal; | |
1840 | int i; | |
1841 | ||
1842 | RetVal = 0; | |
1843 | ||
1844 | /* save CLK_RUN bits (YUKON-Lite) */ | |
1845 | SK_IN16(IoC, B0_CTST, &CtrlStat); | |
1846 | ||
1847 | #ifdef SK_PCI_RESET | |
1848 | (void)SkGePciReset(pAC, IoC); | |
1849 | #endif /* SK_PCI_RESET */ | |
1850 | ||
1851 | /* do the SW-reset */ | |
1852 | SK_OUT8(IoC, B0_CTST, CS_RST_SET); | |
1853 | ||
1854 | /* release the SW-reset */ | |
1855 | SK_OUT8(IoC, B0_CTST, CS_RST_CLR); | |
1856 | ||
1857 | /* reset all error bits in the PCI STATUS register */ | |
1858 | /* | |
1859 | * Note: PCI Cfg cycles cannot be used, because they are not | |
1860 | * available on some platforms after 'boot time'. | |
1861 | */ | |
1862 | SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); | |
42d1f039 | 1863 | |
7152b1d0 WD |
1864 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
1865 | SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); | |
1866 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | |
1867 | ||
1868 | /* release Master Reset */ | |
1869 | SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); | |
1870 | ||
1871 | #ifdef CLK_RUN | |
1872 | CtrlStat |= CS_CLK_RUN_ENA; | |
1873 | #endif /* CLK_RUN */ | |
1874 | ||
1875 | /* restore CLK_RUN bits */ | |
1876 | SK_OUT16(IoC, B0_CTST, CtrlStat & | |
1877 | (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)); | |
42d1f039 | 1878 | |
7152b1d0 WD |
1879 | /* read Chip Identification Number */ |
1880 | SK_IN8(IoC, B2_CHIP_ID, &Byte); | |
1881 | pAC->GIni.GIChipId = Byte; | |
42d1f039 | 1882 | |
7152b1d0 WD |
1883 | /* read number of MACs */ |
1884 | SK_IN8(IoC, B2_MAC_CFG, &Byte); | |
6d0f6bcf | 1885 | pAC->GIni.GIMacsFound = (Byte & CONFIG_SYS_SNG_MAC) ? 1 : 2; |
42d1f039 | 1886 | |
7152b1d0 | 1887 | /* get Chip Revision Number */ |
6d0f6bcf | 1888 | pAC->GIni.GIChipRev = (SK_U8)((Byte & CONFIG_SYS_CHIP_R_MSK) >> 4); |
7152b1d0 WD |
1889 | |
1890 | /* get diff. PCI parameters */ | |
1891 | SK_IN16(IoC, B0_CTST, &CtrlStat); | |
42d1f039 | 1892 | |
7152b1d0 WD |
1893 | /* read the adapters RAM size */ |
1894 | SK_IN8(IoC, B2_E_0, &Byte); | |
42d1f039 | 1895 | |
7152b1d0 WD |
1896 | if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { |
1897 | ||
1898 | pAC->GIni.GIGenesis = SK_TRUE; | |
1899 | ||
42d1f039 | 1900 | if (Byte == 3) { |
7152b1d0 WD |
1901 | /* special case: 4 x 64k x 36, offset = 0x80000 */ |
1902 | pAC->GIni.GIRamSize = 1024; | |
1903 | pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; | |
1904 | } | |
1905 | else { | |
1906 | pAC->GIni.GIRamSize = (int)Byte * 512; | |
1907 | pAC->GIni.GIRamOffs = 0; | |
1908 | } | |
1909 | /* all GE adapters work with 53.125 MHz host clock */ | |
1910 | pAC->GIni.GIHstClkFact = SK_FACT_53; | |
42d1f039 | 1911 | |
7152b1d0 WD |
1912 | /* set Descr. Poll Timer Init Value to 250 ms */ |
1913 | pAC->GIni.GIPollTimerVal = | |
1914 | SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; | |
1915 | } | |
1916 | else { | |
1917 | pAC->GIni.GIGenesis = SK_FALSE; | |
1918 | ||
1919 | #ifndef VCPU | |
1920 | pAC->GIni.GIRamSize = (Byte == 0) ? 128 : (int)Byte * 4; | |
1921 | #else | |
1922 | pAC->GIni.GIRamSize = 128; | |
42d1f039 | 1923 | #endif |
7152b1d0 | 1924 | pAC->GIni.GIRamOffs = 0; |
42d1f039 | 1925 | |
7152b1d0 WD |
1926 | /* WA for chip Rev. A */ |
1927 | pAC->GIni.GIWolOffs = (pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; | |
42d1f039 | 1928 | |
7152b1d0 WD |
1929 | /* get PM Capabilities of PCI config space */ |
1930 | SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); | |
1931 | ||
1932 | /* check if VAUX is available */ | |
1933 | if (((CtrlStat & CS_VAUX_AVAIL) != 0) && | |
1934 | /* check also if PME from D3cold is set */ | |
1935 | ((Word & PCI_PME_D3C_SUP) != 0)) { | |
1936 | /* set entry in GE init struct */ | |
1937 | pAC->GIni.GIVauxAvail = SK_TRUE; | |
1938 | } | |
42d1f039 | 1939 | |
7152b1d0 WD |
1940 | /* save Flash-Address Register */ |
1941 | SK_IN32(IoC, B2_FAR, &FlashAddr); | |
1942 | ||
1943 | /* test Flash-Address Register */ | |
1944 | SK_OUT8(IoC, B2_FAR + 3, 0xff); | |
1945 | SK_IN8(IoC, B2_FAR + 3, &Byte); | |
42d1f039 | 1946 | |
7152b1d0 | 1947 | pAC->GIni.GIYukonLite = (SK_BOOL)(Byte != 0); |
42d1f039 | 1948 | |
7152b1d0 WD |
1949 | /* restore Flash-Address Register */ |
1950 | SK_OUT32(IoC, B2_FAR, FlashAddr); | |
1951 | ||
1952 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
1953 | /* set GMAC Link Control reset */ | |
1954 | SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); | |
1955 | ||
1956 | /* clear GMAC Link Control reset */ | |
1957 | SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | |
1958 | } | |
1959 | /* all YU chips work with 78.125 MHz host clock */ | |
1960 | pAC->GIni.GIHstClkFact = SK_FACT_78; | |
42d1f039 | 1961 | |
7152b1d0 WD |
1962 | pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ |
1963 | } | |
1964 | ||
1965 | /* check if 64-bit PCI Slot is present */ | |
1966 | pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); | |
42d1f039 | 1967 | |
7152b1d0 WD |
1968 | /* check if 66 MHz PCI Clock is active */ |
1969 | pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); | |
1970 | ||
1971 | /* read PCI HW Revision Id. */ | |
1972 | SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); | |
1973 | pAC->GIni.GIPciHwRev = Byte; | |
1974 | ||
1975 | /* read the PMD type */ | |
1976 | SK_IN8(IoC, B2_PMD_TYP, &Byte); | |
1977 | pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); | |
1978 | ||
1979 | /* read the PHY type */ | |
1980 | SK_IN8(IoC, B2_E_1, &Byte); | |
1981 | ||
1982 | Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ | |
1983 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
42d1f039 | 1984 | |
7152b1d0 WD |
1985 | if (pAC->GIni.GIGenesis) { |
1986 | switch (Byte) { | |
1987 | case SK_PHY_XMAC: | |
1988 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; | |
1989 | break; | |
1990 | case SK_PHY_BCOM: | |
1991 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; | |
1992 | pAC->GIni.GP[i].PMSCap = | |
1993 | SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; | |
1994 | break; | |
1995 | #ifdef OTHER_PHY | |
1996 | case SK_PHY_LONE: | |
1997 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; | |
1998 | break; | |
1999 | case SK_PHY_NAT: | |
2000 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; | |
2001 | break; | |
2002 | #endif /* OTHER_PHY */ | |
2003 | default: | |
2004 | /* ERROR: unexpected PHY type detected */ | |
2005 | RetVal = 5; | |
2006 | break; | |
2007 | } | |
2008 | } | |
2009 | else { | |
2010 | if (Byte == 0) { | |
2011 | /* if this field is not initialized */ | |
2012 | Byte = SK_PHY_MARV_COPPER; | |
2013 | pAC->GIni.GICopperType = SK_TRUE; | |
2014 | } | |
2015 | pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; | |
42d1f039 | 2016 | |
7152b1d0 WD |
2017 | if (pAC->GIni.GICopperType) { |
2018 | pAC->GIni.GP[i].PLinkSpeedCap = SK_LSPEED_CAP_AUTO | | |
2019 | SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | | |
2020 | SK_LSPEED_CAP_1000MBPS; | |
2021 | pAC->GIni.GP[i].PLinkSpeed = SK_LSPEED_AUTO; | |
2022 | pAC->GIni.GP[i].PMSCap = | |
2023 | SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE; | |
2024 | } | |
2025 | else { | |
2026 | Byte = SK_PHY_MARV_FIBER; | |
2027 | } | |
2028 | } | |
42d1f039 | 2029 | |
7152b1d0 | 2030 | pAC->GIni.GP[i].PhyType = Byte; |
42d1f039 | 2031 | |
7152b1d0 WD |
2032 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, |
2033 | ("PHY type: %d PHY addr: %04x\n", Byte, | |
2034 | pAC->GIni.GP[i].PhyAddr)); | |
2035 | } | |
42d1f039 | 2036 | |
7152b1d0 WD |
2037 | /* get Mac Type & set function pointers dependent on */ |
2038 | if (pAC->GIni.GIGenesis) { | |
2039 | pAC->GIni.GIMacType = SK_MAC_XMAC; | |
2040 | ||
2041 | pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; | |
2042 | pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; | |
2043 | pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; | |
2044 | pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; | |
2045 | } | |
2046 | else { | |
2047 | pAC->GIni.GIMacType = SK_MAC_GMAC; | |
2048 | ||
2049 | pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; | |
2050 | pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; | |
2051 | pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; | |
2052 | pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; | |
42d1f039 | 2053 | |
7152b1d0 WD |
2054 | #ifdef SPECIAL_HANDLING |
2055 | if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { | |
2056 | /* check HW self test result */ | |
2057 | SK_IN8(IoC, B2_E_3, &Byte); | |
2058 | if ((Byte & B2_E3_RES_MASK) != 0) { | |
2059 | RetVal = 6; | |
2060 | } | |
2061 | } | |
2062 | #endif | |
2063 | } | |
2064 | return(RetVal); | |
2065 | } /* SkGeInit1 */ | |
2066 | ||
2067 | ||
2068 | /****************************************************************************** | |
2069 | * | |
2070 | * SkGeInit2() - Level 2 Initialization | |
2071 | * | |
2072 | * Description: | |
2073 | * - start the Blink Source Counter | |
2074 | * - start the Descriptor Poll Timer | |
2075 | * - configure the MAC-Arbiter | |
2076 | * - configure the Packet-Arbiter | |
2077 | * - enable the Tx Arbiters | |
2078 | * - enable the RAM Interface Arbiter | |
2079 | * | |
2080 | * Returns: | |
2081 | * nothing | |
2082 | */ | |
2083 | static void SkGeInit2( | |
2084 | SK_AC *pAC, /* adapter context */ | |
2085 | SK_IOC IoC) /* IO context */ | |
2086 | { | |
2087 | SK_U32 DWord; | |
2088 | int i; | |
2089 | ||
2090 | /* start the Descriptor Poll Timer */ | |
2091 | if (pAC->GIni.GIPollTimerVal != 0) { | |
2092 | if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) { | |
2093 | pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; | |
2094 | ||
2095 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); | |
2096 | } | |
2097 | SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); | |
2098 | SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); | |
2099 | } | |
2100 | ||
2101 | if (pAC->GIni.GIGenesis) { | |
2102 | /* start the Blink Source Counter */ | |
2103 | DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; | |
2104 | ||
2105 | SK_OUT32(IoC, B2_BSC_INI, DWord); | |
2106 | SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); | |
2107 | ||
2108 | /* | |
2109 | * Configure the MAC Arbiter and the Packet Arbiter. | |
2110 | * They will be started once and never be stopped. | |
2111 | */ | |
2112 | SkGeInitMacArb(pAC, IoC); | |
2113 | ||
2114 | SkGeInitPktArb(pAC, IoC); | |
2115 | } | |
2116 | else { | |
2117 | /* start Time Stamp Timer */ | |
2118 | SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); | |
2119 | } | |
2120 | ||
2121 | /* enable the Tx Arbiters */ | |
2122 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
2123 | SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB); | |
2124 | } | |
2125 | ||
2126 | /* enable the RAM Interface Arbiter */ | |
2127 | SkGeInitRamIface(pAC, IoC); | |
2128 | ||
2129 | } /* SkGeInit2 */ | |
2130 | ||
2131 | /****************************************************************************** | |
2132 | * | |
2133 | * SkGeInit() - Initialize the GE Adapter with the specified level. | |
2134 | * | |
2135 | * Description: | |
2136 | * Level 0: Initialize the Module structures. | |
2137 | * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has | |
2138 | * to be set before calling this level. | |
2139 | * | |
2140 | * o Do a software reset. | |
2141 | * o Clear all reset bits. | |
2142 | * o Verify that the detected hardware is present. | |
2143 | * Return an error if not. | |
2144 | * o Get the hardware configuration | |
2145 | * + Set GIMacsFound with the number of MACs. | |
2146 | * + Store the RAM size in GIRamSize. | |
2147 | * + Save the PCI Revision ID in GIPciHwRev. | |
2148 | * o return an error | |
2149 | * if Number of MACs > SK_MAX_MACS | |
2150 | * | |
2151 | * After returning from Level 0 the adapter | |
2152 | * may be accessed with IO operations. | |
2153 | * | |
2154 | * Level 2: start the Blink Source Counter | |
2155 | * | |
2156 | * Returns: | |
2157 | * 0: success | |
2158 | * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) | |
2159 | * 2: Adapter not present or not accessible | |
2160 | * 3: Illegal initialization level | |
2161 | * 4: Initialization Level 1 Call missing | |
2162 | * 5: Unexpected PHY type detected | |
2163 | * 6: HW self test failed | |
2164 | */ | |
2165 | int SkGeInit( | |
2166 | SK_AC *pAC, /* adapter context */ | |
2167 | SK_IOC IoC, /* IO context */ | |
2168 | int Level) /* initialization level */ | |
2169 | { | |
2170 | int RetVal; /* return value */ | |
2171 | SK_U32 DWord; | |
2172 | ||
2173 | RetVal = 0; | |
2174 | SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, | |
2175 | ("SkGeInit(Level %d)\n", Level)); | |
2176 | ||
2177 | switch (Level) { | |
2178 | case SK_INIT_DATA: | |
2179 | /* Initialization Level 0 */ | |
2180 | SkGeInit0(pAC, IoC); | |
2181 | pAC->GIni.GILevel = SK_INIT_DATA; | |
2182 | break; | |
42d1f039 | 2183 | |
7152b1d0 WD |
2184 | case SK_INIT_IO: |
2185 | /* Initialization Level 1 */ | |
2186 | RetVal = SkGeInit1(pAC, IoC); | |
2187 | if (RetVal != 0) { | |
2188 | break; | |
2189 | } | |
2190 | ||
2191 | /* check if the adapter seems to be accessible */ | |
2192 | SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L); | |
2193 | SK_IN32(IoC, B2_IRQM_INI, &DWord); | |
2194 | SK_OUT32(IoC, B2_IRQM_INI, 0L); | |
42d1f039 | 2195 | |
7152b1d0 WD |
2196 | if (DWord != 0x11335577L) { |
2197 | RetVal = 2; | |
2198 | break; | |
2199 | } | |
2200 | ||
2201 | /* check if the number of GIMacsFound matches SK_MAX_MACS */ | |
2202 | if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { | |
2203 | RetVal = 1; | |
2204 | break; | |
2205 | } | |
2206 | ||
2207 | /* Level 1 successfully passed */ | |
2208 | pAC->GIni.GILevel = SK_INIT_IO; | |
2209 | break; | |
42d1f039 | 2210 | |
7152b1d0 WD |
2211 | case SK_INIT_RUN: |
2212 | /* Initialization Level 2 */ | |
2213 | if (pAC->GIni.GILevel != SK_INIT_IO) { | |
2214 | #ifndef SK_DIAG | |
2215 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG); | |
2216 | #endif /* !SK_DIAG */ | |
2217 | RetVal = 4; | |
2218 | break; | |
2219 | } | |
2220 | SkGeInit2(pAC, IoC); | |
2221 | ||
2222 | /* Level 2 successfully passed */ | |
2223 | pAC->GIni.GILevel = SK_INIT_RUN; | |
2224 | break; | |
42d1f039 | 2225 | |
7152b1d0 WD |
2226 | default: |
2227 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); | |
2228 | RetVal = 3; | |
2229 | break; | |
2230 | } | |
2231 | ||
2232 | return(RetVal); | |
2233 | } /* SkGeInit */ | |
2234 | ||
2235 | ||
2236 | /****************************************************************************** | |
2237 | * | |
2238 | * SkGeDeInit() - Deinitialize the adapter | |
2239 | * | |
2240 | * Description: | |
2241 | * All ports of the adapter will be stopped if not already done. | |
2242 | * Do a software reset and switch off all LEDs. | |
2243 | * | |
2244 | * Returns: | |
2245 | * nothing | |
2246 | */ | |
2247 | void SkGeDeInit( | |
2248 | SK_AC *pAC, /* adapter context */ | |
2249 | SK_IOC IoC) /* IO context */ | |
2250 | { | |
2251 | int i; | |
2252 | SK_U16 Word; | |
2253 | ||
2254 | #ifndef VCPU | |
2255 | /* ensure I2C is ready */ | |
2256 | SkI2cWaitIrq(pAC, IoC); | |
2257 | #endif | |
2258 | ||
2259 | /* stop all current transfer activity */ | |
2260 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | |
2261 | if (pAC->GIni.GP[i].PState != SK_PRT_STOP && | |
2262 | pAC->GIni.GP[i].PState != SK_PRT_RESET) { | |
2263 | ||
2264 | SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); | |
2265 | } | |
2266 | } | |
2267 | ||
2268 | /* Reset all bits in the PCI STATUS register */ | |
2269 | /* | |
2270 | * Note: PCI Cfg cycles cannot be used, because they are not | |
2271 | * available on some platforms after 'boot time'. | |
2272 | */ | |
2273 | SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); | |
42d1f039 | 2274 | |
7152b1d0 WD |
2275 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2276 | SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS); | |
2277 | SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | |
2278 | ||
2279 | /* do the reset, all LEDs are switched off now */ | |
2280 | SK_OUT8(IoC, B0_CTST, CS_RST_SET); | |
2281 | } /* SkGeDeInit */ | |
2282 | ||
2283 | ||
2284 | /****************************************************************************** | |
2285 | * | |
2286 | * SkGeInitPort() Initialize the specified port. | |
2287 | * | |
2288 | * Description: | |
2289 | * PRxQSize, PXSQSize, and PXAQSize has to be | |
2290 | * configured for the specified port before calling this function. | |
2291 | * The descriptor rings has to be initialized too. | |
2292 | * | |
2293 | * o (Re)configure queues of the specified port. | |
2294 | * o configure the MAC of the specified port. | |
2295 | * o put ASIC and MAC(s) in operational mode. | |
2296 | * o initialize Rx/Tx and Sync LED | |
2297 | * o initialize RAM Buffers and MAC FIFOs | |
2298 | * | |
2299 | * The port is ready to connect when returning. | |
2300 | * | |
2301 | * Note: | |
2302 | * The MAC's Rx and Tx state machine is still disabled when returning. | |
2303 | * | |
2304 | * Returns: | |
2305 | * 0: success | |
2306 | * 1: Queue size initialization error. The configured values | |
2307 | * for PRxQSize, PXSQSize, or PXAQSize are invalid for one | |
2308 | * or more queues. The specified port was NOT initialized. | |
2309 | * An error log entry was generated. | |
2310 | * 2: The port has to be stopped before it can be initialized again. | |
2311 | */ | |
2312 | int SkGeInitPort( | |
2313 | SK_AC *pAC, /* adapter context */ | |
2314 | SK_IOC IoC, /* IO context */ | |
2315 | int Port) /* Port to configure */ | |
2316 | { | |
2317 | SK_GEPORT *pPrt; | |
2318 | ||
2319 | pPrt = &pAC->GIni.GP[Port]; | |
2320 | ||
2321 | if (SkGeCheckQSize(pAC, Port) != 0) { | |
2322 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); | |
2323 | return(1); | |
2324 | } | |
42d1f039 | 2325 | |
7152b1d0 WD |
2326 | if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { |
2327 | SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); | |
2328 | return(2); | |
2329 | } | |
2330 | ||
2331 | /* configuration ok, initialize the Port now */ | |
2332 | ||
2333 | if (pAC->GIni.GIGenesis) { | |
2334 | /* initialize Rx, Tx and Link LED */ | |
2335 | /* | |
2336 | * If 1000BT Phy needs LED initialization than swap | |
2337 | * LED and XMAC initialization order | |
2338 | */ | |
2339 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); | |
2340 | SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); | |
2341 | /* The Link LED is initialized by RLMT or Diagnostics itself */ | |
42d1f039 | 2342 | |
7152b1d0 WD |
2343 | SkXmInitMac(pAC, IoC, Port); |
2344 | } | |
2345 | else { | |
2346 | ||
2347 | SkGmInitMac(pAC, IoC, Port); | |
2348 | } | |
42d1f039 | 2349 | |
7152b1d0 WD |
2350 | /* do NOT initialize the Link Sync Counter */ |
2351 | ||
2352 | SkGeInitMacFifo(pAC, IoC, Port); | |
42d1f039 | 2353 | |
7152b1d0 | 2354 | SkGeInitRamBufs(pAC, IoC, Port); |
42d1f039 | 2355 | |
7152b1d0 WD |
2356 | if (pPrt->PXSQSize != 0) { |
2357 | /* enable Force Sync bit if synchronous queue available */ | |
2358 | SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); | |
2359 | } | |
42d1f039 | 2360 | |
7152b1d0 WD |
2361 | SkGeInitBmu(pAC, IoC, Port); |
2362 | ||
2363 | /* mark port as initialized */ | |
2364 | pPrt->PState = SK_PRT_INIT; | |
2365 | ||
2366 | return(0); | |
2367 | } /* SkGeInitPort */ |