skgesirq.c 65 KB

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