From 07815bc5208ec72395601f998a9801c48cf47ca3 Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 3 May 2004 23:27:26 +0000 Subject: [PATCH] The driver interface detects the cards and publishes defs entries. util.* provide a convenience function to map physical memory. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7397 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/network/ipro1000/driver.c | 191 ++++++++++++++++++ .../kernel/drivers/network/ipro1000/driver.h | 33 +++ .../drivers/network/ipro1000/ether_driver.h | 39 ++++ .../kernel/drivers/network/ipro1000/setup.h | 11 + .../kernel/drivers/network/ipro1000/util.c | 44 ++++ .../kernel/drivers/network/ipro1000/util.h | 26 +++ 6 files changed, 344 insertions(+) create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/driver.c create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/driver.h create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/ether_driver.h create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/setup.h create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/util.c create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/util.h diff --git a/src/add-ons/kernel/drivers/network/ipro1000/driver.c b/src/add-ons/kernel/drivers/network/ipro1000/driver.c new file mode 100644 index 0000000000..3c8ab8159b --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/driver.c @@ -0,0 +1,191 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#include +#include +#include +#include +#include + +//#define DEBUG + +#include "debug.h" +#include "device.h" +#include "driver.h" +#include "mempool.h" + +int32 api_version = B_CUR_DRIVER_API_VERSION; + +pci_module_info *gPci; + +char* gDevNameList[MAX_CARDS + 1]; +pci_info *gDevList[MAX_CARDS]; + +const char * +identify_device(const pci_info *info) +{ + if (info->vendor_id != 0x8086) + return 0; + switch (info->device_id) { + case 0x1000: return "82542"; + case 0x1001: return "82543GC FIBER"; + case 0x1004: return "82543GC COPPER"; + case 0x1008: return "82544EI COPPER"; + case 0x1009: return "82544EI FIBER"; + case 0x100C: return "82544GC COPPER"; + case 0x100D: return "82544GC LOM"; + case 0x100E: return "82540EM"; + case 0x100F: return "82545EM COPPER"; + case 0x1010: return "82546EB COPPER"; + case 0x1011: return "82545EM FIBER"; + case 0x1012: return "82546EB FIBER"; + case 0x1013: return "82541EI"; + case 0x1014: return "unknown 1014"; + case 0x1015: return "82540EM LOM"; + case 0x1016: return "82540EP LOM"; + case 0x1017: return "82540EP"; + case 0x1018: return "82541EI MOBILE"; + case 0x1019: return "82547EI"; + case 0x101A: return "unknown 101A"; + case 0x101D: return "82546EB QUAD COPPER"; + case 0x101E: return "82540EP LP"; + case 0x1026: return "82545GM COPPER"; + case 0x1027: return "82545GM FIBER"; + case 0x1028: return "82545GM SERDES"; + case 0x1075: return "82547GI"; + case 0x1076: return "82541GI"; + case 0x1077: return "82541GI MOBILE"; + case 0x1078: return "82541ER"; + case 0x1079: return "82546GB COPPER"; + case 0x107A: return "82546GB FIBER"; + case 0x107B: return "82546GB SERDES"; + default: return 0; + } +} + +status_t +init_hardware(void) +{ + pci_module_info *pci; + pci_info info; + status_t res; + int i; + + TRACE("init_hardware()\n"); + + if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci) < B_OK) + return B_ERROR; + for (res = B_ERROR, i = 0; pci->get_nth_pci_info(i, &info) == B_OK; i++) { + if (identify_device(&info)) { + res = B_OK; + break; + } + } + put_module(B_PCI_MODULE_NAME); + + return res; +} + + +status_t +init_driver(void) +{ + struct pci_info *item; + int index; + int cards; + +#ifdef DEBUG + set_dprintf_enabled(true); + load_driver_symbols("ipro1000"); +#endif + + dprintf(INFO1"\n"); + dprintf(INFO2"\n"); + dprintf(INFO3"\n"); + + item = (pci_info *)malloc(sizeof(pci_info)); + if (!item) + return B_NO_MEMORY; + + if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) + return B_ERROR; + + for (cards = 0, index = 0; gPci->get_nth_pci_info(index++, item) == B_OK; ) { + const char *info = identify_device(item); + if (info) { + char name[64]; + sprintf(name, "net/ipro1000/%d", cards); + TRACE("/dev/%s is a %s\n", name, info); + gDevList[cards] = item; + gDevNameList[cards] = strdup(name); + gDevNameList[cards + 1] = NULL; + cards++; + item = (pci_info *)malloc(sizeof(pci_info)); + if (!item) + return B_OK; // already found 1 card, but out of memory + if (cards == MAX_CARDS) + break; + } + } + + TRACE("found %d cards\n", cards); + + free(item); + + if (!cards) + goto err; + + if (mempool_init(cards * 768) != 0) { + TRACE("mempool init failed\n"); + goto err; + } + + return B_OK; + +err: + put_module(B_PCI_MODULE_NAME); + return B_ERROR; +} + + +void +uninit_driver(void) +{ + int32 i; + + TRACE("uninit_driver()\n"); + + mempool_exit(); + + for (i = 0; gDevNameList[i] != NULL; i++) { + free(gDevList[i]); + free(gDevNameList[i]); + } + + put_module(B_PCI_MODULE_NAME); +} + + +device_hooks +gDeviceHooks = { + ipro1000_open, + ipro1000_close, + ipro1000_free, + ipro1000_control, + ipro1000_read, + ipro1000_write, +}; + + +const char** +publish_devices() +{ + return (const char**)gDevNameList; +} + + +device_hooks* +find_device(const char* name) +{ + return &gDeviceHooks; +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/driver.h b/src/add-ons/kernel/drivers/network/ipro1000/driver.h new file mode 100644 index 0000000000..72a28c33e0 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/driver.h @@ -0,0 +1,33 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . 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 __DRIVER_H +#define __DRIVER_H + +#include +#include +#include "ether_driver.h" + +#define MAX_CARDS 8 + +extern pci_module_info *gPci; + +extern char* gDevNameList[]; +extern pci_info *gDevList[]; + +#endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/ether_driver.h b/src/add-ons/kernel/drivers/network/ipro1000/ether_driver.h new file mode 100644 index 0000000000..e25f369b4a --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/ether_driver.h @@ -0,0 +1,39 @@ +#ifndef _ETHER_DRIVER_H +#define _ETHER_DRIVER_H + +#include + +/* + * ioctls: belongs in a public header file + * somewhere, so that the net_server and other ethernet drivers can use. + */ +enum { + ETHER_GETADDR = B_DEVICE_OP_CODES_END, /* get ethernet address */ + ETHER_INIT, /* set irq and port */ + ETHER_NONBLOCK, /* set/unset nonblocking mode */ + ETHER_ADDMULTI, /* add multicast addr */ + ETHER_REMMULTI, /* rem multicast addr */ + ETHER_SETPROMISC, /* set promiscuous */ + ETHER_GETFRAMESIZE /* get frame size */ +}; + + +/* + * 48-bit ethernet address, passed back from ETHER_GETADDR + */ +typedef struct { + unsigned char ebyte[6]; +} ether_address_t; + + +/* + * info passed to ETHER_INIT + */ + +typedef struct ether_init_params { + short port; + short irq; + unsigned long mem; +} ether_init_params_t; + +#endif /* _ETHER_DRIVER_H */ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/setup.h b/src/add-ons/kernel/drivers/network/ipro1000/setup.h new file mode 100644 index 0000000000..493ac4bb01 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/setup.h @@ -0,0 +1,11 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#ifndef __SETUP_H +#define __SETUP_H + +#define INFO1 "ipro1000: Intel PRO/1000 Family Driver. Version 0.1 Build " __DATE__ " "__TIME__ +#define INFO2 "ipro1000: Copyright (c) 2001-2003, Intel Corporation. All rights reserved." +#define INFO3 "ipro1000: Copyright (c) 2004 Marcus Overhagen. All rights reserved." + +#endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/util.c b/src/add-ons/kernel/drivers/network/ipro1000/util.c new file mode 100644 index 0000000000..7379c0d313 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/util.c @@ -0,0 +1,44 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#include +#include +#include + +//#define DEBUG + +#include "debug.h" +#include "util.h" + +static inline uint32 +round_to_pagesize(uint32 size) +{ + return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); +} + +area_id +map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name) +{ + uint32 offset; + void *phyadr; + void *mapadr; + area_id area; + + TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, name); + + offset = (uint32)phy & (B_PAGE_SIZE - 1); + phyadr = (char *)phy - offset; + size = round_to_pagesize(size + offset); + area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr); + if (area < B_OK) { + ERROR("mapping '%s' failed, error 0x%lx (%s)\n", name, area, strerror(area)); + return area; + } + + *virt = (char *)mapadr + offset; + + TRACE("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = %p, size = %ld, area = 0x%08lx\n", + phy, *virt, offset, phyadr, mapadr, size, area); + + return area; +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/util.h b/src/add-ons/kernel/drivers/network/ipro1000/util.h new file mode 100644 index 0000000000..b25b3cf584 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/util.h @@ -0,0 +1,26 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . 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 __UTIL_H +#define __UTIL_H + +#include + +area_id map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name); + +#endif