summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/madge/driver/drv_irq.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/ndis/madge/driver/drv_irq.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/private/ntos/ndis/madge/driver/drv_irq.c b/private/ntos/ndis/madge/driver/drv_irq.c
new file mode 100644
index 000000000..5d484aa61
--- /dev/null
+++ b/private/ntos/ndis/madge/driver/drv_irq.c
@@ -0,0 +1,413 @@
+/****************************************************************************
+*
+* DRV_IRQ.C : Part of the FASTMAC TOOL-KIT (FTK)
+*
+* THE DRIVER MODULE (INTERRUPT HANDLE)
+*
+* Copyright (c) Madge Networks Ltd. 1991-1994
+*
+* COMPANY CONFIDENTIAL
+*
+*****************************************************************************
+*
+* The driver module provides a simple interface to allow the use of
+* Fastmac in as general a setting as possible. It handles the downloading
+* of the Fastmac code and the initialization of the adapter card. It
+* provides simple transmit and receive routines. It is desgined to
+* quickly allow the implementation of Fastmac applications. It is not
+* designed as the fastest or most memory efficient solution.
+*
+* DRV_IRQ.C contains code to handle SIF interrupts from the adapter card.
+* The HWI_ modules take care of any PIO interrupts, and anything else is
+* passed here. There is also code for calling the received frame handler
+* from the foreground task rather than at interrupt time.
+*
+****************************************************************************/
+
+/*---------------------------------------------------------------------------
+|
+| DEFINITIONS
+|
+---------------------------------------------------------------------------*/
+
+#include "ftk_defs.h"
+
+/*---------------------------------------------------------------------------
+|
+| MODULE ENTRY POINTS
+|
+---------------------------------------------------------------------------*/
+
+#include "ftk_intr.h" /* routines internal to FTK */
+#include "ftk_extr.h" /* routines provided or used by external FTK user */
+
+/****************************************************************************
+*
+* driver_interrupt_entry
+* ======================
+*
+* PARAMETERS (passed by hwi_<card_type>_sif_interrupt) :
+* ======================================================
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* The adapter handle for the adapter so it can be passed to the user
+* supplied user_receive_frame or user_completed_srb routine.
+*
+* ADAPTER * adapter
+*
+* The details of the adapter that the interrupt has occured on.
+*
+* WORD sifint_actual
+*
+* The actual contents of the EAGLE SIF interrupt register.
+*
+* BODY :
+* ======
+*
+* The driver_interupt_entry routine is called by the HWI. It is entered
+* when an interrupt has occured for the given adapter. This could be
+* because of an SRB free interrupt, an adapter chack interrupt or because
+* frames are in the Fastmac receive buffer. Note these frames may have
+* been in the receive buffer some time but not yet dealt with.
+*
+* On an SRB free interrupt, the interrupt is acknowledged and the
+* driver_completing_srb routine in DRV_SRB.C is called. This results in
+* the user supplied routine user_completed_srb being called informing the
+* user on the success or failure of the current SRB and letting the user
+* know that another SRB can be issued.
+*
+* On adapter check interrupts, the error record for the adapter is filled
+* in to mark the adapter as no longer working. A call to a user function
+* is made in case higher level code needs to take action.
+*
+* On receive frame interrupts, the action taken depends on the receive
+* method being used. In FTK_RX_BY_SCHEDULED_PROCESS mode, the user routine
+* user_schedule_receive_process is called with the adapter handle as the
+* only parameter. It is the job of this user routine to schedule a process
+* to call driver_get_outstanding_receive to get the received frames out of
+* the Fastmac receive buffer. In FTK_RX_OUT_OF_INTERRUPTS mode, the received
+* frames are dealt with immediately via the rxtx_irq_rx_frame_handler
+* routine and the user supplied receive routine user_receive_frame.
+*
+* The rxtx_irq_rx_frame_handler routine is actually the same routine
+* that is called by the driver_get_outstanding_receive routine if the
+* FTK_RX_BY_SCHEDULED_PROCESS receive method is being used.
+*
+*
+* Note on increasing speed:
+*
+* One way of speeding up execution of the receive routine would be to
+* replace the sys_outsw and sys_insw routines by similar routines supplied
+* with your C compiler and have them compiled in-line.
+*
+*
+* RETURNS :
+* =========
+*
+* The routine always succeeds and returns control to the HWI routine
+* hwi_<type>_sif_interrupt.
+*
+****************************************************************************/
+
+#ifdef FTK_IRQ_FUNCTION
+#pragma FTK_IRQ_FUNCTION(driver_interrupt_entry)
+#endif
+
+export void
+driver_interrupt_entry(
+ ADAPTER_HANDLE adapter_handle,
+ ADAPTER * adapter,
+ WORD sifint_actual
+ )
+{
+ WORD sifint_value;
+ WBOOLEAN ack_needed = FALSE;
+
+ /*
+ * XOR the high byte and low byte of contents of EAGLE_SIFINT register.
+ */
+
+ sifint_value = (sifint_actual & 0x00FF) ^ (sifint_actual >> 8);
+
+ /*
+ * AND with 0x000F so left with a nibble identifying interrupt type.
+ */
+
+ sifint_value = sifint_value & 0x000F;
+
+ /*
+ * Action depends on interrupt type.
+ */
+
+ if (sifint_value != 0)
+ {
+ if ((sifint_value & FASTMAC_SIFINT_ADAPTER_CHECK) != 0)
+ {
+ /*
+ * For adapter check, fill in error record so adapter now dead.
+ * No need to check if any other interrupt bits set.
+ */
+
+ adapter->error_record.type = ERROR_TYPE_ADAPTER;
+ adapter->error_record.value = ADAPTER_E_01_ADAPTER_CHECK;
+
+ /*
+ * Allow the user to give some sort of warning.
+ */
+
+ user_handle_adapter_check(adapter_handle);
+ }
+ else
+ {
+ if ((sifint_value & FASTMAC_SIFINT_SRB_FREE) != 0)
+ {
+ /*
+ * For SRB free interrupts, call routine which informs user.
+ */
+
+ driver_completing_srb(adapter_handle, adapter);
+ ack_needed = TRUE;
+ }
+
+ if ((sifint_value & FASTMAC_SIFINT_ARB_COMMAND) != 0)
+ {
+ /*
+ * For ARB command interrupts, do nothing as
+ * they should never happen.
+ */
+
+ ack_needed = TRUE;
+ }
+
+ if ((sifint_value & FASTMAC_SIFINT_SSB_RESPONSE) != 0)
+ {
+ /*
+ * For SSB response interrupts, do nothing as
+ * they should never happen.
+ */
+
+ ack_needed = TRUE;
+ }
+ }
+ }
+
+ /*
+ * Now check for receives and transmits...
+ */
+
+#ifdef FMPLUS
+
+ /*
+ * For Fastmac Plus, we must allow for the possibility that the
+ * interrupt is because a large transmit buffer DMA is complete.
+ */
+
+#ifdef FTK_TX_WITH_COMPLETION
+
+#ifndef FTK_NO_TX_COMPLETION_CALL
+
+ rxtx_irq_tx_completion_check(adapter_handle, adapter);
+
+#endif
+
+#endif
+
+#endif
+
+ /*
+ * Invoke received frame processing based on the receive mode.
+ */
+
+#ifdef FTK_RX_OUT_OF_INTERRUPTS
+
+ rxtx_irq_rx_frame_handler(adapter_handle, adapter);
+
+#endif
+
+#ifdef FTK_RX_BY_SCHEDULED_PROCESS
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_disable_io(adapter);
+#endif
+
+ user_schedule_receive_process(adapter_handle);
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_enable_io(adapter);
+#endif
+
+#endif
+
+ /*
+ * Now do any cleaning up that is needed ...
+ * For certain interrupts, need to interrupt Fastmac to acknowledge.
+ */
+
+ if (ack_needed)
+ {
+ /*
+ * Convert from FASTMAC_SIFINT interrupt into DRIVER_SIFINT_ACK
+ * to acknowledge interrupt.
+ */
+
+ sifint_value = (sifint_value << 8);
+
+ /*
+ * Set interrupt adapter bit in SIFCMD.
+ */
+
+ sifint_value = (sifint_value | DRIVER_SIFINT_IRQ_FASTMAC);
+
+ /*
+ * Mask SIFSTS so not clear interrupt if Fastmac interrupted again.
+ */
+
+ sifint_value = (sifint_value | DRIVER_SIFINT_FASTMAC_IRQ_MASK);
+
+ /*
+ * Interrupt Fastmac.
+ */
+
+ sys_outsw(adapter_handle, adapter->sif_int, sifint_value);
+ }
+
+ /*
+ * Return to hwi_interrupt_entry routine.
+ */
+}
+
+/****************************************************************************
+*
+* driver_get_outstanding_receive
+* ==============================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter which we wish to deal with
+* outstanding received frames on.
+*
+* BODY :
+* ======
+*
+* The driver_get_outstanding_receive routine should be called only when
+* using the FTK_RX_BY_SCHEDULED_PROCESS receive method. The user supplied
+* receive routine (user_receive_frame) is called with the adapter handle
+* and the length and a physical address pointer to the oldest unprocessed
+* received frame for the given adapter. If there are no oustanding
+* received frames the user routine is never called but this is not an
+* error and is not regsitered as such.
+*
+* If the receive routine processes the frame (returns DO_NOT_KEEP_FRAME),
+* and if the Fastmac receive buffer is not empty, the receive routine is
+* called again with the details of the next frame. This continues until
+* either the Fastmac buffer is empty or the receive routine does not
+* process the frame (returns KEEP_FRAME). However, no more than one buffer
+* full of frames is passed to the user receive routine on any one entry to
+* driver_get_outstanding_receive. Note that if the receive buffer is not
+* emptied by the user then another interrupt will occur later and the
+* process that calls driver_get_outstanding_receive will be rescheduled.
+*
+* To deal with the details of handling received frames in the Fastmac
+* buffers, this routine uses rxtx_irq_rx_frame_handler. This is the
+* same routine called out of driver_interrupt_entry if the
+* FTK_RX_OUT_OF_INTERRUPTS receive method is being used. The routine uses
+* an algorithm for dealing with received frames similar to that in the
+* Fastmac specification document.
+*
+* Dealing with received frames using the driver_get_outstanding_receive
+* routine is different to using the driver_interrupt_entry routine in that
+* the former routine is called under user control, in strategy time as
+* opposed to interrupt time, and hence gives the user receive frame
+* routine more time to process frames. This is necessary under certain
+* operating systems such as AIX.
+*
+* Notes on increasing speed:
+*
+* The code between "#ifndef SPEED_ABOVE_TESTING" to "#endif" is only for
+* testing purposes. If SPEED_ABOVE_TESTING is defined during compilation
+* then the code will not be included so the receive routine will execute
+* faster. However, an erroneous adapter handle would then cause a program
+* to crash unpredicatably. The SPEED_ABOVE_TESTING option should be used
+* with care.
+*
+* Another way of speeding up execution of the receive routine would be to
+* replace the sys_outsw and sys_insw routines by similar routines supplied
+* with your C compiler and have them compiled in-line.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation. Note that it will not fail just
+* because there are no frames to receive.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_get_outstanding_receive)
+#endif
+
+export WBOOLEAN
+driver_get_outstanding_receive(
+ ADAPTER_HANDLE adapter_handle
+ )
+{
+ ADAPTER * adapter;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+#ifndef SPEED_ABOVE_TESTING
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_ANY_STATE))
+ {
+ return FALSE;
+ }
+
+#endif
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Inform the system about the IO ports we are going to access.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_enable_io(adapter);
+#endif
+
+ /*
+ * Perform the actual frame receiving uses same routine called out
+ * of interrupts with FTK_RX_OUT_OF_INTERRUPTS.
+ */
+
+ rxtx_irq_rx_frame_handler(adapter_handle, adapter);
+
+ /*
+ * Let the system know we have finished accessing the IO ports.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_disable_io(adapter);
+#endif
+
+ /*
+ * Receive completed.
+ */
+
+ return TRUE;
+}
+
+
+/**** End of DRV_IRQ.C file ************************************************/