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

📄 dec21140.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
    */   status = ld_le32(tbase+memCSR5);   st_le32((tbase+memCSR5), status);   /*    * Frame received?    */   if( status & 0x000000c0 )   {      sc->rxInterrupts++;      rtems_event_send(rxDaemonTid, sc->ioevent);   }}static rtems_isrdec21140Enet_interrupt_handler_entry(){   int i;   /*   ** Check all the initialized dec units for interrupt service   */   for(i=0; i< NDECDRIVER; i++ )   {      if( dec21140_softc[i].base )         dec21140Enet_interrupt_handler( &dec21140_softc[i] );   }}/* * Initialize the ethernet hardware */static voiddec21140Enet_initialize_hardware (struct dec21140_softc *sc){   int i,st;   volatile unsigned int  *tbase;   volatile unsigned char *cp, *setup_frm, *eaddrs;    volatile unsigned char *buffer;   volatile struct MD     *rmd;#ifdef DEC_DEBUG   printk("dec2114x : %02x:%02x:%02x:%02x:%02x:%02x   name '%s%d', io %x, mem %x, int %d\n",          sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],          sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],          sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],          sc->arpcom.ac_if.if_name, sc->arpcom.ac_if.if_unit,          sc->port, (unsigned) sc->base, sc->irqInfo.name );#endif   tbase = sc->base;   /*    * WARNING : First write in CSR6    *           Then Reset the chip ( 1 in CSR0)    */   st_le32( (tbase+memCSR6), CSR6_INIT);     st_le32( (tbase+memCSR0), RESET_CHIP);     rtems_bsp_delay_in_bus_cycles(200);   st_le32( (tbase+memCSR7), NO_IT);    /*    * Init CSR0    */   st_le32( (tbase+memCSR0), CSR0_MODE);     /*    * Init RX ring    */   cp = (volatile unsigned char *)malloc(((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))                                         + (sc->numTxbuffers*RBUF_SIZE)                                         + CPU_CACHE_ALIGNMENT_FOR_BUFFER);   sc->bufferBase = cp;   cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);#if defined(__i386__)#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA    if (_CPU_is_paging_enabled())      _CPU_change_memory_mapping_attribute         (NULL, cp,          ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))          + (sc->numTxbuffers*RBUF_SIZE),          PTE_CACHE_DISABLE | PTE_WRITABLE);#endif#endif   rmd = (volatile struct MD*)cp;   sc->MDbase = rmd;   sc->nextRxMD = sc->MDbase;   buffer = cp + ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD));   st_le32( (tbase+memCSR3), (long)(phys_to_bus((long)(sc->MDbase))));   for (i=0 ; i<sc->numRxbuffers; i++)   {      struct mbuf *m;          /* allocate an mbuf for each receive descriptor */      MGETHDR (m, M_WAIT, MT_DATA);      MCLGET (m, M_WAIT);      m->m_pkthdr.rcvif = &sc->arpcom.ac_if;      rmd->m = m;      rmd->buf2   = phys_to_bus(rmd+1);      rmd->buf1   = phys_to_bus(mtod(m, void *));        rmd->status = 0x80000000;      rmd->counts = 0xfdc00000 | (RBUF_SIZE);      rmd->next   = rmd+1;      rmd++;   }   /*    * mark last RX buffer.    */   sc->MDbase [sc->numRxbuffers-1].buf2   = 0;   sc->MDbase [sc->numRxbuffers-1].counts = 0xfec00000 | (RBUF_SIZE);   sc->MDbase [sc->numRxbuffers-1].next   = sc->MDbase;   /*    * Init TX ring    */   st_le32( (tbase+memCSR4), (long)(phys_to_bus((long)(rmd))) );   for (i=0 ; i<sc->numTxbuffers; i++){      (rmd+i)->buf2   = phys_to_bus(rmd+i+1);      (rmd+i)->buf1   = phys_to_bus(buffer + (i*RBUF_SIZE));      (rmd+i)->counts = 0x01000000;      (rmd+i)->status = 0x0;      (rmd+i)->next   = rmd+i+1;      (rmd+i)->m      = 0;   }    /*    * mark last TX buffer.    */   (rmd+sc->numTxbuffers-1)->buf2   = phys_to_bus(rmd);   (rmd+sc->numTxbuffers-1)->next   = rmd;   /*    * Build setup frame    */   setup_frm = (volatile unsigned char *)(bus_to_phys(rmd->buf1));   eaddrs = (char *)(sc->arpcom.ac_enaddr);   /* Fill the buffer with our physical address. */   for (i = 1; i < 16; i++) {      *setup_frm++ = eaddrs[0];      *setup_frm++ = eaddrs[1];      *setup_frm++ = eaddrs[0];      *setup_frm++ = eaddrs[1];      *setup_frm++ = eaddrs[2];      *setup_frm++ = eaddrs[3];      *setup_frm++ = eaddrs[2];      *setup_frm++ = eaddrs[3];      *setup_frm++ = eaddrs[4];      *setup_frm++ = eaddrs[5];      *setup_frm++ = eaddrs[4];      *setup_frm++ = eaddrs[5];   }   /* Add the broadcast address when doing perfect filtering */   memset((void*) setup_frm, 0xff, 12);   rmd->counts = 0x09000000 | 192 ;   rmd->status = 0x80000000;   st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TX);   st_le32( (tbase+memCSR1), 1);   while (rmd->status != 0x7fffffff);   rmd->counts = 0x01000000;       sc->TxMD = rmd+1;   sc->irqInfo.hdl  = (rtems_irq_hdl)dec21140Enet_interrupt_handler_entry;   sc->irqInfo.on   = no_op;   sc->irqInfo.off  = no_op;   sc->irqInfo.isOn = dec21140IsOn;#ifdef DEC_DEBUG   printk( "dec2114x: Installing IRQ %d\n", sc->irqInfo.name );#endif#ifdef BSP_SHARED_HANDLER_SUPPORT   st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );#else   st = BSP_install_rtems_irq_handler( &sc->irqInfo );#endif   if (!st)      rtems_panic ("dec2114x : Interrupt name %d already in use\n", sc->irqInfo.name );}static voiddec21140_rxDaemon (void *arg){   volatile unsigned int *tbase;   volatile struct MD    *rmd;   struct dec21140_softc *sc;   struct ifnet          *ifp;   struct ether_header   *eh;   struct mbuf           *m;   unsigned int          i,len;   rtems_event_set       events;   for (;;)   {      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,                                  RTEMS_WAIT|RTEMS_EVENT_ANY,                                  RTEMS_NO_TIMEOUT,                                  &events);      for(i=0; i< NDECDRIVER; i++ )      {         sc = &dec21140_softc[i];         if( sc->base )         {            if( events & sc->ioevent )            {               ifp   = &sc->arpcom.ac_if;               tbase = sc->base;               rmd   = sc->nextRxMD;               /*               ** Read off all the packets we've received on this unit               */               while((rmd->status & 0x80000000) == 0)               {                  /* printk("unit %i rx\n", ifp->if_unit ); */                                 /* pass on the packet in the mbuf */                  len = (rmd->status >> 16) & 0x7ff;                  m = (struct mbuf *)(rmd->m);                  m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);                  eh = mtod (m, struct ether_header *);                  m->m_data += sizeof(struct ether_header);                  ether_input (ifp, eh, m);                  /* get a new mbuf for the 21140 */                  MGETHDR (m, M_WAIT, MT_DATA);                  MCLGET (m, M_WAIT);                  m->m_pkthdr.rcvif = ifp;                  rmd->m = m;                  rmd->buf1 = phys_to_bus(mtod(m, void *));                  /* mark the descriptor as ready to receive */                  rmd->status = 0x80000000;                        rmd=rmd->next;               }               sc->nextRxMD = rmd;            }         }      }   }}static voidsendpacket (struct ifnet *ifp, struct mbuf *m){   struct dec21140_softc   *dp = ifp->if_softc;   volatile struct MD      *tmd;   volatile unsigned char  *temp;   struct mbuf             *n;   unsigned int            len;   volatile unsigned int   *tbase;   tbase = dp->base;   /*    * Waiting for Transmitter ready    */	   tmd = dp->TxMD;   n = m;   while ((tmd->status & 0x80000000) != 0)   {      tmd=tmd->next;   }   len = 0;   temp = (volatile unsigned char *)(bus_to_phys(tmd->buf1));     for (;;)   {      len += m->m_len;      memcpy((void*) temp, (char *)m->m_data, m->m_len);      temp += m->m_len ;      if ((m = m->m_next) == NULL)         break;   }   if (len < ET_MINLEN) len = ET_MINLEN;   tmd->counts =  0xe1000000 | (len & 0x7ff);     tmd->status = 0x80000000;   st_le32( (tbase+memCSR1), 0x1);   m_freem(n);   dp->TxMD = tmd->next;}/* * Driver transmit daemon */voiddec21140_txDaemon (void *arg){   struct dec21140_softc *sc;   struct ifnet          *ifp;   struct mbuf           *m;   int i;   rtems_event_set       events;   for (;;)    {      /*       * Wait for packets bound for any of the dec units       */      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,                                  RTEMS_EVENT_ANY | RTEMS_WAIT,                                   RTEMS_NO_TIMEOUT, &events);      for(i=0; i< NDECDRIVER; i++ )      {         sc  = &dec21140_softc[i];         if( sc->base )         {            if( events & sc->ioevent )            {               ifp = &sc->arpcom.ac_if;               /*                * Send packets till queue is empty                */               for(;;)                {                  IF_DEQUEUE(&ifp->if_snd, m);                  if( !m ) break;                  /* printk("unit %i tx\n", ifp->if_unit ); */                  sendpacket (ifp, m);               }               ifp->if_flags &= ~IFF_OACTIVE;            }         }      }   }}static voiddec21140_start (struct ifnet *ifp){   struct dec21140_softc *sc = ifp->if_softc;   rtems_event_send( txDaemonTid, sc->ioevent );   ifp->if_flags |= IFF_OACTIVE;}/* * Initialize and start the device */static voiddec21140_init (void *arg){   struct dec21140_softc *sc = arg;   struct ifnet *ifp = &sc->arpcom.ac_if;   volatile unsigned int *tbase;   /*    * Set up DEC21140 hardware if its not already been done    */   if( !sc->irqInfo.hdl )   {      dec21140Enet_initialize_hardware (sc);   }   /*    * Enable RX and TX    */   tbase = sc->base;   st_le32( (tbase+memCSR5), IT_SETUP);   st_le32( (tbase+memCSR7), IT_SETUP);    st_le32( (unsigned int*)(tbase+memCSR6), CSR6_INIT | CSR6_TXRX);   /*    * Tell the world that we're running.    */   ifp->if_flags |= IFF_RUNNING;}

⌨️ 快捷键说明

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