|
|
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.