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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
         uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL;         UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n")         UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n")         UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n")				 #ifdef DBG_MEM         printk(("uti596_supplyFD: starting receiver"))				 #endif         /* start the receiver */         UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n")         uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;         uti596_softc.scb.rfd_pointer = word_swap ((unsigned long) uti596_softc.pBeginRFA);                  /* Don't ack RNR! The receiver should be stopped in this case */         uti596_softc.scb.command = RX_START | SCB_STAT_RNR;                  UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n")         /* send CA signal */         uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );       }     }     return;   } } else {   /*    * too late , pLastRfd in use ( or NULL ),    * in either case, EL bit has been read, and RNR condition will occur    */   uti596_append( (i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */   uti596_softc.pEndSavedQueue = pRfd;  /* reset end of saved queue */   uti596_softc.savedCount++;   return; }}/* *  send_packet *  *  Send a raw ethernet packet, add a *  	transmit command to the CBL *  *  Input parameters: *  	ifp - a pointer to the ifnet structure *  	  m	-	a pointer to the mbuf being sent * *  Output parameters: NONE  * *  Return value: NONE */void send_packet(  struct ifnet *ifp, struct mbuf *m){  i596_tbd *pPrev = I596_NULL;  i596_tbd *pRemainingTbdList;  i596_tbd *pTbd;  struct mbuf *n, *input_m = m;  uti596_softc_ *sc = ifp->if_softc;  struct mbuf *l = NULL;  unsigned int length = 0;  rtems_status_code status;  int bd_count = 0;  rtems_event_set events; /*  * For all mbufs in the chain,  *  fill a transmit buffer descriptor for each  */  pTbd = (i596_tbd*) word_swap ((unsigned long)sc->pTxCmd->pTbd);  do {    if (m->m_len) {      /*       * Fill in the buffer descriptor       */      length    += m->m_len;      pTbd->data = (char *) word_swap ((unsigned long) mtod (m, void *));      pTbd->size = m->m_len;      pPrev      = pTbd;      pTbd       = (i596_tbd *) word_swap ((unsigned long) pTbd->next);      l          = m;      m          = m->m_next;    }    else {      /*       * Just toss empty mbufs       */      MFREE (m, n);      m = n;      if (l != NULL)        l->m_next = m;    }  } while( m != NULL && ++bd_count < 16 );  if ( length < UTI_596_ETH_MIN_SIZE ) {    pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */    pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */  }  else   /* Don't use pTbd in the send routine */    pTbd = pPrev;  /*  Disconnect the packet from the list of Tbd's  */  pRemainingTbdList = (i596_tbd *) word_swap ((unsigned long)pTbd->next);  pTbd->next  = I596_NULL;  pTbd->size |= UTI_596_END_OF_FRAME;  sc->rawsndcnt++;	#ifdef DBG_SEND  printk(("send_packet: sending packet\n"))	#endif  /* Sending Zero length packet: shouldn't happen */  if (pTbd->size <= 0) return;	#ifdef DBG_PACKETS  printk     (("\nsend_packet: Transmitter adds packet\n"))  print_hdr  ( sc->pTxCmd->pTbd->data ); /* print the first part */  print_pkt  ( sc->pTxCmd->pTbd->next->data ); /* print the first part */  print_echo (sc->pTxCmd->pTbd->data);	#endif  /* add the command to the output command queue */  uti596_addCmd ( (i596_cmd *) sc->pTxCmd );  /* sleep until the command has been processed or Timeout encountered. */  status= rtems_bsdnet_event_receive (INTERRUPT_EVENT,                                      RTEMS_WAIT|RTEMS_EVENT_ANY,                                      RTEMS_NO_TIMEOUT,                                      &events);  if ( status != RTEMS_SUCCESSFUL ) {    printk(("Could not sleep %s\n", rtems_status_text(status)))  }	#ifdef DBG_SEND  printk(("send_packet: RAW - wake\n"))	#endif  sc->txInterrupts++;  if ( sc->pTxCmd -> cmd.status & STAT_OK ) {    sc->stats.tx_packets++;  }  else {    printk(("*** send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status ))    sc->stats.tx_errors++;    if ( sc->pTxCmd->cmd.status  & 0x0020 )      sc->stats.tx_retries_exceeded++;    if (!(sc->pTxCmd->cmd.status & 0x0040))      sc->stats.tx_heartbeat_errors++;    if ( sc->pTxCmd->cmd.status  & 0x0400 )      sc->stats.tx_carrier_errors++;    if ( sc->pTxCmd->cmd.status  & 0x0800 )      sc->stats.collisions++;    if ( sc->pTxCmd->cmd.status  & 0x1000 )      sc->stats.tx_aborted_errors++;  } /* end if stat_ok */  /*   * Restore the transmitted buffer descriptor chain.   */  pTbd -> next = (i596_tbd *) word_swap ((unsigned long)pRemainingTbdList);  /*   * Free the mbufs used by the sender.   */  m = input_m;  while ( m != NULL ) {    MFREE(m,n);    m = n;  }}/*********************************************************************** *  Function:   uti596_attach * *  Description: *              Configure the driver, and connect to the network stack * *  Algorithm: * *              Check parameters in the ifconfig structure, and *              set driver parameters accordingly. *              Initialize required rx and tx buffers. *              Link driver data structure onto device list. *              Return 1 on successful completion. * ***********************************************************************/int uti596_attach(  struct rtems_bsdnet_ifconfig * pConfig,  int attaching){  uti596_softc_ *sc = &uti596_softc;				/* device dependent data structure */  struct ifnet * ifp = (struct ifnet *)&sc->arpcom.ac_if;       /* ifnet structure */  unsigned char j1;    /* State of J1 jumpers */  int unitNumber;  char *unitName;#if defined(mvme167)  char *pAddr;  int addr;#endif  #ifdef DBG_ATTACH  printk(("uti596_attach: begins\n"))  #endif  /* The NIC is not started yet */  sc->started = 0;  /* Indicate to ULCS that this is initialized */  ifp->if_softc = (void *)sc;  sc->pScp = NULL;  /* Parse driver name */  if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)    return 0;  ifp->if_name = unitName;  ifp->if_unit = unitNumber;  /* Assign mtu */  if ( pConfig -> mtu )    ifp->if_mtu = pConfig -> mtu;  else    ifp->if_mtu = ETHERMTU;  /*    * Check whether parameters should be obtained from NVRAM. If   * yes, and if an IP address, netmask, or ethernet address are   * provided in NVRAM, cheat, and stuff them into the ifconfig   * structure, OVERRIDING and existing or NULL values.   *    * Warning: If values are provided in NVRAM, the ifconfig entries   * must be NULL because buffer memory allocated to hold the   * structure values is unrecoverable and would be lost here.   */  /* Read the J1 header */  j1 = (unsigned char)(lcsr->vector_base & 0xFF);#if defined(mvme167)  if ( !(j1 & 0x10) ) {  	/* Jumper J1-4 is on, configure from NVRAM */      if ( (addr = nvram->ipaddr) ) {      /* We have a non-zero entry, copy the value */      if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) )        pConfig->ip_address = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );      else        rtems_panic("Can't allocate ip_address buffer!\n");    }        if ( (addr = nvram->netmask) ) {      /* We have a non-zero entry, copy the value */      if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) )        pConfig->ip_netmask = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );      else        rtems_panic("Can't allocate ip_netmask buffer!\n");    }    /* Ethernet address requires special handling -- it must be copied into     * the arpcom struct. The following if construct serves only to give the     * NVRAM parameter the highest priority if J1-4 indicates we are configuring     * from NVRAM.     *      * If the ethernet address is specified in NVRAM, go ahead and copy it.     * (ETHER_ADDR_LEN = 6 bytes).     */    if ( nvram->enaddr[0] || nvram->enaddr[1] || nvram->enaddr[2] ) {      /* Anything in the first three bytes indicates a non-zero entry, copy value */  	  memcpy ((void *)sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);    }    else if ( pConfig->hardware_address) {      /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */      memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);    }    else {      /* There is no ethernet address provided, so it will be read       * from BBRAM at $FFFC1F2C by default. [mvme167 manual p. 1-47]       */      memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);    }  }  else if ( pConfig->hardware_address) {    /* We are not configuring from NVRAM (J1-4 is off), and the ethernet address     * is given in the ifconfig structure. Copy it.     */    memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);  }  else#endif  {    /* We are not configuring from NVRAM (J1-4 is off), and there is no ethernet     * address provided in the ifconfig struct, so it will be read from BBRAM at     * $FFFC1F2C by default. [mvme167 manual p. 1-47]     */    memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);  }  /* Possibly override default acceptance of broadcast packets */  if (pConfig->ignore_broadcast)  	uti596initSetup[8] |= 0x02;  /* Assign requested receive buffer descriptor count */  if (pConfig->rbuf_count)    sc->rxBdCount = pConfig->rbuf_count;  else    sc->rxBdCount = RX_BUF_COUNT;  /* Assign requested tx buffer descriptor count */  if (pConfig->xbuf_count)    sc->txBdCount = pConfig->xbuf_count;  else    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;  /* Set up fields in the ifnet structure*/  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;  ifp->if_snd.ifq_maxlen = ifqmaxlen;  ifp->if_init = uti596_init;  ifp->if_ioctl = uti596_ioctl;  ifp->if_start = uti596_start;  ifp->if_output = ether_output;  /* uti596_softc housekeeping */  sc->started = 1;  sc->pInboundFrameQueue = I596_NULL;  sc->scb.command = 0;  /*   * Attach the interface   */  if_attach (ifp);  ether_ifattach (ifp);  return 1;}/*********************************************************************** *  Function:  uti596_start * *  Description: *             start the driver * *  Algorithm: *             send an event to the tx task *             set the if_flags * ***********************************************************************/static void uti596_start(  struct ifnet *ifp){  uti596_softc_ *sc = ifp->if_softc;  	#ifdef DBG_START  printk(("uti596_start: begins\n"))	#endif	  rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);  ifp->if_flags |= IFF_OACTIVE;}/*********************************************************************** *  Function:  uti596_init * *  Description: *             driver initialization * *  Algorithm: *             initialize the 82596 *             start driver tx and rx tasks, and reset task *             send the RX_START command the the RU *             set if_flags * * ***********************************************************************/void uti596_init(  void * arg){  uti596_softc_ *sc = arg;  struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;  if (sc->txDaemonTid == 0) {    /*     * Initialize the 82596     */    #ifdef DBG_INIT    printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n"))    #endif    uti596_initialize_hardware(sc);    /*     * Start driver tasks     */    #ifdef DBG_INIT    printk(("uti596_init: starting driver tasks...\n"))    #endif    sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, (void *)sc);    sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, (void *)sc);    sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, (void *)sc);    #ifdef DBG_INIT    printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status ))    #endif  }  /*   * Enable receiver   */  #ifdef DBG_INIT  printk(("uti596_init: enabling the reciever...\n" ))  #endif  sc->scb.command = RX_START;  uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );    /*   * Tell the world that we're running.   */  ifp->if_flags |= IFF_RUNNING;  #ifdef DBG_INIT  printk(("uti596_init: completed.\n"))  #endif  }/*********************************************************************** *  Function:   uti596stop * *  Description: *             stop the driver * *  Algorithm: *             mark driver as not started, *             mark transmitter as busy *             abort any transmissions/receptions *             clean-up all buffers ( RFD's et. al. ) * * ***********************************************************************//* static */ void uti596_stop(  uti596_softc_ *sc){  struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;  ifp->if_flags &= ~IFF_RUNNING;  sc->started = 0;  #ifdef DBG_STOP  printk(("uti596stop: %s: Shutting down ethercard, status was %4.4x.\n",           uti596_softc.arpcom.ac_if.if_name, uti596_softc.scb.status))  #endif  printk(("Stopping interface\n"))  sc->scb.command = CUC_ABORT | RX_ABORT;  i82596->chan_attn = 0x00000000;}/*********************************************************************** *  Function:   void uti596_txDaemon * *  Description: Transmit task *   *  Algorithm: Get mbufs to be transmitted, stuff into RFDs, send *   ***********************************************************************/void uti596_txDaemon(

⌨️ 快捷键说明

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