Added a driver for the Broadcom 570x (aka Tigon 3), version 7.3.5, using the SubIncludeGPL rule.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9129 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
45418db003
commit
d4010e5eae
@ -8,4 +8,5 @@ SubInclude OBOS_TOP src add-ons kernel drivers network via-rhine ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers network rtl8169 ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers network ipro1000 ;
|
||||
|
||||
SubIncludeGPL OBOS_TOP src add-ons kernel drivers network bcm440x ;
|
||||
SubIncludeGPL OBOS_TOP src add-ons kernel drivers network bcm440x ;
|
||||
SubIncludeGPL OBOS_TOP src add-ons kernel drivers network bcm570x ;
|
42
src/add-ons/kernel/drivers/network/bcm570x/Jamfile
Normal file
42
src/add-ons/kernel/drivers/network/bcm570x/Jamfile
Normal file
@ -0,0 +1,42 @@
|
||||
SubDir OBOS_TOP src add-ons kernel drivers network bcm570x ;
|
||||
|
||||
SubDirCcFlags -w -DINCLUDE_TBI_SUPPORT=1 ;
|
||||
|
||||
# For ether_driver.h
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
R5KernelAddon bcm570x : kernel drivers bin :
|
||||
autoneg.c
|
||||
b57um.c
|
||||
tigon3.c
|
||||
mempool.c
|
||||
;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
bcm570x :
|
||||
boot home config add-ons kernel drivers bin ;
|
||||
Package haiku-networkingkit-cvs :
|
||||
<kernel!drivers!dev!net>bcm570x :
|
||||
boot home config add-ons kernel drivers dev net ;
|
||||
|
||||
# Link driver(s) to kernel/drivers/dev/net
|
||||
{
|
||||
local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev net ] ;
|
||||
|
||||
local instDriver = <kernel!drivers!dev!net>bcm570x ;
|
||||
MakeLocate $(instDriver) : $(dir) ;
|
||||
RelSymLink $(instDriver) : bcm570x ;
|
||||
}
|
||||
|
||||
|
||||
# Installation
|
||||
|
||||
OBOSInstall install-networking : /boot/home/config/add-ons/kernel/drivers/bin :
|
||||
bcm570x
|
||||
;
|
||||
|
||||
OBOSInstallRelSymLink install-networking : /boot/home/config/add-ons/kernel/drivers/dev/net :
|
||||
<installed>bcm570x :
|
||||
installed-symlink
|
||||
;
|
||||
|
75
src/add-ons/kernel/drivers/network/bcm570x/README
Normal file
75
src/add-ons/kernel/drivers/network/bcm570x/README
Normal file
@ -0,0 +1,75 @@
|
||||
Broadcom 570x Gigabit Ethernet Driver
|
||||
|
||||
Copyright 2004 Nathan Whitehorn, portions copyright 2000-2004 Broadcom Corporation
|
||||
|
||||
To install, double-click the file appropriately named "Double Click to Install". You must be running BONE, which is included with Zeta.
|
||||
|
||||
The driver is based on version 7.3.5 of the Linux driver provided by Broadcom corporation, which can be obtained from their website, and is licensed under the GNU General Public License, which can be obtained from the Free Software Foundation.
|
||||
|
||||
Questions and support requests should be directed to me at nathanw@uchicago.edu
|
||||
|
||||
Many thanks to Broadcom for not being nVidia, and not only publishing source to their driver, but making it quite portable, even if the source was almost uncommented. Thanks as well to Stephen Flood, for allowing me to abuse his laptop in porting the Broadcom 440x driver, which conveniently uses the same OS-abstraction layer as the 570x one.
|
||||
|
||||
Please note also that the listed support for the 3c940 applies only to certain 3c940 cards that are actually rebranded Tigon 3 chips. Support for the other varieties of 3c940 can be obtained from http://www.bebits.com/app/3886.
|
||||
|
||||
This driver should be compatible with the following network interface cards:
|
||||
Broadcom BCM5700 1000Base-T
|
||||
Broadcom BCM5700 1000Base-SX
|
||||
Broadcom BCM5700 1000Base-SX
|
||||
Broadcom BCM5700 1000Base-T
|
||||
Broadcom BCM5700
|
||||
Broadcom BCM5701 1000Base-T
|
||||
Broadcom BCM5701 1000Base-T
|
||||
Broadcom BCM5701 1000Base-T
|
||||
Broadcom BCM5701 1000Base-SX
|
||||
Broadcom BCM5701 1000Base-T
|
||||
Broadcom BCM5701 1000Base-T
|
||||
Broadcom BCM5701
|
||||
Broadcom BCM5702 1000Base-T
|
||||
Broadcom BCM5703 1000Base-T
|
||||
Broadcom BCM5703 1000Base-SX
|
||||
Broadcom B5703 1000Base-SX
|
||||
3Com 3C996 10/100/1000 Server NIC
|
||||
3Com 3C996 10/100/1000 Server NIC
|
||||
3Com 3C996 Gigabit Fiber-SX Server NIC
|
||||
3Com 3C996 Gigabit Fiber-SX Server NIC
|
||||
3Com 3C996B Gigabit Server NIC
|
||||
3Com 3C997 Gigabit Server NIC
|
||||
3Com 3C997 Gigabit Fiber-SX Server NIC
|
||||
3Com 3C1000 Gigabit NIC
|
||||
3Com 3C1000B-T 10/100/1000 PCI
|
||||
3Com 3C940 Gigabit LOM (21X21)
|
||||
3Com 3C942 Gigabit LOM (31X31)
|
||||
3Com 3C998-T Dual Port 10/100/1000 PCI-X Server NIC
|
||||
3Com 3C998-SX Dual Port 1000-SX PCI-X Server NIC
|
||||
3Com 3C999-T Quad Port 10/100/1000 PCI-X Server NIC
|
||||
HP NC6770 Gigabit Server Adapter
|
||||
NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
|
||||
HP ProLiant NC 150T PCI 4-port Gigabit Combo Switch Adapter
|
||||
HP NC7760 Gigabit Server Adapter
|
||||
HP NC7761 Gigabit Server Adapter
|
||||
HP NC7770 Gigabit Server Adapter
|
||||
HP NC7771 Gigabit Server Adapter
|
||||
HP NC7780 Gigabit Server Adapter
|
||||
HP NC7781 Gigabit Server Adapter
|
||||
HP NC7772 Gigabit Server Adapter
|
||||
HP NC7782 Gigabit Server Adapter
|
||||
HP NC7783 Gigabit Server Adapter
|
||||
HP ProLiant NC 320T PCI Express Gigabit Server Adapter
|
||||
Broadcom BCM5704 CIOB-E 1000Base-T
|
||||
Broadcom BCM5704 1000Base-T
|
||||
Broadcom BCM5704 1000Base-SX
|
||||
Broadcom BCM5705 1000Base-T
|
||||
Broadcom BCM5705M 1000Base-T
|
||||
Broadcom 570x 10/100 Integrated Controller
|
||||
Broadcom BCM5901 100Base-TX
|
||||
Broadcom NetXtreme Gigabit Ethernet for hp
|
||||
Broadcom BCM5788 NetLink 1000Base-T
|
||||
Broadcom BCM5789 NetLink 1000Base-T PCI Express
|
||||
Broadcom BCM5750 1000Base-T PCI
|
||||
Broadcom BCM5750M 1000Base-T PCI
|
||||
Broadcom BCM5720 1000Base-T PCI
|
||||
Broadcom BCM5751 1000Base-T PCI Express
|
||||
Broadcom BCM5751M 1000Base-T PCI Express
|
||||
Broadcom BCM5751F 100Base-TX PCI Express
|
||||
Broadcom BCM5721 1000Base-T PCI Express
|
438
src/add-ons/kernel/drivers/network/bcm570x/autoneg.c
Normal file
438
src/add-ons/kernel/drivers/network/bcm570x/autoneg.c
Normal file
@ -0,0 +1,438 @@
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom */
|
||||
/* Corporation. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation, located in the file LICENSE. */
|
||||
/* */
|
||||
/* History: */
|
||||
/******************************************************************************/
|
||||
|
||||
#if INCLUDE_TBI_SUPPORT
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
void
|
||||
MM_AnTxConfig(
|
||||
PAN_STATE_INFO pAnInfo)
|
||||
{
|
||||
PLM_DEVICE_BLOCK pDevice;
|
||||
|
||||
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
|
||||
|
||||
REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT);
|
||||
|
||||
pDevice->MacMode |= MAC_MODE_SEND_CONFIGS;
|
||||
REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
void
|
||||
MM_AnTxIdle(
|
||||
PAN_STATE_INFO pAnInfo)
|
||||
{
|
||||
PLM_DEVICE_BLOCK pDevice;
|
||||
|
||||
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
|
||||
|
||||
pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS;
|
||||
REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
char
|
||||
MM_AnRxConfig(
|
||||
PAN_STATE_INFO pAnInfo,
|
||||
unsigned short *pRxConfig)
|
||||
{
|
||||
PLM_DEVICE_BLOCK pDevice;
|
||||
LM_UINT32 Value32;
|
||||
char Retcode;
|
||||
|
||||
Retcode = AN_FALSE;
|
||||
|
||||
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
|
||||
|
||||
Value32 = REG_RD(pDevice, MacCtrl.Status);
|
||||
if(Value32 & MAC_STATUS_RECEIVING_CFG)
|
||||
{
|
||||
Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg);
|
||||
*pRxConfig = (unsigned short) Value32;
|
||||
|
||||
Retcode = AN_TRUE;
|
||||
}
|
||||
|
||||
return Retcode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
void
|
||||
AutonegInit(
|
||||
PAN_STATE_INFO pAnInfo)
|
||||
{
|
||||
unsigned long j;
|
||||
|
||||
for(j = 0; j < sizeof(AN_STATE_INFO); j++)
|
||||
{
|
||||
((unsigned char *) pAnInfo)[j] = 0;
|
||||
}
|
||||
|
||||
/* Initialize the default advertisement register. */
|
||||
pAnInfo->mr_adv_full_duplex = 1;
|
||||
pAnInfo->mr_adv_sym_pause = 1;
|
||||
pAnInfo->mr_adv_asym_pause = 1;
|
||||
pAnInfo->mr_an_enable = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
AUTONEG_STATUS
|
||||
Autoneg8023z(
|
||||
PAN_STATE_INFO pAnInfo)
|
||||
{
|
||||
unsigned short RxConfig;
|
||||
unsigned long Delta_us;
|
||||
AUTONEG_STATUS AnRet;
|
||||
|
||||
/* Get the current time. */
|
||||
if(pAnInfo->State == AN_STATE_UNKNOWN)
|
||||
{
|
||||
pAnInfo->RxConfig.AsUSHORT = 0;
|
||||
pAnInfo->CurrentTime_us = 0;
|
||||
pAnInfo->LinkTime_us = 0;
|
||||
pAnInfo->AbilityMatchCfg = 0;
|
||||
pAnInfo->AbilityMatchCnt = 0;
|
||||
pAnInfo->AbilityMatch = AN_FALSE;
|
||||
pAnInfo->IdleMatch = AN_FALSE;
|
||||
pAnInfo->AckMatch = AN_FALSE;
|
||||
}
|
||||
|
||||
/* Increment the timer tick. This function is called every microsecon. */
|
||||
// pAnInfo->CurrentTime_us++;
|
||||
|
||||
/* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */
|
||||
/* corresponding conditions are satisfied. */
|
||||
if(MM_AnRxConfig(pAnInfo, &RxConfig))
|
||||
{
|
||||
if(RxConfig != pAnInfo->AbilityMatchCfg)
|
||||
{
|
||||
pAnInfo->AbilityMatchCfg = RxConfig;
|
||||
pAnInfo->AbilityMatch = AN_FALSE;
|
||||
pAnInfo->AbilityMatchCnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pAnInfo->AbilityMatchCnt++;
|
||||
if(pAnInfo->AbilityMatchCnt > 1)
|
||||
{
|
||||
pAnInfo->AbilityMatch = AN_TRUE;
|
||||
pAnInfo->AbilityMatchCfg = RxConfig;
|
||||
}
|
||||
}
|
||||
|
||||
if(RxConfig & AN_CONFIG_ACK)
|
||||
{
|
||||
pAnInfo->AckMatch = AN_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pAnInfo->AckMatch = AN_FALSE;
|
||||
}
|
||||
|
||||
pAnInfo->IdleMatch = AN_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pAnInfo->IdleMatch = AN_TRUE;
|
||||
|
||||
pAnInfo->AbilityMatchCfg = 0;
|
||||
pAnInfo->AbilityMatchCnt = 0;
|
||||
pAnInfo->AbilityMatch = AN_FALSE;
|
||||
pAnInfo->AckMatch = AN_FALSE;
|
||||
|
||||
RxConfig = 0;
|
||||
}
|
||||
|
||||
/* Save the last Config. */
|
||||
pAnInfo->RxConfig.AsUSHORT = RxConfig;
|
||||
|
||||
/* Default return code. */
|
||||
AnRet = AUTONEG_STATUS_OK;
|
||||
|
||||
/* Autoneg state machine as defined in 802.3z section 37.3.1.5. */
|
||||
switch(pAnInfo->State)
|
||||
{
|
||||
case AN_STATE_UNKNOWN:
|
||||
if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an)
|
||||
{
|
||||
pAnInfo->CurrentTime_us = 0;
|
||||
pAnInfo->State = AN_STATE_AN_ENABLE;
|
||||
}
|
||||
|
||||
/* Fall through.*/
|
||||
|
||||
case AN_STATE_AN_ENABLE:
|
||||
pAnInfo->mr_an_complete = AN_FALSE;
|
||||
pAnInfo->mr_page_rx = AN_FALSE;
|
||||
|
||||
if(pAnInfo->mr_an_enable)
|
||||
{
|
||||
pAnInfo->LinkTime_us = 0;
|
||||
pAnInfo->AbilityMatchCfg = 0;
|
||||
pAnInfo->AbilityMatchCnt = 0;
|
||||
pAnInfo->AbilityMatch = AN_FALSE;
|
||||
pAnInfo->IdleMatch = AN_FALSE;
|
||||
pAnInfo->AckMatch = AN_FALSE;
|
||||
|
||||
pAnInfo->State = AN_STATE_AN_RESTART_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pAnInfo->State = AN_STATE_DISABLE_LINK_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case AN_STATE_AN_RESTART_INIT:
|
||||
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
|
||||
pAnInfo->mr_np_loaded = AN_FALSE;
|
||||
|
||||
pAnInfo->TxConfig.AsUSHORT = 0;
|
||||
MM_AnTxConfig(pAnInfo);
|
||||
|
||||
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
|
||||
|
||||
pAnInfo->State = AN_STATE_AN_RESTART;
|
||||
|
||||
/* Fall through.*/
|
||||
|
||||
case AN_STATE_AN_RESTART:
|
||||
/* Get the current time and compute the delta with the saved */
|
||||
/* link timer. */
|
||||
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
|
||||
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case AN_STATE_DISABLE_LINK_OK:
|
||||
AnRet = AUTONEG_STATUS_DONE;
|
||||
break;
|
||||
|
||||
case AN_STATE_ABILITY_DETECT_INIT:
|
||||
/* Note: in the state diagram, this variable is set to */
|
||||
/* mr_adv_ability<12>. Is this right?. */
|
||||
pAnInfo->mr_toggle_tx = AN_FALSE;
|
||||
|
||||
/* Send the config as advertised in the advertisement register. */
|
||||
pAnInfo->TxConfig.AsUSHORT = 0;
|
||||
pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex;
|
||||
pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex;
|
||||
pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause;
|
||||
pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause;
|
||||
pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1;
|
||||
pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2;
|
||||
pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page;
|
||||
|
||||
MM_AnTxConfig(pAnInfo);
|
||||
|
||||
pAnInfo->State = AN_STATE_ABILITY_DETECT;
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_ABILITY_DETECT:
|
||||
if(pAnInfo->AbilityMatch == AN_TRUE &&
|
||||
pAnInfo->RxConfig.AsUSHORT != 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_ACK_DETECT_INIT;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_ACK_DETECT_INIT:
|
||||
pAnInfo->TxConfig.D14_ACK = 1;
|
||||
MM_AnTxConfig(pAnInfo);
|
||||
|
||||
pAnInfo->State = AN_STATE_ACK_DETECT;
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
case AN_STATE_ACK_DETECT:
|
||||
if(pAnInfo->AckMatch == AN_TRUE)
|
||||
{
|
||||
if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) ==
|
||||
(pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK))
|
||||
{
|
||||
pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pAnInfo->State = AN_STATE_AN_ENABLE;
|
||||
}
|
||||
}
|
||||
else if(pAnInfo->AbilityMatch == AN_TRUE &&
|
||||
pAnInfo->RxConfig.AsUSHORT == 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_AN_ENABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_COMPLETE_ACK_INIT:
|
||||
/* Make sure invalid bits are not set. */
|
||||
if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 ||
|
||||
pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 ||
|
||||
pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 ||
|
||||
pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11)
|
||||
{
|
||||
AnRet = AUTONEG_STATUS_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up the link partner advertisement register. */
|
||||
pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD;
|
||||
pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD;
|
||||
pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1;
|
||||
pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2;
|
||||
pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1;
|
||||
pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2;
|
||||
pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP;
|
||||
|
||||
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
|
||||
|
||||
pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx;
|
||||
pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11;
|
||||
pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP;
|
||||
pAnInfo->mr_page_rx = AN_TRUE;
|
||||
|
||||
pAnInfo->State = AN_STATE_COMPLETE_ACK;
|
||||
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_COMPLETE_ACK:
|
||||
if(pAnInfo->AbilityMatch == AN_TRUE &&
|
||||
pAnInfo->RxConfig.AsUSHORT == 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_AN_ENABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
|
||||
|
||||
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
|
||||
{
|
||||
if(pAnInfo->mr_adv_next_page == 0 ||
|
||||
pAnInfo->mr_lp_adv_next_page == 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pAnInfo->TxConfig.bits.D15 == 0 &&
|
||||
pAnInfo->mr_np_rx == 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnRet = AUTONEG_STATUS_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_IDLE_DETECT_INIT:
|
||||
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
|
||||
|
||||
MM_AnTxIdle(pAnInfo);
|
||||
|
||||
pAnInfo->State = AN_STATE_IDLE_DETECT;
|
||||
|
||||
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_IDLE_DETECT:
|
||||
if(pAnInfo->AbilityMatch == AN_TRUE &&
|
||||
pAnInfo->RxConfig.AsUSHORT == 0)
|
||||
{
|
||||
pAnInfo->State = AN_STATE_AN_ENABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
|
||||
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
|
||||
{
|
||||
// if(pAnInfo->IdleMatch == AN_TRUE)
|
||||
// {
|
||||
pAnInfo->State = AN_STATE_LINK_OK;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// AnRet = AUTONEG_STATUS_FAILED;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_LINK_OK:
|
||||
pAnInfo->mr_an_complete = AN_TRUE;
|
||||
pAnInfo->mr_link_ok = AN_TRUE;
|
||||
AnRet = AUTONEG_STATUS_DONE;
|
||||
|
||||
break;
|
||||
|
||||
case AN_STATE_NEXT_PAGE_WAIT_INIT:
|
||||
break;
|
||||
|
||||
case AN_STATE_NEXT_PAGE_WAIT:
|
||||
break;
|
||||
|
||||
default:
|
||||
AnRet = AUTONEG_STATUS_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
return AnRet;
|
||||
}
|
||||
#endif /* INCLUDE_TBI_SUPPORT */
|
||||
|
418
src/add-ons/kernel/drivers/network/bcm570x/autoneg.h
Normal file
418
src/add-ons/kernel/drivers/network/bcm570x/autoneg.h
Normal file
@ -0,0 +1,418 @@
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom */
|
||||
/* Corporation. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation, located in the file LICENSE. */
|
||||
/* */
|
||||
/* History: */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
#ifndef AUTONEG_H
|
||||
#define AUTONEG_H
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Constants. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define AN_LINK_TIMER_INTERVAL_US 12000 /* 10ms */
|
||||
|
||||
/* TRUE, FALSE */
|
||||
#define AN_TRUE 1
|
||||
#define AN_FALSE 0
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Main data structure for keeping track of 802.3z auto-negotation state */
|
||||
/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Pointer to the operating system specific data structure. */
|
||||
void *pContext;
|
||||
|
||||
/* Current auto-negotiation state. */
|
||||
unsigned long State;
|
||||
#define AN_STATE_UNKNOWN 0
|
||||
#define AN_STATE_AN_ENABLE 1
|
||||
#define AN_STATE_AN_RESTART_INIT 2
|
||||
#define AN_STATE_AN_RESTART 3
|
||||
#define AN_STATE_DISABLE_LINK_OK 4
|
||||
#define AN_STATE_ABILITY_DETECT_INIT 5
|
||||
#define AN_STATE_ABILITY_DETECT 6
|
||||
#define AN_STATE_ACK_DETECT_INIT 7
|
||||
#define AN_STATE_ACK_DETECT 8
|
||||
#define AN_STATE_COMPLETE_ACK_INIT 9
|
||||
#define AN_STATE_COMPLETE_ACK 10
|
||||
#define AN_STATE_IDLE_DETECT_INIT 11
|
||||
#define AN_STATE_IDLE_DETECT 12
|
||||
#define AN_STATE_LINK_OK 13
|
||||
#define AN_STATE_NEXT_PAGE_WAIT_INIT 14
|
||||
#define AN_STATE_NEXT_PAGE_WAIT 16
|
||||
|
||||
/* Link timer. */
|
||||
unsigned long LinkTime_us;
|
||||
|
||||
/* Current time. */
|
||||
unsigned long CurrentTime_us;
|
||||
|
||||
/* Ability, idle, and ack match functions. */
|
||||
unsigned long AbilityMatchCnt;
|
||||
|
||||
/* Need these values for consistency check. */
|
||||
unsigned short AbilityMatchCfg;
|
||||
|
||||
unsigned short reserved;
|
||||
|
||||
char AbilityMatch;
|
||||
char IdleMatch;
|
||||
char AckMatch;
|
||||
char reserved1;
|
||||
|
||||
/* Tx config data */
|
||||
union
|
||||
{
|
||||
/* The TxConfig register is arranged as follows: */
|
||||
/* */
|
||||
/* MSB LSB */
|
||||
/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
|
||||
/* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8| */
|
||||
/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
|
||||
struct
|
||||
{
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
unsigned short D7:1; /* PS1 */
|
||||
unsigned short D6:1; /* HD */
|
||||
unsigned short D5:1; /* FD */
|
||||
unsigned short D4:1;
|
||||
unsigned short D3:1;
|
||||
unsigned short D2:1;
|
||||
unsigned short D1:1;
|
||||
unsigned short D0:1;
|
||||
unsigned short D15:1; /* NP */
|
||||
unsigned short D14:1; /* ACK */
|
||||
unsigned short D13:1; /* RF2 */
|
||||
unsigned short D12:1; /* RF1 */
|
||||
unsigned short D11:1;
|
||||
unsigned short D10:1;
|
||||
unsigned short D9:1;
|
||||
unsigned short D8:1; /* PS2 */
|
||||
#else /* BIG_ENDIAN_HOST */
|
||||
unsigned int D8:1; /* PS2 */
|
||||
unsigned int D9:1;
|
||||
unsigned int D10:1;
|
||||
unsigned int D11:1;
|
||||
unsigned int D12:1; /* RF1 */
|
||||
unsigned int D13:1; /* RF2 */
|
||||
unsigned int D14:1; /* ACK */
|
||||
unsigned int D15:1; /* NP */
|
||||
unsigned int D0:1;
|
||||
unsigned int D1:1;
|
||||
unsigned int D2:1;
|
||||
unsigned int D3:1;
|
||||
unsigned int D4:1;
|
||||
unsigned int D5:1; /* FD */
|
||||
unsigned int D6:1; /* HD */
|
||||
unsigned int D7:1; /* PS1 */
|
||||
#endif
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define D8_PS2 bits.D8
|
||||
#define D12_RF1 bits.D12
|
||||
#define D13_RF2 bits.D13
|
||||
#define D14_ACK bits.D14
|
||||
#define D15_NP bits.D15
|
||||
#define D5_FD bits.D5
|
||||
#define D6_HD bits.D6
|
||||
#define D7_PS1 bits.D7
|
||||
} TxConfig;
|
||||
|
||||
/* Rx config data */
|
||||
union
|
||||
{
|
||||
/* The RxConfig register is arranged as follows: */
|
||||
/* */
|
||||
/* MSB LSB */
|
||||
/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
|
||||
/* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8| */
|
||||
/* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
|
||||
struct
|
||||
{
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
unsigned short D7:1; /* PS1 */
|
||||
unsigned short D6:1; /* HD */
|
||||
unsigned short D5:1; /* FD */
|
||||
unsigned short D4:1;
|
||||
unsigned short D3:1;
|
||||
unsigned short D2:1;
|
||||
unsigned short D1:1;
|
||||
unsigned short D0:1;
|
||||
unsigned short D15:1; /* NP */
|
||||
unsigned short D14:1; /* ACK */
|
||||
unsigned short D13:1; /* RF2 */
|
||||
unsigned short D12:1; /* RF1 */
|
||||
unsigned short D11:1;
|
||||
unsigned short D10:1;
|
||||
unsigned short D9:1;
|
||||
unsigned short D8:1; /* PS2 */
|
||||
#else /* BIG_ENDIAN_HOST */
|
||||
unsigned int D8:1; /* PS2 */
|
||||
unsigned int D9:1;
|
||||
unsigned int D10:1;
|
||||
unsigned int D11:1;
|
||||
unsigned int D12:1; /* RF1 */
|
||||
unsigned int D13:1; /* RF2 */
|
||||
unsigned int D14:1; /* ACK */
|
||||
unsigned int D15:1; /* NP */
|
||||
unsigned int D0:1;
|
||||
unsigned int D1:1;
|
||||
unsigned int D2:1;
|
||||
unsigned int D3:1;
|
||||
unsigned int D4:1;
|
||||
unsigned int D5:1; /* FD */
|
||||
unsigned int D6:1; /* HD */
|
||||
unsigned int D7:1; /* PS1 */
|
||||
#endif
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
} RxConfig;
|
||||
|
||||
#define AN_CONFIG_NP 0x0080
|
||||
#define AN_CONFIG_ACK 0x0040
|
||||
#define AN_CONFIG_RF2 0x0020
|
||||
#define AN_CONFIG_RF1 0x0010
|
||||
#define AN_CONFIG_PS2 0x0001
|
||||
#define AN_CONFIG_PS1 0x8000
|
||||
#define AN_CONFIG_HD 0x4000
|
||||
#define AN_CONFIG_FD 0x2000
|
||||
|
||||
|
||||
/* Management registers. */
|
||||
|
||||
/* Control register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int an_enable:1;
|
||||
unsigned int loopback:1;
|
||||
unsigned int reset:1;
|
||||
unsigned int restart_an:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_an_enable Mr0.bits.an_enable
|
||||
#define mr_loopback Mr0.bits.loopback
|
||||
#define mr_main_reset Mr0.bits.reset
|
||||
#define mr_restart_an Mr0.bits.restart_an
|
||||
} Mr0;
|
||||
|
||||
/* Status register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int an_complete:1;
|
||||
unsigned int link_ok:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_an_complete Mr1.bits.an_complete
|
||||
#define mr_link_ok Mr1.bits.link_ok
|
||||
} Mr1;
|
||||
|
||||
/* Advertisement register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int reserved_4:5;
|
||||
unsigned int full_duplex:1;
|
||||
unsigned int half_duplex:1;
|
||||
unsigned int sym_pause:1;
|
||||
unsigned int asym_pause:1;
|
||||
unsigned int reserved_11:3;
|
||||
unsigned int remote_fault1:1;
|
||||
unsigned int remote_fault2:1;
|
||||
unsigned int reserved_14:1;
|
||||
unsigned int next_page:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_adv_full_duplex Mr4.bits.full_duplex
|
||||
#define mr_adv_half_duplex Mr4.bits.half_duplex
|
||||
#define mr_adv_sym_pause Mr4.bits.sym_pause
|
||||
#define mr_adv_asym_pause Mr4.bits.asym_pause
|
||||
#define mr_adv_remote_fault1 Mr4.bits.remote_fault1
|
||||
#define mr_adv_remote_fault2 Mr4.bits.remote_fault2
|
||||
#define mr_adv_next_page Mr4.bits.next_page
|
||||
} Mr4;
|
||||
|
||||
/* Link partner advertisement register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int reserved_4:5;
|
||||
unsigned int lp_full_duplex:1;
|
||||
unsigned int lp_half_duplex:1;
|
||||
unsigned int lp_sym_pause:1;
|
||||
unsigned int lp_asym_pause:1;
|
||||
unsigned int reserved_11:3;
|
||||
unsigned int lp_remote_fault1:1;
|
||||
unsigned int lp_remote_fault2:1;
|
||||
unsigned int lp_ack:1;
|
||||
unsigned int lp_next_page:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_lp_adv_full_duplex Mr5.bits.lp_full_duplex
|
||||
#define mr_lp_adv_half_duplex Mr5.bits.lp_half_duplex
|
||||
#define mr_lp_adv_sym_pause Mr5.bits.lp_sym_pause
|
||||
#define mr_lp_adv_asym_pause Mr5.bits.lp_asym_pause
|
||||
#define mr_lp_adv_remote_fault1 Mr5.bits.lp_remote_fault1
|
||||
#define mr_lp_adv_remote_fault2 Mr5.bits.lp_remote_fault2
|
||||
#define mr_lp_adv_next_page Mr5.bits.lp_next_page
|
||||
} Mr5;
|
||||
|
||||
/* Auto-negotiation expansion register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int reserved_0:1;
|
||||
unsigned int page_received:1;
|
||||
unsigned int next_pageable:1;
|
||||
unsigned int reserved_15:13;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
} Mr6;
|
||||
|
||||
/* Auto-negotiation next page transmit register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int code_field:11;
|
||||
unsigned int toggle:1;
|
||||
unsigned int ack2:1;
|
||||
unsigned int message_page:1;
|
||||
unsigned int reserved_14:1;
|
||||
unsigned int next_page:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_np_tx Mr7.AsUSHORT
|
||||
} Mr7;
|
||||
|
||||
/* Auto-negotiation link partner ability register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int code_field:11;
|
||||
unsigned int toggle:1;
|
||||
unsigned int ack2:1;
|
||||
unsigned int message_page:1;
|
||||
unsigned int ack:1;
|
||||
unsigned int next_page:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_lp_np_rx Mr8.AsUSHORT
|
||||
} Mr8;
|
||||
|
||||
/* Extended status register. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int reserved_11:12;
|
||||
unsigned int base1000_t_hd:1;
|
||||
unsigned int base1000_t_fd:1;
|
||||
unsigned int base1000_x_hd:1;
|
||||
unsigned int base1000_x_fd:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
} Mr15;
|
||||
|
||||
/* Miscellaneous state variables. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int toggle_tx:1;
|
||||
unsigned int toggle_rx:1;
|
||||
unsigned int np_rx:1;
|
||||
unsigned int page_rx:1;
|
||||
unsigned int np_loaded:1;
|
||||
} bits;
|
||||
|
||||
unsigned short AsUSHORT;
|
||||
|
||||
#define mr_toggle_tx MrMisc.bits.toggle_tx
|
||||
#define mr_toggle_rx MrMisc.bits.toggle_rx
|
||||
#define mr_np_rx MrMisc.bits.np_rx
|
||||
#define mr_page_rx MrMisc.bits.page_rx
|
||||
#define mr_np_loaded MrMisc.bits.np_loaded
|
||||
} MrMisc;
|
||||
|
||||
} AN_STATE_INFO, *PAN_STATE_INFO;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Return code of Autoneg8023z. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUTONEG_STATUS_OK = 0,
|
||||
AUTONEG_STATUS_DONE = 1,
|
||||
AUTONEG_STATUS_TIMER_ENABLED = 2,
|
||||
// AUTONEG_STATUS_FAILED = 0xffffffff,
|
||||
AUTONEG_STATUS_FAILED = 0xfffffff
|
||||
} AUTONEG_STATUS, *PAUTONEG_STATUS;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Function prototypes. */
|
||||
/******************************************************************************/
|
||||
|
||||
AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
|
||||
void AutonegInit(PAN_STATE_INFO pAnInfo);
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* The following functions are defined in the os-dependent module. */
|
||||
/******************************************************************************/
|
||||
|
||||
void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
|
||||
void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
|
||||
char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
|
||||
|
||||
|
||||
|
||||
#endif /* AUTONEG_H */
|
||||
|
841
src/add-ons/kernel/drivers/network/bcm570x/b57um.c
Normal file
841
src/add-ons/kernel/drivers/network/bcm570x/b57um.c
Normal file
@ -0,0 +1,841 @@
|
||||
#include <PCI.h>
|
||||
#include <Drivers.h>
|
||||
#include <malloc.h>
|
||||
#include <ether_driver.h>
|
||||
|
||||
#include "mm.h"
|
||||
#include "lm.h"
|
||||
#include "mempool.h"
|
||||
|
||||
struct pci_module_info *pci = NULL;
|
||||
|
||||
const char *dev_list[11];
|
||||
struct be_b57_dev be_b57_dev_cards[10];
|
||||
int cards_found = 0;
|
||||
|
||||
int b57_Packet_Desc_Size = sizeof(struct B_UM_PACKET);
|
||||
|
||||
#define ROUND_UP_TO_PAGE(size) ((size % 4096 != 0) ? 4096 - (size % 4096) + size : size)
|
||||
|
||||
struct pci_device_id {
|
||||
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
|
||||
unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
|
||||
unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
|
||||
unsigned long driver_data; /* Data private to the driver */
|
||||
};
|
||||
|
||||
#define PCI_ANY_ID 0
|
||||
|
||||
typedef enum {
|
||||
BCM5700A6 = 0,
|
||||
BCM5700T6,
|
||||
BCM5700A9,
|
||||
BCM5700T9,
|
||||
BCM5700,
|
||||
BCM5701A5,
|
||||
BCM5701T1,
|
||||
BCM5701T8,
|
||||
BCM5701A7,
|
||||
BCM5701A10,
|
||||
BCM5701A12,
|
||||
BCM5701,
|
||||
BCM5702,
|
||||
BCM5703,
|
||||
BCM5703A31,
|
||||
BCM5703ARBUCKLE,
|
||||
TC996T,
|
||||
TC996ST,
|
||||
TC996SSX,
|
||||
TC996SX,
|
||||
TC996BT,
|
||||
TC997T,
|
||||
TC997SX,
|
||||
TC1000T,
|
||||
TC1000BT,
|
||||
TC940BR01,
|
||||
TC942BR01,
|
||||
TC998T,
|
||||
TC998SX,
|
||||
TC999T,
|
||||
NC6770,
|
||||
NC1020,
|
||||
NC150T,
|
||||
NC7760,
|
||||
NC7761,
|
||||
NC7770,
|
||||
NC7771,
|
||||
NC7780,
|
||||
NC7781,
|
||||
NC7772,
|
||||
NC7782,
|
||||
NC7783,
|
||||
NC320T,
|
||||
BCM5704CIOBE,
|
||||
BCM5704,
|
||||
BCM5704S,
|
||||
BCM5705,
|
||||
BCM5705M,
|
||||
BCM5705F,
|
||||
BCM5901,
|
||||
BCM5782,
|
||||
BCM5788,
|
||||
BCM5789,
|
||||
BCM5750,
|
||||
BCM5750M,
|
||||
BCM5720,
|
||||
BCM5751,
|
||||
BCM5751M,
|
||||
BCM5751F,
|
||||
BCM5721,
|
||||
} board_t;
|
||||
|
||||
|
||||
/* indexed by board_t, above */
|
||||
static struct {
|
||||
char *name;
|
||||
} board_info[] = {
|
||||
{ "Broadcom BCM5700 1000Base-T" },
|
||||
{ "Broadcom BCM5700 1000Base-SX" },
|
||||
{ "Broadcom BCM5700 1000Base-SX" },
|
||||
{ "Broadcom BCM5700 1000Base-T" },
|
||||
{ "Broadcom BCM5700" },
|
||||
{ "Broadcom BCM5701 1000Base-T" },
|
||||
{ "Broadcom BCM5701 1000Base-T" },
|
||||
{ "Broadcom BCM5701 1000Base-T" },
|
||||
{ "Broadcom BCM5701 1000Base-SX" },
|
||||
{ "Broadcom BCM5701 1000Base-T" },
|
||||
{ "Broadcom BCM5701 1000Base-T" },
|
||||
{ "Broadcom BCM5701" },
|
||||
{ "Broadcom BCM5702 1000Base-T" },
|
||||
{ "Broadcom BCM5703 1000Base-T" },
|
||||
{ "Broadcom BCM5703 1000Base-SX" },
|
||||
{ "Broadcom B5703 1000Base-SX" },
|
||||
{ "3Com 3C996 10/100/1000 Server NIC" },
|
||||
{ "3Com 3C996 10/100/1000 Server NIC" },
|
||||
{ "3Com 3C996 Gigabit Fiber-SX Server NIC" },
|
||||
{ "3Com 3C996 Gigabit Fiber-SX Server NIC" },
|
||||
{ "3Com 3C996B Gigabit Server NIC" },
|
||||
{ "3Com 3C997 Gigabit Server NIC" },
|
||||
{ "3Com 3C997 Gigabit Fiber-SX Server NIC" },
|
||||
{ "3Com 3C1000 Gigabit NIC" },
|
||||
{ "3Com 3C1000B-T 10/100/1000 PCI" },
|
||||
{ "3Com 3C940 Gigabit LOM (21X21)" },
|
||||
{ "3Com 3C942 Gigabit LOM (31X31)" },
|
||||
{ "3Com 3C998-T Dual Port 10/100/1000 PCI-X Server NIC" },
|
||||
{ "3Com 3C998-SX Dual Port 1000-SX PCI-X Server NIC" },
|
||||
{ "3Com 3C999-T Quad Port 10/100/1000 PCI-X Server NIC" },
|
||||
{ "HP NC6770 Gigabit Server Adapter" },
|
||||
{ "NC1020 HP ProLiant Gigabit Server Adapter 32 PCI" },
|
||||
{ "HP ProLiant NC 150T PCI 4-port Gigabit Combo Switch Adapter" },
|
||||
{ "HP NC7760 Gigabit Server Adapter" },
|
||||
{ "HP NC7761 Gigabit Server Adapter" },
|
||||
{ "HP NC7770 Gigabit Server Adapter" },
|
||||
{ "HP NC7771 Gigabit Server Adapter" },
|
||||
{ "HP NC7780 Gigabit Server Adapter" },
|
||||
{ "HP NC7781 Gigabit Server Adapter" },
|
||||
{ "HP NC7772 Gigabit Server Adapter" },
|
||||
{ "HP NC7782 Gigabit Server Adapter" },
|
||||
{ "HP NC7783 Gigabit Server Adapter" },
|
||||
{ "HP ProLiant NC 320T PCI Express Gigabit Server Adapter" },
|
||||
{ "Broadcom BCM5704 CIOB-E 1000Base-T" },
|
||||
{ "Broadcom BCM5704 1000Base-T" },
|
||||
{ "Broadcom BCM5704 1000Base-SX" },
|
||||
{ "Broadcom BCM5705 1000Base-T" },
|
||||
{ "Broadcom BCM5705M 1000Base-T" },
|
||||
{ "Broadcom 570x 10/100 Integrated Controller" },
|
||||
{ "Broadcom BCM5901 100Base-TX" },
|
||||
{ "Broadcom NetXtreme Gigabit Ethernet for hp" },
|
||||
{ "Broadcom BCM5788 NetLink 1000Base-T" },
|
||||
{ "Broadcom BCM5789 NetLink 1000Base-T PCI Express" },
|
||||
{ "Broadcom BCM5750 1000Base-T PCI" },
|
||||
{ "Broadcom BCM5750M 1000Base-T PCI" },
|
||||
{ "Broadcom BCM5720 1000Base-T PCI" },
|
||||
{ "Broadcom BCM5751 1000Base-T PCI Express" },
|
||||
{ "Broadcom BCM5751M 1000Base-T PCI Express" },
|
||||
{ "Broadcom BCM5751F 100Base-TX PCI Express" },
|
||||
{ "Broadcom BCM5721 1000Base-T PCI Express" },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static struct pci_device_id bcm5700_pci_tbl[] = {
|
||||
{0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6 },
|
||||
{0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6 },
|
||||
{0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9 },
|
||||
{0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9 },
|
||||
{0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700 },
|
||||
{0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700 },
|
||||
{0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700 },
|
||||
{0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700 },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX },
|
||||
{0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01 },
|
||||
{0x14e4, 0x1644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5700 },
|
||||
{0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5 },
|
||||
{0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1 },
|
||||
{0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8 },
|
||||
{0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7 },
|
||||
{0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10 },
|
||||
{0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12 },
|
||||
{0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770 },
|
||||
{0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770 },
|
||||
{0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780 },
|
||||
{0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701 },
|
||||
{0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX },
|
||||
{0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT },
|
||||
{0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T },
|
||||
{0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01 },
|
||||
{0x14e4, 0x1645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5701 },
|
||||
{0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x1646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x16a6, 0x14e4, 0x000c, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760 },
|
||||
{0x14e4, 0x16a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x16c6, 0x10b7, 0x1100, 0, 0, TC1000BT },
|
||||
{0x14e4, 0x16c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
|
||||
{0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
|
||||
{0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x1647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
|
||||
{0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x16a7, 0x0e11, 0xca, 0, 0, NC7771 },
|
||||
{0x14e4, 0x16a7, 0x0e11, 0xcb, 0, 0, NC7781 },
|
||||
{0x14e4, 0x16a7, 0x1014, 0x0281, 0, 0, BCM5703ARBUCKLE },
|
||||
{0x14e4, 0x16a7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x16c7, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
|
||||
{0x14e4, 0x16c7, 0x0e11, 0xca, 0, 0, NC7771 },
|
||||
{0x14e4, 0x16c7, 0x0e11, 0xcb, 0, 0, NC7781 },
|
||||
{0x14e4, 0x16c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
|
||||
{0x14e4, 0x1648, 0x0e11, 0xcf, 0, 0, NC7772 },
|
||||
{0x14e4, 0x1648, 0x0e11, 0xd0, 0, 0, NC7782 },
|
||||
{0x14e4, 0x1648, 0x0e11, 0xd1, 0, 0, NC7783 },
|
||||
{0x14e4, 0x1648, 0x10b7, 0x2000, 0, 0, TC998T },
|
||||
{0x14e4, 0x1648, 0x10b7, 0x3000, 0, 0, TC999T },
|
||||
{0x14e4, 0x1648, 0x1166, 0x1648, 0, 0, BCM5704CIOBE },
|
||||
{0x14e4, 0x1648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704 },
|
||||
{0x14e4, 0x1649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704S },
|
||||
{0x14e4, 0x16a8, 0x14e4, 0x16a8, 0, 0, BCM5704S },
|
||||
{0x14e4, 0x16a8, 0x10b7, 0x2001, 0, 0, TC998SX },
|
||||
{0x14e4, 0x16a8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704S },
|
||||
{0x14e4, 0x1653, 0x0e11, 0x00e3, 0, 0, NC7761 },
|
||||
{0x14e4, 0x1653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705 },
|
||||
{0x14e4, 0x1654, 0x0e11, 0x00e3, 0, 0, NC7761 },
|
||||
{0x14e4, 0x1654, 0x103c, 0x3100, 0, 0, NC1020 },
|
||||
{0x14e4, 0x1654, 0x103c, 0x3226, 0, 0, NC150T },
|
||||
{0x14e4, 0x1654, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705 },
|
||||
{0x14e4, 0x165d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705M },
|
||||
{0x14e4, 0x165e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705M },
|
||||
{0x14e4, 0x166e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705F },
|
||||
{0x14e4, 0x1696, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5782 },
|
||||
{0x14e4, 0x169c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5788 },
|
||||
{0x14e4, 0x169d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5789 },
|
||||
{0x14e4, 0x170d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5901 },
|
||||
{0x14e4, 0x170e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5901 },
|
||||
{0x14e4, 0x1676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5750 },
|
||||
{0x14e4, 0x167c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5750M },
|
||||
{0x14e4, 0x1677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751 },
|
||||
{0x14e4, 0x167d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751M },
|
||||
{0x14e4, 0x167e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751F },
|
||||
{0x14e4, 0x1658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5720 },
|
||||
{0x14e4, 0x1659, 0x103c, 0x7031, 0, 0, NC320T },
|
||||
{0x14e4, 0x1659, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5721 },
|
||||
{0,}
|
||||
};
|
||||
|
||||
/* -------- BeOS Driver Hooks ------------ */
|
||||
|
||||
status_t b57_open(const char *name, uint32 flags, void **cookie);
|
||||
status_t b57_close(void *cookie);
|
||||
status_t b57_free(void *cookie);
|
||||
status_t b57_ioctl(void *cookie,uint32 op,void *data,size_t len);
|
||||
status_t b57_read(void *cookie,off_t pos,void *data,size_t *numBytes);
|
||||
status_t b57_write(void *cookie,off_t pos,const void *data,size_t *numBytes);
|
||||
int32 b57_interrupt(void *cookie);
|
||||
int32 tx_cleanup_thread(void *us);
|
||||
|
||||
device_hooks b57_hooks = {b57_open,b57_close,b57_free,b57_ioctl,b57_read,b57_write,NULL,NULL,NULL,NULL};
|
||||
|
||||
//int debug_fd;
|
||||
|
||||
status_t init_hardware(void) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
const char **publish_devices() {
|
||||
return dev_list;
|
||||
}
|
||||
|
||||
device_hooks *find_device(const char *name) {
|
||||
return &b57_hooks;
|
||||
}
|
||||
|
||||
status_t init_driver(void) {
|
||||
int i = 0, j = 0, is_detected;
|
||||
pci_info dev_info;
|
||||
|
||||
//debug_fd = open("/tmp/broadcom_traffic_log",O_RDWR | B_CREATE_FILE);
|
||||
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
while (pci->get_nth_pci_info(i++,&dev_info) == 0) {
|
||||
is_detected = 0;
|
||||
for (j = 0; bcm5700_pci_tbl[j].vendor != 0; j++) {
|
||||
if ((dev_info.class_base == PCI_network) && (dev_info.class_sub == PCI_ethernet)
|
||||
&& (dev_info.vendor_id == bcm5700_pci_tbl[j].vendor) && (dev_info.device_id == bcm5700_pci_tbl[j].device)) {
|
||||
is_detected = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_detected)
|
||||
continue;
|
||||
|
||||
if (cards_found >= 10)
|
||||
break;
|
||||
|
||||
dev_list[cards_found] = (char *)malloc(16 /* net/bcm570x/xx */);
|
||||
sprintf(dev_list[cards_found],"net/bcm570x/%d",cards_found);
|
||||
be_b57_dev_cards[cards_found].pci_data = dev_info;
|
||||
be_b57_dev_cards[cards_found].packet_release_sem = create_sem(0,dev_list[cards_found]);
|
||||
be_b57_dev_cards[cards_found].mem_list_num = 0;
|
||||
be_b57_dev_cards[cards_found].lockmem_list_num = 0;
|
||||
be_b57_dev_cards[cards_found].opened = 0;
|
||||
be_b57_dev_cards[cards_found].block = 1;
|
||||
be_b57_dev_cards[cards_found].lock = 0;
|
||||
|
||||
if (LM_GetAdapterInfo(&be_b57_dev_cards[cards_found].lm_dev) != LM_STATUS_SUCCESS)
|
||||
return ENODEV;
|
||||
|
||||
QQ_InitQueue(&be_b57_dev_cards[cards_found].RxPacketReadQ.Container,MAX_RX_PACKET_DESC_COUNT);
|
||||
|
||||
cards_found++;
|
||||
}
|
||||
|
||||
mempool_init((MAX_RX_PACKET_DESC_COUNT+10) * cards_found);
|
||||
|
||||
dev_list[cards_found] = NULL;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void uninit_driver(void) {
|
||||
int i,j;
|
||||
struct be_b57_dev *pUmDevice;
|
||||
|
||||
for (j = 0; j < cards_found; j++) {
|
||||
pUmDevice = &be_b57_dev_cards[j];
|
||||
for (i = 0; i < pUmDevice->mem_list_num; i++)
|
||||
free(pUmDevice->mem_list[i]);
|
||||
for (i = 0; i < pUmDevice->lockmem_list_num; i++)
|
||||
delete_area(pUmDevice->lockmem_list[i]);
|
||||
|
||||
delete_area(pUmDevice->mem_base);
|
||||
|
||||
free((void *)dev_list[j]);
|
||||
}
|
||||
|
||||
mempool_exit();
|
||||
}
|
||||
|
||||
status_t b57_open(const char *name, uint32 flags, void **cookie) {
|
||||
struct be_b57_dev *pDevice = NULL;
|
||||
int i;
|
||||
|
||||
*cookie = NULL;
|
||||
for (i = 0; i < cards_found; i++) {
|
||||
if (strcmp(dev_list[i],name) == 0) {
|
||||
*cookie = pDevice = &be_b57_dev_cards[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*cookie == NULL)
|
||||
return B_FILE_NOT_FOUND;
|
||||
|
||||
if (atomic_or(&pDevice->opened,1)) {
|
||||
*cookie = pDevice = NULL;
|
||||
return B_BUSY;
|
||||
}
|
||||
|
||||
install_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line,b57_interrupt,*cookie,0);
|
||||
if (LM_InitializeAdapter(&pDevice->lm_dev) != LM_STATUS_SUCCESS) {
|
||||
atomic_and(&pDevice->opened,0);
|
||||
remove_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line,b57_interrupt,*cookie);
|
||||
*cookie = NULL;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/*QQ_InitQueue(&pDevice->rx_out_of_buf_q.Container,
|
||||
MAX_RX_PACKET_DESC_COUNT);*/
|
||||
|
||||
//pDevice->lm_dev.PhyCrcCount = 0;
|
||||
LM_EnableInterrupt(&pDevice->lm_dev);
|
||||
|
||||
dprintf("Broadcom 57xx adapter successfully inited at %s:\n",name);
|
||||
dprintf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",pDevice->lm_dev.NodeAddress[0],pDevice->lm_dev.NodeAddress[1],pDevice->lm_dev.NodeAddress[2],pDevice->lm_dev.NodeAddress[3],pDevice->lm_dev.NodeAddress[4],pDevice->lm_dev.NodeAddress[5]);
|
||||
dprintf("PCI Data: 0x%08x\n",pDevice->pci_data.u.h0.base_registers[0]);
|
||||
dprintf("IRQ: %d\n",pDevice->pci_data.u.h0.interrupt_line);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_close(void *cookie) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(cookie);
|
||||
|
||||
if (cookie == NULL)
|
||||
return B_OK;
|
||||
|
||||
LM_DisableInterrupt(&pUmDevice->lm_dev);
|
||||
LM_Halt(&pUmDevice->lm_dev);
|
||||
pUmDevice->lm_dev.InitDone = 0;
|
||||
atomic_and(&pUmDevice->opened,0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_free(void *cookie) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(cookie);
|
||||
|
||||
if (cookie == NULL)
|
||||
return B_OK;
|
||||
|
||||
remove_io_interrupt_handler(pUmDevice->pci_data.u.h1.interrupt_line,b57_interrupt,cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_ioctl(void *cookie,uint32 op,void *data,size_t len) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(cookie);
|
||||
|
||||
switch (op) {
|
||||
case ETHER_INIT:
|
||||
return B_OK;
|
||||
case ETHER_GETADDR:
|
||||
if (data == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
memcpy(data,pUmDevice->lm_dev.NodeAddress,6);
|
||||
return B_OK;
|
||||
case ETHER_NONBLOCK:
|
||||
pUmDevice->block = *((uint8 *)(data));
|
||||
return B_OK;
|
||||
case ETHER_ADDMULTI:
|
||||
return (LM_MulticastAdd(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR;
|
||||
case ETHER_REMMULTI:
|
||||
return (LM_MulticastDel(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR;
|
||||
case ETHER_SETPROMISC:
|
||||
if (*((uint8 *)(data)))
|
||||
LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask | LM_PROMISCUOUS_MODE);
|
||||
else
|
||||
LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask & ~LM_PROMISCUOUS_MODE);
|
||||
return B_OK;
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 b57_interrupt(void *cookie) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)cookie;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
|
||||
unsigned int handled = 1;
|
||||
int i, max_intr_loop;
|
||||
LM_UINT32 oldtag, newtag;
|
||||
|
||||
if (!pDevice->InitDone)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
|
||||
if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED)
|
||||
{
|
||||
|
||||
max_intr_loop = 50;
|
||||
if (pDevice->Flags & USE_TAGGED_STATUS_FLAG) {
|
||||
MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
|
||||
oldtag = pDevice->pStatusBlkVirt->StatusTag;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
pDevice->pStatusBlkVirt->Status &=
|
||||
~STATUS_BLOCK_UPDATED;
|
||||
|
||||
LM_ServiceInterrupts(pDevice);
|
||||
newtag = pDevice->pStatusBlkVirt->StatusTag;
|
||||
if ((newtag == oldtag) || (i > max_intr_loop)) {
|
||||
MB_REG_WR(pDevice,
|
||||
Mailbox.Interrupt[0].Low,
|
||||
oldtag << 24);
|
||||
pDevice->LastTag = oldtag;
|
||||
if (pDevice->Flags & UNDI_FIX_FLAG) {
|
||||
REG_WR(pDevice, Grc.LocalCtrl,
|
||||
pDevice->GrcLocalCtrl | 0x2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
oldtag = newtag;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i = 0;
|
||||
do {
|
||||
uint dummy;
|
||||
|
||||
MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
|
||||
pDevice->pStatusBlkVirt->Status &=
|
||||
~STATUS_BLOCK_UPDATED;
|
||||
LM_ServiceInterrupts(pDevice);
|
||||
MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
|
||||
dummy = MB_REG_RD(pDevice,
|
||||
Mailbox.Interrupt[0].Low);
|
||||
i++;
|
||||
}
|
||||
while ((pDevice->pStatusBlkVirt->Status &
|
||||
STATUS_BLOCK_UPDATED) && (i < max_intr_loop));
|
||||
if (pDevice->Flags & UNDI_FIX_FLAG) {
|
||||
REG_WR(pDevice, Grc.LocalCtrl,
|
||||
pDevice->GrcLocalCtrl | 0x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
handled = 0;
|
||||
}
|
||||
if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container) ||
|
||||
pDevice->QueueAgain) {
|
||||
|
||||
LM_QueueRxPackets(pDevice);
|
||||
}
|
||||
|
||||
return handled ? B_INVOKE_SCHEDULER : B_UNHANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
status_t b57_read(void *cookie,off_t pos,void *data,size_t *numBytes) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)cookie;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
|
||||
PLM_PACKET pPacket;
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
cpu_status cpu;
|
||||
|
||||
if (pUmDevice->block)
|
||||
acquire_sem(pUmDevice->packet_release_sem);
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
pPacket = (PLM_PACKET)
|
||||
QQ_PopHead(&pUmDevice->RxPacketReadQ.Container);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
|
||||
if (pPacket == 0)
|
||||
return B_ERROR;
|
||||
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
if ((pPacket->PacketStatus != LM_STATUS_SUCCESS) ||
|
||||
((pPacket->PacketSize) > 1518)) {
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
*numBytes = -1;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if ((pPacket->PacketSize) < *numBytes)
|
||||
*numBytes = pPacket->PacketSize;
|
||||
|
||||
memcpy(data,pUmPacket->data,*numBytes);
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
|
||||
//write(debug_fd,"\n\nPacket follows\n",17);
|
||||
//write(debug_fd,data,*numBytes);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_write(void *cookie,off_t pos,const void *data,size_t *numBytes) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)cookie;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
|
||||
PLM_PACKET pPacket;
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
cpu_status cpu;
|
||||
//char debug[255];
|
||||
|
||||
/*if ((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) || !pDevice->InitDone)
|
||||
{
|
||||
return ENETDOWN;
|
||||
}*/
|
||||
|
||||
pPacket = (PLM_PACKET)
|
||||
QQ_PopHead(&pDevice->TxPacketFreeQ.Container);
|
||||
|
||||
if (pPacket == 0)
|
||||
return B_ERROR;
|
||||
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
pUmPacket->data = chunk_pool_get();
|
||||
|
||||
/*sprintf(debug,"Copy %d bytes of packet data (0x%08x->0x%08x (0x%08x - size %d))...",*numBytes,data,pPacket,pUmPacket->data,pUmPacket->size);
|
||||
kernel_debugger(debug);*/
|
||||
|
||||
memcpy(pUmPacket->data/*+pDevice->dataoffset*/,data,*numBytes); /* no guarantee data is contiguous, so we have to copy */
|
||||
pPacket->PacketSize = pUmPacket->size = *numBytes/*+pDevice->rxoffset*/;
|
||||
|
||||
pPacket->u.Tx.FragCount = 1;
|
||||
pPacket->Flags = 0;
|
||||
|
||||
//kernel_debugger("Sending packet...");
|
||||
|
||||
tx_cleanup_thread(pUmDevice);
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
LM_SendPacket(pDevice, pPacket);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
|
||||
//kernel_debugger("Packet sent!");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/* -------- Broadcom MM hooks ----------- */
|
||||
|
||||
LM_STATUS MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 *pValue16) {
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
*pValue16 = (LM_UINT16)pci->read_pci_config(((struct be_b57_dev *)(pDevice))->pci_data.bus,((struct be_b57_dev *)(pDevice))->pci_data.device,((struct be_b57_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16));
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 Value16) {
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
pci->write_pci_config(((struct be_b57_dev *)(pDevice))->pci_data.bus,((struct be_b57_dev *)(pDevice))->pci_data.device,((struct be_b57_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16),(uint32)Value16);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pValue32) {
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
*pValue32 = (LM_UINT32)pci->read_pci_config(((struct be_b57_dev *)(pDevice))->pci_data.bus,((struct be_b57_dev *)(pDevice))->pci_data.device,((struct be_b57_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32));
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 Value32){
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
pci->write_pci_config(((struct be_b57_dev *)(pDevice))->pci_data.bus,((struct be_b57_dev *)(pDevice))->pci_data.device,((struct be_b57_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32),(uint32)Value32);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_MapMemBase(PLM_DEVICE_BLOCK pDevice) {
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(pDevice);
|
||||
size_t size = pUmDevice->pci_data.u.h0.base_register_sizes[0];
|
||||
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
size = ROUND_UP_TO_PAGE(size);
|
||||
pUmDevice->mem_base = map_physical_memory("broadcom_regs",(void *)(pUmDevice->pci_data.u.h0.base_registers[0]),size,B_ANY_KERNEL_BLOCK_ADDRESS,B_READ_AREA | B_WRITE_AREA,(void **)(&pDevice->pMappedMemBase));
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*LM_STATUS MM_MapIoBase(PLM_DEVICE_BLOCK pDevice) {
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
pDevice->pMappedMemBase = pci->ram_address(((struct be_b57_dev *)(pDevice))->pci_data.memory_base);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}*/
|
||||
|
||||
LM_STATUS MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice) {
|
||||
struct be_b57_dev *dev = (struct be_b57_dev *)pDevice;
|
||||
PLM_PACKET pPacket;
|
||||
|
||||
while (1) {
|
||||
pPacket = (PLM_PACKET)
|
||||
QQ_PopHead(&pDevice->RxPacketReceivedQ.Container);
|
||||
if (pPacket == 0)
|
||||
break;
|
||||
|
||||
acquire_spinlock(&dev->lock);
|
||||
release_sem_etc(dev->packet_release_sem,1,B_DO_NOT_RESCHEDULE);
|
||||
release_spinlock(&dev->lock);
|
||||
QQ_PushTail(&dev->RxPacketReadQ.Container, pPacket);
|
||||
}
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice) {
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int32 tx_cleanup_thread(void *us) {
|
||||
PLM_PACKET pPacket;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK)(us);
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(us);
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
cpu_status cpu;
|
||||
|
||||
while (1) {
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
pPacket = (PLM_PACKET)
|
||||
QQ_PopHead(&pDevice->TxPacketXmittedQ.Container);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
if (pPacket == 0)
|
||||
break;
|
||||
pUmPacket = (struct B_UM_PACKET *)(pPacket);
|
||||
chunk_pool_put(pUmPacket->data);
|
||||
pUmPacket->data = NULL;
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
}
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*LM_STATUS MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);*/
|
||||
|
||||
LM_STATUS MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt) {
|
||||
struct be_b57_dev *dev = (struct be_b57_dev *)(pDevice);
|
||||
|
||||
if (dev->mem_list_num == 16)
|
||||
return LM_STATUS_FAILURE;
|
||||
|
||||
*pMemoryBlockVirt = dev->mem_list[(dev->mem_list_num)++] = (void *)malloc(BlockSize);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,LM_BOOL cached /* we ignore this */) {
|
||||
struct be_b57_dev *dev;
|
||||
void *pvirt = NULL;
|
||||
area_id area_desc;
|
||||
physical_entry entry;
|
||||
|
||||
dev = (struct be_b57_dev *)(pDevice);
|
||||
area_desc = dev->lockmem_list[dev->lockmem_list_num++] = create_area("broadcom_shared_mem",&pvirt,B_ANY_KERNEL_ADDRESS,ROUND_UP_TO_PAGE(BlockSize),/*B_CONTIGUOUS | B_FULL_LOCK*/ B_LOMEM,B_READ_AREA | B_WRITE_AREA);
|
||||
|
||||
if (pvirt == NULL)
|
||||
return LM_STATUS_FAILURE;
|
||||
|
||||
memset(pvirt, 0, BlockSize);
|
||||
*pMemoryBlockVirt = (PLM_VOID) pvirt;
|
||||
|
||||
get_memory_map(pvirt,BlockSize,&entry,1);
|
||||
pMemoryBlockPhy->Low = (uint32)(entry.address);
|
||||
pMemoryBlockPhy->High = 0; /* We only support 32 bit */
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_GetConfig(PLM_DEVICE_BLOCK pDevice){
|
||||
pDevice->DisableAutoNeg = FALSE;
|
||||
pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO;
|
||||
pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
|
||||
pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
|
||||
pDevice->RxPacketDescCnt = DEFAULT_RX_PACKET_DESC_COUNT;
|
||||
pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
|
||||
pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
|
||||
pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
|
||||
pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
|
||||
pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
|
||||
pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
|
||||
pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
|
||||
pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status) {
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS
|
||||
MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
int i;
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *) pDevice;
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
PLM_PACKET pPacket;
|
||||
|
||||
for (i = 0; i < pDevice->RxPacketDescCnt; i++) {
|
||||
pPacket = QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
pUmPacket->data = chunk_pool_get();
|
||||
if (pUmPacket->data == 0) {
|
||||
//QQ_PushTail(&pUmDevice->rx_out_of_buf_q.Container, pPacket);
|
||||
// No pretty rx_out_of_buf_q, but we sure as hell don't want anything to do with these packets, so we leak them.
|
||||
// Probably not the best idea, but it works.
|
||||
continue;
|
||||
}
|
||||
QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
|
||||
}
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket) {
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
struct be_b57_dev *pUmDevice = (struct be_b57_dev *) pDevice;
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
chunk_pool_put(pUmPacket->data);
|
||||
pUmPacket->data = NULL;
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
MM_UnmapRxDma(LM_DEVICE_BLOCK *pDevice, LM_PACKET *pPacket) {}
|
||||
|
||||
LM_STATUS
|
||||
MM_CoalesceTxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
|
||||
{return LM_STATUS_SUCCESS;} /* Our buffers are pre-coalesced (which slows things down a little) */
|
||||
|
||||
LM_DEVICE_BLOCK *
|
||||
MM_FindPeerDev(LM_DEVICE_BLOCK *pDevice)
|
||||
{return 0;} /* I have no idea what this routine does. I think it's optional... */
|
||||
|
||||
LM_STATUS
|
||||
MM_Sleep(LM_DEVICE_BLOCK *pDevice, LM_UINT32 msec)
|
||||
{
|
||||
snooze(msec*1e3);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
61
src/add-ons/kernel/drivers/network/bcm570x/bits.h
Normal file
61
src/add-ons/kernel/drivers/network/bcm570x/bits.h
Normal file
@ -0,0 +1,61 @@
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom */
|
||||
/* Corporation. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation, located in the file LICENSE. */
|
||||
/* */
|
||||
/* History: */
|
||||
/* 02/25/00 Hav Khauv Initial version. */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Bit Mask definitions */
|
||||
/******************************************************************************/
|
||||
|
||||
#define BIT_NONE 0x00
|
||||
#define BIT_0 0x01
|
||||
#define BIT_1 0x02
|
||||
#define BIT_2 0x04
|
||||
#define BIT_3 0x08
|
||||
#define BIT_4 0x10
|
||||
#define BIT_5 0x20
|
||||
#define BIT_6 0x40
|
||||
#define BIT_7 0x80
|
||||
#define BIT_8 0x0100
|
||||
#define BIT_9 0x0200
|
||||
#define BIT_10 0x0400
|
||||
#define BIT_11 0x0800
|
||||
#define BIT_12 0x1000
|
||||
#define BIT_13 0x2000
|
||||
#define BIT_14 0x4000
|
||||
#define BIT_15 0x8000
|
||||
#define BIT_16 0x010000
|
||||
#define BIT_17 0x020000
|
||||
#define BIT_18 0x040000
|
||||
#define BIT_19 0x080000
|
||||
#define BIT_20 0x100000
|
||||
#define BIT_21 0x200000
|
||||
#define BIT_22 0x400000
|
||||
#define BIT_23 0x800000
|
||||
#define BIT_24 0x01000000
|
||||
#define BIT_25 0x02000000
|
||||
#define BIT_26 0x04000000
|
||||
#define BIT_27 0x08000000
|
||||
#define BIT_28 0x10000000
|
||||
#define BIT_29 0x20000000
|
||||
#define BIT_30 0x40000000
|
||||
#define BIT_31 0x80000000
|
||||
|
||||
|
||||
|
||||
#endif /* BITS_H */
|
||||
|
466
src/add-ons/kernel/drivers/network/bcm570x/lm.h
Normal file
466
src/add-ons/kernel/drivers/network/bcm570x/lm.h
Normal file
@ -0,0 +1,466 @@
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom */
|
||||
/* Corporation. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation, located in the file LICENSE. */
|
||||
/* */
|
||||
/* History: */
|
||||
/* 02/25/00 Hav Khauv Initial version. */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef LM_H
|
||||
#define LM_H
|
||||
|
||||
#include "queue.h"
|
||||
#include "bits.h"
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Basic types. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef char LM_CHAR, *PLM_CHAR;
|
||||
typedef unsigned int LM_UINT, *PLM_UINT;
|
||||
typedef unsigned char LM_UINT8, *PLM_UINT8;
|
||||
typedef unsigned short LM_UINT16, *PLM_UINT16;
|
||||
typedef unsigned int LM_UINT32, *PLM_UINT32;
|
||||
typedef unsigned int LM_COUNTER, *PLM_COUNTER;
|
||||
typedef void LM_VOID, *PLM_VOID;
|
||||
typedef char LM_BOOL, *PLM_BOOL;
|
||||
|
||||
/* 64bit value. */
|
||||
typedef struct {
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
LM_UINT32 High;
|
||||
LM_UINT32 Low;
|
||||
#else /* BIG_ENDIAN_HOST */
|
||||
LM_UINT32 Low;
|
||||
LM_UINT32 High;
|
||||
#endif /* !BIG_ENDIAN_HOST */
|
||||
} LM_UINT64, *PLM_UINT64;
|
||||
|
||||
typedef LM_UINT64 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
|
||||
|
||||
/* void LM_INC_PHYSICAL_ADDRESS(PLM_PHYSICAL_ADDRESS pAddr,LM_UINT32 IncSize) */
|
||||
#define LM_INC_PHYSICAL_ADDRESS(pAddr, IncSize) \
|
||||
{ \
|
||||
LM_UINT32 OrgLow; \
|
||||
\
|
||||
OrgLow = (pAddr)->Low; \
|
||||
(pAddr)->Low += IncSize; \
|
||||
if((pAddr)->Low < OrgLow) { \
|
||||
(pAddr)->High++; /* Wrap around. */ \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif /* NULL */
|
||||
|
||||
#ifndef OFFSETOF
|
||||
#define OFFSETOF(_s, _m) (MM_UINT_PTR(&(((_s *) 0)->_m)))
|
||||
#endif /* OFFSETOF */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Simple macros. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define IS_ETH_BROADCAST(_pEthAddr) \
|
||||
(((unsigned char *) (_pEthAddr))[0] == ((unsigned char) 0xff))
|
||||
|
||||
#define IS_ETH_MULTICAST(_pEthAddr) \
|
||||
(((unsigned char *) (_pEthAddr))[0] & ((unsigned char) 0x01))
|
||||
|
||||
#define IS_ETH_ADDRESS_EQUAL(_pEtherAddr1, _pEtherAddr2) \
|
||||
((((unsigned char *) (_pEtherAddr1))[0] == \
|
||||
((unsigned char *) (_pEtherAddr2))[0]) && \
|
||||
(((unsigned char *) (_pEtherAddr1))[1] == \
|
||||
((unsigned char *) (_pEtherAddr2))[1]) && \
|
||||
(((unsigned char *) (_pEtherAddr1))[2] == \
|
||||
((unsigned char *) (_pEtherAddr2))[2]) && \
|
||||
(((unsigned char *) (_pEtherAddr1))[3] == \
|
||||
((unsigned char *) (_pEtherAddr2))[3]) && \
|
||||
(((unsigned char *) (_pEtherAddr1))[4] == \
|
||||
((unsigned char *) (_pEtherAddr2))[4]) && \
|
||||
(((unsigned char *) (_pEtherAddr1))[5] == \
|
||||
((unsigned char *) (_pEtherAddr2))[5]))
|
||||
|
||||
#define COPY_ETH_ADDRESS(_Src, _Dst) \
|
||||
((unsigned char *) (_Dst))[0] = ((unsigned char *) (_Src))[0]; \
|
||||
((unsigned char *) (_Dst))[1] = ((unsigned char *) (_Src))[1]; \
|
||||
((unsigned char *) (_Dst))[2] = ((unsigned char *) (_Src))[2]; \
|
||||
((unsigned char *) (_Dst))[3] = ((unsigned char *) (_Src))[3]; \
|
||||
((unsigned char *) (_Dst))[4] = ((unsigned char *) (_Src))[4]; \
|
||||
((unsigned char *) (_Dst))[5] = ((unsigned char *) (_Src))[5];
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Constants. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define ETHERNET_ADDRESS_SIZE 6
|
||||
#define ETHERNET_PACKET_HEADER_SIZE 14
|
||||
#define MIN_ETHERNET_PACKET_SIZE 64 /* with 4 byte crc. */
|
||||
#define MAX_ETHERNET_PACKET_SIZE 1518 /* with 4 byte crc. */
|
||||
#define MIN_ETHERNET_PACKET_SIZE_NO_CRC 60
|
||||
#define MAX_ETHERNET_PACKET_SIZE_NO_CRC 1514
|
||||
#define MAX_ETHERNET_PACKET_BUFFER_SIZE 1536 /* A nice even number. */
|
||||
#define MAX_ETHERNET_JUMBO_PACKET_SIZE_NO_CRC 9014
|
||||
|
||||
#ifndef LM_MAX_MC_TABLE_SIZE
|
||||
#define LM_MAX_MC_TABLE_SIZE 32
|
||||
#endif /* LM_MAX_MC_TABLE_SIZE */
|
||||
#define LM_MC_ENTRY_SIZE (ETHERNET_ADDRESS_SIZE+1)
|
||||
#define LM_MC_INSTANCE_COUNT_INDEX (LM_MC_ENTRY_SIZE-1)
|
||||
|
||||
|
||||
/* Receive filter masks. */
|
||||
#define LM_ACCEPT_UNICAST 0x0001
|
||||
#define LM_ACCEPT_MULTICAST 0x0002
|
||||
#define LM_ACCEPT_ALL_MULTICAST 0x0004
|
||||
#define LM_ACCEPT_BROADCAST 0x0008
|
||||
#define LM_ACCEPT_ERROR_PACKET 0x0010
|
||||
#define LM_KEEP_VLAN_TAG 0x0020
|
||||
|
||||
#define LM_PROMISCUOUS_MODE 0x10000
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* PCI registers. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define PCI_VENDOR_ID_REG 0x00
|
||||
#define PCI_DEVICE_ID_REG 0x02
|
||||
|
||||
#define PCI_COMMAND_REG 0x04
|
||||
#define PCI_IO_SPACE_ENABLE 0x0001
|
||||
#define PCI_MEM_SPACE_ENABLE 0x0002
|
||||
#define PCI_BUSMASTER_ENABLE 0x0004
|
||||
#define PCI_MEMORY_WRITE_INVALIDATE 0x0010
|
||||
#define PCI_PARITY_ERROR_ENABLE 0x0040
|
||||
#define PCI_SYSTEM_ERROR_ENABLE 0x0100
|
||||
#define PCI_FAST_BACK_TO_BACK_ENABLE 0x0200
|
||||
|
||||
#define PCI_STATUS_REG 0x06
|
||||
#define PCI_REV_ID_REG 0x08
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE_REG 0x0c
|
||||
|
||||
#define PCI_IO_BASE_ADDR_REG 0x10
|
||||
#define PCI_IO_BASE_ADDR_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MEM_BASE_ADDR_LOW 0x10
|
||||
#define PCI_MEM_BASE_ADDR_HIGH 0x14
|
||||
|
||||
#define PCI_SUBSYSTEM_VENDOR_ID_REG 0x2c
|
||||
#define PCI_SUBSYSTEM_ID_REG 0x2e
|
||||
#define PCI_INT_LINE_REG 0x3c
|
||||
|
||||
#define PCIX_CAP_REG 0x40
|
||||
#define PCIX_ENABLE_RELAXED_ORDERING BIT_17
|
||||
|
||||
/******************************************************************************/
|
||||
/* Fragment structure. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
LM_UINT32 FragSize;
|
||||
LM_PHYSICAL_ADDRESS FragBuf;
|
||||
} LM_FRAG, *PLM_FRAG;
|
||||
|
||||
typedef struct {
|
||||
/* FragCount is initialized for the caller to the maximum array size, on */
|
||||
/* return FragCount is the number of the actual fragments in the array. */
|
||||
LM_UINT32 FragCount;
|
||||
|
||||
/* Total buffer size. */
|
||||
LM_UINT32 TotalSize;
|
||||
|
||||
/* Fragment array buffer. */
|
||||
LM_FRAG Fragments[1];
|
||||
} LM_FRAG_LIST, *PLM_FRAG_LIST;
|
||||
|
||||
#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_COUNT) \
|
||||
typedef struct { \
|
||||
LM_FRAG_LIST FragList; \
|
||||
LM_FRAG FragListBuffer[_MAX_FRAG_COUNT-1]; \
|
||||
} _FRAG_LIST_TYPE_NAME, *P##_FRAG_LIST_TYPE_NAME
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Status codes. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_STATUS_SUCCESS 0
|
||||
#define LM_STATUS_FAILURE 1
|
||||
|
||||
#define LM_STATUS_INTERRUPT_ACTIVE 2
|
||||
#define LM_STATUS_INTERRUPT_NOT_ACTIVE 3
|
||||
|
||||
#define LM_STATUS_LINK_ACTIVE 4
|
||||
#define LM_STATUS_LINK_DOWN 5
|
||||
#define LM_STATUS_LINK_SETTING_MISMATCH 6
|
||||
|
||||
#define LM_STATUS_TOO_MANY_FRAGMENTS 7
|
||||
#define LM_STATUS_TRANSMIT_ABORTED 8
|
||||
#define LM_STATUS_TRANSMIT_ERROR 9
|
||||
#define LM_STATUS_RECEIVE_ABORTED 10
|
||||
#define LM_STATUS_RECEIVE_ERROR 11
|
||||
#define LM_STATUS_INVALID_PACKET_SIZE 12
|
||||
#define LM_STATUS_OUT_OF_MAP_REGISTERS 13
|
||||
#define LM_STATUS_UNKNOWN_ADAPTER 14
|
||||
|
||||
typedef LM_UINT LM_STATUS, *PLM_STATUS;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Line speed. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_LINE_SPEED_UNKNOWN 0
|
||||
#define LM_LINE_SPEED_AUTO LM_LINE_SPEED_UNKNOWN
|
||||
#define LM_LINE_SPEED_10MBPS 10
|
||||
#define LM_LINE_SPEED_100MBPS 100
|
||||
#define LM_LINE_SPEED_1000MBPS 1000
|
||||
|
||||
typedef LM_UINT32 LM_LINE_SPEED, *PLM_LINE_SPEED;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Duplex mode. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_DUPLEX_MODE_UNKNOWN 0
|
||||
#define LM_DUPLEX_MODE_HALF 1
|
||||
#define LM_DUPLEX_MODE_FULL 2
|
||||
|
||||
typedef LM_UINT32 LM_DUPLEX_MODE, *PLM_DUPLEX_MODE;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Power state. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_POWER_STATE_D0 0
|
||||
#define LM_POWER_STATE_D1 1
|
||||
#define LM_POWER_STATE_D2 2
|
||||
#define LM_POWER_STATE_D3 3
|
||||
|
||||
typedef LM_UINT32 LM_POWER_STATE, *PLM_POWER_STATE;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Task offloading. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_TASK_OFFLOAD_NONE 0x0000
|
||||
#define LM_TASK_OFFLOAD_TX_IP_CHECKSUM 0x0001
|
||||
#define LM_TASK_OFFLOAD_RX_IP_CHECKSUM 0x0002
|
||||
#define LM_TASK_OFFLOAD_TX_TCP_CHECKSUM 0x0004
|
||||
#define LM_TASK_OFFLOAD_RX_TCP_CHECKSUM 0x0008
|
||||
#define LM_TASK_OFFLOAD_TX_UDP_CHECKSUM 0x0010
|
||||
#define LM_TASK_OFFLOAD_RX_UDP_CHECKSUM 0x0020
|
||||
#define LM_TASK_OFFLOAD_TCP_SEGMENTATION 0x0040
|
||||
|
||||
typedef LM_UINT32 LM_TASK_OFFLOAD, *PLM_TASK_OFFLOAD;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Flow control. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_FLOW_CONTROL_NONE 0x00
|
||||
#define LM_FLOW_CONTROL_RECEIVE_PAUSE 0x01
|
||||
#define LM_FLOW_CONTROL_TRANSMIT_PAUSE 0x02
|
||||
#define LM_FLOW_CONTROL_RX_TX_PAUSE (LM_FLOW_CONTROL_RECEIVE_PAUSE | \
|
||||
LM_FLOW_CONTROL_TRANSMIT_PAUSE)
|
||||
|
||||
/* This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE. If the */
|
||||
/* auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE */
|
||||
/* bits are set, then flow control is enabled regardless of link partner's */
|
||||
/* flow control capability. */
|
||||
#define LM_FLOW_CONTROL_AUTO_PAUSE 0x80000000
|
||||
|
||||
typedef LM_UINT32 LM_FLOW_CONTROL, *PLM_FLOW_CONTROL;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Wake up mode. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_WAKE_UP_MODE_NONE 0
|
||||
#define LM_WAKE_UP_MODE_MAGIC_PACKET 1
|
||||
#define LM_WAKE_UP_MODE_NWUF 2
|
||||
#define LM_WAKE_UP_MODE_LINK_CHANGE 4
|
||||
|
||||
typedef LM_UINT32 LM_WAKE_UP_MODE, *PLM_WAKE_UP_MODE;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Counters. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define LM_COUNTER_FRAMES_XMITTED_OK 0
|
||||
#define LM_COUNTER_FRAMES_RECEIVED_OK 1
|
||||
#define LM_COUNTER_ERRORED_TRANSMIT_COUNT 2
|
||||
#define LM_COUNTER_ERRORED_RECEIVE_COUNT 3
|
||||
#define LM_COUNTER_RCV_CRC_ERROR 4
|
||||
#define LM_COUNTER_ALIGNMENT_ERROR 5
|
||||
#define LM_COUNTER_SINGLE_COLLISION_FRAMES 6
|
||||
#define LM_COUNTER_MULTIPLE_COLLISION_FRAMES 7
|
||||
#define LM_COUNTER_FRAMES_DEFERRED 8
|
||||
#define LM_COUNTER_MAX_COLLISIONS 9
|
||||
#define LM_COUNTER_RCV_OVERRUN 10
|
||||
#define LM_COUNTER_XMIT_UNDERRUN 11
|
||||
#define LM_COUNTER_UNICAST_FRAMES_XMIT 12
|
||||
#define LM_COUNTER_MULTICAST_FRAMES_XMIT 13
|
||||
#define LM_COUNTER_BROADCAST_FRAMES_XMIT 14
|
||||
#define LM_COUNTER_UNICAST_FRAMES_RCV 15
|
||||
#define LM_COUNTER_MULTICAST_FRAMES_RCV 16
|
||||
#define LM_COUNTER_BROADCAST_FRAMES_RCV 17
|
||||
|
||||
typedef LM_UINT32 LM_COUNTER_TYPE, *PLM_COUNTER_TYPE;
|
||||
|
||||
|
||||
typedef LM_UINT32 LM_RESET_TYPE;
|
||||
#define LM_SHUTDOWN_RESET 0
|
||||
#define LM_INIT_RESET 1
|
||||
#define LM_SUSPEND_RESET 2
|
||||
|
||||
/******************************************************************************/
|
||||
/* Forward definition. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
|
||||
typedef struct _LM_PACKET *PLM_PACKET;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Function prototypes. */
|
||||
/******************************************************************************/
|
||||
|
||||
LM_STATUS LM_GetAdapterInfo(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_InitializeAdapter(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_ResetAdapter(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_DisableInterrupt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_EnableInterrupt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS LM_ServiceInterrupts(PLM_DEVICE_BLOCK pDevice);
|
||||
#ifdef BCM_NAPI_RXPOLL
|
||||
int LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit);
|
||||
#endif
|
||||
LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
|
||||
LM_STATUS LM_Halt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_MulticastAdd(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
|
||||
LM_STATUS LM_MulticastDel(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
|
||||
LM_STATUS LM_MulticastClear(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_SetMacAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
|
||||
LM_STATUS LM_LoopbackAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
|
||||
|
||||
LM_UINT32 LM_GetCrcCounter(PLM_DEVICE_BLOCK pDevice);
|
||||
|
||||
LM_WAKE_UP_MODE LM_PMCapabilities(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_NwufAdd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
|
||||
LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
|
||||
LM_STATUS LM_NwufRemove(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
|
||||
LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
|
||||
LM_STATUS LM_SetPowerState(PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel);
|
||||
|
||||
LM_VOID LM_ReadPhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
|
||||
PLM_UINT32 pData32);
|
||||
LM_VOID LM_WritePhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
|
||||
LM_UINT32 Data32);
|
||||
|
||||
LM_STATUS LM_EnableMacLoopBack(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_DisableMacLoopBack(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_EnablePhyLoopBack(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_DisablePhyLoopBack(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_EnableExtLoopBack(PLM_DEVICE_BLOCK pDevice, LM_LINE_SPEED Speed);
|
||||
LM_STATUS LM_DisableExtLoopBack(PLM_DEVICE_BLOCK pDevice);
|
||||
|
||||
LM_STATUS LM_SetupPhy(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDuration);
|
||||
LM_STATUS LM_GetStats(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_NvramRead(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pData);
|
||||
LM_STATUS LM_NvramWriteBlock(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pData, LM_UINT32 Size);
|
||||
LM_VOID LM_ResetPhy(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS LM_ShutdownChip(PLM_DEVICE_BLOCK pDevice, LM_RESET_TYPE Mode);
|
||||
LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
|
||||
LM_UINT32 ComputeCrc32(LM_UINT8 *pBuffer, LM_UINT32 BufferSize);
|
||||
LM_STATUS LM_SwitchClocks(PLM_DEVICE_BLOCK pDevice);
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* These are the OS specific functions called by LMAC. */
|
||||
/******************************************************************************/
|
||||
|
||||
LM_STATUS MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 *pValue16);
|
||||
LM_STATUS MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 Value16);
|
||||
LM_STATUS MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pValue32);
|
||||
LM_STATUS MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 Value32);
|
||||
LM_STATUS MM_MapMemBase(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_MapIoBase(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt);
|
||||
LM_STATUS MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,
|
||||
LM_BOOL Cached);
|
||||
LM_STATUS MM_GetConfig(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
|
||||
LM_STATUS MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS MM_CoalesceTxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
PLM_DEVICE_BLOCK MM_FindPeerDev(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_VOID MM_UnmapRxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
#ifdef BCM_NAPI_RXPOLL
|
||||
LM_STATUS MM_ScheduleRxPoll(PLM_DEVICE_BLOCK pDevice);
|
||||
#endif
|
||||
LM_STATUS MM_Sleep(PLM_DEVICE_BLOCK pDevice, LM_UINT32 msec);
|
||||
LM_STATUS LM_MbufWorkAround(PLM_DEVICE_BLOCK pDevice);
|
||||
|
||||
#if INCLUDE_5703_A0_FIX
|
||||
LM_STATUS LM_Load5703DmaWFirmware(PLM_DEVICE_BLOCK pDevice);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* LM_H */
|
||||
|
104
src/add-ons/kernel/drivers/network/bcm570x/mempool.c
Normal file
104
src/add-ons/kernel/drivers/network/bcm570x/mempool.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* Intel PRO/1000 Family Driver
|
||||
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies, and that both the
|
||||
* copyright notice and this permission notice appear in supporting documentation.
|
||||
*
|
||||
* Marcus Overhagen makes no representations about the suitability of this software
|
||||
* for any purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
|
||||
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <KernelExport.h>
|
||||
#include <malloc.h>
|
||||
#include "mempool.h"
|
||||
|
||||
spinlock chunk_pool_lock = 0;
|
||||
void *chunk_pool = 0;
|
||||
void *chunk_head = 0;
|
||||
|
||||
void *
|
||||
area_malloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
size = ROUNDUP(size, B_PAGE_SIZE);
|
||||
|
||||
if (create_area("area_malloc", &p, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK, 0) < 0)
|
||||
return 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
area_free(void *p)
|
||||
{
|
||||
delete_area(area_for(p));
|
||||
}
|
||||
|
||||
int
|
||||
mempool_init(int count)
|
||||
{
|
||||
int chunk_size = 2048;
|
||||
|
||||
int chunk_alloc_size = chunk_size * (count + 1);
|
||||
|
||||
char *chunk_base;
|
||||
|
||||
int i;
|
||||
|
||||
chunk_pool = area_malloc(chunk_alloc_size);
|
||||
if (!chunk_pool) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
chunk_base = (char *)ROUNDUP((unsigned long)chunk_pool, 2048);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
chunk_pool_put(chunk_base + i * chunk_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mempool_exit(void)
|
||||
{
|
||||
area_free(chunk_pool);
|
||||
}
|
||||
|
||||
void *
|
||||
chunk_pool_get(void)
|
||||
{
|
||||
void *p;
|
||||
cpu_status s;
|
||||
s = disable_interrupts();
|
||||
acquire_spinlock(&chunk_pool_lock);
|
||||
|
||||
p = chunk_head;
|
||||
if (p)
|
||||
chunk_head = *(void **)p;
|
||||
|
||||
release_spinlock(&chunk_pool_lock);
|
||||
restore_interrupts(s);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
chunk_pool_put(void *p)
|
||||
{
|
||||
cpu_status s;
|
||||
s = disable_interrupts();
|
||||
acquire_spinlock(&chunk_pool_lock);
|
||||
|
||||
*(void **)p = chunk_head;
|
||||
chunk_head = p;
|
||||
|
||||
release_spinlock(&chunk_pool_lock);
|
||||
restore_interrupts(s);
|
||||
}
|
35
src/add-ons/kernel/drivers/network/bcm570x/mempool.h
Normal file
35
src/add-ons/kernel/drivers/network/bcm570x/mempool.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Intel PRO/1000 Family Driver
|
||||
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies, and that both the
|
||||
* copyright notice and this permission notice appear in supporting documentation.
|
||||
*
|
||||
* Marcus Overhagen makes no representations about the suitability of this software
|
||||
* for any purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
|
||||
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __MEMPOOL_H
|
||||
#define __MEMPOOL_H
|
||||
|
||||
int mempool_init(int count);
|
||||
void mempool_exit(void);
|
||||
|
||||
void *chunk_pool_get(void);
|
||||
void chunk_pool_put(void *p);
|
||||
|
||||
void * area_malloc(size_t size);
|
||||
void area_free(void *p);
|
||||
|
||||
#ifndef ROUNDUP
|
||||
#define ROUNDUP(size, blocksize) (((size) + (blocksize) - 1) & ~((blocksize) - 1))
|
||||
#endif
|
||||
|
||||
#endif
|
156
src/add-ons/kernel/drivers/network/bcm570x/mm.h
Normal file
156
src/add-ons/kernel/drivers/network/bcm570x/mm.h
Normal file
@ -0,0 +1,156 @@
|
||||
#ifndef B57MM_H
|
||||
#define B57MM_H
|
||||
|
||||
#include <PCI.h>
|
||||
#include <Drivers.h>
|
||||
#include <OS.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
typedef vint32 MM_ATOMIC_T;
|
||||
|
||||
//#define MM_SWAP_LE16(x) B_SWAP_INT16(x)
|
||||
#define MM_SWAP_LE16(x) x
|
||||
#define MM_SWAP_LE32(x) x
|
||||
#define MM_SWAP_BE32(x) B_SWAP_INT32(x)
|
||||
|
||||
/*#define MM_ATOMIC_SET(ptr, val) atomic_and(ptr, 0); atomic_add(ptr,val)
|
||||
#define MM_ATOMIC_READ(ptr) atomic_add(ptr,0)
|
||||
#define MM_ATOMIC_INC(ptr) atomic_add(ptr,1)
|
||||
#define MM_ATOMIC_ADD(ptr, val) atomic_add(ptr,val)
|
||||
#define MM_ATOMIC_DEC(ptr) atomic_add(ptr,-1)
|
||||
#define MM_ATOMIC_SUB(ptr, val) atomic_add(ptr,0-val)*/
|
||||
|
||||
#define MM_ATOMIC_SET(ptr, val) *(ptr)=val
|
||||
#define MM_ATOMIC_READ(ptr) *(ptr)
|
||||
#define MM_ATOMIC_INC(ptr) (*(ptr))++
|
||||
#define MM_ATOMIC_ADD(ptr, val) *(ptr)+=val
|
||||
#define MM_ATOMIC_DEC(ptr) (*(ptr))--
|
||||
#define MM_ATOMIC_SUB(ptr, val) *(ptr)-=val
|
||||
|
||||
/* All critical sections are protected by locking mechanisms already */
|
||||
|
||||
#define __io_virt(x) ((void *)(x))
|
||||
#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
|
||||
#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
|
||||
#define __raw_readl readl
|
||||
#define __raw_writel writel
|
||||
|
||||
#define udelay spin
|
||||
|
||||
#define MM_MEMWRITEL(ptr, val) __raw_writel(val, ptr)
|
||||
#define MM_MEMREADL(ptr) __raw_readl(ptr)
|
||||
|
||||
#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
|
||||
#define wmb() mb()
|
||||
#define rmb() mb()
|
||||
|
||||
#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
|
||||
|
||||
#define MM_MB() mb()
|
||||
#define MM_WMB() wmb()
|
||||
#define MM_RMB() rmb()
|
||||
|
||||
#define STATIC static
|
||||
|
||||
extern int b57_Packet_Desc_Size;
|
||||
|
||||
#define MM_PACKET_DESC_SIZE b57_Packet_Desc_Size
|
||||
|
||||
#include "lm.h"
|
||||
#include "queue.h"
|
||||
#include "tigon3.h"
|
||||
|
||||
struct be_b57_dev {
|
||||
struct _LM_DEVICE_BLOCK lm_dev;
|
||||
|
||||
struct pci_info pci_data;
|
||||
|
||||
sem_id packet_release_sem;
|
||||
//sem_id interrupt_sem;
|
||||
//thread_id interrupt_handler;
|
||||
|
||||
LM_RX_PACKET_Q RxPacketReadQ;
|
||||
|
||||
void *mem_list[16];
|
||||
int mem_list_num;
|
||||
|
||||
area_id lockmem_list[16];
|
||||
int lockmem_list_num;
|
||||
|
||||
area_id mem_base;
|
||||
|
||||
vint32 opened;
|
||||
int block;
|
||||
spinlock lock;
|
||||
cpu_status cpu;
|
||||
};
|
||||
|
||||
struct B_UM_PACKET {
|
||||
struct _LM_PACKET pkt;
|
||||
|
||||
void *data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static inline void MM_MapRxDma(PLM_DEVICE_BLOCK pDevice,
|
||||
struct _LM_PACKET *pPacket,
|
||||
T3_64BIT_HOST_ADDR *paddr)
|
||||
{
|
||||
physical_entry entry;
|
||||
struct B_UM_PACKET *bpkt = (struct B_UM_PACKET *)(pPacket);
|
||||
|
||||
get_memory_map(bpkt->data,pPacket->u.Rx.RxBufferSize,&entry,1);
|
||||
paddr->Low = (LM_UINT32) entry.address;
|
||||
paddr->High = 0L;
|
||||
}
|
||||
|
||||
static inline void MM_MapTxDma(PLM_DEVICE_BLOCK pDevice,
|
||||
struct _LM_PACKET *pPacket,
|
||||
T3_64BIT_HOST_ADDR *paddr, LM_UINT32 *len, int frag)
|
||||
{
|
||||
struct B_UM_PACKET *pkt = (struct B_UM_PACKET *)pPacket;
|
||||
physical_entry entry;
|
||||
|
||||
get_memory_map(pkt->data,pkt->size,&entry,1);
|
||||
paddr->Low = (LM_UINT32) entry.address;
|
||||
paddr->High = 0L;
|
||||
*len = pPacket->PacketSize;
|
||||
}
|
||||
|
||||
#if (BITS_PER_LONG == 64)
|
||||
#define MM_GETSTATS(_Ctr) \
|
||||
(unsigned long) (_Ctr).Low + ((unsigned long) (_Ctr).High << 32)
|
||||
#else
|
||||
#define MM_GETSTATS(_Ctr) \
|
||||
(unsigned long) (_Ctr).Low
|
||||
#endif
|
||||
|
||||
#define MM_ACQUIRE_UNDI_LOCK(_pDevice)/* \
|
||||
((struct be_b57_dev *)(_pDevice))->cpu = disable_interrupts(); \
|
||||
acquire_spinlock(&(((struct be_b57_dev *)(_pDevice))->lock));*/
|
||||
|
||||
#define MM_RELEASE_UNDI_LOCK(_pDevice)/* \
|
||||
release_spinlock(&(((struct be_b57_dev *)(_pDevice))->lock)); \
|
||||
enable_interrupts(((struct be_b57_dev *)(_pDevice))->cpu);*/
|
||||
|
||||
#define MM_ACQUIRE_PHY_LOCK_IN_IRQ(_pDevice)/* \
|
||||
((struct be_b57_dev *)(_pDevice))->cpu = disable_interrupts(); \
|
||||
acquire_spinlock(&(((struct be_b57_dev *)(_pDevice))->lock));*/
|
||||
|
||||
#define MM_RELEASE_PHY_LOCK_IN_IRQ(_pDevice) /*\
|
||||
release_spinlock(&(((struct be_b57_dev *)(_pDevice))->lock)); \
|
||||
enable_interrupts(((struct be_b57_dev *)(_pDevice))->cpu);*/
|
||||
|
||||
#define MM_PTR(_ptr) ((unsigned long) (_ptr))
|
||||
#define MM_UINT_PTR(_ptr) ((unsigned long) (_ptr))
|
||||
#define printf(fmt, args...) dprintf(fmt, ##args)
|
||||
#define DbgPrint(fmt, arg...) dprintf(fmt, ##arg)
|
||||
#define DbgBreakPoint()
|
||||
#define MM_Wait(time) udelay(time)
|
||||
#define ASSERT(expr) \
|
||||
if (!(expr)) { \
|
||||
dprintf("ASSERT failed: %s\n", #expr); \
|
||||
}
|
||||
|
||||
#endif
|
347
src/add-ons/kernel/drivers/network/bcm570x/queue.h
Normal file
347
src/add-ons/kernel/drivers/network/bcm570x/queue.h
Normal file
@ -0,0 +1,347 @@
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom */
|
||||
/* Corporation. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation, located in the file LICENSE. */
|
||||
/* */
|
||||
/* Queue functions. */
|
||||
/* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
|
||||
/* char QQ_Full(PQQ_CONTAINER pQueue) */
|
||||
/* char QQ_Empty(PQQ_CONTAINER pQueue) */
|
||||
/* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
|
||||
/* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
|
||||
/* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
|
||||
/* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
|
||||
/* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
|
||||
/* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
|
||||
/* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
|
||||
/* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
|
||||
/* */
|
||||
/* */
|
||||
/* History: */
|
||||
/* 02/25/00 Hav Khauv Initial version. */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef BCM_QUEUE_H
|
||||
#define BCM_QUEUE_H
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Queue definitions. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* Entry for queueing. */
|
||||
typedef void *PQQ_ENTRY;
|
||||
|
||||
|
||||
/* Queue header -- base type. */
|
||||
typedef struct {
|
||||
unsigned int Head;
|
||||
unsigned int Tail;
|
||||
unsigned int Size;
|
||||
MM_ATOMIC_T EntryCnt;
|
||||
PQQ_ENTRY Array[1];
|
||||
} QQ_CONTAINER, *PQQ_CONTAINER;
|
||||
|
||||
|
||||
/* Declare queue type macro. */
|
||||
#define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
|
||||
\
|
||||
typedef struct { \
|
||||
QQ_CONTAINER Container; \
|
||||
PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
|
||||
} _QUEUE_TYPE, *P##_QUEUE_TYPE
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Compilation switches. */
|
||||
/******************************************************************************/
|
||||
|
||||
#if DBG
|
||||
#undef QQ_NO_OVERFLOW_CHECK
|
||||
#undef QQ_NO_UNDERFLOW_CHECK
|
||||
#endif /* DBG */
|
||||
|
||||
#ifdef QQ_USE_MACROS
|
||||
/* notdone */
|
||||
#else
|
||||
|
||||
#ifdef QQ_NO_INLINE
|
||||
#define __inline
|
||||
#endif /* QQ_NO_INLINE */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static void
|
||||
QQ_InitQueue(
|
||||
PQQ_CONTAINER pQueue,
|
||||
unsigned int QueueSize) {
|
||||
pQueue->Head = 0;
|
||||
pQueue->Tail = 0;
|
||||
pQueue->Size = QueueSize+1;
|
||||
MM_ATOMIC_SET(&pQueue->EntryCnt, 0);
|
||||
} /* QQ_InitQueue */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static char
|
||||
QQ_Full(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
unsigned int NewHead;
|
||||
|
||||
NewHead = (pQueue->Head + 1) % pQueue->Size;
|
||||
|
||||
return(NewHead == pQueue->Tail);
|
||||
} /* QQ_Full */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static char
|
||||
QQ_Empty(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
return(pQueue->Head == pQueue->Tail);
|
||||
} /* QQ_Empty */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static unsigned int
|
||||
QQ_GetSize(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
return pQueue->Size;
|
||||
} /* QQ_GetSize */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static unsigned int
|
||||
QQ_GetEntryCnt(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
return MM_ATOMIC_READ(&pQueue->EntryCnt);
|
||||
} /* QQ_GetEntryCnt */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/* TRUE entry was added successfully. */
|
||||
/* FALSE queue is full. */
|
||||
/******************************************************************************/
|
||||
__inline static char
|
||||
QQ_PushHead(
|
||||
PQQ_CONTAINER pQueue,
|
||||
PQQ_ENTRY pEntry) {
|
||||
unsigned int Head;
|
||||
|
||||
Head = (pQueue->Head + 1) % pQueue->Size;
|
||||
|
||||
#if !defined(QQ_NO_OVERFLOW_CHECK)
|
||||
if(Head == pQueue->Tail) {
|
||||
return 0;
|
||||
} /* if */
|
||||
#endif /* QQ_NO_OVERFLOW_CHECK */
|
||||
|
||||
pQueue->Array[pQueue->Head] = pEntry;
|
||||
MM_WMB();
|
||||
pQueue->Head = Head;
|
||||
MM_ATOMIC_INC(&pQueue->EntryCnt);
|
||||
|
||||
return -1;
|
||||
} /* QQ_PushHead */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/* TRUE entry was added successfully. */
|
||||
/* FALSE queue is full. */
|
||||
/******************************************************************************/
|
||||
__inline static char
|
||||
QQ_PushTail(
|
||||
PQQ_CONTAINER pQueue,
|
||||
PQQ_ENTRY pEntry) {
|
||||
unsigned int Tail;
|
||||
|
||||
Tail = pQueue->Tail;
|
||||
if(Tail == 0) {
|
||||
Tail = pQueue->Size;
|
||||
} /* if */
|
||||
Tail--;
|
||||
|
||||
#if !defined(QQ_NO_OVERFLOW_CHECK)
|
||||
if(Tail == pQueue->Head) {
|
||||
return 0;
|
||||
} /* if */
|
||||
#endif /* QQ_NO_OVERFLOW_CHECK */
|
||||
|
||||
pQueue->Array[Tail] = pEntry;
|
||||
MM_WMB();
|
||||
pQueue->Tail = Tail;
|
||||
MM_ATOMIC_INC(&pQueue->EntryCnt);
|
||||
|
||||
return -1;
|
||||
} /* QQ_PushTail */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static PQQ_ENTRY
|
||||
QQ_PopHead(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
unsigned int Head;
|
||||
unsigned int Tail;
|
||||
PQQ_ENTRY Entry;
|
||||
|
||||
Head = pQueue->Head;
|
||||
Tail = pQueue->Tail;
|
||||
|
||||
MM_MB();
|
||||
#if !defined(QQ_NO_UNDERFLOW_CHECK)
|
||||
if(Head == Tail) {
|
||||
return (PQQ_ENTRY) 0;
|
||||
} /* if */
|
||||
#endif /* QQ_NO_UNDERFLOW_CHECK */
|
||||
|
||||
if(Head == 0) {
|
||||
Head = pQueue->Size;
|
||||
} /* if */
|
||||
Head--;
|
||||
|
||||
Entry = pQueue->Array[Head];
|
||||
MM_MB();
|
||||
pQueue->Head = Head;
|
||||
MM_ATOMIC_DEC(&pQueue->EntryCnt);
|
||||
|
||||
return Entry;
|
||||
} /* QQ_PopHead */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static PQQ_ENTRY
|
||||
QQ_PopTail(
|
||||
PQQ_CONTAINER pQueue) {
|
||||
unsigned int Head;
|
||||
unsigned int Tail;
|
||||
PQQ_ENTRY Entry;
|
||||
|
||||
Head = pQueue->Head;
|
||||
Tail = pQueue->Tail;
|
||||
|
||||
MM_MB();
|
||||
#if !defined(QQ_NO_UNDERFLOW_CHECK)
|
||||
if(Tail == Head) {
|
||||
return (PQQ_ENTRY) 0;
|
||||
} /* if */
|
||||
#endif /* QQ_NO_UNDERFLOW_CHECK */
|
||||
|
||||
Entry = pQueue->Array[Tail];
|
||||
MM_MB();
|
||||
pQueue->Tail = (Tail + 1) % pQueue->Size;
|
||||
MM_ATOMIC_DEC(&pQueue->EntryCnt);
|
||||
|
||||
return Entry;
|
||||
} /* QQ_PopTail */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static PQQ_ENTRY
|
||||
QQ_GetHead(
|
||||
PQQ_CONTAINER pQueue,
|
||||
unsigned int Idx)
|
||||
{
|
||||
if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
|
||||
{
|
||||
return (PQQ_ENTRY) 0;
|
||||
}
|
||||
|
||||
if(pQueue->Head > Idx)
|
||||
{
|
||||
Idx = pQueue->Head - Idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
Idx = pQueue->Size - (Idx - pQueue->Head);
|
||||
}
|
||||
Idx--;
|
||||
|
||||
return pQueue->Array[Idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Description: */
|
||||
/* */
|
||||
/* Return: */
|
||||
/******************************************************************************/
|
||||
__inline static PQQ_ENTRY
|
||||
QQ_GetTail(
|
||||
PQQ_CONTAINER pQueue,
|
||||
unsigned int Idx)
|
||||
{
|
||||
if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
|
||||
{
|
||||
return (PQQ_ENTRY) 0;
|
||||
}
|
||||
|
||||
Idx += pQueue->Tail;
|
||||
if(Idx >= pQueue->Size)
|
||||
{
|
||||
Idx = Idx - pQueue->Size;
|
||||
}
|
||||
|
||||
return pQueue->Array[Idx];
|
||||
}
|
||||
|
||||
#endif /* QQ_USE_MACROS */
|
||||
|
||||
|
||||
|
||||
#endif /* QUEUE_H */
|
7905
src/add-ons/kernel/drivers/network/bcm570x/tigon3.c
Normal file
7905
src/add-ons/kernel/drivers/network/bcm570x/tigon3.c
Normal file
File diff suppressed because it is too large
Load Diff
3580
src/add-ons/kernel/drivers/network/bcm570x/tigon3.h
Normal file
3580
src/add-ons/kernel/drivers/network/bcm570x/tigon3.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user