blob: 4b092a03a408f32f813850b88cef893e19870fc0 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
2 *
3 * <:copyright-BRCM:2016:DUAL/GPL:standard
4 *
5 * Copyright (c) 2016 Broadcom
6 * All Rights Reserved
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed
10 * to you under the terms of the GNU General Public License version 2
11 * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
12 * with the following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give
15 * you permission to link this software with independent modules, and
16 * to copy and distribute the resulting executable under terms of your
17 * choice, provided that you also meet, for each linked independent
18 * module, the terms and conditions of the license of that module.
19 * An independent module is a module which is not derived from this
20 * software. The special exception does not apply to any modifications
21 * of the software.
22 *
23 * Not withstanding the above, under no circumstances may you combine
24 * this software in any way with any other Broadcom software provided
25 * under a license other than the GPL, without Broadcom's express prior
26 * written consent.
27 *
28 * :>
29 *
30 *****************************************************************************/
31
32#include <bcm_dev_log.h>
33#include <bcmolt_math.h>
34#include "bcm_topo.h"
35
36#define BCM_TOPO_MAX_LINE_SIZE 256
37#define BCM_TOPO_MAX_NNI_DEVICES 1
38
39uint32_t g_max_nni_ports[BCM_TOPO_MAX_NNI_DEVICES] = {BCM_TOPO_MAX_NNI_PORTS};
40
41typedef struct bcm_topo_dev_context_t bcm_topo_dev_context_t;
42
43typedef struct
44{
45 bcm_topo_dev_context_t *dev; /* Back pointer to the physical device this PON belongs to */
46 bcmos_bool is_initialized;
47 uint32_t pon_id;
48 uint32_t logical_pon;
49 bcm_topo_pon_mode pon_mode;
50 uint32_t max_num_of_onus;
51 void *contexts[BCM_TOPO_PON_CONTEXT_ID__NUM_OF]; /* User context - 1 entry per user */
52} bcm_topo_pon_context_t;
53
54struct bcm_topo_dev_context_t
55{
56 bcm_topo_pon_mode pon_mode; /* Currently we do not allow more than one PON mode per device (e.g: GPONx8 + XGPONx4) */
57 bcmos_bool is_initialized;
58 uint32_t device_id;
59 uint32_t max_num_of_pons;
60 bcm_topo_pon_context_t pons[BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV];
61};
62
63typedef struct
64{
65 bcmos_bool is_initialized;
66 bcm_topo_dev_context_t devs[BCM_TOPO_MAX_NUM_OF_DEVS];
67 bcm_topo_pon_context_t *logical_pon2physical_pon[BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS];
68} bcm_topo_context_t;
69
70static bcm_topo_context_t bcm_topo_context;
71
72#ifdef ENABLE_LOG
73static dev_log_id topo_log_id = DEV_LOG_INVALID_ID;
74#endif
75
76static int2str_t pon_mode2str[] =
77{
78 {BCM_TOPO_PON_MODE_GPON, "gpon"},
79 {BCM_TOPO_PON_MODE_XGPON, "xgpon"},
80 {BCM_TOPO_PON_MODE_XGS, "xgs"},
81 {BCM_TOPO_PON_MODE_EPON_TDMA, "epon_tdma"},
82 {BCM_TOPO_PON_MODE_EPON_1G, "epon_1g"},
83 {BCM_TOPO_PON_MODE_EPON_10G, "epon_10g"},
84 {-1},
85};
86
87static int2int_t pon_mode2max_num_of_pons[] =
88{
89 {BCM_TOPO_PON_MODE_GPON, 16},
90 {BCM_TOPO_PON_MODE_XGPON, 8},
91 {BCM_TOPO_PON_MODE_XGS, 2},
92 {BCM_TOPO_PON_MODE_EPON_TDMA, 8},
93 {BCM_TOPO_PON_MODE_EPON_1G, 16},
94 {BCM_TOPO_PON_MODE_EPON_10G, 8},
95 {-1},
96};
97
98const char *bcm_topo_dev_get_pon_mode_str(bcmolt_devid device_id)
99{
100 return int2str(pon_mode2str, bcm_topo_context.devs[device_id].pon_mode);
101}
102
103int bcm_topo_dev_get_max_pon(bcmolt_devid device_id)
104{
105 return int2int(pon_mode2max_num_of_pons, bcm_topo_context.devs[device_id].pon_mode);
106}
107
108bcm_topo_pon_mode bcm_topo_pon_get_pon_mode(uint32_t pon)
109{
110 bcmolt_devid device_id;
111 uint32_t physical_pon;
112 bcmos_errno rc;
113
114 rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
115 if (rc != BCM_ERR_OK)
116 return BCM_TOPO_PON_MODE_INVALID;
117
118 return bcm_topo_context.devs[device_id].pons[physical_pon].pon_mode;
119}
120
121bcm_topo_pon_family bcm_topo_pon_get_pon_family(uint32_t pon)
122{
123 switch (bcm_topo_pon_get_pon_mode(pon))
124 {
125 case BCM_TOPO_PON_MODE_GPON:
126 case BCM_TOPO_PON_MODE_XGPON:
127 case BCM_TOPO_PON_MODE_XGS:
128 return BCM_TOPO_PON_FAMILY_GPON;
129 case BCM_TOPO_PON_MODE_EPON_TDMA:
130 case BCM_TOPO_PON_MODE_EPON_1G:
131 case BCM_TOPO_PON_MODE_EPON_10G:
132 return BCM_TOPO_PON_FAMILY_EPON;
133 default:
134 return BCM_TOPO_PON_FAMILY_INVALID;
135 }
136}
137
138bcm_topo_pon_sub_family bcm_topo_pon_get_pon_sub_family(uint32_t pon)
139{
140 switch (bcm_topo_pon_get_pon_mode(pon))
141 {
142 case BCM_TOPO_PON_MODE_GPON:
143 return BCM_TOPO_PON_SUB_FAMILY_GPON;
144 case BCM_TOPO_PON_MODE_XGPON:
145 case BCM_TOPO_PON_MODE_XGS:
146 return BCM_TOPO_PON_SUB_FAMILY_XGPON;
147 case BCM_TOPO_PON_MODE_EPON_TDMA:
148 case BCM_TOPO_PON_MODE_EPON_1G:
149 case BCM_TOPO_PON_MODE_EPON_10G:
150 return BCM_TOPO_PON_SUB_FAMILY_EPON;
151 default:
152 return BCM_TOPO_PON_SUB_FAMILY_INVALID;
153 }
154}
155
156uint32_t bcm_topo_pon_get_max_num_of_onus(uint32_t pon)
157{
158 bcmolt_devid device_id;
159 uint32_t physical_pon;
160 bcmos_errno rc;
161
162 rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
163 if (rc != BCM_ERR_OK)
164 return BCM_TOPO_ERR_INVALID;
165
166 return bcm_topo_context.devs[device_id].pons[physical_pon].max_num_of_onus;
167}
168
169bcmos_bool bcm_topo_pon_is_valid(uint32_t pon)
170{
171 bcmolt_devid device_id;
172 uint32_t physical_pon;
173
174 if (bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon) != BCM_ERR_OK)
175 return BCMOS_FALSE;
176
177 return BCMOS_TRUE;
178}
179
180bcmolt_devid bcm_topo_dev_get_next(bcmolt_devid device_id)
181{
182 if (device_id == BCM_TOPO_DEV_INVALID)
183 device_id = 0;
184 else
185 device_id++;
186
187 for (; device_id < BCM_TOPO_MAX_NUM_OF_DEVS && !bcm_topo_context.devs[device_id].is_initialized; device_id++);
188
189 return device_id == BCM_TOPO_MAX_NUM_OF_DEVS ? BCM_TOPO_DEV_INVALID : device_id;
190}
191
192uint32_t bcm_topo_pon_get_next(bcmolt_devid device_id, uint32_t pon)
193{
194 uint32_t physical_pon;
195 bcmos_errno rc;
196
197 if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
198 {
199 BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
200 return BCM_TOPO_PON_INVALID;
201 }
202
203 if (pon == BCM_TOPO_PON_INVALID)
204 physical_pon = 0;
205 else
206 {
207 bcmolt_devid dummy;
208
209 rc = bcm_topo_pon_get_logical2physical(pon, &dummy, &physical_pon);
210 if (rc != BCM_ERR_OK)
211 {
212 return BCM_TOPO_PON_INVALID;
213 }
214 else
215 {
216 physical_pon++;
217 }
218 }
219
220 if (physical_pon < bcm_topo_context.devs[device_id].max_num_of_pons)
221 {
222 rc = bcm_topo_pon_get_physical2logical(device_id, physical_pon, &pon);
223 if (rc != BCM_ERR_OK)
224 {
225 return BCM_TOPO_PON_INVALID;
226 }
227 else
228 {
229 return pon;
230 }
231 }
232
233 return BCM_TOPO_PON_INVALID;
234}
235
236bcmos_errno bcm_topo_pon_get_logical2physical(uint32_t logical_pon, bcmolt_devid *device_id, uint32_t *physical_pon)
237{
238 if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
239 {
240 BCM_LOG(ERROR, topo_log_id, "Logical PON ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
241 return BCM_ERR_RANGE;
242 }
243
244 if (!bcm_topo_context.logical_pon2physical_pon[logical_pon])
245 {
246 BCM_LOG(ERROR, topo_log_id, "Logical PON=%u was not associated with a physical PON\n", logical_pon);
247 return BCM_ERR_RANGE;
248 }
249
250 *physical_pon = bcm_topo_context.logical_pon2physical_pon[logical_pon]->pon_id;
251 *device_id = bcm_topo_context.logical_pon2physical_pon[logical_pon]->dev->device_id;
252
253 return BCM_ERR_OK;
254}
255
256bcmos_errno bcm_topo_pon_get_physical2logical(bcmolt_devid device_id, uint32_t physical_pon, uint32_t *logical_pon)
257{
258 if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
259 {
260 BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
261 return BCM_ERR_RANGE;
262 }
263
264 if (physical_pon >= bcm_topo_context.devs[device_id].max_num_of_pons)
265 {
266 BCM_LOG(ERROR, topo_log_id, "Physical PON ID must be in the range 0 .. %u\n", bcm_topo_context.devs[device_id].max_num_of_pons - 1);
267 return BCM_ERR_RANGE;
268 }
269
270 if (bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon == BCM_TOPO_PON_INVALID)
271 {
272 BCM_LOG(ERROR, topo_log_id, "Physical PON=%u on device=%u was not associated with a logical PON\n", physical_pon, device_id);
273 return BCM_ERR_RANGE;
274 }
275
276 *logical_pon = bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon;
277
278 return BCM_ERR_OK;
279}
280
281bcmos_errno bcm_topo_pon_set_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id, void *context)
282{
283 bcmolt_devid device_id;
284 uint32_t physical_pon;
285 bcmos_errno rc;
286
287 if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
288 {
289 BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
290 return BCM_ERR_RANGE;
291 }
292
293 rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
294 if (rc != BCM_ERR_OK)
295 return rc;
296
297 bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id] = context;
298
299 return BCM_ERR_OK;
300}
301
302void *bcm_topo_pon_get_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id)
303{
304 bcmolt_devid device_id;
305 uint32_t physical_pon;
306 bcmos_errno rc;
307
308 if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
309 {
310 BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
311 return NULL;
312 }
313
314 rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
315 if (rc != BCM_ERR_OK)
316 return NULL;
317
318 return bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id];
319}
320
321static void bcm_topo_init_context(void)
322{
323 uint32_t device_id;
324
325 for (device_id = 0; device_id < BCM_TOPO_MAX_NUM_OF_DEVS; device_id++)
326 {
327 bcm_topo_dev_context_t *dev;
328 uint32_t pon_id;
329
330 dev = &bcm_topo_context.devs[device_id];
331 dev->device_id = device_id;
332 dev->pon_mode = BCM_TOPO_PON_MODE_INVALID;
333 for (pon_id = 0; pon_id < BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV; pon_id++)
334 {
335 bcm_topo_pon_context_t *pon;
336
337 pon = &dev->pons[pon_id];
338 pon->dev = dev;
339 pon->pon_id = pon_id;
340 pon->pon_mode = BCM_TOPO_PON_MODE_INVALID;
341 pon->logical_pon = BCM_TOPO_PON_INVALID;
342 }
343 }
344}
345
346static bcmos_errno bcm_topo_init_line_parse(const char *line, const char *filename, uint32_t line_num, bcmos_bool *is_skipped, uint32_t *logical_pon, bcm_topo_pon_mode *pon_mode,
347 uint32_t *device_id, uint32_t *physical_pon)
348{
349 int rc;
350 char logical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
351 char pon_mode_str[BCM_TOPO_MAX_LINE_SIZE];
352 char device_id_str[BCM_TOPO_MAX_LINE_SIZE];
353 char physical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
354 int2str_t *p;
355
356 /* Skip blank lines and comments. */
357 if (!*line || *line == '\n' || *line == '#')
358 {
359 *is_skipped = BCMOS_TRUE;
360 return BCM_ERR_OK;
361 }
362
363 *is_skipped = BCMOS_FALSE;
364
365 /* Read the tokens separated by commas. */
366 rc = sscanf(line, "%[^,],%*[ ]%[^,],%[^,],%[^\n]", logical_pon_str, pon_mode_str, device_id_str, physical_pon_str);
367 if (rc < 4)
368 {
369 BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
370 return BCM_ERR_PARSE;
371 }
372
373 if (sscanf(logical_pon_str, "%u", logical_pon) < 1)
374 {
375 BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
376 return BCM_ERR_PARSE;
377 }
378
379 if (sscanf(device_id_str, "%u", device_id) < 1)
380 {
381 BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
382 return BCM_ERR_PARSE;
383 }
384
385 if (sscanf(physical_pon_str, "%u", physical_pon) < 1)
386 {
387 BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
388 return BCM_ERR_PARSE;
389 }
390
391 BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical Pon ID=%u, PON mode='%s')\n", *logical_pon, *device_id, *physical_pon, pon_mode_str);
392
393 for (p = pon_mode2str; p->from != -1 && strcmp(pon_mode_str, p->to); p++);
394
395 if (p->from == -1)
396 {
397 BCM_LOG(ERROR, topo_log_id, "Error parsing PON mode at %s:%u\n", filename, line_num);
398 return BCM_ERR_PARSE;
399 }
400
401 *pon_mode = p->from;
402
403 return BCM_ERR_OK;
404}
405
406static void bcm_topo_init_dev(bcm_topo_dev_context_t *dev, bcm_topo_pon_mode pon_mode)
407{
408 dev->pon_mode = pon_mode;
409 dev->max_num_of_pons = int2int(pon_mode2max_num_of_pons, pon_mode);
410}
411
412static void bcm_topo_init_pon(bcm_topo_pon_context_t *pon, bcm_topo_pon_mode pon_mode)
413{
414 pon->pon_mode = pon_mode;
415 switch (pon_mode)
416 {
417 case BCM_TOPO_PON_MODE_GPON:
418 pon->max_num_of_onus = 128;
419 break;
420 case BCM_TOPO_PON_MODE_XGPON:
421 case BCM_TOPO_PON_MODE_XGS:
422 pon->max_num_of_onus = 256;
423 break;
424 case BCM_TOPO_PON_MODE_EPON_TDMA:
425 case BCM_TOPO_PON_MODE_EPON_1G:
426 case BCM_TOPO_PON_MODE_EPON_10G:
427 pon->max_num_of_onus = 0; /* There is no "ONU" in EPON, but LLIDs. */
428 break;
429 default:
430 break;
431 }
432}
433
434static bcmos_errno bcm_topo_init_by_file(FILE *fp, const char *filename)
435{
436 char line[BCM_TOPO_MAX_LINE_SIZE];
437 uint32_t line_num;
438
439 /* Read next line. */
440 line_num = 1;
441 while (fgets(line, sizeof(line), fp))
442 {
443 bcmos_bool is_skipped;
444 uint32_t logical_pon, device_id, physical_pon;
445 bcm_topo_pon_mode pon_mode;
446 bcm_topo_dev_context_t *dev;
447 bcm_topo_pon_context_t *pon;
448
449 if (bcm_topo_init_line_parse(line, filename, line_num, &is_skipped, &logical_pon, &pon_mode, &device_id, &physical_pon) != BCM_ERR_OK)
450 return BCM_ERR_PARSE;
451
452 if (is_skipped)
453 {
454 line_num++;
455 continue;
456 }
457
458 if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
459 {
460 BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
461 return BCM_ERR_RANGE;
462 }
463
464 if (bcm_topo_context.logical_pon2physical_pon[logical_pon])
465 {
466 BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u has already been set before\n", filename, line_num);
467 return BCM_ERR_ALREADY;
468 }
469
470 if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
471 {
472 BCM_LOG(ERROR, topo_log_id, "Physical device ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_DEVS - 1);
473 return BCM_ERR_RANGE;
474 }
475
476 dev = &bcm_topo_context.devs[device_id];
477 if (!dev->is_initialized)
478 {
479 bcm_topo_init_dev(dev, pon_mode);
480 dev->is_initialized = BCMOS_TRUE;
481 }
482 else if (dev->pon_mode != pon_mode)
483 {
484 BCM_LOG(ERROR, topo_log_id, "PON mode at %s:%u conflicts with PON mode='%s' that has already been set for this device\n", filename, line_num,
485 int2str(pon_mode2str, dev->pon_mode));
486 return BCM_ERR_NOT_SUPPORTED;
487 }
488
489 if (physical_pon >= dev->max_num_of_pons)
490 {
491 BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, dev->max_num_of_pons - 1);
492 return BCM_ERR_RANGE;
493 }
494
495 pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
496 if (!pon->is_initialized)
497 {
498 bcm_topo_init_pon(pon, pon_mode);
499 pon->is_initialized = BCMOS_TRUE;
500 }
501 else
502 {
503 BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u has already been set before\n", filename, line_num);
504 return BCM_ERR_ALREADY;
505 }
506
507 bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
508 bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;
509
510 line_num++;
511 }
512
513 return BCM_ERR_OK;
514}
515
516static bcmos_errno bcm_topo_init_by_args(bcm_topo_params *params)
517{
518 uint32_t device_id;
519 uint32_t max_num_of_pons_per_dev;
520
521 if (params->num_of_devs > BCM_TOPO_MAX_NUM_OF_DEVS)
522 {
523 BCM_LOG(ERROR, topo_log_id, "Number of devices must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS);
524 return BCM_ERR_RANGE;
525 }
526
527 max_num_of_pons_per_dev = int2int(pon_mode2max_num_of_pons, params->pon_mode);
528
529 if (params->num_of_pons_per_dev > max_num_of_pons_per_dev)
530 {
531 BCM_LOG(ERROR, topo_log_id, "Number of PONs per device for PON mode '%s' must be in the range 0 .. %u\n", int2str(pon_mode2str, params->pon_mode), BCM_TOPO_MAX_NUM_OF_DEVS);
532 return BCM_ERR_RANGE;
533 }
534
535 for (device_id = 0; device_id < params->num_of_devs; device_id++)
536 {
537 uint32_t physical_pon;
538 bcm_topo_dev_context_t *dev;
539 bcm_topo_pon_context_t *pon;
540
541 dev = &bcm_topo_context.devs[device_id];
542 bcm_topo_init_dev(dev, params->pon_mode);
543 dev->is_initialized = BCMOS_TRUE;
544
545 for (physical_pon = 0; physical_pon < params->num_of_pons_per_dev; physical_pon++)
546 {
547 uint32_t logical_pon;
548
549 logical_pon = (device_id * params->num_of_pons_per_dev) + physical_pon;
550
551 BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical pon ID=%u, PON mode='%s')\n", logical_pon, device_id, physical_pon,
552 int2str(pon_mode2str, params->pon_mode));
553
554 pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
555 bcm_topo_init_pon(pon, params->pon_mode);
556 pon->is_initialized = BCMOS_TRUE;
557
558 bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
559 bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;
560 }
561 }
562
563 return BCM_ERR_OK;
564}
565
566bcmos_errno bcm_topo_init(bcm_topo_params *params, const char *topo_filename)
567{
568 bcmos_errno ret;
569 FILE *topo_fp;
570
571#ifdef ENABLE_LOG
572 if (topo_log_id == DEV_LOG_INVALID_ID)
573 {
574 topo_log_id = bcm_dev_log_id_register("TOPOLOGY", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
575 BUG_ON(topo_log_id == DEV_LOG_INVALID_ID);
576 }
577#endif
578
579 bcm_topo_init_context();
580
581 topo_fp = fopen(topo_filename, "r");
582 if (topo_fp)
583 {
584 BCM_LOG(INFO, topo_log_id, "Topology is taken from file\n");
585 ret = bcm_topo_init_by_file(topo_fp, topo_filename);
586 fclose(topo_fp);
587 }
588 else if (params)
589 {
590 BCM_LOG(INFO, topo_log_id, "Topology is taken from arguments\n");
591 ret = bcm_topo_init_by_args(params);
592 }
593 else
594 {
595 BCM_LOG(INFO, topo_log_id, "At least one of topo_fp and params must be specified and exist\n");
596 ret = BCM_ERR_PARM;
597 }
598
599 if (ret != BCM_ERR_OK)
600 goto exit;
601
602 bcm_topo_context.is_initialized = BCMOS_TRUE;
603
604 ret = BCM_ERR_OK;
605
606exit:
607 return ret;
608}
609
610bcmos_bool bcm_topo_is_initialized(void)
611{
612 return bcm_topo_context.is_initialized;
613}
614
615bcmos_bool bcm_topo_dev_set_max_nni(bcmolt_devid device_id, uint32_t num_nni_ports)
616{
617 if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
618 {
619 return BCM_ERR_PARM;
620 }
621 /* make sure the max number does not exceed the allocated resrouce */
622 if( num_nni_ports > BCM_TOPO_MAX_NNI_PORTS)
623 {
624 return BCM_ERR_PARM;
625 }
626 g_max_nni_ports[device_id] = num_nni_ports;
627
628 return BCMOS_TRUE;
629}
630
631bcmos_bool bcm_topo_dev_get_max_nni(bcmolt_devid device_id, uint32_t *p_num_nni_ports)
632{
633 if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
634 {
635 return BCM_ERR_PARM;
636 }
637 *p_num_nni_ports = g_max_nni_ports[device_id];
638
639 return BCMOS_TRUE;
640}
641
642bcmos_bool bcm_topo_nni_is_valid(uint32_t nni)
643{
644
645 if (nni >= g_max_nni_ports[0])
646 return BCMOS_FALSE;
647
648 return BCMOS_TRUE;
649}
650