1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2007 Christophe Fillot (cf@utc.fr)
4 *
5 * WIC Modules.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <unistd.h>
13 #include <time.h>
14 #include <errno.h>
15 #include <assert.h>
16
17 #include "utils.h"
18 #include "net.h"
19 #include "net_io.h"
20 #include "ptask.h"
21 #include "vm.h"
22 #include "dev_nm_16esw.h"
23 #include "dev_mpc860.h"
24 #include "dev_c1700.h"
25 #include "dev_wic_serial.h"
26
27 /* Get the SCC channel associated to a WIC sub-slot */
dev_c1700_mb_wic_get_scc_chan(struct cisco_card * card,u_int port_id,u_int * scc_chan)28 static int dev_c1700_mb_wic_get_scc_chan(struct cisco_card *card,u_int port_id,
29 u_int *scc_chan)
30 {
31 u_int cid;
32
33 cid = card->subslot_id + port_id;
34
35 switch(cid) {
36 /* WIC 0 port 0 mapped to MPC860 SCC1 */
37 case 0x10:
38 *scc_chan = 0;
39 break;
40
41 /* WIC 0 port 1 mapped to MPC860 SCC4 */
42 case 0x11:
43 *scc_chan = 3;
44 break;
45
46 /* WIC 1 port 0 mapped to MPC860 SCC2 */
47 case 0x20:
48 *scc_chan = 1;
49 break;
50
51 /* WIC 1 port 1 mapped to MPC860 SCC3 */
52 case 0x21:
53 *scc_chan = 2;
54 break;
55
56 default:
57 return(-1);
58 }
59
60 return(0);
61 }
62
63 /* ======================================================================== */
64 /* WIC-1T */
65 /* ======================================================================== */
66
67 /* Initialize a WIC-1T in the specified slot */
dev_c1700_mb_wic1t_init(vm_instance_t * vm,struct cisco_card * card)68 static int dev_c1700_mb_wic1t_init(vm_instance_t *vm,struct cisco_card *card)
69 {
70 struct wic_serial_data *wic_data;
71 m_uint64_t phys_addr;
72 u_int wic_id;
73
74 /* Create the WIC device */
75 wic_id = (card->subslot_id >> 4) - 1;
76
77 if (c1700_get_onboard_wic_addr(wic_id,&phys_addr) == -1) {
78 vm_error(vm,"WIC","invalid slot %u (subslot_id=%u)\n",
79 wic_id,card->subslot_id);
80 return(-1);
81 }
82
83 wic_data = dev_wic_serial_init(vm,card->dev_name,WIC_SERIAL_MODEL_1T,
84 phys_addr,C1700_WIC_SIZE);
85
86 if (!wic_data)
87 return(-1);
88
89 /* Set the EEPROM */
90 cisco_card_set_eeprom(vm,card,cisco_eeprom_find_wic("WIC-1T"));
91
92 /* Store device info into the router structure */
93 card->drv_info = wic_data;
94 return(0);
95 }
96
97 /* Remove a WIC-1T from the specified slot */
98 static int
dev_c1700_mb_wic1t_shutdown(vm_instance_t * vm,struct cisco_card * card)99 dev_c1700_mb_wic1t_shutdown(vm_instance_t *vm,struct cisco_card *card)
100 {
101 /* Remove the WIC device */
102 dev_wic_serial_remove(card->drv_info);
103
104 /* Remove the WIC EEPROM */
105 cisco_card_unset_eeprom(card);
106 return(0);
107 }
108
109 /* Bind a Network IO descriptor */
110 static int
dev_c1700_mb_wic1t_set_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id,netio_desc_t * nio)111 dev_c1700_mb_wic1t_set_nio(vm_instance_t *vm,struct cisco_card *card,
112 u_int port_id,netio_desc_t *nio)
113 {
114 u_int scc_chan;
115
116 if ((port_id > 0) ||
117 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
118 return(-1);
119
120 return(mpc860_scc_set_nio(VM_C1700(vm)->mpc_data,scc_chan,nio));
121 }
122
123 /* Unbind a Network IO descriptor */
124 static int
dev_c1700_mb_wic1t_unset_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id)125 dev_c1700_mb_wic1t_unset_nio(vm_instance_t *vm,struct cisco_card *card,
126 u_int port_id)
127 {
128 u_int scc_chan;
129
130 if ((port_id > 0) ||
131 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
132 return(-1);
133
134 return(mpc860_scc_unset_nio(VM_C1700(vm)->mpc_data,scc_chan));
135 }
136
137 /* ======================================================================== */
138 /* WIC-2T */
139 /* ======================================================================== */
140
141 /* Initialize a WIC-2T in the specified slot */
dev_c1700_mb_wic2t_init(vm_instance_t * vm,struct cisco_card * card)142 static int dev_c1700_mb_wic2t_init(vm_instance_t *vm,struct cisco_card *card)
143 {
144 struct wic_serial_data *wic_data;
145 m_uint64_t phys_addr;
146 u_int wic_id;
147
148 /* Create the WIC device */
149 wic_id = (card->subslot_id >> 4) - 1;
150
151 if (c1700_get_onboard_wic_addr(wic_id,&phys_addr) == -1) {
152 vm_error(vm,"WIC","invalid slot %u (subslot_id=%u)\n",
153 wic_id,card->subslot_id);
154 return(-1);
155 }
156
157 wic_data = dev_wic_serial_init(vm,card->dev_name,WIC_SERIAL_MODEL_2T,
158 phys_addr,C1700_WIC_SIZE);
159
160 if (!wic_data)
161 return(-1);
162
163 /* Set the EEPROM */
164 cisco_card_set_eeprom(vm,card,cisco_eeprom_find_wic("WIC-2T"));
165
166 /* Store device info into the router structure */
167 card->drv_info = wic_data;
168 return(0);
169 }
170
171 /* Remove a WIC-2T from the specified slot */
172 static int
dev_c1700_mb_wic2t_shutdown(vm_instance_t * vm,struct cisco_card * card)173 dev_c1700_mb_wic2t_shutdown(vm_instance_t *vm,struct cisco_card *card)
174 {
175 /* Remove the WIC device */
176 dev_wic_serial_remove(card->drv_info);
177
178 /* Remove the WIC EEPROM */
179 cisco_card_unset_eeprom(card);
180 return(0);
181 }
182
183 /* Bind a Network IO descriptor */
184 static int
dev_c1700_mb_wic2t_set_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id,netio_desc_t * nio)185 dev_c1700_mb_wic2t_set_nio(vm_instance_t *vm,struct cisco_card *card,
186 u_int port_id,netio_desc_t *nio)
187 {
188 u_int scc_chan;
189
190 if ((port_id > 1) ||
191 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
192 return(-1);
193
194 return(mpc860_scc_set_nio(VM_C1700(vm)->mpc_data,scc_chan,nio));
195 }
196
197 /* Unbind a Network IO descriptor */
198 static int
dev_c1700_mb_wic2t_unset_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id)199 dev_c1700_mb_wic2t_unset_nio(vm_instance_t *vm,struct cisco_card *card,
200 u_int port_id)
201 {
202 u_int scc_chan;
203
204 if ((port_id > 1) ||
205 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
206 return(-1);
207
208 return(mpc860_scc_unset_nio(VM_C1700(vm)->mpc_data,scc_chan));
209 }
210
211 /* ======================================================================== */
212 /* WIC-1ENET */
213 /* ======================================================================== */
214
215 /* Initialize a WIC-1ENET in the specified slot */
216 static int
dev_c1700_mb_wic1enet_init(vm_instance_t * vm,struct cisco_card * card)217 dev_c1700_mb_wic1enet_init(vm_instance_t *vm,struct cisco_card *card)
218 {
219 m_uint8_t eeprom_ver;
220 size_t offset;
221 n_eth_addr_t addr;
222 m_uint16_t pid;
223
224 pid = (m_uint16_t)getpid();
225
226 /* Generate automatically the MAC address */
227 addr.eth_addr_byte[0] = vm_get_mac_addr_msb(vm);
228 addr.eth_addr_byte[1] = vm->instance_id & 0xFF;
229 addr.eth_addr_byte[2] = pid >> 8;
230 addr.eth_addr_byte[3] = pid & 0xFF;
231 addr.eth_addr_byte[4] = card->subslot_id;
232 addr.eth_addr_byte[5] = 0x00;
233
234 /* Set the EEPROM */
235 cisco_card_set_eeprom(vm,card,cisco_eeprom_find_wic("WIC-1ENET"));
236
237 /* Read EEPROM format version */
238 cisco_eeprom_get_byte(&card->eeprom,0,&eeprom_ver);
239
240 if (eeprom_ver != 4)
241 return(-1);
242
243 if (cisco_eeprom_v4_find_field(&card->eeprom,0xCF,&offset) == -1)
244 return(-1);
245
246 cisco_eeprom_set_region(&card->eeprom,offset,addr.eth_addr_byte,6);
247
248 /* Store device info into the router structure */
249 card->drv_info = VM_C1700(vm)->mpc_data;
250 return(0);
251 }
252
253 /* Remove a WIC-1ENET from the specified slot */
254 static int
dev_c1700_mb_wic1enet_shutdown(vm_instance_t * vm,struct cisco_card * card)255 dev_c1700_mb_wic1enet_shutdown(vm_instance_t *vm,struct cisco_card *card)
256 {
257 /* Remove the WIC EEPROM */
258 cisco_card_unset_eeprom(card);
259 return(0);
260 }
261
262 /* Bind a Network IO descriptor */
263 static int
dev_c1700_mb_wic1enet_set_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id,netio_desc_t * nio)264 dev_c1700_mb_wic1enet_set_nio(vm_instance_t *vm,struct cisco_card *card,
265 u_int port_id,netio_desc_t *nio)
266 {
267 struct mpc860_data *mpc_data = card->drv_info;
268 u_int scc_chan;
269
270 if ((port_id > 0) ||
271 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
272 return(-1);
273
274 return(mpc860_scc_set_nio(mpc_data,scc_chan,nio));
275 }
276
277 /* Unbind a Network IO descriptor */
278 static int
dev_c1700_mb_wic1enet_unset_nio(vm_instance_t * vm,struct cisco_card * card,u_int port_id)279 dev_c1700_mb_wic1enet_unset_nio(vm_instance_t *vm,struct cisco_card *card,
280 u_int port_id)
281 {
282 struct mpc860_data *mpc_data = card->drv_info;
283 u_int scc_chan;
284
285 if ((port_id > 0) ||
286 (dev_c1700_mb_wic_get_scc_chan(card,port_id,&scc_chan) == -1))
287 return(-1);
288
289 return(mpc860_scc_unset_nio(mpc_data,scc_chan));
290 }
291
292 /* ======================================================================== */
293
294 /* Cisco 1700 WIC-1T driver */
295 struct cisco_card_driver dev_c1700_mb_wic1t_driver = {
296 "WIC-1T", 1, 0,
297 dev_c1700_mb_wic1t_init,
298 dev_c1700_mb_wic1t_shutdown,
299 NULL,
300 dev_c1700_mb_wic1t_set_nio,
301 dev_c1700_mb_wic1t_unset_nio,
302 NULL,
303 };
304
305 /* Cisco 1700 WIC-2T driver */
306 struct cisco_card_driver dev_c1700_mb_wic2t_driver = {
307 "WIC-2T", 1, 0,
308 dev_c1700_mb_wic2t_init,
309 dev_c1700_mb_wic2t_shutdown,
310 NULL,
311 dev_c1700_mb_wic2t_set_nio,
312 dev_c1700_mb_wic2t_unset_nio,
313 NULL,
314 };
315
316 /* Cisco 1700 WIC-1ENET driver */
317 struct cisco_card_driver dev_c1700_mb_wic1enet_driver = {
318 "WIC-1ENET", 1, 0,
319 dev_c1700_mb_wic1enet_init,
320 dev_c1700_mb_wic1enet_shutdown,
321 NULL,
322 dev_c1700_mb_wic1enet_set_nio,
323 dev_c1700_mb_wic1enet_unset_nio,
324 NULL,
325 };
326
327 /* WIC drivers (mainbord slots) */
328 struct cisco_card_driver *dev_c1700_mb_wic_drivers[] = {
329 &dev_c1700_mb_wic1t_driver,
330 &dev_c1700_mb_wic2t_driver,
331 &dev_c1700_mb_wic1enet_driver,
332 NULL,
333 };
334