Changeset 0a8f902e in rtems


Ignore:
Timestamp:
Oct 17, 2009, 10:24:55 PM (10 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, master
Children:
887e1cb
Parents:
7545240
Message:

2009-10-17 Till Straumann <strauman@…>

*network/if_tsec_pub.h, network/tsec.c: Enhanced low-level
API allowing the user to selectively enable/disable/acknowledge
interrupts and to install their own ISR (rather than having
the driver posting an event to a single task).

Location:
c/src/lib/libbsp/powerpc/mvme3100
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/mvme3100/ChangeLog

    r7545240 r0a8f902e  
     12009-10-17      Till Straumann <strauman@slac.stanford.edu>
     2
     3        *network/if_tsec_pub.h, network/tsec.c: Enhanced low-level
     4        API allowing the user to selectively enable/disable/acknowledge
     5        interrupts and to install their own ISR (rather than having
     6        the driver posting an event to a single task).
     7
    182009-10-15      Ralf Corsépius <ralf.corsepius@rtems.org>
    29
  • c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h

    r7545240 r0a8f902e  
    5050#include <rtems.h>
    5151#include <stdio.h>
     52#include <stdint.h>
    5253
    5354#ifdef __cplusplus
     
    6768 */
    6869
     70#define TSEC_TXIRQ ( (1<<(31-9)) | (1<<(31-11))                )
     71#define TSEC_RXIRQ ( (1<<(31-0)) | (1<<(31- 3)) | (1<<(31-24)) )
     72#define TSEC_LKIRQ (  1<<(31- 4)                               )
    6973/*
    7074 * Setup an interface.
     
    138142        int              unit,
    139143        rtems_id driver_tid,
    140         void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
    141         void *cleanup_txbuf_arg,
    142         void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
    143         void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
    144         void *consume_rxbuf_arg,
    145         int             rx_ring_size,
    146         int             tx_ring_size,
    147         int             irq_mask
     144        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
     145        void *   cleanup_txbuf_arg,
     146        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
     147        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
     148        void *   consume_rxbuf_arg,
     149        int              rx_ring_size,
     150        int              tx_ring_size,
     151        int              irq_mask
    148152);
     153
     154/*
     155 * Alternate 'setup' routine allowing the user to install an ISR rather
     156 * than a task ID.
     157 * All parameters (other than 'isr' / 'isr_arg') and the return value
     158 * are identical to the BSP_tsec_setup() entry point.
     159 */
     160struct tsec_private *
     161BSP_tsec_setup_1(
     162        int              unit,
     163        void     (*isr)(void *isr_arg),
     164        void *   isr_arg,
     165        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
     166        void *   cleanup_txbuf_arg,
     167        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
     168        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
     169        void *   consume_rxbuf_arg,
     170        int              rx_ring_size,
     171        int              tx_ring_size,
     172        int              irq_mask
     173);
     174
    149175
    150176/*
     
    336362 */
    337363
     364/* Note: the BSP_tsec_enable/disable/ack_irqs() entry points
     365 *       are deprecated.
     366 *       The newer API where the user passes a mask allows
     367 *       for more selective control.
     368 */
     369
    338370/* Enable interrupts at device */
    339371void
     
    350382uint32_t
    351383BSP_tsec_ack_irqs(struct tsec_private *mp);
     384
     385/* Enable interrupts included in 'mask' (leaving
     386 * already enabled interrupts on). If the mask includes
     387 * bits that were not passed to the 'setup' routine then
     388 * the behavior is undefined.
     389 */
     390void
     391BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
     392
     393/* Disable interrupts included in 'mask' (leaving
     394 * other ones that are currently enabled on). If the mask
     395 * includes bits that were not passed to the 'setup' routine
     396 * then the behavior is undefined.
     397
     398 * RETURNS: Bitmask of interrupts that were enabled upon entry
     399 *          into this routine. This can be used to restore the previous
     400 *          state.
     401 */
     402uint32_t
     403BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
     404
     405/* Acknowledge and clear selected interrupts.
     406 *
     407 * RETURNS: All pending interrupts.
     408 *
     409 * NOTE:    Only pending interrupts contained in 'mask'
     410 *          are cleared. Others are left pending.
     411 *
     412 *          This routine can be used to check for pending
     413 *          interrupts (pass mask ==  0) or to clear all
     414 *          interrupts (pass mask == -1).
     415 */
     416uint32_t
     417BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask);
     418
    352419
    353420/* Retrieve the driver daemon TID that was passed to
  • c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c

    r7545240 r0a8f902e  
    239239#define TSEC_IEVENT_ALL                                                 (-1)
    240240
    241 #define TSEC_TXIRQ      ( TSEC_IEVENT_TXE | TSEC_IEVENT_TXF )
    242 #define TSEC_RXIRQ      ( TSEC_IEVENT_RXF | TSEC_IEVENT_BABR | TSEC_IEVENT_EBERR )
     241#if TSEC_TXIRQ != ( TSEC_IEVENT_TXE | TSEC_IEVENT_TXF )
     242#error "mismatch in definition: TSEC_TXIRQ"
     243#endif
     244
     245#if TSEC_RXIRQ != ( TSEC_IEVENT_RXF | TSEC_IEVENT_BABR | TSEC_IEVENT_EBERR )
     246#error "mismatch in definition: TSEC_RXIRQ"
     247#endif
     248
     249#if TSEC_LKIRQ != TSEC_LINK_INTR
     250#error "mismatch in definition: TSEC_LKIRQ"
     251#endif
    243252
    244253#define TSEC_IMASK                                                      0x014
     
    665674        unsigned                rx_tail;         /* Where we left off scanning for full bufs */
    666675        unsigned                rx_ring_size;
     676        void            (*isr)(void*);
     677        void            *isr_arg;
    667678        void                    (*cleanup_txbuf) /* Callback to cleanup TX ring              */
    668679                          (void*, void*, int);
     
    675686        rtems_id                tid;             /* driver task ID                           */
    676687        uint32_t                irq_mask;
     688        uint32_t                irq_mask_cache;
    677689        uint32_t                irq_pending;
    678690        rtems_event_set event;           /* Task synchronization events              */
     
    888900#endif
    889901        phy_dis_irq_at_phy( mp );
     902
     903        mp->irq_mask_cache = 0;
    890904
    891905        /* Follow the manual resetting the chip */
     
    10471061 *
    10481062 */
    1049 struct tsec_private *
    1050 BSP_tsec_setup(
     1063
     1064static struct tsec_private *
     1065tsec_setup_internal(
    10511066        int              unit,
    10521067        rtems_id driver_tid,
    1053         void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
    1054         void *cleanup_txbuf_arg,
    1055         void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
    1056         void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
    1057         void *consume_rxbuf_arg,
    1058         int             rx_ring_size,
    1059         int             tx_ring_size,
    1060         int             irq_mask
     1068        void     (*isr)(void *, uint32_t),
     1069        void *   isr_arg,
     1070        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
     1071        void *   cleanup_txbuf_arg,
     1072        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
     1073        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
     1074        void *   consume_rxbuf_arg,
     1075        int              rx_ring_size,
     1076        int              tx_ring_size,
     1077        int              irq_mask
    10611078)
    10621079{
     
    11671184
    11681185#ifndef TSEC_CONFIG_NO_PHY_REGLOCK
    1169         /* lazy init of mutex (non thread-safe! - we assume initialization
    1170          * of 1st IF is single-threaded)
    1171          */
    11721186        if ( ! tsec_mtx ) {
    1173                 rtems_status_code sc;
     1187                rtems_status_code     sc;
     1188                rtems_id              new_mtx;
     1189                rtems_interrupt_level l;
    11741190                sc = rtems_semaphore_create(
    11751191                                rtems_build_name('t','s','e','X'),
     
    11771193                                RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_DEFAULT_ATTRIBUTES,
    11781194                                0,
    1179                                 &tsec_mtx);
     1195                                &new_mtx);
    11801196                if ( RTEMS_SUCCESSFUL != sc ) {
    11811197                        rtems_error(sc,DRVNAME": creating mutex\n");
    11821198                        rtems_panic("unable to proceed\n");
    11831199                }
     1200                rtems_interrupt_disable( l );
     1201                        if ( ! tsec_mtx ) {
     1202                                tsec_mtx = new_mtx;
     1203                                new_mtx  = 0;
     1204                        }
     1205                rtems_interrupt_enable( l );
     1206
     1207                if ( new_mtx ) {
     1208                        /* another task was faster installing the mutex */
     1209                        rtems_semaphore_delete( new_mtx );
     1210                }
     1211               
    11841212        }
    11851213#endif
     
    11951223
    11961224        return mp;
     1225}
     1226
     1227struct tsec_private *
     1228BSP_tsec_setup(
     1229        int              unit,
     1230        rtems_id driver_tid,
     1231        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
     1232        void *   cleanup_txbuf_arg,
     1233        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
     1234        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
     1235        void *   consume_rxbuf_arg,
     1236        int              rx_ring_size,
     1237        int              tx_ring_size,
     1238        int              irq_mask
     1239)
     1240{
     1241        if ( irq_mask && ! driver_tid ) {
     1242                printk(DRVNAME": must supply a TID if irq_mask not zero\n");
     1243                return 0;
     1244        }
     1245        return tsec_setup_internal(
     1246                                                                unit,
     1247                                                                driver_tid,
     1248                                                                0, 0,
     1249                                                                cleanup_txbuf, cleanup_txbuf_arg,
     1250                                                                alloc_rxbuf,
     1251                                                                consume_rxbuf, consume_rxbuf_arg,
     1252                                                                rx_ring_size,
     1253                                                                tx_ring_size,
     1254                                                                irq_mask
     1255                                                           );
     1256}
     1257
     1258struct tsec_private *
     1259BSP_tsec_setup_1(
     1260        int              unit,
     1261        void     (*isr)(void*),
     1262        void *   isr_arg,
     1263        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
     1264        void *   cleanup_txbuf_arg,
     1265        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
     1266        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
     1267        void *   consume_rxbuf_arg,
     1268        int              rx_ring_size,
     1269        int              tx_ring_size,
     1270        int              irq_mask
     1271)
     1272{
     1273        if ( irq_mask && ! isr ) {
     1274                printk(DRVNAME": must supply a ISR if irq_mask not zero\n");
     1275                return 0;
     1276        }
     1277        return tsec_setup_internal(
     1278                                                                unit,
     1279                                                                0,
     1280                                                                isr, isr_arg,
     1281                                                                cleanup_txbuf, cleanup_txbuf_arg,
     1282                                                                alloc_rxbuf,
     1283                                                                consume_rxbuf, consume_rxbuf_arg,
     1284                                                                rx_ring_size,
     1285                                                                tx_ring_size,
     1286                                                                irq_mask
     1287                                                           );
    11971288}
    11981289
     
    12881379        fec_wr( b, TSEC_IEVENT, TSEC_IEVENT_ALL );
    12891380        fec_wr( b, TSEC_IMASK,  TSEC_IMASK_NONE );
     1381        mp->irq_mask_cache = 0;
    12901382
    12911383        /* bring other regs. into a known state */
     
    13881480         */
    13891481
    1390         /* disable PHY irq at PIC (fast) */
    1391         phy_dis_irq( mp );
    1392         /* enable PHY irq (MII operation, slow) */
    1393         phy_en_irq_at_phy (mp );
     1482        if ( (TSEC_LINK_INTR & mp->irq_mask) ) {
     1483                /* disable PHY irq at PIC (fast) */
     1484                phy_dis_irq( mp );
     1485                /* enable PHY irq (MII operation, slow) */
     1486                phy_en_irq_at_phy (mp );
     1487        }
    13941488       
    1395         /* globally disable */
    1396         rtems_interrupt_disable( l );
    1397        
    1398         /* enable TSEC IRQs */
    1399         fec_wr( mp->base, TSEC_IMASK, mp->irq_mask );
    1400         /* enable PHY irq at PIC */
    1401         phy_en_irq( mp );
    1402 
    1403         /* globally reenable */
    1404         rtems_interrupt_enable( l );
     1489        BSP_tsec_enable_irq_mask( mp, mp->irq_mask );
    14051490}
    14061491
     
    21092194 * Therefore, we take the following approach:
    21102195 *
    2111  *   ISR masks all interrupts on the TSEC, acks/clears them
     2196 *   ISR masks interrupts on the TSEC, acks/clears them
    21122197 *   and stores the acked irqs in the device struct where
    2113  *   it is picked up by BSP_tsec_ack_irqs().
    2114  *   Since all interrupts are disabled until the daemon
    2115  *   re-enables them after calling BSP_tsec_ack_irqs()
    2116  *   no interrupts are lost.
     2198 *   it is picked up by BSP_tsec_ack_irq_mask().
    21172199 *
    2118  * BUT:  NO isr (including PHY isrs) MUST INTERRUPT ANY
    2119  *       OTHER ONE, i.e., they all must have the same
    2120  *       priority. Otherwise, integrity of the cached
    2121  *       irq_pending variable may be compromised.
    2122  */
    2123 
    2124 static inline void
    2125 tsec_dis_irqs( struct tsec_private *mp)
    2126 {
    2127         phy_dis_irq( mp );
    2128         fec_wr( mp->base, TSEC_IMASK, TSEC_IMASK_NONE );
     2200 */
     2201
     2202static inline uint32_t
     2203tsec_dis_irqs(struct tsec_private *mp, uint32_t mask)
     2204{
     2205uint32_t rval;
     2206
     2207        rval = mp->irq_mask_cache;
     2208        if ( (TSEC_LINK_INTR & mask & mp->irq_mask_cache) )
     2209                phy_dis_irq( mp );
     2210        mp->irq_mask_cache = rval & ~mask;
     2211        fec_wr( mp->base, TSEC_IMASK, (mp->irq_mask_cache & ~TSEC_LINK_INTR) );
     2212
     2213        return rval;
    21292214}
    21302215
     
    21342219uint32_t      rval;
    21352220FEC_Enet_Base b = mp->base;
    2136         tsec_dis_irqs( mp );
    2137         rval = fec_rd( b, TSEC_IEVENT);
     2221
     2222        rval  = fec_rd( b, TSEC_IEVENT);
     2223
     2224        /* Make sure we mask out the link intr */
     2225        rval &= ~TSEC_LINK_INTR;
     2226
     2227        tsec_dis_irqs( mp, rval );
    21382228        fec_wr( b, TSEC_IEVENT, rval );
    2139         /* Make sure we mask out the link intr */
    2140         return rval & ~TSEC_LINK_INTR;
     2229
     2230        return rval;
    21412231}
    21422232
     
    21482238static void tsec_xisr(rtems_irq_hdl_param arg)
    21492239{
    2150 struct tsec_private *mp = (struct tsec_private *)arg;
    2151 
    2152         mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2240struct tsec_private   *mp = (struct tsec_private *)arg;
     2241rtems_interrupt_level l;
     2242
     2243        rtems_interrupt_disable( l );
     2244                mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2245        rtems_interrupt_enable( l );
    21532246
    21542247        mp->stats.xirqs++;
    21552248
    2156         rtems_event_send( mp->tid, mp->event );
     2249        if ( mp->isr )
     2250                mp->isr( mp->isr_arg );
     2251        else
     2252                rtems_event_send( mp->tid, mp->event );
    21572253}
    21582254
    21592255static void tsec_risr(rtems_irq_hdl_param arg)
    21602256{
    2161 struct tsec_private *mp = (struct tsec_private *)arg;
    2162 
    2163         mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2257struct tsec_private   *mp = (struct tsec_private *)arg;
     2258rtems_interrupt_level l;
     2259
     2260        rtems_interrupt_disable( l );
     2261                mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2262        rtems_interrupt_enable( l );
    21642263
    21652264        mp->stats.rirqs++;
    21662265
    2167         rtems_event_send( mp->tid, mp->event );
     2266        if ( mp->isr )
     2267                mp->isr( mp->isr_arg );
     2268        else
     2269                rtems_event_send( mp->tid, mp->event );
    21682270}
    21692271
    21702272static void tsec_eisr(rtems_irq_hdl_param arg)
    21712273{
    2172 struct tsec_private *mp = (struct tsec_private *)arg;
    2173 
    2174         mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2274struct tsec_private   *mp = (struct tsec_private *)arg;
     2275rtems_interrupt_level l;
     2276
     2277        rtems_interrupt_disable( l );
     2278                mp->irq_pending |= tsec_dis_clr_irqs( mp );
     2279        rtems_interrupt_enable( l );
    21752280
    21762281        mp->stats.eirqs++;
    21772282
    2178         rtems_event_send( mp->tid, mp->event );
     2283        if ( mp->isr )
     2284                mp->isr( mp->isr_arg );
     2285        else
     2286                rtems_event_send( mp->tid, mp->event );
    21792287}
    21802288
    21812289static void tsec_lisr(rtems_irq_hdl_param arg)
    21822290{
    2183 struct tsec_private *mp = (struct tsec_private *)arg;
     2291struct tsec_private   *mp = (struct tsec_private *)arg;
     2292rtems_interrupt_level l;
    21842293
    21852294        if ( phy_irq_pending( mp ) ) {
    21862295
    2187                 tsec_dis_irqs( mp );
    2188 
    2189                 mp->irq_pending |= TSEC_LINK_INTR;
     2296                rtems_interrupt_disable( l );
     2297                        tsec_dis_irqs( mp, TSEC_LINK_INTR );
     2298                        mp->irq_pending |= TSEC_LINK_INTR;
     2299                rtems_interrupt_enable( l );
    21902300
    21912301                mp->stats.lirqs++;
    21922302
    2193                 rtems_event_send( mp->tid, mp->event );
     2303                if ( mp->isr )
     2304                        mp->isr( mp->isr_arg );
     2305                else
     2306                        rtems_event_send( mp->tid, mp->event );
    21942307        }
    21952308}
     
    21972310/* Enable interrupts at device */
    21982311void
     2312BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t mask)
     2313{
     2314rtems_interrupt_level l;
     2315
     2316        mask &= mp->irq_mask;
     2317
     2318        rtems_interrupt_disable( l );
     2319        if ( (TSEC_LINK_INTR & mask) && ! (TSEC_LINK_INTR & mp->irq_mask_cache) )
     2320                phy_en_irq( mp );
     2321        mp->irq_mask_cache |= mask;
     2322        fec_wr( mp->base, TSEC_IMASK, (mp->irq_mask_cache & ~TSEC_LINK_INTR) );
     2323        rtems_interrupt_enable( l );
     2324}
     2325
     2326void
    21992327BSP_tsec_enable_irqs(struct tsec_private *mp)
    22002328{
     2329        BSP_tsec_enable_irq_mask(mp, -1);
     2330}
     2331
     2332/* Disable interrupts at device */
     2333uint32_t
     2334BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t mask)
     2335{
     2336uint32_t              rval;
    22012337rtems_interrupt_level l;
     2338
    22022339        rtems_interrupt_disable( l );
    2203         fec_wr( mp->base, TSEC_IMASK, mp->irq_mask );
    2204         phy_en_irq( mp );
     2340                rval = tsec_dis_irqs(mp, mask);
    22052341        rtems_interrupt_enable( l );
    2206 }
    2207 
    2208 /* Disable interrupts at device */
     2342
     2343        return rval;
     2344}
     2345
    22092346void
    22102347BSP_tsec_disable_irqs(struct tsec_private *mp)
    22112348{
    22122349rtems_interrupt_level l;
     2350
    22132351        rtems_interrupt_disable( l );
    2214         tsec_dis_irqs( mp );
     2352                tsec_dis_irqs(mp, -1);
    22152353        rtems_interrupt_enable( l );
    22162354}
     
    22212359 */
    22222360uint32_t
    2223 BSP_tsec_ack_irqs(struct tsec_private *mp)
     2361BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask)
    22242362{
    22252363uint32_t              rval;
    2226 
    2227         /* no need to disable interrupts because
    2228          * this should only be called after receiving
    2229          * a RTEMS event posted by the ISR which
    2230          * already shut off interrupts.
    2231          */
    2232         rval = mp->irq_pending;
    2233         mp->irq_pending = 0;
    2234 
    2235         if ( (rval & TSEC_LINK_INTR) ) {
     2364rtems_interrupt_level l;
     2365
     2366        rtems_interrupt_disable( l );
     2367                rval = mp->irq_pending;
     2368                mp->irq_pending &= ~ mask;
     2369        rtems_interrupt_enable( l );
     2370
     2371        if ( (rval & TSEC_LINK_INTR & mask) ) {
    22362372                /* interacting with the PHY is slow so
    22372373                 * we do it only if we have to...
     
    22412377
    22422378        return rval & mp->irq_mask;
     2379}
     2380
     2381uint32_t
     2382BSP_tsec_ack_irqs(struct tsec_private *mp)
     2383{
     2384        return BSP_tsec_ack_irq_mask(mp, -1);
    22432385}
    22442386
     
    22792421 *                      BSP_tsec_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * /
    22802422 *              }
    2281  *              BSP_tsec_enable_irqs(handle);
     2423 *              BSP_tsec_enable_irq_mask(handle, -1);
    22822424 *    } while (1);
    22832425 *
     
    26102752                                        BSP_tsec_swipe_rx(&sc->pvt);
    26112753
    2612                                 BSP_tsec_enable_irqs(&sc->pvt);
     2754                                BSP_tsec_enable_irq_mask(&sc->pvt, -1);
    26132755                        }
    26142756                }
     
    28743016 * from a IRQ-protected section of code
    28753017 */
     3018
    28763019static void
    28773020phy_en_irq(struct tsec_private *mp)
    28783021{
    2879         if ( ! ( --phy_irq_dis_level ) ) {
     3022        phy_irq_dis_level &= ~(1<<mp->unit);
     3023        if ( 0 == phy_irq_dis_level ) {
    28803024                BSP_enable_irq_at_pic( BSP_PHY_IRQ );
    28813025        }
     
    28863030phy_dis_irq(struct tsec_private *mp)
    28873031{
    2888         if ( !(phy_irq_dis_level++) ) {
    2889                 BSP_disable_irq_at_pic( BSP_PHY_IRQ );
    2890         }
     3032        phy_irq_dis_level |= (1<<mp->unit);
     3033        BSP_disable_irq_at_pic( BSP_PHY_IRQ );
    28913034}
    28923035
Note: See TracChangeset for help on using the changeset viewer.