|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: #include <netdriver_int.h> ! 14: #include <kernel.h> ! 15: #include <of.h> ! 16: #include <rtas.h> ! 17: #include <cpu.h> /* flush_cache */ ! 18: //#include <stdlib.h> /* malloc */ ! 19: #include <unistd.h> /* open, close, read, write */ ! 20: ! 21: unsigned int read_io(void *, size_t); ! 22: int write_io(void *, unsigned int, size_t); ! 23: ! 24: extern void get_mac(char *mac); ! 25: extern snk_module_t of_module; ! 26: ! 27: typedef snk_module_t *(*module_init_t) (snk_kernel_t *, pci_config_t *); ! 28: ! 29: typedef struct { ! 30: const char *name; ! 31: void *link_addr; ! 32: int type; ! 33: } mod_descriptor_t; ! 34: ! 35: static const mod_descriptor_t modules[] = { ! 36: { "net_e1000" , (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 37: { "net_bcm" , (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 38: { "net_nx203x", (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 39: { "net_mcmal" , (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 40: { "net_spider", (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 41: { "net_veth", (void*) 0xF800000, MOD_TYPE_NETWORK }, ! 42: { 0 , (void*) 0 } ! 43: }; ! 44: ! 45: snk_module_t *snk_modules[MODULES_MAX]; ! 46: ! 47: extern snk_kernel_t snk_kernel_interface; ! 48: ! 49: /* Load module and call init code. ! 50: Init code will check, if module is responsible for device. ! 51: Returns -1, if not responsible for device, 0 otherwise. ! 52: */ ! 53: ! 54: static int ! 55: load_module(const char *name) ! 56: { ! 57: int len, i; ! 58: void *addr; ! 59: void *link_addr; ! 60: module_init_t module_init; ! 61: ! 62: /* find module in module list and lookup link address */ ! 63: for(i=0; modules[i].name; ++i) { ! 64: if(strcmp(modules[i].name, name) == 0) ! 65: break; ! 66: } ! 67: if( modules[i].name == 0 ) { ! 68: /* module not in list */ ! 69: return -1; ! 70: } ! 71: link_addr = modules[i].link_addr; ! 72: ! 73: /* check if link address is used already */ ! 74: for(i=0; i<MODULES_MAX; ++i) { ! 75: if(snk_modules[i] && snk_modules[i]->link_addr == link_addr) { ! 76: /* busy, can't load modules */ ! 77: return -2; ! 78: } ! 79: } ! 80: ! 81: /* find empty position in array of loaded modules */ ! 82: for(i=0; i<MODULES_MAX; ++i) { ! 83: if(snk_modules[i] == 0) { ! 84: break; ! 85: } ! 86: } ! 87: if(i == MODULES_MAX) { ! 88: // no space avaliable! ! 89: return -3; ! 90: } ! 91: ! 92: /* Read module from FLASH */ ! 93: len = romfs_lookup(name, &addr); ! 94: if (len <= 0) { ! 95: /* file not found */ ! 96: return -4; ! 97: } ! 98: /* Copy image from flash to RAM ! 99: * FIXME fix address 8MB ! 100: */ ! 101: ! 102: memcpy(link_addr, addr, len); ! 103: ! 104: flush_cache(link_addr, len); ! 105: ! 106: /* Module starts with opd structure of the module_init ! 107: * function. ! 108: */ ! 109: module_init = (module_init_t) link_addr; ! 110: ! 111: snk_modules[i] = module_init(&snk_kernel_interface, &snk_kernel_interface.pci_conf); ! 112: if(snk_modules[i] == 0) { ! 113: /* no device found that can be managed by this module */ ! 114: return -5; ! 115: } ! 116: ! 117: if(snk_modules[i]->type == MOD_TYPE_NETWORK) { ! 118: /* Get mac address from device tree */ ! 119: get_mac(snk_modules[i]->mac_addr); ! 120: } ! 121: ! 122: return i; ! 123: } ! 124: ! 125: void ! 126: modules_init(void) ! 127: { ! 128: int i; ! 129: ! 130: snk_kernel_interface.io_read = read_io; ! 131: snk_kernel_interface.io_write = write_io; ! 132: ! 133: snk_modules[0] = &of_module; ! 134: ! 135: /* Setup Module List */ ! 136: for(i=1; i<MODULES_MAX; ++i) { ! 137: snk_modules[i] = 0; ! 138: } ! 139: ! 140: /* Load all modules */ ! 141: for(i=0; modules[i].name; ++i) { ! 142: load_module(modules[i].name); ! 143: } ! 144: } ! 145: ! 146: void ! 147: modules_term() ! 148: { ! 149: int i; ! 150: ! 151: /* remove all modules */ ! 152: for(i=0; i<MODULES_MAX; ++i) { ! 153: if(snk_modules[i] && snk_modules[i]->running != 0) { ! 154: snk_modules[i]->term(); ! 155: } ! 156: snk_modules[i] = 0; ! 157: } ! 158: } ! 159: ! 160: snk_module_t * ! 161: get_module_by_type(int type) { ! 162: int i; ! 163: ! 164: for(i=0; i<MODULES_MAX; ++i) { ! 165: if(snk_modules[i] && snk_modules[i]->type == type) { ! 166: return snk_modules[i]; ! 167: } ! 168: } ! 169: return 0; ! 170: } ! 171: ! 172: /** ! 173: * insmod_by_type - Load first module of given type ! 174: * ! 175: * @param type Type of module that we want to load ! 176: * @return module descriptor on success ! 177: * NULL if not successful ! 178: */ ! 179: snk_module_t * ! 180: insmod_by_type(int type) { ! 181: int i, j; ! 182: for(i = 0; modules[i].name; ++i) { ! 183: if(modules[i].type != type) ! 184: continue; ! 185: j = load_module(modules[i].name); ! 186: if(j >= 0) ! 187: return snk_modules[j]; ! 188: } ! 189: return 0; ! 190: } ! 191: ! 192: /** ! 193: * rmmod_by_type - Remove all module of given type ! 194: * ! 195: * @param type Type of module that we want to load ! 196: */ ! 197: void ! 198: rmmod_by_type(int type) { ! 199: int i; ! 200: ! 201: for (i = 0; i < MODULES_MAX; ++i) { ! 202: if (snk_modules[i] && snk_modules[i]->type == type) { ! 203: if (snk_modules[i]->running) ! 204: snk_modules[i]->term(); ! 205: snk_modules[i] = 0; ! 206: } ! 207: } ! 208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.