Changeset 998e34a in rtems


Ignore:
Timestamp:
Apr 13, 2017, 12:57:01 PM (2 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
master
Children:
430949aa
Parents:
8927c0f
git-author:
Daniel Hellstrom <daniel@…> (04/13/17 12:57:01)
git-committer:
Daniel Hellstrom <daniel@…> (05/02/17 10:34:50)
Message:

leon, greth: SMP support by using spin-lock protection

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/net/greth.c

    r8927c0f r998e34a  
    4141#include <netinet/in.h>
    4242#include <netinet/if_ether.h>
     43
     44/* map via rtems_interrupt_lock_* API: */
     45#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     46#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     47#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     48#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     49#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     50#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     51#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     52#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    4353
    4454#ifdef malloc
     
    199209   unsigned long txUnderrun;
    200210
     211   /* Spin-lock ISR protection */
     212   SPIN_DECLARE(devlock);
    201213};
    202214
     
    220232        rtems_event_set events = 0;
    221233        struct greth_softc *greth = arg;
    222        
     234        SPIN_ISR_IRQFLAGS(flags);
     235
    223236        /* read and clear interrupt cause */
    224237        status = greth->regs->status;
    225238        greth->regs->status = status;
     239
     240        SPIN_LOCK(&greth->devlock, flags);
    226241        ctrl = greth->regs->ctrl;
    227        
     242
    228243        /* Frame received? */
    229244        if ((ctrl & GRETH_CTRL_RXIRQ) && (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ)))
     
    234249                events |= INTERRUPT_EVENT;
    235250        }
    236        
     251
    237252        if ( (ctrl & GRETH_CTRL_TXIRQ) && (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) )
    238253        {
     
    241256                events |= GRETH_TX_WAIT_EVENT;
    242257        }
    243        
     258
    244259        /* Clear interrupt sources */
    245260        greth->regs->ctrl = ctrl;
    246        
     261        SPIN_UNLOCK(&greth->devlock, flags);
     262
    247263        /* Send the event(s) */
    248264        if ( events )
     
    634650    unsigned int len, len_status, bad;
    635651    rtems_event_set events;
    636     rtems_interrupt_level level;
     652    SPIN_IRQFLAGS(flags);
    637653    int first;
    638                 int tmp;
    639                 unsigned int addr;
    640    
     654    int tmp;
     655    unsigned int addr;
     656
    641657    for (;;)
    642658      {
     
    754770                            dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
    755771                    }
    756                     rtems_interrupt_disable(level);
     772                    SPIN_LOCK_IRQ(&dp->devlock, flags);
    757773                    dp->regs->ctrl |= GRETH_CTRL_RXEN;
    758                     rtems_interrupt_enable(level);
     774                    SPIN_UNLOCK_IRQ(&dp->devlock, flags);
    759775                    dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
    760776            }
    761        
     777
    762778        /* Always scan twice to avoid deadlock */
    763779        if ( first ){
    764780            first=0;
    765             rtems_interrupt_disable(level);
     781            SPIN_LOCK_IRQ(&dp->devlock, flags);
    766782            dp->regs->ctrl |= GRETH_CTRL_RXIRQ;
    767             rtems_interrupt_enable(level);
     783            SPIN_UNLOCK_IRQ(&dp->devlock, flags);
    768784            goto again;
    769785        }
    770786
    771787      }
    772    
    773 }
    774 
    775 static int inside = 0;
     788}
     789
    776790static int
    777791sendpacket (struct ifnet *ifp, struct mbuf *m)
     
    781795    struct mbuf *n;
    782796    unsigned int len;
    783     rtems_interrupt_level level;
    784        
    785     /*printf("Send packet entered\n");*/
    786     if (inside) printf ("error: sendpacket re-entered!!\n");
    787     inside = 1;
    788    
     797    SPIN_IRQFLAGS(flags);
     798
    789799    /*
    790800     * Is there a free descriptor available?
     
    792802    if (GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].ctrl) & GRETH_TXD_ENABLE){
    793803            /* No. */
    794             inside = 0;
    795804            return 1;
    796805    }
     
    834843            }
    835844            dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
    836             rtems_interrupt_disable(level);
     845            SPIN_LOCK_IRQ(&dp->devlock, flags);
    837846            dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
    838             rtems_interrupt_enable(level);
     847            SPIN_UNLOCK_IRQ(&dp->devlock, flags);
    839848           
    840849    }
    841     inside = 0;
    842    
     850
    843851    return 0;
    844852}
     
    855863        struct mbuf *mtmp;
    856864        int int_en;
    857         rtems_interrupt_level level;
    858 
    859         if (inside) printf ("error: sendpacket re-entered!!\n");
    860         inside = 1;
    861        
     865        SPIN_IRQFLAGS(flags);
     866
    862867        len = 0;
    863868#ifdef GRETH_DEBUG
     
    878883       
    879884        if ( frags > dp->txbufs ){
    880             inside = 0;
    881885            printf("GRETH: MBUF-chain cannot be sent. Increase descriptor count.\n");
    882886            return -1;
     
    884888       
    885889        if ( frags > (dp->txbufs-dp->tx_cnt) ){
    886             inside = 0;
    887890            /* Return number of fragments */
    888891            return frags;
     
    948951     
    949952        /* Tell Hardware about newly enabled descriptor */
    950         rtems_interrupt_disable(level);
     953        SPIN_LOCK_IRQ(&dp->devlock, flags);
    951954        dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
    952         rtems_interrupt_enable(level);
    953 
    954         inside = 0;
    955                
     955        SPIN_UNLOCK_IRQ(&dp->devlock, flags);
     956
    956957        return 0;
    957958}
     
    961962    struct ifnet *ifp = &sc->arpcom.ac_if;
    962963    struct mbuf *m;
    963     rtems_interrupt_level level;
     964    SPIN_IRQFLAGS(flags);
    964965    int first=1;
    965    
     966
    966967    /*
    967968     * Send packets till queue is empty
     
    10111012            if ( first ){
    10121013                first = 0;
    1013                 rtems_interrupt_disable(level);
     1014                SPIN_LOCK_IRQ(&sc->devlock, flags);
    10141015                ifp->if_flags |= IFF_OACTIVE;
    10151016                sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
    1016                 rtems_interrupt_enable(level);
     1017                SPIN_UNLOCK_IRQ(&sc->devlock, flags);
    10171018               
    10181019                /* We must check again to be sure that we didn't
     
    10221023                continue;
    10231024            }
    1024            
     1025
    10251026            return -1;
    10261027        }else{
     
    10351036    struct ifnet *ifp = &sc->arpcom.ac_if;
    10361037    struct mbuf *m;
    1037     rtems_interrupt_level level;
     1038    SPIN_IRQFLAGS(flags);
    10381039    int first=1;
    1039    
     1040
    10401041    /*
    10411042     * Send packets till queue is empty
     
    10771078            if ( first ){
    10781079                first = 0;
    1079                 rtems_interrupt_disable(level);
     1080                SPIN_LOCK_IRQ(&sc->devlock, flags);
    10801081                ifp->if_flags |= IFF_OACTIVE;
    10811082                sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
    1082                 rtems_interrupt_enable(level);
    1083                
     1083                SPIN_UNLOCK_IRQ(&sc->devlock, flags);
     1084
    10841085                /* We must check again to be sure that we didn't
    10851086                 * miss an interrupt (if a packet was sent just before
     
    10881089                continue;
    10891090            }
    1090            
     1091
    10911092            return -1;
    10921093        }else{
     
    11291130    if (sc->daemonTid == 0)
    11301131      {
    1131 
    1132           /*
    1133            * Start driver tasks
    1134            */
    1135           name[3] += sc->minor;
    1136           sc->daemonTid = rtems_bsdnet_newproc (name, 4096,
    1137                                                   greth_Daemon, sc);
    1138 
    1139           /*
    1140            * Set up GRETH hardware
    1141            */
    1142       greth_initialize_hardware (sc);
    1143          
     1132          /*
     1133           * Start driver tasks
     1134           */
     1135          name[3] += sc->minor;
     1136          sc->daemonTid = rtems_bsdnet_newproc (name, 4096,
     1137                                                greth_Daemon, sc);
     1138
     1139          /*
     1140           * Set up GRETH hardware
     1141           */
     1142          greth_initialize_hardware (sc);
    11441143      }
    11451144
     
    11481147     */
    11491148    ifp->if_flags |= IFF_RUNNING;
    1150 
    11511149}
    11521150
     
    11581156{
    11591157    struct ifnet *ifp = &sc->arpcom.ac_if;
    1160 
     1158    SPIN_IRQFLAGS(flags);
     1159
     1160    SPIN_LOCK_IRQ(&sc->devlock, flags);
    11611161    ifp->if_flags &= ~IFF_RUNNING;
    11621162
     
    11641164    sc->regs->ctrl = GRETH_CTRL_RST;    /* Reset ON */
    11651165    sc->regs->ctrl = 0;                 /* Reset OFF */
    1166    
     1166    SPIN_UNLOCK_IRQ(&sc->devlock, flags);
     1167
    11671168    sc->next_tx_mbuf = NULL;
    11681169}
     
    13981399    }
    13991400
     1401    /* Initialize Spin-lock for GRSPW Device. This is to protect
     1402     * CTRL and DMACTRL registers from ISR.
     1403     */
     1404    SPIN_INIT(&sc->devlock, sc->devName);
     1405
    14001406    /* Register GRETH device as an Network interface */
    14011407    ifp = malloc(sizeof(struct rtems_bsdnet_ifconfig));
Note: See TracChangeset for help on using the changeset viewer.