skxmac2.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:60k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Name: skxmac2.c
  4.  * Project: GEnesis, PCI Gigabit Ethernet Adapter
  5.  * Version: $Revision: 1.61 $
  6.  * Date: $Date: 2001/02/09 15:40:59 $
  7.  * Purpose: Contains functions to initialize the XMAC II
  8.  *
  9.  ******************************************************************************/
  10. /******************************************************************************
  11.  *
  12.  * (C)Copyright 1998-2001 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: skxmac2.c,v $
  27.  * Revision 1.61  2001/02/09 15:40:59  rassmann
  28.  * Editorial changes.
  29.  *
  30.  * Revision 1.60  2001/02/07 15:02:01  cgoos
  31.  * Added workaround for Fujitsu switch link down.
  32.  *
  33.  * Revision 1.59  2001/01/10 09:38:06  cgoos
  34.  * Fixed Broadcom C0/A1 Id check for workaround.
  35.  *
  36.  * Revision 1.58  2000/11/29 11:30:38  cgoos
  37.  * Changed DEBUG sections with NW output to xDEBUG
  38.  *
  39.  * Revision 1.57  2000/11/27 12:40:40  rassmann
  40.  * Suppressing preamble after first access to BCom, not before (#10556).
  41.  *
  42.  * Revision 1.56  2000/11/09 12:32:48  rassmann
  43.  * Renamed variables.
  44.  *
  45.  * Revision 1.55  2000/11/09 11:30:10  rassmann
  46.  * WA: Waiting after releasing reset until BCom chip is accessible.
  47.  *
  48.  * Revision 1.54  2000/10/02 14:10:27  rassmann
  49.  * Reading BCOM PHY after releasing reset until it returns a valid value.
  50.  *
  51.  * Revision 1.53  2000/07/27 12:22:11  gklug
  52.  * fix: possible endless loop in XmHardRst.
  53.  *
  54.  * Revision 1.52  2000/05/22 08:48:31  malthoff
  55.  * Fix: #10523 errata valid for all BCOM PHYs.
  56.  *
  57.  * Revision 1.51  2000/05/17 12:52:18  malthoff
  58.  * Fixes BCom link errata (#10523).
  59.  *
  60.  * Revision 1.50  1999/11/22 13:40:14  cgoos
  61.  * Changed license header to GPL.
  62.  *
  63.  * Revision 1.49  1999/11/22 08:12:13  malthoff
  64.  * Add workaround for power consumption feature of BCom C0 chip.
  65.  *
  66.  * Revision 1.48  1999/11/16 08:39:01  malthoff
  67.  * Fix: MDIO preamble suppression is port dependent.
  68.  *
  69.  * Revision 1.47  1999/08/27 08:55:35  malthoff
  70.  * 1000BT: Optimizing MDIO transfer by oppressing MDIO preamble.
  71.  *
  72.  * Revision 1.46  1999/08/13 11:01:12  malthoff
  73.  * Fix for 1000BT: pFlowCtrlMode was not set correctly.
  74.  *
  75.  * Revision 1.45  1999/08/12 19:18:28  malthoff
  76.  * 1000BT Fixes: Do not owerwrite XM_MMU_CMD.
  77.  * Do not execute BCOM A1 workaround for B1 chips.
  78.  * Fix pause frame setting.
  79.  * Always set PHY_B_AC_TX_TST in PHY_BCOM_AUX_CTRL.
  80.  *
  81.  * Revision 1.44  1999/08/03 15:23:48  cgoos
  82.  * Fixed setting of PHY interrupt mask in half duplex mode.
  83.  *
  84.  * Revision 1.43  1999/08/03 15:22:17  cgoos
  85.  * Added some debug output.
  86.  * Disabled XMac GP0 interrupt for external PHYs.
  87.  *
  88.  * Revision 1.42  1999/08/02 08:39:23  malthoff
  89.  * BCOM PHY: TX LED: To get the mono flop behaviour it is required
  90.  * to set the LED Traffic Mode bit in PHY_BCOM_P_EXT_CTRL.
  91.  *
  92.  * Revision 1.41  1999/07/30 06:54:31  malthoff
  93.  * Add temp. workarounds for the BCOM Phy revision A1.
  94.  *
  95.  * Revision 1.40  1999/06/01 07:43:26  cgoos
  96.  * Changed Link Mode Status in SkXmAutoNegDone... from FULL/HALF to
  97.  * AUTOFULL/AUTOHALF.
  98.  *
  99.  * Revision 1.39  1999/05/19 07:29:51  cgoos
  100.  * Changes for 1000Base-T.
  101.  *
  102.  * Revision 1.38  1999/04/08 14:35:10  malthoff
  103.  * Add code for enabling signal detect. Enabling signal detect is disabled.
  104.  *
  105.  * Revision 1.37  1999/03/12 13:42:54  malthoff
  106.  * Add: Jumbo Frame Support.
  107.  * Add: Receive modes SK_LENERR_OK_ON/OFF and
  108.  * SK_BIG_PK_OK_ON/OFF in SkXmSetRxCmd().
  109.  *
  110.  * Revision 1.36  1999/03/08 10:10:55  gklug
  111.  * fix: AutoSensing did switch to next mode even if LiPa indicated offline
  112.  *
  113.  * Revision 1.35  1999/02/22 15:16:41  malthoff
  114.  * Remove some compiler warnings.
  115.  *
  116.  * Revision 1.34  1999/01/22 09:19:59  gklug
  117.  * fix: Init DupMode and InitPauseMd are now called in RxTxEnable
  118.  *
  119.  * Revision 1.33  1998/12/11 15:19:11  gklug
  120.  * chg: lipa autoneg stati
  121.  * chg: debug messages
  122.  * chg: do NOT use spurious XmIrq
  123.  *
  124.  * Revision 1.32  1998/12/10 11:08:44  malthoff
  125.  * bug fix: pAC has been used for IOs in SkXmHardRst().
  126.  * SkXmInitPhy() is also called for the Diag in SkXmInitMac().
  127.  *
  128.  * Revision 1.31  1998/12/10 10:39:11  gklug
  129.  * fix: do 4 RESETS of the XMAC at the beginning
  130.  * fix: dummy read interrupt source register BEFORE initializing the Phy
  131.  * add: debug messages
  132.  * fix: Linkpartners autoneg capability cannot be shown by TX_PAGE interrupt
  133.  *
  134.  * Revision 1.30  1998/12/07 12:18:32  gklug
  135.  * add: refinement of autosense mode: take into account the autoneg cap of LiPa
  136.  *
  137.  * Revision 1.29  1998/12/07 07:12:29  gklug
  138.  * fix: if page is received the link is  down.
  139.  *
  140.  * Revision 1.28  1998/12/01 10:12:47  gklug
  141.  * chg: if spurious IRQ from XMAC encountered, save it
  142.  *
  143.  * Revision 1.27  1998/11/26 07:33:38  gklug
  144.  * add: InitPhy call is now in XmInit function
  145.  *
  146.  * Revision 1.26  1998/11/18 13:38:24  malthoff
  147.  * 'Imsk' is also unused in SkXmAutoNegDone.
  148.  *
  149.  * Revision 1.25  1998/11/18 13:28:01  malthoff
  150.  * Remove unused variable 'Reg' in SkXmAutoNegDone().
  151.  *
  152.  * Revision 1.24  1998/11/18 13:18:45  gklug
  153.  * add: workaround for xmac errata #1
  154.  * add: detect Link Down also when Link partner requested config
  155.  * chg: XMIrq is only used when link is up
  156.  *
  157.  * Revision 1.23  1998/11/04 07:07:04  cgoos
  158.  * Added function SkXmRxTxEnable.
  159.  *
  160.  * Revision 1.22  1998/10/30 07:35:54  gklug
  161.  * fix: serve LinkDown interrupt when link is already down
  162.  *
  163.  * Revision 1.21  1998/10/29 15:32:03  gklug
  164.  * fix: Link Down signaling
  165.  *
  166.  * Revision 1.20  1998/10/29 11:17:27  gklug
  167.  * fix: AutoNegDone bug
  168.  *
  169.  * Revision 1.19  1998/10/29 10:14:43  malthoff
  170.  * Add endainesss comment for reading/writing MAC addresses.
  171.  *
  172.  * Revision 1.18  1998/10/28 07:48:55  cgoos
  173.  * Fix: ASS somtimes signaled although link is up.
  174.  *
  175.  * Revision 1.17  1998/10/26 07:55:39  malthoff
  176.  * Fix in SkXmInitPauseMd(): Pause Mode
  177.  * was disabled and not enabled.
  178.  * Fix in SkXmAutoNegDone(): Checking Mode bits
  179.  * always failed, becaues of some missing braces.
  180.  *
  181.  * Revision 1.16  1998/10/22 09:46:52  gklug
  182.  * fix SysKonnectFileId typo
  183.  *
  184.  * Revision 1.15  1998/10/21 05:51:37  gklug
  185.  * add: para DoLoop to InitPhy function for loopback set-up
  186.  *
  187.  * Revision 1.14  1998/10/16 10:59:23  malthoff
  188.  * Remove Lint warning for dummy reads.
  189.  *
  190.  * Revision 1.13  1998/10/15 14:01:20  malthoff
  191.  * Fix: SkXmAutoNegDone() is (int) but does not return a value.
  192.  *
  193.  * Revision 1.12  1998/10/14 14:45:04  malthoff
  194.  * Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by
  195.  * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independant
  196.  * from the Sirq module.
  197.  *
  198.  * Revision 1.11  1998/10/14 13:59:01  gklug
  199.  * add: InitPhy function
  200.  *
  201.  * Revision 1.10  1998/10/14 11:20:57  malthoff
  202.  * Make SkXmAutoNegDone() public, because it's
  203.  * used in diagnostics, too.
  204.  * The Link Up event to the RLMT is issued in
  205.  * SkXmIrq(). SkXmIrq() is not available in
  206.  * diagnostics. Use PHY_READ when reading
  207.  * PHY registers.
  208.  *
  209.  * Revision 1.9  1998/10/14 05:50:10  cgoos
  210.  * Added definition for Para.
  211.  *
  212.  * Revision 1.8  1998/10/14 05:41:28  gklug
  213.  * add: Xmac IRQ
  214.  * add: auto negotiation done function
  215.  *
  216.  * Revision 1.7  1998/10/09 06:55:20  malthoff
  217.  * The configuration of the XMACs Tx Request Threshold
  218.  * depends from the drivers port usage now. The port
  219.  * usage is configured in GIPortUsage.
  220.  *
  221.  * Revision 1.6  1998/10/05 07:48:00  malthoff
  222.  * minor changes
  223.  *
  224.  * Revision 1.5  1998/10/01 07:03:54  gklug
  225.  * add: dummy function for XMAC ISR
  226.  *
  227.  * Revision 1.4  1998/09/30 12:37:44  malthoff
  228.  * Add SkXmSetRxCmd() and related code.
  229.  *
  230.  * Revision 1.3  1998/09/28 13:26:40  malthoff
  231.  * Add SkXmInitMac(), SkXmInitDupMd(), and SkXmInitPauseMd()
  232.  *
  233.  * Revision 1.2  1998/09/16 14:34:21  malthoff
  234.  * Add SkXmClrExactAddr(), SkXmClrSrcCheck(),
  235.  * SkXmClrHashAddr(), SkXmFlushTxFifo(),
  236.  * SkXmFlushRxFifo(), and SkXmHardRst().
  237.  * Finish Coding of SkXmSoftRst().
  238.  * The sources may be compiled now.
  239.  *
  240.  * Revision 1.1  1998/09/04 10:05:56  malthoff
  241.  * Created.
  242.  *
  243.  *
  244.  ******************************************************************************/
  245. #include "h/skdrv1st.h"
  246. #include "h/xmac_ii.h"
  247. #include "h/skdrv2nd.h"
  248. /* defines ********************************************************************/
  249. /* typedefs *******************************************************************/
  250. /* global variables ***********************************************************/
  251. /* local variables ************************************************************/
  252. static const char SysKonnectFileId[] =
  253. "@(#)$Id: skxmac2.c,v 1.61 2001/02/09 15:40:59 rassmann Exp $ (C) SK ";
  254. /* BCOM PHY magic pattern list */
  255. typedef struct s_PhyHack {
  256. int PhyReg; /* Phy register */
  257. SK_U16 PhyVal; /* Value to write */
  258. } BCOM_HACK;
  259. BCOM_HACK BcomRegA1Hack[] = {
  260.  { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
  261.  { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
  262.  { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
  263.  { 0, 0 }
  264. };
  265. BCOM_HACK BcomRegC0Hack[] = {
  266.  { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
  267.  { 0x15, 0x0A04 }, { 0x18, 0x0420 },
  268.  { 0, 0 }
  269. };
  270. /* function prototypes ********************************************************/
  271. static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
  272. static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
  273. static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
  274. static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
  275. static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
  276. static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
  277. static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
  278. static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
  279. /******************************************************************************
  280.  *
  281.  * SkXmSetRxCmd() - Modify the value of the XMACs Rx Command Register
  282.  *
  283.  * Description:
  284.  * The features
  285.  *  o FCS stripping, SK_STRIP_FCS_ON/OFF
  286.  *  o pad byte stripping, SK_STRIP_PAD_ON/OFF
  287.  *  o don't set XMR_FS_ERR in frame SK_LENERR_OK_ON/OFF
  288.  *    status for inrange length error
  289.  *    frames, and
  290.  *  o don't set XMR_FS_ERR in frame SK_BIG_PK_OK_ON/OFF
  291.  *    status for frames > 1514 bytes
  292.  *
  293.  * for incomming packets may be enabled/disabled by this function.
  294.  * Additional modes may be added later.
  295.  * Multiple modes can be enabled/disabled at the same time.
  296.  * The new configuration is stored into the HWAC port configuration
  297.  * and is written to the Receive Command register immediatlely.
  298.  * The new configuration is saved over any SkGePortStop() and
  299.  * SkGeInitPort() calls. The configured value will be overwritten
  300.  * when SkGeInit(Level 0) is executed.
  301.  *
  302.  * Returns:
  303.  * nothing
  304.  */
  305. void SkXmSetRxCmd(
  306. SK_AC *pAC, /* adapter context */
  307. SK_IOC IoC, /* IO context */
  308. int Port, /* The XMAC to handle with belongs to this Port */
  309. int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
  310.    SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
  311. {
  312. SK_GEPORT *pPrt;
  313. SK_U16 OldRxMode;
  314. pPrt = &pAC->GIni.GP[Port];
  315. OldRxMode = pPrt->PRxCmd;
  316. switch(Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
  317. case SK_STRIP_FCS_ON:
  318. pPrt->PRxCmd |= XM_RX_STRIP_FCS;
  319. break;
  320. case SK_STRIP_FCS_OFF:
  321. pPrt->PRxCmd &= ~XM_RX_STRIP_FCS;
  322. break;
  323. }
  324. switch(Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
  325. case SK_STRIP_PAD_ON:
  326. pPrt->PRxCmd |= XM_RX_STRIP_PAD;
  327. break;
  328. case SK_STRIP_PAD_OFF:
  329. pPrt->PRxCmd &= ~XM_RX_STRIP_PAD;
  330. break;
  331. }
  332. switch(Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
  333. case SK_LENERR_OK_ON:
  334. pPrt->PRxCmd |= XM_RX_LENERR_OK;
  335. break;
  336. case SK_LENERR_OK_OFF:
  337. pPrt->PRxCmd &= ~XM_RX_LENERR_OK;
  338. break;
  339. }
  340. switch(Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
  341. case SK_BIG_PK_OK_ON:
  342. pPrt->PRxCmd |= XM_RX_BIG_PK_OK;
  343. break;
  344. case SK_BIG_PK_OK_OFF:
  345. pPrt->PRxCmd &= ~XM_RX_BIG_PK_OK;
  346. break;
  347. }
  348. /* Write the new mode to the receive command register if required */
  349. if (OldRxMode != pPrt->PRxCmd) {
  350. XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd);
  351. }
  352. } /* SkXmSetRxCmd*/
  353. /******************************************************************************
  354.  *
  355.  * SkXmClrExactAddr() - Clear Exact Match Address Registers
  356.  *
  357.  * Description:
  358.  * All Exact Match Address registers of the XMAC 'Port' will be
  359.  * cleared starting with 'StartNum' up to (and including) the
  360.  * Exact Match address number of 'StopNum'.
  361.  *
  362.  * Returns:
  363.  * nothing
  364.  */
  365. void SkXmClrExactAddr(
  366. SK_AC *pAC, /* adapter context */
  367. SK_IOC IoC, /* IO context */
  368. int Port, /* The XMAC to handle with belongs to this Port */
  369. int StartNum, /* Begin with this Address Register Index (0..15) */
  370. int StopNum) /* Stop after finished with this Register Idx (0..15) */
  371. {
  372. int i;
  373. SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
  374. if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
  375. StartNum > StopNum) {
  376. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
  377. return;
  378. }
  379. for (i = StartNum; i <= StopNum; i++) {
  380. XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
  381. }
  382. } /* SkXmClrExactAddr */
  383. /******************************************************************************
  384.  *
  385.  * SkXmClrSrcCheck() - Clear Source Check Address Register
  386.  *
  387.  * Description:
  388.  * The Source Check Address Register of the XMAC 'Port' number
  389.  * will be cleared.
  390.  *
  391.  * Returns:
  392.  * nothing
  393.  */
  394. static void SkXmClrSrcCheck(
  395. SK_AC *pAC, /* adapter context */
  396. SK_IOC IoC, /* IO context */
  397. int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */
  398. {
  399. SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
  400. XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
  401. } /* SkXmClrSrcCheck */
  402. /******************************************************************************
  403.  *
  404.  * SkXmClrHashAddr() - Clear Hash Address Registers
  405.  *
  406.  * Description:
  407.  * The Hash Address Register of the XMAC 'Port' will be cleared.
  408.  *
  409.  * Returns:
  410.  * nothing
  411.  */
  412. static void SkXmClrHashAddr(
  413. SK_AC *pAC, /* adapter context */
  414. SK_IOC IoC, /* IO context */
  415. int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */
  416. {
  417. SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
  418. XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
  419. } /* SkXmClrHashAddr*/
  420. /******************************************************************************
  421.  *
  422.  * SkXmFlushTxFifo() - Flush the XMACs transmit FIFO
  423.  *
  424.  * Description:
  425.  * Flush the transmit FIFO of the XMAC specified by the index 'Port'
  426.  *
  427.  * Returns:
  428.  * nothing
  429.  */
  430. void SkXmFlushTxFifo(
  431. SK_AC *pAC, /* adapter context */
  432. SK_IOC IoC, /* IO context */
  433. int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */
  434. {
  435. SK_U32 MdReg;
  436. XM_IN32(IoC, Port, XM_MODE, &MdReg);
  437. MdReg |= XM_MD_FTF;
  438. XM_OUT32(IoC, Port, XM_MODE, MdReg);
  439. } /* SkXmFlushTxFifo */
  440. /******************************************************************************
  441.  *
  442.  * SkXmFlushRxFifo() - Flush the XMACs receive FIFO
  443.  *
  444.  * Description:
  445.  * Flush the receive FIFO of the XMAC specified by the index 'Port'
  446.  *
  447.  * Returns:
  448.  * nothing
  449.  */
  450. void SkXmFlushRxFifo(
  451. SK_AC *pAC, /* adapter context */
  452. SK_IOC IoC, /* IO context */
  453. int Port) /* The XMAC to handle with belongs to this Port (MAC_1 + n) */
  454. {
  455. SK_U32 MdReg;
  456. XM_IN32(IoC, Port, XM_MODE, &MdReg);
  457. MdReg |= XM_MD_FRF;
  458. XM_OUT32(IoC, Port, XM_MODE, MdReg);
  459. } /* SkXmFlushRxFifo*/
  460. /******************************************************************************
  461.  *
  462.  * SkXmSoftRst() - Do a XMAC software reset
  463.  *
  464.  * Description:
  465.  * The PHY registers should not be destroyed during this
  466.  * kind of software reset. Therefore the XMAC Software Reset
  467.  * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
  468.  *
  469.  * The software reset is done by
  470.  * - disabling the Rx and Tx state maschine,
  471.  * - reseting the statistics module,
  472.  * - clear all other significant XMAC Mode,
  473.  *   Command, and Control Registers
  474.  * - clearing the Hash Register and the
  475.  *   Exact Match Address registers, and
  476.  * - flushing the XMAC's Rx and Tx FIFOs.
  477.  *
  478.  * Note:
  479.  * Another requirement when stopping the XMAC is to
  480.  * avoid sending corrupted frames on the network.
  481.  * Disabling the Tx state maschine will NOT interrupt
  482.  * the currently transmitted frame. But we must take care
  483.  * that the tx FIFO is cleared AFTER the current frame
  484.  * is complete sent to the network.
  485.  *
  486.  * It takes about 12ns to send a frame with 1538 bytes.
  487.  * One PCI clock goes at least 15ns (66MHz). Therefore
  488.  * after reading XM_GP_PORT back, we are sure that the
  489.  * transmitter is disabled AND idle. And this means
  490.  * we may flush the transmit FIFO now.
  491.  *
  492.  * Returns:
  493.  * nothing
  494.  */
  495. void SkXmSoftRst(
  496. SK_AC *pAC, /* adapter context */
  497. SK_IOC IoC, /* IO context */
  498. int Port) /* port to stop (MAC_1 + n) */
  499. {
  500. SK_GEPORT *pPrt;
  501. SK_U16 Word;
  502. pPrt = &pAC->GIni.GP[Port];
  503. /* disable the receiver and transmitter */
  504. XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
  505. XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX|XM_MMU_ENA_TX));
  506. /* reset the statistics module */
  507. XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
  508. /*
  509.  * clear all other significant XMAC Mode,
  510.  * Command, and Control Registers
  511.  */
  512. XM_OUT16(IoC, Port, XM_IMSK, 0xffff); /* disable all IRQs */
  513. XM_OUT32(IoC, Port, XM_MODE, 0x00000000); /* clear Mode Reg */
  514. XM_OUT16(IoC, Port, XM_TX_CMD, 0x0000); /* reset TX CMD Reg */
  515. XM_OUT16(IoC, Port, XM_RX_CMD, 0x0000); /* reset RX CMD Reg */
  516. /* disable all PHY IRQs */
  517. switch (pAC->GIni.GP[Port].PhyType) {
  518. case SK_PHY_BCOM:
  519. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, 0xffff);
  520. break;
  521. case SK_PHY_LONE:
  522. PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, 0x0);
  523. break;
  524. case SK_PHY_NAT:
  525. /* todo: National
  526.  PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 
  527. 0xffff); */
  528. break;
  529. }
  530. /* clear the Hash Register */
  531. SkXmClrHashAddr(pAC, IoC, Port);
  532. /* clear the Exact Match Address registers */
  533. SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
  534. SkXmClrSrcCheck(pAC, IoC, Port);
  535. /* flush the XMAC's Rx and Tx FIFOs */
  536. SkXmFlushTxFifo(pAC, IoC, Port);
  537. SkXmFlushRxFifo(pAC, IoC, Port);
  538. pAC->GIni.GP[Port].PState = SK_PRT_STOP;
  539. } /* SkXmSoftRst*/
  540. /******************************************************************************
  541.  *
  542.  * SkXmHardRst() - Do a XMAC hardware reset
  543.  *
  544.  * Description:
  545.  * The XMAC of the specified 'Port' and all connected devices
  546.  * (PHY and SERDES) will receive a reset signal on its *Reset
  547.  * pins.
  548.  * External PHYs must be reset be clearing a bit in the GPIO
  549.  * register (Timing requirements: Broadcom: 400ns, Level One:
  550.  * none, National: 80ns).
  551.  *
  552.  * ATTENTION:
  553.  *  It is absolutely neccessary to reset the SW_RST Bit first
  554.  * before calling this function.
  555.  *
  556.  * Returns:
  557.  * nothing
  558.  */
  559. void SkXmHardRst(
  560. SK_AC *pAC, /* adapter context */
  561. SK_IOC IoC, /* IO context */
  562. int Port) /* port to stop (MAC_1 + n) */
  563. {
  564. SK_U32 Reg;
  565. int i;
  566. int TOut;
  567. SK_U16 Word;
  568. for (i = 0; i < 4; i++) {
  569. /* TX_MFF_CTRL1 is a 32 bit register but only the lowest 16 */
  570. /* bit contains buttoms to press */
  571. SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);
  572. TOut = 0;
  573. do {
  574. TOut ++;
  575. if (TOut > 10000) {
  576. /*
  577.  * Adapter seems to be in RESET state.
  578.  * Registers cannot be written.
  579.  */
  580. return;
  581. }
  582. SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
  583. (SK_U16) MFF_SET_MAC_RST);
  584. SK_IN16(IoC,MR_ADDR(Port,TX_MFF_CTRL1), &Word);
  585. } while ((Word & MFF_SET_MAC_RST) == 0);
  586. }
  587. /* For external PHYs there must be special handling */
  588. if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
  589. /* reset external PHY */
  590. SK_IN32(IoC, B2_GP_IO, &Reg);
  591. if (Port == 0) {
  592. Reg |= GP_DIR_0; /* set to output */
  593. Reg &= ~GP_IO_0;
  594. }
  595. else {
  596. Reg |= GP_DIR_2; /* set to output */
  597. Reg &= ~GP_IO_2;
  598. }
  599. SK_OUT32(IoC, B2_GP_IO, Reg);
  600. /* short delay */
  601. SK_IN32(IoC, B2_GP_IO, &Reg);
  602. }
  603. pAC->GIni.GP[Port].PState = SK_PRT_RESET;
  604. } /* SkXmHardRst */
  605. /******************************************************************************
  606.  *
  607.  * SkXmInitMac() - Initialize the XMAC II
  608.  *
  609.  * Description:
  610.  * Initialize all the XMAC of the specified port.
  611.  * The XMAC must be reset or stopped before calling this function.
  612.  *
  613.  * Note:
  614.  * The XMAC's Rx and Tx state machine is still disabled when returning.
  615.  *
  616.  * Returns:
  617.  * nothing
  618.  */
  619. void SkXmInitMac(
  620. SK_AC *pAC, /* adapter context */
  621. SK_IOC IoC, /* IO context */
  622. int Port) /* Port Index (MAC_1 + n) */
  623. {
  624. SK_GEPORT *pPrt;
  625. SK_U32 Reg;
  626. int i;
  627. SK_U16 SWord;
  628. SK_U16 PhyId;
  629. pPrt = &pAC->GIni.GP[Port];
  630. if (pPrt->PState == SK_PRT_STOP) {
  631. /* Port State: SK_PRT_STOP */
  632. /* Verify that the reset bit is cleared */
  633. SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
  634. if (SWord & (SK_U16)MFF_SET_MAC_RST) {
  635. /* PState does not match HW state */
  636. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
  637. /* Correct it. */
  638. pPrt->PState = SK_PRT_RESET;
  639. }
  640. }
  641. if (pPrt->PState == SK_PRT_RESET) {
  642. /*
  643.  * clear HW reset
  644.  * Note: The SW reset is self clearing, therefore there is
  645.  *  nothing to do here.
  646.  */
  647. SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), (SK_U16)MFF_CLR_MAC_RST);
  648. /* Ensure that XMAC reset release is done (errata from LReinbold?). */
  649. SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
  650. /* Clear PHY reset. */
  651. if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
  652. SK_IN32(IoC, B2_GP_IO, &Reg);
  653. if (Port == 0) {
  654. Reg |= GP_DIR_0; /* Set to output. */
  655. Reg |= GP_IO_0;
  656. }
  657. else {
  658. Reg |= GP_DIR_2; /* Set to output. */
  659. Reg |= GP_IO_2;
  660. }
  661. SK_OUT32(IoC, B2_GP_IO, Reg);
  662. /* Enable GMII interface. */
  663. XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
  664. PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &PhyId);
  665. #ifdef xDEBUG
  666. if (SWord == 0xFFFF) {
  667. i = 1;
  668. do {
  669. PHY_READ(IoC, pPrt, Port, PHY_XMAC_ID1, &SWord);
  670. i++;
  671. /* Limit retries; else machine may hang. */
  672. } while (SWord == 0xFFFF && i < 500000);
  673. CMSMPrintString(
  674. pAC->pConfigTable,
  675. MSG_TYPE_RUNTIME_INFO,
  676. "ID1 is %x after %d reads.",
  677. (void *)SWord,
  678. (void *)i);
  679. /* Trigger PCI analyzer */
  680. /* SK_IN32(IoC, 0x012c, &Reg); */
  681. }
  682. #endif /* DEBUG */
  683. /*
  684.  * Optimize MDIO transfer by suppressing preamble.
  685.  * Must be done AFTER first access to BCOM chip.
  686.  */
  687. XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
  688. XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
  689. if (PhyId == 0x6044) {
  690. /* Workaround BCOM Errata for the C0 type. */
  691. /* Write magic patterns to reserved registers. */
  692. i = 0;
  693. while (BcomRegC0Hack[i].PhyReg != 0) {
  694. PHY_WRITE(IoC, pPrt, Port, BcomRegC0Hack[i].PhyReg,
  695. BcomRegC0Hack[i].PhyVal);
  696. i++;
  697. }
  698. }
  699. else if (PhyId == 0x6041) {
  700. /* Workaround BCOM Errata for the A1 type. */
  701. /* Write magic patterns to reserved registers. */
  702. i = 0;
  703. while (BcomRegA1Hack[i].PhyReg != 0) {
  704. PHY_WRITE(IoC, pPrt, Port, BcomRegA1Hack[i].PhyReg,
  705. BcomRegA1Hack[i].PhyVal);
  706. i++;
  707. }
  708. }
  709. /* Workaround BCOM Errata (#10523) for all BCom PHYs. */
  710. /* Disable Power Management after reset. */
  711. PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
  712. #ifdef xDEBUG
  713. if (SWord == 0xFFFF) {
  714. i = 1;
  715. do {
  716. PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
  717. i++;
  718. /* Limit retries; else machine may hang. */
  719. } while (SWord == 0xFFFF && i < 500000);
  720. CMSMPrintString(
  721. pAC->pConfigTable,
  722. MSG_TYPE_RUNTIME_INFO,
  723. "AUX_CTRL is %x after %d reads.",
  724. (void *)SWord,
  725. (void *)i);
  726. /* Trigger PCI analyzer */
  727. /* SK_IN32(IoC, 0x012c, &Reg); */
  728. }
  729. #endif /* DEBUG */
  730. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
  731. SWord | PHY_B_AC_DIS_PM);
  732. /* PHY LED initialization is done in SkGeXmitLED(), not here. */
  733. }
  734. /* Dummy read the Interrupt source register */
  735. XM_IN16(IoC, Port, XM_ISRC, &SWord);
  736. /*
  737.  * The autonegotiation process starts immediately after
  738.  * clearing the reset. The autonegotiation process should be
  739.  * started by the SIRQ, therefore stop it here immediately.
  740.  */
  741. SkXmInitPhy(pAC, IoC, Port, SK_FALSE);
  742. #if 0
  743. /* temp. code: enable signal detect */
  744. /* WARNING: do not override GMII setting above */
  745. XM_OUT16(pAC, Port, XM_HW_CFG, XM_HW_COM4SIG);
  746. #endif
  747. }
  748. /*
  749.  * configure the XMACs Station Address
  750.  * B2_MAC_2 = xx xx xx xx xx x1 is programed to XMAC A
  751.  * B2_MAC_3 = xx xx xx xx xx x2 is programed to XMAC B
  752.  */
  753. for (i = 0; i < 3; i++) {
  754. /*
  755.  * The following 2 statements are together endianess
  756.  * independant. Remember this when changing.
  757.  */
  758. SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
  759. XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
  760. }
  761. /* Tx Inter Packet Gap (XM_TX_IPG): use default */
  762. /* Tx High Water Mark (XM_TX_HI_WM): use default */
  763. /* Tx Low Water Mark (XM_TX_LO_WM): use default */
  764. /* Host Request Threshold (XM_HT_THR): use default */
  765. /* Rx Request Threshold (XM_RX_THR): use default */
  766. /* Rx Low Water Mark (XM_RX_LO_WM): use default */
  767. /* configure Rx High Water Mark (XM_RX_HI_WM) */
  768. XM_OUT16(IoC, Port, XM_RX_HI_WM, 0x05aa);
  769. if (pAC->GIni.GIMacsFound > 1) {
  770. switch (pAC->GIni.GIPortUsage) {
  771. case SK_RED_LINK:
  772. /* Configure Tx Request Threshold for red. link */
  773. XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_REDL);
  774. break;
  775. case SK_MUL_LINK:
  776. /* Configure Tx Request Threshold for load bal. */
  777. XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_MULL);
  778. break;
  779. case SK_JUMBO_LINK:
  780. /* Configure Tx Request Threshold for jumbo frames */
  781. XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_JUMBO);
  782. break;
  783. default:
  784. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014,
  785. SKERR_HWI_E014MSG);
  786. break;
  787. }
  788. }
  789. else {
  790. /* Configure Tx Request Threshold for single port */
  791. XM_OUT16(IoC, Port, XM_TX_THR, SK_XM_THR_SL);
  792. }
  793. /*
  794.  * setup register defaults for the Rx Command Register
  795.  * - Enable Automatic Frame Padding on Tx side
  796.  */
  797. XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
  798. /*
  799.  * setup register defaults for the Rx Command Register,
  800.  * program value of PRxCmd
  801.  */
  802. XM_OUT16(IoC, Port, XM_RX_CMD, pPrt->PRxCmd);
  803. /*
  804.  * setup register defaults for the Mode Register
  805.  * - Don't strip error frames to avoid Store & Forward
  806.  *   on the rx side.
  807.  * - Enable 'Check Station Address' bit
  808.  * - Enable 'Check Address Array' bit
  809.  */
  810. XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
  811. /*
  812.  * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
  813.  * - Enable all bits excepting 'Octets Rx OK Low CntOv'
  814.  *   and 'Octets Rx OK Hi Cnt Ov'.
  815.  */
  816. XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
  817. /*
  818.  * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
  819.  * - Enable all bits excepting 'Octets Tx OK Low CntOv'
  820.  *   and 'Octets Tx OK Hi Cnt Ov'.
  821.  */
  822. XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
  823. /*
  824.  * Do NOT init XMAC interrupt mask here.
  825.  * All interrupts remain disable until link comes up!
  826.  */
  827. pPrt->PState = SK_PRT_INIT;
  828. /*
  829.  * Any additional configuration changes may be done now.
  830.  * The last action is to enable the rx and tx state machine.
  831.  * This should be done after the autonegotiation process
  832.  * has been completed successfully.
  833.  */
  834. } /* SkXmInitMac*/
  835. /******************************************************************************
  836.  *
  837.  * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
  838.  *
  839.  * Description:
  840.  * This function initilaizes the XMACs Duplex Mode.
  841.  * It should be called after successfully finishing
  842.  * the Autonegotiation Process
  843.  *
  844.  * Returns:
  845.  * nothing
  846.  */
  847. void SkXmInitDupMd(
  848. SK_AC *pAC, /* adapter context */
  849. SK_IOC IoC, /* IO context */
  850. int Port) /* Port Index (MAC_1 + n) */
  851. {
  852. switch (pAC->GIni.GP[Port].PLinkModeStatus) {
  853. case SK_LMODE_STAT_AUTOHALF:
  854. case SK_LMODE_STAT_HALF:
  855. /* Configuration Actions for Half Duplex Mode */
  856. /*
  857.  * XM_BURST = default value. We are propable not quick
  858.  *  enough at the 'XMAC' bus to burst 8kB.
  859.  * The XMAC stopps bursting if no transmit frames
  860.  * are available or the burst limit is exceeded.
  861.  */
  862. /* XM_TX_RT_LIM = default value (15) */
  863. /* XM_TX_STIME = default value (0xff = 4096 bit times) */
  864. break;
  865. case SK_LMODE_STAT_AUTOFULL:
  866. case SK_LMODE_STAT_FULL:
  867. /* Configuration Actions for Full Duplex Mode */
  868. /*
  869.  * The duplex mode is configured by the PHY,
  870.  * therefore it seems to be that there is nothing
  871.  * to do here.
  872.  */
  873. break;
  874. case SK_LMODE_STAT_UNKNOWN:
  875. default:
  876. SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
  877. break;
  878. }
  879. } /* SkXmInitDupMd */
  880. /******************************************************************************
  881.  *
  882.  * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
  883.  *
  884.  * Description:
  885.  * This function initilaizes the Pause Mode which should
  886.  * be used for this port.
  887.  * It should be called after successfully finishing
  888.  * the Autonegotiation Process
  889.  *
  890.  * Returns:
  891.  * nothing
  892.  */
  893. void SkXmInitPauseMd(
  894. SK_AC *pAC, /* adapter context */
  895. SK_IOC IoC, /* IO context */
  896. int Port) /* Port Index (MAC_1 + n) */
  897. {
  898. SK_GEPORT *pPrt;
  899. SK_U32 DWord;
  900. SK_U16 Word;
  901. pPrt = &pAC->GIni.GP[Port];
  902. if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
  903. pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
  904. /* Disable Pause Frame Reception */
  905. XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
  906. XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_IGN_PF);
  907. }
  908. else {
  909. /*
  910.  * enabling pause frame reception is required for 1000BT 
  911.  * because the XMAC is not reset if the link is going down
  912.  */
  913. /* Enable Pause Frame Reception */
  914. XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
  915. XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~XM_MMU_IGN_PF);
  916. }
  917. if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
  918. pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
  919. /*
  920.  * Configure Pause Frame Generation
  921.  * Use internal and external Pause Frame Generation.
  922.  * Sending pause frames is edge triggert. Send a
  923.  * Pause frame with the maximum pause time if
  924.  * internal oder external FIFO full condition
  925.  * occurs. Send a zero pause time frame to
  926.  * start transmission again.
  927.  */
  928. /* XM_PAUSE_DA = '010000C28001' (default) */
  929. /* XM_MAC_PTIME = 0xffff (maximum) */
  930. /* remember this value is defined in big endian (!) */
  931. XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
  932. /* Set Pause Mode in Mode Register */
  933. XM_IN32(IoC, Port, XM_MODE, &DWord);
  934. XM_OUT32(IoC, Port, XM_MODE, DWord | XM_PAUSE_MODE);
  935. /* Set Pause Mode in MAC Rx FIFO */
  936. SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_ENA_PAUSE);
  937. }
  938. else {
  939. /*
  940.  * disable pause frame generation is required for 1000BT 
  941.  * because the XMAC is not reset if the link is going down
  942.  */
  943. /* Disable Pause Mode in Mode Register */
  944. XM_IN32(IoC, Port, XM_MODE, &DWord);
  945. XM_OUT32(IoC, Port, XM_MODE, DWord & ~XM_PAUSE_MODE);
  946. /* Disable Pause Mode in MAC Rx FIFO */
  947. SK_OUT16(IoC, MR_ADDR(Port,RX_MFF_CTRL1), MFF_DIS_PAUSE);
  948. }
  949. } /* SkXmInitPauseMd*/
  950. /******************************************************************************
  951.  *
  952.  * SkXmInitPhy() - Initialize the XMAC II Phy registers
  953.  *
  954.  * Description:
  955.  * Initialize all the XMACs Phy registers
  956.  *
  957.  * Note:
  958.  *
  959.  * Returns:
  960.  * nothing
  961.  */
  962. void SkXmInitPhy(
  963. SK_AC *pAC, /* adapter context */
  964. SK_IOC IoC, /* IO context */
  965. int Port, /* Port Index (MAC_1 + n) */
  966. SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */
  967. {
  968. SK_GEPORT *pPrt;
  969. pPrt = &pAC->GIni.GP[Port];
  970. switch (pPrt->PhyType) {
  971. case SK_PHY_XMAC:
  972. SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
  973. break;
  974. case SK_PHY_BCOM:
  975. SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
  976. break;
  977. case SK_PHY_LONE:
  978. SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
  979. break;
  980. case SK_PHY_NAT:
  981. SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
  982. break;
  983. }
  984. } /* SkXmInitPhy*/
  985. /******************************************************************************
  986.  *
  987.  * SkXmInitPhyXmac() - Initialize the XMAC II Phy registers
  988.  *
  989.  * Description:
  990.  * Initialize all the XMACs Phy registers
  991.  *
  992.  * Note:
  993.  *
  994.  * Returns:
  995.  * nothing
  996.  */
  997. static void SkXmInitPhyXmac(
  998. SK_AC *pAC, /* adapter context */
  999. SK_IOC IoC, /* IO context */
  1000. int Port, /* Port Index (MAC_1 + n) */
  1001. SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */
  1002. {
  1003. SK_GEPORT *pPrt;
  1004. SK_U16 Ctrl;
  1005. pPrt = &pAC->GIni.GP[Port];
  1006. /* Autonegotiation ? */
  1007. if (pPrt->PLinkMode == SK_LMODE_HALF ||
  1008.     pPrt->PLinkMode == SK_LMODE_FULL) {
  1009. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1010. ("InitPhyXmac: no autonegotiation Port %dn", Port));
  1011. /* No Autonegiotiation */
  1012. /* Set DuplexMode in Config register */
  1013. Ctrl = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
  1014. /*
  1015.  * Do NOT enable Autonegotiation here. This would hold
  1016.  * the link down because no IDLES are transmitted
  1017.  */
  1018. }
  1019. else {
  1020. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1021. ("InitPhyXmac: with autonegotiation Port %dn", Port));
  1022. /* Set Autonegotiation advertisement */
  1023. Ctrl = 0;
  1024. /* Set Full/half duplex capabilities */
  1025. switch (pPrt->PLinkMode) {
  1026. case SK_LMODE_AUTOHALF:
  1027. Ctrl |= PHY_X_AN_HD;
  1028. break;
  1029. case SK_LMODE_AUTOFULL:
  1030. Ctrl |= PHY_X_AN_FD;
  1031. break;
  1032. case SK_LMODE_AUTOBOTH:
  1033. Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
  1034. break;
  1035. default:
  1036. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1037. SKERR_HWI_E015, SKERR_HWI_E015MSG);
  1038. }
  1039. switch (pPrt->PFlowCtrlMode) {
  1040. case SK_FLOW_MODE_NONE:
  1041. Ctrl |= PHY_X_P_NO_PAUSE;
  1042. break;
  1043. case SK_FLOW_MODE_LOC_SEND:
  1044. Ctrl |= PHY_X_P_ASYM_MD;
  1045. break;
  1046. case SK_FLOW_MODE_SYMMETRIC:
  1047. Ctrl |= PHY_X_P_SYM_MD;
  1048. break;
  1049. case SK_FLOW_MODE_SYM_OR_REM:
  1050. Ctrl |= PHY_X_P_BOTH_MD;
  1051. break;
  1052. default:
  1053. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1054. SKERR_HWI_E016, SKERR_HWI_E016MSG);
  1055. }
  1056. /* Write AutoNeg Advertisement Register */
  1057. PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_AUNE_ADV, Ctrl);
  1058. /* Restart Autonegotiation */
  1059. Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
  1060. }
  1061. if (DoLoop) {
  1062. /* Set the Phy Loopback bit, too */
  1063. Ctrl |= PHY_CT_LOOP;
  1064. }
  1065. /* Write to the Phy control register */
  1066. PHY_WRITE(IoC, pPrt, Port, PHY_XMAC_CTRL, Ctrl);
  1067. } /* SkXmInitPhyXmac*/
  1068. /******************************************************************************
  1069.  *
  1070.  * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
  1071.  *
  1072.  * Description:
  1073.  * Initialize all the Broadcom Phy registers
  1074.  *
  1075.  * Note:
  1076.  *
  1077.  * Returns:
  1078.  * nothing
  1079.  */
  1080. static void SkXmInitPhyBcom(
  1081. SK_AC *pAC, /* adapter context */
  1082. SK_IOC IoC, /* IO context */
  1083. int Port, /* Port Index (MAC_1 + n) */
  1084. SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */
  1085. {
  1086. SK_GEPORT *pPrt;
  1087. SK_U16 Ctrl1;
  1088. SK_U16 Ctrl2;
  1089. SK_U16 Ctrl3;
  1090. SK_U16 Ctrl4;
  1091. SK_U16 Ctrl5;
  1092. Ctrl1 = PHY_B_CT_SP1000;
  1093. Ctrl2 = 0;
  1094. Ctrl3 = PHY_SEL_TYPE;
  1095. Ctrl4 = PHY_B_PEC_EN_LTR;
  1096. Ctrl5 = PHY_B_AC_TX_TST;
  1097. pPrt = &pAC->GIni.GP[Port];
  1098. /* manually Master/Slave ? */
  1099. if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
  1100. Ctrl2 |= PHY_B_1000C_MSE;
  1101. if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
  1102. Ctrl2 |= PHY_B_1000C_MSC;
  1103. }
  1104. }
  1105. /* Autonegotiation ? */
  1106. if (pPrt->PLinkMode == SK_LMODE_HALF ||
  1107.     pPrt->PLinkMode == SK_LMODE_FULL) {
  1108. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1109. ("InitPhyBcom: no autonegotiation Port %dn", Port));
  1110. /* No Autonegiotiation */
  1111. /* Set DuplexMode in Config register */
  1112. Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
  1113. /* Determine Master/Slave manually if not already done. */
  1114. if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
  1115. Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
  1116. }
  1117. /*
  1118.  * Do NOT enable Autonegotiation here. This would hold
  1119.  * the link down because no IDLES are transmitted
  1120.  */
  1121. }
  1122. else {
  1123. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1124. ("InitPhyBcom: with autonegotiation Port %dn", Port));
  1125. /* Set Autonegotiation advertisement */
  1126. /* Set Full/half duplex capabilities */
  1127. switch (pPrt->PLinkMode) {
  1128. case SK_LMODE_AUTOHALF:
  1129. Ctrl2 |= PHY_B_1000C_AHD;
  1130. break;
  1131. case SK_LMODE_AUTOFULL:
  1132. Ctrl2 |= PHY_B_1000C_AFD;
  1133. break;
  1134. case SK_LMODE_AUTOBOTH:
  1135. Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
  1136. break;
  1137. default:
  1138. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1139. SKERR_HWI_E015, SKERR_HWI_E015MSG);
  1140. }
  1141. switch (pPrt->PFlowCtrlMode) {
  1142. case SK_FLOW_MODE_NONE:
  1143. Ctrl3 |= PHY_B_P_NO_PAUSE;
  1144. break;
  1145. case SK_FLOW_MODE_LOC_SEND:
  1146. Ctrl3 |= PHY_B_P_ASYM_MD;
  1147. break;
  1148. case SK_FLOW_MODE_SYMMETRIC:
  1149. Ctrl3 |= PHY_B_P_SYM_MD;
  1150. break;
  1151. case SK_FLOW_MODE_SYM_OR_REM:
  1152. Ctrl3 |= PHY_B_P_BOTH_MD;
  1153. break;
  1154. default:
  1155. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1156. SKERR_HWI_E016, SKERR_HWI_E016MSG);
  1157. }
  1158. /* Restart Autonegotiation */
  1159. Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
  1160. }
  1161. /* Initialize LED register here? */
  1162. /* No. Please do it in SkDgXmitLed() (if required) and swap
  1163.    init order of LEDs and XMAC. (MAl) */
  1164. /* Write 1000Base-T Control Register */
  1165. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
  1166. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1167. ("1000Base-T Control Reg = %xn", Ctrl2));
  1168. /* Write AutoNeg Advertisement Register */
  1169. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
  1170. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1171. ("AutoNeg Advertisment Reg = %xn", Ctrl3));
  1172. if (DoLoop) {
  1173. /* Set the Phy Loopback bit, too */
  1174. Ctrl1 |= PHY_CT_LOOP;
  1175. }
  1176. if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
  1177. /* configure fifo to high latency for xmission of ext. packets*/
  1178. Ctrl4 |= PHY_B_PEC_HIGH_LA;
  1179. /* configure reception of extended packets */
  1180. Ctrl5 |= PHY_B_AC_LONG_PACK;
  1181. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
  1182. }
  1183. /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
  1184. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
  1185. /* Write to the Phy control register */
  1186. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, Ctrl1);
  1187. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1188. ("PHY Control Reg = %xn", Ctrl1));
  1189. } /* SkXmInitPhyBcom */
  1190. /******************************************************************************
  1191.  *
  1192.  * SkXmInitPhyLone() - Initialize the Level One Phy registers
  1193.  *
  1194.  * Description:
  1195.  * Initialize all the Level One Phy registers
  1196.  *
  1197.  * Note:
  1198.  *
  1199.  * Returns:
  1200.  * nothing
  1201.  */
  1202. static void SkXmInitPhyLone(
  1203. SK_AC *pAC, /* adapter context */
  1204. SK_IOC IoC, /* IO context */
  1205. int Port, /* Port Index (MAC_1 + n) */
  1206. SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */
  1207. {
  1208. SK_GEPORT *pPrt;
  1209. SK_U16 Ctrl1;
  1210. SK_U16 Ctrl2;
  1211. SK_U16 Ctrl3;
  1212. Ctrl1 = PHY_L_CT_SP1000;
  1213. Ctrl2 = 0;
  1214. Ctrl3 = PHY_SEL_TYPE;
  1215. pPrt = &pAC->GIni.GP[Port];
  1216. /* manually Master/Slave ? */
  1217. if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
  1218. Ctrl2 |= PHY_L_1000C_MSE;
  1219. if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
  1220. Ctrl2 |= PHY_L_1000C_MSC;
  1221. }
  1222. }
  1223. /* Autonegotiation ? */
  1224. if (pPrt->PLinkMode == SK_LMODE_HALF ||
  1225.     pPrt->PLinkMode == SK_LMODE_FULL) {
  1226. /*
  1227.  * level one spec say: "1000Mbps: manual mode not allowed"
  1228.  * but lets see what happens...
  1229.  */
  1230. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1231. 0, "Level One PHY only works with Autoneg");
  1232. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1233. ("InitPhyLone: no autonegotiation Port %dn", Port));
  1234. /* No Autonegiotiation */
  1235. /* Set DuplexMode in Config register */
  1236. Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
  1237. /* Determine Master/Slave manually if not already done. */
  1238. if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
  1239. Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
  1240. }
  1241. /*
  1242.  * Do NOT enable Autonegotiation here. This would hold
  1243.  * the link down because no IDLES are transmitted
  1244.  */
  1245. }
  1246. else {
  1247. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1248. ("InitPhyLone: with autonegotiation Port %dn", Port));
  1249. /* Set Autonegotiation advertisement */
  1250. /* Set Full/half duplex capabilities */
  1251. switch (pPrt->PLinkMode) {
  1252. case SK_LMODE_AUTOHALF:
  1253. Ctrl2 |= PHY_L_1000C_AHD;
  1254. break;
  1255. case SK_LMODE_AUTOFULL:
  1256. Ctrl2 |= PHY_L_1000C_AFD;
  1257. break;
  1258. case SK_LMODE_AUTOBOTH:
  1259. Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
  1260. break;
  1261. default:
  1262. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1263. SKERR_HWI_E015, SKERR_HWI_E015MSG);
  1264. }
  1265. switch (pPrt->PFlowCtrlMode) {
  1266. case SK_FLOW_MODE_NONE:
  1267. Ctrl3 |= PHY_L_P_NO_PAUSE;
  1268. break;
  1269. case SK_FLOW_MODE_LOC_SEND:
  1270. Ctrl3 |= PHY_L_P_ASYM_MD;
  1271. break;
  1272. case SK_FLOW_MODE_SYMMETRIC:
  1273. Ctrl3 |= PHY_L_P_SYM_MD;
  1274. break;
  1275. case SK_FLOW_MODE_SYM_OR_REM:
  1276. Ctrl3 |= PHY_L_P_BOTH_MD;
  1277. break;
  1278. default:
  1279. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1280. SKERR_HWI_E016, SKERR_HWI_E016MSG);
  1281. }
  1282. /* Restart Autonegotiation */
  1283. Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
  1284. }
  1285. /* Initialize LED register here ? */
  1286. /* No. Please do it in SkDgXmitLed() (if required) and swap
  1287.    init order of LEDs and XMAC. (MAl) */
  1288. /* Write 1000Base-T Control Register */
  1289. PHY_WRITE(IoC, pPrt, Port, PHY_LONE_1000T_CTRL, Ctrl2);
  1290. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1291. ("1000Base-T Control Reg = %xn", Ctrl2));
  1292. /* Write AutoNeg Advertisement Register */
  1293. PHY_WRITE(IoC, pPrt, Port, PHY_LONE_AUNE_ADV, Ctrl3);
  1294. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1295. ("AutoNeg Advertisment Reg = %xn", Ctrl3));
  1296. if (DoLoop) {
  1297. /* Set the Phy Loopback bit, too */
  1298. Ctrl1 |= PHY_CT_LOOP;
  1299. }
  1300. if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
  1301. /*
  1302.  * nothing to do for Level one.
  1303.  * PHY supports frames up to 10k.
  1304.  */
  1305. }
  1306. /* Write to the Phy control register */
  1307. PHY_WRITE(IoC, pPrt, Port, PHY_LONE_CTRL, Ctrl1);
  1308. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1309. ("PHY Control Reg = %xn", Ctrl1));
  1310. } /* SkXmInitPhyLone*/
  1311. /******************************************************************************
  1312.  *
  1313.  * SkXmInitPhyNat() - Initialize the National Phy registers
  1314.  *
  1315.  * Description:
  1316.  * Initialize all the National Phy registers
  1317.  *
  1318.  * Note:
  1319.  *
  1320.  * Returns:
  1321.  * nothing
  1322.  */
  1323. static void SkXmInitPhyNat(
  1324. SK_AC *pAC, /* adapter context */
  1325. SK_IOC IoC, /* IO context */
  1326. int Port, /* Port Index (MAC_1 + n) */
  1327. SK_BOOL DoLoop) /* Should a Phy LOOback be set-up? */
  1328. {
  1329. /* todo: National */
  1330. } /* SkXmInitPhyNat*/
  1331. /******************************************************************************
  1332.  *
  1333.  * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do autoneg
  1334.  *
  1335.  * This function analyses the Interrupt status word. If any of the
  1336.  * Autonegotiating interrupt bits are set, the PLipaAutoNeg variable
  1337.  * is set true.
  1338.  */
  1339. void SkXmAutoNegLipaXmac(
  1340. SK_AC *pAC, /* adapter context */
  1341. SK_IOC IoC, /* IO context */
  1342. int Port, /* Port Index (MAC_1 + n) */
  1343. SK_U16 IStatus) /* Interrupt Status word to analyse */
  1344. {
  1345. SK_GEPORT *pPrt;
  1346. pPrt = &pAC->GIni.GP[Port];
  1347. if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
  1348. (IStatus & (XM_IS_LIPA_RC|XM_IS_RX_PAGE|XM_IS_AND))) {
  1349. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1350. ("AutoNegLipa: AutoNeg detected on port %d %xn", Port, IStatus));
  1351. pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
  1352. }
  1353. } /* SkXmAutoNegLipaXmac*/
  1354. /******************************************************************************
  1355.  *
  1356.  * SkXmAutoNegLipaBcom() - Decides whether Link Partner could do autoneg
  1357.  *
  1358.  * This function analyses the PHY status word. If any of the
  1359.  * Autonegotiating bits are set, The PLipaAutoNeg variable
  1360.  * is set true.
  1361.  */
  1362. void SkXmAutoNegLipaBcom(
  1363. SK_AC *pAC, /* adapter context */
  1364. SK_IOC IoC, /* IO context */
  1365. int Port, /* Port Index (MAC_1 + n) */
  1366. SK_U16 PhyStat) /* PHY Status word to analyse */
  1367. {
  1368. SK_GEPORT *pPrt;
  1369. pPrt = &pAC->GIni.GP[Port];
  1370. if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && (PhyStat & PHY_ST_AN_OVER)) {
  1371. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1372. ("AutoNegLipa: AutoNeg detected on port %d %xn", Port, PhyStat));
  1373. pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
  1374. }
  1375. } /* SkXmAutoNegLipaBcom*/
  1376. /******************************************************************************
  1377.  *
  1378.  * SkXmAutoNegLipaLone() - Decides whether Link Partner could do autoneg
  1379.  *
  1380.  * This function analyses the PHY status word. If any of the
  1381.  * Autonegotiating bits are set, The PLipaAutoNeg variable
  1382.  * is set true.
  1383.  */
  1384. void SkXmAutoNegLipaLone(
  1385. SK_AC *pAC, /* adapter context */
  1386. SK_IOC IoC, /* IO context */
  1387. int Port, /* Port Index (MAC_1 + n) */
  1388. SK_U16 PhyStat) /* PHY Status word to analyse */
  1389. {
  1390. SK_GEPORT *pPrt;
  1391. pPrt = &pAC->GIni.GP[Port];
  1392. if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
  1393. (PhyStat & (PHY_ST_AN_OVER))) {
  1394. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1395. ("AutoNegLipa: AutoNeg detected on port %d %xn", Port, PhyStat));
  1396. pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
  1397. }
  1398. } /* SkXmAutoNegLipaLone*/
  1399. /******************************************************************************
  1400.  *
  1401.  * SkXmAutoNegLipaNat() - Decides whether Link Partner could do autoneg
  1402.  *
  1403.  * This function analyses the PHY status word. If any of the
  1404.  * Autonegotiating bits are set, The PLipaAutoNeg variable
  1405.  * is set true.
  1406.  */
  1407. void SkXmAutoNegLipaNat(
  1408. SK_AC *pAC, /* adapter context */
  1409. SK_IOC IoC, /* IO context */
  1410. int Port, /* Port Index (MAC_1 + n) */
  1411. SK_U16 PhyStat) /* PHY Status word to analyse */
  1412. {
  1413. SK_GEPORT *pPrt;
  1414. pPrt = &pAC->GIni.GP[Port];
  1415. if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
  1416. (PhyStat & (PHY_ST_AN_OVER))) {
  1417. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1418. ("AutoNegLipa: AutoNeg detected on port %d %xn", Port, PhyStat));
  1419. pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
  1420. }
  1421. } /* SkXmAutoNegLipaNat*/
  1422. /******************************************************************************
  1423.  *
  1424.  * SkXmAutoNegDone() - Auto negotiation handling
  1425.  *
  1426.  * Description:
  1427.  * This function handles the autonegotiation if the Done bit is set.
  1428.  *
  1429.  * Note:
  1430.  * o The XMACs interrupt source register is NOT read here.
  1431.  * o This function is public because it is used in the diagnostics
  1432.  *   tool, too.
  1433.  *
  1434.  * Returns:
  1435.  * SK_AND_OK o.k.
  1436.  * SK_AND_DUP_CAP  Duplex capability error happened
  1437.  * SK_AND_OTHER  Other error happened
  1438.  */
  1439. int SkXmAutoNegDone(
  1440. SK_AC *pAC, /* adapter context */
  1441. SK_IOC IoC, /* IO context */
  1442. int Port) /* Port Index (MAC_1 + n) */
  1443. {
  1444. switch (pAC->GIni.GP[Port].PhyType) {
  1445. case SK_PHY_XMAC:
  1446. return (SkXmAutoNegDoneXmac(pAC, IoC, Port));
  1447. case SK_PHY_BCOM:
  1448. return (SkXmAutoNegDoneBcom(pAC, IoC, Port));
  1449. case SK_PHY_LONE:
  1450. return (SkXmAutoNegDoneLone(pAC, IoC, Port));
  1451. case SK_PHY_NAT:
  1452. return (SkXmAutoNegDoneNat(pAC, IoC, Port));
  1453. }
  1454. return (SK_AND_OTHER);
  1455. } /* SkXmAutoNegDone*/
  1456. /******************************************************************************
  1457.  *
  1458.  * SkXmAutoNegDoneXmac() - Auto negotiation handling
  1459.  *
  1460.  * Description:
  1461.  * This function handles the autonegotiation if the Done bit is set.
  1462.  *
  1463.  * Note:
  1464.  * o The XMACs interrupt source register is NOT read here.
  1465.  *
  1466.  * Returns:
  1467.  * SK_AND_OK o.k.
  1468.  * SK_AND_DUP_CAP  Duplex capability error happened
  1469.  * SK_AND_OTHER  Other error happened
  1470.  */
  1471. static int SkXmAutoNegDoneXmac(
  1472. SK_AC *pAC, /* adapter context */
  1473. SK_IOC IoC, /* IO context */
  1474. int Port) /* Port Index (MAC_1 + n) */
  1475. {
  1476. SK_GEPORT *pPrt;
  1477. SK_U16 ResAb; /* Resolved Ability */
  1478. SK_U16 LPAb; /* Link Partner Ability */
  1479. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneXmac"
  1480. "Port %dn",Port));
  1481. pPrt = &pAC->GIni.GP[Port];
  1482. /* Get PHY parameters */
  1483. PHY_READ(IoC, pPrt, Port, PHY_XMAC_AUNE_LP, &LPAb);
  1484. PHY_READ(IoC, pPrt, Port, PHY_XMAC_RES_ABI, &ResAb);
  1485. if (LPAb & PHY_X_AN_RFB) {
  1486. /* At least one of the remote fault bit is set */
  1487. /* Error */
  1488. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1489. ("AutoNegFail: Remote fault bit set Port %dn", Port));
  1490. pPrt->PAutoNegFail = SK_TRUE;
  1491. return (SK_AND_OTHER);
  1492. }
  1493. /* Check Duplex mismatch */
  1494. if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
  1495. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
  1496. }
  1497. else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
  1498. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
  1499. }
  1500. else {
  1501. /* Error */
  1502. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1503. ("AutoNegFail: Duplex mode mismatch port %dn", Port));
  1504. pPrt->PAutoNegFail = SK_TRUE;
  1505. return (SK_AND_DUP_CAP);
  1506. }
  1507. /* Check PAUSE mismatch */
  1508. /* We are NOT using chapter 4.23 of the Xaqti manual */
  1509. /* We are using IEEE 802.3z/D5.0 Table 37-4 */
  1510. if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
  1511.      pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
  1512.     (LPAb & PHY_X_P_SYM_MD)) {
  1513. /* Symmetric PAUSE */
  1514. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
  1515. }
  1516. else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
  1517.    (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
  1518. /* Enable PAUSE receive, disable PAUSE transmit */
  1519. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
  1520. }
  1521. else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
  1522.    (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
  1523. /* Disable PAUSE receive, enable PAUSE transmit */
  1524. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
  1525. }
  1526. else {
  1527. /* PAUSE mismatch -> no PAUSE */
  1528. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  1529. }
  1530. /* We checked everything and may now enable the link */
  1531. pPrt->PAutoNegFail = SK_FALSE;
  1532. SkXmRxTxEnable(pAC, IoC, Port);
  1533. return (SK_AND_OK);
  1534. } /* SkXmAutoNegDoneXmac*/
  1535. /******************************************************************************
  1536.  *
  1537.  * SkXmAutoNegDoneBcom() - Auto negotiation handling
  1538.  *
  1539.  * Description:
  1540.  * This function handles the autonegotiation if the Done bit is set.
  1541.  *
  1542.  * Note:
  1543.  * o The XMACs interrupt source register is NOT read here.
  1544.  *
  1545.  * Returns:
  1546.  * SK_AND_OK o.k.
  1547.  * SK_AND_DUP_CAP  Duplex capability error happened
  1548.  * SK_AND_OTHER  Other error happened
  1549.  */
  1550. static int SkXmAutoNegDoneBcom(
  1551. SK_AC *pAC, /* adapter context */
  1552. SK_IOC IoC, /* IO context */
  1553. int Port) /* Port Index (MAC_1 + n) */
  1554. {
  1555. SK_GEPORT *pPrt;
  1556. SK_U16 LPAb; /* Link Partner Ability */
  1557. SK_U16 AuxStat; /* Auxiliary Status */
  1558. #if 0
  1559. 01-Sep-2000 RA;:;:
  1560. SK_U16 ResAb; /* Resolved Ability */
  1561. #endif /* 0 */
  1562. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1563. ("AutoNegDoneBcom, Port %dn", Port));
  1564. pPrt = &pAC->GIni.GP[Port];
  1565. /* Get PHY parameters. */
  1566. PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUNE_LP, &LPAb);
  1567. #if 0
  1568. 01-Sep-2000 RA;:;:
  1569. PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
  1570. #endif /* 0 */
  1571. PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_STAT, &AuxStat);
  1572. if (LPAb & PHY_B_AN_RF) {
  1573. /* Remote fault bit is set: Error. */
  1574. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1575. ("AutoNegFail: Remote fault bit set Port %dn", Port));
  1576. pPrt->PAutoNegFail = SK_TRUE;
  1577. return (SK_AND_OTHER);
  1578. }
  1579. /* Check Duplex mismatch. */
  1580. if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000FD) {
  1581. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
  1582. }
  1583. else if ((AuxStat & PHY_B_AS_AN_RES) == PHY_B_RES_1000HD) {
  1584. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
  1585. }
  1586. else {
  1587. /* Error. */
  1588. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1589. ("AutoNegFail: Duplex mode mismatch port %dn", Port));
  1590. pPrt->PAutoNegFail = SK_TRUE;
  1591. return (SK_AND_DUP_CAP);
  1592. }
  1593. #if 0
  1594. 01-Sep-2000 RA;:;:
  1595. /* Check Master/Slave resolution. */
  1596. if (ResAb & PHY_B_1000S_MSF) {
  1597. /* Error. */
  1598. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
  1599. ("Master/Slave Fault port %dn", Port));
  1600. pPrt->PAutoNegFail = SK_TRUE;
  1601. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1602. return (SK_AND_OTHER);
  1603. }
  1604. else if (ResAb & PHY_B_1000S_MSR) {
  1605. pPrt->PMSStatus = SK_MS_STAT_MASTER;
  1606. }
  1607. else {
  1608. pPrt->PMSStatus = SK_MS_STAT_SLAVE;
  1609. }
  1610. #endif /* 0 */
  1611. /* Check PAUSE mismatch. */
  1612. /* We are NOT using chapter 4.23 of the Xaqti manual. */
  1613. /* We are using IEEE 802.3z/D5.0 Table 37-4. */
  1614. if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == 
  1615. (PHY_B_AS_PRR | PHY_B_AS_PRT)) {
  1616. /* Symmetric PAUSE. */
  1617. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
  1618. }
  1619. else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRR) {
  1620. /* Enable PAUSE receive, disable PAUSE transmit. */
  1621. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
  1622. }
  1623. else if ((AuxStat & (PHY_B_AS_PRR | PHY_B_AS_PRT)) == PHY_B_AS_PRT) {
  1624. /* Disable PAUSE receive, enable PAUSE transmit. */
  1625. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
  1626. }
  1627. else {
  1628. /* PAUSE mismatch -> no PAUSE. */
  1629. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  1630. }
  1631. /* We checked everything and may now enable the link. */
  1632. pPrt->PAutoNegFail = SK_FALSE;
  1633. SkXmRxTxEnable(pAC, IoC, Port);
  1634. return (SK_AND_OK);
  1635. } /* SkXmAutoNegDoneBcom*/
  1636. /******************************************************************************
  1637.  *
  1638.  * SkXmAutoNegDoneLone() - Auto negotiation handling
  1639.  *
  1640.  * Description:
  1641.  * This function handles the autonegotiation if the Done bit is set.
  1642.  *
  1643.  * Note:
  1644.  * o The XMACs interrupt source register is NOT read here.
  1645.  *
  1646.  * Returns:
  1647.  * SK_AND_OK o.k.
  1648.  * SK_AND_DUP_CAP  Duplex capability error happened
  1649.  * SK_AND_OTHER  Other error happened
  1650.  */
  1651. static int SkXmAutoNegDoneLone(
  1652. SK_AC *pAC, /* adapter context */
  1653. SK_IOC IoC, /* IO context */
  1654. int Port) /* Port Index (MAC_1 + n) */
  1655. {
  1656. SK_GEPORT *pPrt;
  1657. SK_U16 ResAb; /* Resolved Ability */
  1658. SK_U16 LPAb; /* Link Partner Ability */
  1659. SK_U16 QuickStat; /* Auxiliary Status */
  1660. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL, ("AutoNegDoneLone"
  1661. "Port %dn",Port));
  1662. pPrt = &pAC->GIni.GP[Port];
  1663. /* Get PHY parameters */
  1664. PHY_READ(IoC, pPrt, Port, PHY_LONE_AUNE_LP, &LPAb);
  1665. PHY_READ(IoC, pPrt, Port, PHY_LONE_1000T_STAT, &ResAb);
  1666. PHY_READ(IoC, pPrt, Port, PHY_LONE_Q_STAT, &QuickStat);
  1667. if (LPAb & PHY_L_AN_RF) {
  1668. /* Remote fault bit is set */
  1669. /* Error */
  1670. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1671. ("AutoNegFail: Remote fault bit set Port %dn", Port));
  1672. pPrt->PAutoNegFail = SK_TRUE;
  1673. return (SK_AND_OTHER);
  1674. }
  1675. /* Check Duplex mismatch */
  1676. if (QuickStat & PHY_L_QS_DUP_MOD) {
  1677. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
  1678. }
  1679. else {
  1680. pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
  1681. }
  1682. /* Check Master/Slave resolution */
  1683. if (ResAb & (PHY_L_1000S_MSF)) {
  1684. /* Error */
  1685. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
  1686. ("Master/Slave Fault port %dn", Port));
  1687. pPrt->PAutoNegFail = SK_TRUE;
  1688. pPrt->PMSStatus = SK_MS_STAT_FAULT;
  1689. return (SK_AND_OTHER);
  1690. }
  1691. else if (ResAb & PHY_L_1000S_MSR) {
  1692. pPrt->PMSStatus = SK_MS_STAT_MASTER;
  1693. }
  1694. else {
  1695. pPrt->PMSStatus = SK_MS_STAT_SLAVE;
  1696. }
  1697. /* Check PAUSE mismatch */
  1698. /* We are NOT using chapter 4.23 of the Xaqti manual */
  1699. /* We are using IEEE 802.3z/D5.0 Table 37-4 */
  1700. /* we must manually resolve the abilities here */
  1701. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
  1702. switch (pPrt->PFlowCtrlMode) {
  1703. case SK_FLOW_MODE_NONE:
  1704. /* default */
  1705. break;
  1706. case SK_FLOW_MODE_LOC_SEND:
  1707. if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
  1708. (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
  1709. /* Disable PAUSE receive, enable PAUSE transmit */
  1710. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
  1711. }
  1712. break;
  1713. case SK_FLOW_MODE_SYMMETRIC:
  1714. if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) {
  1715. /* Symmetric PAUSE */
  1716. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
  1717. }
  1718. break;
  1719. case SK_FLOW_MODE_SYM_OR_REM:
  1720. if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
  1721. PHY_L_QS_AS_PAUSE) {
  1722. /* Enable PAUSE receive, disable PAUSE transmit */
  1723. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
  1724. }
  1725. else if ((QuickStat & PHY_L_QS_PAUSE) == PHY_L_QS_PAUSE) {
  1726. /* Symmetric PAUSE */
  1727. pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
  1728. }
  1729. break;
  1730. default:
  1731. SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT,
  1732. SKERR_HWI_E016, SKERR_HWI_E016MSG);
  1733. }
  1734. /* We checked everything and may now enable the link */
  1735. pPrt->PAutoNegFail = SK_FALSE;
  1736. SkXmRxTxEnable(pAC, IoC, Port);
  1737. return (SK_AND_OK);
  1738. } /* SkXmAutoNegDoneLone */
  1739. /******************************************************************************
  1740.  *
  1741.  * SkXmAutoNegDoneNat() - Auto negotiation handling
  1742.  *
  1743.  * Description:
  1744.  * This function handles the autonegotiation if the Done bit is set.
  1745.  *
  1746.  * Note:
  1747.  * o The XMACs interrupt source register is NOT read here.
  1748.  * o This function is public because it is used in the diagnostics
  1749.  *   tool, too.
  1750.  *
  1751.  * Returns:
  1752.  * SK_AND_OK o.k.
  1753.  * SK_AND_DUP_CAP  Duplex capability error happened
  1754.  * SK_AND_OTHER  Other error happened
  1755.  */
  1756. static int SkXmAutoNegDoneNat(
  1757. SK_AC *pAC, /* adapter context */
  1758. SK_IOC IoC, /* IO context */
  1759. int Port) /* Port Index (MAC_1 + n) */
  1760. {
  1761. /* todo: National */
  1762. return (SK_AND_OK);
  1763. } /* SkXmAutoNegDoneNat*/
  1764. /******************************************************************************
  1765.  *
  1766.  * SkXmRxTxEnable() - Enable RxTx activity if port is up
  1767.  *
  1768.  * Description:
  1769.  *
  1770.  * Note:
  1771.  * o The XMACs interrupt source register is NOT read here.
  1772.  *
  1773.  * Returns:
  1774.  * 0 o.k.
  1775.  * != 0 Error happened
  1776.  */
  1777. int SkXmRxTxEnable(
  1778. SK_AC *pAC, /* adapter context */
  1779. SK_IOC IoC, /* IO context */
  1780. int Port) /* Port Index (MAC_1 + n) */
  1781. {
  1782. SK_GEPORT *pPrt;
  1783. SK_U16 Reg; /* 16bit register value */
  1784. SK_U16 IntMask; /* XMac interrupt mask */
  1785. SK_U16 SWord;
  1786. pPrt = &pAC->GIni.GP[Port];
  1787. if (!pPrt->PHWLinkUp) {
  1788. /* The Hardware link is NOT up */
  1789. return (0);
  1790. }
  1791. if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
  1792.      pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
  1793.      pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
  1794.      pPrt->PAutoNegFail) {
  1795. /* Autonegotiation is not done or failed */
  1796. return (0);
  1797. }
  1798. /* Set Dup Mode and Pause Mode */
  1799. SkXmInitDupMd (pAC, IoC, Port);
  1800. SkXmInitPauseMd (pAC, IoC, Port);
  1801. /*
  1802.  * Initialize the Interrupt Mask Register. Default IRQs are...
  1803.  * - Link Asynchronous Event
  1804.  * - Link Partner requests config
  1805.  * - Auto Negotiation Done
  1806.  * - Rx Counter Event Overflow
  1807.  * - Tx Counter Event Overflow
  1808.  * - Transmit FIFO Underrun
  1809.  */
  1810. if (pPrt->PhyType == SK_PHY_XMAC) {
  1811. IntMask = XM_DEF_MSK;
  1812. }
  1813. else {
  1814. /* disable GP0 interrupt bit */
  1815. IntMask = XM_DEF_MSK | XM_IS_INP_ASS;
  1816. }
  1817. XM_OUT16(IoC, Port, XM_IMSK, IntMask);
  1818. /* RX/TX enable */
  1819. XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
  1820. if (pPrt->PhyType != SK_PHY_XMAC &&
  1821. (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || 
  1822.  pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
  1823. Reg |= XM_MMU_GMII_FD;
  1824. }
  1825. switch (pPrt->PhyType) {
  1826. case SK_PHY_BCOM:
  1827. /* Workaround BCOM Errata (#10523) for all BCom Phys */
  1828. /* Enable Power Management after link up */
  1829. PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
  1830. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, SWord & ~PHY_B_AC_DIS_PM);
  1831. PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
  1832. break;
  1833. case SK_PHY_LONE:
  1834. PHY_WRITE(IoC, pPrt, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
  1835. break;
  1836. case SK_PHY_NAT:
  1837. /* todo National:
  1838. PHY_WRITE(IoC, pPrt, Port, PHY_NAT_INT_MASK, 
  1839. PHY_N_DEF_MSK); */
  1840. /* no interrupts possible from National ??? */
  1841. break;
  1842. }
  1843. XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
  1844.       
  1845. return (0);
  1846. } /* SkXmRxTxEnable*/
  1847. #ifndef SK_DIAG
  1848. /******************************************************************************
  1849.  *
  1850.  * SkXmIrq() - Interrupt service routine
  1851.  *
  1852.  * Description:
  1853.  * Services an Interrupt of the XMAC II
  1854.  *
  1855.  * Note:
  1856.  * The XMACs interrupt source register is NOT read here.
  1857.  * With an external PHY, some interrupt bits are not meaningfull
  1858.  * any more:
  1859.  * - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
  1860.  * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
  1861.  * - Page Received (bit #9) XM_IS_RX_PAGE
  1862.  * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
  1863.  * - AutoNegDone (bit #7) XM_IS_AND
  1864.  * Also probably not valid any more is the GP0 input bit:
  1865.  * - GPRegisterBit0set XM_IS_INP_ASS
  1866.  *
  1867.  * Returns:
  1868.  * nothing
  1869.  */
  1870. void SkXmIrq(
  1871. SK_AC *pAC, /* adapter context */
  1872. SK_IOC IoC, /* IO context */
  1873. int Port, /* Port Index (MAC_1 + n) */
  1874. SK_U16 IStatus) /* Interrupt status read from the XMAC */
  1875. {
  1876. SK_GEPORT *pPrt;
  1877. SK_EVPARA Para;
  1878. SK_U16 IStatus2;
  1879. pPrt = &pAC->GIni.GP[Port];
  1880. if (pPrt->PhyType != SK_PHY_XMAC) {
  1881. /* mask bits that are not used with ext. PHY */
  1882. IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
  1883. XM_IS_RX_PAGE | XM_IS_TX_PAGE |
  1884. XM_IS_AND | XM_IS_INP_ASS);
  1885. }
  1886. /*
  1887.  * LinkPartner Autonegable?
  1888.  */
  1889. if (pPrt->PhyType == SK_PHY_XMAC) {
  1890. SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
  1891. }
  1892. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1893. ("XmacIrq Port %d Isr %xn", Port, IStatus));
  1894. if (!pPrt->PHWLinkUp) {
  1895. /* Spurious XMAC interrupt */
  1896. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1897. ("SkXmIrq: spurious interrupt on port %dn", Port));
  1898. return;
  1899. }
  1900. if (IStatus & XM_IS_INP_ASS) {
  1901. /* Reread ISR Register if link is not in sync */
  1902. XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
  1903. SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
  1904. ("SkXmIrq: Link async. Double check port %d %x %xn",
  1905.  Port, IStatus, IStatus2));
  1906. IStatus &= ~XM_IS_INP_ASS;
  1907. IStatus |= IStatus2;
  1908. }
  1909. if (IStatus & XM_IS_LNK_AE) {
  1910. /* not used GP0 is used instead */
  1911. }
  1912. if (IStatus & XM_IS_TX_ABORT) {
  1913. /* not used */
  1914. }
  1915. if (IStatus & XM_IS_FRC_INT) {
  1916. /* not used. use ASIC IRQ instead if needed */
  1917. }
  1918. if (IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) {
  1919. SkHWLinkDown(pAC, IoC, Port);
  1920. /* Signal to RLMT */
  1921. Para.Para32[0] = (SK_U32) Port;
  1922. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
  1923. /* Start workaround Errata #2 timer */
  1924. SkTimerStart(pAC, IoC, &pAC->GIni.GP[Port].PWaTimer,
  1925. SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para);
  1926. }
  1927. if (IStatus & XM_IS_RX_PAGE) {
  1928. /* not used */
  1929. }
  1930. if (IStatus & XM_IS_TX_PAGE) {
  1931. /* not used */
  1932. }
  1933. if (IStatus & XM_IS_AND) {
  1934. SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_IRQ,
  1935. ("SkXmIrq: AND on link that is up port %dn", Port));
  1936. }
  1937. if (IStatus & XM_IS_TSC_OV) {
  1938. /* not used */
  1939. }
  1940. if (IStatus & XM_IS_RXC_OV) {
  1941. Para.Para32[0] = (SK_U32) Port;
  1942. Para.Para32[1] = (SK_U32) IStatus;
  1943. SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
  1944. }
  1945. if (IStatus & XM_IS_TXC_OV) {
  1946. Para.Para32[0] = (SK_U32) Port;
  1947. Para.Para32[1] = (SK_U32) IStatus;
  1948. SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
  1949. }
  1950. if (IStatus & XM_IS_RXF_OV) {
  1951. /* normal situation -> no effect */
  1952. }
  1953. if (IStatus & XM_IS_TXF_UR) {
  1954. /* may NOT happen -> error log */
  1955. SK_ERR_LOG(pAC, SK_ERRCL_HW , SKERR_SIRQ_E020,
  1956. SKERR_SIRQ_E020MSG);
  1957. }
  1958. if (IStatus & XM_IS_TX_COMP) {
  1959. /* not served here */
  1960. }
  1961. if (IStatus & XM_IS_RX_COMP) {
  1962. /* not served here */
  1963. }
  1964. } /* SkXmIrq*/
  1965. #endif /* !SK_DIAG */
  1966. /* End of file */