Changeset 9d81380 in rtems


Ignore:
Timestamp:
Mar 1, 1999, 11:50:22 PM (23 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
faf7f46
Parents:
73f6236
Message:

Updated Ethernet driver from Erik Ivanenko <erik.ivanenko@…>.
Comments follow:

Please find attached, the updated network driver. I have verified
that it is working as expected, by timestamping the error messages
generated from the ISR.

If you've taken a look inside, the network driver has a reset thread
in addition to the RX and TX threads. It is possible to avoid the
additional reset thread by allowing the TX driver to time out and then
checking status bits set by the ISR. However, this approach demands
that a transmission is necessary for the NIC to be reset.

Due to Eric V's ISR handling, I suppose that the reset routine could
be called from the "ISR" itself, due to the 8259 interrupt mode, and
that the interrupt is acknowledged prior to running the "ISR".
(Providing that no NIC interrupts are generated during reset -- I
worry about re-entrancy. )

This would be a minor improvement, but you know, I don't want to make
this driver my lifes work.



File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/i386ex/network/network.c

    r73f6236 r9d81380  
    55
    66void dump_scb(void);
     7void printk_time(void);
    78
    89#ifdef DBG_VERSION
     
    3536void dumpQ(void);
    3637
    37 #define UTI_596_ASSERT( condition, str )
    38 /*
    39  * {  if (!( condition ) ) printf(str); }
    40  */
     38#define UTI_596_ASSERT( condition, str ) { if (!( condition ) ) printk(str); }
    4139int count_rx = 0;
    4240
     
    107105#define RBUF_SIZE       1520
    108106
    109 #define UTI_596_RFD_NUMBER 4
    110107
    111108/*
     
    260257   
    261258    uti596_softc.pEndRFA -> next = I596_NULL;
    262     UTI_596_ASSERT(uti596_softc.countRFD == UTI_596_RFD_NUMBER,"INIT:WRONG RFD COUNT\n" );
     259    UTI_596_ASSERT(uti596_softc.countRFD == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" );
    263260   
    264261#ifdef DBG_596_RFA
     
    523520{
    524521  int boguscnt = 1000;
     522  rtems_status_code status_code;
     523  struct i596_cmd *pCmd;
     524 
     525  pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */
    525526 
    526527  /* reset the board  */
     
    566567 
    567568  sc->pCmdHead     = sc->scb.pCmd = I596_NULL;
     569  /*
     570   * Wake the transmitter if needed.
     571   */
     572  if ( uti596_softc.txDaemonTid && pCmd != I596_NULL ){ 
     573    printf("****RESET: wakes transmitter!\n");
     574    status_code = rtems_event_send (uti596_softc.txDaemonTid,
     575                           INTERRUPT_EVENT);
     576   
     577    if ( status_code != RTEMS_SUCCESSFUL )
     578      printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",
     579             uti596_softc.txDaemonTid, rtems_status_text (status_code) );
     580  }
    568581 
    569582#ifdef DBG_596
     
    964977
    965978  /* abort ALL of the current work */
    966   sc->scb.command = CUC_ABORT | RX_ABORT;
    967 
    968   outport_word(CHAN_ATTN,0);
    969   UTI_WAIT_COMMAND_ACCEPTED(4000, "reset: abort requested");
     979    /* FEB 17 REMOVED
     980    >>>>>
     981    sc->scb.command = CUC_ABORT | RX_ABORT;
     982    outport_word(CHAN_ATTN,0);
     983    UTI_WAIT_COMMAND_ACCEPTED(4000, "reset: abort requested");
     984    <<<<<
     985    */
    970986
    971987  uti596_reset_hardware(&uti596_softc); /* reset the ethernet hardware. must re-config */
     
    10151031    printf("Reset Set Address Failed\n");
    10161032  /*******/
    1017  
     1033
     1034  sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL; /* Feb 17. clear these out */
     1035
    10181036#ifdef DBG_RESET
    10191037  printf( "After reset, status and command: 0x%x, 0x%x\n",
     
    10251043  /* restore the RFA */
    10261044
    1027   dumpQ();
     1045  /*dumpQ();*/
    10281046
    10291047  if ( sc->pLastUnkRFD != I596_NULL ) {
     
    10531071  uti596clearListStatus(sc->pBeginRFA );
    10541072
    1055   dumpQ(); /* purely for testing */
    1056 
    1057   sc->irqInfo.on(&sc->irqInfo);  /* moved here. Was originally after command issued. */
     1073  /*  dumpQ();*/
     1074
     1075  printf("Reset:Starting NIC\n");
    10581076  sc->scb.command = RX_START;
    1059 
     1077  sc->started = 1;               /* we assume that the start works */
     1078  sc->resetDone = 1;             /* moved here from after channel attn. */
    10601079  outport_word(CHAN_ATTN,0 );
    10611080  UTI_WAIT_COMMAND_ACCEPTED(4000, "reset");
     1081  printf("Reset:Start complete \n");
     1082  UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n");
     1083  sc->irqInfo.on(&sc->irqInfo);  /* moved back here. Tried it before RX command issued. */
    10621084   
    1063   sc->resetDone = 1;
    1064  
    1065   sc->started = 1;
    1066 
    10671085  /* uti596addCmd(&uti506_softc.nop); */ /* just for fun */
    10681086 
     
    12301248     uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
    12311249
    1232      UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: wait prev"); /* ensure prev command complete */
     1250     UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: wait prev");
    12331251
    12341252     uti596_softc.scb.command = CUC_START;
    12351253     outport_word (CHAN_ATTN,0);
    12361254
    1237      UTI_WAIT_COMMAND_ACCEPTED(2000000,"Add Polled command: start"); /* ensure previous command complete */
    1238      /*     if ( !(pCmd -> status & STAT_C ) ){
    1239             printf("****FAILED poll command\n");
    1240             }
    1241             */
     1255     UTI_WAIT_COMMAND_ACCEPTED(2000000,"Add Polled command: start");
    12421256     uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
    12431257
     
    12691283         
    12701284          /*
    1271            * Send packets till queue is empty
     1285           * Send packets till queue is empty.
     1286           * Ensure that irq is on before sending.
    12721287           */
    12731288          for (;;) {
    1274             /*
    1275              * Get the next mbuf chain to transmit.
    1276              */
    1277             IF_DEQUEUE(&ifp->if_snd, m);
    1278             if (!m)
    1279               break;
    1280            
    1281             send_packet (ifp, m); /* blocks */
    1282           } 
     1289              /* Feb 17: No need to make sure a reset is in progress,
     1290               *         Since reset daemon runs at same priority as this thread
     1291               */
     1292              /*
     1293               * Get the next mbuf chain to transmit.
     1294               */
     1295              IF_DEQUEUE(&ifp->if_snd, m);
     1296              if (!m)
     1297                break;
     1298             
     1299              send_packet (ifp, m); /* blocks */
     1300          } /* end for */
    12831301          ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive  */
    12841302        }
     
    12951313        struct uti596_softc *sc = (struct uti596_softc *)arg;
    12961314        rtems_event_set events;
     1315        rtems_time_of_day tm_struct;
     1316
    12971317        /* struct ifnet *ifp = &sc->arpcom.ac_if; */
    12981318
     
    13051325                                      RTEMS_NO_TIMEOUT, &events);
    13061326
    1307           printf("reset daemon: Resetting NIC\n");
     1327          rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
     1328          printf("reset daemon: Resetting NIC @ %d:%d:%d \n",
     1329                 tm_struct.hour, tm_struct.minute, tm_struct.second);
    13081330
    13091331          sc->stats.nic_reset_count++;
     
    19121934 UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:on ISR entry");
    19131935
     1936 if ( !(i8259s_cache & 0x20 )) {
     1937   printk("****Error: network ISR running, no IRR!\n");
     1938   printk("****Error: i8259s_cache = 0x%x\n",i8259s_cache );
     1939   printk_time();
     1940 }
     1941
    19141942 scbStatus = uti596_softc.scb.status & 0xf000;
    19151943
     
    19251953   }
    19261954   else {
    1927      printk("\n***INFO:ISR won't process now\n");
     1955     printk("***INFO: ACK'd w/o processing. status = %x\n", scbStatus);
    19281956     return;
    19291957   }
     
    19351963 
    19361964 if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){
     1965   printk_time();
    19371966   printk("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus);
    19381967   uti596_softc.nic_reset = 1;
     
    19411970
    19421971 if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
     1972   printk_time();
    19431973   printk("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus);
    19441974   uti596_softc.nic_reset = 1;
     
    19471977
    19481978 if ( scbStatus & SCB_CUS_SUSPENDED ) {
     1979   printk_time();
    19491980   printk("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus);
    19501981   uti596_softc.nic_reset = 1;
     
    19531984
    19541985 if ( scbStatus & RU_SUSPENDED  ) {
     1986   printk_time();
    19551987   printk("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus);
    19561988   uti596_softc.nic_reset = 1;
     
    19591991 
    19601992 if ( scbStatus & SCB_STAT_RNR ) {
     1993   printk_time();
    19611994   printk("\n*****WARNING: RNR %x\n",scbStatus);
     1995   printk("*****INFO: RFD cmd: %x status:%x\n",
     1996          uti596_softc.pBeginRFA -> cmd,
     1997          uti596_softc.pBeginRFA -> stat);
    19621998 }
    19631999 
     
    20302066     if ( uti596_softc.countRFD != 0 ) {
    20312067       printk("****ERROR:Count is %d, but begin ptr is NULL\n",uti596_softc.countRFD );
    2032        dumpQ();
    20332068     }
    20342069   }
     
    20562091     
    20572092     /*
    2058       * Adjust the drivers command block list
     2093      * Adjust the command block list
    20592094      */
    20602095     uti596_softc.pCmdHead = pIsrCmd -> next;
     
    21092144           printk("wake TX:0x%x\n",uti596_softc.txDaemonTid);
    21102145#endif
    2111            if ( uti596_softc.txDaemonTid ){  /* Ensure that the transmitter is waiting */
     2146           if ( uti596_softc.txDaemonTid ){  /* Ensure that the transmitter is present */
    21122147             sc = rtems_event_send (uti596_softc.txDaemonTid,
    21132148                                    INTERRUPT_EVENT);
     
    21672202   } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */
    21682203   else {
    2169 
    2170      /* Reset the ethernet card, and wake the transmitter (if necessary) */
    2171 
    2172      printk("****INFO: Resetting board ( tx )\n");
    2173      uti596_softc.nic_reset = 1;
    2174      if ( uti596_softc.txDaemonTid){  /* Ensure that a transmitter is waiting */
    2175        /*  printk("*****INFO:Wake Transmitter\n"); */
    2176        sc = rtems_event_send (uti596_softc.txDaemonTid,
    2177                               INTERRUPT_EVENT);
     2204     if ( pIsrCmd != I596_NULL ) { /* The command MAY be NULL from a RESET */
    21782205       
    2179        if ( sc != RTEMS_SUCCESSFUL )
    2180          printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) );
     2206       /* Reset the ethernet card, and wake the transmitter (if necessary) */
     2207       printk_time();
     2208       printk("****INFO: Request board reset ( tx )\n");
     2209       uti596_softc.nic_reset = 1;
     2210       if ( uti596_softc.txDaemonTid){  /* Ensure that a transmitter is present */
     2211         sc = rtems_event_send (uti596_softc.txDaemonTid,
     2212                                INTERRUPT_EVENT);
     2213         
     2214         if ( sc != RTEMS_SUCCESSFUL )
     2215           printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) );
    21812216#ifdef DBG_RAW_ISR
    2182       else
    2183          printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
     2217        else
     2218           printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
    21842219#endif     
     2220       }
    21852221     }
    21862222   }
     
    22152251               printk("***ERROR:UNK: %p not end->next: %p, end: %p\n",
    22162252                      uti596_softc.pLastUnkRFD,uti596_softc.pEndRFA -> next,uti596_softc.pEndRFA);
    2217                dumpQ();
    22182253               printk("***INFO:countRFD now %d\n",       uti596_softc.countRFD);
    22192254               printk("\n\n");
     
    22352270           if ( uti596_softc.countRFD != 0 ) {
    22362271             printk("****INFO:About to set begin to NULL, with count == %d\n", uti596_softc.countRFD );
    2237              dumpQ();
    22382272             printk("\n\n");
    22392273           }
     
    22582292         if(uti596_softc.countRFD != 0) {
    22592293           printk("****ERROR:Begin pointer is NULL, but count == %d\n",uti596_softc.countRFD);
    2260            dumpQ();
    22612294         }
    22622295#endif
     
    22692302         if ( uti596_softc.countRFD <= 0) {
    22702303           printk("****ERROR:Begin pointer is not NULL, but count == %d\n",uti596_softc.countRFD);
    2271            dumpQ();
    22722304         }
    22732305#endif
     
    22952327#endif
    22962328     
    2297      if ( uti596_softc.countRFD > 1 &&                              /* there is at least TWO */
    2298           !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) { /* restart when not in use !! */
    2299        
     2329     if ( uti596_softc.countRFD > 1) {
     2330       /****REMOVED FEB 18.
     2331         &&           
     2332          !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) {
     2333       *****/
     2334       printk_time();
     2335       printk("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat);
     2336       printk("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd);
     2337       uti596_softc.pBeginRFA -> stat = 0;
    23002338       UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n");
    23012339       uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
     
    23052343       outport_word(CHAN_ATTN, 0);
    23062344    }
    2307      else {
     2345     /*****REMOVED FEB 18.
     2346       else {
    23082347       printk("****WARNING: Receiver NOT Started -- countRFD = %d\n", uti596_softc.countRFD);
    23092348       printk("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
     
    23162355             pISR_Rfd != I596_NULL;
    23172356             pISR_Rfd = pISR_Rfd->next)
    2318          printk("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2357         printk("Frame @ %x, status: %x, cmd: %x\n",
    23192358                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
    23202359       
     
    23232362             pISR_Rfd != I596_NULL;
    23242363             pISR_Rfd = pISR_Rfd->next)
    2325          printk("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2364         printk("Frame @ %x, status: %x, cmd: %x\n",
    23262365                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
    23272366       
     
    23312370             pISR_Rfd != I596_NULL;
    23322371             pISR_Rfd = pISR_Rfd->next)
    2333          printk("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2372         printk("Frame @ %x, status: %x, cmd: %x\n",
    23342373                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
    23352374       printk("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);
    23362375     }
     2376     *****/
    23372377   } /* end stat_rnr */ 
    23382378
    23392379 } /* end if receiver started */
    2340  UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n");
     2380 /* UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n"); */
    23412381 
    23422382#ifdef DBG_ISR
     
    27042744 
    27052745}
    2706 void dump_scb(){
     2746void dump_scb(void){
    27072747  printk("status 0x%x\n",uti596_softc.scb.status);
    27082748  printk("command 0x%x\n",uti596_softc.scb.command);
     
    27192759}
    27202760
     2761void printk_time(void){
     2762    rtems_time_of_day tm_struct;
     2763
     2764    rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
     2765    printk("Current time: %d:%d:%d \n", tm_struct.hour, tm_struct.minute, tm_struct.second); 
     2766}
Note: See TracChangeset for help on using the changeset viewer.