summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2009-10-17 22:24:55 +0000
committerTill Straumann <strauman@slac.stanford.edu>2009-10-17 22:24:55 +0000
commit0a8f902e76f5bcea7175415efbaa1fbb12764472 (patch)
treee447b7ae80e498da2e566248f6f89a2638fd88ed /c
parent2009-10-17 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-0a8f902e76f5bcea7175415efbaa1fbb12764472.tar.bz2
2009-10-17 Till Straumann <strauman@slac.stanford.edu>
*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).
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/mvme3100/ChangeLog7
-rw-r--r--c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h83
-rw-r--r--c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c305
3 files changed, 306 insertions, 89 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog b/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog
index a5a0a29fd2..5596e9e148 100644
--- a/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-17 Till Straumann <strauman@slac.stanford.edu>
+
+ *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).
+
2009-10-15 Ralf Corsépius <ralf.corsepius@rtems.org>
* make/custom/mvme3100.cfg: New (relocated from /make/custom).
diff --git a/c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h b/c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h
index 79846b0093..f0a6f586e3 100644
--- a/c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h
+++ b/c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h
@@ -49,6 +49,7 @@
#include <rtems.h>
#include <stdio.h>
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@@ -66,6 +67,9 @@ struct tsec_private;
* raw ethernet packet communication...
*/
+#define TSEC_TXIRQ ( (1<<(31-9)) | (1<<(31-11)) )
+#define TSEC_RXIRQ ( (1<<(31-0)) | (1<<(31- 3)) | (1<<(31-24)) )
+#define TSEC_LKIRQ ( 1<<(31- 4) )
/*
* Setup an interface.
* Allocates resources for descriptor rings and sets up the driver software structure.
@@ -137,17 +141,39 @@ struct tsec_private *
BSP_tsec_setup(
int unit,
rtems_id driver_tid,
- void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
- void *cleanup_txbuf_arg,
- void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
- void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
- void *consume_rxbuf_arg,
- int rx_ring_size,
- int tx_ring_size,
- int irq_mask
+ void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
+ void * cleanup_txbuf_arg,
+ void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
+ void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
+ void * consume_rxbuf_arg,
+ int rx_ring_size,
+ int tx_ring_size,
+ int irq_mask
);
/*
+ * Alternate 'setup' routine allowing the user to install an ISR rather
+ * than a task ID.
+ * All parameters (other than 'isr' / 'isr_arg') and the return value
+ * are identical to the BSP_tsec_setup() entry point.
+ */
+struct tsec_private *
+BSP_tsec_setup_1(
+ int unit,
+ void (*isr)(void *isr_arg),
+ void * isr_arg,
+ void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
+ void * cleanup_txbuf_arg,
+ void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
+ void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
+ void * consume_rxbuf_arg,
+ int rx_ring_size,
+ int tx_ring_size,
+ int irq_mask
+);
+
+
+/*
* Descriptor scavenger; cleanup the TX ring, passing all buffers
* that have been sent to the cleanup_tx() callback.
* This routine is called from BSP_tsec_send_buf(), BSP_tsec_init_hw(),
@@ -335,6 +361,12 @@ BSP_tsec_media_ioctl(struct tsec_private *mp, int cmd, int *parg);
* irq_pending variable may be compromised.
*/
+/* Note: the BSP_tsec_enable/disable/ack_irqs() entry points
+ * are deprecated.
+ * The newer API where the user passes a mask allows
+ * for more selective control.
+ */
+
/* Enable interrupts at device */
void
BSP_tsec_enable_irqs(struct tsec_private *mp);
@@ -350,6 +382,41 @@ BSP_tsec_disable_irqs(struct tsec_private *mp);
uint32_t
BSP_tsec_ack_irqs(struct tsec_private *mp);
+/* Enable interrupts included in 'mask' (leaving
+ * already enabled interrupts on). If the mask includes
+ * bits that were not passed to the 'setup' routine then
+ * the behavior is undefined.
+ */
+void
+BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
+
+/* Disable interrupts included in 'mask' (leaving
+ * other ones that are currently enabled on). If the mask
+ * includes bits that were not passed to the 'setup' routine
+ * then the behavior is undefined.
+
+ * RETURNS: Bitmask of interrupts that were enabled upon entry
+ * into this routine. This can be used to restore the previous
+ * state.
+ */
+uint32_t
+BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
+
+/* Acknowledge and clear selected interrupts.
+ *
+ * RETURNS: All pending interrupts.
+ *
+ * NOTE: Only pending interrupts contained in 'mask'
+ * are cleared. Others are left pending.
+ *
+ * This routine can be used to check for pending
+ * interrupts (pass mask == 0) or to clear all
+ * interrupts (pass mask == -1).
+ */
+uint32_t
+BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask);
+
+
/* Retrieve the driver daemon TID that was passed to
* BSP_tsec_setup().
*/
diff --git a/c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c b/c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c
index 48b45c1550..b62143cdc2 100644
--- a/c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c
+++ b/c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c
@@ -238,8 +238,17 @@ void tsec_dump_rring(struct tsec_private *mp);
#define TSEC_IEVENT_RXF (1<<(31-24))
#define TSEC_IEVENT_ALL (-1)
-#define TSEC_TXIRQ ( TSEC_IEVENT_TXE | TSEC_IEVENT_TXF )
-#define TSEC_RXIRQ ( TSEC_IEVENT_RXF | TSEC_IEVENT_BABR | TSEC_IEVENT_EBERR )
+#if TSEC_TXIRQ != ( TSEC_IEVENT_TXE | TSEC_IEVENT_TXF )
+#error "mismatch in definition: TSEC_TXIRQ"
+#endif
+
+#if TSEC_RXIRQ != ( TSEC_IEVENT_RXF | TSEC_IEVENT_BABR | TSEC_IEVENT_EBERR )
+#error "mismatch in definition: TSEC_RXIRQ"
+#endif
+
+#if TSEC_LKIRQ != TSEC_LINK_INTR
+#error "mismatch in definition: TSEC_LKIRQ"
+#endif
#define TSEC_IMASK 0x014
#define TSEC_IMASK_BABREN (1<<(31- 0))
@@ -664,6 +673,8 @@ struct tsec_private {
void **rx_ring_user; /* Array of user pointers (1 per BD) */
unsigned rx_tail; /* Where we left off scanning for full bufs */
unsigned rx_ring_size;
+ void (*isr)(void*);
+ void *isr_arg;
void (*cleanup_txbuf) /* Callback to cleanup TX ring */
(void*, void*, int);
void *cleanup_txbuf_arg;
@@ -674,6 +685,7 @@ struct tsec_private {
void *consume_rxbuf_arg;
rtems_id tid; /* driver task ID */
uint32_t irq_mask;
+ uint32_t irq_mask_cache;
uint32_t irq_pending;
rtems_event_set event; /* Task synchronization events */
struct { /* Statistics */
@@ -888,6 +900,8 @@ FEC_Enet_Base b = mp->base;
#endif
phy_dis_irq_at_phy( mp );
+ mp->irq_mask_cache = 0;
+
/* Follow the manual resetting the chip */
/* Do graceful stop (if not in stop condition already) */
@@ -1046,18 +1060,21 @@ install_remove_isrs(int install, struct tsec_private *mp, uint32_t irq_mask)
* Interrupts to enable. OR of flags from above.
*
*/
-struct tsec_private *
-BSP_tsec_setup(
+
+static struct tsec_private *
+tsec_setup_internal(
int unit,
rtems_id driver_tid,
- void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
- void *cleanup_txbuf_arg,
- void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
- void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
- void *consume_rxbuf_arg,
- int rx_ring_size,
- int tx_ring_size,
- int irq_mask
+ void (*isr)(void *, uint32_t),
+ void * isr_arg,
+ void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
+ void * cleanup_txbuf_arg,
+ void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
+ void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
+ void * consume_rxbuf_arg,
+ int rx_ring_size,
+ int tx_ring_size,
+ int irq_mask
)
{
struct tsec_private *mp;
@@ -1166,21 +1183,32 @@ struct ifnet *ifp;
}
#ifndef TSEC_CONFIG_NO_PHY_REGLOCK
- /* lazy init of mutex (non thread-safe! - we assume initialization
- * of 1st IF is single-threaded)
- */
if ( ! tsec_mtx ) {
- rtems_status_code sc;
+ rtems_status_code sc;
+ rtems_id new_mtx;
+ rtems_interrupt_level l;
sc = rtems_semaphore_create(
rtems_build_name('t','s','e','X'),
1,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_DEFAULT_ATTRIBUTES,
0,
- &tsec_mtx);
+ &new_mtx);
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc,DRVNAME": creating mutex\n");
rtems_panic("unable to proceed\n");
}
+ rtems_interrupt_disable( l );
+ if ( ! tsec_mtx ) {
+ tsec_mtx = new_mtx;
+ new_mtx = 0;
+ }
+ rtems_interrupt_enable( l );
+
+ if ( new_mtx ) {
+ /* another task was faster installing the mutex */
+ rtems_semaphore_delete( new_mtx );
+ }
+
}
#endif
@@ -1196,6 +1224,69 @@ struct ifnet *ifp;
return mp;
}
+struct tsec_private *
+BSP_tsec_setup(
+ int unit,
+ rtems_id driver_tid,
+ void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
+ void * cleanup_txbuf_arg,
+ void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
+ void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
+ void * consume_rxbuf_arg,
+ int rx_ring_size,
+ int tx_ring_size,
+ int irq_mask
+)
+{
+ if ( irq_mask && ! driver_tid ) {
+ printk(DRVNAME": must supply a TID if irq_mask not zero\n");
+ return 0;
+ }
+ return tsec_setup_internal(
+ unit,
+ driver_tid,
+ 0, 0,
+ cleanup_txbuf, cleanup_txbuf_arg,
+ alloc_rxbuf,
+ consume_rxbuf, consume_rxbuf_arg,
+ rx_ring_size,
+ tx_ring_size,
+ irq_mask
+ );
+}
+
+struct tsec_private *
+BSP_tsec_setup_1(
+ int unit,
+ void (*isr)(void*),
+ void * isr_arg,
+ void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
+ void * cleanup_txbuf_arg,
+ void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
+ void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
+ void * consume_rxbuf_arg,
+ int rx_ring_size,
+ int tx_ring_size,
+ int irq_mask
+)
+{
+ if ( irq_mask && ! isr ) {
+ printk(DRVNAME": must supply a ISR if irq_mask not zero\n");
+ return 0;
+ }
+ return tsec_setup_internal(
+ unit,
+ 0,
+ isr, isr_arg,
+ cleanup_txbuf, cleanup_txbuf_arg,
+ alloc_rxbuf,
+ consume_rxbuf, consume_rxbuf_arg,
+ rx_ring_size,
+ tx_ring_size,
+ irq_mask
+ );
+}
+
void
BSP_tsec_reset_stats(struct tsec_private *mp)
{
@@ -1287,6 +1378,7 @@ rtems_interrupt_level l;
/* clear and disable IRQs */
fec_wr( b, TSEC_IEVENT, TSEC_IEVENT_ALL );
fec_wr( b, TSEC_IMASK, TSEC_IMASK_NONE );
+ mp->irq_mask_cache = 0;
/* bring other regs. into a known state */
fec_wr( b, TSEC_EDIS, 0 );
@@ -1387,21 +1479,14 @@ rtems_interrupt_level l;
* (slow MII)
*/
- /* disable PHY irq at PIC (fast) */
- phy_dis_irq( mp );
- /* enable PHY irq (MII operation, slow) */
- phy_en_irq_at_phy (mp );
-
- /* globally disable */
- rtems_interrupt_disable( l );
+ if ( (TSEC_LINK_INTR & mp->irq_mask) ) {
+ /* disable PHY irq at PIC (fast) */
+ phy_dis_irq( mp );
+ /* enable PHY irq (MII operation, slow) */
+ phy_en_irq_at_phy (mp );
+ }
- /* enable TSEC IRQs */
- fec_wr( mp->base, TSEC_IMASK, mp->irq_mask );
- /* enable PHY irq at PIC */
- phy_en_irq( mp );
-
- /* globally reenable */
- rtems_interrupt_enable( l );
+ BSP_tsec_enable_irq_mask( mp, mp->irq_mask );
}
static uint8_t
@@ -2108,24 +2193,24 @@ int rval;
*
* Therefore, we take the following approach:
*
- * ISR masks all interrupts on the TSEC, acks/clears them
+ * ISR masks interrupts on the TSEC, acks/clears them
* and stores the acked irqs in the device struct where
- * it is picked up by BSP_tsec_ack_irqs().
- * Since all interrupts are disabled until the daemon
- * re-enables them after calling BSP_tsec_ack_irqs()
- * no interrupts are lost.
+ * it is picked up by BSP_tsec_ack_irq_mask().
*
- * BUT: NO isr (including PHY isrs) MUST INTERRUPT ANY
- * OTHER ONE, i.e., they all must have the same
- * priority. Otherwise, integrity of the cached
- * irq_pending variable may be compromised.
*/
-static inline void
-tsec_dis_irqs( struct tsec_private *mp)
+static inline uint32_t
+tsec_dis_irqs(struct tsec_private *mp, uint32_t mask)
{
- phy_dis_irq( mp );
- fec_wr( mp->base, TSEC_IMASK, TSEC_IMASK_NONE );
+uint32_t rval;
+
+ rval = mp->irq_mask_cache;
+ if ( (TSEC_LINK_INTR & mask & mp->irq_mask_cache) )
+ phy_dis_irq( mp );
+ mp->irq_mask_cache = rval & ~mask;
+ fec_wr( mp->base, TSEC_IMASK, (mp->irq_mask_cache & ~TSEC_LINK_INTR) );
+
+ return rval;
}
static inline uint32_t
@@ -2133,11 +2218,16 @@ tsec_dis_clr_irqs(struct tsec_private *mp)
{
uint32_t rval;
FEC_Enet_Base b = mp->base;
- tsec_dis_irqs( mp );
- rval = fec_rd( b, TSEC_IEVENT);
- fec_wr( b, TSEC_IEVENT, rval );
+
+ rval = fec_rd( b, TSEC_IEVENT);
+
/* Make sure we mask out the link intr */
- return rval & ~TSEC_LINK_INTR;
+ rval &= ~TSEC_LINK_INTR;
+
+ tsec_dis_irqs( mp, rval );
+ fec_wr( b, TSEC_IEVENT, rval );
+
+ return rval;
}
/*
@@ -2147,71 +2237,119 @@ FEC_Enet_Base b = mp->base;
static void tsec_xisr(rtems_irq_hdl_param arg)
{
-struct tsec_private *mp = (struct tsec_private *)arg;
+struct tsec_private *mp = (struct tsec_private *)arg;
+rtems_interrupt_level l;
- mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_disable( l );
+ mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_enable( l );
mp->stats.xirqs++;
- rtems_event_send( mp->tid, mp->event );
+ if ( mp->isr )
+ mp->isr( mp->isr_arg );
+ else
+ rtems_event_send( mp->tid, mp->event );
}
static void tsec_risr(rtems_irq_hdl_param arg)
{
-struct tsec_private *mp = (struct tsec_private *)arg;
+struct tsec_private *mp = (struct tsec_private *)arg;
+rtems_interrupt_level l;
- mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_disable( l );
+ mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_enable( l );
mp->stats.rirqs++;
- rtems_event_send( mp->tid, mp->event );
+ if ( mp->isr )
+ mp->isr( mp->isr_arg );
+ else
+ rtems_event_send( mp->tid, mp->event );
}
static void tsec_eisr(rtems_irq_hdl_param arg)
{
-struct tsec_private *mp = (struct tsec_private *)arg;
+struct tsec_private *mp = (struct tsec_private *)arg;
+rtems_interrupt_level l;
- mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_disable( l );
+ mp->irq_pending |= tsec_dis_clr_irqs( mp );
+ rtems_interrupt_enable( l );
mp->stats.eirqs++;
- rtems_event_send( mp->tid, mp->event );
+ if ( mp->isr )
+ mp->isr( mp->isr_arg );
+ else
+ rtems_event_send( mp->tid, mp->event );
}
static void tsec_lisr(rtems_irq_hdl_param arg)
{
-struct tsec_private *mp = (struct tsec_private *)arg;
+struct tsec_private *mp = (struct tsec_private *)arg;
+rtems_interrupt_level l;
if ( phy_irq_pending( mp ) ) {
- tsec_dis_irqs( mp );
-
- mp->irq_pending |= TSEC_LINK_INTR;
+ rtems_interrupt_disable( l );
+ tsec_dis_irqs( mp, TSEC_LINK_INTR );
+ mp->irq_pending |= TSEC_LINK_INTR;
+ rtems_interrupt_enable( l );
mp->stats.lirqs++;
- rtems_event_send( mp->tid, mp->event );
+ if ( mp->isr )
+ mp->isr( mp->isr_arg );
+ else
+ rtems_event_send( mp->tid, mp->event );
}
}
/* Enable interrupts at device */
void
-BSP_tsec_enable_irqs(struct tsec_private *mp)
+BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t mask)
{
rtems_interrupt_level l;
+
+ mask &= mp->irq_mask;
+
rtems_interrupt_disable( l );
- fec_wr( mp->base, TSEC_IMASK, mp->irq_mask );
- phy_en_irq( mp );
+ if ( (TSEC_LINK_INTR & mask) && ! (TSEC_LINK_INTR & mp->irq_mask_cache) )
+ phy_en_irq( mp );
+ mp->irq_mask_cache |= mask;
+ fec_wr( mp->base, TSEC_IMASK, (mp->irq_mask_cache & ~TSEC_LINK_INTR) );
rtems_interrupt_enable( l );
}
+void
+BSP_tsec_enable_irqs(struct tsec_private *mp)
+{
+ BSP_tsec_enable_irq_mask(mp, -1);
+}
+
/* Disable interrupts at device */
+uint32_t
+BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t mask)
+{
+uint32_t rval;
+rtems_interrupt_level l;
+
+ rtems_interrupt_disable( l );
+ rval = tsec_dis_irqs(mp, mask);
+ rtems_interrupt_enable( l );
+
+ return rval;
+}
+
void
BSP_tsec_disable_irqs(struct tsec_private *mp)
{
rtems_interrupt_level l;
+
rtems_interrupt_disable( l );
- tsec_dis_irqs( mp );
+ tsec_dis_irqs(mp, -1);
rtems_interrupt_enable( l );
}
@@ -2220,19 +2358,17 @@ rtems_interrupt_level l;
* RETURNS: interrupts that were raised.
*/
uint32_t
-BSP_tsec_ack_irqs(struct tsec_private *mp)
+BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask)
{
uint32_t rval;
+rtems_interrupt_level l;
- /* no need to disable interrupts because
- * this should only be called after receiving
- * a RTEMS event posted by the ISR which
- * already shut off interrupts.
- */
- rval = mp->irq_pending;
- mp->irq_pending = 0;
+ rtems_interrupt_disable( l );
+ rval = mp->irq_pending;
+ mp->irq_pending &= ~ mask;
+ rtems_interrupt_enable( l );
- if ( (rval & TSEC_LINK_INTR) ) {
+ if ( (rval & TSEC_LINK_INTR & mask) ) {
/* interacting with the PHY is slow so
* we do it only if we have to...
*/
@@ -2242,6 +2378,12 @@ uint32_t rval;
return rval & mp->irq_mask;
}
+uint32_t
+BSP_tsec_ack_irqs(struct tsec_private *mp)
+{
+ return BSP_tsec_ack_irq_mask(mp, -1);
+}
+
/* Retrieve the driver daemon TID that was passed to
* BSP_tsec_setup().
*/
@@ -2278,7 +2420,7 @@ BSP_tsec_getp(unsigned index)
* if ( irqs & BSP_TSEC_IRQ_RX ) {
* BSP_tsec_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * /
* }
- * BSP_tsec_enable_irqs(handle);
+ * BSP_tsec_enable_irq_mask(handle, -1);
* } while (1);
*
*/
@@ -2609,7 +2751,7 @@ rtems_event_set evs;
if ( (TSEC_RXIRQ & x) )
BSP_tsec_swipe_rx(&sc->pvt);
- BSP_tsec_enable_irqs(&sc->pvt);
+ BSP_tsec_enable_irq_mask(&sc->pvt, -1);
}
}
}
@@ -2873,10 +3015,12 @@ STATIC int phy_irq_dis_level = 0;
* tsec + phy isrs must have the same priority) or
* from a IRQ-protected section of code
*/
+
static void
phy_en_irq(struct tsec_private *mp)
{
- if ( ! ( --phy_irq_dis_level ) ) {
+ phy_irq_dis_level &= ~(1<<mp->unit);
+ if ( 0 == phy_irq_dis_level ) {
BSP_enable_irq_at_pic( BSP_PHY_IRQ );
}
}
@@ -2885,9 +3029,8 @@ phy_en_irq(struct tsec_private *mp)
static void
phy_dis_irq(struct tsec_private *mp)
{
- if ( !(phy_irq_dis_level++) ) {
- BSP_disable_irq_at_pic( BSP_PHY_IRQ );
- }
+ phy_irq_dis_level |= (1<<mp->unit);
+ BSP_disable_irq_at_pic( BSP_PHY_IRQ );
}
static int