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

📄 sonic.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
   *  request an interrupt on every other transmitted packet.   *   *  NOTE: sonic_allocate() zeroes all of the memory allocated.   */  sc->tdaTail = sonic_allocate(sc->tdaCount * sizeof *tdp);#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)  printf( "tdaTail = %p\n", sc->tdaTail );#endif  tdp = sc->tdaTail;  for (i = 0 ; i < sc->tdaCount ; i++) {    /*     *  Start off with the table of outstanding mbuf's      */    /*     *  status, pkt_config, pkt_size, and all fragment fields      *  are set to zero by sonic_allocate.     *//* XXX not used by the BSD drivers    tdp->frag[0].frag_link = LSW(tdp + 1);*/    if (i & 3)      tdp->pkt_config = TDA_CONFIG_PINT;    tdp->status 	= 0;    tdp->frag_count     = 0;    tdp->link_pad       = LSW(tdp + 1) | TDA_LINK_EOL;    tdp->linkp          = &((tdp + 1)->frag[0].frag_link);    tdp->next           = (TransmitDescriptor_t *)(tdp + 1);#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)    sonic_print_tx_descriptor( tdp );#endif    tdp++;  }  tdp--;  sc->tdaHead = tdp;  tdp->link_pad = LSW(sc->tdaTail) | TDA_LINK_EOL;  tdp->next = (TransmitDescriptor_t *)sc->tdaTail;  tdp->linkp = &sc->tdaTail->frag[0].frag_link;  /*   *  Set up circular linked list in Receive Descriptor Area.   *  Leaves sc->rda pointing at the `beginning' of the list.   *   *  NOTE: The RDA and CDP must have the same MSW for their addresses.   */  sc->rda = sonic_allocate(              (sc->rdaCount * sizeof(ReceiveDescriptor_t)) +                 sizeof(CamDescriptor_t) );  sc->cdp = (CamDescriptorPointer_t) ((unsigned char *)sc->rda +        (sc->rdaCount * sizeof(ReceiveDescriptor_t)));#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)  printf( "rda area = %p\n", sc->rda );  printf( "cdp area = %p\n", sc->cdp );#endif  ordp = rdp = sc->rda;  for (i = 0 ; i < sc->rdaCount ; i++) {    /*     *  status, byte_count, pkt_ptr0, pkt_ptr1, and seq_no are set     *  to zero by sonic_allocate.     */    rdp->link   = LSW(rdp + 1);    rdp->in_use = RDA_FREE;    rdp->next   = (ReceiveDescriptor_t *)(rdp + 1);    ordp = rdp;    rdp++;  }  /*   *  Link the last desriptor to the 1st one and mark it as the end   *  of the list.   */  ordp->next   = sc->rda;  ordp->link   = LSW(sc->rda) | RDA_LINK_EOL;  sc->rdp_last = ordp;   /*   * Allocate the receive resource area.   * In accordance with National Application Note 746, make the   * receive resource area bigger than the receive descriptor area.   * This has the useful side effect of making the receive resource   * area big enough to hold the CAM descriptor area.   */  sc->rsa = sonic_allocate((sc->rdaCount + RRA_EXTRA_COUNT) * sizeof *sc->rsa);#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)  printf( "rsa area = %p\n", sc->rsa );#endif  /*   *  Set up list in Receive Resource Area.   *  Allocate space for incoming packets.   */  rwp = sc->rsa;  for (i = 0 ; i < (sc->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {    /*     * Allocate memory for buffer.     * Place a pointer to the mbuf at the beginning of the buffer     * so we can find the mbuf when the SONIC returns the buffer     * to the driver.     */        MGETHDR (m, M_WAIT, MT_DATA);    MCLGET (m, M_WAIT);    m->m_pkthdr.rcvif = &sc->arpcom.ac_if;    sc->rda[i].mbufp = m;    p = mtod (m, void *);    /*     * Set up RRA entry     */    rwp->buff_ptr_lsw = LSW(p);    rwp->buff_ptr_msw = MSW(p);    rwp->buff_wc_lsw = RBUF_WC;    rwp->buff_wc_msw = 0;#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)    sonic_print_rx_descriptor( &sc->rda[i] );#endif  }  sc->rea = rwp;#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)  printf( "rea area = %p\n", sc->rea );#endif  /*   * Issue a software reset.   */  (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );  /*   * Set up data configuration registers.   */  (*sc->write_register)( rp, SONIC_REG_DCR, sc->dcr_value );  (*sc->write_register)( rp, SONIC_REG_DCR2, sc->dc2_value );  (*sc->write_register)( rp, SONIC_REG_CR, CR_STP | CR_RXDIS | CR_HTX );  /*   * Mask all interrupts   */  (*sc->write_register)( rp, SONIC_REG_IMR, 0x0 ); /* XXX was backwards */  /*   * Clear outstanding interrupts.   */  (*sc->write_register)( rp, SONIC_REG_ISR, 0x7FFF );  /*   *  Clear the tally counters   */  (*sc->write_register)( rp, SONIC_REG_CRCT, 0xFFFF );  (*sc->write_register)( rp, SONIC_REG_FAET, 0xFFFF );  (*sc->write_register)( rp, SONIC_REG_MPT, 0xFFFF );  (*sc->write_register)( rp, SONIC_REG_RSC, 0 );  /*   *  Set the Receiver mode   *   *  Enable/disable reception of broadcast packets   */  if (sc->acceptBroadcast)    (*sc->write_register)( rp, SONIC_REG_RCR, RCR_BRD );  else    (*sc->write_register)( rp, SONIC_REG_RCR, 0 );  /*   * Set up Resource Area pointers   */  (*sc->write_register)( rp, SONIC_REG_URRA, MSW(sc->rsa) );  (*sc->write_register)( rp, SONIC_REG_RSA, LSW(sc->rsa) );  (*sc->write_register)( rp, SONIC_REG_REA, LSW(sc->rea) );  (*sc->write_register)( rp, SONIC_REG_RRP, LSW(sc->rsa) );  (*sc->write_register)( rp, SONIC_REG_RWP, LSW(sc->rsa) ); /* XXX was rea */  (*sc->write_register)( rp, SONIC_REG_URDA, MSW(sc->rda) );  (*sc->write_register)( rp, SONIC_REG_CRDA, LSW(sc->rda) );  (*sc->write_register)( rp, SONIC_REG_UTDA, MSW(sc->tdaTail) );  (*sc->write_register)( rp, SONIC_REG_CTDA, LSW(sc->tdaTail) );  /*   * Set End Of Buffer Count register to the value recommended   * in Note 1 of Section 3.4.4.4 of the SONIC data sheet.   */  (*sc->write_register)( rp, SONIC_REG_EOBC, RBUF_WC - 2 );  /*   *  Issue the load RRA command   */  (*sc->write_register)( rp, SONIC_REG_CR, CR_RRRA );  while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_RRRA)    continue;  /*   * Remove device reset   */  (*sc->write_register)( rp, SONIC_REG_CR, 0 );  /*   *  Set up the SONIC CAM with our hardware address.   */  hwaddr = sc->arpcom.ac_enaddr;  cdp = sc->cdp;#if (SONIC_DEBUG & SONIC_DEBUG_CAM)  printf( "hwaddr: %2x:%2x:%2x:%2x:%2x:%2x\n",     hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5] );#endif  cdp->cep  = 0;                     /* Fill first and only entry in CAM */  cdp->cap0 = hwaddr[1] << 8 | hwaddr[0];  cdp->cap1 = hwaddr[3] << 8 | hwaddr[2];  cdp->cap2 = hwaddr[5] << 8 | hwaddr[4];  cdp->ce   = 0x0001;                /* Enable first entry in CAM */  (*sc->write_register)( rp, SONIC_REG_CDC, 1 );      /* 1 entry in CDA */  (*sc->write_register)( rp, SONIC_REG_CDP, LSW(cdp) );  (*sc->write_register)( rp, SONIC_REG_CR,  CR_LCAM );  /* Load the CAM */  while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_LCAM)    continue;  /*   * Verify that CAM was properly loaded.   */  (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );#if (SONIC_DEBUG & SONIC_DEBUG_CAM)  (*sc->write_register)( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */    printf ("Loaded Ethernet address into SONIC CAM.\n"      "  Wrote %04x%04x%04x - %#x\n"      "   Read %04x%04x%04x - %#x\n",         cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,        (*sc->read_register)( rp, SONIC_REG_CAP2 ),        (*sc->read_register)( rp, SONIC_REG_CAP1 ),        (*sc->read_register)( rp, SONIC_REG_CAP0 ),        (*sc->read_register)( rp, SONIC_REG_CE ));  (*sc->write_register)( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */  if (((*sc->read_register)( rp, SONIC_REG_CAP2 ) != cdp->cap2)   || ((*sc->read_register)( rp, SONIC_REG_CAP1 ) != cdp->cap1)   || ((*sc->read_register)( rp, SONIC_REG_CAP0 ) != cdp->cap0)   || ((*sc->read_register)( rp, SONIC_REG_CE ) != cdp->ce)) {    printf ("Failed to load Ethernet address into SONIC CAM.\n"      "  Wrote %04x%04x%04x - %#x\n"      "   Read %04x%04x%04x - %#x\n",         cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,        (*sc->read_register)( rp, SONIC_REG_CAP2 ),        (*sc->read_register)( rp, SONIC_REG_CAP1 ),        (*sc->read_register)( rp, SONIC_REG_CAP0 ),        (*sc->read_register)( rp, SONIC_REG_CE ));    rtems_panic ("SONIC LCAM");  }#endif  (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);  /*   * Attach SONIC interrupt handler   *//* XXX  (*sc->write_register)( rp, SONIC_REG_IMR, 0 );*/  old_handler = set_vector(sonic_interrupt_handler, sc->vector, 1);  /*   * Remainder of hardware initialization is   * done by the receive and transmit daemons.   */}/* * Send packet (caller provides header). */SONIC_STATIC void sonic_start(struct ifnet *ifp){  struct sonic_softc *sc = ifp->if_softc;  rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);  ifp->if_flags |= IFF_OACTIVE;}/* * Initialize and start the device */SONIC_STATIC void sonic_init (void *arg){  struct sonic_softc *sc = arg;  struct ifnet *ifp = &sc->arpcom.ac_if;  void *rp = sc->sonic;  int rcr;  if (sc->txDaemonTid == 0) {    /*     * Set up SONIC hardware     */    sonic_initialize_hardware (sc);    /*     * Start driver tasks     */    sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);    sc->txDaemonTid = rtems_bsdnet_newproc ("SNtx", 4096, sonic_txDaemon, sc);  }  /*   * Set flags appropriately   */  rcr = (*sc->read_register)( rp, SONIC_REG_RCR );  if (ifp->if_flags & IFF_PROMISC)    rcr |= RCR_PRO;  else    rcr &= ~RCR_PRO;  (*sc->write_register)( rp, SONIC_REG_RCR, rcr);  /*   * Tell the world that we're running.   */  ifp->if_flags |= IFF_RUNNING;  /*   * Enable receiver and transmitter   */  sonic_enable_interrupts( sc, IMR_TXEREN | (IMR_PRXEN | IMR_RBAEEN) );  sonic_command( sc, CR_RXEN );}/* * Driver ioctl handler */static intsonic_ioctl (struct ifnet *ifp, int command, caddr_t data){  struct sonic_softc *sc = ifp->if_softc;  int error = 0;  switch (command) {    case SIOCGIFADDR:    case SIOCSIFADDR:      ether_ioctl (ifp, command, data);      break;    case SIOCSIFFLAGS:      switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {        case IFF_RUNNING:          sonic_stop (sc);          break;        case IFF_UP:          sonic_init (sc);          break;        case IFF_UP | IFF_RUNNING:          sonic_stop (sc);          sonic_init (sc);          break;        default:          break;        }      break;    case SIO_RTEMS_SHOW_STATS:      sonic_stats (sc);      break;        /*     * FIXME: All sorts of multicast commands need to be added here!     */    default:      error = EINVAL;      break;  }  return error;}/* * Attach an SONIC driver to the system * This is the only `extern' function in the driver. */intrtems_sonic_driver_attach (  struct rtems_bsdnet_ifconfig *config,  sonic_configuration_t *chip){  struct sonic_softc *sc;  struct ifnet *ifp;  int mtu;  int unitNumber;  char *unitName;  /*   * Parse driver name   */  if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)    return 0;  /*   * Is driver free?   */  if ((unitNumber <= 0) || (unitNumber > NSONIC)) {    printf ("Bad SONIC unit number.\n");     return 0;  }  sc = &sonic_softc[unitNumber - 1];  ifp = &sc->arpcom.ac_if;  if (ifp->if_softc != NULL) {    printf ("Driver already in use.\n");    return 0;  }  /*   *  zero out the control structure   */  memset( sc, 0, sizeof(*sc) );  /*   * Process options   */  if (config->hardware_address) {    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {    memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);  }  if (config->mtu)    mtu = config->mtu;  else    mtu = ETHERMTU;  if (config->rbuf_count)    sc->rdaCount = config->rbuf_count;  else    sc->rdaCount = chip->rda_count;  if (config->xbuf_count)    sc->tdaCount = config->xbuf_count;  else    sc->tdaCount = chip->tda_count;  sc->acceptBroadcast = !config->ignore_broadcast;  sc->sonic = (void *) chip->base_address;  sc->vector = chip->vector;  sc->dcr_value = chip->dcr_value;  sc->dc2_value  = chip->dc2_value;  sc->write_register = chip->write_register;  sc->read_register  = chip->read_register;  /*   * Set up network interface values   */  ifp->if_softc = sc;  ifp->if_unit = unitNumber;  ifp->if_name = unitName;  ifp->if_mtu = mtu;  ifp->if_init = sonic_init;  ifp->if_ioctl = sonic_ioctl;  ifp->if_start = sonic_start;  ifp->if_output = ether_output;  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;  if (ifp->if_snd.ifq_maxlen == 0)    ifp->if_snd.ifq_maxlen = ifqmaxlen;  /*   * Attach the interface   */  if_attach (ifp);  ether_ifattach (ifp);  return 1;}#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)#include <stdio.h>char SONIC_Reg_name[64][6]= {    "CR",         /* 0x00 */    "DCR",        /* 0x01 */    "RCR",        /* 0x02 */    "TCR",        /* 0x03 */    "IMR",        /* 0x04 */    "ISR",        /* 0x05 */    "UTDA",       /* 0x06 */    "CTDA",       /* 0x07 */    "0x08",       /* 0x08 */    "0x09",       /* 0x09 */    "0x0A",       /* 0x0A */    "0x0B",       /* 0x0B */    "0x0C",       /* 0x0C */    "URDA",       /* 0x0D */    "CRDA",       /* 0x0E */    "0x0F",       /* 0x0F */    "0x10",       /* 0x10 */    "0x11",       /* 0x11 */    "0x12",       /* 0x12 */    "EOBC",       /* 0x13 */    "URRA",       /* 0x14 */    "RSA",        /* 0x15 */    "REA",        /* 0x16 */    "RRP",        /* 0x17 */    "RWP",        /* 0x18 */    "0x19",       /* 0x19 */    "0x1A",       /* 0x1A */    "0x1B",       /* 0x1B */    "0x1C",       /* 0x1C */    "0x0D",       /* 0x1D */    "0x1E",       /* 0x1E */    "0x1F",       /* 0x1F */    "0x20",       /* 0x20 */    "CEP",        /* 0x21 */    "CAP2",       /* 0x22 */    "CAP1",       /* 0x23 */    "CAP0",       /* 0x24 */    "CE",         /* 0x25 */    "CDP",        /* 0x26 */    "CDC",        /* 0x27 */    "SR",         /* 0x28 */    "WT0",        /* 0x29 */    "WT1",        /* 0x2A */    "RSC",        /* 0x2B */    "CRCT",       /* 0x2C */    "FAET",       /* 0x2D */    "MPT",        /* 0x2E */    "MDT",        /* 0x2F */    "0x30",       /* 0x30 */    "0x31",       /* 0x31 */    "0x32",       /* 0x32 */    "0x33",       /* 0x33 */    "0x34",       /* 0x34 */    "0x35",       /* 0x35 */    "0x36",       /* 0x36 */    "0x37",       /* 0x37 */    "0x38",       /* 0x38 */    "0x39",       /* 0x39 */    "0x3A",       /* 0x3A */    "0x3B",       /* 0x3B */    "0x3C",       /* 0x3C */    "0x3D",       /* 0x3D */    "0x3E",       /* 0x3E */    "DCR2"        /* 0x3F */};#endif

⌨️ 快捷键说明

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