phymod_ctrl.c (7539B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: phymod_ctrl.c 8 * Purpose: Interface functions for PHYMOD 9 */ 10 11 #ifdef PHYMOD_SUPPORT 12 13 #include <shared/bsl.h> 14 15 #include <soc/drv.h> 16 #include <soc/phy/phymod_ctrl.h> 17 #include <phymod/phymod_types.h> 18 #include <phymod/phymod.h> 19 20 #define OBJ_ID(obj_) (obj_)->obj_id 21 #define OBJ_ID_VALID(id_) ((id_) >= 0) 22 23 static soc_phy_obj_t *core_list[SOC_MAX_NUM_DEVICES]; 24 static soc_phy_obj_t *phy_list[SOC_MAX_NUM_DEVICES]; 25 26 27 28 STATIC int 29 soc_phy_obj_exists(soc_phy_obj_t **obj_head, int obj_id, soc_phy_obj_t **f_obj) 30 { 31 soc_phy_obj_t *obj = *obj_head; 32 33 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 34 (BSL_META("obj_exists 0x%x "), obj_id)); 35 while (obj) { 36 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 37 (BSL_META("[0x%x] "), OBJ_ID(obj))); 38 if (OBJ_ID(obj) == obj_id) { 39 if (f_obj) { 40 *f_obj = obj; 41 } 42 return 1; 43 } 44 obj = obj->next; 45 } 46 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 47 (BSL_META("\n"))); 48 return 0; 49 } 50 51 STATIC int 52 soc_phy_obj_insert(soc_phy_obj_t **obj_head, soc_phy_obj_t *new_obj) 53 { 54 soc_phy_obj_t *obj = *obj_head; 55 56 if (new_obj == NULL) { 57 return -1; 58 } 59 60 new_obj->next = NULL; 61 62 while (obj && obj->next) { 63 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 64 (BSL_META("[0x%x] "), OBJ_ID(obj))); 65 if (OBJ_ID(obj->next) > OBJ_ID(new_obj)) { 66 break; 67 } 68 obj = obj->next; 69 } 70 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 71 (BSL_META("\n"))); 72 73 if (obj) { 74 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 75 (BSL_META("end_id 0x%x\n"), OBJ_ID(obj))); 76 if (OBJ_ID(obj) > OBJ_ID(new_obj)) { 77 new_obj->next = obj; 78 *obj_head = new_obj; 79 } else { 80 new_obj->next = obj->next; 81 obj->next = new_obj; 82 } 83 } else { 84 *obj_head = new_obj; 85 } 86 87 return 0; 88 } 89 90 STATIC int 91 soc_phy_obj_delete(soc_phy_obj_t **obj_head, soc_phy_obj_t *del_obj) 92 { 93 soc_phy_obj_t *prev, *obj = *obj_head; 94 95 if (del_obj == NULL) { 96 return -1; 97 } 98 99 prev = NULL; 100 while (obj) { 101 if (OBJ_ID(obj) == OBJ_ID(del_obj)) { 102 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 103 (BSL_META("delete 0x%x\n"), OBJ_ID(obj))); 104 if (prev) { 105 prev->next = obj->next; 106 } else { 107 *obj_head = (*obj_head)->next; 108 } 109 break; 110 } 111 prev = obj; 112 obj = obj->next; 113 } 114 115 return 0; 116 } 117 118 STATIC int 119 soc_phymod_free_core_id_get(int unit) 120 { 121 soc_phy_obj_t *core = core_list[unit]; 122 int new_id = 1; 123 124 while (core && core->next) { 125 new_id = OBJ_ID(core) + 1; 126 if (new_id != OBJ_ID(core->next)) { 127 return new_id; 128 } 129 core = core->next; 130 } 131 132 if (core) { 133 new_id = OBJ_ID(core) + 1; 134 } 135 136 return 0; 137 } 138 139 STATIC int 140 soc_phymod_free_phy_id_get(int unit) 141 { 142 soc_phy_obj_t *phy = phy_list[unit]; 143 int new_id = 1; 144 145 while (phy && phy->next) { 146 new_id = OBJ_ID(phy) + 1; 147 if (new_id != OBJ_ID(phy->next)) { 148 return new_id; 149 } 150 phy = phy->next; 151 } 152 153 if (phy) { 154 new_id = OBJ_ID(phy) + 1; 155 } 156 157 return new_id; 158 } 159 160 int 161 soc_phymod_miim_bus_read(int unit, uint32_t addr, uint32_t reg, uint32_t *data) 162 { 163 int rv; 164 uint16 data16; 165 166 rv = soc_miim_read(unit, addr, reg, &data16); 167 *data = data16; 168 169 return rv; 170 } 171 172 int 173 soc_phymod_miim_bus_write(int unit, uint32_t addr, uint32_t reg, uint32_t data) 174 { 175 return soc_miim_write(unit, addr, reg, data); 176 } 177 178 int 179 soc_phymod_core_create(int unit, int core_id, soc_phymod_core_t **core) 180 { 181 soc_phymod_core_t *new_core; 182 soc_phy_obj_t *core_obj; 183 184 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 185 (BSL_META("core_create 0x%x\n"), core_id)); 186 if (OBJ_ID_VALID(core_id) && 187 soc_phy_obj_exists(&core_list[unit], core_id, NULL)) { 188 return SOC_E_EXISTS; 189 } 190 191 new_core = sal_alloc(sizeof(soc_phymod_core_t), "soc_phymod_core"); 192 if (new_core == NULL) { 193 return SOC_E_MEMORY; 194 } 195 sal_memset(new_core, 0 ,sizeof(soc_phymod_core_t)); 196 core_obj = &new_core->obj; 197 core_obj->owner = (void *)new_core; 198 199 if (OBJ_ID_VALID(core_id)) { 200 OBJ_ID(core_obj) = core_id; 201 } else { 202 OBJ_ID(core_obj) = soc_phymod_free_core_id_get(unit); 203 } 204 205 soc_phy_obj_insert(&core_list[unit], core_obj); 206 207 new_core->device_aux_modes = NULL ; 208 209 *core = new_core; 210 211 return SOC_E_NONE; 212 } 213 214 int 215 soc_phymod_core_destroy(int unit, soc_phymod_core_t *core) 216 { 217 if (core == NULL) { 218 return SOC_E_PARAM; 219 } 220 221 soc_phy_obj_delete(&core_list[unit], &core->obj); 222 223 sal_free(core); 224 225 return SOC_E_NONE; 226 } 227 228 int 229 soc_phymod_core_find_by_id(int unit, int core_id, soc_phymod_core_t **core) 230 { 231 soc_phy_obj_t *core_obj; 232 233 if (core == NULL) { 234 return SOC_E_PARAM; 235 } 236 237 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 238 (BSL_META("core_find 0x%x\n"), core_id)); 239 if (OBJ_ID_VALID(core_id) && 240 soc_phy_obj_exists(&core_list[unit], core_id, &core_obj)) { 241 *core = (soc_phymod_core_t *)core_obj->owner; 242 return SOC_E_NONE; 243 } 244 245 return SOC_E_NOT_FOUND; 246 } 247 248 int 249 soc_phymod_phy_create(int unit, int phy_id, soc_phymod_phy_t **phy) 250 { 251 soc_phymod_phy_t *new_phy; 252 soc_phy_obj_t *phy_obj; 253 254 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 255 (BSL_META("phy_create 0x%x\n"), phy_id)); 256 if (OBJ_ID_VALID(phy_id) && 257 soc_phy_obj_exists(&phy_list[unit], phy_id, NULL)) { 258 return SOC_E_EXISTS; 259 } 260 261 new_phy = sal_alloc(sizeof(soc_phymod_phy_t), "soc_phymod_phy"); 262 if (new_phy == NULL) { 263 return SOC_E_MEMORY; 264 } 265 phy_obj = &new_phy->obj; 266 phy_obj->owner = (void *)new_phy; 267 268 if (OBJ_ID_VALID(phy_id)) { 269 OBJ_ID(phy_obj) = phy_id; 270 } else { 271 OBJ_ID(phy_obj) = soc_phymod_free_phy_id_get(unit); 272 } 273 274 soc_phy_obj_insert(&phy_list[unit], phy_obj); 275 276 *phy = new_phy; 277 278 return SOC_E_NONE; 279 } 280 281 int 282 soc_phymod_phy_destroy(int unit, soc_phymod_phy_t *phy) 283 { 284 if (phy == NULL) { 285 return SOC_E_PARAM; 286 } 287 288 soc_phy_obj_delete(&phy_list[unit], &phy->obj); 289 290 sal_free(phy); 291 292 return SOC_E_NONE; 293 } 294 295 int 296 soc_phymod_phy_find_by_id(int unit, int phy_id, soc_phymod_phy_t **phy) 297 { 298 soc_phy_obj_t *phy_obj; 299 300 if (phy == NULL) { 301 return SOC_E_PARAM; 302 } 303 304 LOG_DEBUG(BSL_LS_SOC_PHYMOD, 305 (BSL_META("phy_find 0x%x\n"), phy_id)); 306 if (OBJ_ID_VALID(phy_id) && 307 soc_phy_obj_exists(&phy_list[unit], phy_id, &phy_obj)) { 308 *phy = (soc_phymod_phy_t *)phy_obj->owner; 309 return SOC_E_NONE; 310 } 311 312 return SOC_E_NOT_FOUND; 313 } 314 315 void 316 soc_phymod_usleep(uint32_t usecs) 317 { 318 sal_usleep(usecs); 319 } 320 321 void 322 soc_phymod_sleep(int secs) 323 { 324 sal_sleep(secs); 325 } 326 327 int 328 soc_phymod_strcmp(const char *str1, const char *str2) 329 { 330 return sal_strcmp(str1, str2); 331 } 332 333 void * 334 soc_phymod_memcpy(void *dst, const void *src, size_t n) 335 { 336 return sal_memcpy(dst, src, n); 337 } 338 339 void * 340 soc_phymod_memset(void *dst, int c, size_t n) 341 { 342 return sal_memset(dst, c, n); 343 } 344 345 void * 346 soc_phymod_alloc(size_t size, char *descr) 347 { 348 return sal_alloc(size, descr); 349 } 350 351 void 352 soc_phymod_free(void *ptr) 353 { 354 sal_free(ptr); 355 } 356 357 #else 358 int _phymod_ctrl_not_empty; 359 #endif