skgesirq.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229
  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. static 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. /* Snap statistic counters */
  512. (void)SkXmUpdateStats(pAC, IoC, 0);
  513. (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
  514. pPrt->LastOctets = (SK_U64)RegVal32 << 32;
  515. (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
  516. pPrt->LastOctets += RegVal32;
  517. Para.Para32[0] = 0;
  518. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  519. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  520. }
  521. }
  522. #endif /* GENESIS */
  523. }
  524. if ((Istatus & IS_PA_TO_TX2) != 0) {
  525. pPrt = &pAC->GIni.GP[1];
  526. /* May be a normal situation in a server with a slow network */
  527. SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
  528. #ifdef GENESIS
  529. if (pAC->GIni.GIGenesis) {
  530. /* workaround: see above */
  531. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  532. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
  533. !pPrt->HalfDupTimerActive) {
  534. pPrt->HalfDupTimerActive = SK_TRUE;
  535. /* Snap statistic counters */
  536. (void)SkXmUpdateStats(pAC, IoC, 1);
  537. (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
  538. pPrt->LastOctets = (SK_U64)RegVal32 << 32;
  539. (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
  540. pPrt->LastOctets += RegVal32;
  541. Para.Para32[0] = 1;
  542. SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
  543. SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
  544. }
  545. }
  546. #endif /* GENESIS */
  547. }
  548. /* Check interrupts of the particular queues */
  549. if ((Istatus & IS_R1_C) != 0) {
  550. /* Clear IRQ */
  551. SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
  552. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
  553. SKERR_SIRQ_E006MSG);
  554. Para.Para64 = MAC_1;
  555. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  556. Para.Para32[0] = MAC_1;
  557. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  558. }
  559. if ((Istatus & IS_R2_C) != 0) {
  560. /* Clear IRQ */
  561. SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
  562. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
  563. SKERR_SIRQ_E007MSG);
  564. Para.Para64 = MAC_2;
  565. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  566. Para.Para32[0] = MAC_2;
  567. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  568. }
  569. if ((Istatus & IS_XS1_C) != 0) {
  570. /* Clear IRQ */
  571. SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
  572. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
  573. SKERR_SIRQ_E008MSG);
  574. Para.Para64 = MAC_1;
  575. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  576. Para.Para32[0] = MAC_1;
  577. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  578. }
  579. if ((Istatus & IS_XA1_C) != 0) {
  580. /* Clear IRQ */
  581. SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
  582. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
  583. SKERR_SIRQ_E009MSG);
  584. Para.Para64 = MAC_1;
  585. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  586. Para.Para32[0] = MAC_1;
  587. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  588. }
  589. if ((Istatus & IS_XS2_C) != 0) {
  590. /* Clear IRQ */
  591. SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
  592. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
  593. SKERR_SIRQ_E010MSG);
  594. Para.Para64 = MAC_2;
  595. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  596. Para.Para32[0] = MAC_2;
  597. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  598. }
  599. if ((Istatus & IS_XA2_C) != 0) {
  600. /* Clear IRQ */
  601. SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
  602. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
  603. SKERR_SIRQ_E011MSG);
  604. Para.Para64 = MAC_2;
  605. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
  606. Para.Para32[0] = MAC_2;
  607. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  608. }
  609. /* External reg interrupt */
  610. if ((Istatus & IS_EXT_REG) != 0) {
  611. /* Test IRQs from PHY */
  612. for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
  613. pPrt = &pAC->GIni.GP[i];
  614. if (pPrt->PState == SK_PRT_RESET) {
  615. continue;
  616. }
  617. #ifdef GENESIS
  618. if (pAC->GIni.GIGenesis) {
  619. switch (pPrt->PhyType) {
  620. case SK_PHY_XMAC:
  621. break;
  622. case SK_PHY_BCOM:
  623. SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
  624. if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
  625. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  626. ("Port %d Bcom Int: 0x%04X\n",
  627. i, PhyInt));
  628. SkPhyIsrBcom(pAC, IoC, i, PhyInt);
  629. }
  630. break;
  631. #ifdef OTHER_PHY
  632. case SK_PHY_LONE:
  633. SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
  634. if ((PhyInt & PHY_L_DEF_MSK) != 0) {
  635. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  636. ("Port %d Lone Int: %x\n",
  637. i, PhyInt));
  638. SkPhyIsrLone(pAC, IoC, i, PhyInt);
  639. }
  640. break;
  641. #endif /* OTHER_PHY */
  642. }
  643. }
  644. #endif /* GENESIS */
  645. #ifdef YUKON
  646. if (pAC->GIni.GIYukon) {
  647. /* Read PHY Interrupt Status */
  648. SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
  649. if ((PhyInt & PHY_M_DEF_MSK) != 0) {
  650. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  651. ("Port %d Marv Int: 0x%04X\n",
  652. i, PhyInt));
  653. SkPhyIsrGmac(pAC, IoC, i, PhyInt);
  654. }
  655. }
  656. #endif /* YUKON */
  657. }
  658. }
  659. /* I2C Ready interrupt */
  660. if ((Istatus & IS_I2C_READY) != 0) {
  661. #ifdef SK_SLIM
  662. SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
  663. #else
  664. SkI2cIsr(pAC, IoC);
  665. #endif
  666. }
  667. /* SW forced interrupt */
  668. if ((Istatus & IS_IRQ_SW) != 0) {
  669. /* clear the software IRQ */
  670. SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
  671. }
  672. if ((Istatus & IS_LNK_SYNC_M1) != 0) {
  673. /*
  674. * We do NOT need the Link Sync interrupt, because it shows
  675. * us only a link going down.
  676. */
  677. /* clear interrupt */
  678. SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
  679. }
  680. /* Check MAC after link sync counter */
  681. if ((Istatus & IS_MAC1) != 0) {
  682. /* IRQ from MAC 1 */
  683. SkMacIrq(pAC, IoC, MAC_1);
  684. }
  685. if ((Istatus & IS_LNK_SYNC_M2) != 0) {
  686. /*
  687. * We do NOT need the Link Sync interrupt, because it shows
  688. * us only a link going down.
  689. */
  690. /* clear interrupt */
  691. SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
  692. }
  693. /* Check MAC after link sync counter */
  694. if ((Istatus & IS_MAC2) != 0) {
  695. /* IRQ from MAC 2 */
  696. SkMacIrq(pAC, IoC, MAC_2);
  697. }
  698. /* Timer interrupt (served last) */
  699. if ((Istatus & IS_TIMINT) != 0) {
  700. /* check for HW Errors */
  701. if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
  702. /* read the HW Error Interrupt source */
  703. SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
  704. SkGeHwErr(pAC, IoC, RegVal32);
  705. }
  706. SkHwtIsr(pAC, IoC);
  707. }
  708. } /* SkGeSirqIsr */
  709. #ifdef GENESIS
  710. /******************************************************************************
  711. *
  712. * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
  713. *
  714. * return:
  715. * 0 o.k. nothing needed
  716. * 1 Restart needed on this port
  717. */
  718. static int SkGePortCheckShorts(
  719. SK_AC *pAC, /* Adapter Context */
  720. SK_IOC IoC, /* IO Context */
  721. int Port) /* Which port should be checked */
  722. {
  723. SK_U32 Shorts; /* Short Event Counter */
  724. SK_U32 CheckShorts; /* Check value for Short Event Counter */
  725. SK_U64 RxCts; /* Rx Counter (packets on network) */
  726. SK_U32 RxTmp; /* Rx temp. Counter */
  727. SK_U32 FcsErrCts; /* FCS Error Counter */
  728. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  729. int Rtv; /* Return value */
  730. int i;
  731. pPrt = &pAC->GIni.GP[Port];
  732. /* Default: no action */
  733. Rtv = SK_HW_PS_NONE;
  734. (void)SkXmUpdateStats(pAC, IoC, Port);
  735. /* Extra precaution: check for short Event counter */
  736. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  737. /*
  738. * Read Rx counters (packets seen on the network and not necessarily
  739. * really received.
  740. */
  741. RxCts = 0;
  742. for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
  743. (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
  744. RxCts += (SK_U64)RxTmp;
  745. }
  746. /* On default: check shorts against zero */
  747. CheckShorts = 0;
  748. /* Extra precaution on active links */
  749. if (pPrt->PHWLinkUp) {
  750. /* Reset Link Restart counter */
  751. pPrt->PLinkResCt = 0;
  752. pPrt->PAutoNegTOCt = 0;
  753. /* If link is up check for 2 */
  754. CheckShorts = 2;
  755. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
  756. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  757. pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
  758. (pPrt->PLinkMode == SK_LMODE_HALF ||
  759. pPrt->PLinkMode == SK_LMODE_FULL)) {
  760. /*
  761. * This is autosensing and we are in the fallback
  762. * manual full/half duplex mode.
  763. */
  764. if (RxCts == pPrt->PPrevRx) {
  765. /* Nothing received, restart link */
  766. pPrt->PPrevFcs = FcsErrCts;
  767. pPrt->PPrevShorts = Shorts;
  768. return(SK_HW_PS_RESTART);
  769. }
  770. else {
  771. pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
  772. }
  773. }
  774. if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
  775. (!(FcsErrCts - pPrt->PPrevFcs))) {
  776. /*
  777. * Note: The compare with zero above has to be done the way shown,
  778. * otherwise the Linux driver will have a problem.
  779. */
  780. /*
  781. * We received a bunch of frames or no CRC error occured on the
  782. * network -> ok.
  783. */
  784. pPrt->PPrevRx = RxCts;
  785. pPrt->PPrevFcs = FcsErrCts;
  786. pPrt->PPrevShorts = Shorts;
  787. return(SK_HW_PS_NONE);
  788. }
  789. pPrt->PPrevFcs = FcsErrCts;
  790. }
  791. if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
  792. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  793. ("Short Event Count Restart Port %d \n", Port));
  794. Rtv = SK_HW_PS_RESTART;
  795. }
  796. pPrt->PPrevShorts = Shorts;
  797. pPrt->PPrevRx = RxCts;
  798. return(Rtv);
  799. } /* SkGePortCheckShorts */
  800. #endif /* GENESIS */
  801. /******************************************************************************
  802. *
  803. * SkGePortCheckUp() - Check if the link is up
  804. *
  805. * return:
  806. * 0 o.k. nothing needed
  807. * 1 Restart needed on this port
  808. * 2 Link came up
  809. */
  810. static int SkGePortCheckUp(
  811. SK_AC *pAC, /* Adapter Context */
  812. SK_IOC IoC, /* IO Context */
  813. int Port) /* Which port should be checked */
  814. {
  815. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  816. SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
  817. int Rtv; /* Return value */
  818. Rtv = SK_HW_PS_NONE;
  819. pPrt = &pAC->GIni.GP[Port];
  820. if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
  821. AutoNeg = SK_FALSE;
  822. }
  823. else {
  824. AutoNeg = SK_TRUE;
  825. }
  826. #ifdef GENESIS
  827. if (pAC->GIni.GIGenesis) {
  828. switch (pPrt->PhyType) {
  829. case SK_PHY_XMAC:
  830. Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
  831. break;
  832. case SK_PHY_BCOM:
  833. Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
  834. break;
  835. #ifdef OTHER_PHY
  836. case SK_PHY_LONE:
  837. Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
  838. break;
  839. case SK_PHY_NAT:
  840. Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
  841. break;
  842. #endif /* OTHER_PHY */
  843. }
  844. }
  845. #endif /* GENESIS */
  846. #ifdef YUKON
  847. if (pAC->GIni.GIYukon) {
  848. Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
  849. }
  850. #endif /* YUKON */
  851. return(Rtv);
  852. } /* SkGePortCheckUp */
  853. #ifdef GENESIS
  854. /******************************************************************************
  855. *
  856. * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
  857. *
  858. * return:
  859. * 0 o.k. nothing needed
  860. * 1 Restart needed on this port
  861. * 2 Link came up
  862. */
  863. static int SkGePortCheckUpXmac(
  864. SK_AC *pAC, /* Adapter Context */
  865. SK_IOC IoC, /* IO Context */
  866. int Port, /* Which port should be checked */
  867. SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
  868. {
  869. SK_U32 Shorts; /* Short Event Counter */
  870. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  871. int Done;
  872. SK_U32 GpReg; /* General Purpose register value */
  873. SK_U16 Isrc; /* Interrupt source register */
  874. SK_U16 IsrcSum; /* Interrupt source register sum */
  875. SK_U16 LpAb; /* Link Partner Ability */
  876. SK_U16 ResAb; /* Resolved Ability */
  877. SK_U16 ExtStat; /* Extended Status Register */
  878. SK_U8 NextMode; /* Next AutoSensing Mode */
  879. pPrt = &pAC->GIni.GP[Port];
  880. if (pPrt->PHWLinkUp) {
  881. if (pPrt->PhyType != SK_PHY_XMAC) {
  882. return(SK_HW_PS_NONE);
  883. }
  884. else {
  885. return(SkGePortCheckShorts(pAC, IoC, Port));
  886. }
  887. }
  888. IsrcSum = pPrt->PIsave;
  889. pPrt->PIsave = 0;
  890. /* Now wait for each port's link */
  891. if (pPrt->PLinkBroken) {
  892. /* Link was broken */
  893. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  894. if ((GpReg & XM_GP_INP_ASS) == 0) {
  895. /* The Link is in sync */
  896. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  897. IsrcSum |= Isrc;
  898. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  899. if ((Isrc & XM_IS_INP_ASS) == 0) {
  900. /* It has been in sync since last time */
  901. /* Restart the PORT */
  902. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  903. ("Link in sync Restart Port %d\n", Port));
  904. (void)SkXmUpdateStats(pAC, IoC, Port);
  905. /* We now need to reinitialize the PrevShorts counter */
  906. (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
  907. pPrt->PPrevShorts = Shorts;
  908. pPrt->PLinkBroken = SK_FALSE;
  909. /*
  910. * Link Restart Workaround:
  911. * it may be possible that the other Link side
  912. * restarts its link as well an we detect
  913. * another LinkBroken. To prevent this
  914. * happening we check for a maximum number
  915. * of consecutive restart. If those happens,
  916. * we do NOT restart the active link and
  917. * check whether the link is now o.k.
  918. */
  919. pPrt->PLinkResCt++;
  920. pPrt->PAutoNegTimeOut = 0;
  921. if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
  922. return(SK_HW_PS_RESTART);
  923. }
  924. pPrt->PLinkResCt = 0;
  925. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  926. ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
  927. }
  928. else {
  929. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  930. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  931. ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
  932. /* Do nothing more if link is broken */
  933. return(SK_HW_PS_NONE);
  934. }
  935. }
  936. else {
  937. /* Do nothing more if link is broken */
  938. return(SK_HW_PS_NONE);
  939. }
  940. }
  941. else {
  942. /* Link was not broken, check if it is */
  943. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  944. IsrcSum |= Isrc;
  945. if ((Isrc & XM_IS_INP_ASS) != 0) {
  946. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  947. IsrcSum |= Isrc;
  948. if ((Isrc & XM_IS_INP_ASS) != 0) {
  949. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  950. IsrcSum |= Isrc;
  951. if ((Isrc & XM_IS_INP_ASS) != 0) {
  952. pPrt->PLinkBroken = SK_TRUE;
  953. /* Re-Init Link partner Autoneg flag */
  954. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  955. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  956. ("Link broken Port %d\n", Port));
  957. /* Cable removed-> reinit sense mode */
  958. SkHWInitDefSense(pAC, IoC, Port);
  959. return(SK_HW_PS_RESTART);
  960. }
  961. }
  962. }
  963. else {
  964. SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
  965. if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
  966. return(SK_HW_PS_RESTART);
  967. }
  968. }
  969. }
  970. /*
  971. * here we usually can check whether the link is in sync and
  972. * auto-negotiation is done.
  973. */
  974. XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
  975. XM_IN16(IoC, Port, XM_ISRC, &Isrc);
  976. IsrcSum |= Isrc;
  977. SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
  978. if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
  979. if ((GpReg & XM_GP_INP_ASS) == 0) {
  980. /* Save Auto-negotiation Done interrupt only if link is in sync */
  981. pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
  982. }
  983. #ifdef DEBUG
  984. if ((pPrt->PIsave & XM_IS_AND) != 0) {
  985. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  986. ("AutoNeg done rescheduled Port %d\n", Port));
  987. }
  988. #endif /* DEBUG */
  989. return(SK_HW_PS_NONE);
  990. }
  991. if (AutoNeg) {
  992. if ((IsrcSum & XM_IS_AND) != 0) {
  993. SkHWLinkUp(pAC, IoC, Port);
  994. Done = SkMacAutoNegDone(pAC, IoC, Port);
  995. if (Done != SK_AND_OK) {
  996. /* Get PHY parameters, for debugging only */
  997. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
  998. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
  999. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1000. ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
  1001. Port, LpAb, ResAb));
  1002. /* Try next possible mode */
  1003. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1004. SkHWLinkDown(pAC, IoC, Port);
  1005. if (Done == SK_AND_DUP_CAP) {
  1006. /* GoTo next mode */
  1007. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1008. }
  1009. return(SK_HW_PS_RESTART);
  1010. }
  1011. /*
  1012. * Dummy Read extended status to prevent extra link down/ups
  1013. * (clear Page Received bit if set)
  1014. */
  1015. SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
  1016. return(SK_HW_PS_LINK);
  1017. }
  1018. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1019. pPrt->PAutoNegTimeOut++;
  1020. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1021. /* Increase the Timeout counter */
  1022. pPrt->PAutoNegTOCt++;
  1023. /* Timeout occured */
  1024. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1025. ("AutoNeg timeout Port %d\n", Port));
  1026. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1027. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1028. /* Set Link manually up */
  1029. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1030. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1031. ("Set manual full duplex Port %d\n", Port));
  1032. }
  1033. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1034. pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
  1035. pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
  1036. /*
  1037. * This is rather complicated.
  1038. * we need to check here whether the LIPA_AUTO
  1039. * we saw before is false alert. We saw at one
  1040. * switch ( SR8800) that on boot time it sends
  1041. * just one auto-neg packet and does no further
  1042. * auto-negotiation.
  1043. * Solution: we restart the autosensing after
  1044. * a few timeouts.
  1045. */
  1046. pPrt->PAutoNegTOCt = 0;
  1047. pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
  1048. SkHWInitDefSense(pAC, IoC, Port);
  1049. }
  1050. /* Do the restart */
  1051. return(SK_HW_PS_RESTART);
  1052. }
  1053. }
  1054. else {
  1055. /* Link is up and we don't need more */
  1056. #ifdef DEBUG
  1057. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1058. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1059. ("ERROR: Lipa auto detected on port %d\n", Port));
  1060. }
  1061. #endif /* DEBUG */
  1062. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1063. ("Link sync(GP), Port %d\n", Port));
  1064. SkHWLinkUp(pAC, IoC, Port);
  1065. /*
  1066. * Link sync (GP) and so assume a good connection. But if not received
  1067. * a bunch of frames received in a time slot (maybe broken tx cable)
  1068. * the port is restart.
  1069. */
  1070. return(SK_HW_PS_LINK);
  1071. }
  1072. return(SK_HW_PS_NONE);
  1073. } /* SkGePortCheckUpXmac */
  1074. /******************************************************************************
  1075. *
  1076. * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
  1077. *
  1078. * return:
  1079. * 0 o.k. nothing needed
  1080. * 1 Restart needed on this port
  1081. * 2 Link came up
  1082. */
  1083. static int SkGePortCheckUpBcom(
  1084. SK_AC *pAC, /* Adapter Context */
  1085. SK_IOC IoC, /* IO Context */
  1086. int Port, /* Which port should be checked */
  1087. SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
  1088. {
  1089. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1090. int Done;
  1091. SK_U16 Isrc; /* Interrupt source register */
  1092. SK_U16 PhyStat; /* Phy Status Register */
  1093. SK_U16 ResAb; /* Master/Slave resolution */
  1094. SK_U16 Ctrl; /* Broadcom control flags */
  1095. #ifdef DEBUG
  1096. SK_U16 LpAb;
  1097. SK_U16 ExtStat;
  1098. #endif /* DEBUG */
  1099. pPrt = &pAC->GIni.GP[Port];
  1100. /* Check for No HCD Link events (#10523) */
  1101. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
  1102. #ifdef xDEBUG
  1103. if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
  1104. (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
  1105. SK_U32 Stat1, Stat2, Stat3;
  1106. Stat1 = 0;
  1107. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1108. CMSMPrintString(
  1109. pAC->pConfigTable,
  1110. MSG_TYPE_RUNTIME_INFO,
  1111. "CheckUp1 - Stat: %x, Mask: %x",
  1112. (void *)Isrc,
  1113. (void *)Stat1);
  1114. Stat1 = 0;
  1115. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1116. Stat2 = 0;
  1117. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
  1118. Stat1 = Stat1 << 16 | Stat2;
  1119. Stat2 = 0;
  1120. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1121. Stat3 = 0;
  1122. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1123. Stat2 = Stat2 << 16 | Stat3;
  1124. CMSMPrintString(
  1125. pAC->pConfigTable,
  1126. MSG_TYPE_RUNTIME_INFO,
  1127. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1128. (void *)Stat1,
  1129. (void *)Stat2);
  1130. Stat1 = 0;
  1131. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1132. Stat2 = 0;
  1133. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1134. Stat1 = Stat1 << 16 | Stat2;
  1135. Stat2 = 0;
  1136. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1137. Stat3 = 0;
  1138. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
  1139. Stat2 = Stat2 << 16 | Stat3;
  1140. CMSMPrintString(
  1141. pAC->pConfigTable,
  1142. MSG_TYPE_RUNTIME_INFO,
  1143. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1144. (void *)Stat1,
  1145. (void *)Stat2);
  1146. Stat1 = 0;
  1147. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1148. Stat2 = 0;
  1149. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1150. Stat1 = Stat1 << 16 | Stat2;
  1151. Stat2 = 0;
  1152. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1153. Stat3 = 0;
  1154. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1155. Stat2 = Stat2 << 16 | Stat3;
  1156. CMSMPrintString(
  1157. pAC->pConfigTable,
  1158. MSG_TYPE_RUNTIME_INFO,
  1159. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1160. (void *)Stat1,
  1161. (void *)Stat2);
  1162. }
  1163. #endif /* DEBUG */
  1164. if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
  1165. /*
  1166. * Workaround BCom Errata:
  1167. * enable and disable loopback mode if "NO HCD" occurs.
  1168. */
  1169. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
  1170. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1171. (SK_U16)(Ctrl | PHY_CT_LOOP));
  1172. SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
  1173. (SK_U16)(Ctrl & ~PHY_CT_LOOP));
  1174. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1175. ("No HCD Link event, Port %d\n", Port));
  1176. #ifdef xDEBUG
  1177. CMSMPrintString(
  1178. pAC->pConfigTable,
  1179. MSG_TYPE_RUNTIME_INFO,
  1180. "No HCD link event, port %d.",
  1181. (void *)Port,
  1182. (void *)NULL);
  1183. #endif /* DEBUG */
  1184. }
  1185. /* Not obsolete: link status bit is latched to 0 and autoclearing! */
  1186. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1187. if (pPrt->PHWLinkUp) {
  1188. return(SK_HW_PS_NONE);
  1189. }
  1190. #ifdef xDEBUG
  1191. {
  1192. SK_U32 Stat1, Stat2, Stat3;
  1193. Stat1 = 0;
  1194. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
  1195. CMSMPrintString(
  1196. pAC->pConfigTable,
  1197. MSG_TYPE_RUNTIME_INFO,
  1198. "CheckUp1a - Stat: %x, Mask: %x",
  1199. (void *)Isrc,
  1200. (void *)Stat1);
  1201. Stat1 = 0;
  1202. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
  1203. Stat2 = 0;
  1204. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1205. Stat1 = Stat1 << 16 | PhyStat;
  1206. Stat2 = 0;
  1207. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
  1208. Stat3 = 0;
  1209. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
  1210. Stat2 = Stat2 << 16 | Stat3;
  1211. CMSMPrintString(
  1212. pAC->pConfigTable,
  1213. MSG_TYPE_RUNTIME_INFO,
  1214. "Ctrl/Stat: %x, AN Adv/LP: %x",
  1215. (void *)Stat1,
  1216. (void *)Stat2);
  1217. Stat1 = 0;
  1218. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
  1219. Stat2 = 0;
  1220. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
  1221. Stat1 = Stat1 << 16 | Stat2;
  1222. Stat2 = 0;
  1223. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
  1224. Stat3 = 0;
  1225. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1226. Stat2 = Stat2 << 16 | ResAb;
  1227. CMSMPrintString(
  1228. pAC->pConfigTable,
  1229. MSG_TYPE_RUNTIME_INFO,
  1230. "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
  1231. (void *)Stat1,
  1232. (void *)Stat2);
  1233. Stat1 = 0;
  1234. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
  1235. Stat2 = 0;
  1236. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
  1237. Stat1 = Stat1 << 16 | Stat2;
  1238. Stat2 = 0;
  1239. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
  1240. Stat3 = 0;
  1241. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
  1242. Stat2 = Stat2 << 16 | Stat3;
  1243. CMSMPrintString(
  1244. pAC->pConfigTable,
  1245. MSG_TYPE_RUNTIME_INFO,
  1246. "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
  1247. (void *)Stat1,
  1248. (void *)Stat2);
  1249. }
  1250. #endif /* DEBUG */
  1251. /*
  1252. * Here we usually can check whether the link is in sync and
  1253. * auto-negotiation is done.
  1254. */
  1255. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
  1256. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1257. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1258. ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
  1259. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1260. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1261. /* Error */
  1262. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1263. ("Master/Slave Fault port %d\n", Port));
  1264. pPrt->PAutoNegFail = SK_TRUE;
  1265. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1266. return(SK_HW_PS_RESTART);
  1267. }
  1268. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1269. return(SK_HW_PS_NONE);
  1270. }
  1271. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1272. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1273. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1274. ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
  1275. if (AutoNeg) {
  1276. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1277. SkHWLinkUp(pAC, IoC, Port);
  1278. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1279. if (Done != SK_AND_OK) {
  1280. #ifdef DEBUG
  1281. /* Get PHY parameters, for debugging only */
  1282. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
  1283. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
  1284. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1285. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1286. Port, LpAb, ExtStat));
  1287. #endif /* DEBUG */
  1288. return(SK_HW_PS_RESTART);
  1289. }
  1290. else {
  1291. #ifdef xDEBUG
  1292. /* Dummy read ISR to prevent extra link downs/ups */
  1293. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1294. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1295. CMSMPrintString(
  1296. pAC->pConfigTable,
  1297. MSG_TYPE_RUNTIME_INFO,
  1298. "CheckUp2 - Stat: %x",
  1299. (void *)ExtStat,
  1300. (void *)NULL);
  1301. }
  1302. #endif /* DEBUG */
  1303. return(SK_HW_PS_LINK);
  1304. }
  1305. }
  1306. }
  1307. else { /* !AutoNeg */
  1308. /* Link is up and we don't need more. */
  1309. #ifdef DEBUG
  1310. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1311. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1312. ("ERROR: Lipa auto detected on port %d\n", Port));
  1313. }
  1314. #endif /* DEBUG */
  1315. #ifdef xDEBUG
  1316. /* Dummy read ISR to prevent extra link downs/ups */
  1317. SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
  1318. if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
  1319. CMSMPrintString(
  1320. pAC->pConfigTable,
  1321. MSG_TYPE_RUNTIME_INFO,
  1322. "CheckUp3 - Stat: %x",
  1323. (void *)ExtStat,
  1324. (void *)NULL);
  1325. }
  1326. #endif /* DEBUG */
  1327. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1328. ("Link sync(GP), Port %d\n", Port));
  1329. SkHWLinkUp(pAC, IoC, Port);
  1330. return(SK_HW_PS_LINK);
  1331. }
  1332. return(SK_HW_PS_NONE);
  1333. } /* SkGePortCheckUpBcom */
  1334. #endif /* GENESIS */
  1335. #ifdef YUKON
  1336. /******************************************************************************
  1337. *
  1338. * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
  1339. *
  1340. * return:
  1341. * 0 o.k. nothing needed
  1342. * 1 Restart needed on this port
  1343. * 2 Link came up
  1344. */
  1345. static int SkGePortCheckUpGmac(
  1346. SK_AC *pAC, /* Adapter Context */
  1347. SK_IOC IoC, /* IO Context */
  1348. int Port, /* Which port should be checked */
  1349. SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
  1350. {
  1351. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1352. int Done;
  1353. SK_U16 PhyIsrc; /* PHY Interrupt source */
  1354. SK_U16 PhyStat; /* PPY Status */
  1355. SK_U16 PhySpecStat;/* PHY Specific Status */
  1356. SK_U16 ResAb; /* Master/Slave resolution */
  1357. SK_EVPARA Para;
  1358. #ifdef DEBUG
  1359. SK_U16 Word; /* I/O helper */
  1360. #endif /* DEBUG */
  1361. pPrt = &pAC->GIni.GP[Port];
  1362. if (pPrt->PHWLinkUp) {
  1363. return(SK_HW_PS_NONE);
  1364. }
  1365. /* Read PHY Status */
  1366. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
  1367. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1368. ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
  1369. /* Read PHY Interrupt Status */
  1370. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
  1371. if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
  1372. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1373. ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
  1374. }
  1375. if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
  1376. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1377. ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
  1378. }
  1379. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1380. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
  1381. if ((ResAb & PHY_B_1000S_MSF) != 0) {
  1382. /* Error */
  1383. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1384. ("Master/Slave Fault port %d\n", Port));
  1385. pPrt->PAutoNegFail = SK_TRUE;
  1386. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1387. return(SK_HW_PS_RESTART);
  1388. }
  1389. /* Read PHY Specific Status */
  1390. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
  1391. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1392. ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
  1393. #ifdef DEBUG
  1394. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
  1395. if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
  1396. (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) {
  1397. /* Read PHY Next Page Link Partner */
  1398. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
  1399. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1400. ("Page Received, NextPage: 0x%04X\n", Word));
  1401. }
  1402. #endif /* DEBUG */
  1403. if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
  1404. return(SK_HW_PS_NONE);
  1405. }
  1406. if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
  1407. (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
  1408. /* Downshift detected */
  1409. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
  1410. Para.Para64 = Port;
  1411. SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
  1412. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1413. ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
  1414. }
  1415. pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
  1416. SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
  1417. pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
  1418. if (AutoNeg) {
  1419. /* Auto-Negotiation Over ? */
  1420. if ((PhyStat & PHY_ST_AN_OVER) != 0) {
  1421. SkHWLinkUp(pAC, IoC, Port);
  1422. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1423. if (Done != SK_AND_OK) {
  1424. return(SK_HW_PS_RESTART);
  1425. }
  1426. return(SK_HW_PS_LINK);
  1427. }
  1428. }
  1429. else { /* !AutoNeg */
  1430. /* Link is up and we don't need more */
  1431. #ifdef DEBUG
  1432. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1433. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1434. ("ERROR: Lipa auto detected on port %d\n", Port));
  1435. }
  1436. #endif /* DEBUG */
  1437. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1438. ("Link sync, Port %d\n", Port));
  1439. SkHWLinkUp(pAC, IoC, Port);
  1440. return(SK_HW_PS_LINK);
  1441. }
  1442. return(SK_HW_PS_NONE);
  1443. } /* SkGePortCheckUpGmac */
  1444. #endif /* YUKON */
  1445. #ifdef OTHER_PHY
  1446. /******************************************************************************
  1447. *
  1448. * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
  1449. *
  1450. * return:
  1451. * 0 o.k. nothing needed
  1452. * 1 Restart needed on this port
  1453. * 2 Link came up
  1454. */
  1455. static int SkGePortCheckUpLone(
  1456. SK_AC *pAC, /* Adapter Context */
  1457. SK_IOC IoC, /* IO Context */
  1458. int Port, /* Which port should be checked */
  1459. SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
  1460. {
  1461. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1462. int Done;
  1463. SK_U16 Isrc; /* Interrupt source register */
  1464. SK_U16 LpAb; /* Link Partner Ability */
  1465. SK_U16 ExtStat; /* Extended Status Register */
  1466. SK_U16 PhyStat; /* Phy Status Register */
  1467. SK_U16 StatSum;
  1468. SK_U8 NextMode; /* Next AutoSensing Mode */
  1469. pPrt = &pAC->GIni.GP[Port];
  1470. if (pPrt->PHWLinkUp) {
  1471. return(SK_HW_PS_NONE);
  1472. }
  1473. StatSum = pPrt->PIsave;
  1474. pPrt->PIsave = 0;
  1475. /*
  1476. * here we usually can check whether the link is in sync and
  1477. * auto-negotiation is done.
  1478. */
  1479. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
  1480. StatSum |= PhyStat;
  1481. SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
  1482. if ((PhyStat & PHY_ST_LSYNC) == 0) {
  1483. /* Save Auto-negotiation Done bit */
  1484. pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
  1485. #ifdef DEBUG
  1486. if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
  1487. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1488. ("AutoNeg done rescheduled Port %d\n", Port));
  1489. }
  1490. #endif /* DEBUG */
  1491. return(SK_HW_PS_NONE);
  1492. }
  1493. if (AutoNeg) {
  1494. if ((StatSum & PHY_ST_AN_OVER) != 0) {
  1495. SkHWLinkUp(pAC, IoC, Port);
  1496. Done = SkMacAutoNegDone(pAC, IoC, Port);
  1497. if (Done != SK_AND_OK) {
  1498. /* Get PHY parameters, for debugging only */
  1499. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
  1500. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
  1501. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1502. ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
  1503. Port, LpAb, ExtStat));
  1504. /* Try next possible mode */
  1505. NextMode = SkHWSenseGetNext(pAC, IoC, Port);
  1506. SkHWLinkDown(pAC, IoC, Port);
  1507. if (Done == SK_AND_DUP_CAP) {
  1508. /* GoTo next mode */
  1509. SkHWSenseSetNext(pAC, IoC, Port, NextMode);
  1510. }
  1511. return(SK_HW_PS_RESTART);
  1512. }
  1513. else {
  1514. /*
  1515. * Dummy Read interrupt status to prevent
  1516. * extra link down/ups
  1517. */
  1518. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1519. return(SK_HW_PS_LINK);
  1520. }
  1521. }
  1522. /* AutoNeg not done, but HW link is up. Check for timeouts */
  1523. pPrt->PAutoNegTimeOut++;
  1524. if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
  1525. /* Timeout occured */
  1526. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1527. ("AutoNeg timeout Port %d\n", Port));
  1528. if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
  1529. pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
  1530. /* Set Link manually up */
  1531. SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
  1532. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1533. ("Set manual full duplex Port %d\n", Port));
  1534. }
  1535. /* Do the restart */
  1536. return(SK_HW_PS_RESTART);
  1537. }
  1538. }
  1539. else {
  1540. /* Link is up and we don't need more */
  1541. #ifdef DEBUG
  1542. if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
  1543. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1544. ("ERROR: Lipa auto detected on port %d\n", Port));
  1545. }
  1546. #endif /* DEBUG */
  1547. /*
  1548. * Dummy Read interrupt status to prevent
  1549. * extra link down/ups
  1550. */
  1551. SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
  1552. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1553. ("Link sync(GP), Port %d\n", Port));
  1554. SkHWLinkUp(pAC, IoC, Port);
  1555. return(SK_HW_PS_LINK);
  1556. }
  1557. return(SK_HW_PS_NONE);
  1558. } /* SkGePortCheckUpLone */
  1559. /******************************************************************************
  1560. *
  1561. * SkGePortCheckUpNat() - Check if the link is up on National PHY
  1562. *
  1563. * return:
  1564. * 0 o.k. nothing needed
  1565. * 1 Restart needed on this port
  1566. * 2 Link came up
  1567. */
  1568. static int SkGePortCheckUpNat(
  1569. SK_AC *pAC, /* Adapter Context */
  1570. SK_IOC IoC, /* IO Context */
  1571. int Port, /* Which port should be checked */
  1572. SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
  1573. {
  1574. /* todo: National */
  1575. return(SK_HW_PS_NONE);
  1576. } /* SkGePortCheckUpNat */
  1577. #endif /* OTHER_PHY */
  1578. /******************************************************************************
  1579. *
  1580. * SkGeSirqEvent() - Event Service Routine
  1581. *
  1582. * Description:
  1583. *
  1584. * Notes:
  1585. */
  1586. int SkGeSirqEvent(
  1587. SK_AC *pAC, /* Adapter Context */
  1588. SK_IOC IoC, /* Io Context */
  1589. SK_U32 Event, /* Module specific Event */
  1590. SK_EVPARA Para) /* Event specific Parameter */
  1591. {
  1592. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1593. SK_U32 Port;
  1594. SK_U32 Val32;
  1595. int PortStat;
  1596. SK_U8 Val8;
  1597. #ifdef GENESIS
  1598. SK_U64 Octets;
  1599. #endif /* GENESIS */
  1600. Port = Para.Para32[0];
  1601. pPrt = &pAC->GIni.GP[Port];
  1602. switch (Event) {
  1603. case SK_HWEV_WATIM:
  1604. if (pPrt->PState == SK_PRT_RESET) {
  1605. PortStat = SK_HW_PS_NONE;
  1606. }
  1607. else {
  1608. /* Check whether port came up */
  1609. PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
  1610. }
  1611. switch (PortStat) {
  1612. case SK_HW_PS_RESTART:
  1613. if (pPrt->PHWLinkUp) {
  1614. /* Set Link to down */
  1615. SkHWLinkDown(pAC, IoC, (int)Port);
  1616. /*
  1617. * Signal directly to RLMT to ensure correct
  1618. * sequence of SWITCH and RESET event.
  1619. */
  1620. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1621. }
  1622. /* Restart needed */
  1623. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1624. break;
  1625. case SK_HW_PS_LINK:
  1626. /* Signal to RLMT */
  1627. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
  1628. break;
  1629. }
  1630. /* Start again the check Timer */
  1631. if (pPrt->PHWLinkUp) {
  1632. Val32 = SK_WA_ACT_TIME;
  1633. }
  1634. else {
  1635. Val32 = SK_WA_INA_TIME;
  1636. }
  1637. /* Todo: still needed for non-XMAC PHYs??? */
  1638. /* Start workaround Errata #2 timer */
  1639. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
  1640. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1641. break;
  1642. case SK_HWEV_PORT_START:
  1643. if (pPrt->PHWLinkUp) {
  1644. /*
  1645. * Signal directly to RLMT to ensure correct
  1646. * sequence of SWITCH and RESET event.
  1647. */
  1648. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1649. }
  1650. SkHWLinkDown(pAC, IoC, (int)Port);
  1651. /* Schedule Port RESET */
  1652. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  1653. /* Start workaround Errata #2 timer */
  1654. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  1655. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1656. break;
  1657. case SK_HWEV_PORT_STOP:
  1658. if (pPrt->PHWLinkUp) {
  1659. /*
  1660. * Signal directly to RLMT to ensure correct
  1661. * sequence of SWITCH and RESET event.
  1662. */
  1663. SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
  1664. }
  1665. /* Stop Workaround Timer */
  1666. SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
  1667. SkHWLinkDown(pAC, IoC, (int)Port);
  1668. break;
  1669. case SK_HWEV_UPDATE_STAT:
  1670. /* We do NOT need to update any statistics */
  1671. break;
  1672. case SK_HWEV_CLEAR_STAT:
  1673. /* We do NOT need to clear any statistics */
  1674. for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
  1675. pPrt->PPrevRx = 0;
  1676. pPrt->PPrevFcs = 0;
  1677. pPrt->PPrevShorts = 0;
  1678. }
  1679. break;
  1680. case SK_HWEV_SET_LMODE:
  1681. Val8 = (SK_U8)Para.Para32[1];
  1682. if (pPrt->PLinkModeConf != Val8) {
  1683. /* Set New link mode */
  1684. pPrt->PLinkModeConf = Val8;
  1685. /* Restart Port */
  1686. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1687. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1688. }
  1689. break;
  1690. case SK_HWEV_SET_FLOWMODE:
  1691. Val8 = (SK_U8)Para.Para32[1];
  1692. if (pPrt->PFlowCtrlMode != Val8) {
  1693. /* Set New Flow Control mode */
  1694. pPrt->PFlowCtrlMode = Val8;
  1695. /* Restart Port */
  1696. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1697. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1698. }
  1699. break;
  1700. case SK_HWEV_SET_ROLE:
  1701. /* not possible for fiber */
  1702. if (!pAC->GIni.GICopperType) {
  1703. break;
  1704. }
  1705. Val8 = (SK_U8)Para.Para32[1];
  1706. if (pPrt->PMSMode != Val8) {
  1707. /* Set New Role (Master/Slave) mode */
  1708. pPrt->PMSMode = 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_SPEED:
  1715. if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
  1716. break;
  1717. }
  1718. Val8 = (SK_U8)Para.Para32[1];
  1719. if (pPrt->PLinkSpeed != Val8) {
  1720. /* Set New Speed parameter */
  1721. pPrt->PLinkSpeed = Val8;
  1722. /* Restart Port */
  1723. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
  1724. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
  1725. }
  1726. break;
  1727. #ifdef GENESIS
  1728. case SK_HWEV_HALFDUP_CHK:
  1729. if (pAC->GIni.GIGenesis) {
  1730. /*
  1731. * half duplex hangup workaround.
  1732. * See packet arbiter timeout interrupt for description
  1733. */
  1734. pPrt->HalfDupTimerActive = SK_FALSE;
  1735. if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
  1736. pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
  1737. /* Snap statistic counters */
  1738. (void)SkXmUpdateStats(pAC, IoC, Port);
  1739. (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
  1740. Octets = (SK_U64)Val32 << 32;
  1741. (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
  1742. Octets += Val32;
  1743. if (pPrt->LastOctets == Octets) {
  1744. /* Tx hanging, a FIFO flush restarts it */
  1745. SkMacFlushTxFifo(pAC, IoC, Port);
  1746. }
  1747. }
  1748. }
  1749. break;
  1750. #endif /* GENESIS */
  1751. default:
  1752. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
  1753. break;
  1754. }
  1755. return(0);
  1756. } /* SkGeSirqEvent */
  1757. #ifdef GENESIS
  1758. /******************************************************************************
  1759. *
  1760. * SkPhyIsrBcom() - PHY interrupt service routine
  1761. *
  1762. * Description: handles all interrupts from BCom PHY
  1763. *
  1764. * Returns: N/A
  1765. */
  1766. static void SkPhyIsrBcom(
  1767. SK_AC *pAC, /* Adapter Context */
  1768. SK_IOC IoC, /* Io Context */
  1769. int Port, /* Port Num = PHY Num */
  1770. SK_U16 IStatus) /* Interrupt Status */
  1771. {
  1772. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1773. SK_EVPARA Para;
  1774. pPrt = &pAC->GIni.GP[Port];
  1775. if ((IStatus & PHY_B_IS_PSE) != 0) {
  1776. /* Incorrectable pair swap error */
  1777. SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
  1778. SKERR_SIRQ_E022MSG);
  1779. }
  1780. if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
  1781. SkHWLinkDown(pAC, IoC, Port);
  1782. Para.Para32[0] = (SK_U32)Port;
  1783. /* Signal to RLMT */
  1784. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  1785. /* Start workaround Errata #2 timer */
  1786. SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
  1787. SKGE_HWAC, SK_HWEV_WATIM, Para);
  1788. }
  1789. } /* SkPhyIsrBcom */
  1790. #endif /* GENESIS */
  1791. #ifdef YUKON
  1792. /******************************************************************************
  1793. *
  1794. * SkPhyIsrGmac() - PHY interrupt service routine
  1795. *
  1796. * Description: handles all interrupts from Marvell PHY
  1797. *
  1798. * Returns: N/A
  1799. */
  1800. static void SkPhyIsrGmac(
  1801. SK_AC *pAC, /* Adapter Context */
  1802. SK_IOC IoC, /* Io Context */
  1803. int Port, /* Port Num = PHY Num */
  1804. SK_U16 IStatus) /* Interrupt Status */
  1805. {
  1806. SK_GEPORT *pPrt; /* GIni Port struct pointer */
  1807. SK_EVPARA Para;
  1808. SK_U16 Word;
  1809. pPrt = &pAC->GIni.GP[Port];
  1810. if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
  1811. SkHWLinkDown(pAC, IoC, Port);
  1812. SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
  1813. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1814. ("AutoNeg.Adv: 0x%04X\n", Word));
  1815. /* Set Auto-negotiation advertisement */
  1816. if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
  1817. /* restore Asymmetric Pause bit */
  1818. SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
  1819. (SK_U16)(Word | PHY_M_AN_ASP));
  1820. }
  1821. Para.Para32[0] = (SK_U32)Port;
  1822. /* Signal to RLMT */
  1823. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  1824. }
  1825. if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
  1826. /* Auto-Negotiation Error */
  1827. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
  1828. }
  1829. if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
  1830. /* FIFO Overflow/Underrun Error */
  1831. SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
  1832. }
  1833. } /* SkPhyIsrGmac */
  1834. #endif /* YUKON */
  1835. #ifdef OTHER_PHY
  1836. /******************************************************************************
  1837. *
  1838. * SkPhyIsrLone() - PHY interrupt service routine
  1839. *
  1840. * Description: handles all interrupts from LONE PHY
  1841. *
  1842. * Returns: N/A
  1843. */
  1844. static void SkPhyIsrLone(
  1845. SK_AC *pAC, /* Adapter Context */
  1846. SK_IOC IoC, /* Io Context */
  1847. int Port, /* Port Num = PHY Num */
  1848. SK_U16 IStatus) /* Interrupt Status */
  1849. {
  1850. SK_EVPARA Para;
  1851. if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
  1852. SkHWLinkDown(pAC, IoC, Port);
  1853. Para.Para32[0] = (SK_U32)Port;
  1854. /* Signal to RLMT */
  1855. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  1856. }
  1857. } /* SkPhyIsrLone */
  1858. #endif /* OTHER_PHY */
  1859. /* End of File */