Fixed the most obvious bugs:
- it's restore_interrupts() not enable_interrupts() - B_READ_AREA|B_WRITE_AREA gives every *userland* application full access - fixed coding style - the PCI module was never put away (but get_module() was called almost everywhere) - added comments where the code looked buggy on first sight git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12326 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d67e6bc8a2
commit
c46e419bc5
@ -93,7 +93,7 @@ typedef enum {
|
||||
/* indexed by board_t, above */
|
||||
static struct {
|
||||
char *name;
|
||||
} board_info[] = {
|
||||
} board_info[] = {
|
||||
{ "Broadcom BCM5700 1000Base-T" },
|
||||
{ "Broadcom BCM5700 1000Base-SX" },
|
||||
{ "Broadcom BCM5700 1000Base-SX" },
|
||||
@ -264,91 +264,114 @@ device_hooks b57_hooks = {b57_open,b57_close,b57_free,b57_ioctl,b57_read,b57_wri
|
||||
|
||||
//int debug_fd;
|
||||
|
||||
status_t init_hardware(void) {
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
const char **publish_devices() {
|
||||
return dev_list;
|
||||
|
||||
const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
return dev_list;
|
||||
}
|
||||
|
||||
device_hooks *find_device(const char *name) {
|
||||
|
||||
device_hooks *
|
||||
find_device(const char *name)
|
||||
{
|
||||
return &b57_hooks;
|
||||
}
|
||||
|
||||
status_t init_driver(void) {
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
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) {
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
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+MAX_TX_PACKET_DESC_COUNT) * cards_found);
|
||||
|
||||
dev_list[cards_found] = NULL;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void uninit_driver(void) {
|
||||
int i,j;
|
||||
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
struct be_b57_dev *pUmDevice;
|
||||
|
||||
int i, j;
|
||||
|
||||
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();
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
}
|
||||
|
||||
status_t b57_open(const char *name, uint32 flags, void **cookie) {
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static 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) {
|
||||
@ -356,62 +379,75 @@ status_t b57_open(const char *name, uint32 flags, void **cookie) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*cookie == NULL)
|
||||
return B_FILE_NOT_FOUND;
|
||||
|
||||
if (atomic_or(&pDevice->opened,1)) {
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
static 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);
|
||||
|
||||
atomic_and(&pUmDevice->opened, 0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_free(void *cookie) {
|
||||
|
||||
static 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);
|
||||
|
||||
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) {
|
||||
|
||||
static 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) {
|
||||
@ -420,47 +456,52 @@ status_t b57_ioctl(void *cookie,uint32 op,void *data,size_t len) {
|
||||
case ETHER_GETADDR:
|
||||
if (data == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
memcpy(data,pUmDevice->lm_dev.NodeAddress,6);
|
||||
|
||||
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;
|
||||
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;
|
||||
return (LM_MulticastDel(&pUmDevice->lm_dev,
|
||||
(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR;
|
||||
case ETHER_SETPROMISC:
|
||||
if (*((uint8 *)(data)))
|
||||
if (*((uint8 *)(data))) {
|
||||
LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask | LM_PROMISCUOUS_MODE);
|
||||
else
|
||||
} else {
|
||||
LM_SetReceiveMask(&pUmDevice->lm_dev,
|
||||
pUmDevice->lm_dev.ReceiveMask & ~LM_PROMISCUOUS_MODE);
|
||||
}
|
||||
return B_OK;
|
||||
case ETHER_GETLINKSTATE: {
|
||||
ether_link_state_t *state_buffer = (ether_link_state_t *)(data);
|
||||
state_buffer->link_speed = pUmDevice->lm_dev.LineSpeed;
|
||||
state_buffer->link_quality = (pUmDevice->lm_dev.LinkStatus == LM_STATUS_LINK_DOWN) ? 0.0 : 1.0;
|
||||
state_buffer->duplex_mode = (pUmDevice->lm_dev.DuplexMode == LM_DUPLEX_MODE_FULL);
|
||||
} return B_OK;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 b57_interrupt(void *cookie) {
|
||||
|
||||
static 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)
|
||||
{
|
||||
|
||||
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);
|
||||
@ -485,8 +526,7 @@ int32 b57_interrupt(void *cookie) {
|
||||
}
|
||||
oldtag = newtag;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
i = 0;
|
||||
do {
|
||||
uint dummy;
|
||||
@ -500,231 +540,266 @@ int32 b57_interrupt(void *cookie) {
|
||||
Mailbox.Interrupt[0].Low);
|
||||
i++;
|
||||
}
|
||||
while ((pDevice->pStatusBlkVirt->Status &
|
||||
STATUS_BLOCK_UPDATED) && (i < max_intr_loop));
|
||||
|
||||
while ((pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) != 0
|
||||
&& i < max_intr_loop)
|
||||
;
|
||||
|
||||
if (pDevice->Flags & UNDI_FIX_FLAG) {
|
||||
REG_WR(pDevice, Grc.LocalCtrl,
|
||||
pDevice->GrcLocalCtrl | 0x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else
|
||||
handled = 0;
|
||||
}
|
||||
if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container) ||
|
||||
pDevice->QueueAgain) {
|
||||
|
||||
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) {
|
||||
|
||||
static 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);
|
||||
else
|
||||
acquire_sem_etc(pUmDevice->packet_release_sem,1,B_RELATIVE_TIMEOUT,0); // Decrement the receive sem anyway, but don't block
|
||||
|
||||
else {
|
||||
// ToDo: this looks severly broken
|
||||
// Decrement the receive sem anyway, but don't block
|
||||
acquire_sem_etc(pUmDevice->packet_release_sem, 1, B_RELATIVE_TIMEOUT, 0);
|
||||
}
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
|
||||
pPacket = (PLM_PACKET)
|
||||
QQ_PopHead(&pUmDevice->RxPacketReadQ.Container);
|
||||
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
|
||||
restore_interrupts(cpu);
|
||||
|
||||
if (pPacket == 0) {
|
||||
*numBytes = -1;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
pUmPacket = (struct B_UM_PACKET *) pPacket;
|
||||
if ((pPacket->PacketStatus != LM_STATUS_SUCCESS) ||
|
||||
((pPacket->PacketSize) > 1518)) {
|
||||
|
||||
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);
|
||||
restore_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);
|
||||
|
||||
restore_interrupts(cpu);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t b57_write(void *cookie,off_t pos,const void *data,size_t *numBytes) {
|
||||
|
||||
static 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;
|
||||
|
||||
|
||||
/*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 = (struct B_UM_PACKET *)pPacket;
|
||||
pUmPacket->data = chunk_pool_get();
|
||||
|
||||
|
||||
memcpy(pUmPacket->data,data,*numBytes); /* no guarantee data is contiguous, so we have to copy */
|
||||
pPacket->PacketSize = pUmPacket->size = *numBytes;
|
||||
|
||||
|
||||
pPacket->u.Tx.FragCount = 1;
|
||||
pPacket->Flags = 0;
|
||||
|
||||
|
||||
tx_cleanup_thread(pUmDevice);
|
||||
|
||||
|
||||
cpu = disable_interrupts();
|
||||
acquire_spinlock(&pUmDevice->lock);
|
||||
|
||||
|
||||
LM_SendPacket(pDevice, pPacket);
|
||||
|
||||
|
||||
release_spinlock(&pUmDevice->lock);
|
||||
enable_interrupts(cpu);
|
||||
|
||||
restore_interrupts(cpu);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
/* -------- 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_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 *pValue16)
|
||||
{
|
||||
*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_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT16 Value16)
|
||||
{
|
||||
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_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 *pValue32)
|
||||
{
|
||||
*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_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
|
||||
LM_UINT32 Value32)
|
||||
{
|
||||
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));
|
||||
|
||||
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];
|
||||
|
||||
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, 0,
|
||||
(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);
|
||||
|
||||
/*
|
||||
LM_STATUS
|
||||
MM_MapIoBase(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
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) {
|
||||
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_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) {
|
||||
|
||||
LM_STATUS
|
||||
MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int32 tx_cleanup_thread(void *us) {
|
||||
|
||||
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);
|
||||
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);
|
||||
enable_interrupts(cpu);
|
||||
restore_interrupts(cpu);
|
||||
}
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
@ -732,41 +807,54 @@ int32 tx_cleanup_thread(void *us) {
|
||||
/*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_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_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, 0);
|
||||
// ToDo: B_LOMEM???
|
||||
|
||||
if (area_desc < B_OK)
|
||||
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){
|
||||
|
||||
LM_STATUS
|
||||
MM_GetConfig(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
pDevice->DisableAutoNeg = FALSE;
|
||||
pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO;
|
||||
pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
|
||||
@ -784,10 +872,13 @@ LM_STATUS MM_GetConfig(PLM_DEVICE_BLOCK pDevice){
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LM_STATUS MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status) {
|
||||
|
||||
LM_STATUS
|
||||
MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status) {
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
LM_STATUS
|
||||
MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice)
|
||||
{
|
||||
@ -795,7 +886,7 @@ MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice)
|
||||
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;
|
||||
@ -821,16 +912,28 @@ LM_STATUS MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket) {
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MM_UnmapRxDma(LM_DEVICE_BLOCK *pDevice, LM_PACKET *pPacket) {}
|
||||
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) */
|
||||
{
|
||||
/* Our buffers are pre-coalesced (which slows things down a little) */
|
||||
return LM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
LM_DEVICE_BLOCK *
|
||||
MM_FindPeerDev(LM_DEVICE_BLOCK *pDevice)
|
||||
{return 0;} /* I have no idea what this routine does. I think it's optional... */
|
||||
{
|
||||
/* I have no idea what this routine does. I think it's optional... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
LM_STATUS
|
||||
MM_Sleep(LM_DEVICE_BLOCK *pDevice, LM_UINT32 msec)
|
||||
|
Loading…
x
Reference in New Issue
Block a user