skgesirq.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411
  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. /*
  338. * Special Interrupt handler
  339. *
  340. * The following abstract should show how this module is included
  341. * in the driver path:
  342. *
  343. * In the ISR of the driver the bits for frame transmission complete and
  344. * for receive complete are checked and handled by the driver itself.
  345. * The bits of the slow path mask are checked after that and then the
  346. * entry into the so-called "slow path" is prepared. It is an implementors
  347. * decision whether this is executed directly or just scheduled by
  348. * disabling the mask. In the interrupt service routine some events may be
  349. * generated, so it would be a good idea to call the EventDispatcher
  350. * right after this ISR.
  351. *
  352. * The Interrupt source register of the adapter is NOT read by this module.
  353. * SO if the drivers implementor needs a while loop around the
  354. * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
  355. * each loop entered.
  356. *
  357. * However, the MAC Interrupt status registers are read in a while loop.
  358. *
  359. */
  360. static const char SysKonnectFileId[] =
  361. "$Id: skgesirq.c,v 1.83 2003/02/05 15:10:59 rschmidt Exp $" ;
  362. #include "h/skdrv1st.h" /* Driver Specific Definitions */
  363. #include "h/skgepnmi.h" /* PNMI Definitions */
  364. #include "h/skrlmt.h" /* RLMT Definitions */
  365. #include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
  366. /* local function prototypes */
  367. static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int);
  368. static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int);
  369. static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int);
  370. static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
  371. static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
  372. #ifdef OTHER_PHY
  373. static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int);
  374. static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int);
  375. static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
  376. #endif /* OTHER_PHY */
  377. /*
  378. * array of Rx counter from XMAC which are checked
  379. * in AutoSense mode to check whether a link is not able to auto-negotiate.
  380. */
  381. static const SK_U16 SkGeRxRegs[]= {
  382. XM_RXF_64B,
  383. XM_RXF_127B,
  384. XM_RXF_255B,
  385. XM_RXF_511B,
  386. XM_RXF_1023B,
  387. XM_RXF_MAX_SZ
  388. } ;
  389. #ifdef __C2MAN__
  390. /*
  391. * Special IRQ function
  392. *
  393. * General Description:
  394. *
  395. */
  396. intro()
  397. {}
  398. #endif
  399. /* Define return codes of SkGePortCheckUp and CheckShort */
  400. #define SK_HW_PS_NONE 0 /* No action needed */
  401. #define SK_HW_PS_RESTART 1 /* Restart needed */
  402. #define SK_HW_PS_LINK 2 /* Link Up actions needed */
  403. /******************************************************************************
  404. *
  405. * SkHWInitDefSense() - Default Autosensing mode initialization
  406. *
  407. * Description: sets the PLinkMode for HWInit
  408. *
  409. * Returns: N/A
  410. */
  411. static void SkHWInitDefSense(
  412. SK_AC *pAC, /* adapter context */
  413. SK_IOC IoC, /* IO context */
  414. int Port) /* Port Index (MAC_1 + n) */
  415. {
  416. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  417. pPrt = &pAC->GIni.GP[Port];
  418. pPrt->PAutoNegTimeOut = 0;
  419. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  420. pPrt->PLinkMode = pPrt->PLinkModeConf;
  421. return;
  422. }
  423. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  424. ("AutoSensing: First mode %d on Port %d\n",
  425. (int)SK_LMODE_AUTOFULL, Port));
  426. pPrt->PLinkMode = SK_LMODE_AUTOFULL;
  427. return;
  428. } /* SkHWInitDefSense */
  429. /******************************************************************************
  430. *
  431. * SkHWSenseGetNext() - Get Next Autosensing Mode
  432. *
  433. * Description: gets the appropriate next mode
  434. *
  435. * Note:
  436. *
  437. */
  438. SK_U8 SkHWSenseGetNext(
  439. SK_AC *pAC, /* adapter context */
  440. SK_IOC IoC, /* IO context */
  441. int Port) /* Port Index (MAC_1 + n) */
  442. {
  443. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  444. pPrt = &pAC->GIni.GP[Port];
  445. pPrt->PAutoNegTimeOut = 0;
  446. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  447. /* Leave all as configured */
  448. return(pPrt->PLinkModeConf);
  449. }
  450. if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) {
  451. /* Return next mode AUTOBOTH */
  452. return(SK_LMODE_AUTOBOTH);
  453. }
  454. /* Return default autofull */
  455. return(SK_LMODE_AUTOFULL);
  456. } /* SkHWSenseGetNext */
  457. /******************************************************************************
  458. *
  459. * SkHWSenseSetNext() - Autosensing Set next mode
  460. *
  461. * Description: sets the appropriate next mode
  462. *
  463. * Returns: N/A
  464. */
  465. void SkHWSenseSetNext(
  466. SK_AC *pAC, /* adapter context */
  467. SK_IOC IoC, /* IO context */
  468. int Port, /* Port Index (MAC_1 + n) */
  469. SK_U8 NewMode) /* New Mode to be written in sense mode */
  470. {
  471. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  472. pPrt = &pAC->GIni.GP[Port];
  473. pPrt->PAutoNegTimeOut = 0;
  474. if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
  475. return;
  476. }
  477. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  478. ("AutoSensing: next mode %d on Port %d\n",
  479. (int)NewMode, Port));
  480. pPrt->PLinkMode = NewMode;
  481. return;
  482. } /* SkHWSenseSetNext */
  483. /******************************************************************************
  484. *
  485. * SkHWLinkDown() - Link Down handling
  486. *
  487. * Description: handles the hardware link down signal
  488. *
  489. * Returns: N/A
  490. */
  491. void SkHWLinkDown(
  492. SK_AC *pAC, /* adapter context */
  493. SK_IOC IoC, /* IO context */
  494. int Port) /* Port Index (MAC_1 + n) */
  495. {
  496. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  497. pPrt = &pAC->GIni.GP[Port];
  498. /* Disable all MAC interrupts */
  499. SkMacIrqDisable(pAC, IoC, Port);
  500. /* Disable Receiver and Transmitter */
  501. SkMacRxTxDisable(pAC, IoC, Port);
  502. /* Init default sense mode */
  503. SkHWInitDefSense(pAC, IoC, Port);
  504. if (!pPrt->PHWLinkUp) {
  505. return;
  506. }
  507. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  508. ("Link down Port %d\n", Port));
  509. /* Set Link to DOWN */
  510. pPrt->PHWLinkUp = SK_FALSE;
  511. /* Reset Port stati */
  512. pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
  513. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  514. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
  515. /* Re-init Phy especially when the AutoSense default is set now */
  516. SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
  517. /* GP0: used for workaround of Rev. C Errata 2 */
  518. /* Do NOT signal to RLMT */
  519. /* Do NOT start the timer here */
  520. } /* SkHWLinkDown */
  521. /******************************************************************************
  522. *
  523. * SkHWLinkUp() - Link Up handling
  524. *
  525. * Description: handles the hardware link up signal
  526. *
  527. * Returns: N/A
  528. */
  529. void SkHWLinkUp(
  530. SK_AC *pAC, /* adapter context */
  531. SK_IOC IoC, /* IO context */
  532. int Port) /* Port Index (MAC_1 + n) */
  533. {
  534. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  535. pPrt = &pAC->GIni.GP[Port];
  536. if (pPrt->PHWLinkUp) {
  537. /* We do NOT need to proceed on active link */
  538. return;
  539. }
  540. pPrt->PHWLinkUp = SK_TRUE;
  541. pPrt->PAutoNegFail = SK_FALSE;
  542. pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
  543. if (pPrt->PLinkMode != SK_LMODE_AUTOHALF &&
  544. pPrt->PLinkMode != SK_LMODE_AUTOFULL &&
  545. pPrt->PLinkMode != SK_LMODE_AUTOBOTH) {
  546. /* Link is up and no Auto-negotiation should be done */
  547. /* Link speed should be the configured one */
  548. switch (pPrt->PLinkSpeed) {
  549. case SK_LSPEED_AUTO:
  550. /* default is 1000 Mbps */
  551. case SK_LSPEED_1000MBPS:
  552. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
  553. break;
  554. case SK_LSPEED_100MBPS:
  555. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
  556. break;
  557. case SK_LSPEED_10MBPS:
  558. pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
  559. break;
  560. }
  561. /* Set Link Mode Status */
  562. if (pPrt->PLinkMode == SK_LMODE_FULL) {
  563. pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
  564. }
  565. else {
  566. pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;
  567. }
  568. /* No flow control without auto-negotiation */
  569. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  570. /* enable Rx/Tx */
  571. SkMacRxTxEnable(pAC, IoC, Port);
  572. }
  573. } /* SkHWLinkUp */
  574. /******************************************************************************
  575. *
  576. * SkMacParity() - MAC parity workaround
  577. *
  578. * Description: handles MAC parity errors correctly
  579. *
  580. * Returns: N/A
  581. */
  582. static void SkMacParity(
  583. SK_AC *pAC, /* adapter context */
  584. SK_IOC IoC, /* IO context */
  585. int Port) /* Port Index of the port failed */
  586. {
  587. SK_EVPARA Para;
  588. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  589. SK_U32 TxMax; /* TxMax Counter */
  590. pPrt = &pAC->GIni.GP[Port];
  591. /* Clear IRQ Tx Parity Error */
  592. if (pAC->GIni.GIGenesis) {
  593. SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
  594. }
  595. else {
  596. /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
  597. SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
  598. (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
  599. }
  600. if (pPrt->PCheckPar) {
  601. if (Port == MAC_1) {
  602. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
  603. }
  604. else {
  605. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
  606. }
  607. Para.Para64 = Port;
  608. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  609. Para.Para32[0] = Port;
  610. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  611. return;
  612. }
  613. /* Check whether frames with a size of 1k were sent */
  614. if (pAC->GIni.GIGenesis) {
  615. /* Snap statistic counters */
  616. (void)SkXmUpdateStats(pAC, IoC, Port);
  617. (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
  618. }
  619. else {
  620. (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
  621. }
  622. if (TxMax > 0) {
  623. /* From now on check the parity */
  624. pPrt->PCheckPar = SK_TRUE;
  625. }
  626. } /* SkMacParity */
  627. /******************************************************************************
  628. *
  629. * SkGeHwErr() - Hardware Error service routine
  630. *
  631. * Description: handles all HW Error interrupts
  632. *
  633. * Returns: N/A
  634. */
  635. static void SkGeHwErr(
  636. SK_AC *pAC, /* adapter context */
  637. SK_IOC IoC, /* IO context */
  638. SK_U32 HwStatus) /* Interrupt status word */
  639. {
  640. SK_EVPARA Para;
  641. SK_U16 Word;
  642. if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
  643. /* PCI Errors occured */
  644. if ((HwStatus & IS_IRQ_STAT) != 0) {
  645. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
  646. }
  647. else {
  648. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
  649. }
  650. /* Reset all bits in the PCI STATUS register */
  651. SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
  652. SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
  653. SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
  654. SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
  655. Para.Para64 = 0;
  656. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  657. }
  658. if (pAC->GIni.GIGenesis) {
  659. if ((HwStatus & IS_NO_STAT_M1) != 0) {
  660. /* Ignore it */
  661. /* This situation is also indicated in the descriptor */
  662. SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
  663. }
  664. if ((HwStatus & IS_NO_STAT_M2) != 0) {
  665. /* Ignore it */
  666. /* This situation is also indicated in the descriptor */
  667. SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
  668. }
  669. if ((HwStatus & IS_NO_TIST_M1) != 0) {
  670. /* Ignore it */
  671. /* This situation is also indicated in the descriptor */
  672. SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
  673. }
  674. if ((HwStatus & IS_NO_TIST_M2) != 0) {
  675. /* Ignore it */
  676. /* This situation is also indicated in the descriptor */
  677. SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
  678. }
  679. }
  680. else { /* YUKON */
  681. /* This is necessary only for Rx timing measurements */
  682. if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
  683. /* Clear Time Stamp Timer IRQ */
  684. SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
  685. }
  686. if ((HwStatus & IS_IRQ_SENSOR) != 0) {
  687. /* Clear I2C IRQ */
  688. SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
  689. }
  690. }
  691. if ((HwStatus & IS_RAM_RD_PAR) != 0) {
  692. SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
  693. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
  694. Para.Para64 = 0;
  695. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  696. }
  697. if ((HwStatus & IS_RAM_WR_PAR) != 0) {
  698. SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
  699. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
  700. Para.Para64 = 0;
  701. SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
  702. }
  703. if ((HwStatus & IS_M1_PAR_ERR) != 0) {
  704. SkMacParity(pAC, IoC, MAC_1);
  705. }
  706. if ((HwStatus & IS_M2_PAR_ERR) != 0) {
  707. SkMacParity(pAC, IoC, MAC_2);
  708. }
  709. if ((HwStatus & IS_R1_PAR_ERR) != 0) {
  710. /* Clear IRQ */
  711. SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
  712. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
  713. Para.Para64 = MAC_1;
  714. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  715. Para.Para32[0] = MAC_1;
  716. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  717. }
  718. if ((HwStatus & IS_R2_PAR_ERR) != 0) {
  719. /* Clear IRQ */
  720. SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
  721. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
  722. Para.Para64 = MAC_2;
  723. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  724. Para.Para32[0] = MAC_2;
  725. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  726. }
  727. } /* SkGeHwErr */
  728. /******************************************************************************
  729. *
  730. * SkGeSirqIsr() - Special Interrupt Service Routine
  731. *
  732. * Description: handles all non data transfer specific interrupts (slow path)
  733. *
  734. * Returns: N/A
  735. */
  736. void SkGeSirqIsr(
  737. SK_AC *pAC, /* adapter context */
  738. SK_IOC IoC, /* IO context */
  739. SK_U32 Istatus) /* Interrupt status word */
  740. {
  741. SK_EVPARA Para;
  742. SK_U32 RegVal32; /* Read register value */
  743. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  744. unsigned Len;
  745. SK_U64 Octets;
  746. SK_U16 PhyInt;
  747. SK_U16 PhyIMsk;
  748. int i;
  749. if ((Istatus & IS_HW_ERR) != 0) {
  750. /* read the HW Error Interrupt source */
  751. SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
  752. SkGeHwErr(pAC, IoC, RegVal32);
  753. }
  754. /*
  755. * Packet Timeout interrupts
  756. */
  757. /* Check whether MACs are correctly initialized */
  758. if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
  759. pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
  760. /* MAC 1 was not initialized but Packet timeout occured */
  761. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
  762. SKERR_SIRQ_E004MSG);
  763. }
  764. if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
  765. pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
  766. /* MAC 2 was not initialized but Packet timeout occured */
  767. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
  768. SKERR_SIRQ_E005MSG);
  769. }
  770. if ((Istatus & IS_PA_TO_RX1) != 0) {
  771. /* Means network is filling us up */
  772. SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
  773. SKERR_SIRQ_E002MSG);
  774. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
  775. }
  776. if ((Istatus & IS_PA_TO_RX2) != 0) {
  777. /* Means network is filling us up */
  778. SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
  779. SKERR_SIRQ_E003MSG);
  780. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
  781. }
  782. if ((Istatus & IS_PA_TO_TX1) != 0) {
  783. pPrt = &pAC->GIni.GP[0];
  784. /* May be a normal situation in a server with a slow network */
  785. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
  786. /*
  787. * workaround: if in half duplex mode, check for Tx hangup.
  788. * Read number of TX'ed bytes, wait for 10 ms, then compare
  789. * the number with current value. If nothing changed, we assume
  790. * that Tx is hanging and do a FIFO flush (see event routine).
  791. */
  792. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  793. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
  794. !pPrt->HalfDupTimerActive) {
  795. /*
  796. * many more pack. arb. timeouts may come in between,
  797. * we ignore those
  798. */
  799. pPrt->HalfDupTimerActive = SK_TRUE;
  800. Len = sizeof(SK_U64);
  801. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  802. &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),
  803. pAC->Rlmt.Port[0].Net->NetNumber);
  804. pPrt->LastOctets = Octets;
  805. Para.Para32[0] = 0;
  806. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  807. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  808. }
  809. }
  810. if ((Istatus & IS_PA_TO_TX2) != 0) {
  811. pPrt = &pAC->GIni.GP[1];
  812. /* May be a normal situation in a server with a slow network */
  813. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
  814. /* workaround: see above */
  815. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  816. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
  817. !pPrt->HalfDupTimerActive) {
  818. pPrt->HalfDupTimerActive = SK_TRUE;
  819. Len = sizeof(SK_U64);
  820. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  821. &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),
  822. pAC->Rlmt.Port[1].Net->NetNumber);
  823. pPrt->LastOctets = Octets;
  824. Para.Para32[0] = 1;
  825. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  826. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  827. }
  828. }
  829. /* Check interrupts of the particular queues */
  830. if ((Istatus & IS_R1_C) != 0) {
  831. /* Clear IRQ */
  832. SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
  833. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
  834. SKERR_SIRQ_E006MSG);
  835. Para.Para64 = MAC_1;
  836. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  837. Para.Para32[0] = MAC_1;
  838. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  839. }
  840. if ((Istatus & IS_R2_C) != 0) {
  841. /* Clear IRQ */
  842. SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
  843. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
  844. SKERR_SIRQ_E007MSG);
  845. Para.Para64 = MAC_2;
  846. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  847. Para.Para32[0] = MAC_2;
  848. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  849. }
  850. if ((Istatus & IS_XS1_C) != 0) {
  851. /* Clear IRQ */
  852. SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
  853. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
  854. SKERR_SIRQ_E008MSG);
  855. Para.Para64 = MAC_1;
  856. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  857. Para.Para32[0] = MAC_1;
  858. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  859. }
  860. if ((Istatus & IS_XA1_C) != 0) {
  861. /* Clear IRQ */
  862. SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
  863. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
  864. SKERR_SIRQ_E009MSG);
  865. Para.Para64 = MAC_1;
  866. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  867. Para.Para32[0] = MAC_1;
  868. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  869. }
  870. if ((Istatus & IS_XS2_C) != 0) {
  871. /* Clear IRQ */
  872. SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
  873. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
  874. SKERR_SIRQ_E010MSG);
  875. Para.Para64 = MAC_2;
  876. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  877. Para.Para32[0] = MAC_2;
  878. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  879. }
  880. if ((Istatus & IS_XA2_C) != 0) {
  881. /* Clear IRQ */
  882. SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
  883. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
  884. SKERR_SIRQ_E011MSG);
  885. Para.Para64 = MAC_2;
  886. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  887. Para.Para32[0] = MAC_2;
  888. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  889. }
  890. /* External reg interrupt */
  891. if ((Istatus & IS_EXT_REG) != 0) {
  892. /* Test IRQs from PHY */
  893. for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
  894. pPrt = &pAC->GIni.GP[i];
  895. if (pPrt->PState == SK_PRT_RESET) {
  896. continue;
  897. }
  898. switch (pPrt->PhyType) {
  899. case SK_PHY_XMAC:
  900. break;
  901. case SK_PHY_BCOM:
  902. SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
  903. SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk);
  904. if ((PhyInt & ~PhyIMsk) != 0) {
  905. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  906. ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n",
  907. i, PhyInt, PhyIMsk));
  908. SkPhyIsrBcom(pAC, IoC, i, PhyInt);
  909. }
  910. break;
  911. case SK_PHY_MARV_COPPER:
  912. case SK_PHY_MARV_FIBER:
  913. SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
  914. SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk);
  915. if ((PhyInt & PhyIMsk) != 0) {
  916. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  917. ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n",
  918. i, PhyInt, PhyIMsk));
  919. SkPhyIsrGmac(pAC, IoC, i, PhyInt);
  920. }
  921. break;
  922. #ifdef OTHER_PHY
  923. case SK_PHY_LONE:
  924. SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
  925. SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk);
  926. if ((PhyInt & PhyIMsk) != 0) {
  927. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  928. ("Port %d Lone Int: %x Mask: %x\n",
  929. i, PhyInt, PhyIMsk));
  930. SkPhyIsrLone(pAC, IoC, i, PhyInt);
  931. }
  932. break;
  933. case SK_PHY_NAT:
  934. /* todo: National */
  935. break;
  936. #endif /* OTHER_PHY */
  937. }
  938. }
  939. }
  940. /* I2C Ready interrupt */
  941. if ((Istatus & IS_I2C_READY) != 0) {
  942. SkI2cIsr(pAC, IoC);
  943. }
  944. if ((Istatus & IS_LNK_SYNC_M1) != 0) {
  945. /*
  946. * We do NOT need the Link Sync interrupt, because it shows
  947. * us only a link going down.
  948. */
  949. /* clear interrupt */
  950. SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
  951. }
  952. /* Check MAC after link sync counter */
  953. if ((Istatus & IS_MAC1) != 0) {
  954. /* IRQ from MAC 1 */
  955. SkMacIrq(pAC, IoC, MAC_1);
  956. }
  957. if ((Istatus & IS_LNK_SYNC_M2) != 0) {
  958. /*
  959. * We do NOT need the Link Sync interrupt, because it shows
  960. * us only a link going down.
  961. */
  962. /* clear interrupt */
  963. SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
  964. }
  965. /* Check MAC after link sync counter */
  966. if ((Istatus & IS_MAC2) != 0) {
  967. /* IRQ from MAC 2 */
  968. SkMacIrq(pAC, IoC, MAC_2);
  969. }
  970. /* Timer interrupt (served last) */
  971. if ((Istatus & IS_TIMINT) != 0) {
  972. SkHwtIsr(pAC, IoC);
  973. }
  974. } /* SkGeSirqIsr */
  975. /******************************************************************************
  976. *
  977. * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
  978. *
  979. * return:
  980. * 0 o.k. nothing needed
  981. * 1 Restart needed on this port
  982. */
  983. static int SkGePortCheckShorts(
  984. SK_AC *pAC, /* Adapter Context */
  985. SK_IOC IoC, /* IO Context */
  986. int Port) /* Which port should be checked */
  987. {
  988. SK_U32 Shorts; /* Short Event Counter */
  989. SK_U32 CheckShorts; /* Check value for Short Event Counter */
  990. SK_U64 RxCts; /* Rx Counter (packets on network) */
  991. SK_U32 RxTmp; /* Rx temp. Counter */
  992. SK_U32 FcsErrCts; /* FCS Error Counter */
  993. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  994. int Rtv; /* Return value */
  995. int i;
  996. pPrt = &pAC->GIni.GP[Port];
  997. /* Default: no action */
  998. Rtv = SK_HW_PS_NONE;
  999. (void)SkXmUpdateStats(pAC, IoC, Port);
  1000. /* Extra precaution: check for short Event counter */
  1001. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  1002. /*
  1003. * Read Rx counter (packets seen on the network and not necessarily
  1004. * really received.
  1005. */
  1006. RxCts = 0;
  1007. for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
  1008. (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
  1009. RxCts += (SK_U64)RxTmp;
  1010. }
  1011. /* On default: check shorts against zero */
  1012. CheckShorts = 0;
  1013. /* Extra precaution on active links */
  1014. if (pPrt->PHWLinkUp) {
  1015. /* Reset Link Restart counter */
  1016. pPrt->PLinkResCt = 0;
  1017. pPrt->PAutoNegTOCt = 0;
  1018. /* If link is up check for 2 */
  1019. CheckShorts = 2;
  1020. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
  1021. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1022. pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
  1023. (pPrt->PLinkMode == SK_LMODE_HALF ||
  1024. pPrt->PLinkMode == SK_LMODE_FULL)) {
  1025. /*
  1026. * This is autosensing and we are in the fallback
  1027. * manual full/half duplex mode.
  1028. */
  1029. if (RxCts == pPrt->PPrevRx) {
  1030. /* Nothing received, restart link */
  1031. pPrt->PPrevFcs = FcsErrCts;
  1032. pPrt->PPrevShorts = Shorts;
  1033. return(SK_HW_PS_RESTART);
  1034. }
  1035. else {
  1036. pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
  1037. }
  1038. }
  1039. if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
  1040. (!(FcsErrCts - pPrt->PPrevFcs))) {
  1041. /*
  1042. * Note: The compare with zero above has to be done the way shown,
  1043. * otherwise the Linux driver will have a problem.
  1044. */
  1045. /*
  1046. * We received a bunch of frames or no CRC error occured on the
  1047. * network -> ok.
  1048. */
  1049. pPrt->PPrevRx = RxCts;
  1050. pPrt->PPrevFcs = FcsErrCts;
  1051. pPrt->PPrevShorts = Shorts;
  1052. return(SK_HW_PS_NONE);
  1053. }
  1054. pPrt->PPrevFcs = FcsErrCts;
  1055. }
  1056. if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
  1057. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1058. ("Short Event Count Restart Port %d \n", Port));
  1059. Rtv = SK_HW_PS_RESTART;
  1060. }
  1061. pPrt->PPrevShorts = Shorts;
  1062. pPrt->PPrevRx = RxCts;
  1063. return(Rtv);
  1064. } /* SkGePortCheckShorts */
  1065. /******************************************************************************
  1066. *
  1067. * SkGePortCheckUp() - Check if the link is up
  1068. *
  1069. * return:
  1070. * 0 o.k. nothing needed
  1071. * 1 Restart needed on this port
  1072. * 2 Link came up
  1073. */
  1074. static int SkGePortCheckUp(
  1075. SK_AC *pAC, /* Adapter Context */
  1076. SK_IOC IoC, /* IO Context */
  1077. int Port) /* Which port should be checked */
  1078. {
  1079. switch (pAC->GIni.GP[Port].PhyType) {
  1080. case SK_PHY_XMAC:
  1081. return(SkGePortCheckUpXmac(pAC, IoC, Port));
  1082. case SK_PHY_BCOM:
  1083. return(SkGePortCheckUpBcom(pAC, IoC, Port));
  1084. case SK_PHY_MARV_COPPER:
  1085. case SK_PHY_MARV_FIBER:
  1086. return(SkGePortCheckUpGmac(pAC, IoC, Port));
  1087. #ifdef OTHER_PHY
  1088. case SK_PHY_LONE:
  1089. return(SkGePortCheckUpLone(pAC, IoC, Port));
  1090. case SK_PHY_NAT:
  1091. return(SkGePortCheckUpNat(pAC, IoC, Port));
  1092. #endif /* OTHER_PHY */
  1093. }
  1094. return(SK_HW_PS_NONE);
  1095. } /* SkGePortCheckUp */
  1096. /******************************************************************************
  1097. *
  1098. * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
  1099. *
  1100. * return:
  1101. * 0 o.k. nothing needed
  1102. * 1 Restart needed on this port
  1103. * 2 Link came up
  1104. */
  1105. static int SkGePortCheckUpXmac(
  1106. SK_AC *pAC, /* Adapter Context */
  1107. SK_IOC IoC, /* IO Context */
  1108. int Port) /* Which port should be checked */
  1109. {
  1110. SK_U32 Shorts; /* Short Event Counter */
  1111. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1112. int Done;
  1113. SK_U32 GpReg; /* General Purpose register value */
  1114. SK_U16 Isrc; /* Interrupt source register */
  1115. SK_U16 IsrcSum; /* Interrupt source register sum */
  1116. SK_U16 LpAb; /* Link Partner Ability */
  1117. SK_U16 ResAb; /* Resolved Ability */
  1118. SK_U16 ExtStat; /* Extended Status Register */
  1119. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1120. SK_U8 NextMode; /* Next AutoSensing Mode */
  1121. pPrt = &pAC->GIni.GP[Port];
  1122. if (pPrt->PHWLinkUp) {
  1123. if (pPrt->PhyType != SK_PHY_XMAC) {
  1124. return(SK_HW_PS_NONE);
  1125. }
  1126. else {
  1127. return(SkGePortCheckShorts(pAC, IoC, Port));
  1128. }
  1129. }
  1130. IsrcSum = pPrt->PIsave;
  1131. pPrt->PIsave = 0;
  1132. /* Now wait for each port's link */
  1133. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1134. AutoNeg = SK_FALSE;
  1135. }
  1136. else {
  1137. AutoNeg = SK_TRUE;
  1138. }
  1139. if (pPrt->PLinkBroken) {
  1140. /* Link was broken */
  1141. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  1142. if ((GpReg & XM_GP_INP_ASS) == 0) {
  1143. /* The Link is in sync */
  1144. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1145. IsrcSum |= Isrc;
  1146. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  1147. if ((Isrc & XM_IS_INP_ASS) == 0) {
  1148. /* It has been in sync since last time */
  1149. /* Restart the PORT */
  1150. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1151. ("Link in sync Restart Port %d\n", Port));
  1152. (void)SkXmUpdateStats(pAC, IoC, Port);
  1153. /* We now need to reinitialize the PrevShorts counter */
  1154. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  1155. pPrt->PPrevShorts = Shorts;
  1156. pPrt->PLinkBroken = SK_FALSE;
  1157. /*
  1158. * Link Restart Workaround:
  1159. * it may be possible that the other Link side
  1160. * restarts its link as well an we detect
  1161. * another LinkBroken. To prevent this
  1162. * happening we check for a maximum number
  1163. * of consecutive restart. If those happens,
  1164. * we do NOT restart the active link and
  1165. * check whether the link is now o.k.
  1166. */
  1167. pPrt->PLinkResCt++;
  1168. pPrt->PAutoNegTimeOut = 0;
  1169. if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
  1170. return(SK_HW_PS_RESTART);
  1171. }
  1172. pPrt->PLinkResCt = 0;
  1173. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1174. ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
  1175. }
  1176. else {
  1177. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  1178. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1179. ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
  1180. /* Do nothing more if link is broken */
  1181. return(SK_HW_PS_NONE);
  1182. }
  1183. }
  1184. else {
  1185. /* Do nothing more if link is broken */
  1186. return(SK_HW_PS_NONE);
  1187. }
  1188. }
  1189. else {
  1190. /* Link was not broken, check if it is */
  1191. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1192. IsrcSum |= Isrc;
  1193. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1194. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1195. IsrcSum |= Isrc;
  1196. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1197. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1198. IsrcSum |= Isrc;
  1199. if ((Isrc & XM_IS_INP_ASS) != 0) {
  1200. pPrt->PLinkBroken = SK_TRUE;
  1201. /* Re-Init Link partner Autoneg flag */
  1202. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  1203. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1204. ("Link broken Port %d\n", Port));
  1205. /* Cable removed-> reinit sense mode */
  1206. SkHWInitDefSense(pAC, IoC, Port);
  1207. return(SK_HW_PS_RESTART);
  1208. }
  1209. }
  1210. }
  1211. else {
  1212. SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
  1213. if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
  1214. return(SK_HW_PS_RESTART);
  1215. }
  1216. }
  1217. }
  1218. /*
  1219. * here we usually can check whether the link is in sync and
  1220. * auto-negotiation is done.
  1221. */
  1222. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  1223. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  1224. IsrcSum |= Isrc;
  1225. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  1226. if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
  1227. if ((GpReg & XM_GP_INP_ASS) == 0) {
  1228. /* Save Auto-negotiation Done interrupt only if link is in sync */
  1229. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  1230. }
  1231. #ifdef DEBUG
  1232. if ((pPrt->PIsave & XM_IS_AND) != 0) {
  1233. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1234. ("AutoNeg done rescheduled Port %d\n", Port));
  1235. }
  1236. #endif /* DEBUG */
  1237. return(SK_HW_PS_NONE);
  1238. }
  1239. if (AutoNeg) {
  1240. if ((IsrcSum & XM_IS_AND) != 0) {
  1241. SkHWLinkUp(pAC, IoC, Port);
  1242. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1243. if (Done != SK_AND_OK) {
  1244. /* Get PHY parameters, for debugging only */
  1245. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
  1246. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
  1247. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1248. ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
  1249. Port, LpAb, ResAb));
  1250. /* Try next possible mode */
  1251. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1252. SkHWLinkDown(pAC, IoC, Port);
  1253. if (Done == SK_AND_DUP_CAP) {
  1254. /* GoTo next mode */
  1255. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1256. }
  1257. return(SK_HW_PS_RESTART);
  1258. }
  1259. /*
  1260. * Dummy Read extended status to prevent extra link down/ups
  1261. * (clear Page Received bit if set)
  1262. */
  1263. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
  1264. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1265. ("AutoNeg done Port %d\n", Port));
  1266. return(SK_HW_PS_LINK);
  1267. }
  1268. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1269. pPrt->PAutoNegTimeOut++;
  1270. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1271. /* Increase the Timeout counter */
  1272. pPrt->PAutoNegTOCt++;
  1273. /* Timeout occured */
  1274. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1275. ("AutoNeg timeout Port %d\n", Port));
  1276. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1277. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1278. /* Set Link manually up */
  1279. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1280. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1281. ("Set manual full duplex Port %d\n", Port));
  1282. }
  1283. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1284. pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
  1285. pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
  1286. /*
  1287. * This is rather complicated.
  1288. * we need to check here whether the LIPA_AUTO
  1289. * we saw before is false alert. We saw at one
  1290. * switch ( SR8800) that on boot time it sends
  1291. * just one auto-neg packet and does no further
  1292. * auto-negotiation.
  1293. * Solution: we restart the autosensing after
  1294. * a few timeouts.
  1295. */
  1296. pPrt->PAutoNegTOCt = 0;
  1297. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  1298. SkHWInitDefSense(pAC, IoC, Port);
  1299. }
  1300. /* Do the restart */
  1301. return(SK_HW_PS_RESTART);
  1302. }
  1303. }
  1304. else {
  1305. /* Link is up and we don't need more */
  1306. #ifdef DEBUG
  1307. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1308. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1309. ("ERROR: Lipa auto detected on port %d\n", Port));
  1310. }
  1311. #endif /* DEBUG */
  1312. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1313. ("Link sync(GP), Port %d\n", Port));
  1314. SkHWLinkUp(pAC, IoC, Port);
  1315. /*
  1316. * Link sync (GP) and so assume a good connection. But if not received
  1317. * a bunch of frames received in a time slot (maybe broken tx cable)
  1318. * the port is restart.
  1319. */
  1320. return(SK_HW_PS_LINK);
  1321. }
  1322. return(SK_HW_PS_NONE);
  1323. } /* SkGePortCheckUpXmac */
  1324. /******************************************************************************
  1325. *
  1326. * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
  1327. *
  1328. * return:
  1329. * 0 o.k. nothing needed
  1330. * 1 Restart needed on this port
  1331. * 2 Link came up
  1332. */
  1333. static int SkGePortCheckUpBcom(
  1334. SK_AC *pAC, /* Adapter Context */
  1335. SK_IOC IoC, /* IO Context */
  1336. int Port) /* Which port should be checked */
  1337. {
  1338. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1339. int Done;
  1340. SK_U16 Isrc; /* Interrupt source register */
  1341. SK_U16 PhyStat; /* Phy Status Register */
  1342. SK_U16 ResAb; /* Master/Slave resolution */
  1343. SK_U16 Ctrl; /* Broadcom control flags */
  1344. #ifdef DEBUG
  1345. SK_U16 LpAb;
  1346. SK_U16 ExtStat;
  1347. #endif /* DEBUG */
  1348. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1349. pPrt = &pAC->GIni.GP[Port];
  1350. /* Check for No HCD Link events (#10523) */
  1351. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
  1352. #ifdef xDEBUG
  1353. if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
  1354. (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
  1355. SK_U32 Stat1, Stat2, Stat3;
  1356. Stat1 = 0;
  1357. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1358. CMSMPrintString(
  1359. pAC->pConfigTable,
  1360. MSG_TYPE_RUNTIME_INFO,
  1361. "CheckUp1 - Stat: %x, Mask: %x",
  1362. (void *)Isrc,
  1363. (void *)Stat1);
  1364. Stat1 = 0;
  1365. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1366. Stat2 = 0;
  1367. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
  1368. Stat1 = Stat1 << 16 | Stat2;
  1369. Stat2 = 0;
  1370. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1371. Stat3 = 0;
  1372. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1373. Stat2 = Stat2 << 16 | Stat3;
  1374. CMSMPrintString(
  1375. pAC->pConfigTable,
  1376. MSG_TYPE_RUNTIME_INFO,
  1377. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1378. (void *)Stat1,
  1379. (void *)Stat2);
  1380. Stat1 = 0;
  1381. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1382. Stat2 = 0;
  1383. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1384. Stat1 = Stat1 << 16 | Stat2;
  1385. Stat2 = 0;
  1386. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1387. Stat3 = 0;
  1388. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
  1389. Stat2 = Stat2 << 16 | Stat3;
  1390. CMSMPrintString(
  1391. pAC->pConfigTable,
  1392. MSG_TYPE_RUNTIME_INFO,
  1393. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1394. (void *)Stat1,
  1395. (void *)Stat2);
  1396. Stat1 = 0;
  1397. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1398. Stat2 = 0;
  1399. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1400. Stat1 = Stat1 << 16 | Stat2;
  1401. Stat2 = 0;
  1402. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1403. Stat3 = 0;
  1404. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1405. Stat2 = Stat2 << 16 | Stat3;
  1406. CMSMPrintString(
  1407. pAC->pConfigTable,
  1408. MSG_TYPE_RUNTIME_INFO,
  1409. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1410. (void *)Stat1,
  1411. (void *)Stat2);
  1412. }
  1413. #endif /* DEBUG */
  1414. if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
  1415. /*
  1416. * Workaround BCom Errata:
  1417. * enable and disable loopback mode if "NO HCD" occurs.
  1418. */
  1419. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
  1420. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1421. (SK_U16)(Ctrl | PHY_CT_LOOP));
  1422. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1423. (SK_U16)(Ctrl & ~PHY_CT_LOOP));
  1424. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1425. ("No HCD Link event, Port %d\n", Port));
  1426. #ifdef xDEBUG
  1427. CMSMPrintString(
  1428. pAC->pConfigTable,
  1429. MSG_TYPE_RUNTIME_INFO,
  1430. "No HCD link event, port %d.",
  1431. (void *)Port,
  1432. (void *)NULL);
  1433. #endif /* DEBUG */
  1434. }
  1435. /* Not obsolete: link status bit is latched to 0 and autoclearing! */
  1436. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1437. if (pPrt->PHWLinkUp) {
  1438. return(SK_HW_PS_NONE);
  1439. }
  1440. #ifdef xDEBUG
  1441. {
  1442. SK_U32 Stat1, Stat2, Stat3;
  1443. Stat1 = 0;
  1444. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1445. CMSMPrintString(
  1446. pAC->pConfigTable,
  1447. MSG_TYPE_RUNTIME_INFO,
  1448. "CheckUp1a - Stat: %x, Mask: %x",
  1449. (void *)Isrc,
  1450. (void *)Stat1);
  1451. Stat1 = 0;
  1452. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1453. Stat2 = 0;
  1454. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1455. Stat1 = Stat1 << 16 | PhyStat;
  1456. Stat2 = 0;
  1457. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1458. Stat3 = 0;
  1459. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1460. Stat2 = Stat2 << 16 | Stat3;
  1461. CMSMPrintString(
  1462. pAC->pConfigTable,
  1463. MSG_TYPE_RUNTIME_INFO,
  1464. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1465. (void *)Stat1,
  1466. (void *)Stat2);
  1467. Stat1 = 0;
  1468. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1469. Stat2 = 0;
  1470. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1471. Stat1 = Stat1 << 16 | Stat2;
  1472. Stat2 = 0;
  1473. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1474. Stat3 = 0;
  1475. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1476. Stat2 = Stat2 << 16 | ResAb;
  1477. CMSMPrintString(
  1478. pAC->pConfigTable,
  1479. MSG_TYPE_RUNTIME_INFO,
  1480. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1481. (void *)Stat1,
  1482. (void *)Stat2);
  1483. Stat1 = 0;
  1484. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1485. Stat2 = 0;
  1486. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1487. Stat1 = Stat1 << 16 | Stat2;
  1488. Stat2 = 0;
  1489. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1490. Stat3 = 0;
  1491. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1492. Stat2 = Stat2 << 16 | Stat3;
  1493. CMSMPrintString(
  1494. pAC->pConfigTable,
  1495. MSG_TYPE_RUNTIME_INFO,
  1496. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1497. (void *)Stat1,
  1498. (void *)Stat2);
  1499. }
  1500. #endif /* DEBUG */
  1501. /* Now wait for each port's link */
  1502. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1503. AutoNeg = SK_FALSE;
  1504. }
  1505. else {
  1506. AutoNeg = SK_TRUE;
  1507. }
  1508. /*
  1509. * Here we usually can check whether the link is in sync and
  1510. * auto-negotiation is done.
  1511. */
  1512. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1513. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1514. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1515. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1516. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1517. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1518. /* Error */
  1519. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1520. ("Master/Slave Fault port %d\n", Port));
  1521. pPrt->PAutoNegFail = SK_TRUE;
  1522. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1523. return(SK_HW_PS_RESTART);
  1524. }
  1525. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1526. return(SK_HW_PS_NONE);
  1527. }
  1528. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1529. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1530. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1531. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1532. if (AutoNeg) {
  1533. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1534. SkHWLinkUp(pAC, IoC, Port);
  1535. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1536. if (Done != SK_AND_OK) {
  1537. #ifdef DEBUG
  1538. /* Get PHY parameters, for debugging only */
  1539. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
  1540. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
  1541. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1542. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1543. Port, LpAb, ExtStat));
  1544. #endif /* DEBUG */
  1545. return(SK_HW_PS_RESTART);
  1546. }
  1547. else {
  1548. #ifdef xDEBUG
  1549. /* Dummy read ISR to prevent extra link downs/ups */
  1550. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1551. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1552. CMSMPrintString(
  1553. pAC->pConfigTable,
  1554. MSG_TYPE_RUNTIME_INFO,
  1555. "CheckUp2 - Stat: %x",
  1556. (void *)ExtStat,
  1557. (void *)NULL);
  1558. }
  1559. #endif /* DEBUG */
  1560. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1561. ("AutoNeg done Port %d\n", Port));
  1562. return(SK_HW_PS_LINK);
  1563. }
  1564. }
  1565. }
  1566. else { /* !AutoNeg */
  1567. /* Link is up and we don't need more. */
  1568. #ifdef DEBUG
  1569. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1570. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1571. ("ERROR: Lipa auto detected on port %d\n", Port));
  1572. }
  1573. #endif /* DEBUG */
  1574. #ifdef xDEBUG
  1575. /* Dummy read ISR to prevent extra link downs/ups */
  1576. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1577. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1578. CMSMPrintString(
  1579. pAC->pConfigTable,
  1580. MSG_TYPE_RUNTIME_INFO,
  1581. "CheckUp3 - Stat: %x",
  1582. (void *)ExtStat,
  1583. (void *)NULL);
  1584. }
  1585. #endif /* DEBUG */
  1586. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1587. ("Link sync(GP), Port %d\n", Port));
  1588. SkHWLinkUp(pAC, IoC, Port);
  1589. return(SK_HW_PS_LINK);
  1590. }
  1591. return(SK_HW_PS_NONE);
  1592. } /* SkGePortCheckUpBcom */
  1593. /******************************************************************************
  1594. *
  1595. * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
  1596. *
  1597. * return:
  1598. * 0 o.k. nothing needed
  1599. * 1 Restart needed on this port
  1600. * 2 Link came up
  1601. */
  1602. static int SkGePortCheckUpGmac(
  1603. SK_AC *pAC, /* Adapter Context */
  1604. SK_IOC IoC, /* IO Context */
  1605. int Port) /* Which port should be checked */
  1606. {
  1607. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1608. int Done;
  1609. SK_U16 Isrc; /* Interrupt source */
  1610. SK_U16 PhyStat; /* Phy Status */
  1611. SK_U16 PhySpecStat;/* Phy Specific Status */
  1612. SK_U16 ResAb; /* Master/Slave resolution */
  1613. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1614. pPrt = &pAC->GIni.GP[Port];
  1615. /* Read PHY Interrupt Status */
  1616. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc);
  1617. if ((Isrc & PHY_M_IS_AN_COMPL) != 0) {
  1618. /* TBD */
  1619. }
  1620. if ((Isrc & PHY_M_IS_DOWNSH_DET) != 0) {
  1621. /* TBD */
  1622. }
  1623. if (pPrt->PHWLinkUp) {
  1624. return(SK_HW_PS_NONE);
  1625. }
  1626. /* Now wait for each port's link */
  1627. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1628. AutoNeg = SK_FALSE;
  1629. }
  1630. else {
  1631. AutoNeg = SK_TRUE;
  1632. }
  1633. /* Read PHY Status */
  1634. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
  1635. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1636. ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
  1637. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1638. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
  1639. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1640. /* Error */
  1641. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1642. ("Master/Slave Fault port %d\n", Port));
  1643. pPrt->PAutoNegFail = SK_TRUE;
  1644. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1645. return(SK_HW_PS_RESTART);
  1646. }
  1647. /* Read PHY Specific Status */
  1648. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
  1649. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1650. ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat));
  1651. if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
  1652. return(SK_HW_PS_NONE);
  1653. }
  1654. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1655. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1656. pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
  1657. if (AutoNeg) {
  1658. /* Auto-Negotiation Over ? */
  1659. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1660. SkHWLinkUp(pAC, IoC, Port);
  1661. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1662. if (Done != SK_AND_OK) {
  1663. return(SK_HW_PS_RESTART);
  1664. }
  1665. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1666. ("AutoNeg done Port %d\n", Port));
  1667. return(SK_HW_PS_LINK);
  1668. }
  1669. }
  1670. else { /* !AutoNeg */
  1671. /* Link is up and we don't need more */
  1672. #ifdef DEBUG
  1673. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1674. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1675. ("ERROR: Lipa auto detected on port %d\n", Port));
  1676. }
  1677. #endif /* DEBUG */
  1678. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1679. ("Link sync, Port %d\n", Port));
  1680. SkHWLinkUp(pAC, IoC, Port);
  1681. return(SK_HW_PS_LINK);
  1682. }
  1683. return(SK_HW_PS_NONE);
  1684. } /* SkGePortCheckUpGmac */
  1685. #ifdef OTHER_PHY
  1686. /******************************************************************************
  1687. *
  1688. * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
  1689. *
  1690. * return:
  1691. * 0 o.k. nothing needed
  1692. * 1 Restart needed on this port
  1693. * 2 Link came up
  1694. */
  1695. static int SkGePortCheckUpLone(
  1696. SK_AC *pAC, /* Adapter Context */
  1697. SK_IOC IoC, /* IO Context */
  1698. int Port) /* Which port should be checked */
  1699. {
  1700. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1701. int Done;
  1702. SK_U16 Isrc; /* Interrupt source register */
  1703. SK_U16 LpAb; /* Link Partner Ability */
  1704. SK_U16 ExtStat; /* Extended Status Register */
  1705. SK_U16 PhyStat; /* Phy Status Register */
  1706. SK_U16 StatSum;
  1707. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  1708. SK_U8 NextMode; /* Next AutoSensing Mode */
  1709. pPrt = &pAC->GIni.GP[Port];
  1710. if (pPrt->PHWLinkUp) {
  1711. return(SK_HW_PS_NONE);
  1712. }
  1713. StatSum = pPrt->PIsave;
  1714. pPrt->PIsave = 0;
  1715. /* Now wait for each ports link */
  1716. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  1717. AutoNeg = SK_FALSE;
  1718. }
  1719. else {
  1720. AutoNeg = SK_TRUE;
  1721. }
  1722. /*
  1723. * here we usually can check whether the link is in sync and
  1724. * auto-negotiation is done.
  1725. */
  1726. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
  1727. StatSum |= PhyStat;
  1728. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1729. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1730. /* Save Auto-negotiation Done bit */
  1731. pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
  1732. #ifdef DEBUG
  1733. if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
  1734. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1735. ("AutoNeg done rescheduled Port %d\n", Port));
  1736. }
  1737. #endif /* DEBUG */
  1738. return(SK_HW_PS_NONE);
  1739. }
  1740. if (AutoNeg) {
  1741. if ((StatSum & PHY_ST_AN_OVER) != 0) {
  1742. SkHWLinkUp(pAC, IoC, Port);
  1743. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1744. if (Done != SK_AND_OK) {
  1745. /* Get PHY parameters, for debugging only */
  1746. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
  1747. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
  1748. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1749. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1750. Port, LpAb, ExtStat));
  1751. /* Try next possible mode */
  1752. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1753. SkHWLinkDown(pAC, IoC, Port);
  1754. if (Done == SK_AND_DUP_CAP) {
  1755. /* GoTo next mode */
  1756. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1757. }
  1758. return(SK_HW_PS_RESTART);
  1759. }
  1760. else {
  1761. /*
  1762. * Dummy Read interrupt status to prevent
  1763. * extra link down/ups
  1764. */
  1765. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1766. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1767. ("AutoNeg done Port %d\n", Port));
  1768. return(SK_HW_PS_LINK);
  1769. }
  1770. }
  1771. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1772. pPrt->PAutoNegTimeOut++;
  1773. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1774. /* Timeout occured */
  1775. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1776. ("AutoNeg timeout Port %d\n", Port));
  1777. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1778. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1779. /* Set Link manually up */
  1780. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1781. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1782. ("Set manual full duplex Port %d\n", Port));
  1783. }
  1784. /* Do the restart */
  1785. return(SK_HW_PS_RESTART);
  1786. }
  1787. }
  1788. else {
  1789. /* Link is up and we don't need more */
  1790. #ifdef DEBUG
  1791. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1792. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1793. ("ERROR: Lipa auto detected on port %d\n", Port));
  1794. }
  1795. #endif /* DEBUG */
  1796. /*
  1797. * Dummy Read interrupt status to prevent
  1798. * extra link down/ups
  1799. */
  1800. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1801. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1802. ("Link sync(GP), Port %d\n", Port));
  1803. SkHWLinkUp(pAC, IoC, Port);
  1804. return(SK_HW_PS_LINK);
  1805. }
  1806. return(SK_HW_PS_NONE);
  1807. } /* SkGePortCheckUpLone */
  1808. /******************************************************************************
  1809. *
  1810. * SkGePortCheckUpNat() - Check if the link is up on National PHY
  1811. *
  1812. * return:
  1813. * 0 o.k. nothing needed
  1814. * 1 Restart needed on this port
  1815. * 2 Link came up
  1816. */
  1817. static int SkGePortCheckUpNat(
  1818. SK_AC *pAC, /* Adapter Context */
  1819. SK_IOC IoC, /* IO Context */
  1820. int Port) /* Which port should be checked */
  1821. {
  1822. /* todo: National */
  1823. return(SK_HW_PS_NONE);
  1824. } /* SkGePortCheckUpNat */
  1825. #endif /* OTHER_PHY */
  1826. /******************************************************************************
  1827. *
  1828. * SkGeSirqEvent() - Event Service Routine
  1829. *
  1830. * Description:
  1831. *
  1832. * Notes:
  1833. */
  1834. int SkGeSirqEvent(
  1835. SK_AC *pAC, /* Adapter Context */
  1836. SK_IOC IoC, /* Io Context */
  1837. SK_U32 Event, /* Module specific Event */
  1838. SK_EVPARA Para) /* Event specific Parameter */
  1839. {
  1840. SK_U64 Octets;
  1841. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1842. SK_U32 Port;
  1843. SK_U32 Time;
  1844. unsigned Len;
  1845. int PortStat;
  1846. SK_U8 Val8;
  1847. Port = Para.Para32[0];
  1848. pPrt = &pAC->GIni.GP[Port];
  1849. switch (Event) {
  1850. case SK_HWEV_WATIM:
  1851. /* Check whether port came up */
  1852. PortStat = SkGePortCheckUp(pAC, IoC, Port);
  1853. switch (PortStat) {
  1854. case SK_HW_PS_RESTART:
  1855. if (pPrt->PHWLinkUp) {
  1856. /*
  1857. * Set Link to down.
  1858. */
  1859. SkHWLinkDown(pAC, IoC, Port);
  1860. /*
  1861. * Signal directly to RLMT to ensure correct
  1862. * sequence of SWITCH and RESET event.
  1863. */
  1864. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1865. }
  1866. /* Restart needed */
  1867. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1868. break;
  1869. case SK_HW_PS_LINK:
  1870. /* Signal to RLMT */
  1871. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
  1872. break;
  1873. }
  1874. /* Start again the check Timer */
  1875. if (pPrt->PHWLinkUp) {
  1876. Time = SK_WA_ACT_TIME;
  1877. }
  1878. else {
  1879. Time = SK_WA_INA_TIME;
  1880. }
  1881. /* Todo: still needed for non-XMAC PHYs??? */
  1882. /* Start workaround Errata #2 timer */
  1883. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time,
  1884. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1885. break;
  1886. case SK_HWEV_PORT_START:
  1887. if (pPrt->PHWLinkUp) {
  1888. /*
  1889. * Signal directly to RLMT to ensure correct
  1890. * sequence of SWITCH and RESET event.
  1891. */
  1892. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1893. }
  1894. SkHWLinkDown(pAC, IoC, Port);
  1895. /* Schedule Port RESET */
  1896. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1897. /* Start workaround Errata #2 timer */
  1898. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  1899. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1900. break;
  1901. case SK_HWEV_PORT_STOP:
  1902. if (pPrt->PHWLinkUp) {
  1903. /*
  1904. * Signal directly to RLMT to ensure correct
  1905. * sequence of SWITCH and RESET event.
  1906. */
  1907. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1908. }
  1909. /* Stop Workaround Timer */
  1910. SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
  1911. SkHWLinkDown(pAC, IoC, Port);
  1912. break;
  1913. case SK_HWEV_UPDATE_STAT:
  1914. /* We do NOT need to update any statistics */
  1915. break;
  1916. case SK_HWEV_CLEAR_STAT:
  1917. /* We do NOT need to clear any statistics */
  1918. for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
  1919. pPrt->PPrevRx = 0;
  1920. pPrt->PPrevFcs = 0;
  1921. pPrt->PPrevShorts = 0;
  1922. }
  1923. break;
  1924. case SK_HWEV_SET_LMODE:
  1925. Val8 = (SK_U8)Para.Para32[1];
  1926. if (pPrt->PLinkModeConf != Val8) {
  1927. /* Set New link mode */
  1928. pPrt->PLinkModeConf = Val8;
  1929. /* Restart Port */
  1930. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1931. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1932. }
  1933. break;
  1934. case SK_HWEV_SET_FLOWMODE:
  1935. Val8 = (SK_U8)Para.Para32[1];
  1936. if (pPrt->PFlowCtrlMode != Val8) {
  1937. /* Set New Flow Control mode */
  1938. pPrt->PFlowCtrlMode = Val8;
  1939. /* Restart Port */
  1940. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1941. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1942. }
  1943. break;
  1944. case SK_HWEV_SET_ROLE:
  1945. /* not possible for fiber */
  1946. if (!pAC->GIni.GICopperType) {
  1947. break;
  1948. }
  1949. Val8 = (SK_U8)Para.Para32[1];
  1950. if (pPrt->PMSMode != Val8) {
  1951. /* Set New link mode */
  1952. pPrt->PMSMode = Val8;
  1953. /* Restart Port */
  1954. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1955. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1956. }
  1957. break;
  1958. case SK_HWEV_SET_SPEED:
  1959. if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
  1960. break;
  1961. }
  1962. Val8 = (SK_U8)Para.Para32[1];
  1963. if (pPrt->PLinkSpeed != Val8) {
  1964. /* Set New Speed parameter */
  1965. pPrt->PLinkSpeed = Val8;
  1966. /* Restart Port */
  1967. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1968. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1969. }
  1970. break;
  1971. case SK_HWEV_HALFDUP_CHK:
  1972. /*
  1973. * half duplex hangup workaround.
  1974. * See packet arbiter timeout interrupt for description
  1975. */
  1976. pPrt->HalfDupTimerActive = SK_FALSE;
  1977. if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  1978. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
  1979. Len = sizeof(SK_U64);
  1980. SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
  1981. &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
  1982. pAC->Rlmt.Port[Port].Net->NetNumber);
  1983. if (pPrt->LastOctets == Octets) {
  1984. /* Tx hanging, a FIFO flush restarts it */
  1985. SkMacFlushTxFifo(pAC, IoC, Port);
  1986. }
  1987. }
  1988. break;
  1989. default:
  1990. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
  1991. break;
  1992. }
  1993. return(0);
  1994. } /* SkGeSirqEvent */
  1995. /******************************************************************************
  1996. *
  1997. * SkPhyIsrBcom() - PHY interrupt service routine
  1998. *
  1999. * Description: handles all interrupts from BCom PHY
  2000. *
  2001. * Returns: N/A
  2002. */
  2003. static void SkPhyIsrBcom(
  2004. SK_AC *pAC, /* Adapter Context */
  2005. SK_IOC IoC, /* Io Context */
  2006. int Port, /* Port Num = PHY Num */
  2007. SK_U16 IStatus) /* Interrupt Status */
  2008. {
  2009. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  2010. SK_EVPARA Para;
  2011. pPrt = &pAC->GIni.GP[Port];
  2012. if ((IStatus & PHY_B_IS_PSE) != 0) {
  2013. /* Incorrectable pair swap error */
  2014. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
  2015. SKERR_SIRQ_E022MSG);
  2016. }
  2017. if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
  2018. Para.Para32[0] = (SK_U32)Port;
  2019. SkHWLinkDown(pAC, IoC, Port);
  2020. /* Signal to RLMT */
  2021. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2022. /* Start workaround Errata #2 timer */
  2023. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  2024. SKGE_HWAC, SK_HWEV_WATIM, Para);
  2025. }
  2026. } /* SkPhyIsrBcom */
  2027. /******************************************************************************
  2028. *
  2029. * SkPhyIsrGmac() - PHY interrupt service routine
  2030. *
  2031. * Description: handles all interrupts from Marvell PHY
  2032. *
  2033. * Returns: N/A
  2034. */
  2035. static void SkPhyIsrGmac(
  2036. SK_AC *pAC, /* Adapter Context */
  2037. SK_IOC IoC, /* Io Context */
  2038. int Port, /* Port Num = PHY Num */
  2039. SK_U16 IStatus) /* Interrupt Status */
  2040. {
  2041. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  2042. SK_EVPARA Para;
  2043. pPrt = &pAC->GIni.GP[Port];
  2044. if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
  2045. Para.Para32[0] = (SK_U32)Port;
  2046. SkHWLinkDown(pAC, IoC, Port);
  2047. /* Signal to RLMT */
  2048. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2049. }
  2050. if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
  2051. /* Auto-Negotiation Error */
  2052. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
  2053. }
  2054. if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
  2055. /* TBD */
  2056. }
  2057. if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
  2058. /* FIFO Overflow/Underrun Error */
  2059. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
  2060. }
  2061. } /* SkPhyIsrGmac */
  2062. #ifdef OTHER_PHY
  2063. /******************************************************************************
  2064. *
  2065. * SkPhyIsrLone() - PHY interrupt service routine
  2066. *
  2067. * Description: handles all interrupts from LONE PHY
  2068. *
  2069. * Returns: N/A
  2070. */
  2071. static void SkPhyIsrLone(
  2072. SK_AC *pAC, /* Adapter Context */
  2073. SK_IOC IoC, /* Io Context */
  2074. int Port, /* Port Num = PHY Num */
  2075. SK_U16 IStatus) /* Interrupt Status */
  2076. {
  2077. SK_EVPARA Para;
  2078. if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
  2079. SkHWLinkDown(pAC, IoC, Port);
  2080. /* Signal to RLMT */
  2081. Para.Para32[0] = (SK_U32)Port;
  2082. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  2083. }
  2084. } /* SkPhyIsrLone */
  2085. #endif /* OTHER_PHY */
  2086. /* End of File */