Added the Broadcom 440x driver under the SubIncludeGPL rule.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9127 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
45abc8d70d
commit
58fcb06c24
@ -7,3 +7,5 @@ SubInclude OBOS_TOP src add-ons kernel drivers network wb840 ;
|
||||
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 ;
|
51
src/add-ons/kernel/drivers/network/bcm440x/Jamfile
Normal file
51
src/add-ons/kernel/drivers/network/bcm440x/Jamfile
Normal file
@ -0,0 +1,51 @@
|
||||
SubDir OBOS_TOP src add-ons kernel drivers network bcm440x ;
|
||||
|
||||
# For ether_driver.h
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
R5KernelAddon bcm440x : kernel drivers bin :
|
||||
b44lm.c
|
||||
b44um.c
|
||||
mempool.c
|
||||
;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
bcm440x :
|
||||
boot home config add-ons kernel drivers bin ;
|
||||
Package haiku-networkingkit-cvs :
|
||||
<kernel!drivers!dev!net>bcm440x :
|
||||
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>bcm440x ;
|
||||
MakeLocate $(instDriver) : $(dir) ;
|
||||
RelSymLink $(instDriver) : bcm440x ;
|
||||
}
|
||||
|
||||
|
||||
rule InstallSiS900
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
}
|
||||
|
||||
actions ignore InstallSiS900
|
||||
{
|
||||
cp $(>) /boot/home/config/add-ons/kernel/drivers/bin/
|
||||
}
|
||||
|
||||
#InstallSiS900 install : sis900 ;
|
||||
|
||||
# Installation
|
||||
|
||||
OBOSInstall install-networking : /boot/home/config/add-ons/kernel/drivers/bin :
|
||||
sis900
|
||||
;
|
||||
|
||||
OBOSInstallRelSymLink install-networking : /boot/home/config/add-ons/kernel/drivers/dev/net :
|
||||
<installed>sis900 :
|
||||
installed-symlink
|
||||
;
|
||||
|
11
src/add-ons/kernel/drivers/network/bcm440x/README
Normal file
11
src/add-ons/kernel/drivers/network/bcm440x/README
Normal file
@ -0,0 +1,11 @@
|
||||
Broadcom 440x 10/100 Ethernet Driver
|
||||
|
||||
Copyright 2003-4 Nathan Whitehorn, portions copyright 2000-2004 Broadcom Corporation
|
||||
|
||||
To install, double-click the file appropriately named "Double Click to Install". This has not been tested with net_server, but it should work.
|
||||
|
||||
The driver is based on version 3.0.7 of the Linux drivers 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 this driver.
|
1130
src/add-ons/kernel/drivers/network/bcm440x/b44.h
Normal file
1130
src/add-ons/kernel/drivers/network/bcm440x/b44.h
Normal file
File diff suppressed because it is too large
Load Diff
2097
src/add-ons/kernel/drivers/network/bcm440x/b44lm.c
Normal file
2097
src/add-ons/kernel/drivers/network/bcm440x/b44lm.c
Normal file
File diff suppressed because it is too large
Load Diff
411
src/add-ons/kernel/drivers/network/bcm440x/b44lm.h
Normal file
411
src/add-ons/kernel/drivers/network/bcm440x/b44lm.h
Normal file
@ -0,0 +1,411 @@
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM4400 Linux Network Driver, Copyright (c) 2002 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 B44LM_H
|
||||
#define B44LM_H
|
||||
|
||||
#include "b44queue.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 long LM_COUNTER, *PLM_COUNTER;
|
||||
typedef void LM_VOID, *PLM_VOID;
|
||||
typedef char LM_BOOL, *PLM_BOOL;
|
||||
|
||||
typedef LM_UINT32 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
|
||||
|
||||
#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) (B44_MM_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. */
|
||||
|
||||
#ifndef LM_MAX_MC_TABLE_SIZE
|
||||
#define LM_MAX_MC_TABLE_SIZE 63
|
||||
#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_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
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Forward definition. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
|
||||
typedef struct _LM_PACKET *PLM_PACKET;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Function prototypes. */
|
||||
/******************************************************************************/
|
||||
|
||||
LM_STATUS b44_LM_GetAdapterInfo(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_InitializeAdapter(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_ResetAdapter(PLM_DEVICE_BLOCK pDevice, LM_BOOL full);
|
||||
LM_STATUS b44_LM_DisableInterrupt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_EnableInterrupt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS b44_LM_ServiceInterrupts(PLM_DEVICE_BLOCK pDevice);
|
||||
#ifdef BCM_NAPI_RXPOLL
|
||||
int b44_LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit);
|
||||
#endif
|
||||
LM_STATUS b44_LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
|
||||
LM_STATUS b44_LM_Halt(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_Abort(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_MulticastAdd(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
|
||||
LM_STATUS b44_LM_MulticastDel(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
|
||||
LM_STATUS b44_LM_MulticastClear(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_SetMacAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
|
||||
LM_STATUS b44_LM_LoopbackAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
|
||||
|
||||
LM_WAKE_UP_MODE b44_LM_PMCapabilities(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_SetPowerState(PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel);
|
||||
|
||||
LM_VOID b44_LM_ReadPhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
|
||||
PLM_UINT32 pData32);
|
||||
LM_VOID b44_LM_WritePhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
|
||||
LM_UINT32 Data32);
|
||||
|
||||
LM_STATUS b44_LM_SetupPhy(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_ResetPhy(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_GetStats(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_NvramRead(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pData);
|
||||
LM_STATUS b44_LM_NvramWriteBlock(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pData, LM_UINT32 Size);
|
||||
void b44_LM_PollLink(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_LM_StatsUpdate(PLM_DEVICE_BLOCK pDevice);
|
||||
#ifdef BCM_WOL
|
||||
LM_VOID b44_LM_pmset(PLM_DEVICE_BLOCK pDevice);
|
||||
#endif
|
||||
LM_VOID b44_LM_PowerDownPhy(PLM_DEVICE_BLOCK pDevice);
|
||||
|
||||
/******************************************************************************/
|
||||
/* These are the OS specific functions called by LMAC. */
|
||||
/******************************************************************************/
|
||||
|
||||
LM_STATUS b44_MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 *pValue16);
|
||||
LM_STATUS b44_MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 Value16);
|
||||
LM_STATUS b44_MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pValue32);
|
||||
LM_STATUS b44_MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 Value32);
|
||||
LM_STATUS b44_MM_MapMemBase(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_MapIoBase(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS b44_MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS b44_MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt);
|
||||
LM_STATUS b44_MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy);
|
||||
LM_STATUS b44_MM_GetConfig(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
|
||||
LM_STATUS b44_MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice);
|
||||
LM_STATUS b44_MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
#ifdef BCM_NAPI_RXPOLL
|
||||
LM_STATUS b44_MM_ScheduleRxPoll(PLM_DEVICE_BLOCK pDevice);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* B44LM_H */
|
||||
|
132
src/add-ons/kernel/drivers/network/bcm440x/b44mm.h
Normal file
132
src/add-ons/kernel/drivers/network/bcm440x/b44mm.h
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef B44MM_H
|
||||
#define B44MM_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_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 readl(addr) (*(volatile unsigned int *) __io_virt(addr))
|
||||
|
||||
#define MM_MB() mb()
|
||||
#define MM_WMB() wmb()
|
||||
|
||||
#define STATIC static
|
||||
|
||||
extern int b44_Packet_Desc_Size;
|
||||
|
||||
#define B44_MM_PACKET_DESC_SIZE b44_Packet_Desc_Size
|
||||
|
||||
#include "b44lm.h"
|
||||
#include "b44queue.h"
|
||||
#include "b44.h"
|
||||
|
||||
struct be_b44_dev {
|
||||
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;
|
||||
};
|
||||
|
||||
struct B_UM_PACKET {
|
||||
struct _LM_PACKET pkt;
|
||||
|
||||
void *data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static inline void b44_MM_MapRxDma(PLM_DEVICE_BLOCK pDevice,
|
||||
struct _LM_PACKET *pPacket,
|
||||
LM_UINT32 *paddr)
|
||||
{
|
||||
physical_entry entry;
|
||||
|
||||
get_memory_map(pPacket->u.Rx.pRxBufferVirt,pPacket->u.Rx.RxBufferSize,&entry,1);
|
||||
*paddr = (LM_UINT32) entry.address;
|
||||
}
|
||||
|
||||
static inline void b44_MM_MapTxDma(PLM_DEVICE_BLOCK pDevice,
|
||||
struct _LM_PACKET *pPacket,
|
||||
LM_UINT32 *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 = (LM_UINT32) entry.address;
|
||||
*len = pPacket->PacketSize;
|
||||
}
|
||||
|
||||
#if (BITS_PER_LONG == 64)
|
||||
#define B44_MM_GETSTATS(_Ctr) \
|
||||
(unsigned long) (_Ctr).Low + ((unsigned long) (_Ctr).High << 32)
|
||||
#else
|
||||
#define B44_MM_GETSTATS(_Ctr) \
|
||||
(unsigned long) (_Ctr).Low
|
||||
#endif
|
||||
|
||||
#define B44_MM_PTR(_ptr) ((unsigned long) (_ptr))
|
||||
#define printf(fmt, args...) dprintf(fmt, ##args)
|
||||
#define DbgPrint(fmt, arg...) dprintf(fmt, ##arg)
|
||||
#define DbgBreakPoint()
|
||||
#define b44_MM_Wait(time) udelay(time)
|
||||
#define ASSERT(expr) \
|
||||
if (!(expr)) { \
|
||||
dprintf("ASSERT failed: %s\n", #expr); \
|
||||
}
|
||||
|
||||
#endif
|
342
src/add-ons/kernel/drivers/network/bcm440x/b44queue.h
Normal file
342
src/add-ons/kernel/drivers/network/bcm440x/b44queue.h
Normal file
@ -0,0 +1,342 @@
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Broadcom BCM4400 Linux Network Driver, Copyright (c) 2002 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;
|
||||
PQQ_ENTRY Entry;
|
||||
|
||||
Head = pQueue->Head;
|
||||
|
||||
#if !defined(QQ_NO_UNDERFLOW_CHECK)
|
||||
if(Head == pQueue->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 Tail;
|
||||
PQQ_ENTRY Entry;
|
||||
|
||||
Tail = pQueue->Tail;
|
||||
|
||||
#if !defined(QQ_NO_UNDERFLOW_CHECK)
|
||||
if(Tail == pQueue->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 >= 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 >= 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 */
|
489
src/add-ons/kernel/drivers/network/bcm440x/b44um.c
Normal file
489
src/add-ons/kernel/drivers/network/bcm440x/b44um.c
Normal file
@ -0,0 +1,489 @@
|
||||
#include <PCI.h>
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <ether_driver.h>
|
||||
|
||||
#include "b44mm.h"
|
||||
#include "b44lm.h"
|
||||
#include "mempool.h"
|
||||
|
||||
struct pci_module_info *pci = NULL;
|
||||
|
||||
const char *dev_list[11];
|
||||
struct be_b44_dev be_b44_dev_cards[10];
|
||||
int cards_found = 0;
|
||||
|
||||
int b44_Packet_Desc_Size = sizeof(struct B_UM_PACKET);
|
||||
|
||||
#define ROUND_UP_TO_PAGE(size) ((size % 4096 != 0) ? 4096 - (size % 4096) + size : size)
|
||||
|
||||
/* -------- BeOS Driver Hooks ------------ */
|
||||
|
||||
status_t b44_open(const char *name, uint32 flags, void **cookie);
|
||||
status_t b44_close(void *cookie);
|
||||
status_t b44_free(void *cookie);
|
||||
status_t b44_ioctl(void *cookie,uint32 op,void *data,size_t len);
|
||||
status_t b44_read(void *cookie,off_t pos,void *data,size_t *numBytes);
|
||||
status_t b44_write(void *cookie,off_t pos,const void *data,size_t *numBytes);
|
||||
int32 b44_interrupt(void *cookie);
|
||||
int32 tx_cleanup_thread(void *us);
|
||||
|
||||
device_hooks b44_hooks = {b44_open,b44_close,b44_free,b44_ioctl,b44_read,b44_write,NULL,NULL,NULL,NULL};
|
||||
|
||||
status_t init_hardware(void) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
const char **publish_devices() {
|
||||
return dev_list;
|
||||
}
|
||||
|
||||
device_hooks *find_device(const char *name) {
|
||||
return &b44_hooks;
|
||||
}
|
||||
|
||||
status_t init_driver(void) {
|
||||
int i = 0;
|
||||
pci_info dev_info;
|
||||
|
||||
if (pci == NULL)
|
||||
get_module(B_PCI_MODULE_NAME,(module_info **)&pci);
|
||||
|
||||
while (pci->get_nth_pci_info(i++,&dev_info) == 0) {
|
||||
if (!((dev_info.class_base == PCI_network) && (dev_info.class_sub == PCI_ethernet)
|
||||
&& (dev_info.vendor_id == 0x14e4) && (dev_info.device_id == 0x4401)))
|
||||
continue;
|
||||
|
||||
if (cards_found >= 10)
|
||||
break;
|
||||
|
||||
dev_list[cards_found] = (char *)malloc(16 /* net/bcm440x/xx */);
|
||||
sprintf(dev_list[cards_found],"net/bcm440x/%d",cards_found);
|
||||
be_b44_dev_cards[cards_found].pci_data = dev_info;
|
||||
be_b44_dev_cards[cards_found].packet_release_sem = create_sem(0,dev_list[cards_found]);
|
||||
be_b44_dev_cards[cards_found].mem_list_num = 0;
|
||||
be_b44_dev_cards[cards_found].lockmem_list_num = 0;
|
||||
be_b44_dev_cards[cards_found].opened = 0;
|
||||
be_b44_dev_cards[cards_found].block = 1;
|
||||
be_b44_dev_cards[cards_found].lock = 0;
|
||||
|
||||
if (b44_LM_GetAdapterInfo(&be_b44_dev_cards[cards_found].lm_dev) != LM_STATUS_SUCCESS)
|
||||
return ENODEV;
|
||||
|
||||
QQ_InitQueue(&be_b44_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_b44_dev *pUmDevice;
|
||||
|
||||
for (j = 0; j < cards_found; j++) {
|
||||
pUmDevice = &be_b44_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(dev_list[j]);
|
||||
}
|
||||
|
||||
mempool_exit();
|
||||
}
|
||||
|
||||
status_t b44_open(const char *name, uint32 flags, void **cookie) {
|
||||
struct be_b44_dev *pDevice = NULL;
|
||||
int i;
|
||||
|
||||
*cookie = NULL;
|
||||
for (i = 0; i < cards_found; i++) {
|
||||
if (strcmp(dev_list[i],name) == 0) {
|
||||
*cookie = pDevice = &be_b44_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,b44_interrupt,*cookie,0);
|
||||
if (b44_LM_InitializeAdapter(&pDevice->lm_dev) != LM_STATUS_SUCCESS) {
|
||||
atomic_and(&pDevice->opened,0);
|
||||
remove_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line,b44_interrupt,*cookie);
|
||||
*cookie = NULL;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/*QQ_InitQueue(&pDevice->rx_out_of_buf_q.Container,
|
||||
MAX_RX_PACKET_DESC_COUNT);*/
|
||||
|
||||
b44_LM_EnableInterrupt(&pDevice->lm_dev);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b44_close(void *cookie) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_dev *)(cookie);
|
||||
|
||||
if (cookie == NULL)
|
||||
return B_OK;
|
||||
|
||||
atomic_and(&pUmDevice->opened,0);
|
||||
b44_LM_Halt(&pUmDevice->lm_dev);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b44_free(void *cookie) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_dev *)(cookie);
|
||||
|
||||
if (cookie == NULL)
|
||||
return B_OK;
|
||||
|
||||
remove_io_interrupt_handler(pUmDevice->pci_data.u.h0.interrupt_line,b44_interrupt,cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b44_ioctl(void *cookie,uint32 op,void *data,size_t len) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_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 (b44_LM_MulticastAdd(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR;
|
||||
case ETHER_REMMULTI:
|
||||
return (b44_LM_MulticastDel(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR;
|
||||
case ETHER_SETPROMISC:
|
||||
if (*((uint8 *)(data)))
|
||||
b44_LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask | LM_PROMISCUOUS_MODE);
|
||||
else
|
||||
b44_LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask & ~LM_PROMISCUOUS_MODE);
|
||||
return B_OK;
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 b44_interrupt(void *cookie) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
|
||||
|
||||
|
||||
if (!pDevice->InitDone)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
|
||||
if (b44_LM_ServiceInterrupts(pDevice) == 12)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
|
||||
if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container)) {
|
||||
b44_LM_QueueRxPackets(pDevice);
|
||||
return B_INVOKE_SCHEDULER;
|
||||
}
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
status_t b44_read(void *cookie,off_t pos,void *data,size_t *numBytes) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_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);
|
||||
restore_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);
|
||||
restore_interrupts(cpu);
|
||||
*numBytes = -1;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if ((pPacket->PacketSize/*-pDevice->rxoffset*/) < *numBytes)
|
||||
*numBytes = pPacket->PacketSize/*-pDevice->rxoffset*/;
|
||||
|
||||
memcpy(data,pUmPacket->data+pDevice->rxoffset,*numBytes);
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
restore_interrupts(cpu);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b44_write(void *cookie,off_t pos,const void *data,size_t *numBytes) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie;
|
||||
PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
|
||||
PLM_PACKET pPacket;
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
|
||||
/*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();
|
||||
|
||||
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;
|
||||
|
||||
tx_cleanup_thread(pUmDevice);
|
||||
|
||||
b44_LM_SendPacket(pDevice, pPacket);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/* -------- Broadcom MM hooks ----------- */
|
||||
|
||||
LM_STATUS b44_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_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16));
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_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_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16),(uint32)Value16);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_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_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32));
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_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_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32),(uint32)Value32);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_MM_MapMemBase(PLM_DEVICE_BLOCK pDevice) {
|
||||
struct be_b44_dev *pUmDevice = (struct be_b44_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 = ROUNDUP(size,B_PAGE_SIZE);
|
||||
pUmDevice->mem_base = map_physical_memory("bcm440x_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 b44_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_b44_dev *)(pDevice))->pci_data.memory_base);
|
||||
return LM_STATUS_SUCCESS;
|
||||
}*/
|
||||
|
||||
LM_STATUS b44_MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice) {
|
||||
struct be_b44_dev *dev = (struct be_b44_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 b44_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_b44_dev *pUmDevice = (struct be_b44_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);
|
||||
restore_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);
|
||||
restore_interrupts(cpu);
|
||||
}
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*LM_STATUS b44_MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
|
||||
LM_STATUS b44_MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);*/
|
||||
|
||||
LM_STATUS b44_MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt) {
|
||||
struct be_b44_dev *dev = (struct be_b44_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 b44_MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
|
||||
PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy) {
|
||||
struct be_b44_dev *dev;
|
||||
void *pvirt = NULL;
|
||||
area_id area_desc;
|
||||
physical_entry entry;
|
||||
|
||||
dev = (struct be_b44_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 = (LM_PHYSICAL_ADDRESS) entry.address;
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_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->TxPacketDescCnt = tx_pkt_desc_cnt[DEFAULT_TX_PACKET_DESC_COUNT];
|
||||
pDevice->RxPacketDescCnt = DEFAULT_RX_PACKET_DESC_COUNT;
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status) {
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS
|
||||
b44_MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
int i;
|
||||
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);
|
||||
continue;
|
||||
}*/
|
||||
pPacket->u.Rx.pRxBufferVirt = pUmPacket->data;
|
||||
QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
|
||||
}
|
||||
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS b44_MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket) {
|
||||
struct B_UM_PACKET *pUmPacket;
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
chunk_pool_put(pUmPacket->data);
|
||||
pUmPacket->data = NULL;
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
104
src/add-ons/kernel/drivers/network/bcm440x/mempool.c
Normal file
104
src/add-ons/kernel/drivers/network/bcm440x/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/bcm440x/mempool.h
Normal file
35
src/add-ons/kernel/drivers/network/bcm440x/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
|
Loading…
Reference in New Issue
Block a user