skgesirq.c 58 KB

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