skgesirq.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:58k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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