skgesirq.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417
  1. /******************************************************************************
  2. *
  3. * Name: skgesirq.c
  4. * Project: GEnesis, PCI Gigabit Ethernet Adapter
  5. * Version: $Revision: 1.83 $
  6. * Date: $Date: 2003/02/05 15:10:59 $
  7. * Purpose: Special IRQ module
  8. *
  9. ******************************************************************************/
  10. /******************************************************************************
  11. *
  12. * (C)Copyright 1998-2003 SysKonnect GmbH.
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * The information in this file is provided "AS IS" without warranty.
  20. *
  21. ******************************************************************************/
  22. /******************************************************************************
  23. *
  24. * History:
  25. *
  26. * $Log: skgesirq.c,v $
  27. * Revision 1.83 2003/02/05 15:10:59 rschmidt
  28. * Fixed setting of PLinkSpeedUsed in SkHWLinkUp() when
  29. * auto-negotiation is disabled.
  30. * Editorial changes.
  31. *
  32. * Revision 1.82 2003/01/29 13:34:33 rschmidt
  33. * Added some typecasts to avoid compiler warnings.
  34. *
  35. * Revision 1.81 2002/12/05 10:49:51 rschmidt
  36. * Fixed missing Link Down Event for fiber (Bug Id #10768)
  37. * Added reading of cable length when link is up
  38. * Removed testing of unused error bits in PHY ISR
  39. * Editorial changes.
  40. *
  41. * Revision 1.80 2002/11/12 17:15:21 rschmidt
  42. * Replaced SkPnmiGetVar() by ...MacStatistic() in SkMacParity().
  43. * Editorial changes.
  44. *
  45. * Revision 1.79 2002/10/14 15:14:51 rschmidt
  46. * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
  47. * SkMacParity() depending on GIChipRev (HW-Bug #8).
  48. * Added error messages for GPHY Auto-Negotiation Error and
  49. * FIFO Overflow/Underrun in SkPhyIsrGmac().
  50. * Editorial changes.
  51. *
  52. * Revision 1.78 2002/10/10 15:54:29 mkarl
  53. * changes for PLinkSpeedUsed
  54. *
  55. * Revision 1.77 2002/09/12 08:58:51 rwahl
  56. * Retrieve counters needed for XMAC errata workarounds directly because
  57. * PNMI returns corrected counter values (e.g. #10620).
  58. *
  59. * Revision 1.76 2002/08/16 15:21:54 rschmidt
  60. * Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
  61. * Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros.
  62. * Editorial changes.
  63. *
  64. * Revision 1.75 2002/08/12 13:50:47 rschmidt
  65. * Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
  66. * SkMacParity() by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE (HW-Bug #8).
  67. * Added clearing of IS_IRQ_TIST_OV and IS_IRQ_SENSOR in SkGeHwErr().
  68. * Corrected handling of Link Up and Auto-Negotiation Over for GPHY.
  69. * in SkGePortCheckUpGmac().
  70. * Editorial changes.
  71. *
  72. * Revision 1.74 2002/08/08 16:17:04 rschmidt
  73. * Added PhyType check for SK_HWEV_SET_ROLE event (copper only)
  74. * Changed Link Up check reading PHY Specific Status (YUKON)
  75. * Editorial changes
  76. *
  77. * Revision 1.73 2002/07/15 18:36:53 rwahl
  78. * Editorial changes.
  79. *
  80. * Revision 1.72 2002/07/15 15:46:26 rschmidt
  81. * Added new event: SK_HWEV_SET_SPEED
  82. * Editorial changes
  83. *
  84. * Revision 1.71 2002/06/10 09:34:19 rschmidt
  85. * Editorial changes
  86. *
  87. * Revision 1.70 2002/06/05 08:29:18 rschmidt
  88. * SkXmRxTxEnable() replaced by SkMacRxTxEnable().
  89. * Editorial changes.
  90. *
  91. * Revision 1.69 2002/04/25 13:03:49 rschmidt
  92. * Changes for handling YUKON.
  93. * Use of #ifdef OTHER_PHY to eliminate code for unused Phy types.
  94. * Replaced all XMAC-access macros by functions: SkMacRxTxDisable(),
  95. * SkMacIrqDisable().
  96. * Added handling for GMAC FIFO in SkMacParity().
  97. * Replaced all SkXm...() functions with SkMac...() to handle also
  98. * YUKON's GMAC.
  99. * Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced
  100. * by functions SkXmPhyRead(), SkXmPhyWrite().
  101. * Disabling all PHY interrupts moved to SkMacIrqDisable().
  102. * Added handling for GPHY IRQ in SkGeSirqIsr().
  103. * Removed status parameter from MAC IRQ handler SkMacIrq().
  104. * Added SkGePortCheckUpGmac(), SkPhyIsrGmac() for GMAC.
  105. * Editorial changes
  106. *
  107. * Revision 1.68 2002/02/26 15:24:53 rwahl
  108. * Fix: no link with manual configuration (#10673). The previous fix for
  109. * #10639 was removed. So for RLMT mode = CLS the RLMT may switch to
  110. * misconfigured port. It should not occur for the other RLMT modes.
  111. *
  112. * Revision 1.67 2001/11/20 09:19:58 rwahl
  113. * Reworked bugfix #10639 (no dependency to RLMT mode).
  114. *
  115. * Revision 1.66 2001/10/26 07:52:53 afischer
  116. * Port switching bug in `check local link` mode
  117. *
  118. * Revision 1.65 2001/02/23 13:41:51 gklug
  119. * fix: PHYS2INST should be used correctly for Dual Net operation
  120. * chg: do no longer work with older PNMI
  121. *
  122. * Revision 1.64 2001/02/15 11:27:04 rassmann
  123. * Working with RLMT v1 if SK_MAX_NETS undefined.
  124. *
  125. * Revision 1.63 2001/02/06 10:44:23 mkunz
  126. * - NetIndex added to interface functions of pnmi V4 with dual net support
  127. *
  128. * Revision 1.62 2001/01/31 15:31:41 gklug
  129. * fix: problem with autosensing an SR8800 switch
  130. *
  131. * Revision 1.61 2000/11/09 11:30:09 rassmann
  132. * WA: Waiting after releasing reset until BCom chip is accessible.
  133. *
  134. * Revision 1.60 2000/10/18 12:37:48 cgoos
  135. * Reinserted the comment for version 1.56.
  136. *
  137. * Revision 1.59 2000/10/18 12:22:20 cgoos
  138. * Added workaround for half duplex hangup.
  139. *
  140. * Revision 1.58 2000/09/28 13:06:04 gklug
  141. * fix: BCom may NOT be touched if XMAC is in RESET state
  142. *
  143. * Revision 1.57 2000/09/08 12:38:39 cgoos
  144. * Added forgotten variable declaration.
  145. *
  146. * Revision 1.56 2000/09/08 08:12:13 cgoos
  147. * Changed handling of parity errors in SkGeHwErr (correct reset of error).
  148. *
  149. * Revision 1.55 2000/06/19 08:36:25 cgoos
  150. * Changed comment.
  151. *
  152. * Revision 1.54 2000/05/22 08:45:57 malthoff
  153. * Fix: #10523 is valid for all BCom PHYs.
  154. *
  155. * Revision 1.53 2000/05/19 10:20:30 cgoos
  156. * Removed Solaris debug output code.
  157. *
  158. * Revision 1.52 2000/05/19 10:19:37 cgoos
  159. * Added PHY state check in HWLinkDown.
  160. * Move PHY interrupt code to IS_EXT_REG case in SkGeSirqIsr.
  161. *
  162. * Revision 1.51 2000/05/18 05:56:20 cgoos
  163. * Fixed typo.
  164. *
  165. * Revision 1.50 2000/05/17 12:49:49 malthoff
  166. * Fixes BCom link bugs (#10523).
  167. *
  168. * Revision 1.49 1999/12/17 11:02:50 gklug
  169. * fix: read PHY_STAT of Broadcom chip more often to assure good status
  170. *
  171. * Revision 1.48 1999/12/06 10:01:17 cgoos
  172. * Added SET function for Role.
  173. *
  174. * Revision 1.47 1999/11/22 13:34:24 cgoos
  175. * Changed license header to GPL.
  176. *
  177. * Revision 1.46 1999/09/16 10:30:07 cgoos
  178. * Removed debugging output statement from Linux.
  179. *
  180. * Revision 1.45 1999/09/16 07:32:55 cgoos
  181. * Fixed dual-port copperfield bug (PHY_READ from resetted port).
  182. * Removed some unused variables.
  183. *
  184. * Revision 1.44 1999/08/03 15:25:04 cgoos
  185. * Removed workaround for disabled interrupts in half duplex mode.
  186. *
  187. * Revision 1.43 1999/08/03 14:27:58 cgoos
  188. * Removed SENSE mode code from SkGePortCheckUpBcom.
  189. *
  190. * Revision 1.42 1999/07/26 09:16:54 cgoos
  191. * Added some typecasts to avoid compiler warnings.
  192. *
  193. * Revision 1.41 1999/05/19 07:28:59 cgoos
  194. * Changes for 1000Base-T.
  195. *
  196. * Revision 1.40 1999/04/08 13:59:39 gklug
  197. * fix: problem with 3Com switches endless RESTARTs
  198. *
  199. * Revision 1.39 1999/03/08 10:10:52 gklug
  200. * fix: AutoSensing did switch to next mode even if LiPa indicated offline
  201. *
  202. * Revision 1.38 1999/03/08 09:49:03 gklug
  203. * fix: Bug using pAC instead of IoC, causing AIX problems
  204. * fix: change compare for Linux compiler bug workaround
  205. *
  206. * Revision 1.37 1999/01/28 14:51:33 gklug
  207. * fix: monitor for autosensing and extra RESETS the RX on wire counters
  208. *
  209. * Revision 1.36 1999/01/22 09:19:55 gklug
  210. * fix: Init DupMode and InitPauseMd are now called in RxTxEnable
  211. *
  212. * Revision 1.35 1998/12/11 15:22:59 gklug
  213. * chg: autosensing: check for receive if manual mode was guessed
  214. * chg: simplified workaround for XMAC errata
  215. * chg: wait additional 100 ms before link goes up.
  216. * chg: autoneg timeout to 600 ms
  217. * chg: restart autoneg even if configured to autonegotiation
  218. *
  219. * Revision 1.34 1998/12/10 10:33:14 gklug
  220. * add: more debug messages
  221. * fix: do a new InitPhy if link went down (AutoSensing problem)
  222. * chg: Check for zero shorts if link is NOT up
  223. * chg: reset Port if link goes down
  224. * chg: wait additional 100 ms when link comes up to check shorts
  225. * fix: dummy read extended autoneg status to prevent link going down immediately
  226. *
  227. * Revision 1.33 1998/12/07 12:18:29 gklug
  228. * add: refinement of autosense mode: take into account the autoneg cap of LiPa
  229. *
  230. * Revision 1.32 1998/12/07 07:11:21 gklug
  231. * fix: compiler warning
  232. *
  233. * Revision 1.31 1998/12/02 09:29:05 gklug
  234. * fix: WA XMAC Errata: FCSCt check was not correct.
  235. * fix: WA XMAC Errata: Prec Counter were NOT updated in case of short checks.
  236. * fix: Clear Stat : now clears the Prev counters of all known Ports
  237. *
  238. * Revision 1.30 1998/12/01 10:54:15 gklug
  239. * dd: workaround for XMAC errata changed. Check RX count and CRC err Count, too.
  240. *
  241. * Revision 1.29 1998/12/01 10:01:53 gklug
  242. * fix: if MAC IRQ occurs during port down, this will be handled correctly
  243. *
  244. * Revision 1.28 1998/11/26 16:22:11 gklug
  245. * fix: bug in autosense if manual modes are used
  246. *
  247. * Revision 1.27 1998/11/26 15:50:06 gklug
  248. * fix: PNMI needs to set PLinkModeConf
  249. *
  250. * Revision 1.26 1998/11/26 14:51:58 gklug
  251. * add: AutoSensing functionalty
  252. *
  253. * Revision 1.25 1998/11/26 07:34:37 gklug
  254. * fix: Init PrevShorts when restarting port due to Link connection
  255. *
  256. * Revision 1.24 1998/11/25 10:57:32 gklug
  257. * fix: remove unreferenced local vars
  258. *
  259. * Revision 1.23 1998/11/25 08:26:40 gklug
  260. * fix: don't do a RESET on a starting or stopping port
  261. *
  262. * Revision 1.22 1998/11/24 13:29:44 gklug
  263. * add: Workaround for MAC parity errata
  264. *
  265. * Revision 1.21 1998/11/18 15:31:06 gklug
  266. * fix: lint bugs
  267. *
  268. * Revision 1.20 1998/11/18 12:58:54 gklug
  269. * fix: use PNMI query instead of hardware access
  270. *
  271. * Revision 1.19 1998/11/18 12:54:55 gklug
  272. * chg: add new workaround for XMAC Errata
  273. * add: short event counter monitoring on active link too
  274. *
  275. * Revision 1.18 1998/11/13 14:27:41 malthoff
  276. * Bug Fix: Packet Arbiter Timeout was not cleared correctly
  277. * for timeout on TX1 and TX2.
  278. *
  279. * Revision 1.17 1998/11/04 07:01:59 cgoos
  280. * Moved HW link poll sequence.
  281. * Added call to SkXmRxTxEnable.
  282. *
  283. * Revision 1.16 1998/11/03 13:46:03 gklug
  284. * add: functionality of SET_LMODE and SET_FLOW_MODE
  285. * fix: send RLMT LinkDown event when Port stop is given with LinkUp
  286. *
  287. * Revision 1.15 1998/11/03 12:56:47 gklug
  288. * fix: Needs more events
  289. *
  290. * Revision 1.14 1998/10/30 07:36:35 gklug
  291. * rmv: unnecessary code
  292. *
  293. * Revision 1.13 1998/10/29 15:21:57 gklug
  294. * add: Poll link feature for activating HW link
  295. * fix: Deactivate HWLink when Port STOP is given
  296. *
  297. * Revision 1.12 1998/10/28 07:38:57 cgoos
  298. * Checking link status at begin of SkHWLinkUp.
  299. *
  300. * Revision 1.11 1998/10/22 09:46:50 gklug
  301. * fix SysKonnectFileId typo
  302. *
  303. * Revision 1.10 1998/10/14 13:57:47 gklug
  304. * add: Port start/stop event
  305. *
  306. * Revision 1.9 1998/10/14 05:48:29 cgoos
  307. * Added definition for Para.
  308. *
  309. * Revision 1.8 1998/10/14 05:40:09 gklug
  310. * add: Hardware Linkup signal used
  311. *
  312. * Revision 1.7 1998/10/09 06:50:20 malthoff
  313. * Remove ID_sccs by SysKonnectFileId.
  314. *
  315. * Revision 1.6 1998/10/08 09:11:49 gklug
  316. * add: clear IRQ commands
  317. *
  318. * Revision 1.5 1998/10/02 14:27:35 cgoos
  319. * Fixed some typos and wrong event names.
  320. *
  321. * Revision 1.4 1998/10/02 06:24:17 gklug
  322. * add: HW error function
  323. * fix: OUT macros
  324. *
  325. * Revision 1.3 1998/10/01 07:03:00 gklug
  326. * add: ISR for the usual interrupt source register
  327. *
  328. * Revision 1.2 1998/09/03 13:50:33 gklug
  329. * add: function prototypes
  330. *
  331. * Revision 1.1 1998/08/27 11:50:21 gklug
  332. * initial revision
  333. *
  334. *
  335. *
  336. ******************************************************************************/
  337. #include <config.h>
  338. #ifdef CONFIG_SK98
  339. /*
  340. * Special Interrupt handler
  341. *
  342. * The following abstract should show how this module is included
  343. * in the driver path:
  344. *
  345. * In the ISR of the driver the bits for frame transmission complete and
  346. * for receive complete are checked and handled by the driver itself.
  347. * The bits of the slow path mask are checked after that and then the
  348. * entry into the so-called "slow path" is prepared. It is an implementors
  349. * decision whether this is executed directly or just scheduled by
  350. * disabling the mask. In the interrupt service routine some events may be
  351. * generated, so it would be a good idea to call the EventDispatcher
  352. * right after this ISR.
  353. *
  354. * The Interrupt source register of the adapter is NOT read by this module.
  355. * SO if the drivers implementor needs a while loop around the
  356. * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
  357. * each loop entered.
  358. *
  359. * However, the MAC Interrupt status registers are read in a while loop.
  360. *
  361. */
  362. static const char SysKonnectFileId[] =
  363. "$Id: skgesirq.c,v 1.83 2003/02/05 15:10:59 rschmidt Exp $" ;
  364. #include "h/skdrv1st.h" /* Driver Specific Definitions */
  365. #include "h/skgepnmi.h" /* PNMI Definitions */
  366. #include "h/skrlmt.h" /* RLMT Definitions */
  367. #include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
  368. /* local function prototypes */
  369. static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int);
  370. static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int);
  371. static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int);
  372. static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
  373. static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
  374. #ifdef OTHER_PHY
  375. static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int);
  376. static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int);
  377. static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
  378. #endif /* OTHER_PHY */
  379. /*
  380. * array of Rx counter from XMAC which are checked
  381. * in AutoSense mode to check whether a link is not able to auto-negotiate.
  382. */
  383. static const SK_U16 SkGeRxRegs[]= {
  384. XM_RXF_64B,
  385. XM_RXF_127B,
  386. XM_RXF_255B,
  387. XM_RXF_511B,
  388. XM_RXF_1023B,
  389. XM_RXF_MAX_SZ
  390. } ;
  391. #ifdef __C2MAN__
  392. /*
  393. * Special IRQ function
  394. *
  395. * General Description:
  396. *
  397. */
  398. intro()
  399. {}
  400. #endif
  401. /* Define return codes of SkGePortCheckUp and CheckShort */
  402. #define SK_HW_PS_NONE 0 /* No action needed */
  403. #define SK_HW_PS_RESTART 1 /* Restart needed */
  404. #define SK_HW_PS_LINK 2 /* Link Up actions needed */
  405. /******************************************************************************
  406. *
  407. * SkHWInitDefSense() - Default Autosensing mode initialization
  408. *
  409. * Description: sets the PLinkMode for HWInit
  410. *
  411. * Returns: N/A
  412. */
  413. static void SkHWInitDefSense(
  414. SK_AC *pAC, /* adapter context */
  415. SK_IOC IoC, /* IO context */
  416. int Port) /* Port Index (MAC_1 + n) */
  417. {
  418. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  419. pPrt = &pAC->GIni.GP[Port];
  420. pPrt->PAutoNegTimeOut = 0;
  421. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  422. pPrt->PLinkMode = pPrt->PLinkModeConf;
  423. return;
  424. }
  425. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  426. ("AutoSensing: First mode %d on Port %d\n",
  427. (int)SK_LMODE_AUTOFULL, Port));
  428. pPrt->PLinkMode = SK_LMODE_AUTOFULL;
  429. return;
  430. } /* SkHWInitDefSense */
  431. /******************************************************************************
  432. *
  433. * SkHWSenseGetNext() - Get Next Autosensing Mode
  434. *
  435. * Description: gets the appropriate next mode
  436. *
  437. * Note:
  438. *
  439. */
  440. SK_U8 SkHWSenseGetNext(
  441. SK_AC *pAC, /* adapter context */
  442. SK_IOC IoC, /* IO context */
  443. int Port) /* Port Index (MAC_1 + n) */
  444. {
  445. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  446. pPrt = &pAC->GIni.GP[Port];
  447. pPrt->PAutoNegTimeOut = 0;
  448. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  449. /* Leave all as configured */
  450. return(pPrt->PLinkModeConf);
  451. }
  452. if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) {
  453. /* Return next mode AUTOBOTH */
  454. return(SK_LMODE_AUTOBOTH);
  455. }
  456. /* Return default autofull */
  457. return(SK_LMODE_AUTOFULL);
  458. } /* SkHWSenseGetNext */
  459. /******************************************************************************
  460. *
  461. * SkHWSenseSetNext() - Autosensing Set next mode
  462. *
  463. * Description: sets the appropriate next mode
  464. *
  465. * Returns: N/A
  466. */
  467. void SkHWSenseSetNext(
  468. SK_AC *pAC, /* adapter context */
  469. SK_IOC IoC, /* IO context */
  470. int Port, /* Port Index (MAC_1 + n) */
  471. SK_U8 NewMode) /* New Mode to be written in sense mode */
  472. {
  473. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  474. pPrt = &pAC->GIni.GP[Port];
  475. pPrt->PAutoNegTimeOut = 0;
  476. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  477. return;
  478. }
  479. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  480. ("AutoSensing: next mode %d on Port %d\n",
  481. (int)NewMode, Port));
  482. pPrt->PLinkMode = NewMode;
  483. return;
  484. } /* SkHWSenseSetNext */
  485. /******************************************************************************
  486. *
  487. * SkHWLinkDown() - Link Down handling
  488. *
  489. * Description: handles the hardware link down signal
  490. *
  491. * Returns: N/A
  492. */
  493. void SkHWLinkDown(
  494. SK_AC *pAC, /* adapter context */
  495. SK_IOC IoC, /* IO context */
  496. int Port) /* Port Index (MAC_1 + n) */
  497. {
  498. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  499. pPrt = &pAC->GIni.GP[Port];
  500. /* Disable all MAC interrupts */
  501. SkMacIrqDisable(pAC, IoC, Port);
  502. /* Disable Receiver and Transmitter */
  503. SkMacRxTxDisable(pAC, IoC, Port);
  504. /* Init default sense mode */
  505. SkHWInitDefSense(pAC, IoC, Port);
  506. if (!pPrt->PHWLinkUp) {
  507. return;
  508. }
  509. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  510. ("Link down Port %d\n", Port));
  511. /* Set Link to DOWN */
  512. pPrt->PHWLinkUp = SK_FALSE;
  513. /* Reset Port stati */
  514. pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
  515. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  516. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
  517. /* Re-init Phy especially when the AutoSense default is set now */
  518. SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
  519. /* GP0: used for workaround of Rev. C Errata 2 */
  520. /* Do NOT signal to RLMT */
  521. /* Do NOT start the timer here */
  522. } /* SkHWLinkDown */
  523. /******************************************************************************
  524. *
  525. * SkHWLinkUp() - Link Up handling
  526. *
  527. * Description: handles the hardware link up signal
  528. *
  529. * Returns: N/A
  530. */
  531. void SkHWLinkUp(
  532. SK_AC *pAC, /* adapter context */
  533. SK_IOC IoC, /* IO context */
  534. int Port) /* Port Index (MAC_1 + n) */
  535. {
  536. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  537. pPrt = &pAC->GIni.GP[Port];
  538. if (pPrt->PHWLinkUp) {
  539. /* We do NOT need to proceed on active link */
  540. return;
  541. }
  542. pPrt->PHWLinkUp = SK_TRUE;
  543. pPrt->PAutoNegFail = SK_FALSE;
  544. pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
  545. if (pPrt->PLinkMode != SK_LMODE_AUTOHALF &&
  546. pPrt->PLinkMode != SK_LMODE_AUTOFULL &&
  547. pPrt->PLinkMode != SK_LMODE_AUTOBOTH) {
  548. /* Link is up and no Auto-negotiation should be done */
  549. /* Link speed should be the configured one */
  550. switch (pPrt->PLinkSpeed) {
  551. case SK_LSPEED_AUTO:
  552. /* default is 1000 Mbps */
  553. case SK_LSPEED_1000MBPS:
  554. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
  555. break;
  556. case SK_LSPEED_100MBPS:
  557. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
  558. break;
  559. case SK_LSPEED_10MBPS:
  560. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
  561. break;
  562. }
  563. /* Set Link Mode Status */
  564. if (pPrt->PLinkMode == SK_LMODE_FULL) {
  565. pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
  566. }
  567. else {
  568. pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;
  569. }
  570. /* No flow control without auto-negotiation */
  571. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  572. /* enable Rx/Tx */
  573. SkMacRxTxEnable(pAC, IoC, Port);
  574. }
  575. } /* SkHWLinkUp */
  576. /******************************************************************************
  577. *
  578. * SkMacParity() - MAC parity workaround
  579. *
  580. * Description: handles MAC parity errors correctly
  581. *
  582. * Returns: N/A
  583. */
  584. static void SkMacParity(
  585. SK_AC *pAC, /* adapter context */
  586. SK_IOC IoC, /* IO context */
  587. int Port) /* Port Index of the port failed */
  588. {
  589. SK_EVPARA Para;
  590. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  591. SK_U32 TxMax; /* TxMax Counter */
  592. pPrt = &pAC->GIni.GP[Port];
  593. /* Clear IRQ Tx Parity Error */
  594. if (pAC->GIni.GIGenesis) {
  595. SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
  596. }
  597. else {
  598. /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
  599. SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
  600. (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
  601. }
  602. if (pPrt->PCheckPar) {
  603. if (Port == MAC_1) {
  604. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
  605. }
  606. else {
  607. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
  608. }
  609. Para.Para64 = Port;
  610. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  611. Para.Para32[0] = Port;
  612. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  613. return;
  614. }
  615. /* Check whether frames with a size of 1k were sent */
  616. if (pAC->GIni.GIGenesis) {
  617. /* Snap statistic counters */
  618. (void)SkXmUpdateStats(pAC, IoC, Port);
  619. (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
  620. }
  621. else {
  622. (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
  623. }
  624. if (TxMax > 0) {
  625. /* From now on check the parity */
  626. pPrt->PCheckPar = SK_TRUE;
  627. }
  628. } /* SkMacParity */
  629. /******************************************************************************
  630. *
  631. * SkGeHwErr() - Hardware Error service routine
  632. *
  633. * Description: handles all HW Error interrupts
  634. *
  635. * Returns: N/A
  636. */
  637. static void SkGeHwErr(
  638. SK_AC *pAC, /* adapter context */
  639. SK_IOC IoC, /* IO context */
  640. SK_U32 HwStatus) /* Interrupt status word */
  641. {
  642. SK_EVPARA Para;
  643. SK_U16 Word;
  644. if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
  645. /* PCI Errors occured */
  646. if ((HwStatus & IS_IRQ_STAT) != 0) {
  647. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
  648. }
  649. else {
  650. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
  651. }
  652. /* Reset all bits in the PCI STATUS register */
  653. SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
  654. SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
  655. SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
  656. SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
  657. Para.Para64 = 0;
  658. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  659. }
  660. if (pAC->GIni.GIGenesis) {
  661. if ((HwStatus & IS_NO_STAT_M1) != 0) {
  662. /* Ignore it */
  663. /* This situation is also indicated in the descriptor */
  664. SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
  665. }
  666. if ((HwStatus & IS_NO_STAT_M2) != 0) {
  667. /* Ignore it */
  668. /* This situation is also indicated in the descriptor */
  669. SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
  670. }
  671. if ((HwStatus & IS_NO_TIST_M1) != 0) {
  672. /* Ignore it */
  673. /* This situation is also indicated in the descriptor */
  674. SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
  675. }
  676. if ((HwStatus & IS_NO_TIST_M2) != 0) {
  677. /* Ignore it */
  678. /* This situation is also indicated in the descriptor */
  679. SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
  680. }
  681. }
  682. else { /* YUKON */
  683. /* This is necessary only for Rx timing measurements */
  684. if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
  685. /* Clear Time Stamp Timer IRQ */
  686. SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
  687. }
  688. if ((HwStatus & IS_IRQ_SENSOR) != 0) {
  689. /* Clear I2C IRQ */
  690. SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
  691. }
  692. }
  693. if ((HwStatus & IS_RAM_RD_PAR) != 0) {
  694. SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
  695. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
  696. Para.Para64 = 0;
  697. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  698. }
  699. if ((HwStatus & IS_RAM_WR_PAR) != 0) {
  700. SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
  701. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
  702. Para.Para64 = 0;
  703. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  704. }
  705. if ((HwStatus & IS_M1_PAR_ERR) != 0) {
  706. SkMacParity(pAC, IoC, MAC_1);
  707. }
  708. if ((HwStatus & IS_M2_PAR_ERR) != 0) {
  709. SkMacParity(pAC, IoC, MAC_2);
  710. }
  711. if ((HwStatus & IS_R1_PAR_ERR) != 0) {
  712. /* Clear IRQ */
  713. SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
  714. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
  715. Para.Para64 = MAC_1;
  716. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  717. Para.Para32[0] = MAC_1;
  718. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  719. }
  720. if ((HwStatus & IS_R2_PAR_ERR) != 0) {
  721. /* Clear IRQ */
  722. SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
  723. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
  724. Para.Para64 = MAC_2;
  725. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  726. Para.Para32[0] = MAC_2;
  727. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  728. }
  729. } /* SkGeHwErr */
  730. /******************************************************************************
  731. *
  732. * SkGeSirqIsr() - Special Interrupt Service Routine
  733. *
  734. * Description: handles all non data transfer specific interrupts (slow path)
  735. *
  736. * Returns: N/A
  737. */
  738. void SkGeSirqIsr(
  739. SK_AC *pAC, /* adapter context */
  740. SK_IOC IoC, /* IO context */
  741. SK_U32 Istatus) /* Interrupt status word */
  742. {
  743. SK_EVPARA Para;
  744. SK_U32 RegVal32; /* Read register value */
  745. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  746. unsigned Len;
  747. SK_U64 Octets;
  748. SK_U16 PhyInt;
  749. SK_U16 PhyIMsk;
  750. int i;
  751. if ((Istatus & IS_HW_ERR) != 0) {
  752. /* read the HW Error Interrupt source */
  753. SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
  754. SkGeHwErr(pAC, IoC, RegVal32);
  755. }
  756. /*
  757. * Packet Timeout interrupts
  758. */
  759. /* Check whether MACs are correctly initialized */
  760. if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
  761. pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
  762. /* MAC 1 was not initialized but Packet timeout occured */
  763. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
  764. SKERR_SIRQ_E004MSG);
  765. }
  766. if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
  767. pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
  768. /* MAC 2 was not initialized but Packet timeout occured */
  769. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
  770. SKERR_SIRQ_E005MSG);
  771. }
  772. if ((Istatus & IS_PA_TO_RX1) != 0) {
  773. /* Means network is filling us up */
  774. SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
  775. SKERR_SIRQ_E002MSG);
  776. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
  777. }
  778. if ((Istatus & IS_PA_TO_RX2) != 0) {
  779. /* Means network is filling us up */
  780. SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
  781. SKERR_SIRQ_E003MSG);
  782. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
  783. }
  784. if ((Istatus & IS_PA_TO_TX1) != 0) {
  785. pPrt = &pAC->GIni.GP[0];
  786. /* May be a normal situation in a server with a slow network */
  787. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
  788. /*
  789. * workaround: if in half duplex mode, check for Tx hangup.
  790. * Read number of TX'ed bytes, wait for 10 ms, then compare
  791. * the number with current value. If nothing changed, we assume
  792. * that Tx is hanging and do a FIFO flush (see event routine).
  793. */
  794. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  795. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
  796. !pPrt->HalfDupTimerActive) {
  797. /*
  798. * many more pack. arb. timeouts may come in between,
  799. * we ignore those
  800. */
  801. pPrt->HalfDupTimerActive = SK_TRUE;
  802. Len = sizeof(SK_U64);
  803. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  804. &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),
  805. pAC->Rlmt.Port[0].Net->NetNumber);
  806. pPrt->LastOctets = Octets;
  807. Para.Para32[0] = 0;
  808. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  809. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  810. }
  811. }
  812. if ((Istatus & IS_PA_TO_TX2) != 0) {
  813. pPrt = &pAC->GIni.GP[1];
  814. /* May be a normal situation in a server with a slow network */
  815. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
  816. /* workaround: see above */
  817. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  818. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
  819. !pPrt->HalfDupTimerActive) {
  820. pPrt->HalfDupTimerActive = SK_TRUE;
  821. Len = sizeof(SK_U64);
  822. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  823. &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),
  824. pAC->Rlmt.Port[1].Net->NetNumber);
  825. pPrt->LastOctets = Octets;
  826. Para.Para32[0] = 1;
  827. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  828. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  829. }
  830. }
  831. /* Check interrupts of the particular queues */
  832. if ((Istatus & IS_R1_C) != 0) {
  833. /* Clear IRQ */
  834. SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
  835. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
  836. SKERR_SIRQ_E006MSG);
  837. Para.Para64 = MAC_1;
  838. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  839. Para.Para32[0] = MAC_1;
  840. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  841. }
  842. if ((Istatus & IS_R2_C) != 0) {
  843. /* Clear IRQ */
  844. SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
  845. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
  846. SKERR_SIRQ_E007MSG);
  847. Para.Para64 = MAC_2;
  848. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  849. Para.Para32[0] = MAC_2;
  850. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  851. }
  852. if ((Istatus & IS_XS1_C) != 0) {
  853. /* Clear IRQ */
  854. SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
  855. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
  856. SKERR_SIRQ_E008MSG);
  857. Para.Para64 = MAC_1;
  858. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  859. Para.Para32[0] = MAC_1;
  860. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  861. }
  862. if ((Istatus & IS_XA1_C) != 0) {
  863. /* Clear IRQ */
  864. SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
  865. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
  866. SKERR_SIRQ_E009MSG);
  867. Para.Para64 = MAC_1;
  868. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  869. Para.Para32[0] = MAC_1;
  870. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  871. }
  872. if ((Istatus & IS_XS2_C) != 0) {
  873. /* Clear IRQ */
  874. SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
  875. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
  876. SKERR_SIRQ_E010MSG);
  877. Para.Para64 = MAC_2;
  878. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  879. Para.Para32[0] = MAC_2;
  880. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  881. }
  882. if ((Istatus & IS_XA2_C) != 0) {
  883. /* Clear IRQ */
  884. SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
  885. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
  886. SKERR_SIRQ_E011MSG);
  887. Para.Para64 = MAC_2;
  888. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  889. Para.Para32[0] = MAC_2;
  890. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  891. }
  892. /* External reg interrupt */
  893. if ((Istatus & IS_EXT_REG) != 0) {
  894. /* Test IRQs from PHY */
  895. for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
  896. pPrt = &pAC->GIni.GP[i];
  897. if (pPrt->PState == SK_PRT_RESET) {
  898. continue;
  899. }
  900. switch (pPrt->PhyType) {
  901. case SK_PHY_XMAC:
  902. break;
  903. case SK_PHY_BCOM:
  904. SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
  905. SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk);
  906. if ((PhyInt & ~PhyIMsk) != 0) {
  907. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  908. ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n",
  909. i, PhyInt, PhyIMsk));
  910. SkPhyIsrBcom(pAC, IoC, i, PhyInt);
  911. }
  912. break;
  913. case SK_PHY_MARV_COPPER:
  914. case SK_PHY_MARV_FIBER:
  915. SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
  916. SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk);
  917. if ((PhyInt & PhyIMsk) != 0) {
  918. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  919. ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n",
  920. i, PhyInt, PhyIMsk));
  921. SkPhyIsrGmac(pAC, IoC, i, PhyInt);
  922. }
  923. break;
  924. #ifdef OTHER_PHY
  925. case SK_PHY_LONE:
  926. SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
  927. SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk);
  928. if ((PhyInt & PhyIMsk) != 0) {
  929. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  930. ("Port %d Lone Int: %x Mask: %x\n",
  931. i, PhyInt, PhyIMsk));
  932. SkPhyIsrLone(pAC, IoC, i, PhyInt);
  933. }
  934. break;
  935. case SK_PHY_NAT:
  936. /* todo: National */
  937. break;
  938. #endif /* OTHER_PHY */
  939. }
  940. }
  941. }
  942. /* I2C Ready interrupt */
  943. if ((Istatus & IS_I2C_READY) != 0) {
  944. SkI2cIsr(pAC, IoC);
  945. }
  946. if ((Istatus & IS_LNK_SYNC_M1) != 0) {
  947. /*
  948. * We do NOT need the Link Sync interrupt, because it shows
  949. * us only a link going down.
  950. */
  951. /* clear interrupt */
  952. SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
  953. }
  954. /* Check MAC after link sync counter */
  955. if ((Istatus & IS_MAC1) != 0) {
  956. /* IRQ from MAC 1 */
  957. SkMacIrq(pAC, IoC, MAC_1);
  958. }
  959. if ((Istatus & IS_LNK_SYNC_M2) != 0) {
  960. /*
  961. * We do NOT need the Link Sync interrupt, because it shows
  962. * us only a link going down.
  963. */
  964. /* clear interrupt */
  965. SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
  966. }
  967. /* Check MAC after link sync counter */
  968. if ((Istatus & IS_MAC2) != 0) {
  969. /* IRQ from MAC 2 */
  970. SkMacIrq(pAC, IoC, MAC_2);
  971. }
  972. /* Timer interrupt (served last) */
  973. if ((Istatus & IS_TIMINT) != 0) {
  974. SkHwtIsr(pAC, IoC);
  975. }
  976. } /* SkGeSirqIsr */
  977. /******************************************************************************
  978. *
  979. * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
  980. *
  981. * return:
  982. * 0 o.k. nothing needed
  983. * 1 Restart needed on this port
  984. */
  985. static int SkGePortCheckShorts(
  986. SK_AC *pAC, /* Adapter Context */
  987. SK_IOC IoC, /* IO Context */
  988. int Port) /* Which port should be checked */
  989. {
  990. SK_U32 Shorts; /* Short Event Counter */
  991. SK_U32 CheckShorts; /* Check value for Short Event Counter */
  992. SK_U64 RxCts; /* Rx Counter (packets on network) */
  993. SK_U32 RxTmp; /* Rx temp. Counter */
  994. SK_U32 FcsErrCts; /* FCS Error Counter */
  995. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  996. int Rtv; /* Return value */
  997. int i;
  998. pPrt = &pAC->GIni.GP[Port];
  999. /* Default: no action */
  1000. Rtv = SK_HW_PS_NONE;
  1001. (void)SkXmUpdateStats(pAC, IoC, Port);
  1002. /* Extra precaution: check for short Event counter */
  1003. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  1004. /*
  1005. * Read Rx counter (packets seen on the network and not necessarily
  1006. * really received.
  1007. */
  1008. RxCts = 0;
  1009. for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
  1010. (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
  1011. RxCts += (SK_U64)RxTmp;
  1012. }
  1013. /* On default: check shorts against zero */
  1014. CheckShorts = 0;
  1015. /* Extra precaution on active links */
  1016. if (pPrt->PHWLinkUp) {
  1017. /* Reset Link Restart counter */
  1018. pPrt->PLinkResCt = 0;
  1019. pPrt->PAutoNegTOCt = 0;
  1020. /* If link is up check for 2 */
  1021. CheckShorts = 2;
  1022. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
  1023. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1024. pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
  1025. (pPrt->PLinkMode == SK_LMODE_HALF ||
  1026. pPrt->PLinkMode == SK_LMODE_FULL)) {
  1027. /*
  1028. * This is autosensing and we are in the fallback
  1029. * manual full/half duplex mode.
  1030. */
  1031. if (RxCts == pPrt->PPrevRx) {
  1032. /* Nothing received, restart link */
  1033. pPrt->PPrevFcs = FcsErrCts;
  1034. pPrt->PPrevShorts = Shorts;
  1035. return(SK_HW_PS_RESTART);
  1036. }
  1037. else {
  1038. pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
  1039. }
  1040. }
  1041. if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
  1042. (!(FcsErrCts - pPrt->PPrevFcs))) {
  1043. /*
  1044. * Note: The compare with zero above has to be done the way shown,
  1045. * otherwise the Linux driver will have a problem.
  1046. */
  1047. /*
  1048. * We received a bunch of frames or no CRC error occured on the
  1049. * network -> ok.
  1050. */
  1051. pPrt->PPrevRx = RxCts;
  1052. pPrt->PPrevFcs = FcsErrCts;
  1053. pPrt->PPrevShorts = Shorts;
  1054. return(SK_HW_PS_NONE);
  1055. }
  1056. pPrt->PPrevFcs = FcsErrCts;
  1057. }
  1058. if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
  1059. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1060. ("Short Event Count Restart Port %d \n", Port));
  1061. Rtv = SK_HW_PS_RESTART;
  1062. }
  1063. pPrt->PPrevShorts = Shorts;
  1064. pPrt->PPrevRx = RxCts;
  1065. return(Rtv);
  1066. } /* SkGePortCheckShorts */
  1067. /******************************************************************************
  1068. *
  1069. * SkGePortCheckUp() - Check if the link is up
  1070. *
  1071. * return:
  1072. * 0 o.k. nothing needed
  1073. * 1 Restart needed on this port
  1074. * 2 Link came up
  1075. */
  1076. static int SkGePortCheckUp(
  1077. SK_AC *pAC, /* Adapter Context */
  1078. SK_IOC IoC, /* IO Context */
  1079. int Port) /* Which port should be checked */
  1080. {
  1081. switch (pAC->GIni.GP[Port].PhyType) {
  1082. case SK_PHY_XMAC:
  1083. return(SkGePortCheckUpXmac(pAC, IoC, Port));
  1084. case SK_PHY_BCOM:
  1085. return(SkGePortCheckUpBcom(pAC, IoC, Port));
  1086. case SK_PHY_MARV_COPPER:
  1087. case SK_PHY_MARV_FIBER:
  1088. return(SkGePortCheckUpGmac(pAC, IoC, Port));
  1089. #ifdef OTHER_PHY
  1090. case SK_PHY_LONE:
  1091. return(SkGePortCheckUpLone(pAC, IoC, Port));
  1092. case SK_PHY_NAT:
  1093. return(SkGePortCheckUpNat(pAC, IoC, Port));
  1094. #endif /* OTHER_PHY */
  1095. }
  1096. return(SK_HW_PS_NONE);
  1097. } /* SkGePortCheckUp */
  1098. /******************************************************************************
  1099. *
  1100. * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
  1101. *
  1102. * return:
  1103. * 0 o.k. nothing needed
  1104. * 1 Restart needed on this port
  1105. * 2 Link came up
  1106. */
  1107. static int SkGePortCheckUpXmac(
  1108. SK_AC *pAC, /* Adapter Context */
  1109. SK_IOC IoC, /* IO Context */
  1110. int Port) /* Which port should be checked */
  1111. {
  1112. SK_U32 Shorts; /* Short Event Counter */
  1113. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1114. int Done;
  1115. SK_U32 GpReg; /* General Purpose register value */
  1116. SK_U16 Isrc; /* Interrupt source register */
  1117. SK_U16 IsrcSum; /* Interrupt source register sum */
  1118. SK_U16 LpAb; /* Link Partner Ability */
  1119. SK_U16 ResAb; /* Resolved Ability */
  1120. SK_U16 ExtStat; /* Extended Status Register */
  1121. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1122. SK_U8 NextMode; /* Next AutoSensing Mode */
  1123. pPrt = &pAC->GIni.GP[Port];
  1124. if (pPrt->PHWLinkUp) {
  1125. if (pPrt->PhyType != SK_PHY_XMAC) {
  1126. return(SK_HW_PS_NONE);
  1127. }
  1128. else {
  1129. return(SkGePortCheckShorts(pAC, IoC, Port));
  1130. }
  1131. }
  1132. IsrcSum = pPrt->PIsave;
  1133. pPrt->PIsave = 0;
  1134. /* Now wait for each port's link */
  1135. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1136. AutoNeg = SK_FALSE;
  1137. }
  1138. else {
  1139. AutoNeg = SK_TRUE;
  1140. }
  1141. if (pPrt->PLinkBroken) {
  1142. /* Link was broken */
  1143. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  1144. if ((GpReg & XM_GP_INP_ASS) == 0) {
  1145. /* The Link is in sync */
  1146. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1147. IsrcSum |= Isrc;
  1148. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  1149. if ((Isrc & XM_IS_INP_ASS) == 0) {
  1150. /* It has been in sync since last time */
  1151. /* Restart the PORT */
  1152. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1153. ("Link in sync Restart Port %d\n", Port));
  1154. (void)SkXmUpdateStats(pAC, IoC, Port);
  1155. /* We now need to reinitialize the PrevShorts counter */
  1156. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  1157. pPrt->PPrevShorts = Shorts;
  1158. pPrt->PLinkBroken = SK_FALSE;
  1159. /*
  1160. * Link Restart Workaround:
  1161. * it may be possible that the other Link side
  1162. * restarts its link as well an we detect
  1163. * another LinkBroken. To prevent this
  1164. * happening we check for a maximum number
  1165. * of consecutive restart. If those happens,
  1166. * we do NOT restart the active link and
  1167. * check whether the link is now o.k.
  1168. */
  1169. pPrt->PLinkResCt++;
  1170. pPrt->PAutoNegTimeOut = 0;
  1171. if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
  1172. return(SK_HW_PS_RESTART);
  1173. }
  1174. pPrt->PLinkResCt = 0;
  1175. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1176. ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
  1177. }
  1178. else {
  1179. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  1180. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1181. ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
  1182. /* Do nothing more if link is broken */
  1183. return(SK_HW_PS_NONE);
  1184. }
  1185. }
  1186. else {
  1187. /* Do nothing more if link is broken */
  1188. return(SK_HW_PS_NONE);
  1189. }
  1190. }
  1191. else {
  1192. /* Link was not broken, check if it is */
  1193. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1194. IsrcSum |= Isrc;
  1195. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1196. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1197. IsrcSum |= Isrc;
  1198. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1199. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1200. IsrcSum |= Isrc;
  1201. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1202. pPrt->PLinkBroken = SK_TRUE;
  1203. /* Re-Init Link partner Autoneg flag */
  1204. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  1205. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1206. ("Link broken Port %d\n", Port));
  1207. /* Cable removed-> reinit sense mode */
  1208. SkHWInitDefSense(pAC, IoC, Port);
  1209. return(SK_HW_PS_RESTART);
  1210. }
  1211. }
  1212. }
  1213. else {
  1214. SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
  1215. if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
  1216. return(SK_HW_PS_RESTART);
  1217. }
  1218. }
  1219. }
  1220. /*
  1221. * here we usually can check whether the link is in sync and
  1222. * auto-negotiation is done.
  1223. */
  1224. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  1225. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1226. IsrcSum |= Isrc;
  1227. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  1228. if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
  1229. if ((GpReg & XM_GP_INP_ASS) == 0) {
  1230. /* Save Auto-negotiation Done interrupt only if link is in sync */
  1231. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  1232. }
  1233. #ifdef DEBUG
  1234. if ((pPrt->PIsave & XM_IS_AND) != 0) {
  1235. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1236. ("AutoNeg done rescheduled Port %d\n", Port));
  1237. }
  1238. #endif /* DEBUG */
  1239. return(SK_HW_PS_NONE);
  1240. }
  1241. if (AutoNeg) {
  1242. if ((IsrcSum & XM_IS_AND) != 0) {
  1243. SkHWLinkUp(pAC, IoC, Port);
  1244. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1245. if (Done != SK_AND_OK) {
  1246. /* Get PHY parameters, for debugging only */
  1247. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
  1248. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
  1249. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1250. ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
  1251. Port, LpAb, ResAb));
  1252. /* Try next possible mode */
  1253. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1254. SkHWLinkDown(pAC, IoC, Port);
  1255. if (Done == SK_AND_DUP_CAP) {
  1256. /* GoTo next mode */
  1257. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1258. }
  1259. return(SK_HW_PS_RESTART);
  1260. }
  1261. /*
  1262. * Dummy Read extended status to prevent extra link down/ups
  1263. * (clear Page Received bit if set)
  1264. */
  1265. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
  1266. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1267. ("AutoNeg done Port %d\n", Port));
  1268. return(SK_HW_PS_LINK);
  1269. }
  1270. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1271. pPrt->PAutoNegTimeOut++;
  1272. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1273. /* Increase the Timeout counter */
  1274. pPrt->PAutoNegTOCt++;
  1275. /* Timeout occured */
  1276. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1277. ("AutoNeg timeout Port %d\n", Port));
  1278. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1279. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1280. /* Set Link manually up */
  1281. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1282. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1283. ("Set manual full duplex Port %d\n", Port));
  1284. }
  1285. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1286. pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
  1287. pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
  1288. /*
  1289. * This is rather complicated.
  1290. * we need to check here whether the LIPA_AUTO
  1291. * we saw before is false alert. We saw at one
  1292. * switch ( SR8800) that on boot time it sends
  1293. * just one auto-neg packet and does no further
  1294. * auto-negotiation.
  1295. * Solution: we restart the autosensing after
  1296. * a few timeouts.
  1297. */
  1298. pPrt->PAutoNegTOCt = 0;
  1299. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  1300. SkHWInitDefSense(pAC, IoC, Port);
  1301. }
  1302. /* Do the restart */
  1303. return(SK_HW_PS_RESTART);
  1304. }
  1305. }
  1306. else {
  1307. /* Link is up and we don't need more */
  1308. #ifdef DEBUG
  1309. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1310. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1311. ("ERROR: Lipa auto detected on port %d\n", Port));
  1312. }
  1313. #endif /* DEBUG */
  1314. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1315. ("Link sync(GP), Port %d\n", Port));
  1316. SkHWLinkUp(pAC, IoC, Port);
  1317. /*
  1318. * Link sync (GP) and so assume a good connection. But if not received
  1319. * a bunch of frames received in a time slot (maybe broken tx cable)
  1320. * the port is restart.
  1321. */
  1322. return(SK_HW_PS_LINK);
  1323. }
  1324. return(SK_HW_PS_NONE);
  1325. } /* SkGePortCheckUpXmac */
  1326. /******************************************************************************
  1327. *
  1328. * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
  1329. *
  1330. * return:
  1331. * 0 o.k. nothing needed
  1332. * 1 Restart needed on this port
  1333. * 2 Link came up
  1334. */
  1335. static int SkGePortCheckUpBcom(
  1336. SK_AC *pAC, /* Adapter Context */
  1337. SK_IOC IoC, /* IO Context */
  1338. int Port) /* Which port should be checked */
  1339. {
  1340. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1341. int Done;
  1342. SK_U16 Isrc; /* Interrupt source register */
  1343. SK_U16 PhyStat; /* Phy Status Register */
  1344. SK_U16 ResAb; /* Master/Slave resolution */
  1345. SK_U16 Ctrl; /* Broadcom control flags */
  1346. #ifdef DEBUG
  1347. SK_U16 LpAb;
  1348. SK_U16 ExtStat;
  1349. #endif /* DEBUG */
  1350. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1351. pPrt = &pAC->GIni.GP[Port];
  1352. /* Check for No HCD Link events (#10523) */
  1353. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
  1354. #ifdef xDEBUG
  1355. if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
  1356. (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
  1357. SK_U32 Stat1, Stat2, Stat3;
  1358. Stat1 = 0;
  1359. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1360. CMSMPrintString(
  1361. pAC->pConfigTable,
  1362. MSG_TYPE_RUNTIME_INFO,
  1363. "CheckUp1 - Stat: %x, Mask: %x",
  1364. (void *)Isrc,
  1365. (void *)Stat1);
  1366. Stat1 = 0;
  1367. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1368. Stat2 = 0;
  1369. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
  1370. Stat1 = Stat1 << 16 | Stat2;
  1371. Stat2 = 0;
  1372. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1373. Stat3 = 0;
  1374. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1375. Stat2 = Stat2 << 16 | Stat3;
  1376. CMSMPrintString(
  1377. pAC->pConfigTable,
  1378. MSG_TYPE_RUNTIME_INFO,
  1379. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1380. (void *)Stat1,
  1381. (void *)Stat2);
  1382. Stat1 = 0;
  1383. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1384. Stat2 = 0;
  1385. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1386. Stat1 = Stat1 << 16 | Stat2;
  1387. Stat2 = 0;
  1388. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1389. Stat3 = 0;
  1390. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
  1391. Stat2 = Stat2 << 16 | Stat3;
  1392. CMSMPrintString(
  1393. pAC->pConfigTable,
  1394. MSG_TYPE_RUNTIME_INFO,
  1395. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1396. (void *)Stat1,
  1397. (void *)Stat2);
  1398. Stat1 = 0;
  1399. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1400. Stat2 = 0;
  1401. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1402. Stat1 = Stat1 << 16 | Stat2;
  1403. Stat2 = 0;
  1404. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1405. Stat3 = 0;
  1406. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1407. Stat2 = Stat2 << 16 | Stat3;
  1408. CMSMPrintString(
  1409. pAC->pConfigTable,
  1410. MSG_TYPE_RUNTIME_INFO,
  1411. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1412. (void *)Stat1,
  1413. (void *)Stat2);
  1414. }
  1415. #endif /* DEBUG */
  1416. if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
  1417. /*
  1418. * Workaround BCom Errata:
  1419. * enable and disable loopback mode if "NO HCD" occurs.
  1420. */
  1421. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
  1422. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1423. (SK_U16)(Ctrl | PHY_CT_LOOP));
  1424. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1425. (SK_U16)(Ctrl & ~PHY_CT_LOOP));
  1426. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1427. ("No HCD Link event, Port %d\n", Port));
  1428. #ifdef xDEBUG
  1429. CMSMPrintString(
  1430. pAC->pConfigTable,
  1431. MSG_TYPE_RUNTIME_INFO,
  1432. "No HCD link event, port %d.",
  1433. (void *)Port,
  1434. (void *)NULL);
  1435. #endif /* DEBUG */
  1436. }
  1437. /* Not obsolete: link status bit is latched to 0 and autoclearing! */
  1438. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1439. if (pPrt->PHWLinkUp) {
  1440. return(SK_HW_PS_NONE);
  1441. }
  1442. #ifdef xDEBUG
  1443. {
  1444. SK_U32 Stat1, Stat2, Stat3;
  1445. Stat1 = 0;
  1446. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1447. CMSMPrintString(
  1448. pAC->pConfigTable,
  1449. MSG_TYPE_RUNTIME_INFO,
  1450. "CheckUp1a - Stat: %x, Mask: %x",
  1451. (void *)Isrc,
  1452. (void *)Stat1);
  1453. Stat1 = 0;
  1454. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1455. Stat2 = 0;
  1456. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1457. Stat1 = Stat1 << 16 | PhyStat;
  1458. Stat2 = 0;
  1459. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1460. Stat3 = 0;
  1461. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1462. Stat2 = Stat2 << 16 | Stat3;
  1463. CMSMPrintString(
  1464. pAC->pConfigTable,
  1465. MSG_TYPE_RUNTIME_INFO,
  1466. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1467. (void *)Stat1,
  1468. (void *)Stat2);
  1469. Stat1 = 0;
  1470. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1471. Stat2 = 0;
  1472. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1473. Stat1 = Stat1 << 16 | Stat2;
  1474. Stat2 = 0;
  1475. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1476. Stat3 = 0;
  1477. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1478. Stat2 = Stat2 << 16 | ResAb;
  1479. CMSMPrintString(
  1480. pAC->pConfigTable,
  1481. MSG_TYPE_RUNTIME_INFO,
  1482. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1483. (void *)Stat1,
  1484. (void *)Stat2);
  1485. Stat1 = 0;
  1486. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1487. Stat2 = 0;
  1488. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1489. Stat1 = Stat1 << 16 | Stat2;
  1490. Stat2 = 0;
  1491. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1492. Stat3 = 0;
  1493. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1494. Stat2 = Stat2 << 16 | Stat3;
  1495. CMSMPrintString(
  1496. pAC->pConfigTable,
  1497. MSG_TYPE_RUNTIME_INFO,
  1498. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1499. (void *)Stat1,
  1500. (void *)Stat2);
  1501. }
  1502. #endif /* DEBUG */
  1503. /* Now wait for each port's link */
  1504. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1505. AutoNeg = SK_FALSE;
  1506. }
  1507. else {
  1508. AutoNeg = SK_TRUE;
  1509. }
  1510. /*
  1511. * Here we usually can check whether the link is in sync and
  1512. * auto-negotiation is done.
  1513. */
  1514. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1515. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1516. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1517. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1518. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1519. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1520. /* Error */
  1521. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1522. ("Master/Slave Fault port %d\n", Port));
  1523. pPrt->PAutoNegFail = SK_TRUE;
  1524. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1525. return(SK_HW_PS_RESTART);
  1526. }
  1527. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1528. return(SK_HW_PS_NONE);
  1529. }
  1530. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1531. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1532. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1533. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1534. if (AutoNeg) {
  1535. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1536. SkHWLinkUp(pAC, IoC, Port);
  1537. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1538. if (Done != SK_AND_OK) {
  1539. #ifdef DEBUG
  1540. /* Get PHY parameters, for debugging only */
  1541. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
  1542. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
  1543. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1544. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1545. Port, LpAb, ExtStat));
  1546. #endif /* DEBUG */
  1547. return(SK_HW_PS_RESTART);
  1548. }
  1549. else {
  1550. #ifdef xDEBUG
  1551. /* Dummy read ISR to prevent extra link downs/ups */
  1552. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1553. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1554. CMSMPrintString(
  1555. pAC->pConfigTable,
  1556. MSG_TYPE_RUNTIME_INFO,
  1557. "CheckUp2 - Stat: %x",
  1558. (void *)ExtStat,
  1559. (void *)NULL);
  1560. }
  1561. #endif /* DEBUG */
  1562. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1563. ("AutoNeg done Port %d\n", Port));
  1564. return(SK_HW_PS_LINK);
  1565. }
  1566. }
  1567. }
  1568. else { /* !AutoNeg */
  1569. /* Link is up and we don't need more. */
  1570. #ifdef DEBUG
  1571. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1572. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1573. ("ERROR: Lipa auto detected on port %d\n", Port));
  1574. }
  1575. #endif /* DEBUG */
  1576. #ifdef xDEBUG
  1577. /* Dummy read ISR to prevent extra link downs/ups */
  1578. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1579. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1580. CMSMPrintString(
  1581. pAC->pConfigTable,
  1582. MSG_TYPE_RUNTIME_INFO,
  1583. "CheckUp3 - Stat: %x",
  1584. (void *)ExtStat,
  1585. (void *)NULL);
  1586. }
  1587. #endif /* DEBUG */
  1588. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1589. ("Link sync(GP), Port %d\n", Port));
  1590. SkHWLinkUp(pAC, IoC, Port);
  1591. return(SK_HW_PS_LINK);
  1592. }
  1593. return(SK_HW_PS_NONE);
  1594. } /* SkGePortCheckUpBcom */
  1595. /******************************************************************************
  1596. *
  1597. * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
  1598. *
  1599. * return:
  1600. * 0 o.k. nothing needed
  1601. * 1 Restart needed on this port
  1602. * 2 Link came up
  1603. */
  1604. static int SkGePortCheckUpGmac(
  1605. SK_AC *pAC, /* Adapter Context */
  1606. SK_IOC IoC, /* IO Context */
  1607. int Port) /* Which port should be checked */
  1608. {
  1609. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1610. int Done;
  1611. SK_U16 Isrc; /* Interrupt source */
  1612. SK_U16 PhyStat; /* Phy Status */
  1613. SK_U16 PhySpecStat;/* Phy Specific Status */
  1614. SK_U16 ResAb; /* Master/Slave resolution */
  1615. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1616. pPrt = &pAC->GIni.GP[Port];
  1617. /* Read PHY Interrupt Status */
  1618. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc);
  1619. if ((Isrc & PHY_M_IS_AN_COMPL) != 0) {
  1620. /* TBD */
  1621. }
  1622. if ((Isrc & PHY_M_IS_DOWNSH_DET) != 0) {
  1623. /* TBD */
  1624. }
  1625. if (pPrt->PHWLinkUp) {
  1626. return(SK_HW_PS_NONE);
  1627. }
  1628. /* Now wait for each port's link */
  1629. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1630. AutoNeg = SK_FALSE;
  1631. }
  1632. else {
  1633. AutoNeg = SK_TRUE;
  1634. }
  1635. /* Read PHY Status */
  1636. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
  1637. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1638. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1639. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1640. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
  1641. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1642. /* Error */
  1643. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1644. ("Master/Slave Fault port %d\n", Port));
  1645. pPrt->PAutoNegFail = SK_TRUE;
  1646. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1647. return(SK_HW_PS_RESTART);
  1648. }
  1649. /* Read PHY Specific Status */
  1650. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
  1651. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1652. ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat));
  1653. if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
  1654. return(SK_HW_PS_NONE);
  1655. }
  1656. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1657. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1658. pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
  1659. if (AutoNeg) {
  1660. /* Auto-Negotiation Over ? */
  1661. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1662. SkHWLinkUp(pAC, IoC, Port);
  1663. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1664. if (Done != SK_AND_OK) {
  1665. return(SK_HW_PS_RESTART);
  1666. }
  1667. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1668. ("AutoNeg done Port %d\n", Port));
  1669. return(SK_HW_PS_LINK);
  1670. }
  1671. }
  1672. else { /* !AutoNeg */
  1673. /* Link is up and we don't need more */
  1674. #ifdef DEBUG
  1675. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1676. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1677. ("ERROR: Lipa auto detected on port %d\n", Port));
  1678. }
  1679. #endif /* DEBUG */
  1680. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1681. ("Link sync, Port %d\n", Port));
  1682. SkHWLinkUp(pAC, IoC, Port);
  1683. return(SK_HW_PS_LINK);
  1684. }
  1685. return(SK_HW_PS_NONE);
  1686. } /* SkGePortCheckUpGmac */
  1687. #ifdef OTHER_PHY
  1688. /******************************************************************************
  1689. *
  1690. * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
  1691. *
  1692. * return:
  1693. * 0 o.k. nothing needed
  1694. * 1 Restart needed on this port
  1695. * 2 Link came up
  1696. */
  1697. static int SkGePortCheckUpLone(
  1698. SK_AC *pAC, /* Adapter Context */
  1699. SK_IOC IoC, /* IO Context */
  1700. int Port) /* Which port should be checked */
  1701. {
  1702. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1703. int Done;
  1704. SK_U16 Isrc; /* Interrupt source register */
  1705. SK_U16 LpAb; /* Link Partner Ability */
  1706. SK_U16 ExtStat; /* Extended Status Register */
  1707. SK_U16 PhyStat; /* Phy Status Register */
  1708. SK_U16 StatSum;
  1709. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1710. SK_U8 NextMode; /* Next AutoSensing Mode */
  1711. pPrt = &pAC->GIni.GP[Port];
  1712. if (pPrt->PHWLinkUp) {
  1713. return(SK_HW_PS_NONE);
  1714. }
  1715. StatSum = pPrt->PIsave;
  1716. pPrt->PIsave = 0;
  1717. /* Now wait for each ports link */
  1718. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1719. AutoNeg = SK_FALSE;
  1720. }
  1721. else {
  1722. AutoNeg = SK_TRUE;
  1723. }
  1724. /*
  1725. * here we usually can check whether the link is in sync and
  1726. * auto-negotiation is done.
  1727. */
  1728. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
  1729. StatSum |= PhyStat;
  1730. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1731. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1732. /* Save Auto-negotiation Done bit */
  1733. pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
  1734. #ifdef DEBUG
  1735. if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
  1736. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1737. ("AutoNeg done rescheduled Port %d\n", Port));
  1738. }
  1739. #endif /* DEBUG */
  1740. return(SK_HW_PS_NONE);
  1741. }
  1742. if (AutoNeg) {
  1743. if ((StatSum & PHY_ST_AN_OVER) != 0) {
  1744. SkHWLinkUp(pAC, IoC, Port);
  1745. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1746. if (Done != SK_AND_OK) {
  1747. /* Get PHY parameters, for debugging only */
  1748. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
  1749. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
  1750. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1751. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1752. Port, LpAb, ExtStat));
  1753. /* Try next possible mode */
  1754. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1755. SkHWLinkDown(pAC, IoC, Port);
  1756. if (Done == SK_AND_DUP_CAP) {
  1757. /* GoTo next mode */
  1758. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1759. }
  1760. return(SK_HW_PS_RESTART);
  1761. }
  1762. else {
  1763. /*
  1764. * Dummy Read interrupt status to prevent
  1765. * extra link down/ups
  1766. */
  1767. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1768. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1769. ("AutoNeg done Port %d\n", Port));
  1770. return(SK_HW_PS_LINK);
  1771. }
  1772. }
  1773. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1774. pPrt->PAutoNegTimeOut++;
  1775. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1776. /* Timeout occured */
  1777. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1778. ("AutoNeg timeout Port %d\n", Port));
  1779. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1780. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1781. /* Set Link manually up */
  1782. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1783. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1784. ("Set manual full duplex Port %d\n", Port));
  1785. }
  1786. /* Do the restart */
  1787. return(SK_HW_PS_RESTART);
  1788. }
  1789. }
  1790. else {
  1791. /* Link is up and we don't need more */
  1792. #ifdef DEBUG
  1793. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1794. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1795. ("ERROR: Lipa auto detected on port %d\n", Port));
  1796. }
  1797. #endif /* DEBUG */
  1798. /*
  1799. * Dummy Read interrupt status to prevent
  1800. * extra link down/ups
  1801. */
  1802. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1803. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1804. ("Link sync(GP), Port %d\n", Port));
  1805. SkHWLinkUp(pAC, IoC, Port);
  1806. return(SK_HW_PS_LINK);
  1807. }
  1808. return(SK_HW_PS_NONE);
  1809. } /* SkGePortCheckUpLone */
  1810. /******************************************************************************
  1811. *
  1812. * SkGePortCheckUpNat() - Check if the link is up on National PHY
  1813. *
  1814. * return:
  1815. * 0 o.k. nothing needed
  1816. * 1 Restart needed on this port
  1817. * 2 Link came up
  1818. */
  1819. static int SkGePortCheckUpNat(
  1820. SK_AC *pAC, /* Adapter Context */
  1821. SK_IOC IoC, /* IO Context */
  1822. int Port) /* Which port should be checked */
  1823. {
  1824. /* todo: National */
  1825. return(SK_HW_PS_NONE);
  1826. } /* SkGePortCheckUpNat */
  1827. #endif /* OTHER_PHY */
  1828. /******************************************************************************
  1829. *
  1830. * SkGeSirqEvent() - Event Service Routine
  1831. *
  1832. * Description:
  1833. *
  1834. * Notes:
  1835. */
  1836. int SkGeSirqEvent(
  1837. SK_AC *pAC, /* Adapter Context */
  1838. SK_IOC IoC, /* Io Context */
  1839. SK_U32 Event, /* Module specific Event */
  1840. SK_EVPARA Para) /* Event specific Parameter */
  1841. {
  1842. SK_U64 Octets;
  1843. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1844. SK_U32 Port;
  1845. SK_U32 Time;
  1846. unsigned Len;
  1847. int PortStat;
  1848. SK_U8 Val8;
  1849. Port = Para.Para32[0];
  1850. pPrt = &pAC->GIni.GP[Port];
  1851. switch (Event) {
  1852. case SK_HWEV_WATIM:
  1853. /* Check whether port came up */
  1854. PortStat = SkGePortCheckUp(pAC, IoC, Port);
  1855. switch (PortStat) {
  1856. case SK_HW_PS_RESTART:
  1857. if (pPrt->PHWLinkUp) {
  1858. /*
  1859. * Set Link to down.
  1860. */
  1861. SkHWLinkDown(pAC, IoC, Port);
  1862. /*
  1863. * Signal directly to RLMT to ensure correct
  1864. * sequence of SWITCH and RESET event.
  1865. */
  1866. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1867. }
  1868. /* Restart needed */
  1869. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1870. break;
  1871. case SK_HW_PS_LINK:
  1872. /* Signal to RLMT */
  1873. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
  1874. break;
  1875. }
  1876. /* Start again the check Timer */
  1877. if (pPrt->PHWLinkUp) {
  1878. Time = SK_WA_ACT_TIME;
  1879. }
  1880. else {
  1881. Time = SK_WA_INA_TIME;
  1882. }
  1883. /* Todo: still needed for non-XMAC PHYs??? */
  1884. /* Start workaround Errata #2 timer */
  1885. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time,
  1886. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1887. break;
  1888. case SK_HWEV_PORT_START:
  1889. if (pPrt->PHWLinkUp) {
  1890. /*
  1891. * Signal directly to RLMT to ensure correct
  1892. * sequence of SWITCH and RESET event.
  1893. */
  1894. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1895. }
  1896. SkHWLinkDown(pAC, IoC, Port);
  1897. /* Schedule Port RESET */
  1898. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1899. /* Start workaround Errata #2 timer */
  1900. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  1901. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1902. break;
  1903. case SK_HWEV_PORT_STOP:
  1904. if (pPrt->PHWLinkUp) {
  1905. /*
  1906. * Signal directly to RLMT to ensure correct
  1907. * sequence of SWITCH and RESET event.
  1908. */
  1909. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1910. }
  1911. /* Stop Workaround Timer */
  1912. SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
  1913. SkHWLinkDown(pAC, IoC, Port);
  1914. break;
  1915. case SK_HWEV_UPDATE_STAT:
  1916. /* We do NOT need to update any statistics */
  1917. break;
  1918. case SK_HWEV_CLEAR_STAT:
  1919. /* We do NOT need to clear any statistics */
  1920. for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
  1921. pPrt->PPrevRx = 0;
  1922. pPrt->PPrevFcs = 0;
  1923. pPrt->PPrevShorts = 0;
  1924. }
  1925. break;
  1926. case SK_HWEV_SET_LMODE:
  1927. Val8 = (SK_U8)Para.Para32[1];
  1928. if (pPrt->PLinkModeConf != Val8) {
  1929. /* Set New link mode */
  1930. pPrt->PLinkModeConf = Val8;
  1931. /* Restart Port */
  1932. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1933. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1934. }
  1935. break;
  1936. case SK_HWEV_SET_FLOWMODE:
  1937. Val8 = (SK_U8)Para.Para32[1];
  1938. if (pPrt->PFlowCtrlMode != Val8) {
  1939. /* Set New Flow Control mode */
  1940. pPrt->PFlowCtrlMode = Val8;
  1941. /* Restart Port */
  1942. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1943. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1944. }
  1945. break;
  1946. case SK_HWEV_SET_ROLE:
  1947. /* not possible for fiber */
  1948. if (!pAC->GIni.GICopperType) {
  1949. break;
  1950. }
  1951. Val8 = (SK_U8)Para.Para32[1];
  1952. if (pPrt->PMSMode != Val8) {
  1953. /* Set New link mode */
  1954. pPrt->PMSMode = Val8;
  1955. /* Restart Port */
  1956. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1957. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1958. }
  1959. break;
  1960. case SK_HWEV_SET_SPEED:
  1961. if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
  1962. break;
  1963. }
  1964. Val8 = (SK_U8)Para.Para32[1];
  1965. if (pPrt->PLinkSpeed != Val8) {
  1966. /* Set New Speed parameter */
  1967. pPrt->PLinkSpeed = Val8;
  1968. /* Restart Port */
  1969. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1970. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1971. }
  1972. break;
  1973. case SK_HWEV_HALFDUP_CHK:
  1974. /*
  1975. * half duplex hangup workaround.
  1976. * See packet arbiter timeout interrupt for description
  1977. */
  1978. pPrt->HalfDupTimerActive = SK_FALSE;
  1979. if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  1980. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
  1981. Len = sizeof(SK_U64);
  1982. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  1983. &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
  1984. pAC->Rlmt.Port[Port].Net->NetNumber);
  1985. if (pPrt->LastOctets == Octets) {
  1986. /* Tx hanging, a FIFO flush restarts it */
  1987. SkMacFlushTxFifo(pAC, IoC, Port);
  1988. }
  1989. }
  1990. break;
  1991. default:
  1992. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
  1993. break;
  1994. }
  1995. return(0);
  1996. } /* SkGeSirqEvent */
  1997. /******************************************************************************
  1998. *
  1999. * SkPhyIsrBcom() - PHY interrupt service routine
  2000. *
  2001. * Description: handles all interrupts from BCom PHY
  2002. *
  2003. * Returns: N/A
  2004. */
  2005. static void SkPhyIsrBcom(
  2006. SK_AC *pAC, /* Adapter Context */
  2007. SK_IOC IoC, /* Io Context */
  2008. int Port, /* Port Num = PHY Num */
  2009. SK_U16 IStatus) /* Interrupt Status */
  2010. {
  2011. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  2012. SK_EVPARA Para;
  2013. pPrt = &pAC->GIni.GP[Port];
  2014. if ((IStatus & PHY_B_IS_PSE) != 0) {
  2015. /* Incorrectable pair swap error */
  2016. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
  2017. SKERR_SIRQ_E022MSG);
  2018. }
  2019. if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
  2020. Para.Para32[0] = (SK_U32)Port;
  2021. SkHWLinkDown(pAC, IoC, Port);
  2022. /* Signal to RLMT */
  2023. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2024. /* Start workaround Errata #2 timer */
  2025. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  2026. SKGE_HWAC, SK_HWEV_WATIM, Para);
  2027. }
  2028. } /* SkPhyIsrBcom */
  2029. /******************************************************************************
  2030. *
  2031. * SkPhyIsrGmac() - PHY interrupt service routine
  2032. *
  2033. * Description: handles all interrupts from Marvell PHY
  2034. *
  2035. * Returns: N/A
  2036. */
  2037. static void SkPhyIsrGmac(
  2038. SK_AC *pAC, /* Adapter Context */
  2039. SK_IOC IoC, /* Io Context */
  2040. int Port, /* Port Num = PHY Num */
  2041. SK_U16 IStatus) /* Interrupt Status */
  2042. {
  2043. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  2044. SK_EVPARA Para;
  2045. pPrt = &pAC->GIni.GP[Port];
  2046. if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
  2047. Para.Para32[0] = (SK_U32)Port;
  2048. SkHWLinkDown(pAC, IoC, Port);
  2049. /* Signal to RLMT */
  2050. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2051. }
  2052. if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
  2053. /* Auto-Negotiation Error */
  2054. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
  2055. }
  2056. if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
  2057. /* TBD */
  2058. }
  2059. if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
  2060. /* FIFO Overflow/Underrun Error */
  2061. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
  2062. }
  2063. } /* SkPhyIsrGmac */
  2064. #ifdef OTHER_PHY
  2065. /******************************************************************************
  2066. *
  2067. * SkPhyIsrLone() - PHY interrupt service routine
  2068. *
  2069. * Description: handles all interrupts from LONE PHY
  2070. *
  2071. * Returns: N/A
  2072. */
  2073. static void SkPhyIsrLone(
  2074. SK_AC *pAC, /* Adapter Context */
  2075. SK_IOC IoC, /* Io Context */
  2076. int Port, /* Port Num = PHY Num */
  2077. SK_U16 IStatus) /* Interrupt Status */
  2078. {
  2079. SK_EVPARA Para;
  2080. if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
  2081. SkHWLinkDown(pAC, IoC, Port);
  2082. /* Signal to RLMT */
  2083. Para.Para32[0] = (SK_U32)Port;
  2084. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2085. }
  2086. } /* SkPhyIsrLone */
  2087. #endif /* OTHER_PHY */
  2088. #endif /* CONFIG_SK98 */
  2089. /* End of File */