mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2187 lines
62 KiB
2187 lines
62 KiB
/****************************************************************************
|
|
*
|
|
* FTK_USER.C
|
|
*
|
|
* FastMAC Plus based NDIS3 miniport driver FTK interface. This module
|
|
* contains all of the routines required to interface with the FastMAC
|
|
* Plus FTK. This is includes the routines traditionally found in transmit.c
|
|
* and receive.c.
|
|
*
|
|
* Copyright (c) Madge Networks Ltd 1994
|
|
*
|
|
* COMPANY CONFIDENTIAL
|
|
*
|
|
* Created: PBA 21/06/1994
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <ndis.h>
|
|
|
|
#include "ftk_defs.h"
|
|
#include "ftk_extr.h"
|
|
#include "ftk_intr.h"
|
|
|
|
#include "mdgmport.upd"
|
|
#include "ndismod.h"
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| LOCAL VARIABLES
|
|
|
|
|
---------------------------------------------------------------------------*/
|
|
|
|
//
|
|
// To cut down on accesses to the slot structures on the card we keep
|
|
// a host cache of various detaisl we need.
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
DWORD PhysicalAddress;
|
|
PVOID VirtualAddress;
|
|
}
|
|
RX_SLOT_CACHE, *PRX_SLOT_CACHE;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
ULONG BufferSize;
|
|
ULONG SharedMemoryAllocation;
|
|
PVOID SharedMemoryVirtAddr;
|
|
DWORD SharedMemoryPhysAddr;
|
|
|
|
RX_SLOT_CACHE rx_slot_cache[FMPLUS_MAX_RX_SLOTS];
|
|
|
|
UINT active_rx_slot; /* Used to count through the slot array */
|
|
}
|
|
RX_SLOT_MGMNT, *PRX_SLOT_MGMNT;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
DWORD PhysicalAddress;
|
|
PVOID VirtualAddress;
|
|
}
|
|
TX_SLOT_CACHE, *PTX_SLOT_CACHE;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
ULONG BufferSize;
|
|
ULONG SharedMemoryAllocation;
|
|
PVOID SharedMemoryVirtAddr;
|
|
DWORD SharedMemoryPhysAddr;
|
|
|
|
TX_SLOT_CACHE tx_slot_cache[FMPLUS_MAX_TX_SLOTS];
|
|
|
|
UINT active_tx_slot;
|
|
UINT first_tx_in_use;
|
|
UINT number_tx_in_use;
|
|
}
|
|
TX_SLOT_MGMNT, *PTX_SLOT_MGMNT;
|
|
|
|
|
|
#define FRAME_TYPE_MASK ((BYTE) 0xC0) // What is ANDed with FC byte.
|
|
#define FRAME_TYPE_MAC ((BYTE) 0x00) // What's left for a MAC frame.
|
|
|
|
|
|
typedef struct
|
|
{
|
|
ADAPTER_HANDLE adapter_handle;
|
|
ADAPTER * adapter;
|
|
TX_SLOT * tx_slot_ptr;
|
|
RX_SLOT * rx_slot_ptr;
|
|
UINT frame_length;
|
|
UINT result1;
|
|
UINT result2;
|
|
}
|
|
MPSAFE_INFO;
|
|
|
|
|
|
#if 0
|
|
|
|
typedef struct
|
|
{
|
|
ADAPTER_HANDLE handle;
|
|
WORD location;
|
|
WORD result;
|
|
}
|
|
RDIO;
|
|
|
|
WORD
|
|
_madge_rdio(
|
|
void * ptr
|
|
)
|
|
{
|
|
RDIO * rdio;
|
|
|
|
rdio = (RDIO *) ptr;
|
|
|
|
sys_outsw(
|
|
rdio->handle,
|
|
adapter_record[rdio->handle]->sif_adr,
|
|
rdio->location
|
|
);
|
|
|
|
rdio->result = sys_insw(
|
|
rdio->handle,
|
|
adapter_record[rdio->handle]->sif_dat
|
|
);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
WORD
|
|
madge_rdio(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
WORD dio_location
|
|
)
|
|
{
|
|
RDIO rdio;
|
|
|
|
rdio.handle = adapter_handle;
|
|
rdio.location = dio_location;
|
|
|
|
sys_sync_with_interrupt(
|
|
adapter_handle,
|
|
_madge_rdio,
|
|
(void *) &rdio
|
|
);
|
|
|
|
return rdio.result;
|
|
}
|
|
|
|
|
|
void
|
|
madge_dump_fmplus_info(
|
|
ADAPTER_HANDLE adapter_handle
|
|
)
|
|
{
|
|
ADAPTER * adapter;
|
|
PRX_SLOT_MGMNT rx_slot_mgmnt;
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
RX_SLOT * * rx_slot_array;
|
|
TX_SLOT * * tx_slot_array;
|
|
UINT active_rx_slot;
|
|
UINT active_tx_slot;
|
|
UINT first_tx_slot;
|
|
UINT rx_slots;
|
|
UINT tx_slots;
|
|
UINT i;
|
|
|
|
adapter = adapter_record[adapter_handle];
|
|
|
|
rx_slot_array = adapter->rx_slot_array;
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
active_rx_slot = rx_slot_mgmnt->active_rx_slot;
|
|
rx_slots = adapter->init_block->fastmac_parms.rx_slots;
|
|
|
|
tx_slot_array = adapter->tx_slot_array;
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
active_tx_slot = tx_slot_mgmnt->active_tx_slot;
|
|
first_tx_slot = tx_slot_mgmnt->first_tx_in_use;
|
|
tx_slots = adapter->init_block->fastmac_parms.tx_slots;
|
|
|
|
DbgPrint("----------------------------------------------------------\n");
|
|
|
|
DbgPrint(
|
|
"SIFADR high word = %04x\n\n",
|
|
sys_insw(adapter_handle, adapter->sif_adx)
|
|
);
|
|
|
|
DbgPrint("RX SLOTS:\n\n");
|
|
DbgPrint("Active slot = %d\n", active_rx_slot);
|
|
|
|
DbgPrint(" Len Res Buffer Stat Next\n");
|
|
DbgPrint(" ---- ---- --------- ---- ----\n");
|
|
|
|
for (i = 0; i < rx_slots; i++)
|
|
{
|
|
DbgPrint(
|
|
"%04x: %04x %04x %04x %04x %04x %04x\n",
|
|
(WORD) (card_t) rx_slot_array[i],
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->buffer_len),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->reserved),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->buffer_hiw),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->buffer_low),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->rx_status),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &rx_slot_array[i]->next_slot)
|
|
);
|
|
}
|
|
|
|
DbgPrint("\n");
|
|
|
|
DbgPrint("TX SLOTS:\n\n");
|
|
DbgPrint("Active slot = %d\n", active_tx_slot);
|
|
DbgPrint("First used slot = %d\n", first_tx_slot);
|
|
|
|
DbgPrint(" Stat SLen LLen Res1 Res2 Sbuffer Next LBuffer\n");
|
|
DbgPrint(" ---- ---- ---- ---- ---- --------- ---- ---------\n");
|
|
|
|
for (i = 0; i < tx_slots; i++)
|
|
{
|
|
DbgPrint(
|
|
"%04x: %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
|
|
(WORD) (card_t) tx_slot_array[i],
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->tx_status),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->small_buffer_len),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->large_buffer_len),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->reserved[0]),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->reserved[1]),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->small_buffer_hiw),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->small_buffer_low),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->next_slot),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->large_buffer_hiw),
|
|
madge_rdio(adapter_handle, (WORD) (card_t) &tx_slot_array[i]->large_buffer_low)
|
|
);
|
|
}
|
|
|
|
DbgPrint("\n");
|
|
|
|
DbgPrint("DIO LOCATION 0x0CE0\n\n");
|
|
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
DbgPrint(" %04x", madge_rdio(adapter_handle, (WORD) (0x0ce0 + i * 2)));
|
|
if (i == 15)
|
|
{
|
|
DbgPrint("\n");
|
|
}
|
|
}
|
|
|
|
DbgPrint("\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_allocate_rx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* max_frame_size -> Maximum frame size.
|
|
* number_of_slots -> Number of receive slots.
|
|
*
|
|
* Purpose - Allocate buffer space for the receive slots.
|
|
*
|
|
* Returns - TRUE if it succeeds or FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
WBOOLEAN
|
|
rxtx_allocate_rx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(rxtx_allocate_rx_buffers)
|
|
|
|
WBOOLEAN
|
|
rxtx_allocate_rx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
PRX_SLOT_MGMNT rx_slot_mgmnt;
|
|
NDIS_STATUS status;
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
DWORD SharedMemVirtAddr;
|
|
DWORD SharedMemPhysAddr;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
|
|
//
|
|
// Only want to allocate the receive buffers and slot management once
|
|
// per adapter.
|
|
//
|
|
|
|
if (rx_slot_mgmnt == NULL)
|
|
{
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
//
|
|
// Allocate the slot management structure.
|
|
//
|
|
|
|
MADGE_ALLOC_MEMORY(
|
|
&status,
|
|
&adapter->rx_slot_mgmnt,
|
|
sizeof(RX_SLOT_MGMNT)
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
MADGE_ZERO_MEMORY(adapter->rx_slot_mgmnt, sizeof(RX_SLOT_MGMNT));
|
|
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
|
|
//
|
|
// Work out how big the buffer should be. Remember to add
|
|
// four to the buffer allocation for the CRC. The addition
|
|
// of 32 provides a little space between receive buffers
|
|
// for those naughty transport protocols that read more
|
|
// then the indicated lookahead.
|
|
//
|
|
|
|
rx_slot_mgmnt->BufferSize = (max_frame_size + 4 + 32 + 3) & ~3;
|
|
|
|
rx_slot_mgmnt->SharedMemoryAllocation =
|
|
rx_slot_mgmnt->BufferSize * number_of_slots;
|
|
|
|
//
|
|
// Allocate the buffer.
|
|
//
|
|
|
|
if (!sys_alloc_dma_phys_buffer(
|
|
adapter_handle,
|
|
rx_slot_mgmnt->SharedMemoryAllocation,
|
|
&SharedMemPhysAddr,
|
|
&SharedMemVirtAddr
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
rx_slot_mgmnt->SharedMemoryVirtAddr = (VOID *) SharedMemVirtAddr;
|
|
rx_slot_mgmnt->SharedMemoryPhysAddr = SharedMemPhysAddr;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_setup_rx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* physical_addresses -> Use physical addresses?
|
|
* number_of_slots -> Number of receive slots.
|
|
*
|
|
* Purpose - Set up the adapter receive slots.
|
|
*
|
|
* Returns - TRUE if it succeeds or FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_setup_rx_buffers(
|
|
ADAPTER * adapter,
|
|
WBOOLEAN physical_addresses,
|
|
WORD number_of_slots
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(rxtx_setup_rx_buffers)
|
|
|
|
void
|
|
rxtx_setup_rx_buffers(
|
|
ADAPTER * adapter,
|
|
WBOOLEAN physical_addresses,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
PRX_SLOT_MGMNT rx_slot_mgmnt;
|
|
NDIS_STATUS status;
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
PVOID SharedMemVirtAddr;
|
|
DWORD SharedMemPhysAddr;
|
|
PRX_SLOT_CACHE rx_slot_cache;
|
|
RX_SLOT * * rx_slot_array;
|
|
DWORD phys_addr;
|
|
WORD slot_index;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
WORD sifdatinc;
|
|
UINT buffer_size;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
rx_slot_array = adapter->rx_slot_array;
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
rx_slot_cache = rx_slot_mgmnt->rx_slot_cache;
|
|
SharedMemVirtAddr = rx_slot_mgmnt->SharedMemoryVirtAddr;
|
|
SharedMemPhysAddr = rx_slot_mgmnt->SharedMemoryPhysAddr;
|
|
buffer_size = rx_slot_mgmnt->BufferSize;
|
|
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
sifdatinc = adapter->sif_datinc;
|
|
|
|
MadgePrint2("rxtx_setup_rx_buffers number_of_slots = %d\n", number_of_slots);
|
|
MadgePrint2("rxtx_setup_rx_buffers buffer_size = %d\n", buffer_size);
|
|
|
|
//
|
|
// Work out the physical and virtual address of each buffer.
|
|
//
|
|
|
|
for (slot_index = 0; slot_index < number_of_slots; slot_index++)
|
|
{
|
|
rx_slot_cache[slot_index].VirtualAddress = SharedMemVirtAddr;
|
|
(PUCHAR) SharedMemVirtAddr += buffer_size;
|
|
|
|
rx_slot_cache[slot_index].PhysicalAddress = SharedMemPhysAddr;
|
|
SharedMemPhysAddr += buffer_size;
|
|
|
|
phys_addr = (physical_addresses)
|
|
? (DWORD) rx_slot_cache[slot_index].PhysicalAddress
|
|
: (DWORD) rx_slot_cache[slot_index].VirtualAddress;
|
|
|
|
//
|
|
// Write the buffer locations into the slots.
|
|
//
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_array[slot_index]->buffer_hiw
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdatinc,
|
|
(WORD) (phys_addr >> 16)
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
(WORD) (phys_addr & 0x0FFFF)
|
|
);
|
|
}
|
|
|
|
ndisAdap->RxTxBufferState |= MADGE_RX_INITIALIZED;
|
|
rx_slot_mgmnt->active_rx_slot = 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_free_rx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* max_frame_size -> Maximum frame size.
|
|
* number_of_slots -> Number of receive slots.
|
|
*
|
|
* Purpose - Free the previously allocated receive buffers.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_free_rx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
PRX_SLOT_MGMNT rx_slot_mgmnt;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
|
|
//
|
|
// If the slot management structure exists them free it
|
|
// and the buffers.
|
|
//
|
|
|
|
if (rx_slot_mgmnt != NULL)
|
|
{
|
|
if (rx_slot_mgmnt->SharedMemoryVirtAddr != NULL)
|
|
{
|
|
sys_free_dma_phys_buffer(
|
|
adapter_handle,
|
|
rx_slot_mgmnt->SharedMemoryAllocation,
|
|
(DWORD) rx_slot_mgmnt->SharedMemoryPhysAddr,
|
|
(DWORD) rx_slot_mgmnt->SharedMemoryVirtAddr
|
|
);
|
|
}
|
|
|
|
MADGE_FREE_MEMORY(adapter->rx_slot_mgmnt, sizeof(RX_SLOT_MGMNT));
|
|
|
|
adapter->rx_slot_mgmnt = NULL;
|
|
|
|
ndisAdap->RxTxBufferState &= ~MADGE_RX_INITIALIZED;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_allocate_tx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* max_frame_size -> Maximum frame size.
|
|
* number_of_slots -> Number of transmit slots.
|
|
*
|
|
* Purpose - Allocate buffer space for the transmit slots.
|
|
*
|
|
* Returns - TRUE if it succeeds or FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
WBOOLEAN
|
|
rxtx_allocate_tx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(rxtx_allocate_tx_buffers)
|
|
|
|
WBOOLEAN
|
|
rxtx_allocate_tx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
NDIS_STATUS status;
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
DWORD SharedMemVirtAddr;
|
|
DWORD SharedMemPhysAddr;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
|
|
//
|
|
// Only want to allocate the receive buffers and slot management once
|
|
// per adapter.
|
|
//
|
|
|
|
if (tx_slot_mgmnt == NULL)
|
|
{
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
//
|
|
// Allocate the slot management structure.
|
|
//
|
|
|
|
MADGE_ALLOC_MEMORY(
|
|
&status,
|
|
&adapter->tx_slot_mgmnt,
|
|
sizeof(TX_SLOT_MGMNT)
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
MADGE_ZERO_MEMORY(adapter->tx_slot_mgmnt, sizeof(TX_SLOT_MGMNT));
|
|
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
|
|
//
|
|
// Work out how big the buffer should be.
|
|
//
|
|
|
|
tx_slot_mgmnt->BufferSize = (max_frame_size + 3) & ~3;
|
|
|
|
tx_slot_mgmnt->SharedMemoryAllocation =
|
|
tx_slot_mgmnt->BufferSize * number_of_slots;
|
|
|
|
//
|
|
// Allocate the buffer.
|
|
//
|
|
|
|
if (!sys_alloc_dma_phys_buffer(
|
|
adapter_handle,
|
|
tx_slot_mgmnt->SharedMemoryAllocation,
|
|
&SharedMemPhysAddr,
|
|
&SharedMemVirtAddr
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
tx_slot_mgmnt->SharedMemoryVirtAddr = (VOID *) SharedMemVirtAddr;
|
|
tx_slot_mgmnt->SharedMemoryPhysAddr = SharedMemPhysAddr;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_setup_tx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* physical_addresses -> Use physical addresses?
|
|
* number_of_slots -> Number of transmit slots.
|
|
*
|
|
* Purpose - Set up the adapter transmit slots.
|
|
*
|
|
* Returns - TRUE if it succeeds or FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_setup_tx_buffers(
|
|
ADAPTER * adapter,
|
|
WBOOLEAN physical_addresses,
|
|
WORD number_of_slots
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(rxtx_setup_tx_buffers)
|
|
|
|
void
|
|
rxtx_setup_tx_buffers(
|
|
ADAPTER * adapter,
|
|
WBOOLEAN physical_addresses,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
NDIS_STATUS status;
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
PVOID SharedMemVirtAddr;
|
|
DWORD SharedMemPhysAddr;
|
|
PTX_SLOT_CACHE tx_slot_cache;
|
|
TX_SLOT * * tx_slot_array;
|
|
DWORD phys_addr;
|
|
WORD slot_index;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
WORD sifdatinc;
|
|
UINT buffer_size;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
tx_slot_array = adapter->tx_slot_array;
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
tx_slot_cache = tx_slot_mgmnt->tx_slot_cache;
|
|
SharedMemVirtAddr = tx_slot_mgmnt->SharedMemoryVirtAddr;
|
|
SharedMemPhysAddr = tx_slot_mgmnt->SharedMemoryPhysAddr;
|
|
buffer_size = tx_slot_mgmnt->BufferSize;
|
|
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
sifdatinc = adapter->sif_datinc;
|
|
|
|
MadgePrint2("rxtx_setup_tx_buffers number_of_slots = %d\n", number_of_slots);
|
|
MadgePrint2("rxtx_setup_tx_buffers buffer_size = %d\n", buffer_size);
|
|
|
|
//
|
|
// Work out the physical and virtual address of each buffer.
|
|
//
|
|
|
|
for (slot_index = 0; slot_index < number_of_slots; slot_index++)
|
|
{
|
|
tx_slot_cache[slot_index].VirtualAddress = SharedMemVirtAddr;
|
|
(PUCHAR) SharedMemVirtAddr += buffer_size;
|
|
|
|
tx_slot_cache[slot_index].PhysicalAddress = SharedMemPhysAddr;
|
|
SharedMemPhysAddr += buffer_size;
|
|
|
|
phys_addr = (physical_addresses)
|
|
? (DWORD) tx_slot_cache[slot_index].PhysicalAddress
|
|
: (DWORD) tx_slot_cache[slot_index].VirtualAddress;
|
|
|
|
//
|
|
// Write the buffer locations into the slots.
|
|
//
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_array[slot_index]->large_buffer_hiw
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdatinc,
|
|
(WORD) (phys_addr >> 16)
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
(WORD) (phys_addr & 0x0FFFF)
|
|
);
|
|
}
|
|
|
|
ndisAdap->RxTxBufferState |= MADGE_TX_INITIALIZED;
|
|
tx_slot_mgmnt->active_tx_slot = 0;
|
|
tx_slot_mgmnt->first_tx_in_use = 0;
|
|
tx_slot_mgmnt->number_tx_in_use = 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_free_tx_buffers
|
|
*
|
|
* Parameters - adapter -> Pointer to an FTK adapter structure.
|
|
* max_frame_size -> Maximum frame size.
|
|
* number_of_slots -> Number of transmit slots.
|
|
*
|
|
* Purpose - Free the previously allocated transmit buffers.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_free_tx_buffers(
|
|
ADAPTER * adapter,
|
|
WORD max_frame_size,
|
|
WORD number_of_slots
|
|
)
|
|
{
|
|
ADAPTER_HANDLE adapter_handle;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter_handle = adapter->adapter_handle;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
|
|
//
|
|
// If the slot management structure exists them free it
|
|
// and the buffers.
|
|
//
|
|
|
|
if (tx_slot_mgmnt != NULL)
|
|
{
|
|
if (tx_slot_mgmnt->SharedMemoryVirtAddr != NULL)
|
|
{
|
|
sys_free_dma_phys_buffer(
|
|
adapter_handle,
|
|
tx_slot_mgmnt->SharedMemoryAllocation,
|
|
(DWORD) tx_slot_mgmnt->SharedMemoryPhysAddr,
|
|
(DWORD) tx_slot_mgmnt->SharedMemoryVirtAddr
|
|
);
|
|
}
|
|
|
|
MADGE_FREE_MEMORY(adapter->tx_slot_mgmnt, sizeof(TX_SLOT_MGMNT));
|
|
|
|
adapter->tx_slot_mgmnt = NULL;
|
|
|
|
ndisAdap->RxTxBufferState &= ~MADGE_TX_INITIALIZED;
|
|
}
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
| Function - MPSafeReadTxStatus
|
|
|
|
|
| Paramters - ptr -> Pointer to an MPSAFE_INFO structure.
|
|
|
|
|
| Purpose - Reads the transmit status from the next slot to use. This
|
|
| function is called via NdisSynchronizeWithInterrupt when
|
|
| in PIO mode so that we don't get SIF register contention
|
|
| on a multiprocessor.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
MPSafeReadTxStatus(PVOID ptr)
|
|
{
|
|
MPSAFE_INFO * info = (MPSAFE_INFO *) ptr;
|
|
|
|
//
|
|
// Read the transmit status from the slot.
|
|
//
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->tx_slot_ptr)->tx_status
|
|
);
|
|
|
|
info->result1 = sys_insw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_irq_tx_completion_check
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
* adapter -> Pointer to FTK adapter structure.
|
|
*
|
|
* Purpose - Complete any outstanding transmits.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_irq_tx_completion_check(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
ADAPTER * adapter
|
|
)
|
|
{
|
|
UINT tx_slots;
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
PTX_SLOT_CACHE tx_slot_cache;
|
|
TX_SLOT * * tx_slot_array;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
UINT tx_status;
|
|
MPSAFE_INFO info;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
tx_slot_cache = tx_slot_mgmnt->tx_slot_cache;
|
|
tx_slot_array = adapter->tx_slot_array;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
tx_slots = adapter->init_block->fastmac_parms.tx_slots;
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
|
|
//
|
|
// If we're doing multiprocessor safe PIO then we need to set up
|
|
// the info structure.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.adapter_handle = adapter_handle;
|
|
info.adapter = adapter;
|
|
}
|
|
|
|
//
|
|
// Iterate around the transmit slots that are are marked as in use
|
|
// checking if they are now free. Note: we must work with the
|
|
// global coopies of the first_tx_in_use and number_tx_in_use
|
|
// in case rxtx_transmit_frame is called during our up-call
|
|
// to the wrapper.
|
|
//
|
|
|
|
while (tx_slot_mgmnt->number_tx_in_use > 0)
|
|
{
|
|
//
|
|
// Read the transmit status from the slot. If we're doing
|
|
// multiprocessor safe PIO we must do the DIO via an ISR
|
|
// synchronized function.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.tx_slot_ptr = tx_slot_array[tx_slot_mgmnt->first_tx_in_use];
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeReadTxStatus,
|
|
&info
|
|
);
|
|
|
|
tx_status = info.result1;
|
|
}
|
|
else
|
|
{
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_array[
|
|
tx_slot_mgmnt->first_tx_in_use
|
|
]->tx_status
|
|
);
|
|
|
|
tx_status = sys_insw(
|
|
adapter_handle,
|
|
sifdat
|
|
);
|
|
}
|
|
|
|
//
|
|
// If the slot is still in use then we must give up. This will
|
|
// also work if a PCMCIA adapter has been removed because
|
|
// tx_status will have been read as 0xffff.
|
|
//
|
|
|
|
if (tx_status >= 0x8000 || tx_status == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Update the appropriate counters from the frame transmit
|
|
// status.
|
|
//
|
|
|
|
if ((tx_status & TX_RECEIVE_STATUS_MASK) == TX_RECEIVE_LOST_FRAME)
|
|
{
|
|
ndisAdap->LostFrames++;
|
|
}
|
|
else if ((tx_status & GOOD_TX_FRAME_MASK) != GOOD_TX_FRAME_VALUE)
|
|
{
|
|
ndisAdap->FrameTransmitErrors++;
|
|
}
|
|
|
|
//
|
|
// Update the slot usage.
|
|
//
|
|
|
|
tx_slot_mgmnt->number_tx_in_use--;
|
|
|
|
if (++tx_slot_mgmnt->first_tx_in_use == tx_slots)
|
|
{
|
|
tx_slot_mgmnt->first_tx_in_use = 0;
|
|
}
|
|
|
|
//
|
|
// Tell the wrapper that there is a free slot.
|
|
//
|
|
|
|
NdisMSendResourcesAvailable(ndisAdap->UsedInISR.MiniportHandle);
|
|
}
|
|
|
|
//
|
|
// If there are any frames we have queued for transmit that
|
|
// have not been completed then arm the timer so we are guaranteed
|
|
// to be called again. Under normal operation our DPR gets called
|
|
// often enough that this function is called frequently enough to
|
|
// complete all of the frames. However if we have an adapter in a
|
|
// fast bus (PCI/EISA) with a lot of RAM and we are not
|
|
// getting any recieve interrupts we can occasionally miss
|
|
// completing a frame. Hence the timer.
|
|
//
|
|
|
|
if (tx_slot_mgmnt->number_tx_in_use > 0)
|
|
{
|
|
NdisMSetTimer(&ndisAdap->CompletionTimer, 20);
|
|
}
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
| Function - MPSafeStartTx
|
|
|
|
|
| Paramters - ptr -> Pointer to an MPSAFE_INFO structure.
|
|
|
|
|
| Purpose - Set up a tx slot and start the transmit going. This
|
|
| function is called via NdisSynchronizeWithInterrupt when
|
|
| in PIO mode so that we don't get SIF register contention
|
|
| on a multiprocessor.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
MPSafeStartTx(PVOID ptr)
|
|
{
|
|
MPSAFE_INFO * info = (MPSAFE_INFO *) ptr;
|
|
|
|
//
|
|
// Reset the transmit status in the transmit slot.
|
|
//
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->tx_slot_ptr)->tx_status
|
|
);
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat,
|
|
0x8000
|
|
);
|
|
|
|
//
|
|
// Write in the length of the buffer into the transmit slot
|
|
// (large buffer).
|
|
//
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->tx_slot_ptr)->large_buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat,
|
|
(WORD) info->frame_length
|
|
);
|
|
|
|
//
|
|
// Write the length of the small buffer in the transmit slot to
|
|
// start the transmit going.
|
|
//
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->tx_slot_ptr)->small_buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat,
|
|
FMPLUS_SBUFF_ZERO_LENGTH
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_transmit_frame
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
* tx_frame_identifier -> NDIS packet handle or a pointer
|
|
* to some data to send.
|
|
* tx_frame_length -> Length of the frame.
|
|
* tx_is_packet -> TRUE if tx_frame_identifier is
|
|
* an NDIS packet handle.
|
|
*
|
|
* Purpose - Attempts to transmit a frame by copying it into a transmit
|
|
* buffer and activating a FastMAC Plus tx slot.
|
|
*
|
|
* Returns - DRIVER_TRANSMIT_SUCCESS if it succeeds or
|
|
* DRIVER_TRANSMIT_FAILURE if it does not.
|
|
*
|
|
****************************************************************************/
|
|
|
|
WORD
|
|
rxtx_transmit_frame(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
DWORD tx_frame_identifier,
|
|
WORD tx_frame_length,
|
|
WORD tx_is_packet
|
|
)
|
|
{
|
|
ADAPTER * adapter;
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
PTX_SLOT_CACHE tx_slot_cache;
|
|
TX_SLOT * tx_slot_ptr;
|
|
UINT active_tx_slot;
|
|
UINT tx_slots;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
UINT bytes_copied;
|
|
UINT tx_status;
|
|
MPSAFE_INFO info;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter = adapter_record[adapter_handle];
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
tx_slot_cache = tx_slot_mgmnt->tx_slot_cache;
|
|
active_tx_slot = tx_slot_mgmnt->active_tx_slot;
|
|
tx_slot_ptr = adapter->tx_slot_array[active_tx_slot];
|
|
tx_slots = adapter->init_block->fastmac_parms.tx_slots;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
|
|
//
|
|
// If we are a PCMCIA adapter it is possible that the adapter
|
|
// may have been removed. To detect this we check if SIFADR
|
|
// is 0xffff since this should not normally be true.
|
|
//
|
|
|
|
if (adapter->adapter_card_bus_type == ADAPTER_CARD_PCMCIA_BUS_TYPE)
|
|
{
|
|
if (sys_insw(adapter_handle, sifadr) == 0xffff)
|
|
{
|
|
rxtx_adapter_removed(adapter_handle);
|
|
|
|
return DRIVER_TRANSMIT_SUCCEED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If the next slot to be used is still in use then we must
|
|
// give up.
|
|
//
|
|
|
|
if (tx_slot_mgmnt->number_tx_in_use == tx_slots)
|
|
{
|
|
|
|
#ifdef OID_MADGE_MONITOR
|
|
(ndisAdap->MonitorInfo).FailedToTransmit++;
|
|
#endif
|
|
|
|
return DRIVER_TRANSMIT_FAIL;
|
|
}
|
|
|
|
//
|
|
// Copy the frame into the transmit buffer.
|
|
//
|
|
|
|
if (tx_is_packet)
|
|
{
|
|
MadgeCopyFromPacketToBuffer(
|
|
(PNDIS_PACKET) tx_frame_identifier,
|
|
0,
|
|
tx_frame_length,
|
|
(PUCHAR) tx_slot_cache[active_tx_slot].VirtualAddress,
|
|
&bytes_copied
|
|
);
|
|
}
|
|
else
|
|
{
|
|
MADGE_MOVE_MEMORY(
|
|
tx_slot_cache[active_tx_slot].VirtualAddress,
|
|
(PUCHAR) tx_frame_identifier,
|
|
tx_frame_length
|
|
);
|
|
}
|
|
|
|
//
|
|
// Set up the tx slot and start the transmit. If we're using
|
|
// multiprocessor safe PIO then we must do the DIO via an ISR
|
|
// synchronised function.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.adapter_handle = adapter_handle;
|
|
info.adapter = adapter;
|
|
info.tx_slot_ptr = tx_slot_ptr;
|
|
info.frame_length = tx_frame_length;
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeStartTx,
|
|
&info
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Reset the transmit status in the transmit slot.
|
|
//
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_ptr->tx_status
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
(WORD) 0x8000
|
|
);
|
|
|
|
//
|
|
// Write in the length of the buffer into the transmit slot
|
|
// (large buffer).
|
|
//
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_ptr->large_buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
(WORD) tx_frame_length
|
|
);
|
|
|
|
//
|
|
// Write the length of the small buffer in the transmit slot to
|
|
// start the transmit going.
|
|
//
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_ptr->small_buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
FMPLUS_SBUFF_ZERO_LENGTH
|
|
);
|
|
}
|
|
|
|
//
|
|
// Note that the slot is in use.
|
|
//
|
|
|
|
tx_slot_mgmnt->number_tx_in_use++;
|
|
|
|
//
|
|
// Update the slot counter ready for the next transmit.
|
|
//
|
|
|
|
if (++tx_slot_mgmnt->active_tx_slot == tx_slots)
|
|
{
|
|
tx_slot_mgmnt->active_tx_slot = 0;
|
|
}
|
|
|
|
return DRIVER_TRANSMIT_SUCCEED;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
| Function - ProcessTestAndXIDFrames
|
|
|
|
|
| Paramters - adapHnd -> An FTK adapter handle.
|
|
| framePtr -> Pointer to the start of the frame.
|
|
| frameLen -> The length of the frame.
|
|
| headerLen -> The length of the frame header.
|
|
|
|
|
| Purpose - Process LLC Test and XID frames in the same way as IBM
|
|
| adapter hardware.
|
|
|
|
|
| Returns - TRUE if the frame was processed or FALSE if not.
|
|
|
|
|
|-------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
ProcessTestAndXIDFrames(
|
|
ADAPTER_HANDLE adapHnd,
|
|
UCHAR *framePtr,
|
|
UINT frameLen,
|
|
UINT headerLen
|
|
)
|
|
{
|
|
UINT llcCmd;
|
|
UINT sSAP;
|
|
NODE_ADDRESS tempNodeAddr;
|
|
BOOLEAN doneFrame;
|
|
|
|
doneFrame = FALSE;
|
|
|
|
//
|
|
// We are only interested in frames that are LLC (i.e. frame
|
|
// control byte is 0x40), have a null destination SAP and are
|
|
// commands (i.e. 0x01 bit of the source SAP is clear).
|
|
//
|
|
|
|
sSAP = framePtr[headerLen + 1];
|
|
|
|
if (framePtr[1] == 0x40 &&
|
|
framePtr[headerLen] == 0x00 &&
|
|
(sSAP & 0x01) == 0x00)
|
|
{
|
|
llcCmd = framePtr[headerLen + 2] & 0xef;
|
|
|
|
//
|
|
// Test frames have an LLC command byte of 0b111x0011.
|
|
//
|
|
|
|
if (llcCmd == 0xe3)
|
|
{
|
|
MadgePrint1("Got TEST frame\n");
|
|
|
|
//
|
|
// We don't need to do anything to a test frame
|
|
// other than send it back.
|
|
//
|
|
|
|
doneFrame = TRUE;
|
|
}
|
|
|
|
//
|
|
// XID frames have an LLC command byte of 0b101x1111 and
|
|
// a standard IEEE defined XID frame will have 3 data
|
|
// bytes and its first data byte set to 0x81.
|
|
//
|
|
|
|
else if (llcCmd == 0xaf &&
|
|
frameLen == headerLen + 6 &&
|
|
framePtr[headerLen + 3] == 0x81)
|
|
{
|
|
MadgePrint1("Got XID frame\n");
|
|
|
|
//
|
|
// Fill in the XID frame data with 0x81 0x01 0x00
|
|
// (Standard XID frame, type 1 only and 0 sized
|
|
// receive window).
|
|
//
|
|
|
|
framePtr[headerLen + 4] = 0x01;
|
|
framePtr[headerLen + 5] = 0x00;
|
|
|
|
doneFrame = TRUE;
|
|
}
|
|
|
|
//
|
|
// If we've had a TEST or a XID frame then doneFrame will
|
|
// be TRUE and we should send a frame back.
|
|
//
|
|
|
|
if (doneFrame)
|
|
{
|
|
//
|
|
// Flip the direction bit in the source routing
|
|
// control word and switch the source routing flag
|
|
// from the source to destination address.
|
|
//
|
|
|
|
if ((framePtr[8] & 0x80) != 0)
|
|
{
|
|
framePtr[14] &= 0x1f; // Clear broadcast bits.
|
|
framePtr[15] ^= 0x80; // Flip direction bit.
|
|
framePtr[8] &= 0x7f; // Clear source routing bit.
|
|
framePtr[2] |= 0x80; // Set source routing bit.
|
|
}
|
|
|
|
//
|
|
// Swap the node addresses around.
|
|
//
|
|
|
|
tempNodeAddr = *((NODE_ADDRESS *) &framePtr[2]);
|
|
*((NODE_ADDRESS *) &framePtr[2]) = *((NODE_ADDRESS *) &framePtr[8]);
|
|
*((NODE_ADDRESS *) &framePtr[8]) = tempNodeAddr;
|
|
|
|
//
|
|
// Swap the SAPs around and set the response bit in the
|
|
// new source SAP.
|
|
//
|
|
|
|
framePtr[headerLen + 1] = 0x01;
|
|
framePtr[headerLen] = sSAP;
|
|
framePtr[0] = 0x10;
|
|
|
|
//
|
|
// And now send the frame.
|
|
//
|
|
|
|
rxtx_transmit_frame(
|
|
adapHnd,
|
|
(DWORD) framePtr,
|
|
(WORD) frameLen,
|
|
FALSE
|
|
);
|
|
}
|
|
}
|
|
|
|
return doneFrame;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
| Function - MPSafeReadRxStatus
|
|
|
|
|
| Paramters - ptr -> Pointer to an MPSAFE_INFO structure.
|
|
|
|
|
| Purpose - Read the status and length of the current rx slot. This
|
|
| function is called via NdisSynchronizeWithInterrupt when
|
|
| in PIO mode so that we don't get SIF register contention
|
|
| on a multiprocessor.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
MPSafeReadRxStatus(PVOID ptr)
|
|
{
|
|
MPSAFE_INFO * info = (MPSAFE_INFO *) ptr;
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->rx_slot_ptr)->buffer_len
|
|
);
|
|
|
|
info->result1 = sys_insw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat
|
|
);
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->rx_slot_ptr)->rx_status
|
|
);
|
|
|
|
info->result2 = sys_insw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
| Function - MPSafeFreeRxSlot
|
|
|
|
|
| Paramters - ptr -> Pointer to an MPSAFE_INFO structure.
|
|
|
|
|
| Purpose - Free an rx slot. This
|
|
| function is called via NdisSynchronizeWithInterrupt when
|
|
| in PIO mode so that we don't get SIF register contention
|
|
| on a multiprocessor.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
MPSafeFreeRxSlot(PVOID ptr)
|
|
{
|
|
MPSAFE_INFO * info = (MPSAFE_INFO *) ptr;
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_adr,
|
|
(WORD) (card_t) &(info->rx_slot_ptr)->buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
info->adapter_handle,
|
|
info->adapter->sif_dat,
|
|
(WORD) 0x0000
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_irq_rx_frame_handler
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
* adapter -> Pointer to an FTK adapter structure.
|
|
*
|
|
* Purpose - Called out of the back or our DPR route via
|
|
* driver_get_outstanding_receive() to process received
|
|
* frames.
|
|
*
|
|
* Note we preserve the value of SIFADR so that the transmit
|
|
* code does not have to worry about it changing under its
|
|
* feet. No we don't because we are called out of a DPR
|
|
* and the wrapper will have grabbed a spin lock so
|
|
* we can't be executing at the same time as the transmit
|
|
* code.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define PROM_OR_MAC \
|
|
(NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_MAC_FRAME)
|
|
|
|
void
|
|
rxtx_irq_rx_frame_handler(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
ADAPTER * adapter
|
|
)
|
|
{
|
|
BYTE * rx_frame_addr;
|
|
UINT rx_frame_stat;
|
|
UINT rx_frame_length;
|
|
UINT slot_count;
|
|
UINT active_rx_slot;
|
|
PRX_SLOT_MGMNT rx_slot_mgmnt;
|
|
PRX_SLOT_CACHE rx_slot_cache;
|
|
RX_SLOT * * rx_slot_array;
|
|
RX_SLOT * rx_slot_ptr;
|
|
UINT rx_slots;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
UINT packet_filter;
|
|
UINT header_len;
|
|
BOOLEAN done_frame;
|
|
BOOLEAN ignore_frame;
|
|
BOOLEAN test_and_xid;
|
|
MPSAFE_INFO info;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
rx_slot_array = adapter->rx_slot_array;
|
|
rx_slot_mgmnt = (PRX_SLOT_MGMNT) adapter->rx_slot_mgmnt;
|
|
active_rx_slot = rx_slot_mgmnt->active_rx_slot;
|
|
rx_slot_cache = rx_slot_mgmnt->rx_slot_cache;
|
|
rx_slots = adapter->init_block->fastmac_parms.rx_slots;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
packet_filter = ndisAdap->CurrentPacketFilter;
|
|
test_and_xid = ndisAdap->TestAndXIDEnabled;
|
|
done_frame = FALSE;
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
|
|
//
|
|
// If we're doing multiprocessor safe PIO then we need to set up
|
|
// the info structure.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.adapter_handle = adapter_handle;
|
|
info.adapter = adapter;
|
|
}
|
|
|
|
//
|
|
// Now read the length and status fields of the current receive slot.
|
|
// If we are doing multiprocessor safe PIO then we must do the DIO via
|
|
// an ISR synchronised function.
|
|
//
|
|
|
|
rx_slot_ptr = rx_slot_array[active_rx_slot];
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.rx_slot_ptr = rx_slot_ptr;
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeReadRxStatus,
|
|
&info
|
|
);
|
|
|
|
rx_frame_length = info.result1;
|
|
rx_frame_stat = info.result2;
|
|
}
|
|
else
|
|
{
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_ptr->buffer_len
|
|
);
|
|
|
|
rx_frame_length = sys_insw(
|
|
adapter_handle,
|
|
sifdat
|
|
);
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_ptr->rx_status
|
|
);
|
|
|
|
rx_frame_stat = sys_insw(
|
|
adapter_handle,
|
|
sifdat
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Try to receive as many frames as possible, but only examine as many
|
|
// slots as we have, otherwise we might end up going round this loop
|
|
// forever! If we do stop and there is still a frame to be received, we
|
|
// will be re-interrupted anyway.
|
|
//
|
|
|
|
slot_count = 0;
|
|
|
|
while (rx_frame_length != 0 && slot_count++ < rx_slots)
|
|
{
|
|
//
|
|
// It is possible that a PCMCIA adapter may have been removed
|
|
// in which case we must not wait forever. If an adapter has
|
|
// been removed we would expect to read 0xffff from any IO
|
|
// location occupied by the adapter. 0xffff is not a valid
|
|
// value for an FMP RX status.
|
|
//
|
|
|
|
if (rx_frame_stat == 0xffff)
|
|
{
|
|
MadgePrint1("Rx frame: RX status == 0xffff\n");
|
|
ndisAdap->AdapterRemoved = TRUE;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// FastMAC Plus includes the CRC in the frame length.
|
|
//
|
|
|
|
rx_frame_length -= 4;
|
|
|
|
if ((rx_frame_stat & GOOD_RX_FRAME_MASK) == 0)
|
|
{
|
|
//
|
|
// We have got a good frame here.
|
|
//
|
|
|
|
rx_frame_addr = rx_slot_cache[active_rx_slot].VirtualAddress;
|
|
|
|
header_len = (FRAME_IS_SOURCE_ROUTED(rx_frame_addr))
|
|
? FRAME_HEADER_SIZE + FRAME_SOURCE_ROUTING_BYTES(rx_frame_addr)
|
|
: FRAME_HEADER_SIZE;
|
|
|
|
//
|
|
// Check for a frame copied error.
|
|
//
|
|
|
|
if ((rx_frame_addr[2] & 0x80) && (rx_frame_stat & 0x80))
|
|
{
|
|
ndisAdap->FrameCopiedErrors++;
|
|
}
|
|
|
|
//
|
|
// We may have to behave like the hardware of an IBM adapter
|
|
// and process LLC TEST and XID frames ourselves.
|
|
//
|
|
|
|
if (test_and_xid)
|
|
{
|
|
ignore_frame = ProcessTestAndXIDFrames(
|
|
adapter_handle,
|
|
rx_frame_addr,
|
|
rx_frame_length,
|
|
header_len
|
|
);
|
|
}
|
|
else
|
|
{
|
|
ignore_frame = FALSE;
|
|
}
|
|
|
|
//
|
|
// If we've got a valid frame then pass it up to the user.
|
|
//
|
|
|
|
if (!ignore_frame &&
|
|
((rx_frame_addr[1] & FRAME_TYPE_MASK) != FRAME_TYPE_MAC ||
|
|
(packet_filter & PROM_OR_MAC) != 0))
|
|
{
|
|
//
|
|
// When indicating the frame, we can pass all of it
|
|
// as lookahead if we want, but we ought to take
|
|
// account of the current lookahead setting in case it
|
|
// is less than the frame size. This becomes important in
|
|
// WFWG, where it is unable to cope with large lookaheads. The
|
|
// lookahead length used to be :
|
|
// (UINT) rx_frame_length - header_len
|
|
//
|
|
|
|
NdisMTrIndicateReceive(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
(NDIS_HANDLE) (rx_frame_addr + header_len),
|
|
(PVOID) rx_frame_addr,
|
|
(UINT) header_len,
|
|
(PVOID) (rx_frame_addr + header_len),
|
|
(UINT) MIN(
|
|
ndisAdap->CurrentLookahead,
|
|
(rx_frame_length - header_len)
|
|
),
|
|
(UINT) (rx_frame_length - header_len)
|
|
);
|
|
|
|
//
|
|
// Note that we've given the upper protocol at
|
|
// least one frame.
|
|
//
|
|
|
|
done_frame = TRUE;
|
|
|
|
ndisAdap->FramesReceived++;
|
|
|
|
#ifdef OID_MADGE_MONITOR
|
|
//
|
|
// Update the appropriate parts of the monitor structure
|
|
//
|
|
(ndisAdap->MonitorInfo).ReceiveFrames++;
|
|
(ndisAdap->MonitorInfo).ReceiveFrameSize[rx_frame_length/128]++;
|
|
(ndisAdap->MonitorInfo).CurrentFrameSize = rx_frame_length;
|
|
(ndisAdap->MonitorInfo).ReceiveFlag = 1;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//
|
|
// Otherwise we have some sort of receive error.
|
|
//
|
|
|
|
else
|
|
{
|
|
ndisAdap->FrameReceiveErrors++;
|
|
}
|
|
|
|
//
|
|
// Zero the frame length so that FastMAC Plus can reuse the buffer.
|
|
// If we're doing multiprocessor safe PIO then we must do the DIO
|
|
// via an ISR synchronised function.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.rx_slot_ptr = rx_slot_ptr;
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeFreeRxSlot,
|
|
&info
|
|
);
|
|
}
|
|
else
|
|
{
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_ptr->buffer_len
|
|
);
|
|
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifdat,
|
|
0x0000
|
|
);
|
|
}
|
|
|
|
//
|
|
// Update the active receive slot pointer.
|
|
//
|
|
|
|
if (++active_rx_slot == rx_slots)
|
|
{
|
|
active_rx_slot = 0;
|
|
}
|
|
|
|
rx_slot_mgmnt->active_rx_slot = active_rx_slot;
|
|
|
|
//
|
|
// Now we had better look at the next slot in case another frame
|
|
// has been received.
|
|
//
|
|
|
|
rx_slot_ptr = rx_slot_array[active_rx_slot];
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.rx_slot_ptr = rx_slot_ptr;
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeReadRxStatus,
|
|
&info
|
|
);
|
|
|
|
rx_frame_length = info.result1;
|
|
rx_frame_stat = info.result2;
|
|
}
|
|
else
|
|
{
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_ptr->buffer_len
|
|
);
|
|
|
|
rx_frame_length = sys_insw(
|
|
adapter_handle,
|
|
sifdat
|
|
);
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &rx_slot_ptr->rx_status
|
|
);
|
|
|
|
rx_frame_stat = sys_insw(
|
|
adapter_handle,
|
|
sifdat
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we've given the upper protocol a frame then call the
|
|
// receive completion routine.
|
|
//
|
|
|
|
if (done_frame)
|
|
{
|
|
NdisMTrIndicateReceiveComplete(ndisAdap->UsedInISR.MiniportHandle);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_abort_txing_frames
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Stop sending frames.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_abort_txing_frames(ADAPTER_HANDLE adapter_handle)
|
|
{
|
|
//
|
|
// Nothing to do here.
|
|
//
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_await_empty_tx_slots
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Wait until all of the tx slots are empty.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_await_empty_tx_slots(ADAPTER_HANDLE adapter_handle)
|
|
{
|
|
ADAPTER * adapter;
|
|
FASTMAC_INIT_PARMS * fastmac_parms;
|
|
TX_SLOT * * tx_slot_array;
|
|
UINT i;
|
|
UINT status;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
MPSAFE_INFO info;
|
|
WORD sifadr;
|
|
WORD sifdat;
|
|
|
|
if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_ANY_STATE))
|
|
{
|
|
MadgePrint1("rxtx_await_empty_tx_slots: adapter not running\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter = adapter_record[adapter_handle];
|
|
fastmac_parms = &adapter->init_block->fastmac_parms;
|
|
tx_slot_array = adapter->tx_slot_array;
|
|
info.adapter_handle = adapter_handle;
|
|
info.adapter = adapter;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
sifadr = adapter->sif_adr;
|
|
sifdat = adapter->sif_dat;
|
|
|
|
for (i = 0; i < fastmac_parms->tx_slots; i++)
|
|
{
|
|
do
|
|
{
|
|
//
|
|
// Get the slot status. If we are doing multiprocessor safe
|
|
// PIO then we must do this with an ISR synchronised function.
|
|
//
|
|
|
|
if (ndisAdap->UseMPSafePIO)
|
|
{
|
|
info.tx_slot_ptr = tx_slot_array[i];
|
|
|
|
NdisMSynchronizeWithInterrupt(
|
|
&ndisAdap->Interrupt,
|
|
MPSafeReadTxStatus,
|
|
&info
|
|
);
|
|
|
|
status = info.result1;
|
|
}
|
|
else
|
|
{
|
|
sys_outsw(
|
|
adapter_handle,
|
|
sifadr,
|
|
(WORD) (card_t) &tx_slot_array[i]->tx_status
|
|
);
|
|
|
|
status = sys_insw(adapter_handle, sifdat);
|
|
}
|
|
|
|
//
|
|
// It is possible that a PCMCIA adapter may have been removed
|
|
// in which case we must not wait forever. If an adapter has
|
|
// been removed we would expect to read 0xffff from any IO
|
|
// location occupied by the adapter. 0xffff is not a valid
|
|
// value for an FMP TX status.
|
|
//
|
|
|
|
if (status == 0xffff)
|
|
{
|
|
MadgePrint1("Await empty tx: TX status == 0xffff\n");
|
|
return;
|
|
}
|
|
}
|
|
while (status >= 0x8000 || status == 0);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - user_completed_srb
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
* srb_completed_successfully -> SRB successful?
|
|
*
|
|
* Purpose - Record that an SRB has completed and arrange for our
|
|
* DPR to be scheduled.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
user_completed_srb(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
WBOOLEAN srb_completed_successfully
|
|
)
|
|
{
|
|
PMADGE_ADAPTER ndisAdap;
|
|
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
//
|
|
// If we have issued a private SRB then we just clear the
|
|
// private SRB flag. Otherwise we need to arrange for our
|
|
// DPR to be told about the SRB.
|
|
//
|
|
|
|
if (ndisAdap->PrivateSrbInProgress)
|
|
{
|
|
ndisAdap->PrivateSrbInProgress = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ndisAdap->UsedInISR.SrbRequestStatus = (BOOLEAN) srb_completed_successfully;
|
|
ndisAdap->UsedInISR.SrbRequestCompleted = TRUE;
|
|
ndisAdap->DprRequired = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - user_shedule_receive_process
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Arrange for our DPR to be scheduled so that we can deal
|
|
* with received frames.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
void
|
|
user_schedule_receive_process(ADAPTER_HANDLE adapter_handle)
|
|
{
|
|
PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle)->DprRequired = TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - user_adapter_removed
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Arrange for our DPR to be scheduled so that we can deal
|
|
* with a removed adapter.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
void
|
|
user_adapter_removed(ADAPTER_HANDLE adapter_handle)
|
|
{
|
|
PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle)->DprRequired = TRUE;
|
|
PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle)->AdapterRemoved = TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - user_handle_adapter_check
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Called on an adapter check. Not a lot we can do really!
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
void
|
|
user_handle_adapter_check(ADAPTER_HANDLE adapter_handle)
|
|
{
|
|
MadgePrint1("Adapter Check!!!!\n");
|
|
}
|
|
|
|
|
|
//
|
|
// Currently we are not supporting transmit modes that require
|
|
// user completion routine.
|
|
//
|
|
|
|
#if 0
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - user_transmit_completion
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
* identifier -> NDIS packet handle.
|
|
*
|
|
* Purpose - To notify an upper protocol that a transmit has completed.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
void
|
|
user_transmit_completion(
|
|
ADAPTER_HANDLE adapter_handle,
|
|
DWORD identifier
|
|
)
|
|
{
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - rxtx_adapter_removed
|
|
*
|
|
* Parameters - adapter_handle -> FTK adapter handle.
|
|
*
|
|
* Purpose - Called to tidy up when we find out that the adapter has
|
|
* been removed. All we do is tell the wrapper that we
|
|
* have finished any submitted transmits.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
rxtx_adapter_removed(
|
|
ADAPTER_HANDLE adapter_handle
|
|
)
|
|
{
|
|
ADAPTER * adapter;
|
|
PTX_SLOT_MGMNT tx_slot_mgmnt;
|
|
UINT tx_slots;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
|
|
//
|
|
// Pre-calculate some commonly used values.
|
|
//
|
|
|
|
adapter = adapter_record[adapter_handle];
|
|
tx_slot_mgmnt = (PTX_SLOT_MGMNT) adapter->tx_slot_mgmnt;
|
|
tx_slots = adapter->init_block->fastmac_parms.tx_slots;
|
|
ndisAdap = PMADGE_ADAPTER_FROM_ADAPTER_HANDLE(adapter_handle);
|
|
|
|
//
|
|
// Note that the adapter has been removed.
|
|
//
|
|
|
|
ndisAdap->AdapterRemoved = TRUE;
|
|
|
|
//
|
|
// Iterate around the transmit slots that are in use and
|
|
// up call to indicate that the transmits are over.
|
|
//
|
|
|
|
while (tx_slot_mgmnt->number_tx_in_use > 0)
|
|
{
|
|
//
|
|
// Update the slot usage.
|
|
//
|
|
|
|
tx_slot_mgmnt->number_tx_in_use--;
|
|
|
|
if (++tx_slot_mgmnt->first_tx_in_use == tx_slots)
|
|
{
|
|
tx_slot_mgmnt->first_tx_in_use = 0;
|
|
}
|
|
|
|
//
|
|
// Tell the wrapper that there is a free slot.
|
|
//
|
|
|
|
NdisMSendResourcesAvailable(ndisAdap->UsedInISR.MiniportHandle);
|
|
}
|
|
}
|
|
|
|
|
|
/******** End of FTK_USER.C ***********************************************/
|
|
|