⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elnk.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
      XL_SEL_WIN(1);   sc->xl_stats.rxstatus  = CSR_READ_2(sc, XL_W1_RX_STATUS );   sc->xl_stats.txstatus  = CSR_READ_1(sc, XL_W1_TX_STATUS );   sc->xl_stats.smbstatus = CSR_READ_2(sc, 2 );   XL_SEL_WIN(3);   sc->xl_stats.internalconfig = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);   sc->xl_stats.mac_control    = CSR_READ_2(sc, XL_W3_MAC_CTRL);   sc->xl_stats.txfree         = CSR_READ_2(sc, XL_W3_FREE_TX );         /* Read all the stats registers. */   XL_SEL_WIN(6);   sc->xl_stats.xl_carrier_lost              += CSR_READ_1(sc, XL_W6_CARRIER_LOST);   sc->xl_stats.xl_sqe_errs                  += CSR_READ_1(sc, XL_W6_SQE_ERRORS);   sc->xl_stats.xl_tx_multi_collision        += CSR_READ_1(sc, XL_W6_COL_MULTIPLE);   sc->xl_stats.xl_tx_single_collision       += CSR_READ_1(sc, XL_W6_COL_SINGLE);   sc->xl_stats.xl_tx_late_collision         += CSR_READ_1(sc, XL_W6_COL_LATE);   sc->xl_stats.xl_rx_overrun                += CSR_READ_1(sc, XL_W6_RX_OVERRUN);   sc->xl_stats.xl_tx_deferred               += CSR_READ_1(sc, XL_W6_DEFERRED);   sc->xl_stats.xl_tx_frames_ok              += CSR_READ_1(sc, XL_W6_TX_OK);   sc->xl_stats.xl_rx_frames_ok              += CSR_READ_1(sc, XL_W6_RX_OK);   sc->xl_stats.xl_rx_bytes_ok               += CSR_READ_2(sc, XL_W6_TX_BYTES_OK );   sc->xl_stats.xl_tx_bytes_ok               += CSR_READ_2(sc, XL_W6_RX_BYTES_OK );   t1 = CSR_READ_1(sc, XL_W6_UPPER_FRAMES_OK);   sc->xl_stats.xl_rx_frames_ok +=  ((t1 & 0x3) << 8);   sc->xl_stats.xl_tx_frames_ok +=  (((t1 >> 4) & 0x3) << 8);   ifp->if_ierrors += sc->xl_stats.xl_rx_overrun;   ifp->if_collisions += sc->xl_stats.xl_tx_multi_collision +      sc->xl_stats.xl_tx_single_collision +      sc->xl_stats.xl_tx_late_collision;   /*    * Boomerang and cyclone chips have an extra stats counter    * in window 4 (BadSSD). We have to read this too in order    * to clear out all the stats registers and avoid a statsoflow    * interrupt.    */   XL_SEL_WIN(4);   t1 = CSR_READ_1(sc, XL_W4_UPPERBYTESOK);   sc->xl_stats.xl_rx_bytes_ok += ((t1 & 0xf) << 16);   sc->xl_stats.xl_tx_bytes_ok += (((t1 >> 4) & 0xf) << 16);   sc->xl_stats.xl_badssd               += CSR_READ_1(sc, XL_W4_BADSSD);   sc->xl_stats.mediastatus             = CSR_READ_2(sc, XL_W4_MEDIA_STATUS );   sc->xl_stats.dmactl                  = CSR_READ_4(sc, XL_DMACTL );   XL_SEL_WIN(7);   if (!sc->xl_stats_no_timeout)      rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );   return;}static voidxl_reset(sc)   struct elnk_softc		*sc;{   register int		i;   XL_SEL_WIN(0);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |                ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?                XL_RESETOPT_DISADVFD:0));   for (i = 0; i < XL_TIMEOUT; i++) {      DELAY(10);      if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))         break;   }   if (i == XL_TIMEOUT)      printk("etherlink : unit elnk%d reset didn't complete\n", sc->xl_unit);   /* Reset TX and RX. */   /* Note: the RX reset takes an absurd amount of time    * on newer versions of the Tornado chips such as those    * on the 3c905CX and newer 3c908C cards. We wait an    * extra amount of time so that xl_wait() doesn't complain    * and annoy the users.    */   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);   DELAY(100000);   xl_wait(sc);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);   xl_wait(sc);   if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||        sc->xl_flags & XL_FLAG_INVERT_MII_PWR)    {      XL_SEL_WIN(2);      CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,                                                      XL_W2_RESET_OPTIONS)                   | ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR)?XL_RESETOPT_INVERT_LED:0)                  | ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR)?XL_RESETOPT_INVERT_MII:0)         );   }   /* Wait a little while for the chip to get its brains in order. */   DELAY(100000);   return;}static voidxl_stop(sc)   struct elnk_softc		*sc;{   struct ifnet		*ifp;   ifp = &sc->arpcom.ac_if;   ifp->if_timer = 0;   rtems_timer_cancel( sc->stat_timer_id );   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISCARD);   xl_wait(sc);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);   DELAY(800);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);   return;}static voidxl_setcfg(sc)   struct elnk_softc		*sc;{   u_int32_t		icfg;   XL_SEL_WIN(3);   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);   icfg &= ~XL_ICFG_CONNECTOR_MASK;   if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BT4)      icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);   if (sc->xl_media & XL_MEDIAOPT_BTX)      icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);   XL_SEL_WIN(7);   return;}static voidxl_setmode(sc, media)   struct elnk_softc	*sc;   int			media;{   u_int32_t		icfg;   u_int16_t		mediastat;   printk("etherlink : unit elnk%d selecting ", sc->xl_unit);   XL_SEL_WIN(4);   mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);   XL_SEL_WIN(3);   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);   if (sc->xl_media & XL_MEDIAOPT_BT) {      if (IFM_SUBTYPE(media) == IFM_10_T) {         printk("10baseT transceiver, ");         sc->xl_xcvr = XL_XCVR_10BT;         icfg &= ~XL_ICFG_CONNECTOR_MASK;         icfg |= (XL_XCVR_10BT << XL_ICFG_CONNECTOR_BITS);         mediastat |= XL_MEDIASTAT_LINKBEAT|            XL_MEDIASTAT_JABGUARD;         mediastat &= ~XL_MEDIASTAT_SQEENB;      }   }   if (sc->xl_media & XL_MEDIAOPT_BFX) {      if (IFM_SUBTYPE(media) == IFM_100_FX) {         printk("100baseFX port, ");         sc->xl_xcvr = XL_XCVR_100BFX;         icfg &= ~XL_ICFG_CONNECTOR_MASK;         icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);         mediastat |= XL_MEDIASTAT_LINKBEAT;         mediastat &= ~XL_MEDIASTAT_SQEENB;      }   }   if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {      if (IFM_SUBTYPE(media) == IFM_10_5) {         printk("AUI port, ");         sc->xl_xcvr = XL_XCVR_AUI;         icfg &= ~XL_ICFG_CONNECTOR_MASK;         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|                        XL_MEDIASTAT_JABGUARD);         mediastat |= ~XL_MEDIASTAT_SQEENB;      }      if (IFM_SUBTYPE(media) == IFM_10_FL) {         printk("10baseFL transceiver, ");         sc->xl_xcvr = XL_XCVR_AUI;         icfg &= ~XL_ICFG_CONNECTOR_MASK;         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|                        XL_MEDIASTAT_JABGUARD);         mediastat |= ~XL_MEDIASTAT_SQEENB;      }   }   if (sc->xl_media & XL_MEDIAOPT_BNC) {      if (IFM_SUBTYPE(media) == IFM_10_2) {         printk("BNC port, ");         sc->xl_xcvr = XL_XCVR_COAX;         icfg &= ~XL_ICFG_CONNECTOR_MASK;         icfg |= (XL_XCVR_COAX << XL_ICFG_CONNECTOR_BITS);         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|                        XL_MEDIASTAT_JABGUARD|                        XL_MEDIASTAT_SQEENB);      }   }   if ((media & IFM_GMASK) == IFM_FDX ||       IFM_SUBTYPE(media) == IFM_100_FX) {      printk("full duplex\n");      XL_SEL_WIN(3);      CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);   } else {      printk("half duplex\n");      XL_SEL_WIN(3);      CSR_WRITE_1(sc, XL_W3_MAC_CTRL,                  (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));   }   if (IFM_SUBTYPE(media) == IFM_10_2)      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);   else      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);   XL_SEL_WIN(4);   CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);   DELAY(800);   XL_SEL_WIN(7);   return;}static voidxl_choose_xcvr(sc, verbose)   struct elnk_softc	*sc;   int			verbose;{   u_int16_t		devid;   /*    * Read the device ID from the EEPROM.    * This is what's loaded into the PCI device ID register, so it has    * to be correct otherwise we wouldn't have gotten this far.    */   xl_read_eeprom(sc, (caddr_t)&devid, XL_EE_PRODID, 1, 0);   switch(devid) {      case TC_DEVICEID_BOOMERANG_10BT:	/* 3c900-TPO */      case TC_DEVICEID_KRAKATOA_10BT:		/* 3c900B-TPO */         sc->xl_media = XL_MEDIAOPT_BT;         sc->xl_xcvr = XL_XCVR_10BT;         if (verbose)            printk("etherlink : unit elnk%d guessing 10BaseT "                   "transceiver\n", sc->xl_unit);         break;      case TC_DEVICEID_BOOMERANG_10BT_COMBO:	/* 3c900-COMBO */      case TC_DEVICEID_KRAKATOA_10BT_COMBO:	/* 3c900B-COMBO */         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;         sc->xl_xcvr = XL_XCVR_10BT;         if (verbose)            printk("etherlink : unit elnk%d guessing COMBO "                   "(AUI/BNC/TP)\n", sc->xl_unit);         break;      case TC_DEVICEID_KRAKATOA_10BT_TPC:	/* 3c900B-TPC */         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;         sc->xl_xcvr = XL_XCVR_10BT;         if (verbose)            printk("etherlink : unit elnk%d guessing TPC (BNC/TP)\n", sc->xl_unit);         break;      case TC_DEVICEID_CYCLONE_10FL:		/* 3c900B-FL */         sc->xl_media = XL_MEDIAOPT_10FL;         sc->xl_xcvr = XL_XCVR_AUI;         if (verbose)            printk("etherlink : unit elnk%d guessing 10baseFL\n", sc->xl_unit);         break;      case TC_DEVICEID_BOOMERANG_10_100BT:	/* 3c905-TX */      case TC_DEVICEID_HURRICANE_555:		/* 3c555 */      case TC_DEVICEID_HURRICANE_556:		/* 3c556 */      case TC_DEVICEID_HURRICANE_556B:	/* 3c556B */      case TC_DEVICEID_HURRICANE_575A:	/* 3c575TX */      case TC_DEVICEID_HURRICANE_575B:	/* 3c575B */      case TC_DEVICEID_HURRICANE_575C:	/* 3c575C */      case TC_DEVICEID_HURRICANE_656:		/* 3c656 */      case TC_DEVICEID_HURRICANE_656B:	/* 3c656B */      case TC_DEVICEID_TORNADO_656C:		/* 3c656C */      case TC_DEVICEID_TORNADO_10_100BT_920B:	/* 3c920B-EMB */         sc->xl_media = XL_MEDIAOPT_MII;         sc->xl_xcvr = XL_XCVR_MII;         if (verbose)            printk("etherlink : unit elnk%d guessing MII\n", sc->xl_unit);         break;      case TC_DEVICEID_BOOMERANG_100BT4:	/* 3c905-T4 */      case TC_DEVICEID_CYCLONE_10_100BT4:	/* 3c905B-T4 */         sc->xl_media = XL_MEDIAOPT_BT4;         sc->xl_xcvr = XL_XCVR_MII;         if (verbose)            printk("etherlink : unit elnk%d guessing 100BaseT4/MII\n", sc->xl_unit);         break;      case TC_DEVICEID_HURRICANE_10_100BT:	/* 3c905B-TX */      case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */      case TC_DEVICEID_TORNADO_10_100BT_SERV:	/* 3c980C-TX */      case TC_DEVICEID_HURRICANE_SOHO100TX:	/* 3cSOHO100-TX */      case TC_DEVICEID_TORNADO_10_100BT:	/* 3c905C-TX */      case TC_DEVICEID_TORNADO_HOMECONNECT:	/* 3c450-TX */         sc->xl_media = XL_MEDIAOPT_BTX;         sc->xl_xcvr = XL_XCVR_AUTO;         if (verbose)            printk("etherlink : unit elnk%d guessing 10/100 internal\n", sc->xl_unit);         break;      case TC_DEVICEID_CYCLONE_10_100_COMBO:	/* 3c905B-COMBO */         sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;         sc->xl_xcvr = XL_XCVR_AUTO;         if (verbose)            printk("etherlink : unit elnk%d guessing 10/100 "                   "plus BNC/AUI\n", sc->xl_unit);         break;      default:         printk("etherlink : unit elnk%d unknown device ID: %x -- "                "defaulting to 10baseT\n", sc->xl_unit, devid);         sc->xl_media = XL_MEDIAOPT_BT;         break;   }   return;}/* * This routine is a kludge to work around possible hardware faults * or manufacturing defects that can cause the media options register * (or reset options register, as it's called for the first generation * 3c90x adapters) to return an incorrect result. I have encountered * one Dell Latitude laptop docking station with an integrated 3c905-TX * which doesn't have any of the 'mediaopt' bits set. This screws up * the attach routine pretty badly because it doesn't know what media * to look for. If we find ourselves in this predicament, this routine * will try to guess the media options values and warn the user of a * possible manufacturing defect with his adapter/system/whatever. */static voidxl_mediacheck(sc)   struct elnk_softc		*sc;{   xl_choose_xcvr(sc, 1);   /*    * If some of the media options bits are set, assume they are    * correct. If not, try to figure it out down below.    * XXX I should check for 10baseFL, but I don't have an adapter    * to test with.    */   if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {      /*       * Check the XCVR value. If it's not in the normal range       * of values, we need to fake it up here.       */      if (sc->xl_xcvr <= XL_XCVR_AUTO)         return;      else {         printk("etherlink : unit elnk%d bogus xcvr value "                "in EEPROM (%x)\n", sc->xl_unit, sc->xl_xcvr);         printk("etherlink : unit elnk%d choosing new default based "                "on card type\n", sc->xl_unit);      }   } else {      if (sc->xl_type == XL_TYPE_905B &&          sc->xl_media & XL_MEDIAOPT_10FL)         return;      printk("etherlink : unit elnk%d WARNING: no media options bits set in "             "the media options register!!\n", sc->xl_unit);      printk("etherlink : unit elnk%d this could be a manufacturing defect in "             "your adapter or system\n", sc->xl_unit);      printk("etherlink : unit elnk%d attempting to guess media type; you "             "should probably consult your vendor\n", sc->xl_unit);   }   return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -