📄 dec21143.c
字号:
/* */
/* NU_SUCCESS is returned if no errors occur, otherwise -1 is returned. */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Uriah T. Pollock 01/12/99 Created initial version 1.0 */
/* */
/****************************************************************************/
STATUS DEC21143_Open (UINT8 *ether_addr, DV_DEVICE_ENTRY *device)
{
NET_BUFFER *setup_frame;
STATUS ret_status;
VOID *pointer;
UINT8 eeprom_data[128];
UINT8 x;
UINT32 csr6_val;
DEC21143_XDATA *dec_data;
VOID (*DEC21143_old_vect_routine)(INT);
static INT open_count = 0;
/* Point at the DEC21143 xtended data. */
dec_data = (DEC21143_XDATA *)device->user_defined_1;
/* Collect some SNMP data */
SNMP_ifDescr(device->dev_index, "DEC21143 Ethernet: Software revision 1.0");
SNMP_ifType(device->dev_index, 6);
SNMP_ifMtu(device->dev_index, device->dev_mtu);
/* First thing, find the card and store off its PCI ID. */
dec_data->DEC21143_PCI_ID = DEC21143_Find_PCI_ID (open_count);
/* Make sure the card was found. */
if (dec_data->DEC21143_PCI_ID == DEC21143_INVALID_ID)
{
/* Log the error and get out. */
NU_Tcp_Log_Error (DRV_RESOURCE_ALLOCATION_ERROR, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
/* Read the chip revision. Step 2.A */
dec_data->DEC21143_Revision =
DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CFRV);
/* Read the interrupt line that will be use by this card. Step 2.B */
device->dev_irq = (CFIT_GET_INTERRUPT_LINE &
DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CFIT));
/* Associate the device with a vector number. Compute the vector based
on the IRQ line read from the chip. */
#ifdef PROTECTED_MODE
if (device->dev_irq < 8)
device->dev_vect = 0x78 + device->dev_irq;
else
device->dev_vect = 0x70 + (device->dev_irq - 8);
#else
switch(device -> dev_irq)
{
case 3:
device->dev_vect = IRQ_3_VECTOR;
break;
case 4:
device->dev_vect = IRQ_4_VECTOR;
break;
case 5:
device->dev_vect = IRQ_5_VECTOR;
break;
case 9:
device->dev_vect = IRQ_9_VECTOR;
break;
case 10:
device->dev_vect = IRQ_10_VECTOR;
break;
case 11:
device->dev_vect = IRQ_11_VECTOR;
break;
case 12:
device->dev_vect = IRQ_12_VECTOR;
break;
case 15:
device->dev_vect = IRQ_15_VECTOR;
break;
default:
return(-1);
}
#endif /* defined PROTECTED_MODE */
/* read old, load new */
NU_Register_LISR (device->dev_vect, DEC21143_LISR,
&DEC21143_old_vect_routine);
/* The HISR can be shared by all DEC21143 devices. So only create one. */
if (open_count++ == 0)
{
#ifdef PROTECTED_MODE
/* Install LISRs to handle the 77 and 7f interrupts. These
occur during high traffic. All the LISR does is reset the
interrupt. */
NU_Register_LISR(IRQ_15_VECTOR, Unknown_Int_LISR, &DEC21143_old_vect_routine);
NU_Register_LISR(UNKNOWN_INT, Unknown_Int_LISR, &DEC21143_old_vect_routine);
#endif
/* create the HISR for handling the interrupt from the Ethernet card */
ret_status = NU_Allocate_Memory (&System_Memory, &pointer, 2000,
NU_NO_SUSPEND);
if (ret_status != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = normalize_ptr(pointer);
ret_status = NU_Create_HISR (&DEC21143_RX_HISR_CB, "ETHER_RX",
DEC21143_RX_HISR,
0, pointer, 2000);
if (ret_status != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
/* create the HISR for transmitting packets */
if (NU_Allocate_Memory (&System_Memory, &pointer, 2000,
NU_NO_SUSPEND) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = normalize_ptr(pointer);
if (NU_Create_HISR (&DEC21143_TX_HISR_CB, "ETHER_TX",
DEC21143_TX_HISR, 0, pointer, 2000) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
/* create the HISR for renegotiating the link */
if (NU_Allocate_Memory (&System_Memory, &pointer, 2000,
NU_NO_SUSPEND) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = normalize_ptr(pointer);
if (NU_Create_HISR (&DEC21143_Negotiate_Link_HISR_CB, "ETHER_NL",
DEC21143_Negotiate_Link_HISR, 0, pointer, 2000) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
}
/* Now get the base IO address, be sure to clear bit 0, this is not
part of the address. Step 2.C */
device->dev_io_addr = DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CBIO);
DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CBIO, device->dev_io_addr);
device->dev_io_addr &= ~0x00000003;
/* Read in the entire EEPROM */
for (x = 0; x < (sizeof (eeprom_data) / 2); x++)
((UINT16 *)eeprom_data) [x] = DEC21143_Read_EEPROM
(device->dev_io_addr, x);
/* Get the physical address from the EEPROM data just read in
and store it in the device structure. */
DEC21143_Get_Address(eeprom_data, ether_addr);
/* Disable all interrupts from the DEC chip. */
OUTDW (device->dev_io_addr + CSR7, CLEAR_ALL);
/* Select the port before chip reset */
/* Read the register. */
csr6_val = INDW (device->dev_io_addr + CSR6);
/* Turn off the transmitter and receiver and port select. */
csr6_val &= ~(CSR6_START_TX | CSR6_START_RX | CSR6_PORT_SELECT);
/* Write it to the register. */
OUTDW (device->dev_io_addr + CSR6, csr6_val);
/* Software reset of the chip, this does not reset the port
select done above. */
OUTDW (device->dev_io_addr + CSR0, CLEAR_ALL);
DEC21143_Delay();
OUTDW (device->dev_io_addr + CSR0, CSR0_SOFTWARE_RESET);
DEC21143_Delay();
OUTDW (device->dev_io_addr + CSR0, CLEAR_ALL);
DEC21143_Delay();
/* Now make sure there aren't any other bits set that we do not want. */
csr6_val = INDW (device->dev_io_addr + CSR6);
csr6_val &= (~(CSR6_PASS_BAD_FRAMES | CSR6_PASS_ALL_MULTICAST |
CSR6_FORCE_COLLISION_MODE | CSR6_IGNORE_DST_ADDRESS_MSB |
CSR6_RX_ALL | CSR6_TX_THRESHOLD_MODE |
CSR6_PROMISCUOUS_MODE));
/* Write it to the register. */
OUTDW (device->dev_io_addr + CSR6, csr6_val);
/* After the reset wake the chip up. */
DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFDD, CLEAR_ALL);
/* Set the chip to accept register accesses and to have the ability
to take master operation of the PCI bus. Step 2.D */
DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFCS,
(CFCS_IO_SPACE_ACCESS |
CFCS_MASTER_OPERATION |
CFCS_PARITY_ERROR_RESPONSE));
/* Set the cache line size to zero and the latency timer to max,
0xFF. Step 2.E */
DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFLT, CFLT_INITIALIZE);
/* Set the cache alignment and burst length and reset all other
bits. Step 3 */
OUTDW (device->dev_io_addr + CSR0, (CSR0_CACHE_ALIGNMENT_16 |
CSR0_BURST_LENGTH_16));
/* Turn on the interrupts that we want to handle and mask those
that we don't. Step 4*/
OUTDW (device->dev_io_addr + CSR7, DEC21143_INTERRUPTS);
/* Initialize the RX buffer descriptor and set its base address.
Step 5 */
dec_data->DEC21143_First_RX_Descriptor =
dec_data->DEC21143_Current_RX_Descriptor =
DEC21143_Allocate_Descriptor (DEC21143_MAX_RX_DESCRIPTORS,
&System_Memory,
NU_TRUE);
/* Make sure the allocation worked. */
if (dec_data->DEC21143_First_RX_Descriptor)
/* Store the base address. */
OUTDW (device->dev_io_addr + CSR3, (UINT32) (dec_data->DEC21143_First_RX_Descriptor));
else
{
/* Log the error and get out. */
NU_Tcp_Log_Error (DRV_RESOURCE_ALLOCATION_ERROR, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -